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

55 lines (54 loc) • 2.56 kB
import { f as StateStorage, n as CreateStorageOptions, u as PersistStorage } from "../persist-core-B649IGlX.mjs"; import { UseStore } from "idb-keyval"; //#region src/adapters/backends/idb.d.ts interface IdbStorageOptions extends CreateStorageOptions { /** * Custom `idb-keyval` store (`createStore(dbName, storeName)`) — e.g. to * namespace persisted state away from other idb-keyval users. * @default idb-keyval's shared default store (`keyval-store` / `keyval`) */ store?: UseStore; } /** * `StateStorage` over idb-keyval — fully async; maps idb-keyval's * `undefined`-for-missing to the `null` this seam expects. Generic over the * wire type: `string` for codec-encoded use, `StorageValue<S>` for the * structured-clone mode (see `createIdbStorage`). IndexedDB * unavailability (private-mode edge cases, forced closes) surfaces as a * rejection on first use — reported via `onError` phase `"hydrate"` — not at * construction (`createStorage`'s sync try-guard can't see it). */ declare function idbStateStorage<TRaw = string>(store?: UseStore): StateStorage<TRaw>; /** * Build an IndexedDB-backed `PersistStorage` (via idb-keyval) — * **structured-clone mode**: IndexedDB stores the `StorageValue` envelope * NATIVELY, so `Set` / `Map` / `Date` round-trip via the structured-clone * algorithm with zero (de)serialization — no seroval, no JSON, and better * DevTools inspection (objects, not encoded strings). The payoff of the * generic wire-type seam (`StateStorage<TRaw>`). * * Codec use cases (encryption at rest, compression, legacy string payloads) * are a one-line composition over the core primitives instead of a second * factory: * * ```ts * createStorage(() => idbStateStorage(store), myEncryptedCodec, options); * ``` * * Semantics vs `localStorage` backends: * hydration can't settle before first paint, so `useHydrated` gating is * mandatory rather than optional; IndexedDB fires no `storage` events, so * `crossTab` needs a `BroadcastChannel` bridge via `crossTabEventTarget`; * and `clearCorruptOnFailure` is inert here — the identity decode never * throws (structured clone can't truncate-corrupt the way strings can). * * @example * ```ts * import { createIdbStorage } from "@stainless-code/persist/backends/idb"; * * const storage = createIdbStorage<Prefs>(); // Set/Map/Date just work * ``` */ declare function createIdbStorage<S>(options?: IdbStorageOptions): PersistStorage<S> | undefined; //#endregion export { IdbStorageOptions, createIdbStorage, idbStateStorage };