diff --git a/.yarn/install-state.gz b/.yarn/install-state.gz index c3d4420..d928cc4 100644 Binary files a/.yarn/install-state.gz and b/.yarn/install-state.gz differ diff --git a/examples/Counter/package.json b/examples/Counter/package.json index cc11ebd..46fa1fd 100644 --- a/examples/Counter/package.json +++ b/examples/Counter/package.json @@ -1,4 +1,5 @@ { + "name": "amos-examples-counter", "private": true, "version": "0.0.0", "type": "module", diff --git a/examples/Counter/src/App.tsx b/examples/Counter/src/App.tsx index 0cd876e..3cc97e5 100644 --- a/examples/Counter/src/App.tsx +++ b/examples/Counter/src/App.tsx @@ -7,7 +7,7 @@ import { numberBox } from 'amos'; import { useDispatch, useSelector } from 'amos/react'; import { memo } from 'react'; -const countBox = numberBox('count', 0); +const countBox = numberBox('count'); export const App = memo(() => { const dispatch = useDispatch(); @@ -15,7 +15,7 @@ export const App = memo(() => { return (
Count: {count}  - +
); }); diff --git a/examples/Counter/tsconfig.json b/examples/Counter/tsconfig.json new file mode 100644 index 0000000..f1cb59f --- /dev/null +++ b/examples/Counter/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "lib": ["ES2022", "DOM"], + "declaration": false, + "emitDeclarationOnly": false + } +} diff --git a/examples/TodoMVC/package.json b/examples/TodoMVC/package.json index cc11ebd..64aff32 100644 --- a/examples/TodoMVC/package.json +++ b/examples/TodoMVC/package.json @@ -1,4 +1,5 @@ { + "name": "amos-examples-todomvc", "private": true, "version": "0.0.0", "type": "module", diff --git a/packages/amos-core/src/enhancers/withDevtools.ts b/packages/amos-core/src/enhancers/withDevtools.ts index 253c0ba..61e20d7 100644 --- a/packages/amos-core/src/enhancers/withDevtools.ts +++ b/packages/amos-core/src/enhancers/withDevtools.ts @@ -58,7 +58,7 @@ export function withDevtools(): StoreEnhancer { dev.send( { type: `P:${s.key}`, - state: result, + args: [result], }, store.state, ); @@ -77,7 +77,7 @@ export function withDevtools(): StoreEnhancer { dev.send( { type: `${task[$amos].charAt(0).toUpperCase()}:${task.type}`, - params: task.args, + args: task.args, }, store.state, ); diff --git a/packages/amos-core/src/store.ts b/packages/amos-core/src/store.ts index 9c375d6..8c82146 100644 --- a/packages/amos-core/src/store.ts +++ b/packages/amos-core/src/store.ts @@ -79,6 +79,11 @@ export interface EnhanceableStore extends Store { * {@link import('amos-utils').fromJS}. */ getInitialState: (box: Box) => S; + + /** + * This function will be called after the store created. + */ + init: () => void; } export type StoreEnhancer = Enhancer<[StoreOptions], EnhanceableStore>; @@ -92,8 +97,9 @@ export function createStore(options: StoreOptions = {}, ...enhancers: StoreEnhan let isDispatching = false; return { state: {}, - snapshot: () => store.state, getInitialState: (box) => box.initialState, + init: () => void 0, + snapshot: () => store.state, subscribe: ec.subscribe, // only accepts Dispatchable here dispatch: (_task: any) => { @@ -147,6 +153,7 @@ export function createStore(options: StoreOptions = {}, ...enhancers: StoreEnhan }; }, ); + store.init(); return { snapshot: store.snapshot, subscribe: store.subscribe, diff --git a/packages/amos-core/src/types.ts b/packages/amos-core/src/types.ts index a4fdc2a..f2e2e5e 100644 --- a/packages/amos-core/src/types.ts +++ b/packages/amos-core/src/types.ts @@ -17,13 +17,15 @@ export interface DispatchableRecord { export type Dispatchable = DispatchableRecord[keyof DispatchableRecord]; -export type MapDispatchable = { - [P in keyof Rs]: Rs[P] extends Dispatchable ? R : never; +export type ResultOfDispatchable = D extends Dispatchable ? R : never; + +export type MapDispatchables = { + [P in keyof Rs]: ResultOfDispatchable; }; export interface Dispatch { (dispatchable: Dispatchable): R; - (dispatchables: Rs): MapDispatchable; + (dispatchables: Rs): MapDispatchables; (dispatchables: readonly Dispatchable[]): R[]; } @@ -34,13 +36,15 @@ export interface SelectableRecord { export type Selectable = SelectableRecord[keyof SelectableRecord]; -export type MapSelectable = { - [P in keyof Rs]: Rs[P] extends Selectable ? R : never; +export type StateOfSelectable = S extends Selectable ? R : never; + +export type MapSelectables = { + [P in keyof Rs]: StateOfSelectable; }; export interface Select { (selectable: Selectable): R; - (selectables: Rs): MapSelectable; + (selectables: Rs): MapSelectables; (selectables: readonly Selectable[]): R[]; } diff --git a/packages/amos-persist/src/actions.ts b/packages/amos-persist/src/actions.ts index afa48fa..d3861f9 100644 --- a/packages/amos-persist/src/actions.ts +++ b/packages/amos-persist/src/actions.ts @@ -3,11 +3,11 @@ * @author junbao */ -import { Action, action, Box, Dispatch, MapSelectable, Select } from 'amos-core'; +import { Action, action, Box, Dispatch, MapSelectables, Select } from 'amos-core'; import { NotImplemented } from 'amos-utils'; export interface LoadBoxes { - (...boxes: A): Action>>; + (...boxes: A): Action>>; } export const loadBoxes: LoadBoxes = action( diff --git a/packages/amos-persist/src/enhancer.ts b/packages/amos-persist/src/enhancer.ts index 3cf9ac3..77822cc 100644 --- a/packages/amos-persist/src/enhancer.ts +++ b/packages/amos-persist/src/enhancer.ts @@ -18,14 +18,19 @@ export function withPersist(options: PartialRequired) ...options, }; - store.dispatch( - persistBox.setState({ - options: finalOptions, - loading: loading, - }), - ); + override(store, 'init', (init) => { + return () => { + init(); + store.dispatch( + persistBox.setState({ + options: finalOptions, + loading: loading, + }), + ); + }; + }); - override(store, 'select', (original) => { + override(store, 'select', (select) => { return (selectable: any): any => { throw new NotImplemented(); }; diff --git a/packages/amos-react/src/useSelector.spec.tsx b/packages/amos-react/src/useSelector.spec.tsx index 6a9d4b7..067a339 100644 --- a/packages/amos-react/src/useSelector.spec.tsx +++ b/packages/amos-react/src/useSelector.spec.tsx @@ -4,7 +4,7 @@ */ import { act, renderHook, RenderHookResult } from '@testing-library/react-hooks'; -import { createStore, MapSelectable, Select, Selectable, selector, Snapshot, Store } from 'amos-core'; +import { createStore, MapSelectables, Select, Selectable, selector, Snapshot, Store } from 'amos-core'; import { addTwiceAsync, countBox, @@ -35,7 +35,7 @@ function renderUseSelector( fn: (props: P) => Rs, preloaded?: Snapshot, initialProps?: P, -): RenderHookResult> & Store { +): RenderHookResult> & Store { const store = createStore({ preloadedState: preloaded }); const hook = renderHook((props: P) => useSelector(fn(props)), { wrapper: (props: any) => {props.children}, diff --git a/packages/amos-react/src/useSelector.ts b/packages/amos-react/src/useSelector.ts index 28cc044..bd1668f 100644 --- a/packages/amos-react/src/useSelector.ts +++ b/packages/amos-react/src/useSelector.ts @@ -9,8 +9,8 @@ import { isSelectValueEqual, Select, Selectable, - Selector, SelectEntry, + Selector, } from 'amos'; import { useCallback, useDebugValue, useLayoutEffect, useReducer, useRef } from 'react'; import { useStore } from './context'; diff --git a/packages/amos/src/index.ts b/packages/amos/src/index.ts index 6e57448..ef1fad3 100644 --- a/packages/amos/src/index.ts +++ b/packages/amos/src/index.ts @@ -44,7 +44,7 @@ export { Dispatchable, DispatchableRecord, EnhanceableStore, - MapSelectable, + MapSelectables, Mutation, MutationFactory, MutationOptions, diff --git a/yarn.lock b/yarn.lock index 49f3fdf..c9ca8ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4516,36 +4516,6 @@ __metadata: languageName: node linkType: hard -"Counter-ec41ce@workspace:examples/Counter": - version: 0.0.0-use.local - resolution: "Counter-ec41ce@workspace:examples/Counter" - dependencies: - "@types/react": "npm:^18.3.10" - "@types/react-dom": "npm:^18.3.0" - "@vitejs/plugin-react": "npm:^4.3.2" - globals: "npm:^15.9.0" - react: "npm:^18.3.1" - react-dom: "npm:^18.3.1" - typescript: "npm:^5.5.3" - vite: "npm:^5.4.8" - languageName: unknown - linkType: soft - -"TodoMVC-1c0570@workspace:examples/TodoMVC": - version: 0.0.0-use.local - resolution: "TodoMVC-1c0570@workspace:examples/TodoMVC" - dependencies: - "@types/react": "npm:^18.3.10" - "@types/react-dom": "npm:^18.3.0" - "@vitejs/plugin-react": "npm:^4.3.2" - globals: "npm:^15.9.0" - react: "npm:^18.3.1" - react-dom: "npm:^18.3.1" - typescript: "npm:^5.5.3" - vite: "npm:^5.4.8" - languageName: unknown - linkType: soft - "abbrev@npm:^2.0.0": version: 2.0.0 resolution: "abbrev@npm:2.0.0" @@ -4729,6 +4699,36 @@ __metadata: languageName: unknown linkType: soft +"amos-examples-counter@workspace:examples/Counter": + version: 0.0.0-use.local + resolution: "amos-examples-counter@workspace:examples/Counter" + dependencies: + "@types/react": "npm:^18.3.10" + "@types/react-dom": "npm:^18.3.0" + "@vitejs/plugin-react": "npm:^4.3.2" + globals: "npm:^15.9.0" + react: "npm:^18.3.1" + react-dom: "npm:^18.3.1" + typescript: "npm:^5.5.3" + vite: "npm:^5.4.8" + languageName: unknown + linkType: soft + +"amos-examples-todomvc@workspace:examples/TodoMVC": + version: 0.0.0-use.local + resolution: "amos-examples-todomvc@workspace:examples/TodoMVC" + dependencies: + "@types/react": "npm:^18.3.10" + "@types/react-dom": "npm:^18.3.0" + "@vitejs/plugin-react": "npm:^4.3.2" + globals: "npm:^15.9.0" + react: "npm:^18.3.1" + react-dom: "npm:^18.3.1" + typescript: "npm:^5.5.3" + vite: "npm:^5.4.8" + languageName: unknown + linkType: soft + "amos-io@workspace:packages/amos-io": version: 0.0.0-use.local resolution: "amos-io@workspace:packages/amos-io"