diff --git a/src/Updux.ts b/src/Updux.ts index b3c8952..fd3ac49 100644 --- a/src/Updux.ts +++ b/src/Updux.ts @@ -22,6 +22,7 @@ import { buildInitial, AggregateState } from './initial.js'; import { buildReducer, MutationCase } from './reducer.js'; import { augmentGetState, augmentMiddlewareApi, buildEffectsMiddleware, EffectMiddleware } from './effects.js'; import { ToolkitStore } from '@reduxjs/toolkit/dist/configureStore.js'; +import prepare from 'immer'; type MyActionCreator = { type: string } & ((...args: any) => any); @@ -132,7 +133,9 @@ export default class Updux< Object.entries(this.#subduxes) .filter(([slice, { selectors }]) => selectors) .map(([slice, { selectors }]) => - R.mapValues(selectors, (s) => (state) => s(state[slice])), + R.mapValues(selectors, (s) => (state = {}) => { + return s(state?.[slice]) + }), ), ); @@ -218,6 +221,7 @@ export default class Updux< } (store as any).actions = this.actions; + (store as any).selectors = this.selectors; return store as ToolkitStore< @@ -276,10 +280,12 @@ export default class Updux< matcher = matcher.match; } + const immerMutation = (...args) => prepare(mutation(...args)); + this.#localMutations.push({ terminal, matcher, - mutation, + mutation: immerMutation, }); } diff --git a/src/buildActions.ts b/src/buildActions.ts index bee0ebb..f93ac42 100644 --- a/src/buildActions.ts +++ b/src/buildActions.ts @@ -21,7 +21,7 @@ export function buildActions(localActions, subduxes) { if (!subdux) continue; for (const a in subdux) { - if (actions[a]) { + if (actions[a] && subduxes[actions[a]].actions[a] !== subdux[a]) { throw new Error( `action '${a}' defined both in subduxes '${actions[a]}' and '${slice}'`, ); diff --git a/src/reducer.ts b/src/reducer.ts index c11c60b..1f7b956 100644 --- a/src/reducer.ts +++ b/src/reducer.ts @@ -4,6 +4,7 @@ import * as R from 'remeda'; import { Dux } from './types.js'; import { Mutation } from './Updux.js'; import u from '@yanick/updeep-remeda'; +import prepare from 'immer'; export type MutationCase = { matcher: (action: Action) => boolean; @@ -35,9 +36,10 @@ export function buildReducer( .forEach(({ mutation, terminal: t }) => { if (t) terminal = true; didSomething = true; - // - // TODO wrap mutations in immer - state = mutation((action as any).payload, action)(state); + state = prepare( + state, + mutation((action as any).payload, action), + ); }); if (!didSomething && defaultMutation) {