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