subdux effects

main
Yanick Champoux 2023-03-11 13:37:33 -05:00
parent 95768706fa
commit daa8421251
3 changed files with 60 additions and 8 deletions

View File

@ -6,6 +6,7 @@ import {
Action,
MiddlewareAPI,
AnyAction,
Middleware,
} from 'redux';
import {
configureStore,
@ -88,7 +89,7 @@ export default class Updux<
>;
#selectors: any;
#effects: any[] = [];
#localEffects: Middleware[] = [];
constructor(
config: Partial<{
@ -128,19 +129,42 @@ export default class Updux<
return this.#initial;
}
get effects() {
return [
...this.#localEffects,
...Object.entries(this.#subduxes).flatMap(
([slice, { effects }]) => {
if (!effects) return [];
return effects.map(effect => (api) => effect({
...api,
getState: () => api.getState()[slice],
}))
}
)
]
}
createStore(
options: Partial<{
initial: T_LocalState;
}> = {},
) {
const preloadedState: any = options.initial ?? this.initial;
const effects = buildEffectsMiddleware(
this.effects,
this.actions,
this.selectors,
);
const store = configureStore({
reducer: ((state) => state) as Reducer<
AggregateState<T_LocalState, T_Subduxes>,
AnyAction
>,
preloadedState,
middleware: [this.effectsMiddleware],
middleware: [effects],
});
const dispatch: any = store.dispatch;
@ -221,11 +245,7 @@ export default class Updux<
}
addEffect(effect: EffectMiddleware) {
this.#effects.push(effect);
}
get effects() {
return this.#effects;
this.#localEffects.push(effect);
}
get effectsMiddleware() {

View File

@ -75,5 +75,36 @@ test('basic', () => {
expect(seen).toEqual(1);
});
test('subdux', () => {
const bar = new Updux({
initial: 'bar state',
actions: { foo: 0 },
});
let seen = 0;
bar.addEffect((api) => next => action => {
seen++;
expect(api.getState()).toBe('bar state');
next(action);
});
const dux = new Updux({
initial: {
loaded: true,
},
subduxes: {
bar
},
});
const store = dux.createStore();
expect(seen).toEqual(0);
store.dispatch.foo();
expect(seen).toEqual(1);
});
// TODO subdux effects
// TODO allow to subscribe / unsubscribe effects?

View File

@ -1,4 +1,4 @@
import { Action, ActionCreator, Reducer } from 'redux';
import { Action, ActionCreator, Middleware, Reducer } from 'redux';
export type Dux<
STATE = any,
@ -11,6 +11,7 @@ export type Dux<
state: STATE,
action: ReturnType<ACTIONS[keyof ACTIONS]>,
) => STATE;
effects: Middleware[];
}>;
type ActionsOf<DUX> = DUX extends { actions: infer A } ? A : {};