UNPKG

@stainless-code/persist

Version:

Hydration-aware persistence middleware for reactive stores (storage × codec seams, TanStack Store adapters, React hydration hook)

54 lines (53 loc) 1.85 kB
import { a as jsonCodec, i as identityCodec, n as createPersistRegistry, o as persistSource, r as createStorage, t as createJSONStorage } from "./persist-core-BFflqOey.mjs"; //#region src/hydration.ts /** * Derive a `HydrationSignal` from a `HydrationSource` (e.g. a `PersistApi`), * bridging `onHydrate` / `onFinishHydration` into one external-store * subscribe target that notifies on either transition. Null-tolerant: * `null` / `undefined` in → `null` out, so a conditional-persist consumer * drops its hydration ternary (`persist ? toHydrationSignal(persist) : null` * → `toHydrationSignal(persist)`). */ function toHydrationSignal(source) { if (!source) return null; const listeners = /* @__PURE__ */ new Set(); const emit = () => { for (const listener of listeners) listener(); }; let unsubHydrate = null; let unsubFinish = null; return { subscribeHydrated(listener) { const entry = () => listener(); listeners.add(entry); if (listeners.size === 1) { unsubHydrate = source.onHydrate(emit); unsubFinish = source.onFinishHydration(emit); } return () => { if (!listeners.delete(entry)) return; if (listeners.size === 0) { unsubHydrate?.(); unsubFinish?.(); unsubHydrate = null; unsubFinish = null; } }; }, isHydrated: () => source.hasHydrated() }; } /** * Always-hydrated `HydrationSignal` for the no-persist path — a uniform * handle instead of a `null` branch at the call site. Solves null-tolerance * once in the core so framework adapters stay dumb (subscribe + snapshot, * nothing else). */ function alwaysHydratedSignal() { return { subscribeHydrated: () => () => {}, isHydrated: () => true }; } //#endregion export { alwaysHydratedSignal, createJSONStorage, createPersistRegistry, createStorage, identityCodec, jsonCodec, persistSource, toHydrationSignal };