add subdux actions
This commit is contained in:
parent
d304fc0fcc
commit
5e39c2b162
21
src/Updux.ts
21
src/Updux.ts
@ -1,3 +1,4 @@
|
|||||||
|
import * as R from 'remeda';
|
||||||
import {
|
import {
|
||||||
createStore as reduxCreateStore,
|
createStore as reduxCreateStore,
|
||||||
applyMiddleware,
|
applyMiddleware,
|
||||||
@ -5,7 +6,8 @@ import {
|
|||||||
Action,
|
Action,
|
||||||
} from 'redux';
|
} from 'redux';
|
||||||
import { configureStore, Reducer, createAction } from '@reduxjs/toolkit';
|
import { configureStore, Reducer, createAction } from '@reduxjs/toolkit';
|
||||||
import { withPayload } from './actions';
|
import { withPayload } from './actions.js';
|
||||||
|
import { AggregateActions, Dux, UnionToIntersection } from './types.js';
|
||||||
|
|
||||||
type ActionCreator = ReturnType<typeof createAction>;
|
type ActionCreator = ReturnType<typeof createAction>;
|
||||||
|
|
||||||
@ -20,6 +22,7 @@ type Mutation<A extends ActionCreator = ActionCreator, S = any> = (
|
|||||||
export default class Updux<
|
export default class Updux<
|
||||||
T_LocalState = Record<any, any>,
|
T_LocalState = Record<any, any>,
|
||||||
T_LocalActions = {},
|
T_LocalActions = {},
|
||||||
|
SUBDUXES extends Record<string, Dux> = {},
|
||||||
> {
|
> {
|
||||||
#localInitial: T_LocalState;
|
#localInitial: T_LocalState;
|
||||||
#localActions: T_LocalActions;
|
#localActions: T_LocalActions;
|
||||||
@ -27,16 +30,28 @@ export default class Updux<
|
|||||||
string,
|
string,
|
||||||
Mutation<ActionCreator, AggregateState<T_LocalState>>
|
Mutation<ActionCreator, AggregateState<T_LocalState>>
|
||||||
> = {};
|
> = {};
|
||||||
|
#subduxes: SUBDUXES;
|
||||||
|
|
||||||
|
#actions: Record<string, ActionCreator>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: Partial<{
|
config: Partial<{
|
||||||
initial: T_LocalState;
|
initial: T_LocalState;
|
||||||
actions: T_LocalActions;
|
actions: T_LocalActions;
|
||||||
|
subduxes: SUBDUXES;
|
||||||
}>,
|
}>,
|
||||||
) {
|
) {
|
||||||
// TODO check that we can't alter the initial after the fact
|
// TODO check that we can't alter the initial after the fact
|
||||||
this.#localInitial = config.initial ?? ({} as T_LocalState);
|
this.#localInitial = config.initial ?? ({} as T_LocalState);
|
||||||
this.#localActions = config.actions ?? ({} as T_LocalActions);
|
this.#localActions = config.actions ?? ({} as T_LocalActions);
|
||||||
|
this.#subduxes = config.subduxes ?? ({} as SUBDUXES);
|
||||||
|
}
|
||||||
|
|
||||||
|
get actions(): AggregateActions<T_LocalActions, SUBDUXES> {
|
||||||
|
return R.mergeAll([
|
||||||
|
this.#localActions,
|
||||||
|
...Object.values(this.#subduxes).map(R.pathOr(['actions'], {})),
|
||||||
|
]) as any;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO memoize?
|
// TODO memoize?
|
||||||
@ -44,10 +59,6 @@ export default class Updux<
|
|||||||
return this.#localInitial;
|
return this.#localInitial;
|
||||||
}
|
}
|
||||||
|
|
||||||
get actions() {
|
|
||||||
return this.#localActions;
|
|
||||||
}
|
|
||||||
|
|
||||||
createStore(
|
createStore(
|
||||||
options: Partial<{
|
options: Partial<{
|
||||||
initial: T_LocalState;
|
initial: T_LocalState;
|
||||||
|
@ -34,23 +34,6 @@ test('Updux config accepts actions', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('subduxes actions', () => {
|
|
||||||
const foo = new Updux({
|
|
||||||
actions: {
|
|
||||||
foo: null,
|
|
||||||
},
|
|
||||||
subduxes: {
|
|
||||||
beta: {
|
|
||||||
actions: {
|
|
||||||
bar: null,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(foo.actions).toHaveProperty('foo');
|
|
||||||
expect(foo.actions).toHaveProperty('bar');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('throw if double action', () => {
|
test('throw if double action', () => {
|
||||||
expect(
|
expect(
|
||||||
|
27
src/actions.test.ts
Normal file
27
src/actions.test.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import Updux, { createAction } from './index.js';
|
||||||
|
|
||||||
|
test('subduxes actions', () => {
|
||||||
|
const bar = createAction<number>('bar');
|
||||||
|
const baz = createAction('baz');
|
||||||
|
|
||||||
|
const foo = new Updux({
|
||||||
|
actions: {
|
||||||
|
bar,
|
||||||
|
},
|
||||||
|
subduxes: {
|
||||||
|
beta: {
|
||||||
|
actions: {
|
||||||
|
baz,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// to check if we can deal with empty actions
|
||||||
|
gamma: {},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(foo.actions).toHaveProperty('bar');
|
||||||
|
expect(foo.actions).toHaveProperty('baz');
|
||||||
|
|
||||||
|
expect(foo.actions.bar(2)).toHaveProperty('type', 'bar');
|
||||||
|
expect(foo.actions.baz()).toHaveProperty('type', 'baz');
|
||||||
|
});
|
@ -1,5 +1,7 @@
|
|||||||
|
import { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
export { createAction } from '@reduxjs/toolkit';
|
export { createAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
export const withPayload =
|
export const withPayload =
|
||||||
<P>() =>
|
<P>() =>
|
||||||
(payload: P) => ({ payload });
|
(payload: P) => ({ payload });
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import Updux from './Updux';
|
import Updux from './Updux.js';
|
||||||
|
|
||||||
export { withPayload, createAction } from './actions';
|
export { withPayload, createAction } from './actions.js';
|
||||||
|
|
||||||
export default Updux;
|
export default Updux;
|
||||||
|
21
src/types.ts
Normal file
21
src/types.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { Action, ActionCreator } from 'redux';
|
||||||
|
|
||||||
|
export type Dux<
|
||||||
|
STATE = any,
|
||||||
|
ACTIONS extends Record<string, ActionCreator<string>> = {},
|
||||||
|
> = Partial<{
|
||||||
|
initial: STATE;
|
||||||
|
actions: ACTIONS;
|
||||||
|
}>;
|
||||||
|
|
||||||
|
type ActionsOf<DUX> = DUX extends { actions: infer A } ? A : {};
|
||||||
|
|
||||||
|
export type AggregateActions<A, S> = UnionToIntersection<
|
||||||
|
ActionsOf<S[keyof S]> | A
|
||||||
|
>;
|
||||||
|
|
||||||
|
export type UnionToIntersection<U> = (
|
||||||
|
U extends any ? (k: U) => void : never
|
||||||
|
) extends (k: infer I) => void
|
||||||
|
? I
|
||||||
|
: never;
|
Loading…
Reference in New Issue
Block a user