### Install devalue for Custom Serialization Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Instructions for installing the devalue package, which is recommended for serializing complex JavaScript objects like Maps, Sets, and Dates that JSON cannot handle natively. ```bash npm install devalue ``` -------------------------------- ### Full Example: Using persistedState Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Demonstrates configuring and using `persistedState` with custom options and types. Ensure the `UserPrefs` interface matches your state structure. ```typescript // Using persistedState import { persistedState } from 'svelte-persisted-state'; import type { Options } from 'svelte-persisted-state'; interface UserPrefs { theme: 'light' | 'dark'; } const config: Options = { storage: 'local', syncTabs: true }; const prefs = persistedState('prefs', { theme: 'light' }, config); ``` -------------------------------- ### Full Example: Using persistedStateAsync Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Shows how to set up `persistedStateAsync` with IndexedDB configuration. This is useful for larger data sets or when asynchronous storage is required. ```typescript // Using persistedStateAsync import { persistedStateAsync } from 'svelte-persisted-state'; import type { AsyncOptions, AsyncPersistedState } from 'svelte-persisted-state'; const config: AsyncOptions = { indexedDB: { dbName: 'my-app' } }; const data: AsyncPersistedState = persistedStateAsync('data', [], config); ``` -------------------------------- ### Install svelte-persisted-state Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Install the package using npm. This package requires Svelte 5. ```bash npm install svelte-persisted-state ``` -------------------------------- ### Usage Example with CookieOptions Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md Demonstrates how to configure persisted state to use cookie storage with custom cookie options. Ensure 'cookie' is specified as the storage type. ```typescript import { persistedState } from 'svelte-persisted-state'; const sessionCookie = persistedState('session', {}, { storage: 'cookie', cookieOptions: { expireDays: 7, path: '/app', sameSite: 'Strict', secure: true } }); ``` -------------------------------- ### IndexedDBOptions Usage Example Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md Shows how to configure IndexedDB options for both the high-level persistedStateAsync API and the low-level getItem/setItem functions, specifying custom database and store names. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; import { getItem, setItem } from 'svelte-persisted-state'; // High-level API const state = persistedStateAsync('key', {}, { indexedDB: { dbName: 'my-database', storeName: 'my-store', version: 1 } }); // Low-level API await setItem('key', 'value', { dbName: 'my-database', storeName: 'my-store', version: 1 }); const retrieved = await getItem('key', { dbName: 'my-database', storeName: 'my-store', version: 1 }); ``` -------------------------------- ### User Preferences with localStorage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Example of managing user preferences like theme and font size using localStorage. The `syncTabs` option ensures state consistency across browser tabs. ```typescript import { persistedState } from 'svelte-persisted-state'; interface Preferences { theme: 'light' | 'dark'; fontSize: number; } const prefs = persistedState('prefs', { theme: 'light', fontSize: 16 }, { syncTabs: true // Sync across browser tabs }); // In component: let theme = $derived(prefs.current.theme); ``` -------------------------------- ### Persist State with Cookie Storage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Shows how to use cookies for state persistence with custom expiration times. This example demonstrates persisting user session data and shopping cart items, each with different expiry durations. ```svelte {#if userSession.current.isLoggedIn}

Welcome back, {userSession.current.username}!

{:else} {/if}

Cart items: {cart.current.length}

