initial reducer
This commit is contained in:
parent
93533a739f
commit
4c28a9ad05
@ -41,11 +41,13 @@ type ResolveActions<
|
||||
: never;
|
||||
};
|
||||
|
||||
type Mutation<A extends ActionCreator<any> = ActionCreator<any>, S = any> = (
|
||||
state: S,
|
||||
export type Mutation<
|
||||
A extends ActionCreator<any> = ActionCreator<any>,
|
||||
S = any,
|
||||
> = (
|
||||
payload: ReturnType<A>['payload'],
|
||||
action: ReturnType<A>,
|
||||
) => S | void;
|
||||
) => (state: S) => S | void;
|
||||
|
||||
export default class Updux<
|
||||
T_LocalState = Record<any, any>,
|
||||
|
@ -1,19 +0,0 @@
|
||||
import { test, expect } from 'vitest';
|
||||
|
||||
import { Updux } from './Updux.js';
|
||||
|
||||
test('basic reducer', () => {
|
||||
const dux = new Updux({ initial: { a: 3 } });
|
||||
|
||||
expect(dux.reducer).toBeTypeOf('function');
|
||||
|
||||
expect(dux.reducer({ a: 1 }, { type: 'foo' })).toMatchObject({ a: 1 }); // noop
|
||||
});
|
||||
|
||||
test('basic upreducer', () => {
|
||||
const dux = new Updux({ initial: { a: 3 } });
|
||||
|
||||
expect(dux.upreducer).toBeTypeOf('function');
|
||||
|
||||
expect(dux.upreducer({ type: 'foo' })({ a: 1 })).toMatchObject({ a: 1 }); // noop
|
||||
});
|
31
src/reducer.test.ts
Normal file
31
src/reducer.test.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { test, expect } from 'vitest';
|
||||
|
||||
import { buildReducer } from './reducer.js';
|
||||
import Updux from './Updux.js';
|
||||
|
||||
test('buildReducer, initial state', () => {
|
||||
const reducer = buildReducer({ a: 1 });
|
||||
|
||||
expect(reducer(undefined, { type: 'foo' })).toEqual({ a: 1 });
|
||||
});
|
||||
|
||||
test('buildReducer, mutation', () => {
|
||||
const reducer = buildReducer(1, [
|
||||
{
|
||||
matcher: ({ type }) => type === 'inc',
|
||||
mutation: () => (state) => state + 1,
|
||||
terminal: false,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(reducer(undefined, { type: 'foo' })).toEqual(1);
|
||||
expect(reducer(undefined, { type: 'inc' })).toEqual(2);
|
||||
});
|
||||
|
||||
test.todo('basic reducer', () => {
|
||||
const dux = new Updux({ initial: { a: 3 } });
|
||||
|
||||
expect(dux.reducer).toBeTypeOf('function');
|
||||
|
||||
expect(dux.reducer({ a: 1 }, { type: 'foo' })).toMatchObject({ a: 1 }); // noop
|
||||
});
|
79
src/reducer.ts
Normal file
79
src/reducer.ts
Normal file
@ -0,0 +1,79 @@
|
||||
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;
|
||||
*/
|
||||
}
|
Loading…
Reference in New Issue
Block a user