@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
122 lines (121 loc) • 5.27 kB
text/typescript
import { f as StateStorage, n as CreateStorageOptions, p as StorageCodec, u as PersistStorage } from "../persist-core-B649IGlX.mjs";
//#region src/adapters/codecs/standard-schema.d.ts
/**
* Minimal vendored Standard Schema v1 types.
* Vendoring keeps schema integration type-only and avoids a runtime dependency.
*
* @see https://standardschema.dev
*/
interface StandardSchemaV1<Input = unknown, Output = Input> {
readonly "~standard": StandardSchemaV1.Props<Input, Output>;
}
declare namespace StandardSchemaV1 {
interface Props<Input = unknown, Output = Input> {
readonly version: 1;
readonly vendor: string;
readonly validate: (value: unknown) => Result<Output> | Promise<Result<Output>>;
readonly types?: Types<Input, Output> | undefined;
}
type Result<Output> = SuccessResult<Output> | FailureResult;
interface SuccessResult<Output> {
readonly value: Output;
readonly issues?: undefined;
}
interface FailureResult {
readonly issues: ReadonlyArray<Issue>;
}
interface Issue {
readonly message: string;
readonly path?: ReadonlyArray<PropertyKey | PathSegment> | undefined;
}
interface PathSegment {
readonly key: PropertyKey;
}
interface Types<Input = unknown, Output = Input> {
readonly input: Input;
readonly output: Output;
}
type InferInput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["input"];
type InferOutput<Schema extends StandardSchemaV1> = NonNullable<Schema["~standard"]["types"]>["output"];
}
/** Same options as `createStorage` (`clearCorruptOnFailure`). */
type StandardSchemaStorageOptions = CreateStorageOptions;
/**
* Sync `~standard` codec for `state` only. Encode persists schema `value`
* (defaults/transforms); throws → `onError` `"write"`. Decode failures →
* corrupt path (`null` / `clearCorruptOnFailure`). Async validate throws
* {@link PersistDecodeRethrowError} (not clearCorrupt under `createStorage`).
* Envelope `version` / `timestamp` / `buster` are not schema-checked.
*/
declare function standardSchemaCodec<Output>(schema: StandardSchemaV1<unknown, Output>): StorageCodec<Output>;
/**
* Sync `~standard` wrap over an existing `PersistStorage` (typed envelope
* already decoded). Promise-aware for backend `getItem` only — async schemas
* throw toward `withStandardSchemaAsync`.
*
* @example
* ```ts
* import { createIdbStorage } from "@stainless-code/persist/backends/idb";
* import { withStandardSchema } from "@stainless-code/persist/codecs/standard-schema";
*
* const storage = withStandardSchema(createIdbStorage<Prefs>()!, prefs, {
* clearCorruptOnFailure: true,
* });
* ```
*/
declare function withStandardSchema<S>(storage: PersistStorage<S>, schema: StandardSchemaV1<unknown, S>, options?: StandardSchemaStorageOptions): PersistStorage<S>;
/**
* Async `~standard` wrap over an existing `PersistStorage`. Awaits validate
* (sync schemas OK). Prefer this for Yup / async refine; use
* `withStandardSchema` when validate is sync. Forces async hydrate even over
* `localStorage` — gate UI with `useHydrated` (same as IndexedDB).
*
* @example
* ```ts
* import { createJSONStorage } from "@stainless-code/persist";
* import { withStandardSchemaAsync } from "@stainless-code/persist/codecs/standard-schema";
*
* const storage = withStandardSchemaAsync(
* createJSONStorage<Prefs>(() => localStorage)!,
* yupSchema,
* );
* ```
*/
declare function withStandardSchemaAsync<S>(storage: PersistStorage<S>, schema: StandardSchemaV1<unknown, S>, options?: StandardSchemaStorageOptions): PersistStorage<S>;
/**
* Build a Standard Schema–gated `PersistStorage` over any string-keyed
* `StateStorage`. JSON sugar over `withStandardSchema` — pass a schema that
* implements sync `~standard`.
*
* @example
* ```ts
* import { z } from "zod";
* const prefs = z.object({ theme: z.enum(["light", "dark"]) });
* const storage = createStandardSchemaStorage<{ theme: "light" | "dark" }>(
* () => localStorage,
* prefs,
* { clearCorruptOnFailure: true },
* );
* ```
*/
declare function createStandardSchemaStorage<Output>(getStorage: () => StateStorage, schema: StandardSchemaV1<unknown, Output>, options?: StandardSchemaStorageOptions): PersistStorage<Output> | undefined;
/**
* JSON sugar over `withStandardSchemaAsync` for async `~standard` schemas
* (Yup, async refine). Sync schemas also work through this lane. Forces async
* hydrate even over `localStorage` — gate UI with `useHydrated`.
*
* @example
* ```ts
* import { createStandardSchemaStorageAsync } from "@stainless-code/persist/codecs/standard-schema";
*
* // Pass any async ~standard schema (Yup, async refine, …).
* const storage = createStandardSchemaStorageAsync<Prefs>(
* () => localStorage,
* yupSchema,
* { clearCorruptOnFailure: true },
* );
* ```
*/
declare function createStandardSchemaStorageAsync<Output>(getStorage: () => StateStorage, schema: StandardSchemaV1<unknown, Output>, options?: StandardSchemaStorageOptions): PersistStorage<Output> | undefined;
//#endregion
export { StandardSchemaStorageOptions, StandardSchemaV1, createStandardSchemaStorage, createStandardSchemaStorageAsync, standardSchemaCodec, withStandardSchema, withStandardSchemaAsync };