@stainless-code/persist
Version:
Hydration-aware persistence for any reactive store — zero-dep persistSource core; codecs, backends, cross-tab transport, source + framework hydration adapters ship as opt-in recipes
63 lines (46 loc) • 2.26 kB
Markdown
---
name: persist-pinia
description: Persist a Pinia store instance with -code/persist (persistStore). Use when wiring Pinia option/setup stores to storage; hydrate applies via $state = (not $patch), with default shallow merge.
license: MIT
metadata:
type: composition
library: "@stainless-code/persist"
library_version: "0.4.1"
framework: "pinia"
sources:
- stainless-code/persist:src/adapters/sources/pinia.ts
- stainless-code/persist:docs/architecture.md
---
# Persisting Pinia
`-code/persist/sources/pinia` maps a **store instance** onto `persistSource`. Hydrate applies via **`$state =`** (not `$patch`); default `merge` still shallow-spreads, so keys absent from the payload can remain. Subscribe uses `$subscribe(…, { detached: true })` so the listener survives Vue `effectScope` stop.
## When to use this skill
- You have `const store = useX()` and want reload survival for option or setup stores.
- You need Persist's gate / codecs / cross-tab instead of (or beside) pinia-plugin-persistedstate.
## Install
```bash
bun add -code/persist pinia
```
`pinia` is an optional peer of `/sources/pinia` (Vue app + `createPinia()` still required by Pinia).
## Minimal wiring
```ts
import { defineStore } from "pinia";
import { createJSONStorage } from "@stainless-code/persist";
import { persistStore } from "@stainless-code/persist/sources/pinia";
const usePrefs = defineStore("prefs", {
state: () => ({ theme: "light" as const }),
});
const store = usePrefs(); // instance, after pinia is active
const persist = persistStore(store, {
name: "app:prefs:v1",
storage: createJSONStorage(() => localStorage),
});
```
## Common mistakes
- **Passing `defineStore(...)` / the factory** instead of `usePrefs()` instance.
- **Expecting `$patch` semantics on hydrate.** Persist assigns `$state` after `merge`.
- **Name clash with Redux `persistStore`.** Import from `/sources/pinia` (or alias).
- **Call before `setActivePinia` / app.use(pinia).** Same as any Pinia store use.
## API surface
- `persistStore(store, options) → PersistApi` — `store` is a Pinia `Store`
- Options / `PersistApi`: same as `persistSource`
See also: `react-persist` / Vue hydration adapters for UI gating on async backends.