Merge branch 'mutations-of-subduxes' into typescript
This commit is contained in:
commit
3e9049ce93
@ -116,6 +116,7 @@ export default class Updux<
|
|||||||
this.initial,
|
this.initial,
|
||||||
this.#localMutations,
|
this.#localMutations,
|
||||||
this.#defaultMutation,
|
this.#defaultMutation,
|
||||||
|
this.#subduxes,
|
||||||
) as any as (
|
) as any as (
|
||||||
state: undefined | typeof this.initial,
|
state: undefined | typeof this.initial,
|
||||||
action: Action,
|
action: Action,
|
||||||
|
@ -1,45 +0,0 @@
|
|||||||
import u from 'updeep';
|
|
||||||
import { mapValues } from 'lodash-es';
|
|
||||||
|
|
||||||
export function buildUpreducer(
|
|
||||||
initial,
|
|
||||||
mutations,
|
|
||||||
subduxes = {},
|
|
||||||
wrapper = undefined,
|
|
||||||
) {
|
|
||||||
const subReducers =
|
|
||||||
Object.keys(subduxes).length > 0
|
|
||||||
? mapValues(subduxes, ({ upreducer }) => upreducer)
|
|
||||||
: null;
|
|
||||||
|
|
||||||
const upreducer = (action) => (state) => {
|
|
||||||
if (!action?.type)
|
|
||||||
throw new Error('upreducer called with a bad action');
|
|
||||||
|
|
||||||
let newState = state ?? initial;
|
|
||||||
|
|
||||||
if (subReducers) {
|
|
||||||
if (subduxes['*']) {
|
|
||||||
newState = u.updateIn(
|
|
||||||
'*',
|
|
||||||
subduxes['*'].upreducer(action),
|
|
||||||
newState,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
const update = mapValues(subReducers, (upReducer) =>
|
|
||||||
upReducer(action),
|
|
||||||
);
|
|
||||||
|
|
||||||
newState = u(update, newState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const a = mutations[action.type] || mutations['+'];
|
|
||||||
|
|
||||||
if (!a) return newState;
|
|
||||||
|
|
||||||
return a(action.payload, action)(newState);
|
|
||||||
};
|
|
||||||
|
|
||||||
return wrapper ? wrapper(upreducer) : upreducer;
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
import schema from 'json-schema-shorthand';
|
|
||||||
import u from 'updeep';
|
|
||||||
|
|
||||||
import { action } from './actions.js';
|
|
||||||
|
|
||||||
import { Updux, dux } from './Updux.js';
|
|
||||||
|
|
||||||
test('mutation of a subdux', async () => {
|
|
||||||
const bar = dux({
|
|
||||||
actions: {
|
|
||||||
baz: null,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
bar.setMutation('baz', () => (state) => ({ ...state, x: 1 }));
|
|
||||||
|
|
||||||
const foo = dux({
|
|
||||||
subduxes: { bar },
|
|
||||||
});
|
|
||||||
|
|
||||||
const store = foo.createStore();
|
|
||||||
store.dispatch.baz();
|
|
||||||
expect(store.getState()).toMatchObject({ bar: { x: 1 } });
|
|
||||||
});
|
|
||||||
|
|
||||||
test('strings and generators', async () => {
|
|
||||||
const actionA = action('a');
|
|
||||||
|
|
||||||
const foo = dux({
|
|
||||||
actions: {
|
|
||||||
b: null,
|
|
||||||
a: actionA,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// as a string and defined
|
|
||||||
expect(() => foo.setMutation('a', () => {})).not.toThrow();
|
|
||||||
|
|
||||||
// as a generator and defined
|
|
||||||
expect(() => foo.setMutation(actionA, () => {})).not.toThrow();
|
|
||||||
|
|
||||||
// as a string, not defined
|
|
||||||
expect(() => foo.setMutation('c', () => {})).toThrow();
|
|
||||||
|
|
||||||
foo.setMutation(action('d'), () => {});
|
|
||||||
|
|
||||||
expect(foo.actions.d).toBeTypeOf('function');
|
|
||||||
});
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
|||||||
import { test, expect } from 'vitest';
|
import { test, expect } from 'vitest';
|
||||||
|
|
||||||
import Updux from './index.js';
|
import Updux, { createAction } from './index.js';
|
||||||
|
|
||||||
test('set a mutation', () => {
|
test('set a mutation', () => {
|
||||||
const dux = new Updux({
|
const dux = new Updux({
|
||||||
@ -53,3 +53,28 @@ test('default mutation', () => {
|
|||||||
expect(dux.reducer(undefined, { type: 'foo' })).toEqual('got it');
|
expect(dux.reducer(undefined, { type: 'foo' })).toEqual('got it');
|
||||||
expect(dux.reducer(undefined, { type: 'bar' })).toEqual('bar');
|
expect(dux.reducer(undefined, { type: 'bar' })).toEqual('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('mutation of a subdux', () => {
|
||||||
|
const baz = createAction('baz');
|
||||||
|
const noop = createAction('noop');
|
||||||
|
const stopit = createAction('stopit');
|
||||||
|
|
||||||
|
const bar = new Updux({
|
||||||
|
initial: 0,
|
||||||
|
actions: {
|
||||||
|
baz,
|
||||||
|
stopit,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
bar.addMutation(baz, () => () => 1);
|
||||||
|
bar.addMutation(stopit, () => () => 2);
|
||||||
|
|
||||||
|
const foo = new Updux({
|
||||||
|
subduxes: { bar },
|
||||||
|
});
|
||||||
|
foo.addMutation(stopit, () => (state) => state, true);
|
||||||
|
|
||||||
|
expect(foo.reducer(undefined, noop())).toHaveProperty('bar', 0);
|
||||||
|
expect(foo.reducer(undefined, baz())).toHaveProperty('bar', 1);
|
||||||
|
expect(foo.reducer(undefined, stopit())).toHaveProperty('bar', 0);
|
||||||
|
});
|
||||||
|
@ -16,8 +16,7 @@ export function buildReducer(
|
|||||||
defaultMutation?: Omit<MutationCase, 'matcher'>,
|
defaultMutation?: Omit<MutationCase, 'matcher'>,
|
||||||
subduxes: Record<string, Dux> = {},
|
subduxes: Record<string, Dux> = {},
|
||||||
) {
|
) {
|
||||||
// const subReducers =
|
const subReducers = R.mapValues(subduxes, R.prop('reducer'));
|
||||||
// ? R.mapValues(subduxes, R.prop('reducer'));
|
|
||||||
|
|
||||||
// TODO matcherMutation
|
// TODO matcherMutation
|
||||||
// TODO defaultMutation
|
// TODO defaultMutation
|
||||||
@ -48,6 +47,16 @@ export function buildReducer(
|
|||||||
)(state);
|
)(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!terminal && Object.keys(subduxes).length > 0) {
|
||||||
|
// subduxes
|
||||||
|
state = R.merge(
|
||||||
|
state,
|
||||||
|
R.mapValues(subReducers, (reducer, slice) =>
|
||||||
|
(reducer as any)(state[slice], action),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user