beginning on selectors
This commit is contained in:
parent
3e9049ce93
commit
c660b7be1d
35
src/Updux.ts
35
src/Updux.ts
@ -26,10 +26,10 @@ type ResolveAction<
|
||||
? ActionArg
|
||||
: ActionArg extends (...args: any) => any
|
||||
? ActionCreatorWithPreparedPayload<
|
||||
Parameters<ActionArg>,
|
||||
ReturnType<ActionArg>,
|
||||
ActionType
|
||||
>
|
||||
Parameters<ActionArg>,
|
||||
ReturnType<ActionArg>,
|
||||
ActionType
|
||||
>
|
||||
: ActionCreatorWithoutPayload<ActionType>;
|
||||
|
||||
type ResolveActions<
|
||||
@ -37,10 +37,10 @@ type ResolveActions<
|
||||
[key: string]: any;
|
||||
},
|
||||
> = {
|
||||
[ActionType in keyof A]: ActionType extends string
|
||||
[ActionType in keyof A]: ActionType extends string
|
||||
? ResolveAction<ActionType, A[ActionType]>
|
||||
: never;
|
||||
};
|
||||
};
|
||||
|
||||
export type Mutation<A extends Action<any> = Action<any>, S = any> = (
|
||||
payload: A extends {
|
||||
@ -51,12 +51,22 @@ export type Mutation<A extends Action<any> = Action<any>, S = any> = (
|
||||
action: A,
|
||||
) => (state: S) => S | void;
|
||||
|
||||
export type AggregateSelectors<S> = S;
|
||||
|
||||
type SelectorForState<S> = (state: S) => unknown;
|
||||
type SelectorsForState<S> = {
|
||||
[key: string]: SelectorForState<S>;
|
||||
};
|
||||
|
||||
export default class Updux<
|
||||
T_LocalState = Record<any, any>,
|
||||
T_LocalActions extends {
|
||||
[actionType: string]: any;
|
||||
} = {},
|
||||
T_Subduxes extends Record<string, Dux> = {},
|
||||
T_LocalSelectors extends SelectorsForState<
|
||||
AggregateState<T_LocalState, T_Subduxes>
|
||||
> = {},
|
||||
> {
|
||||
#localInitial: T_LocalState;
|
||||
#localActions: T_LocalActions;
|
||||
@ -70,11 +80,19 @@ export default class Updux<
|
||||
|
||||
#initial: AggregateState<T_LocalState, T_Subduxes>;
|
||||
|
||||
#localSelectors: Record<
|
||||
string,
|
||||
(state: AggregateState<T_LocalState, T_Subduxes>) => any
|
||||
>;
|
||||
|
||||
#selectors: AggregateSelectors<T_LocalSelectors>;
|
||||
|
||||
constructor(
|
||||
config: Partial<{
|
||||
initial: T_LocalState;
|
||||
actions: T_LocalActions;
|
||||
subduxes: T_Subduxes;
|
||||
selectors: T_LocalSelectors;
|
||||
}>,
|
||||
) {
|
||||
// TODO check that we can't alter the initial after the fact
|
||||
@ -85,6 +103,7 @@ export default class Updux<
|
||||
this.#actions = buildActions(this.#localActions, this.#subduxes);
|
||||
|
||||
this.#initial = buildInitial(this.#localInitial, this.#subduxes);
|
||||
this.#localSelectors = config.selectors;
|
||||
}
|
||||
|
||||
get actions() {
|
||||
@ -110,6 +129,10 @@ export default class Updux<
|
||||
return store;
|
||||
}
|
||||
|
||||
get selectors(): T_LocalSelectors {
|
||||
return this.#localSelectors as any;
|
||||
}
|
||||
|
||||
// TODO memoize this sucker
|
||||
get reducer() {
|
||||
return buildReducer(
|
||||
|
27
src/selectors.test.ts
Normal file
27
src/selectors.test.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import { test, expect } from 'vitest';
|
||||
|
||||
import Updux, { createAction } from './index.js';
|
||||
|
||||
test('basic selectors', () => {
|
||||
type State = { x: number };
|
||||
|
||||
const foo = new Updux({
|
||||
initial: {
|
||||
x: 1,
|
||||
},
|
||||
selectors: {
|
||||
getX: ({ x }: State) => x,
|
||||
},
|
||||
subduxes: {
|
||||
bar: new Updux({
|
||||
initial: { y: 2 },
|
||||
selectors: {
|
||||
getY: ({ y }: { y: number }) => y,
|
||||
},
|
||||
}),
|
||||
},
|
||||
});
|
||||
|
||||
expect(foo.selectors.getY({ bar: { y: 3 } } as typeof foo.initial)).toBe(3);
|
||||
expect(foo.selectors.getX({ x: 4 } as typeof foo.initial)).toBe(4);
|
||||
});
|
Loading…
Reference in New Issue
Block a user