import { create } from "zustand"; import { 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( defaultState: T, methods: ( set: SetStoreState>, get: () => T & MakeUpdater, ) => M, persistOptions: SecondParam>>, ) { return create>()( persist((set, get) => { return { ...defaultState, ...methods(set as any, get), lastUpdateTime: 0, markUpdate() { set({ lastUpdateTime: Date.now() } as Partial< T & M & MakeUpdater >); }, update(updater) { const state = deepClone(get()); updater(state); get().markUpdate(); set(state); }, }; }, persistOptions), ); }