/** * Configuration for persistent state */ export interface PersistentStateConfig { key: string; defaultValue: T; storage?: 'localStorage' | 'sessionStorage'; serialize?: (value: T) => string; deserialize?: (value: string) => T; debounceMs?: number; version?: number; } /** * Create a persistent state that automatically syncs with storage * Uses Svelte 5 $state() for reactivity * * Besides `value`, the returned object exposes `hasStoredValue` — whether an * entry for this key exists in storage. That is what lets a consumer tell a * *stored empty* value (`[]`, `''`, `null` — the user cleared it) from *nothing * stored at all*, so a cleared state can win over a default/seed instead of * being re-applied on every load. Two rules keep that signal meaningful: a save * that would not change the stored bytes is skipped, and an instance nobody * wrote to never creates an entry for its own default (so `reset()` is not * undone by the auto-save, and untouched state stays out of storage). Writing * the default *back* — clearing — is a real write and does create the entry. * * Values must round-trip through the configured `serialize`/`deserialize`; * `Set`/`Map` do not under the `JSON.stringify` default (they serialize to * `{}`), so pass converting functions or store plain arrays/objects. */ export declare function createPersistentState(config: PersistentStateConfig): { value: T; /** * Whether storage currently holds an entry for this key: `true` when * construction (or `reload()`) found a parseable entry, and after a write * actually reached storage; `false` when the key was absent or corrupt, * after `reset()`, and always without a working storage (SSR, private * mode). Use it to distinguish a stored empty value from an absent one. */ readonly hasStoredValue: boolean; /** * Reset to default value and clear storage */ reset(): void; /** * Force immediate save (bypasses debounce). A no-op when storage already * holds exactly this value, and — like the auto-save — when the instance * was never written to and still holds its default. */ forceSave(): void; /** * Reload from storage */ reload(): void; }; /** * Storage addressing for a persistent preference channel: the id that scopes * the storage key, which web storage backs it, and how long writes debounce. * The shape the table's prefs factories (summaries, hidden columns, column * order, selection) take — nothing filter-specific about it. */ export interface PersistenceKeyConfig { tableId: string; storage?: 'localStorage' | 'sessionStorage'; debounceMs?: number; }