From 1555e4d289e26ed0a233449597571c564f207f23 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 9 Mar 2023 14:48:11 -0500 Subject: [PATCH 1/3] add subdux test --- src/mutations.test.todo | 16 ---------------- src/mutations.test.ts | 20 +++++++++++++++++++- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/src/mutations.test.todo b/src/mutations.test.todo index 7e72b34..dccf11b 100644 --- a/src/mutations.test.todo +++ b/src/mutations.test.todo @@ -5,22 +5,6 @@ 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'); diff --git a/src/mutations.test.ts b/src/mutations.test.ts index 09c3000..9f19df8 100644 --- a/src/mutations.test.ts +++ b/src/mutations.test.ts @@ -1,6 +1,6 @@ import { test, expect } from 'vitest'; -import Updux from './index.js'; +import Updux, { createAction } from './index.js'; test('set a mutation', () => { const dux = new Updux({ @@ -53,3 +53,21 @@ test('default mutation', () => { expect(dux.reducer(undefined, { type: 'foo' })).toEqual('got it'); expect(dux.reducer(undefined, { type: 'bar' })).toEqual('bar'); }); + +test('mutation of a subdux', () => { + const baz = createAction('baz'); + + const bar = new Updux({ + initial: 0, + actions: { + baz, + }, + }); + bar.addMutation(baz, () => () => 1); + + const foo = new Updux({ + subduxes: { bar }, + }); + + expect(foo.reducer(undefined, baz())).toHaveProperty('bar', 1); +}); From 769b70dfcea5f2238bbe345acc0a55aaaecf21c6 Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 9 Mar 2023 15:13:13 -0500 Subject: [PATCH 2/3] test is passing --- src/Updux.ts | 1 + src/mutations.test.ts | 7 +++++++ src/reducer.ts | 13 +++++++++++-- 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/Updux.ts b/src/Updux.ts index b9358a9..d35b81c 100644 --- a/src/Updux.ts +++ b/src/Updux.ts @@ -116,6 +116,7 @@ export default class Updux< this.initial, this.#localMutations, this.#defaultMutation, + this.#subduxes, ) as any as ( state: undefined | typeof this.initial, action: Action, diff --git a/src/mutations.test.ts b/src/mutations.test.ts index 9f19df8..5858b63 100644 --- a/src/mutations.test.ts +++ b/src/mutations.test.ts @@ -56,18 +56,25 @@ test('default mutation', () => { 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); }); diff --git a/src/reducer.ts b/src/reducer.ts index 12b431c..9ca2571 100644 --- a/src/reducer.ts +++ b/src/reducer.ts @@ -16,8 +16,7 @@ export function buildReducer( defaultMutation?: Omit, subduxes: Record = {}, ) { - // const subReducers = - // ? R.mapValues(subduxes, R.prop('reducer')); + const subReducers = R.mapValues(subduxes, R.prop('reducer')); // TODO matcherMutation // TODO defaultMutation @@ -48,6 +47,16 @@ export function buildReducer( )(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; }; From 1df6ac5329373042106da881cad3c8b07a56418c Mon Sep 17 00:00:00 2001 From: Yanick Champoux Date: Thu, 9 Mar 2023 15:32:41 -0500 Subject: [PATCH 3/3] subdux mutations are go --- src/buildUpreducer.todo | 45 ----------------------------------------- src/mutations.test.todo | 32 ----------------------------- 2 files changed, 77 deletions(-) delete mode 100644 src/buildUpreducer.todo delete mode 100644 src/mutations.test.todo diff --git a/src/buildUpreducer.todo b/src/buildUpreducer.todo deleted file mode 100644 index 39672ac..0000000 --- a/src/buildUpreducer.todo +++ /dev/null @@ -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; -} diff --git a/src/mutations.test.todo b/src/mutations.test.todo deleted file mode 100644 index dccf11b..0000000 --- a/src/mutations.test.todo +++ /dev/null @@ -1,32 +0,0 @@ -import schema from 'json-schema-shorthand'; -import u from 'updeep'; - -import { action } from './actions.js'; - -import { Updux, dux } from './Updux.js'; - - -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'); -}); -