Skip to content

Instantly share code, notes, and snippets.

@mary-ext
Last active December 12, 2024 04:45
Show Gist options
  • Save mary-ext/b120ec326a9e51059dcf4031db6e4495 to your computer and use it in GitHub Desktop.
Save mary-ext/b120ec326a9e51059dcf4031db6e4495 to your computer and use it in GitHub Desktop.
Local storage persistence for Pinia states
import { PiniaPlugin, StateTree } from "pinia";
const PREFIX = "pinia:";
export interface PersistenceOptions<S extends StateTree> {
validate?: (state: StateTree) => state is S;
}
declare module "pinia" {
// eslint-disable-next-line no-undef, @typescript-eslint/no-unused-vars
export interface DefineStoreOptionsBase<S extends StateTree, Store> {
persist?: PersistenceOptions<S>;
}
export interface PiniaCustomProperties {
$persist: () => void;
}
}
export const createPiniaPersister = (): PiniaPlugin => {
return ({ store, options: { persist } }) => {
if (!persist) {
return;
}
const id = store.$id;
const storageKey = PREFIX + id;
store.$persist = () => {
try {
const raw = JSON.stringify(store.$state);
localStorage.setItem(storageKey, raw);
} catch (err) {
console.error(`[pinia-persist]: failed to persist ${id}`, err);
}
};
// Hydrate the store
try {
const persisted = localStorage.getItem(storageKey);
if (persisted) {
const json = JSON.parse(persisted);
const valid = persist.validate?.(json) ?? true;
if (valid) {
store.$patch(json);
} else {
console.warn(`[pinia-persist]: invalid hydration for ${id}`);
}
}
} catch (err) {
console.error(`[pinia-persist]: failed to hydrate ${id}`, err);
}
// Subscribe to the store
store.$subscribe(() => store.$persist());
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment