rename initial as initialState

This commit is contained in:
Yanick Champoux 2023-03-23 18:15:32 -04:00
parent a9cb408521
commit 5ff07b2e2f
18 changed files with 95 additions and 94 deletions

View File

@ -36,10 +36,10 @@ export interface UpduxConfig<
TSubduxes = {} TSubduxes = {}
> { > {
/** /**
* Local initial state. * Local initialState state.
* @default {} * @default {}
*/ */
initial?: TState; initialState?: TState;
/** /**
* Subduxes to be merged to this dux. * Subduxes to be merged to this dux.
@ -116,7 +116,7 @@ export class Updux<
TSubduxes extends object = {} TSubduxes extends object = {}
> { > {
/** @type { unknown } */ /** @type { unknown } */
#initial = {}; #initialState = {};
#subduxes = {}; #subduxes = {};
/** @type Record<string,Function> */ /** @type Record<string,Function> */
@ -134,7 +134,7 @@ export class Updux<
constructor( constructor(
config: UpduxConfig<TState, TActions, TSelectors, TSubduxes> config: UpduxConfig<TState, TActions, TSelectors, TSubduxes>
) { ) {
this.#initial = config.initial ?? {}; this.#initialState = config.initialState ?? {};
this.#subduxes = config.subduxes ?? {}; this.#subduxes = config.subduxes ?? {};
if (config.subduxes) { if (config.subduxes) {
@ -210,8 +210,8 @@ export class Updux<
} }
/** @member { unknown } */ /** @member { unknown } */
get initial(): AggregateDuxState<TState, TSubduxes> { get initialState(): AggregateDuxState<TState, TSubduxes> {
return this.#memoInitial(this.#initial, this.#subduxes); return this.#memoInitial(this.#initialState, this.#subduxes);
} }
get actions(): AggregateDuxActions<TActions, TSubduxes> { get actions(): AggregateDuxActions<TActions, TSubduxes> {
@ -233,7 +233,7 @@ export class Updux<
ItemsOf<AggregateDuxActions<TActions, TSubduxes>> ItemsOf<AggregateDuxActions<TActions, TSubduxes>>
> { > {
return this.#memoUpreducer( return this.#memoUpreducer(
this.initial, this.initialState,
this.#mutations, this.#mutations,
this.#subduxes, this.#subduxes,
this.#upreducerWrapper this.#upreducerWrapper
@ -407,7 +407,7 @@ export class Updux<
}; };
} }
createStore(initial?: unknown, enhancerGenerator?: Function) { createStore(initialState?: unknown, enhancerGenerator?: Function) {
const enhancer = (enhancerGenerator ?? applyMiddleware)( const enhancer = (enhancerGenerator ?? applyMiddleware)(
this.middleware this.middleware
); );
@ -419,7 +419,7 @@ export class Updux<
actions: AggregateDuxActions<TActions, TSubduxes>; actions: AggregateDuxActions<TActions, TSubduxes>;
} = reduxCreateStore( } = reduxCreateStore(
this.reducer as any, this.reducer as any,
initial ?? this.initial, initialState ?? this.initialState,
enhancer enhancer
) as any; ) as any;

View File

@ -3,7 +3,7 @@ import Updux from './Updux';
test('subdux idempotency', () => { test('subdux idempotency', () => {
// const c = new Updux({ // const c = new Updux({
// initial: 2, // initialState: 2,
// }); // });
// const b = new Updux({ // const b = new Updux({
// subduxes: { // subduxes: {
@ -12,7 +12,7 @@ test('subdux idempotency', () => {
// }); // });
const foo = new Updux({ const foo = new Updux({
subduxes: { subduxes: {
a: new Updux({ initial: 2 }), a: new Updux({ initialState: 2 }),
}, },
}); });

View File

@ -35,7 +35,7 @@ export class Updux {
this.#middlewareWrapper = config.middlewareWrapper; this.#middlewareWrapper = config.middlewareWrapper;
this.#localInitial = config.initial; this.#localInitial = config.initialState;
this.#subduxes = config.subduxes ?? {}; this.#subduxes = config.subduxes ?? {};
this.#actions = R.mapValues(config.actions ?? {}, (arg, name) => this.#actions = R.mapValues(config.actions ?? {}, (arg, name) =>
@ -89,7 +89,7 @@ export class Updux {
return this.#actions; return this.#actions;
} }
get initial() { get initialState() {
if (Object.keys(this.#subduxes).length === 0) if (Object.keys(this.#subduxes).length === 0)
return this.#localInitial ?? {}; return this.#localInitial ?? {};
@ -101,7 +101,7 @@ export class Updux {
return Object.assign( return Object.assign(
{}, {},
this.#localInitial ?? {}, this.#localInitial ?? {},
R.mapValues(this.#subduxes, ({ initial }) => initial), R.mapValues(this.#subduxes, ({ initialState }) => initialState),
); );
} }
@ -167,14 +167,14 @@ export class Updux {
); );
} }
createStore(initial = undefined, enhancerGenerator = undefined) { createStore(initialState = undefined, enhancerGenerator = undefined) {
const enhancer = (enhancerGenerator ?? applyMiddleware)( const enhancer = (enhancerGenerator ?? applyMiddleware)(
this.middleware, this.middleware,
); );
const store = reduxCreateStore( const store = reduxCreateStore(
this.reducer, this.reducer,
initial ?? this.initial, initialState ?? this.initialState,
enhancer, enhancer,
); );
@ -256,7 +256,7 @@ export class Updux {
delete gone[key]; delete gone[key];
} else { } else {
const dux = new Updux({ const dux = new Updux({
initial: null, initialState: null,
actions: { update: null }, actions: { update: null },
mutations: { mutations: {
update: (payload) => () => payload, update: (payload) => () => payload,

View File

@ -100,7 +100,7 @@ export default class Updux<
#actions: AggregateActions<ResolveActions<T_LocalActions>, T_Subduxes>; #actions: AggregateActions<ResolveActions<T_LocalActions>, T_Subduxes>;
#initial: AggregateState<T_LocalState, T_Subduxes>; #initialState: AggregateState<T_LocalState, T_Subduxes>;
#localSelectors: Record< #localSelectors: Record<
string, string,
@ -112,20 +112,20 @@ export default class Updux<
constructor( constructor(
config: Partial<{ config: Partial<{
initial: T_LocalState; initialState: T_LocalState;
actions: T_LocalActions; actions: T_LocalActions;
subduxes: T_Subduxes; subduxes: T_Subduxes;
selectors: T_LocalSelectors; selectors: T_LocalSelectors;
}>, }>,
) { ) {
// TODO check that we can't alter the initial after the fact // TODO check that we can't alter the initialState after the fact
this.#localInitial = config.initial ?? ({} as T_LocalState); this.#localInitial = config.initialState ?? ({} as T_LocalState);
this.#localActions = config.actions ?? ({} as T_LocalActions); this.#localActions = config.actions ?? ({} as T_LocalActions);
this.#subduxes = config.subduxes ?? ({} as T_Subduxes); this.#subduxes = config.subduxes ?? ({} as T_Subduxes);
this.#actions = buildActions(this.#localActions, this.#subduxes); this.#actions = buildActions(this.#localActions, this.#subduxes);
this.#initial = buildInitial(this.#localInitial, this.#subduxes); this.#initialState = buildInitial(this.#localInitial, this.#subduxes);
this.#localSelectors = config.selectors; this.#localSelectors = config.selectors;
const basedSelectors = R.mergeAll( const basedSelectors = R.mergeAll(
@ -144,8 +144,8 @@ export default class Updux<
} }
// TODO memoize? // TODO memoize?
get initial() { get initialState() {
return this.#initial; return this.#initialState;
} }
get effects() { get effects() {
@ -178,10 +178,10 @@ export default class Updux<
createStore( createStore(
options: Partial<{ options: Partial<{
initial: T_LocalState; initialState: T_LocalState;
}> = {}, }> = {},
) { ) {
const preloadedState: any = options.initial ?? this.initial; const preloadedState: any = options.initialState ?? this.initialState;
const effects = buildEffectsMiddleware( const effects = buildEffectsMiddleware(
this.effects, this.effects,
@ -246,14 +246,14 @@ export default class Updux<
// TODO memoize this sucker // TODO memoize this sucker
get reducer() { get reducer() {
return buildReducer( return buildReducer(
this.initial, this.initialState,
this.#localMutations, this.#localMutations,
this.#defaultMutation, this.#defaultMutation,
this.#subduxes, this.#subduxes,
) as any as ( ) as any as (
state: undefined | typeof this.initial, state: undefined | typeof this.initialState,
action: Action, action: Action,
) => typeof this.initial; ) => typeof this.initialState;
} }
// TODO be smarter with the guard? // TODO be smarter with the guard?

View File

@ -14,6 +14,7 @@ export const withPayload: WithPayload = ((prepare) =>
payload: prepare ? prepare(...input) : input[0], payload: prepare ? prepare(...input) : input[0],
})) as any; })) as any;
const id = (x) => x;
export const createPayloadAction = < export const createPayloadAction = <
P extends any = any, P extends any = any,
T extends string = string, T extends string = string,

View File

@ -5,7 +5,7 @@ test('basic', () => {
expect( expect(
buildInitial( buildInitial(
{ a: 1 }, { a: 1 },
{ b: { initial: { c: 2 } }, d: { initial: 'e' } }, { b: { initialState: { c: 2 } }, d: { initialState: 'e' } },
), ),
).toEqual({ ).toEqual({
a: 1, a: 1,
@ -14,7 +14,7 @@ test('basic', () => {
}); });
}); });
test('throw if subduxes and initial is not an object', () => { test('throw if subduxes and initialState is not an object', () => {
expect(() => { expect(() => {
buildInitial(3, { bar: 'foo' }); buildInitial(3, { bar: 'foo' });
}).toThrow(); }).toThrow();

View File

@ -6,7 +6,7 @@ import { matches } from './utils.js';
test('basic selectors', () => { test('basic selectors', () => {
const foo = dux({ const foo = dux({
initial: { initialState: {
x: 1, x: 1,
}, },
selectors: { selectors: {
@ -14,7 +14,7 @@ test('basic selectors', () => {
}, },
subduxes: { subduxes: {
bar: { bar: {
initial: { y: 2 }, initialState: { y: 2 },
selectors: { selectors: {
getY: ({ y }) => y, getY: ({ y }) => y,
}, },
@ -27,7 +27,7 @@ test('basic selectors', () => {
test('splat selector', async () => { test('splat selector', async () => {
const bar = new Updux({ const bar = new Updux({
initial: { id: 0, label: '' }, initialState: { id: 0, label: '' },
selectors: { selectors: {
getLabel: R.prop('label'), getLabel: R.prop('label'),
getLabelAppended: (state) => (suffix) => state.label + ' ' + suffix, getLabelAppended: (state) => (suffix) => state.label + ' ' + suffix,
@ -35,7 +35,7 @@ test('splat selector', async () => {
}); });
const foo = new Updux({ const foo = new Updux({
initial: [], initialState: [],
findSelectors: { findSelectors: {
getBar: (state) => (id) => { getBar: (state) => (id) => {
return state.find(matches({ id })); return state.find(matches({ id }));

View File

@ -48,7 +48,7 @@ test('buildEffectsMiddleware', () => {
test('basic', () => { test('basic', () => {
const dux = new Updux({ const dux = new Updux({
initial: { initialState: {
loaded: true, loaded: true,
}, },
actions: { actions: {
@ -77,7 +77,7 @@ test('basic', () => {
test('subdux', () => { test('subdux', () => {
const bar = new Updux({ const bar = new Updux({
initial: 'bar state', initialState: 'bar state',
actions: { foo: 0 }, actions: { foo: 0 },
}); });
@ -89,7 +89,7 @@ test('subdux', () => {
}); });
const dux = new Updux({ const dux = new Updux({
initial: { initialState: {
loaded: true, loaded: true,
}, },
subduxes: { subduxes: {

View File

@ -1,40 +1,40 @@
import { expectType } from './tutorial.test.js'; import { expectType } from './tutorial.test.js';
import Updux from './Updux.js'; import Updux from './Updux.js';
const bar = new Updux({ initial: 123 }); const bar = new Updux({ initialState: 123 });
const foo = new Updux({ const foo = new Updux({
initial: { root: 'abc' }, initialState: { root: 'abc' },
subduxes: { subduxes: {
bar, bar,
}, },
}); });
test('default', () => { test('default', () => {
const { initial } = new Updux({}); const { initialState } = new Updux({});
expect(initial).toBeTypeOf('object'); expect(initialState).toBeTypeOf('object');
expect(initial).toEqual({}); expect(initialState).toEqual({});
}); });
test('number', () => { test('number', () => {
const { initial } = new Updux({ initial: 3 }); const { initialState } = new Updux({ initialState: 3 });
expect(initial).toBeTypeOf('number'); expect(initialState).toBeTypeOf('number');
expect(initial).toEqual(3); expect(initialState).toEqual(3);
}); });
test('initial to createStore', () => { test('initialState to createStore', () => {
const initial = { const initialState = {
a: 1, a: 1,
b: 2, b: 2,
}; };
const dux = new Updux({ const dux = new Updux({
initial, initialState,
}); });
expect(dux.createStore({ initial: { a: 3, b: 4 } }).getState()).toEqual({ expect(dux.createStore({ initialState: { a: 3, b: 4 } }).getState()).toEqual({
a: 3, a: 3,
b: 4, b: 4,
}); });
@ -42,15 +42,15 @@ test('initial to createStore', () => {
test('single dux', () => { test('single dux', () => {
const foo = new Updux({ const foo = new Updux({
initial: { a: 1 }, initialState: { a: 1 },
}); });
expect(foo.initial).toEqual({ a: 1 }); expect(foo.initialState).toEqual({ a: 1 });
}); });
// TODO add 'check for no todo eslint rule' // TODO add 'check for no todo eslint rule'
test('initial value', () => { test('initialState value', () => {
expect(foo.initial).toEqual({ expect(foo.initialState).toEqual({
root: 'abc', root: 'abc',
bar: 123, bar: 123,
}); });
@ -58,41 +58,41 @@ test('initial value', () => {
expectType<{ expectType<{
root: string; root: string;
bar: number; bar: number;
}>(foo.initial); }>(foo.initialState);
}); });
test('no initial', () => { test('no initialState', () => {
const dux = new Updux({}); const dux = new Updux({});
expectType<{}>(dux.initial); expectType<{}>(dux.initialState);
expect(dux.initial).toEqual({}); expect(dux.initialState).toEqual({});
}); });
test('no initial for subdux', () => { test('no initialState for subdux', () => {
const dux = new Updux({ const dux = new Updux({
subduxes: { subduxes: {
bar: new Updux({}), bar: new Updux({}),
baz: new Updux({ initial: 'potato' }), baz: new Updux({ initialState: 'potato' }),
}, },
}); });
expectType<{ bar: {}; baz: string }>(dux.initial); expectType<{ bar: {}; baz: string }>(dux.initialState);
expect(dux.initial).toEqual({ bar: {}, baz: 'potato' }); expect(dux.initialState).toEqual({ bar: {}, baz: 'potato' });
}); });
test.todo('splat initial', async () => { test.todo('splat initialState', async () => {
const bar = new Updux({ const bar = new Updux({
initial: { id: 0 }, initialState: { id: 0 },
}); });
const foo = new Updux({ const foo = new Updux({
subduxes: { '*': bar }, subduxes: { '*': bar },
}); });
expect(foo.initial).toEqual([]); expect(foo.initialState).toEqual([]);
expect( expect(
new Updux({ new Updux({
initial: 'overriden', initialState: 'overriden',
subduxes: { '*': bar }, subduxes: { '*': bar },
}).initial, }).initialState,
).toEqual('overriden'); ).toEqual('overriden');
}); });

View File

@ -1,7 +1,7 @@
import u from '@yanick/updeep-remeda'; import u from '@yanick/updeep-remeda';
import * as R from 'remeda'; import * as R from 'remeda';
type SubduxState<S> = 'initial' extends keyof S ? S['initial'] : {}; type SubduxState<S> = 'initialState' extends keyof S ? S['initialState'] : {};
export type AggregateState<LOCAL, SUBDUXES extends Record<any, any>> = LOCAL & export type AggregateState<LOCAL, SUBDUXES extends Record<any, any>> = LOCAL &
(keyof SUBDUXES extends never (keyof SUBDUXES extends never
@ -15,9 +15,9 @@ export type AggregateState<LOCAL, SUBDUXES extends Record<any, any>> = LOCAL &
export function buildInitial(localInitial, subduxes) { export function buildInitial(localInitial, subduxes) {
if (Object.keys(subduxes).length > 0 && typeof localInitial !== 'object') { if (Object.keys(subduxes).length > 0 && typeof localInitial !== 'object') {
throw new Error( throw new Error(
"can't have subduxes when the initial value is not an object", "can't have subduxes when the initialState value is not an object",
); );
} }
return u(localInitial, R.mapValues(subduxes, R.pathOr(['initial'], {}))); return u(localInitial, R.mapValues(subduxes, R.pathOr(['initialState'], {})));
} }

View File

@ -4,7 +4,7 @@ import Updux, { createAction } from './index.js';
test('set a mutation', () => { test('set a mutation', () => {
const dux = new Updux({ const dux = new Updux({
initial: 'potato', initialState: 'potato',
actions: { actions: {
foo: (x) => ({ x }), foo: (x) => ({ x }),
bar: 0, bar: 0,
@ -27,7 +27,7 @@ test('set a mutation', () => {
test('catch-all mutation', () => { test('catch-all mutation', () => {
const dux = new Updux({ const dux = new Updux({
initial: '', initialState: '',
}); });
dux.addMutation( dux.addMutation(
@ -40,7 +40,7 @@ test('catch-all mutation', () => {
test('default mutation', () => { test('default mutation', () => {
const dux = new Updux({ const dux = new Updux({
initial: '', initialState: '',
actions: { actions: {
foo: 0, foo: 0,
}, },
@ -60,7 +60,7 @@ test('mutation of a subdux', () => {
const stopit = createAction('stopit'); const stopit = createAction('stopit');
const bar = new Updux({ const bar = new Updux({
initial: 0, initialState: 0,
actions: { actions: {
baz, baz,
stopit, stopit,

View File

@ -3,7 +3,7 @@ import Updux from './index.js';
test('basic reactions', () => { test('basic reactions', () => {
const foo = new Updux({ const foo = new Updux({
initial: 0, initialState: 0,
actions: { inc: 0, reset: 0 }, actions: { inc: 0, reset: 0 },
}); });
@ -39,7 +39,7 @@ test('basic reactions', () => {
test('subdux reactions', () => { test('subdux reactions', () => {
const bar = new Updux({ const bar = new Updux({
initial: 0, initialState: 0,
actions: { inc: 0, reset: 0 }, actions: { inc: 0, reset: 0 },
selectors: { selectors: {
getIt: (x) => x, getIt: (x) => x,

View File

@ -3,7 +3,7 @@ import { test, expect } from 'vitest';
import { buildReducer } from './reducer.js'; import { buildReducer } from './reducer.js';
import Updux from './Updux.js'; import Updux from './Updux.js';
test('buildReducer, initial state', () => { test('buildReducer, initialState state', () => {
const reducer = buildReducer({ a: 1 }); const reducer = buildReducer({ a: 1 });
expect(reducer(undefined, { type: 'foo' })).toEqual({ a: 1 }); expect(reducer(undefined, { type: 'foo' })).toEqual({ a: 1 });
@ -23,7 +23,7 @@ test('buildReducer, mutation', () => {
}); });
test.todo('basic reducer', () => { test.todo('basic reducer', () => {
const dux = new Updux({ initial: { a: 3 } }); const dux = new Updux({ initialState: { a: 3 } });
expect(dux.reducer).toBeTypeOf('function'); expect(dux.reducer).toBeTypeOf('function');

View File

@ -12,7 +12,7 @@ export type MutationCase = {
}; };
export function buildReducer( export function buildReducer(
initialState: any, initialStateState: any,
mutations: MutationCase[] = [], mutations: MutationCase[] = [],
defaultMutation?: Omit<MutationCase, 'matcher'>, defaultMutation?: Omit<MutationCase, 'matcher'>,
subduxes: Record<string, Dux> = {}, subduxes: Record<string, Dux> = {},
@ -22,7 +22,7 @@ export function buildReducer(
// TODO matcherMutation // TODO matcherMutation
// TODO defaultMutation // TODO defaultMutation
// //
const reducer = (state = initialState, action: Action) => { const reducer = (state = initialStateState, action: Action) => {
const orig = state; const orig = state;
if (!action?.type) if (!action?.type)
throw new Error('upreducer called with a bad action'); throw new Error('upreducer called with a bad action');

View File

@ -6,7 +6,7 @@ test('basic selectors', () => {
type State = { x: number }; type State = { x: number };
const foo = new Updux({ const foo = new Updux({
initial: { initialState: {
x: 1, x: 1,
}, },
selectors: { selectors: {
@ -14,7 +14,7 @@ test('basic selectors', () => {
}, },
subduxes: { subduxes: {
bar: new Updux({ bar: new Updux({
initial: { y: 2 }, initialState: { y: 2 },
selectors: { selectors: {
getY: ({ y }: { y: number }) => y, getY: ({ y }: { y: number }) => y,
getYPlus: getYPlus:

View File

@ -9,7 +9,7 @@ const thingReactionSnitch = vi.fn();
const subThing = new Updux({ const subThing = new Updux({
name: 'subThing', name: 'subThing',
initial: 0, initialState: 0,
}); });
subThing.addReaction((api) => (state, previousState, unsubscribe) => { subThing.addReaction((api) => (state, previousState, unsubscribe) => {
@ -18,7 +18,7 @@ subThing.addReaction((api) => (state, previousState, unsubscribe) => {
const thing = new Updux({ const thing = new Updux({
name: 'thing', name: 'thing',
initial: {}, initialState: {},
subduxes: { subduxes: {
'*': subThing, '*': subThing,
}, },
@ -41,11 +41,11 @@ const things = new Updux({
subduxes: { subduxes: {
'*': thing, '*': thing,
}, },
initial: {}, initialState: {},
actions: { newThing: (id) => id }, actions: { newThing: (id) => id },
splatReactionMapper: ({ id }) => id, splatReactionMapper: ({ id }) => id,
mutations: { mutations: {
newThing: (id) => (state) => ({ ...state, [id]: thing.initial }), newThing: (id) => (state) => ({ ...state, [id]: thing.initialState }),
}, },
}); });

View File

@ -3,25 +3,25 @@ import u from '@yanick/updeep-remeda';
export const expectType = <T>(value: T) => value; export const expectType = <T>(value: T) => value;
test('initial state', () => { test('initialState state', () => {
const initial = { const initialState = {
next_id: 1, next_id: 1,
todos: [], todos: [],
}; };
const dux = new Updux({ const dux = new Updux({
initial, initialState,
}); });
expectType<{ expectType<{
next_id: number; next_id: number;
todos: unknown[]; todos: unknown[];
}>(dux.initial); }>(dux.initialState);
expect(dux.initial).toEqual(initial); expect(dux.initialState).toEqual(initialState);
const store = dux.createStore(); const store = dux.createStore();
expect(store.getState()).toEqual(initial); expect(store.getState()).toEqual(initialState);
}); });
test('actions', () => { test('actions', () => {
@ -51,7 +51,7 @@ test('mutation', () => {
}; };
const dux = new Updux({ const dux = new Updux({
initial: { nextId: 0, todos: [] as Todo[] }, initialState: { nextId: 0, todos: [] as Todo[] },
}); });
dux.addMutation(addTodo, (description) => (state) => { dux.addMutation(addTodo, (description) => (state) => {

View File

@ -4,7 +4,7 @@ export type Dux<
STATE = any, STATE = any,
ACTIONS extends Record<string, ActionCreator<string>> = {}, ACTIONS extends Record<string, ActionCreator<string>> = {},
> = Partial<{ > = Partial<{
initial: STATE; initialState: STATE;
actions: ACTIONS; actions: ACTIONS;
selectors: Record<string, (state: STATE) => any>; selectors: Record<string, (state: STATE) => any>;
reducer: ( reducer: (