80 lines
2.1 KiB
TypeScript
80 lines
2.1 KiB
TypeScript
import { Action, ActionCreator, createAction } from '@reduxjs/toolkit';
|
|
import { BaseActionCreator } from '@reduxjs/toolkit/dist/createAction.js';
|
|
import * as R from 'remeda';
|
|
import { Dux } from './types.js';
|
|
import { Mutation } from './Updux.js';
|
|
|
|
type MutationCase = {
|
|
matcher: (action: Action) => boolean;
|
|
mutation: Mutation;
|
|
terminal: boolean;
|
|
};
|
|
|
|
export function buildReducer(
|
|
initialState: any,
|
|
mutations: MutationCase[] = [],
|
|
subduxes: Record<string, Dux> = {},
|
|
) {
|
|
// const subReducers =
|
|
// ? R.mapValues(subduxes, R.prop('reducer'));
|
|
|
|
// TODO matcherMutation
|
|
// TODO defaultMutation
|
|
|
|
const reducer = (state = initialState, action: Action) => {
|
|
if (!action?.type)
|
|
throw new Error('upreducer called with a bad action');
|
|
|
|
let terminal = false;
|
|
let didSomething = false;
|
|
|
|
const foo = createAction('foo');
|
|
|
|
const localMutation = mutations.find(({ matcher }) => matcher(action));
|
|
|
|
if (localMutation) {
|
|
didSomething = true;
|
|
if (localMutation.terminal) terminal = true;
|
|
|
|
// TODO wrap mutations in immer
|
|
state = localMutation.mutation(
|
|
(action as any).payload,
|
|
action,
|
|
)(state);
|
|
}
|
|
|
|
// TODO defaultMutation
|
|
|
|
return state;
|
|
};
|
|
|
|
return reducer;
|
|
|
|
/*
|
|
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;
|
|
*/
|
|
}
|