Merge branch 'subdux-selectors'
This commit is contained in:
commit
7280381ca8
@ -15,6 +15,7 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"module": "dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./dist/index.js"
|
||||
|
26
src/Updux.ts
26
src/Updux.ts
@ -122,17 +122,17 @@ export default class Updux<D extends DuxConfig> {
|
||||
matcher: A,
|
||||
mutation: Mutation<DuxActions<D>[A] extends (...args: any) => infer P ? P : never, DuxState<D>>,
|
||||
terminal?: boolean,
|
||||
);
|
||||
): Updux<D>;
|
||||
addMutation<A extends Action<any>>(
|
||||
matcher: (action: A) => boolean,
|
||||
mutation: Mutation<A, DuxState<D>>,
|
||||
terminal?: boolean,
|
||||
);
|
||||
): Updux<D>;
|
||||
addMutation<A extends ActionCreator<any>>(
|
||||
actionCreator: A,
|
||||
mutation: Mutation<ReturnType<A>, DuxState<D>>,
|
||||
terminal?: boolean,
|
||||
);
|
||||
): Updux<D>;
|
||||
addMutation(matcher, mutation, terminal = false) {
|
||||
|
||||
if (typeof matcher === 'string') {
|
||||
@ -157,6 +157,8 @@ export default class Updux<D extends DuxConfig> {
|
||||
mutation,
|
||||
},
|
||||
];
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
#defaultMutation;
|
||||
@ -189,6 +191,7 @@ export default class Updux<D extends DuxConfig> {
|
||||
options: Partial<{
|
||||
preloadedState: DuxState<D>;
|
||||
validate: boolean;
|
||||
buildMiddleware: (middleware: any[]) => any
|
||||
}> = {},
|
||||
): EnhancedStore<DuxState<D>> & AugmentedMiddlewareAPI<D> {
|
||||
const preloadedState = options.preloadedState;
|
||||
@ -199,7 +202,7 @@ export default class Updux<D extends DuxConfig> {
|
||||
this.selectors,
|
||||
);
|
||||
|
||||
const middleware = [effects];
|
||||
let middleware = [effects];
|
||||
|
||||
if (options.validate) {
|
||||
middleware.unshift(
|
||||
@ -207,6 +210,9 @@ export default class Updux<D extends DuxConfig> {
|
||||
)
|
||||
}
|
||||
|
||||
if (options.buildMiddleware)
|
||||
middleware = options.buildMiddleware(middleware);
|
||||
|
||||
const store = configureStore({
|
||||
reducer: this.reducer,
|
||||
preloadedState,
|
||||
@ -253,16 +259,16 @@ export default class Updux<D extends DuxConfig> {
|
||||
addEffect(
|
||||
actionType: keyof DuxActions<D>,
|
||||
effect: EffectMiddleware<D>,
|
||||
): EffectMiddleware<D>;
|
||||
): Updux<D>;
|
||||
addEffect(
|
||||
actionCreator: { match: (action: any) => boolean },
|
||||
effect: EffectMiddleware<D>,
|
||||
): EffectMiddleware<D>;
|
||||
): Updux<D>;
|
||||
addEffect(
|
||||
guardFunc: (action: AnyAction) => boolean,
|
||||
effect: EffectMiddleware<D>,
|
||||
): EffectMiddleware<D>;
|
||||
addEffect(effect: EffectMiddleware<D>): EffectMiddleware<D>;
|
||||
): Updux<D>;
|
||||
addEffect(effect: EffectMiddleware<D>): Updux<D>;
|
||||
addEffect(...args) {
|
||||
let effect;
|
||||
if (args.length === 1) {
|
||||
@ -294,10 +300,10 @@ export default class Updux<D extends DuxConfig> {
|
||||
|
||||
this.#effects = [...this.#effects, effect];
|
||||
|
||||
return effect;
|
||||
return this;
|
||||
}
|
||||
|
||||
get effects() {
|
||||
get effects(): any {
|
||||
return this.memoBuildEffects(this.#effects, this.duxConfig.subduxes);
|
||||
}
|
||||
|
||||
|
@ -126,10 +126,10 @@ test('addEffect with actionCreator', () => {
|
||||
const next = vi.fn();
|
||||
const spy = vi.fn();
|
||||
|
||||
const mw = dux.addEffect(
|
||||
const [mw] = dux.addEffect(
|
||||
dux.actions.foo,
|
||||
(api) => (next) => (action) => next(spy(action)),
|
||||
);
|
||||
).effects;
|
||||
|
||||
mw({} as any)(next)(dux.actions.bar());
|
||||
expect(next).toHaveBeenCalled();
|
||||
@ -152,10 +152,10 @@ test('addEffect with function', () => {
|
||||
const next = vi.fn();
|
||||
const spy = vi.fn();
|
||||
|
||||
const mw = dux.addEffect(
|
||||
const [mw] = dux.addEffect(
|
||||
(action) => action.type[0] === 'f',
|
||||
(api) => (next) => (action) => next(spy(action)),
|
||||
);
|
||||
).effects;
|
||||
|
||||
mw({} as any)(next)(dux.actions.bar());
|
||||
expect(next).toHaveBeenCalled();
|
||||
@ -170,13 +170,13 @@ test('addEffect with function', () => {
|
||||
test('catchall addEffect', () => {
|
||||
const dux = new Updux({
|
||||
initialState: {
|
||||
a: 1
|
||||
}
|
||||
a: 1,
|
||||
},
|
||||
});
|
||||
|
||||
const spy = vi.fn();
|
||||
|
||||
dux.addEffect((api) => next => action => {
|
||||
dux.addEffect((api) => (next) => (action) => {
|
||||
expectTypeOf(api.getState()).toMatchTypeOf<{
|
||||
a: number;
|
||||
}>();
|
||||
@ -191,7 +191,6 @@ test('catchall addEffect', () => {
|
||||
store.dispatch({ type: 'noop' });
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
|
||||
});
|
||||
|
||||
// TODO subdux effects
|
||||
|
@ -5,7 +5,7 @@ import Updux, { createAction } from './index.js';
|
||||
describe('basic selectors', () => {
|
||||
type State = { x: number };
|
||||
|
||||
const foo = new Updux({
|
||||
const config = {
|
||||
initialState: {
|
||||
x: 1,
|
||||
},
|
||||
@ -23,8 +23,16 @@ describe('basic selectors', () => {
|
||||
(y + incr) as number,
|
||||
},
|
||||
}),
|
||||
// cause the type to fail
|
||||
baz: new Updux({
|
||||
selectors: {
|
||||
getFromBaz: () => 'potato',
|
||||
},
|
||||
});
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
const foo = new Updux(config);
|
||||
|
||||
const sample = {
|
||||
x: 4,
|
||||
|
@ -17,9 +17,11 @@ type Values<X> = X[keyof X];
|
||||
|
||||
export type DuxSelectors<D> = (D extends { selectors: infer S } ? S : {}) &
|
||||
(D extends { subduxes: infer SUB }
|
||||
? Values<{
|
||||
? UnionToIntersection<
|
||||
Values<{
|
||||
[key in keyof SUB]: RebaseSelectors<key, SUB[key]>;
|
||||
}>
|
||||
>
|
||||
: {});
|
||||
|
||||
export function buildSelectors(localSelectors = {}, subduxes = {}) {
|
||||
|
@ -48,7 +48,7 @@
|
||||
// "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */
|
||||
|
||||
/* Emit */
|
||||
// "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */
|
||||
"declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */,
|
||||
// "declarationMap": true, /* Create sourcemaps for d.ts files. */
|
||||
// "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */
|
||||
// "sourceMap": true, /* Create source map files for emitted JavaScript files. */
|
||||
|
Loading…
Reference in New Issue
Block a user