Skip to content

Commit

Permalink
feat: init & map select types
Browse files Browse the repository at this point in the history
  • Loading branch information
acrazing committed Oct 23, 2024
1 parent 3fc6bd1 commit 6bc801e
Show file tree
Hide file tree
Showing 14 changed files with 80 additions and 54 deletions.
Binary file modified .yarn/install-state.gz
Binary file not shown.
1 change: 1 addition & 0 deletions examples/Counter/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "amos-examples-counter",
"private": true,
"version": "0.0.0",
"type": "module",
Expand Down
4 changes: 2 additions & 2 deletions examples/Counter/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@ 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();
const count = useSelector(countBox);
return (
<div>
<span>Count: {count}&nbsp;</span>
<button onClick={() => dispatch(countBox.setState((c) => c + 1))}>Click me!</button>
<button onClick={() => dispatch(countBox.add(1))}>Click me!</button>
</div>
);
});
8 changes: 8 additions & 0 deletions examples/Counter/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"lib": ["ES2022", "DOM"],
"declaration": false,
"emitDeclarationOnly": false
}
}
1 change: 1 addition & 0 deletions examples/TodoMVC/package.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"name": "amos-examples-todomvc",
"private": true,
"version": "0.0.0",
"type": "module",
Expand Down
4 changes: 2 additions & 2 deletions packages/amos-core/src/enhancers/withDevtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export function withDevtools(): StoreEnhancer {
dev.send(
{
type: `P:${s.key}`,
state: result,
args: [result],
},
store.state,
);
Expand All @@ -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,
);
Expand Down
9 changes: 8 additions & 1 deletion packages/amos-core/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ export interface EnhanceableStore extends Store {
* {@link import('amos-utils').fromJS}.
*/
getInitialState: <S>(box: Box<S>) => S;

/**
* This function will be called after the store created.
*/
init: () => void;
}

export type StoreEnhancer = Enhancer<[StoreOptions], EnhanceableStore>;
Expand All @@ -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) => {
Expand Down Expand Up @@ -147,6 +153,7 @@ export function createStore(options: StoreOptions = {}, ...enhancers: StoreEnhan
};
},
);
store.init();
return {
snapshot: store.snapshot,
subscribe: store.subscribe,
Expand Down
16 changes: 10 additions & 6 deletions packages/amos-core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,15 @@ export interface DispatchableRecord<R> {

export type Dispatchable<R = any> = DispatchableRecord<R>[keyof DispatchableRecord<R>];

export type MapDispatchable<Rs extends readonly Dispatchable[]> = {
[P in keyof Rs]: Rs[P] extends Dispatchable<infer R> ? R : never;
export type ResultOfDispatchable<D> = D extends Dispatchable<infer R> ? R : never;

export type MapDispatchables<Rs extends readonly Dispatchable[]> = {
[P in keyof Rs]: ResultOfDispatchable<Rs[P]>;
};

export interface Dispatch {
<R>(dispatchable: Dispatchable<R>): R;
<Rs extends readonly Dispatchable[]>(dispatchables: Rs): MapDispatchable<Rs>;
<Rs extends readonly Dispatchable[] | []>(dispatchables: Rs): MapDispatchables<Rs>;
<R>(dispatchables: readonly Dispatchable<R>[]): R[];
}

Expand All @@ -34,13 +36,15 @@ export interface SelectableRecord<R> {

export type Selectable<R = any> = SelectableRecord<R>[keyof SelectableRecord<R>];

export type MapSelectable<Rs extends readonly Selectable[]> = {
[P in keyof Rs]: Rs[P] extends Selectable<infer R> ? R : never;
export type StateOfSelectable<S> = S extends Selectable<infer R> ? R : never;

export type MapSelectables<Rs extends readonly Selectable[]> = {
[P in keyof Rs]: StateOfSelectable<Rs[P]>;
};

export interface Select {
<R>(selectable: Selectable<R>): R;
<Rs extends readonly Selectable[]>(selectables: Rs): MapSelectable<Rs>;
<Rs extends readonly Selectable[] | []>(selectables: Rs): MapSelectables<Rs>;
<R>(selectables: readonly Selectable<R>[]): R[];
}

Expand Down
4 changes: 2 additions & 2 deletions packages/amos-persist/src/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
* @author junbao <[email protected]>
*/

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 {
<A extends Box[]>(...boxes: A): Action<A, Promise<MapSelectable<A>>>;
<A extends Box[]>(...boxes: A): Action<A, Promise<MapSelectables<A>>>;
}

export const loadBoxes: LoadBoxes = action(
Expand Down
19 changes: 12 additions & 7 deletions packages/amos-persist/src/enhancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@ export function withPersist(options: PartialRequired<PersistOptions, 'storage'>)
...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();
};
Expand Down
4 changes: 2 additions & 2 deletions packages/amos-react/src/useSelector.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -35,7 +35,7 @@ function renderUseSelector<P, Rs extends readonly Selectable[]>(
fn: (props: P) => Rs,
preloaded?: Snapshot,
initialProps?: P,
): RenderHookResult<P, MapSelectable<Rs>> & Store {
): RenderHookResult<P, MapSelectables<Rs>> & Store {
const store = createStore({ preloadedState: preloaded });
const hook = renderHook((props: P) => useSelector(fn(props)), {
wrapper: (props: any) => <Provider store={store}>{props.children}</Provider>,
Expand Down
2 changes: 1 addition & 1 deletion packages/amos-react/src/useSelector.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
2 changes: 1 addition & 1 deletion packages/amos/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export {
Dispatchable,
DispatchableRecord,
EnhanceableStore,
MapSelectable,
MapSelectables,
Mutation,
MutationFactory,
MutationOptions,
Expand Down
60 changes: 30 additions & 30 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down

0 comments on commit 6bc801e

Please sign in to comment.