subdux effects
This commit is contained in:
parent
95768706fa
commit
daa8421251
34
src/Updux.ts
34
src/Updux.ts
@ -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() {
|
||||
|
@ -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?
|
||||
|
@ -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 : {};
|
||||
|
Loading…
Reference in New Issue
Block a user