update
This commit is contained in:
parent
18d79b79a7
commit
112b737cc4
@ -22,7 +22,8 @@
|
|||||||
"immer": "^10.1.1",
|
"immer": "^10.1.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0",
|
||||||
|
"zustand": "^4.5.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@3rapp/code-config": "workspace:*",
|
"@3rapp/code-config": "workspace:*",
|
||||||
|
2
apps/admin/src/components/store/index.ts
Normal file
2
apps/admin/src/components/store/index.ts
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './utils';
|
||||||
|
export * from './types';
|
8
apps/admin/src/components/store/types.ts
Normal file
8
apps/admin/src/components/store/types.ts
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
export type ZustandHookSelectors<StateType> = {
|
||||||
|
[Key in keyof StateType as `use${Capitalize<string & Key>}`]: () => StateType[Key];
|
||||||
|
};
|
||||||
|
export interface ZustandGetterSelectors<StateType> {
|
||||||
|
getters: {
|
||||||
|
[key in keyof StateType]: () => StateType[key];
|
||||||
|
};
|
||||||
|
}
|
160
apps/admin/src/components/store/utils.ts
Normal file
160
apps/admin/src/components/store/utils.ts
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
import { capitalize } from 'lodash';
|
||||||
|
import { create, Mutate, StateCreator, StoreApi, UseBoundStore } from 'zustand';
|
||||||
|
import {
|
||||||
|
subscribeWithSelector,
|
||||||
|
devtools,
|
||||||
|
persist,
|
||||||
|
PersistOptions,
|
||||||
|
DevtoolsOptions,
|
||||||
|
redux,
|
||||||
|
} from 'zustand/middleware';
|
||||||
|
import { immer } from 'zustand/middleware/immer';
|
||||||
|
|
||||||
|
import { ZustandGetterSelectors, ZustandHookSelectors } from './types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建包含订阅,immer以及devtoools功能的普通状态商店
|
||||||
|
* @param creator
|
||||||
|
* @param devtoolsOptions
|
||||||
|
*/
|
||||||
|
export const createStore = <T extends object>(
|
||||||
|
creator: StateCreator<
|
||||||
|
T,
|
||||||
|
[
|
||||||
|
['zustand/subscribeWithSelector', never],
|
||||||
|
['zustand/immer', never],
|
||||||
|
['zustand/devtools', never],
|
||||||
|
]
|
||||||
|
>,
|
||||||
|
devtoolsOptions?: DevtoolsOptions,
|
||||||
|
) => {
|
||||||
|
return create<T>()(subscribeWithSelector(immer(devtools(creator, devtoolsOptions))));
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建包含订阅,immer以及devtoools功能的普通状态商店
|
||||||
|
* 同时支持自动存储到客户端,默认存储到localstorage
|
||||||
|
* @param creator
|
||||||
|
* @param persistOptions
|
||||||
|
* @param devtoolsOptions
|
||||||
|
*/
|
||||||
|
export const createPersistStore = <T extends object, P = T>(
|
||||||
|
creator: StateCreator<
|
||||||
|
T,
|
||||||
|
[
|
||||||
|
['zustand/subscribeWithSelector', never],
|
||||||
|
['zustand/immer', never],
|
||||||
|
['zustand/devtools', never],
|
||||||
|
['zustand/persist', P],
|
||||||
|
]
|
||||||
|
>,
|
||||||
|
persistOptions: PersistOptions<T, P>,
|
||||||
|
devtoolsOptions?: DevtoolsOptions,
|
||||||
|
) => {
|
||||||
|
return create<T>()(
|
||||||
|
subscribeWithSelector(
|
||||||
|
immer(devtools(persist(creator as unknown as any, persistOptions), devtoolsOptions)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建包含订阅,immer以及devtoools功能的reducer状态商店
|
||||||
|
* 同时支持自动存储到客户端,默认存储到localstorage
|
||||||
|
* @param reducer
|
||||||
|
* @param initialState
|
||||||
|
* @param devtoolsOptions
|
||||||
|
*/
|
||||||
|
export const createReduxStore = <
|
||||||
|
T extends object,
|
||||||
|
A extends {
|
||||||
|
type: string;
|
||||||
|
},
|
||||||
|
>(
|
||||||
|
reducer: (state: T, action: A) => T,
|
||||||
|
initialState: T,
|
||||||
|
devtoolsOptions?: DevtoolsOptions,
|
||||||
|
) => create(subscribeWithSelector(immer(devtools(redux(reducer, initialState), devtoolsOptions))));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建包含订阅,immer以及devtoools功能的reducer状态商店
|
||||||
|
* @param reducer
|
||||||
|
* @param initialState
|
||||||
|
* @param persistOptions
|
||||||
|
* @param devtoolsOptions
|
||||||
|
*/
|
||||||
|
export const createPersistReduxStore = <
|
||||||
|
T extends object,
|
||||||
|
A extends {
|
||||||
|
type: string;
|
||||||
|
},
|
||||||
|
P = T,
|
||||||
|
>(
|
||||||
|
reducer: (state: T, action: A) => T,
|
||||||
|
initialState: T,
|
||||||
|
persistOptions: PersistOptions<T, P>,
|
||||||
|
devtoolsOptions?: DevtoolsOptions,
|
||||||
|
) =>
|
||||||
|
create(
|
||||||
|
subscribeWithSelector(
|
||||||
|
immer(
|
||||||
|
devtools(
|
||||||
|
persist(redux(reducer, initialState), persistOptions as any),
|
||||||
|
devtoolsOptions,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接通过getters获取状态值,比如store.getters.xxx()
|
||||||
|
* @param store
|
||||||
|
*/
|
||||||
|
export function createStoreGetters<T extends object>(
|
||||||
|
store: UseBoundStore<
|
||||||
|
Mutate<
|
||||||
|
StoreApi<T>,
|
||||||
|
[
|
||||||
|
['zustand/subscribeWithSelector', never],
|
||||||
|
['zustand/immer', never],
|
||||||
|
['zustand/devtools', never],
|
||||||
|
]
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const storeIn = store as any;
|
||||||
|
|
||||||
|
storeIn.getters = {};
|
||||||
|
Object.keys(storeIn.getState()).forEach((key) => {
|
||||||
|
const selector = (state: T) => state[key as keyof T];
|
||||||
|
storeIn.getters[key] = () => storeIn(selector);
|
||||||
|
});
|
||||||
|
|
||||||
|
return storeIn as typeof store & ZustandGetterSelectors<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接通过类似hooks的方法获取状态值,比如store.useXxx()
|
||||||
|
* @param store
|
||||||
|
*/
|
||||||
|
export function createStoreHooks<T extends Record<string, any>>(
|
||||||
|
store: UseBoundStore<
|
||||||
|
Mutate<
|
||||||
|
StoreApi<T>,
|
||||||
|
[
|
||||||
|
['zustand/subscribeWithSelector', never],
|
||||||
|
['zustand/immer', never],
|
||||||
|
['zustand/devtools', never],
|
||||||
|
]
|
||||||
|
>
|
||||||
|
>,
|
||||||
|
) {
|
||||||
|
const storeIn = store as any;
|
||||||
|
|
||||||
|
Object.keys(storeIn.getState()).forEach((key) => {
|
||||||
|
const selector = (state: T) => state[key as keyof T];
|
||||||
|
storeIn[`use${capitalize(key)}`] = () => storeIn(selector);
|
||||||
|
});
|
||||||
|
|
||||||
|
return storeIn as typeof store & ZustandHookSelectors<T>;
|
||||||
|
}
|
@ -56,6 +56,9 @@ importers:
|
|||||||
react-dom:
|
react-dom:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.3.1(react@18.3.1)
|
version: 18.3.1(react@18.3.1)
|
||||||
|
zustand:
|
||||||
|
specifier: ^4.5.2
|
||||||
|
version: 4.5.2(@types/react@18.3.1)(immer@10.1.1)(react@18.3.1)
|
||||||
devDependencies:
|
devDependencies:
|
||||||
'@3rapp/code-config':
|
'@3rapp/code-config':
|
||||||
specifier: workspace:*
|
specifier: workspace:*
|
||||||
@ -5432,6 +5435,11 @@ packages:
|
|||||||
uri-js@4.4.1:
|
uri-js@4.4.1:
|
||||||
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
|
||||||
|
|
||||||
|
use-sync-external-store@1.2.0:
|
||||||
|
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
|
||||||
|
peerDependencies:
|
||||||
|
react: ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||||
|
|
||||||
util-deprecate@1.0.2:
|
util-deprecate@1.0.2:
|
||||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||||
|
|
||||||
@ -5606,6 +5614,21 @@ packages:
|
|||||||
engines: {node: '>=8.0.0'}
|
engines: {node: '>=8.0.0'}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
zustand@4.5.2:
|
||||||
|
resolution: {integrity: sha512-2cN1tPkDVkwCy5ickKrI7vijSjPksFRfqS6237NzT0vqSsztTNnQdHw9mmN7uBdk3gceVXU0a+21jFzFzAc9+g==}
|
||||||
|
engines: {node: '>=12.7.0'}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '>=16.8'
|
||||||
|
immer: '>=9.0.6'
|
||||||
|
react: '>=16.8'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
immer:
|
||||||
|
optional: true
|
||||||
|
react:
|
||||||
|
optional: true
|
||||||
|
|
||||||
snapshots:
|
snapshots:
|
||||||
|
|
||||||
'@alloc/quick-lru@5.2.0': {}
|
'@alloc/quick-lru@5.2.0': {}
|
||||||
@ -11360,6 +11383,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
punycode: 2.3.1
|
punycode: 2.3.1
|
||||||
|
|
||||||
|
use-sync-external-store@1.2.0(react@18.3.1):
|
||||||
|
dependencies:
|
||||||
|
react: 18.3.1
|
||||||
|
|
||||||
util-deprecate@1.0.2: {}
|
util-deprecate@1.0.2: {}
|
||||||
|
|
||||||
uuid@9.0.1: {}
|
uuid@9.0.1: {}
|
||||||
@ -11553,3 +11580,11 @@ snapshots:
|
|||||||
validator: 13.12.0
|
validator: 13.12.0
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
commander: 9.5.0
|
commander: 9.5.0
|
||||||
|
|
||||||
|
zustand@4.5.2(@types/react@18.3.1)(immer@10.1.1)(react@18.3.1):
|
||||||
|
dependencies:
|
||||||
|
use-sync-external-store: 1.2.0(react@18.3.1)
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/react': 18.3.1
|
||||||
|
immer: 10.1.1
|
||||||
|
react: 18.3.1
|
||||||
|
Loading…
Reference in New Issue
Block a user