UNPKG

@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 (48 loc) • 1.79 kB
--- name: alpine-persist description: Gate Alpine.js UI on Persist hydration (Alpine.plugin + useHydrated / $hydrated). Use when wiring HydrationSignal into Alpine data components. license: MIT metadata: type: framework library: "@stainless-code/persist" library_version: "0.4.1" framework: "alpine" requires: - persist sources: - stainless-code/persist:src/adapters/frameworks/alpine.ts --- # Alpine hydration gate `@stainless-code/persist/frameworks/alpine` is **plugin-first**: `Alpine.plugin(persist)` registers `$hydrated` and enables reactive `useHydrated`. Call `destroy()` from `Alpine.data` teardown. ## Install ```bash bun add @stainless-code/persist alpinejs ``` Peer: `alpinejs` `>=3.0.0` (types via `@types/alpinejs` — package ships none). ## Minimal wiring ```ts import Alpine from "alpinejs"; import persist, { useHydrated, } from "@stainless-code/persist/frameworks/alpine"; Alpine.plugin(persist); Alpine.data("prefs", () => { const hydration = useHydrated(prefsHydration); return { get hydrated() { return hydration.hydrated; }, destroy() { hydration.destroy(); }, }; }); ``` Template: `x-show="$hydrated(prefsHydration).hydrated"` — `$hydrated(signal)` returns a **bag** (`{ hydrated, destroy }`), not a boolean (a bare bag is always truthy in `x-show`). Magic caches per element. ## Common mistakes - **Skipping `Alpine.plugin(persist)`.** `useHydrated` falls back to a plain object + one-time non-prod warn. - **`x-show="$hydrated(...)"` without `.hydrated`.** - **Not forwarding `destroy()`** from `Alpine.data`. ## API surface - default/`persist(Alpine)` — plugin; registers `$hydrated(signal) → HydratedBag` - `useHydrated(signal) → { hydrated; destroy() }` (null signal → `{ hydrated: true }`)