``` -------------------------------- ### Persisted State Usage Example Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md Demonstrates how to use the `persistedState` function with custom options, including specifying storage, enabling tab synchronization, applying a `beforeWrite` transformation for validation, and handling write errors. ```typescript import { persistedState } from 'svelte-persisted-state'; interface UserPrefs { theme: 'light' | 'dark'; fontSize: number; } const prefs = persistedState( 'user-prefs', { theme: 'light', fontSize: 16 }, { storage: 'local', syncTabs: true, beforeWrite: (value) => { // Validation or transformation return { ...value, fontSize: Math.max(12, Math.min(32, value.fontSize)) }; }, onWriteError: (error) => { console.error('Failed to save preferences:', error); } } ); ``` -------------------------------- ### AsyncPersistedState Usage Example Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md Demonstrates how to use the persistedStateAsync function to manage asynchronous state, including checking loading status, waiting for hydration, modifying state, and resetting. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; const data = persistedStateAsync('data', []); // Check loading state if (data.isLoading) { console.log('Still loading...'); } // Wait for hydration await data.ready; console.log('Loaded:', data.current); // Modify state data.current = [...data.current, { id: 1, title: 'Item' }]; // Reset to initial value data.reset(); ``` -------------------------------- ### Large Dataset with IndexedDB Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Manage large datasets using IndexedDB with `persistedStateAsync`. This example shows how to configure IndexedDB storage, sync across tabs, and use `onHydrated` and `beforeWrite` hooks. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; interface AppData { notes: { id: string; title: string; content: string; created: Date }[]; lastSync: Date; syncInProgress: boolean; } const appData = persistedStateAsync( 'app-data', { notes: [], lastSync: new Date(), syncInProgress: false }, { indexedDB: { dbName: 'notes-app', storeName: 'app-state', version: 1 }, syncTabs: true, onHydrated: (data) => { console.log(`Loaded ${data.notes.length} notes`); }, beforeWrite: (value) => { // Don't persist sync status return { ...value, syncInProgress: false }; } } ); ``` -------------------------------- ### Using persistedStateAsync with AsyncOptions Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md Example demonstrating how to use persistedStateAsync with custom IndexedDB configuration and hydration callbacks. Ensure the AppState interface matches your application's state structure. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; interface AppState { user: { id: string; name: string } | null; settings: Map; } const appState = persistedStateAsync( 'app-state', { user: null, settings: new Map() }, { indexedDB: { dbName: 'my-app', storeName: 'state', version: 1 }, syncTabs: true, onHydrated: (value) => { console.log('App state loaded:', value); }, onHydrationError: (error) => { console.error('Failed to load app state:', error); } } ); ``` -------------------------------- ### Low-Level IndexedDB Utilities Import Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Shows the import statement for various low-level IndexedDB utility functions provided by the svelte-persisted-state library, including functions for opening, getting, setting, removing, and closing IndexedDB connections. ```typescript import { openDB, getItem, setItem, removeItem, closeDB, closeAllDBs, clearConnectionCache } from 'svelte-persisted-state'; ``` -------------------------------- ### Cookie-Based Session Storage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Example of configuring `persistedState` to use cookie storage for session data. Includes options for expiration and security. ```typescript import { persistedState } from 'svelte-persisted-state'; const session = persistedState('session', {}, { storage: 'cookie', cookieOptions: { expireDays: 30, secure: true, sameSite: 'Strict' } }); ``` -------------------------------- ### Quick Start: Initialize Persisted State Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/START_HERE.md Initialize a reactive state variable that automatically synchronizes with browser localStorage. Update it like normal Svelte state. ```typescript import { persistedState } from 'svelte-persisted-state'; // Your state automatically saves to localStorage const counter = persistedState('count', 0); // Update it like normal state counter.current = 5; // It's reactive in components //

{counter.current}

``` -------------------------------- ### Low-Level IndexedDB Utilities Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Provides direct access to IndexedDB operations for advanced use cases, including opening/closing databases, getting, setting, and removing items, and managing connection caches. ```APIDOC ## Low-Level IndexedDB Utilities ### Description This module exposes low-level functions for direct interaction with IndexedDB, offering granular control over database connections and data manipulation. These utilities are useful for advanced scenarios or custom storage logic. ### Imported Functions ```typescript import { openDB, getItem, setItem, removeItem, closeDB, closeAllDBs, clearConnectionCache } from 'svelte-persisted-state'; ``` ### Functions - **`openDB(name: string, version: number)`**: Opens or creates an IndexedDB database, returning a promise that resolves with the database instance. It also manages a connection cache. - **`getItem(db: IDBDatabase, storeName: string, key: IDBKeyPath)`**: Retrieves an item from a specified object store within an IndexedDB database. - **`setItem(db: IDBDatabase, storeName: string, key: IDBKeyPath, value: T)`**: Adds or updates an item in a specified object store. - **`removeItem(db: IDBDatabase, storeName: string, key: IDBKeyPath)`**: Deletes an item from a specified object store. - **`closeDB(db: IDBDatabase)`**: Closes a specific IndexedDB database connection. - **`closeAllDBs()`**: Closes all active IndexedDB connections managed by the library. - **`clearConnectionCache()`**: Clears the internal cache of IndexedDB connections, primarily useful for testing. ``` -------------------------------- ### Secure Cookie-Based Session Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Implement secure session management using cookie storage with `persistedState`. This example configures cookie options for security, including expiration, path, secure flag, and SameSite attribute. ```typescript import { persistedState } from 'svelte-persisted-state'; interface Session { token: string; userId: string; expiresAt: string; } const session = persistedState( 'auth-session', { token: '', userId: '', expiresAt: '' }, { storage: 'cookie', cookieOptions: { expireDays: 30, path: '/app', secure: true, // HTTPS only sameSite: 'Strict', // No cross-site requests httpOnly: false // JavaScript accessible (real browsers ignore this) }, beforeRead: (value) => { // Validate expiration const now = new Date().toISOString(); if (value.expiresAt < now) { return { token: '', userId: '', expiresAt: '' }; // Expired } return value; } } ); ``` -------------------------------- ### Cookie Storage Configuration Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Example of configuring persistedState to use cookies for storage, suitable for SSR or cross-subdomain persistence. Specify `storage: 'cookie'` and optionally configure cookie options like expiration. ```typescript import { persistedState } from 'svelte-persisted-state'; const cookieState = persistedState('myCookieKey', 'defaultValue', { storage: 'cookie', cookieOptions: { expireDays: 30 // Custom expiration } }); ``` -------------------------------- ### Open or Get Cached IndexedDB Connection Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/indexeddb-storage.md Opens a new IndexedDB connection or returns a cached one if available. Automatically handles schema creation on first access. Use for custom storage scenarios requiring direct database access. ```typescript import { openDB } from 'svelte-persisted-state'; const connection = await openDB({ dbName: 'my-app', storeName: 'users', version: 1 }); console.log(connection.db.name); console.log(connection.storeName); const cached = await openDB({ dbName: 'my-app', storeName: 'users', version: 1 }); ``` -------------------------------- ### Get Item from IndexedDB Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Retrieve a value from IndexedDB using a key. Optionally accepts IndexedDBOptions. ```typescript export async function getItem( key: string, options?: IndexedDBOptions ): Promise ``` -------------------------------- ### Get Item from IndexedDB Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Retrieve a value from IndexedDB using the getItem function. It takes a key as an argument. ```typescript const value = await getItem('key'); ``` -------------------------------- ### Open IndexedDB with Version Management Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/indexeddb-storage.md Shows how to open an IndexedDB database and manage its version. Incrementing the version number triggers schema migrations if the current version is lower. ```typescript // First deployment: version 1 await openDB({ dbName: 'app', version: 1 }); // Later: need to add an index or create a new store await openDB({ dbName: 'app', version: 2 }); // This triggers onupgradeneeded if version < 2 ``` -------------------------------- ### Usage of Storage Types Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md Shows how to specify different storage types when initializing persistedState. Each type offers different persistence and tab synchronization behaviors. ```typescript import { persistedState } from 'svelte-persisted-state'; const localStorage_state = persistedState('key', 'value', { storage: 'local' }); const sessionStorage_state = persistedState('key', 'value', { storage: 'session' }); const cookie_state = persistedState('key', 'value', { storage: 'cookie' }); ``` -------------------------------- ### Initialize with localStorage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Use localStorage for persistent data across browser sessions. It's the default storage type and offers cross-tab synchronization. ```typescript import { persistedState } from 'svelte-persisted-state'; const state = persistedState('my-key', 'initial-value', { storage: 'local' // or omit, as it's the default }); ``` -------------------------------- ### Awaiting State Hydration in JavaScript Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/persisted-state-async.md Shows how to use the `await data.ready` pattern in a JavaScript async function to ensure state hydration is complete before proceeding with application logic that depends on the persisted state. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; async function initializeApp() { const data = persistedStateAsync('app-data', { initialized: false }); // Wait for hydration before proceeding const hydratedValue = await data.ready; console.log('App initialized with:', hydratedValue); // Now safe to use data.current if (!data.current.initialized) { data.current = { initialized: true }; } } initializeApp(); ``` -------------------------------- ### Handle Storage Quota Exceeded Write Error Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/errors.md Use `onWriteError` to detect and handle `QuotaExceededError` when storage is full. This example shows strategies like deleting old data. ```typescript import { persistedState } from 'svelte-persisted-state'; const state = persistedState('data', { size: 0 }, { onWriteError: (error) => { if (error instanceof DOMException && error.name === 'QuotaExceededError') { console.error('Storage quota exceeded. Attempting cleanup...'); // Strategy 1: Delete old data localStorage.removeItem('cache'); localStorage.removeItem('temp'); // Strategy 2: Reduce data size // Strategy 3: Request persistent storage } else { console.error('Unexpected write error:', error); } } }); try { // This might trigger QuotaExceededError state.current = { size: 1000000 }; } catch { // Note: errors are not thrown, but handled in callback } ``` -------------------------------- ### Handling Loading States with isLoading or #await Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Optionally display loading indicators while data is hydrating using the `isLoading` property or the `{#await}` block with the `ready` promise. ```svelte {#if data.isLoading} {:else} {/if} {#await data.ready}

Loading...

{:then} {:catch error}

Error: {error.message}

{/await} ``` -------------------------------- ### Basic Persisted State in JavaScript Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Demonstrates basic usage of persistedState for simple string values. Import the function and initialize state with a key and initial value. Access and modify the state using the `.current` property and reset it with `.reset()`. ```javascript import { persistedState } from 'svelte-persisted-state'; const myState = persistedState('myKey', 'initialValue'); // Use myState.current to get or set the state console.log(myState.current); myState.current = 'newValue'; // Reset to initial value myState.reset(); ``` -------------------------------- ### AsyncPersistedState Interface Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md The AsyncPersistedState interface represents the state object returned by `persistedStateAsync`. It provides methods to get, set, and reset the current state, along with properties to track loading status and readiness. ```APIDOC ## AsyncPersistedState The state object returned by `persistedStateAsync`. ### Definition ```typescript export interface AsyncPersistedState { get current(): T; set current(newValue: T); readonly isLoading: boolean; readonly ready: Promise; reset(): void; } ``` ### Properties | Property | Type | Description | |----------|------|-------------| | `current` | `T` (getter/setter) | Gets or sets the current state. Initially returns `initialValue`; updated when hydration completes. | | `isLoading` | `boolean` (readonly) | `true` while hydration is in progress, `false` once complete. | | `ready` | `Promise` (readonly) | Promise that resolves with the hydrated value when loading completes, or rejects if hydration fails. | ### Methods | Method | Returns | Description | |--------|---------|-------------| | `reset()` | `void` | Resets the state to its `initialValue` and persists the reset. | ### Usage ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; const data = persistedStateAsync('data', []); // Check loading state if (data.isLoading) { console.log('Still loading...'); } // Wait for hydration await data.ready; console.log('Loaded:', data.current); // Modify state data.current = [...data.current, { id: 1, title: 'Item' }]; // Reset to initial value data.reset(); ``` ``` -------------------------------- ### IndexedDB Storage Utilities Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/_MANIFEST.txt Provides low-level utilities for interacting with IndexedDB as a storage backend, including functions to open, read, write, and close IndexedDB databases. ```APIDOC ## IndexedDB Storage Utilities ### Description This module exposes low-level functions for managing IndexedDB storage, allowing for direct interaction with the database for advanced use cases or custom storage implementations. ### Available Functions - **openDB(name: string, version: number, options?: IndexedDBOptions): Promise** Opens or creates an IndexedDB database. - **getItem(db: IDBDatabase, storeName: string, key: IDBKeyPath): Promise** Retrieves an item from a specified object store. - **setItem(db: IDBDatabase, storeName: string, key: IDBKeyPath, value: T): Promise** Adds or updates an item in a specified object store. - **removeItem(db: IDBDatabase, storeName: string, key: IDBKeyPath): Promise** Removes an item from a specified object store. - **closeDB(db: IDBDatabase): void** Closes a specific IndexedDB database connection. - **closeAllDBs(): Promise** Closes all open IndexedDB database connections managed by the library. - **clearConnectionCache(): void** Clears the internal cache of database connections. ### Parameters - **db** (IDBDatabase) - An active IndexedDB database connection. - **storeName** (string) - The name of the object store within the database. - **key** (IDBKeyPath) - The key of the item to retrieve, add, update, or remove. - **value** (T) - The value to store for the given key. - **name** (string) - The name of the IndexedDB database. - **version** (number) - The version of the database schema. - **options** (IndexedDBOptions) - Optional configuration for IndexedDB operations. ### Request Example ```javascript import { openDB, getItem, setItem } from 'svelte-persisted-state/indexeddb-storage'; async function manageUserData() { const db = await openDB('my-app-db', 1, { upgrade(db) { db.createObjectStore('user-data'); } }); await setItem(db, 'user-data', 'profile', { name: 'Bob' }); const user = await getItem(db, 'user-data', 'profile'); console.log(user); closeDB(db); } ``` ### Response Functions typically return Promises that resolve with the result of the IndexedDB operation (e.g., retrieved data, void for write operations, or the database connection itself). ``` -------------------------------- ### Persist Typed State with localStorage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Demonstrates how to persist a typed state object using localStorage. It initializes with default values and allows modification of theme and font size, which are then reflected in the UI. ```svelte

Current theme: {theme}

Current font size: {fontSize}px

``` -------------------------------- ### Initialize with sessionStorage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Utilize sessionStorage for temporary data that is cleared when the tab or window closes. Each tab maintains its own storage. ```typescript import { persistedState } from 'svelte-persisted-state'; const state = persistedState('session-key', {}, { storage: 'session' }); ``` -------------------------------- ### Configure IndexedDB for persistedStateAsync Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Set custom database and store names for IndexedDB persistence. Defaults are 'svelte-persisted-state' for dbName and 'state' for storeName. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; const state = persistedStateAsync('my-key', {}, { indexedDB: { dbName: 'my-app-db', storeName: 'my-store', version: 1 } }); ``` -------------------------------- ### Options Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Configuration object for the `persistedState` function. Allows customization of storage type, serialization, tab synchronization, cookie settings, and error handling. ```APIDOC ## Interface Options ### Description Configuration object for `persistedState`. ### Fields - **storage** (StorageType) - Optional - Specifies the storage backend ('local', 'session', 'cookie'). - **serializer** (Serializer) - Optional - Custom object for serializing and deserializing values. - **syncTabs** (boolean) - Optional - Whether to synchronize state across browser tabs. - **cookieExpireDays** (number) - Deprecated - Number of days for cookie expiration. - **cookieOptions** (CookieOptions) - Optional - Advanced cookie-specific configuration. - **onWriteError** ((error: unknown) => void) - Optional - Callback function for write errors. - **onParseError** ((error: unknown) => void) - Optional - Callback function for parse errors. - **beforeRead** ((value: T) => T) - Optional - Transformation function applied before reading a value. - **beforeWrite** ((value: T) => T) - Optional - Transformation function applied before writing a value. ``` -------------------------------- ### Error Handling with Fallbacks Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Illustrates setting up error handlers for write and parse errors. Provides fallback mechanisms to maintain application stability. ```typescript import { persistedState } from 'svelte-persisted-state'; const state = persistedState('data', { fallback: true }, { onWriteError: (error) => { console.warn('Data could not be saved:', error); // App continues with in-memory state }, onParseError: (error) => { console.warn('Stored data was corrupted, using defaults'); // State automatically reverts to initialValue } }); ``` -------------------------------- ### Handle IndexedDB Write Transaction Failure Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/errors.md Implement `onWriteError` to be notified when an IndexedDB write operation fails, for example, if the database becomes inaccessible or quota is exceeded during a transaction. Note that the in-memory state will still be updated, but persistence will be lost on page reload. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; const state = persistedStateAsync('data', { count: 0 }, { onWriteError: (error) => { console.error('Failed to write to IndexedDB:', error); // State value is updated, but persistence failed // Data will be lost on page reload } }); state.current = { count: 1 }; // If database is inaccessible, onWriteError is called // But state.current is now { count: 1 } in memory ``` -------------------------------- ### StorageType Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md An enumeration of supported storage backends for persisted state. ```APIDOC ## Type StorageType ### Description Storage backend identifier. ### Values - 'local': Use browser's localStorage. - 'session': Use browser's sessionStorage. - 'cookie': Use browser's cookies. ``` -------------------------------- ### Basic Async State with IndexedDB Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/persisted-state-async.md Demonstrates basic usage of persistedStateAsync for managing an array of notes. The state is initialized with an empty array and hydrates asynchronously from IndexedDB. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; const notes = persistedStateAsync('notes', []); // Returns immediately with [] console.log(notes.current); // [] // Hydration happens in the background await notes.ready; console.log('Loaded:', notes.current); // Persist changes notes.current = [...notes.current, { id: 1, text: 'Buy milk' }]; ``` -------------------------------- ### Initialize with Cookie Storage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Configure cookie storage for data that needs to persist until expiration and be accessible on the server. Note the size limit per cookie. ```typescript import { persistedState } from 'svelte-persisted-state'; const state = persistedState('cookie-key', 'value', { storage: 'cookie', cookieOptions: { expireDays: 30, sameSite: 'Strict', secure: true } }); ``` -------------------------------- ### User Preferences with Tab Synchronization Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/START_HERE.md Sets up persisted state for user preferences, enabling synchronization across different browser tabs. ```typescript const prefs = persistedState('prefs', { theme: 'light', fontSize: 16 }, { syncTabs: true } ); ``` -------------------------------- ### Large Dataset with IndexedDB Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Demonstrates using `persistedStateAsync` for managing large datasets with IndexedDB. The UI remains responsive as data loads in the background. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; const notes = persistedStateAsync('notes', []); // Use immediately (shows initial empty array) // Data loads in background without blocking UI ``` -------------------------------- ### Custom IndexedDB Configuration Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/persisted-state-async.md Illustrates how to customize the IndexedDB configuration for persistedStateAsync, allowing specification of the database name, store name, and version. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; const appState = persistedStateAsync('app-state', {}, { indexedDB: { dbName: 'my-app', storeName: 'app-data', version: 2 } }); await appState.ready; ``` -------------------------------- ### User Preferences with Fallback Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Configure user preferences with default values and a fallback mechanism using `beforeRead`. This ensures backwards compatibility by merging new defaults with existing stored values. ```typescript import { persistedState } from 'svelte-persisted-state'; interface UserPrefs { theme: 'light' | 'dark'; fontSize: number; language: string; } const defaults: UserPrefs = { theme: 'light', fontSize: 16, language: 'en' }; const prefs = persistedState('user-prefs', defaults, { storage: 'local', syncTabs: true, beforeRead: (value) => { ...defaults, ...value // Merge with defaults (backwards compatible) }, onWriteError: (error) => { console.warn('Could not save preferences:', error); } }); ``` -------------------------------- ### Correct Named Exports Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Demonstrates the correct way to import named exports from the svelte-persisted-state package. ```typescript // ✅ Correct import { persistedState, persistedStateAsync } from 'svelte-persisted-state'; ``` -------------------------------- ### Minimal persistedStateAsync Usage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Demonstrates the minimal usage of `persistedStateAsync` for managing an array of items. It shows how to wait for the data to be ready and then push a new item. ```typescript const data = persistedStateAsync('items', []); await data.ready; data.current.push({ id: 1 }); ``` -------------------------------- ### IndexedDBOptions Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/persisted-state-async.md Configuration options for persisting state to IndexedDB. ```APIDOC ## Interface: IndexedDBOptions ### Description Options to configure the IndexedDB storage for persisted state. ### Properties | Key | Type | Default | Description | |-----|------|---------|-------------| | `dbName` | `string` | `'svelte-persisted-state'` | IndexedDB database name | | `storeName` | `string` | `'state'` | Object store name within the database | | `version` | `number` | `1` | Database schema version; increment to trigger `onupgradeneeded` | ``` -------------------------------- ### Minimal persistedState Usage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Demonstrates the minimal usage of `persistedState` for managing a simple counter. It shows how to initialize a state variable and update its value. ```typescript const counter = persistedState('count', 0); counter.current = 5; counter.reset(); ``` -------------------------------- ### IndexedDBOptions Configuration Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/types.md The IndexedDBOptions interface allows configuration for selecting the IndexedDB database and object store. These options can be used with both the high-level `persistedStateAsync` and low-level `setItem`/`getItem` functions. ```APIDOC ## IndexedDBOptions Configuration object for IndexedDB database and object store selection. ### Definition ```typescript export interface IndexedDBOptions { dbName?: string; storeName?: string; version?: number; } ``` ### Properties | Property | Type | Default | Description | |----------|------|---------|-------------| | `dbName` | `string` | `'svelte-persisted-state'` | IndexedDB database name. | | `storeName` | `string` | `'state'` | Object store name within the database. | | `version` | `number` | `1` | Database schema version. Increment to trigger `onupgradeneeded` events. | ### Usage ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; import { getItem, setItem } from 'svelte-persisted-state'; // High-level API const state = persistedStateAsync('key', {}, { indexedDB: { dbName: 'my-database', storeName: 'my-store', version: 1 } }); // Low-level API await setItem('key', 'value', { dbName: 'my-database', storeName: 'my-store', version: 1 }); const retrieved = await getItem('key', { dbName: 'my-database', storeName: 'my-store', version: 1 }); ``` ``` -------------------------------- ### CookieOptions Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Provides detailed configuration for cookie-based storage, including expiration, path, domain, security, and SameSite attributes. ```APIDOC ## Interface CookieOptions ### Description Cookie-specific configuration. ### Fields - **expireDays** (number) - Optional - Number of days until the cookie expires. - **maxAge** (number) - Optional - Maximum age of the cookie in seconds. - **path** (string) - Optional - The path the cookie is valid for. - **domain** (string) - Optional - The domain the cookie is valid for. - **secure** (boolean) - Optional - Whether the cookie should only be sent over HTTPS. - **sameSite** ('Strict' | 'Lax' | 'None') - Optional - Controls when cookies are sent with cross-site requests. - **httpOnly** (boolean) - Optional - Whether the cookie is accessible via client-side scripts. ``` -------------------------------- ### Interface Definitions for Options Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/README.md Defines interfaces for configuration options, including synchronous, asynchronous, cookie, and IndexedDB specific options. ```typescript interface Options { /* ... */ } interface AsyncOptions { /* ... */ } interface CookieOptions { /* ... */ } interface IndexedDBOptions { /* ... */ } ``` -------------------------------- ### Custom JSON Serialization Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/persisted-state-async.md Demonstrates how to opt-in to using the standard JSON serializer instead of the default Structured Clone algorithm for persistedStateAsync. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; // Use JSON instead of Structured Clone const state = persistedStateAsync('data', { count: 0 }, { serializer: JSON }); await state.ready; state.current = { count: 5 }; ``` -------------------------------- ### Loading Large Datasets with Async Storage Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/START_HERE.md Initializes persisted state for large datasets using asynchronous storage (IndexedDB). It's necessary to await the 'ready' promise before accessing the data. ```typescript const notes = persistedStateAsync('notes', []); await notes.ready; // Wait for IndexedDB load ``` -------------------------------- ### Recommended Imports for Persisted State Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Import the main API functions for managing persisted state. Includes types for TypeScript projects. ```typescript // Main API import { persistedState, persistedStateAsync } from 'svelte-persisted-state'; // Types (for TypeScript) import type { AsyncOptions, AsyncPersistedState, IndexedDBOptions } from 'svelte-persisted-state'; ``` -------------------------------- ### Transforming Data on Read/Write Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/persisted-state-async.md Shows how to transform data before writing to storage (`beforeWrite`) and after reading from storage (`beforeRead`) using persistedStateAsync. Includes an `onHydrated` callback for post-hydration actions. ```typescript import { persistedStateAsync } from 'svelte-persisted-state'; interface Config { secretKey: string; settings: object; } const config = persistedStateAsync('config', { secretKey: '', settings: {} }, { beforeWrite: (value) => { // Encrypt before storing return { ...value, secretKey: encrypt(value.secretKey) }; }, beforeRead: (value) => { // Decrypt after loading return { ...value, secretKey: decrypt(value.secretKey) }; }, onHydrated: (value) => console.log('Config loaded:', value) } ); ``` -------------------------------- ### Persisted State with Custom Serializer (devalue) Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Demonstrates using a custom serializer with persistedState to handle complex data types. Import devalue and create a serializer object with `stringify` and `parse` methods. This allows persisting Maps, Sets, Dates, and nested structures. ```typescript import { persistedState } from 'svelte-persisted-state'; import * as devalue from 'devalue'; const devalueSerializer = { stringify: devalue.stringify, parse: devalue.parse }; // Works with Maps, Sets, Dates, nested structures, etc. export const complexData = persistedState( 'complexData', { name: 'Example', created: new Date(), nested: { array: [1, 2, 3], map: new Map([ ['key1', 'value1'], ['key2', 'value2'] ]), set: new Set([1, 2, 3]) } }, { serializer: devalueSerializer } ); // Tip: if you mutate a Map/Set in-place, reassign to trigger reactivity: // complexData.current.nested.map.set('key3', 'value3'); // complexData.current = { ...complexData.current }; ``` -------------------------------- ### Test IndexedDB Storage Operations Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/api-reference/indexeddb-storage.md Provides a comprehensive test suite for IndexedDB storage using Vitest. It covers setting, retrieving, and handling non-existent keys, ensuring data integrity and correct behavior. ```typescript import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { setItem, getItem, removeItem, closeAllDBs, clearConnectionCache } from 'svelte-persisted-state'; describe('IndexedDB Storage', () => { beforeEach(() => { closeAllDBs(); clearConnectionCache(); }); afterEach(() => { closeAllDBs(); clearConnectionCache(); }); it('should store and retrieve values', async () => { const testData = { name: 'Test', count: 42, timestamp: new Date() }; await setItem('test-key', testData); const retrieved = await getItem('test-key'); expect(retrieved).toEqual(testData); expect(retrieved.timestamp instanceof Date).toBe(true); }); it('should return null for non-existent keys', async () => { const result = await getItem('nonexistent'); expect(result).toBeNull(); }); }); ``` -------------------------------- ### Use Multiple IndexedDB Databases Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Organize state into different databases and stores by specifying unique dbName and storeName for each persisted state instance. ```typescript // User data in one database const userData = persistedStateAsync('user', {}, { indexedDB: { dbName: 'users', storeName: 'profiles' } }); // App settings in another const appSettings = persistedStateAsync('settings', {}, { indexedDB: { dbName: 'app', storeName: 'config' } }); ``` -------------------------------- ### Typed Persisted State with Options Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Shows how to use persistedState with TypeScript for type safety and custom storage options. Define an interface for your state and pass it as a generic type argument. Configure storage, tab synchronization, and error handling callbacks. ```typescript import { persistedState } from 'svelte-persisted-state'; interface UserPreferences { theme: 'light' | 'dark'; fontSize: number; notifications: boolean; } const userPreferences = persistedState( 'userPreferences', { theme: 'light', fontSize: 16, notifications: true }, { storage: 'local', syncTabs: true, beforeWrite: (value) => { console.log('Saving preferences:', value); return value; }, onWriteError: (error) => { console.error('Failed to save preferences:', error); } } ); function toggleTheme() { userPreferences.current.theme = userPreferences.current.theme === 'light' ? 'dark' : 'light'; } // Using $derived for reactive computations const theme = $derived(userPreferences.current.theme); // The UI will automatically update when the state changes ``` -------------------------------- ### Peer Dependencies Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Specifies the required Svelte version for the package. ```json { "svelte": "^5.0.0-next.1" } ``` -------------------------------- ### Configure Error Handling for Persistence Operations Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Set up callbacks for various error scenarios, including database writes, parsing custom serializers, and hydration failures. These allow for custom error logging or recovery logic. ```typescript const state = persistedStateAsync('data', {}, { onWriteError: (error) => { console.error('Database write failed:', error); }, onParseError: (error) => { console.error('Parse failed:', error); // Only triggered if using custom serializer }, onHydrationError: (error) => { console.error('Hydration failed:', error); } }); ``` -------------------------------- ### Package.json Exports Configuration Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Defines the export map for the package, enabling ESM imports, type resolution, and Svelte integration. ```json { "exports": { ".": { "types": "./dist/index.svelte.d.ts", "svelte": "./dist/index.svelte.js" } }, "types": "./dist/index.svelte.d.ts", "svelte": "./dist/index.svelte.js" } ``` -------------------------------- ### persistedState (Sync) Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/README.md Creates a synchronous persisted state that automatically syncs with localStorage, sessionStorage, or browser cookies. It allows for custom storage types, serialization, tab synchronization, and error handling. ```APIDOC ## persistedState (Sync) ### Description The `persistedState` function creates a persisted state that automatically syncs with local storage, session storage, or browser cookies. ### Parameters - `key` (string): A string key used for storage. - `initialValue` (any): The initial value of the state. - `options` (object, optional): An optional object with the following properties: - `storage` (string): 'local' (default), 'session', or 'cookie'. - `serializer` (object): Custom serializer object with `parse` and `stringify` methods (default: JSON). - `syncTabs` (boolean): Boolean to sync state across tabs (default: true, only works with localStorage). - `cookieOptions` (object): Cookie-specific configuration object (only applies when storage is 'cookie'): - `expireDays` (number): Number of days before cookie expires (default: 365, max: 400 due to browser limits). - `maxAge` (number): Max-Age in seconds (takes precedence over expireDays if both are specified). - `path` (string): Cookie path (default: '/'). - `domain` (string): Cookie domain (default: current domain). - `secure` (boolean): Secure flag - cookie only sent over HTTPS (default: false). - `sameSite` (string): SameSite attribute for CSRF protection - 'Strict' | 'Lax' | 'None' (default: 'Lax'). - `httpOnly` (boolean): HttpOnly flag - prevents client-side script access (default: false). - `onWriteError` (function): Function to handle write errors. - `onParseError` (function): Function to handle parse errors. - `beforeRead` (function): Function to process value before reading. - `beforeWrite` (function): Function to process value before writing. ### Return Value The `persistedState` function returns an object with the following properties: - `current` (any): Get or set the current state value. - `reset()`: Reset the state to its initial value. ``` -------------------------------- ### IndexedDBOptions Interface Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/EXPORTS.md Configuration for IndexedDB database and object store. Specifies database name, store name, and version. ```typescript export interface IndexedDBOptions { dbName?: string; storeName?: string; version?: number; } ``` -------------------------------- ### Configure IndexedDB Schema Versioning Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Manage IndexedDB schema versions to handle database upgrades. Specify the version number in the options; a change triggers onupgradeneeded if the new version is higher than the existing one. ```typescript // Initial version const state = persistedStateAsync('key', {}, { indexedDB: { dbName: 'app', version: 1 } }); // Later: need schema change const state2 = persistedStateAsync('key', {}, { indexedDB: { dbName: 'app', version: 2 } // This triggers onupgradeneeded if version < 2 }); ``` -------------------------------- ### Configure SameSite Cookie Security Source: https://github.com/oman-rod/svelte-persisted-state/blob/main/_autodocs/configuration.md Configure the `sameSite` attribute for CSRF protection. Options include 'Strict', 'Lax' (default), and 'None' (requires `secure: true`). ```typescript // Strict: Cookie never sent in cross-site requests const strictCookie = persistedState('c1', 'v', { storage: 'cookie', cookieOptions: { sameSite: 'Strict' } }); // Lax: Cookie sent in top-level navigations (default) const laxCookie = persistedState('c2', 'v', { storage: 'cookie', cookieOptions: { sameSite: 'Lax' } }); // None: Cookie sent in all requests (requires secure: true) const noneCookie = persistedState('c3', 'v', { storage: 'cookie', cookieOptions: { sameSite: 'None', secure: true } }); ```