import { create } from "zustand"; import { combine, persist } from "zustand/middleware"; import { Updater } from "../typing"; import { deepClone } from "./clone"; type SecondParam = T extends ( _f: infer _F, _s: infer S, ...args: infer _U ) => any ? S : never; type MakeUpdater = { lastUpdateTime: number; markUpdate: () => void; update: Updater; }; type SetStoreState = ( partial: T | Partial | ((state: T) => T | Partial), replace?: boolean | undefined, ) => void; export function createPersistStore( state: T, methods: ( set: SetStoreState>, get: () => T & MakeUpdater, ) => M, persistOptions: SecondParam>>, ) { return create( persist( combine( { ...state, lastUpdateTime: 0, }, (set, get) => { return { ...methods(set, get as any), markUpdate() { set({ lastUpdateTime: Date.now() } as Partial< T & M & MakeUpdater >); }, update(updater) { const state = deepClone(get()); updater(state); set({ ...state, lastUpdateTime: Date.now(), }); }, } as M & MakeUpdater; }, ), persistOptions as any, ), ); }