change reaction api

main
Yanick Champoux 2023-03-22 12:04:07 -04:00
parent 0e894b7db1
commit bde9cac053
4 changed files with 11 additions and 5 deletions

View File

@ -40,6 +40,7 @@
"prettier": "^2.7.1",
"redux-toolkit": "^1.1.2",
"typescript": "^4.9.5",
"vite": "^4.2.1",
"vitest": "0.23.1"
}
}

View File

@ -56,7 +56,7 @@ type ResolveActions<
};
type Reaction<S = any, M extends MiddlewareAPI = MiddlewareAPI> =
(api: M, state: S, previousState: S, unsubscribe: () => void) => void;
(api: M) => (state: S, previousState: S, unsubscribe: () => void) => any;
type AugmentedMiddlewareAPI<S, A, SELECTORS> =
MiddlewareAPI<Dispatch<AnyAction>, S> & {
@ -217,6 +217,8 @@ export default class Updux<
unsub = store.subscribe(() => r(unsub));
}
(store as any).actions = this.actions;
return store as ToolkitStore<
AggregateState<T_LocalState, T_Subduxes>
@ -326,12 +328,13 @@ export default class Updux<
this.actions,
this.selectors
);
const r = reaction(api);
return (unsub: () => void) => {
const state = api.getState();
if (state === previous) return;
let p = previous;
previous = state;
reaction(api, state, p, unsub);
r(state, p, unsub);
}
}
;

View File

@ -11,7 +11,7 @@ test('basic reactions', () => {
foo.addMutation(foo.actions.inc, () => (state) => state + 1);
foo.addMutation(foo.actions.reset, () => (state) => 0);
foo.addReaction((api, state, _previous, unsubscribe) => {
foo.addReaction((api) => (state, _previous, unsubscribe) => {
if (state < 3) return;
unsubscribe();
api.dispatch.reset();
@ -53,7 +53,7 @@ test('subdux reactions', () => {
bar.addMutation(foo.actions.reset, () => (state) => 0);
let seen = 0;
bar.addReaction((api, state, _previous, unsubscribe) => {
bar.addReaction((api) => (state, _previous, unsubscribe) => {
seen++;
expect(api.actions).not.toHaveProperty('notInBar');
expect(state).toBeTypeOf('number');

View File

@ -3,6 +3,7 @@ import { BaseActionCreator } from '@reduxjs/toolkit/dist/createAction.js';
import * as R from 'remeda';
import { Dux } from './types.js';
import { Mutation } from './Updux.js';
import u from '@yanick/updeep-remeda';
export type MutationCase = {
matcher: (action: Action) => boolean;
@ -22,6 +23,7 @@ export function buildReducer(
// TODO defaultMutation
//
const reducer = (state = initialState, action: Action) => {
const orig = state;
if (!action?.type)
throw new Error('upreducer called with a bad action');
@ -49,7 +51,7 @@ export function buildReducer(
if (!terminal && Object.keys(subduxes).length > 0) {
// subduxes
state = R.merge(
state = u.update(
state,
R.mapValues(subReducers, (reducer, slice) =>
(reducer as any)(state[slice], action),