update
This commit is contained in:
parent
18d79b79a7
commit
112b737cc4
@ -22,7 +22,8 @@
|
||||
"immer": "^10.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"zustand": "^4.5.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@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:
|
||||
specifier: ^18.2.0
|
||||
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:
|
||||
'@3rapp/code-config':
|
||||
specifier: workspace:*
|
||||
@ -5432,6 +5435,11 @@ packages:
|
||||
uri-js@4.4.1:
|
||||
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:
|
||||
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
|
||||
|
||||
@ -5606,6 +5614,21 @@ packages:
|
||||
engines: {node: '>=8.0.0'}
|
||||
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:
|
||||
|
||||
'@alloc/quick-lru@5.2.0': {}
|
||||
@ -11360,6 +11383,10 @@ snapshots:
|
||||
dependencies:
|
||||
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: {}
|
||||
|
||||
uuid@9.0.1: {}
|
||||
@ -11553,3 +11580,11 @@ snapshots:
|
||||
validator: 13.12.0
|
||||
optionalDependencies:
|
||||
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