beginning on selectors

This commit is contained in:
Yanick Champoux 2023-03-10 10:31:30 -05:00
parent 3e9049ce93
commit c660b7be1d
2 changed files with 56 additions and 6 deletions

View File

@ -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
View 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);
});