initial state and subduxes
This commit is contained in:
parent
9ac3032a7f
commit
e9778f98e8
@ -18,6 +18,7 @@ import {
|
|||||||
import { withPayload } from './actions.js';
|
import { withPayload } from './actions.js';
|
||||||
import { AggregateActions, Dux, UnionToIntersection } from './types.js';
|
import { AggregateActions, Dux, UnionToIntersection } from './types.js';
|
||||||
import { buildActions } from './buildActions.js';
|
import { buildActions } from './buildActions.js';
|
||||||
|
import { buildInitial } from './buildInitial.js';
|
||||||
|
|
||||||
type AggregateState<L> = L;
|
type AggregateState<L> = L;
|
||||||
|
|
||||||
@ -73,6 +74,8 @@ export default class Updux<
|
|||||||
|
|
||||||
#actions: AggregateActions<ResolveActions<T_LocalActions>, SUBDUXES>;
|
#actions: AggregateActions<ResolveActions<T_LocalActions>, SUBDUXES>;
|
||||||
|
|
||||||
|
#initial: any;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: Partial<{
|
config: Partial<{
|
||||||
initial: T_LocalState;
|
initial: T_LocalState;
|
||||||
@ -86,6 +89,8 @@ export default class Updux<
|
|||||||
this.#subduxes = config.subduxes ?? ({} as SUBDUXES);
|
this.#subduxes = config.subduxes ?? ({} as SUBDUXES);
|
||||||
|
|
||||||
this.#actions = buildActions(this.#localActions, this.#subduxes);
|
this.#actions = buildActions(this.#localActions, this.#subduxes);
|
||||||
|
|
||||||
|
this.#initial = buildInitial(this.#localInitial, this.#subduxes);
|
||||||
}
|
}
|
||||||
|
|
||||||
get actions() {
|
get actions() {
|
||||||
@ -94,7 +99,7 @@ export default class Updux<
|
|||||||
|
|
||||||
// TODO memoize?
|
// TODO memoize?
|
||||||
get initial() {
|
get initial() {
|
||||||
return this.#localInitial;
|
return this.#initial;
|
||||||
}
|
}
|
||||||
|
|
||||||
createStore(
|
createStore(
|
||||||
|
21
src/buildInitial.test.ts
Normal file
21
src/buildInitial.test.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
import { test, expect } from 'vitest';
|
||||||
|
import { buildInitial } from './buildInitial.js';
|
||||||
|
|
||||||
|
test('basic', () => {
|
||||||
|
expect(
|
||||||
|
buildInitial(
|
||||||
|
{ a: 1 },
|
||||||
|
{ b: { initial: { c: 2 } }, d: { initial: 'e' } },
|
||||||
|
),
|
||||||
|
).toEqual({
|
||||||
|
a: 1,
|
||||||
|
b: { c: 2 },
|
||||||
|
d: 'e',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throw if subduxes and initial is not an object', () => {
|
||||||
|
expect(() => {
|
||||||
|
buildInitial(3, { bar: 'foo' });
|
||||||
|
}).toThrow();
|
||||||
|
});
|
12
src/buildInitial.ts
Normal file
12
src/buildInitial.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import u from '@yanick/updeep-remeda';
|
||||||
|
import * as R from 'remeda';
|
||||||
|
|
||||||
|
export function buildInitial(localInitial, subduxes) {
|
||||||
|
if (Object.keys(subduxes).length > 0 && typeof localInitial !== 'object') {
|
||||||
|
throw new Error(
|
||||||
|
"can't have subduxes when the initial value is not an object",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return u(localInitial, R.mapValues(subduxes, R.pathOr(['initial'], {})));
|
||||||
|
}
|
@ -1,46 +0,0 @@
|
|||||||
import { test, expect } from 'vitest';
|
|
||||||
|
|
||||||
import { Updux } from './Updux.js';
|
|
||||||
|
|
||||||
const bar = new Updux({ initial: 123 });
|
|
||||||
|
|
||||||
const foo = new Updux({
|
|
||||||
initial: { root: 'abc' },
|
|
||||||
subduxes: {
|
|
||||||
bar,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
test('single dux', () => {
|
|
||||||
const foo = new Updux({
|
|
||||||
initial: { a: 1 },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(foo.initial).toEqual({ a: 1 });
|
|
||||||
});
|
|
||||||
|
|
||||||
test('initial value', () => {
|
|
||||||
expect(foo.initial).toEqual({
|
|
||||||
root: 'abc',
|
|
||||||
bar: 123,
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
test('splat initial', async () => {
|
|
||||||
const bar = new Updux({
|
|
||||||
initial: { id: 0 },
|
|
||||||
});
|
|
||||||
|
|
||||||
const foo = new Updux({
|
|
||||||
subduxes: { '*': bar },
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(foo.initial).toEqual([]);
|
|
||||||
|
|
||||||
expect(
|
|
||||||
new Updux({
|
|
||||||
initial: 'overriden',
|
|
||||||
subduxes: { '*': bar },
|
|
||||||
}).initial,
|
|
||||||
).toEqual('overriden');
|
|
||||||
});
|
|
@ -1,5 +1,15 @@
|
|||||||
|
import { expectType } from './tutorial.test.js';
|
||||||
import Updux from './Updux.js';
|
import Updux from './Updux.js';
|
||||||
|
|
||||||
|
const bar = new Updux({ initial: 123 });
|
||||||
|
|
||||||
|
const foo = new Updux({
|
||||||
|
initial: { root: 'abc' },
|
||||||
|
subduxes: {
|
||||||
|
bar,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
test('default', () => {
|
test('default', () => {
|
||||||
const { initial } = new Updux({});
|
const { initial } = new Updux({});
|
||||||
|
|
||||||
@ -29,3 +39,60 @@ test('initial to createStore', () => {
|
|||||||
b: 4,
|
b: 4,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('single dux', () => {
|
||||||
|
const foo = new Updux({
|
||||||
|
initial: { a: 1 },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(foo.initial).toEqual({ a: 1 });
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO add 'check for no todo eslint rule'
|
||||||
|
test.only('initial value', () => {
|
||||||
|
expect(foo.initial).toEqual({
|
||||||
|
root: 'abc',
|
||||||
|
bar: 123,
|
||||||
|
});
|
||||||
|
|
||||||
|
expectType<{
|
||||||
|
root: string;
|
||||||
|
bar: number;
|
||||||
|
}>(foo.initial);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no initial', () => {
|
||||||
|
const dux = new Updux({});
|
||||||
|
expectType<{}>(dux.initial);
|
||||||
|
expect(dux.initial).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('no initial for subdux', () => {
|
||||||
|
const dux = new Updux({
|
||||||
|
subduxes: {
|
||||||
|
bar: new Updux({}),
|
||||||
|
baz: new Updux({ initial: 'potato' }),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expectType<{ bar: {}; baz: string }>(dux.initial);
|
||||||
|
expect(dux.initial).toEqual({ bar: {}, baz: 'potato' });
|
||||||
|
});
|
||||||
|
|
||||||
|
test('splat initial', async () => {
|
||||||
|
const bar = new Updux({
|
||||||
|
initial: { id: 0 },
|
||||||
|
});
|
||||||
|
|
||||||
|
const foo = new Updux({
|
||||||
|
subduxes: { '*': bar },
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(foo.initial).toEqual([]);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
new Updux({
|
||||||
|
initial: 'overriden',
|
||||||
|
subduxes: { '*': bar },
|
||||||
|
}).initial,
|
||||||
|
).toEqual('overriden');
|
||||||
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import Updux, { createAction, withPayload } from './index.js';
|
import Updux, { createAction, withPayload } from './index.js';
|
||||||
import u from '@yanick/updeep-remeda';
|
import u from '@yanick/updeep-remeda';
|
||||||
|
|
||||||
const expectType = <T>(value: T) => value;
|
export const expectType = <T>(value: T) => value;
|
||||||
|
|
||||||
test('initial state', () => {
|
test('initial state', () => {
|
||||||
const initial = {
|
const initial = {
|
||||||
|
Loading…
Reference in New Issue
Block a user