Skip to content

Instantly share code, notes, and snippets.

@kinoadr
Last active January 12, 2023 23:11
Show Gist options
  • Save kinoadr/9766a45293ac9102471d96f218bd5eaa to your computer and use it in GitHub Desktop.
Save kinoadr/9766a45293ac9102471d96f218bd5eaa to your computer and use it in GitHub Desktop.
Zustand (^3.7.0) persist middleware with deferred hydration.
import { persist, PersistOptions } from 'zustand/middleware';
import { GetState, SetState, StoreApi } from 'zustand/vanilla';
type DeferredPersistOptions<S extends object> = PersistOptions<S, Partial<S>> & {
hydrateOnResolve?: Promise<void>;
};
const DEFAULT_GET_STORAGE = () => localStorage;
export default function deferredPersist<
S extends object,
CustomSetState extends SetState<S> = SetState<S>,
CustomGetState extends GetState<S> = GetState<S>,
CustomStoreApi extends StoreApi<S> = StoreApi<S>,
>(
config: (set: CustomSetState, get: CustomGetState, api: CustomStoreApi) => S,
deferredOptions: DeferredPersistOptions<S>,
) {
const hydrateOnResolve = deferredOptions.hydrateOnResolve || Promise.resolve();
const getStorage = deferredOptions.getStorage || DEFAULT_GET_STORAGE;
const options: PersistOptions<S> = {
...deferredOptions,
getStorage: () => ({
setItem: async (...args) => hydrateOnResolve.then(() => getStorage().setItem(...args)),
getItem: async (...args) => hydrateOnResolve.then(() => getStorage().getItem(...args)),
removeItem: async (...args) => hydrateOnResolve.then(() => getStorage().removeItem?.(...args)),
}),
};
return persist<S, CustomSetState, CustomGetState, CustomStoreApi>(config, options);
}
@leosh1d
Copy link

leosh1d commented Dec 23, 2022

Impementation for ^4.1.5

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment