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,
|
Action,
|
||||||
MiddlewareAPI,
|
MiddlewareAPI,
|
||||||
AnyAction,
|
AnyAction,
|
||||||
|
Middleware,
|
||||||
} from 'redux';
|
} from 'redux';
|
||||||
import {
|
import {
|
||||||
configureStore,
|
configureStore,
|
||||||
@ -88,7 +89,7 @@ export default class Updux<
|
|||||||
>;
|
>;
|
||||||
#selectors: any;
|
#selectors: any;
|
||||||
|
|
||||||
#effects: any[] = [];
|
#localEffects: Middleware[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: Partial<{
|
config: Partial<{
|
||||||
@ -128,19 +129,42 @@ export default class Updux<
|
|||||||
return this.#initial;
|
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(
|
createStore(
|
||||||
options: Partial<{
|
options: Partial<{
|
||||||
initial: T_LocalState;
|
initial: T_LocalState;
|
||||||
}> = {},
|
}> = {},
|
||||||
) {
|
) {
|
||||||
const preloadedState: any = options.initial ?? this.initial;
|
const preloadedState: any = options.initial ?? this.initial;
|
||||||
|
|
||||||
|
const effects = buildEffectsMiddleware(
|
||||||
|
this.effects,
|
||||||
|
this.actions,
|
||||||
|
this.selectors,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
const store = configureStore({
|
const store = configureStore({
|
||||||
reducer: ((state) => state) as Reducer<
|
reducer: ((state) => state) as Reducer<
|
||||||
AggregateState<T_LocalState, T_Subduxes>,
|
AggregateState<T_LocalState, T_Subduxes>,
|
||||||
AnyAction
|
AnyAction
|
||||||
>,
|
>,
|
||||||
preloadedState,
|
preloadedState,
|
||||||
middleware: [this.effectsMiddleware],
|
middleware: [effects],
|
||||||
});
|
});
|
||||||
|
|
||||||
const dispatch: any = store.dispatch;
|
const dispatch: any = store.dispatch;
|
||||||
@ -221,11 +245,7 @@ export default class Updux<
|
|||||||
}
|
}
|
||||||
|
|
||||||
addEffect(effect: EffectMiddleware) {
|
addEffect(effect: EffectMiddleware) {
|
||||||
this.#effects.push(effect);
|
this.#localEffects.push(effect);
|
||||||
}
|
|
||||||
|
|
||||||
get effects() {
|
|
||||||
return this.#effects;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
get effectsMiddleware() {
|
get effectsMiddleware() {
|
||||||
|
@ -75,5 +75,36 @@ test('basic', () => {
|
|||||||
expect(seen).toEqual(1);
|
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 subdux effects
|
||||||
// TODO allow to subscribe / unsubscribe 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<
|
export type Dux<
|
||||||
STATE = any,
|
STATE = any,
|
||||||
@ -11,6 +11,7 @@ export type Dux<
|
|||||||
state: STATE,
|
state: STATE,
|
||||||
action: ReturnType<ACTIONS[keyof ACTIONS]>,
|
action: ReturnType<ACTIONS[keyof ACTIONS]>,
|
||||||
) => STATE;
|
) => STATE;
|
||||||
|
effects: Middleware[];
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
type ActionsOf<DUX> = DUX extends { actions: infer A } ? A : {};
|
type ActionsOf<DUX> = DUX extends { actions: infer A } ? A : {};
|
||||||
|
Loading…
Reference in New Issue
Block a user