import { createStore as createZutandStore, StateCreator, StoreApi } from 'zustand/vanilla'; import { shallow } from 'zustand/shallow'; import { get } from 'lodash-es'; import deepEqual from 'fast-deep-equal'; export const create = createZutandStore; export type { StateCreator, StoreApi }; type Listener = (state: any, prevState: any) => void; export class StoreManager { stores: Record; constructor() { this.stores = {}; } createStore(initialStore: StateCreator, key: string) { if (this.stores[key]) { return this.stores[key]; } this.stores[key] = createZutandStore(initialStore); return this.stores[key] as StoreApi; } create(initialStore: StateCreator, key: string) { return this.createStore(initialStore, key); } getStore(key: string) { return this.stores[key]; } removeStore(key: string) { delete this.stores[key]; } clearStores() { this.stores = {}; } shallow(objA: any, objB: any) { return shallow(objA, objB); } /** * path 为可以是 '.a.b.c'的形式 * @param fn * @param param1 * @returns */ subscribe(fn: Listener, { key, path, deep, store }: { key: string; path: string; deep?: boolean; store?: StoreApi }) { const _store = store || (this.stores[key] as StoreApi); if (!_store) { console.error('no store', key); return; } return _store.subscribe((newState, oldState) => { try { const newPath = get(newState, path); const oldPath = get(oldState, path); if (!newPath && !oldPath) { return; } if (deep) { if (!deepEqual(newPath, oldPath)) { fn?.(newState, oldState); } return; } if (!shallow(newPath, oldPath)) { fn?.(newState, oldState); } } catch (e) { console.error('subscribe error', e); } }); } } // export const store = new StoreManager(); type FnListener = (state: T, prevState: T) => void; type SubOptions = { path?: string; deep?: boolean; store?: StoreApi; }; export const sub = (fn: FnListener, { path, deep, store }: SubOptions) => { if (!store) { console.error('no store'); return; } return store.subscribe((newState: T, oldState: T) => { try { const newPath = get(newState, path); const oldPath = get(oldState, path); if (!newPath && !oldPath) { // 都不存在 return; } if (deep) { if (!deepEqual(newPath, oldPath)) { fn?.(newState, oldState); } return; } if (!shallow(newPath, oldPath)) { fn?.(newState, oldState); } } catch (e) { console.error('subscribe error', e); } }); }; export { shallow, deepEqual };