add sink mutations
This commit is contained in:
parent
73973a9588
commit
0e03628502
@ -12,7 +12,7 @@ type SubMutations = {
|
||||
}
|
||||
|
||||
function buildMutations(
|
||||
mutations :Dictionary<Mutation> = {},
|
||||
mutations :Dictionary<Mutation|([Mutation,boolean|undefined])> = {},
|
||||
subduxes = {}
|
||||
) {
|
||||
// we have to differentiate the subduxes with '*' than those
|
||||
@ -49,15 +49,26 @@ function buildMutations(
|
||||
|
||||
nonGlobby.forEach(([slice, {mutations = {}, reducer = {}}]:any[]) => {
|
||||
Object.entries(mutations).forEach(([type, mutation]) => {
|
||||
const localized = (payload = null, action :Action) =>
|
||||
u.updateIn(slice)((mutation as Mutation)(payload, action));
|
||||
const localized = (payload = null, action :Action) => {
|
||||
console.log(slice);
|
||||
|
||||
return u.updateIn(slice)((mutation as Mutation)(payload, action));
|
||||
}
|
||||
|
||||
mergedMutations[type].push(localized);
|
||||
});
|
||||
});
|
||||
|
||||
Object.entries(mutations).forEach(([type, mutation]) => {
|
||||
mergedMutations[type].push(mutation);
|
||||
if ( Array.isArray(mutation) ) {
|
||||
if( mutation[1] ) {
|
||||
mergedMutations[type] = [
|
||||
mutation[0]
|
||||
]
|
||||
}
|
||||
else mergedMutations[type].push( mutation[0] );
|
||||
}
|
||||
else mergedMutations[type].push(mutation);
|
||||
});
|
||||
|
||||
return fp.mapValues(composeMutations)(mergedMutations);
|
||||
|
39
src/sink.test.ts
Normal file
39
src/sink.test.ts
Normal file
@ -0,0 +1,39 @@
|
||||
import Updux from './updux';
|
||||
|
||||
const foo = new Updux<number>({
|
||||
initial: 0,
|
||||
mutations: {
|
||||
doIt: () => (state: number) => {
|
||||
console.log(state);
|
||||
return state + 1;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
const bar = new Updux<{foo: number}>({
|
||||
subduxes: {foo},
|
||||
mutations: {
|
||||
doIt: () => (state: any) => state,
|
||||
},
|
||||
});
|
||||
|
||||
bar.addMutation(
|
||||
foo.actions.doIt,
|
||||
() => (state: any) => ({...state, bar: 'yay'}),
|
||||
true,
|
||||
);
|
||||
|
||||
test('initial', () => {
|
||||
expect(bar.initial).toEqual({foo: 0});
|
||||
});
|
||||
|
||||
test('foo alone', () => {
|
||||
expect(foo.reducer(undefined, foo.actions.doIt())).toEqual(1);
|
||||
});
|
||||
|
||||
test('sink mutations', () => {
|
||||
expect(bar.reducer(undefined, bar.actions.doIt())).toEqual({
|
||||
foo: 0,
|
||||
bar: 'yay',
|
||||
});
|
||||
});
|
96
src/updux.ts
96
src/updux.ts
@ -42,12 +42,12 @@ export type Dux<S> = Pick<
|
||||
>;
|
||||
|
||||
/**
|
||||
* `Updux` is a way to minimize and simplify the boilerplate associated with the
|
||||
* creation of a `Redux` store. It takes a shorthand configuration
|
||||
* object, and generates the appropriate reducer, actions, middleware, etc.
|
||||
* In true `Redux`-like fashion, upduxes can be made of sub-upduxes (`subduxes` for short) for different slices of the root state.
|
||||
* @typeparam S Store's state type. Defaults to `any`.
|
||||
*/
|
||||
* `Updux` is a way to minimize and simplify the boilerplate associated with the
|
||||
* creation of a `Redux` store. It takes a shorthand configuration
|
||||
* object, and generates the appropriate reducer, actions, middleware, etc.
|
||||
* In true `Redux`-like fashion, upduxes can be made of sub-upduxes (`subduxes` for short) for different slices of the root state.
|
||||
* @typeparam S Store's state type. Defaults to `any`.
|
||||
*/
|
||||
export class Updux<S = any> {
|
||||
subduxes: Dictionary<Updux>;
|
||||
|
||||
@ -60,41 +60,41 @@ export class Updux<S = any> {
|
||||
*/
|
||||
initial: S;
|
||||
|
||||
/**
|
||||
* Function that can be provided to alter all local mutations of the updux
|
||||
* (the mutations of subduxes are left untouched).
|
||||
*
|
||||
* Can be used, for example, for Immer integration:
|
||||
*
|
||||
* ```
|
||||
* import Updux from 'updux';
|
||||
* import { produce } from 'Immer';
|
||||
*
|
||||
* const updux = new Updux({
|
||||
* initial: { counter: 0 },
|
||||
* groomMutations: mutation => (...args) => produce( mutation(...args) ),
|
||||
* mutations: {
|
||||
* add: (inc=1) => draft => draft.counter += inc
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* Or perhaps for debugging:
|
||||
*
|
||||
* ```
|
||||
* import Updux from 'updux';
|
||||
*
|
||||
* const updux = new Updux({
|
||||
* initial: { counter: 0 },
|
||||
* groomMutations: mutation => (...args) => state => {
|
||||
* console.log( "got action ", args[1] );
|
||||
* return mutation(...args)(state);
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
/**
|
||||
* Function that can be provided to alter all local mutations of the updux
|
||||
* (the mutations of subduxes are left untouched).
|
||||
*
|
||||
* Can be used, for example, for Immer integration:
|
||||
*
|
||||
* ```
|
||||
* import Updux from 'updux';
|
||||
* import { produce } from 'Immer';
|
||||
*
|
||||
* const updux = new Updux({
|
||||
* initial: { counter: 0 },
|
||||
* groomMutations: mutation => (...args) => produce( mutation(...args) ),
|
||||
* mutations: {
|
||||
* add: (inc=1) => draft => draft.counter += inc
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* ```
|
||||
*
|
||||
* Or perhaps for debugging:
|
||||
*
|
||||
* ```
|
||||
* import Updux from 'updux';
|
||||
*
|
||||
* const updux = new Updux({
|
||||
* initial: { counter: 0 },
|
||||
* groomMutations: mutation => (...args) => state => {
|
||||
* console.log( "got action ", args[1] );
|
||||
* return mutation(...args)(state);
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* ```
|
||||
*/
|
||||
groomMutations: (mutation: Mutation<S>) => Mutation<S>;
|
||||
|
||||
@observable private localEffects: Dictionary<
|
||||
@ -103,7 +103,9 @@ export class Updux<S = any> {
|
||||
|
||||
@observable private localActions: Dictionary<ActionCreator>;
|
||||
|
||||
@observable private localMutations: Dictionary<Mutation<S>>;
|
||||
@observable private localMutations: Dictionary<
|
||||
Mutation<S> | [Mutation<S>, boolean | undefined]
|
||||
>;
|
||||
|
||||
constructor(config: UpduxConfig = {}) {
|
||||
this.groomMutations = config.groomMutations || ((x: Mutation<S>) => x);
|
||||
@ -245,6 +247,8 @@ export class Updux<S = any> {
|
||||
* Adds a mutation and its associated action to the updux.
|
||||
* If a local mutation was already associated to the action,
|
||||
* it will be replaced by the new one.
|
||||
* @param isSink
|
||||
* If `true`, disables the subduxes mutations for this action.
|
||||
* @example
|
||||
* ```
|
||||
* updux.addMutation( add, inc => state => state + inc );
|
||||
@ -253,11 +257,13 @@ export class Updux<S = any> {
|
||||
addMutation<A extends ActionCreator>(
|
||||
creator: A,
|
||||
mutation: Mutation<S, A extends (...args: any[]) => infer R ? R : never>,
|
||||
isSink?: boolean,
|
||||
) {
|
||||
this.localActions[creator.type] = creator;
|
||||
this.localMutations[creator.type] = this.groomMutations(
|
||||
mutation as any,
|
||||
) as Mutation<S>;
|
||||
this.localMutations[creator.type] = [
|
||||
this.groomMutations(mutation as any) as Mutation<S>,
|
||||
isSink,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user