### Install IDB-Keyval via npm Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Install the idb-keyval package using npm. This is the recommended method for use with module bundlers. ```sh npm install idb-keyval ``` -------------------------------- ### Basic idb-keyval Usage Pattern Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Provides a fundamental example of using idb-keyval for setting, getting, updating, batching, retrieving all data, and deleting values with an optional store. ```typescript // Create or use default store const store = createStore('database', 'objectstore'); // Set a value await set('key', value, store); // Get a value const value = await get('key', store); // Atomic update await update('counter', (val) => (val || 0) + 1, store); // Batch operations await setMany([['a', 1], ['b', 2]], store); const values = await getMany(['a', 'b'], store); // Retrieve all data const allKeys = await keys(store); const allValues = await values(store); const allEntries = await entries(store); // Delete operations await del('key', store); await delMany(['a', 'b'], store); await clear(store); ``` -------------------------------- ### Get All Keys with keys Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Retrieve all keys present in the store. Ensure keys is imported. ```javascript import { keys } from 'idb-keyval'; // logs: [123, 'hello'] keys().then((keys) => console.log(keys)); ``` -------------------------------- ### Custom Store Usage Example Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/types.md Demonstrates how to create and use a custom store function with idb-keyval methods to specify custom database and store names. ```typescript import { createStore, set } from 'idb-keyval'; // Create a custom store function const customStore = createStore('my-db', 'my-store'); // Pass it to any idb-keyval method set('key', 'value', customStore); ``` -------------------------------- ### Import core functions Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Import the get and set functions from the idb-keyval library for use in your project. ```js import { get, set } from 'idb-keyval'; ``` -------------------------------- ### Session store example Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/createStore.md Shows how to create a dedicated store for session data, including initializing session details and retrieving the session ID. The entire session can be cleared using `clear`. ```typescript import { createStore, set, get, clear } from 'idb-keyval'; const sessionStore = createStore('session-db', 'session-data'); async function initializeSession(sessionId) { await set('id', sessionId, sessionStore); await set('started', new Date(), sessionStore); } async function getSessionId() { return get('id', sessionStore); } async function endSession() { await clear(sessionStore); } ``` -------------------------------- ### Clear with confirmation Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/clear.md This example demonstrates how to prompt the user for confirmation before clearing the store, preventing accidental data loss. Import `clear` from 'idb-keyval'. ```typescript import { clear } from 'idb-keyval'; const confirmed = confirm('Delete all data?'); if (confirmed) { await clear(); console.log('All data deleted'); } ``` -------------------------------- ### Get All Values with values Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Retrieve all values stored in the store. Ensure values is imported. ```javascript import { values } from 'idb-keyval'; // logs: [456, 'world'] values().then((values) => console.log(values)); ``` -------------------------------- ### Define and Use a Custom Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/custom-stores.md Use `createStore` to specify custom database and store names for `idb-keyval` operations. This example shows how to set a key-value pair in a custom store. ```javascript import { set, createStore } from 'idb-keyval'; const customStore = createStore('custom-db-name', 'custom-store-name'); set('hello', 'world', customStore); ``` -------------------------------- ### Bulk Cleanup of Cache Entries with delMany Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/delMany.md Example of performing a bulk cleanup of cache entries by filtering and deleting keys that start with 'cache:'. ```typescript import { delMany, keys } from 'idb-keyval'; // Clear all cache entries while preserving important data const allKeys = await keys(); const cacheKeys = allKeys.filter(k => k.startsWith('cache:')); if (cacheKeys.length > 0) { await delMany(cacheKeys); console.log(`Cleared ${cacheKeys.length} cache entries`); } ``` -------------------------------- ### Get a value by key Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Use the `get` function to retrieve the value associated with a given key. If the key does not exist, `get` resolves with `undefined`. ```js import { get } from 'idb-keyval'; // logs: "world" get('hello').then((val) => console.log(val)); ``` -------------------------------- ### Get Store Statistics Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/keys.md Retrieves all keys and logs the total number of entries in the store. This provides a quick way to get a count of items stored. ```typescript import { keys } from 'idb-keyval'; const allKeys = await keys(); console.log('Store contains', allKeys.length, 'entries'); ``` -------------------------------- ### Emergency data cleanup Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/clear.md This example demonstrates an emergency data cleanup procedure, including error handling for the `clear` operation. Import `clear` from 'idb-keyval'. ```typescript import { clear } from 'idb-keyval'; async function emergencyCleanup() { try { await clear(); console.log('Emergency cleanup complete'); } catch (err) { console.error('Cleanup failed:', err); } } ``` -------------------------------- ### Get All Entries with entries Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Retrieve all key-value pairs from the store as an array of [key, value] arrays. Ensure entries is imported. ```javascript import { entries } from 'idb-keyval'; // logs: [[123, 456], ['hello', 'world']] entries().then((entries) => console.log(entries)); ``` -------------------------------- ### Basic Caching Implementation Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Implement a basic caching mechanism by storing fetched data. Requires get and set imports from 'idb-keyval'. ```typescript import { get, set } from 'idb-keyval'; async function getCachedUser(id) { let user = await get(`user:${id}`); if (!user) { user = await fetchFromAPI(`/users/${id}`); await set(`user:${id}`, user); } return user; } ``` -------------------------------- ### Create a custom store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/createStore.md Use createStore to define custom database and store names. This custom store can then be passed to idb-keyval methods like set and get. ```typescript import { createStore, set, get } from 'idb-keyval'; const customStore = createStore('my-app-db', 'my-store'); await set('key', 'value', customStore); const value = await get('key', customStore); ``` -------------------------------- ### Get all entries Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/entries.md Retrieves all key-value pairs from the store. This is the most basic usage of the entries() function. ```typescript import { entries } from 'idb-keyval'; const allEntries = await entries(); console.log('All entries:', allEntries); // Output: [['user:1', { name: 'Alice' }], ['user:2', { name: 'Bob' }]] ``` -------------------------------- ### Basic Retrieval with get Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/get.md Use the basic get function to retrieve a value by its key. The promise resolves with the stored value or undefined if the key is not found. ```typescript import { get } from 'idb-keyval'; const value = await get('username'); console.log(value); // Logs the stored value, or undefined if not found ``` -------------------------------- ### Get All Keys Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/keys.md Retrieves all keys from the default store. The keys are logged to the console. This is the most basic usage of the `keys` function. ```typescript import { keys } from 'idb-keyval'; const allKeys = await keys(); console.log('All keys:', allKeys); // Output: ['user:1', 'user:2', 'cache:data', 'settings'] ``` -------------------------------- ### Get All Values Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/values.md Retrieves all values from the default store. Use this when you need to process all stored data. ```typescript import { values } from 'idb-keyval'; const allValues = await values(); console.log('All values:', allValues); ``` -------------------------------- ### Retrieval with Custom Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/get.md Use a custom store configuration with the get function to interact with non-default database or store names. Ensure the custom store is created using createStore. ```typescript import { get, createStore } from 'idb-keyval'; const customStore = createStore('app-db', 'app-store'); const value = await get('key', customStore); ``` -------------------------------- ### Using the Default Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Operations use a default store unless specified. Imports are required for get and set operations. ```typescript import { get, set } from 'idb-keyval'; // Uses default store: database="keyval-store", store="keyval" await set('key', 'value'); const value = await get('key'); ``` -------------------------------- ### Iterate Over All Entries Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/keys.md Retrieves all keys and then iterates through them to fetch and log each corresponding value using the `get` function. This pattern is useful for processing all data in the store. ```typescript import { keys, get } from 'idb-keyval'; const allKeys = await keys(); for (const key of allKeys) { const value = await get(key); console.log(key, ':', value); } ``` -------------------------------- ### Simple Set Operation Data Flow Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/architecture.md Illustrates the data flow for a simple 'set' operation, starting from the function call to the promise resolving when data is written to IndexedDB. ```plaintext set('key', value) ↓ uses defaultGetStore() ↓ customStore('readwrite', (store) => { store.put(value, key) return promisifyRequest(store.transaction) }) ↓ promisifyRequest waits for transaction.oncomplete ↓ Promise resolves when written to IDB ``` -------------------------------- ### Clear on logout Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/clear.md A practical example of using `clear` to remove cached user data during a logout process. Import `clear` from 'idb-keyval'. ```typescript import { clear } from 'idb-keyval'; async function logout() { // Clear all cached user data await clear(); // Redirect to login page window.location.href = '/login'; } ``` -------------------------------- ### Session Storage with Custom Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Manage session data using a custom store created with createStore. Requires imports for createStore, set, get, and clear. ```typescript import { createStore, set, get, clear } from 'idb-keyval'; const session = createStore('session', 'data'); async function login(credentials) { const token = await authenticateAPI(credentials); await set('token', token, session); } async function logout() { await clear(session); } ``` -------------------------------- ### Custom store pattern for advanced use cases Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/overview.md Demonstrates passing a custom store function to operations like set and get for advanced transaction management. ```typescript import { createStore, set, get } from 'idb-keyval'; const customStore = createStore('custom-db', 'custom-store'); await set('key', 'value', customStore); const value = await get('key', customStore); ``` -------------------------------- ### Custom store for feature flags Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/createStore.md Utilizes createStore to manage feature flag configurations in a dedicated store. This example shows initializing multiple feature flags using setMany. ```typescript import { createStore, setMany } from 'idb-keyval'; const featureFlags = createStore('app-state', 'features'); const initialFlags = [ ['feature.darkMode', false], ['feature.betaUI', true], ['feature.analytics', true] ]; await setMany(initialFlags, featureFlags); ``` -------------------------------- ### Reset app state Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/clear.md An example of resetting the application's state by clearing the store and then reinitializing default values. Includes basic error handling. Import `clear` from 'idb-keyval'. ```typescript import { clear } from 'idb-keyval'; async function resetApp() { try { await clear(); // Reinitialize default values console.log('App reset to defaults'); } catch (err) { console.error('Failed to reset:', err); } } ``` -------------------------------- ### Creating and using a custom store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/overview.md Demonstrates how to create and use a custom IndexedDB store with specific database and store names. ```typescript import { createStore, set } from 'idb-keyval'; const myStore = createStore('my-app-db', 'my-data'); await set('key', 'value', myStore); ``` -------------------------------- ### Graceful Degradation with Storage Availability Check Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/advanced-patterns.md Provides safe wrappers for `set` and `get` operations that degrade gracefully if storage becomes unavailable, such as due to quota exceeded errors. It maintains an `storageAvailable` flag to prevent further attempts. ```typescript import { set, get } from 'idb-keyval'; let storageAvailable = true; async function safeSet(key: string, value: any): Promise { if (!storageAvailable) return false; try { await set(key, value); return true; } catch (err) { if (err.name === 'QuotaExceededError') { storageAvailable = false; console.warn('Storage quota exceeded, falling back to memory'); } return false; } } async function safeGet(key: string): Promise { if (!storageAvailable) return null; try { return await get(key); } catch (err) { storageAvailable = false; return null; } } ``` -------------------------------- ### Implement Backup and Restore with Custom Stores Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Use `createStore()` to define stores for both the application data and its backup. This allows for copying all entries from the primary store to the backup store and vice versa using `entries()` and `setMany()`. ```typescript import { createStore, entries, setMany } from 'idb-keyval'; const store = createStore('app', 'data'); const backupDb = createStore('app-backup', 'data'); // Backup: copy all entries async function backup() { const allEntries = await entries(store); await setMany(allEntries, backupDb); console.log('Backed up', allEntries.length, 'entries'); } // Restore: copy back async function restore() { const allEntries = await entries(backupDb); await setMany(allEntries, store); console.log('Restored', allEntries.length, 'entries'); } ``` -------------------------------- ### Feature Flag Management Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Manage feature flags using setMany for initialization and get for checking status. Imports for setMany and get are needed. ```typescript import { setMany, get } from 'idb-keyval'; async function initializeFlags() { await setMany([ ['feature.darkMode', false], ['feature.betaUI', true], ]); } async function isFeatureEnabled(flag) { return get(flag) || false; } ``` -------------------------------- ### Type-Inferred Retrieval with get Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/get.md Specify the expected type of the retrieved value using a generic type parameter with the get function. This enables TypeScript to infer the type of the returned value. ```typescript import { get } from 'idb-keyval'; interface User { id: number; name: string; email: string; } const user = await get('user:123'); // TypeScript knows user has type User | undefined ``` -------------------------------- ### Create and Use a Custom Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Demonstrates creating a custom store and performing set operations. The store function caches the database connection for subsequent operations, improving performance. ```typescript const store = createStore('db', 'store'); await set('key1', 'value1', store); // Connection cached await set('key2', 'value2', store); // Reuses cached connection, efficient ``` -------------------------------- ### Get multiple values by keys Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Use `getMany` to retrieve multiple values by their keys in a single operation, which is more performant than multiple `get` calls. Resolves with an array of values in the same order as the keys. ```js import { get, getMany } from 'idb-keyval'; // Instead of: // Promise.all([get(123), get('hello')]).then(([firstVal, secondVal]) => // console.log(firstVal, secondVal), // ); // It's faster to do: getMany([123, 'hello']).then(([firstVal, secondVal]) => console.log(firstVal, secondVal), ); ``` -------------------------------- ### Using delMany with a Custom Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/delMany.md Demonstrates how to use delMany with a custom database and store configuration. ```typescript import { delMany, createStore } from 'idb-keyval'; const cache = createStore('cache-db', 'entries'); await delMany([1, 2, 3, 4, 5], cache); ``` -------------------------------- ### Using idb-keyval with compat build for older browsers Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/overview.md Shows how to import the compat build of idb-keyval for IE10/11 support, including a Promise polyfill. ```typescript // IE10/11 + Promise polyfill import 'es6-promise/auto'; import { get, set } from 'idb-keyval/dist/esm-compat'; ``` -------------------------------- ### Import compat version with Promise polyfill Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md For IE10/11 compatibility, import the compat version of idb-keyval and a Promise polyfill. ```js // Import a Promise polyfill import 'es6-promise/auto'; import { get, set } from 'idb-keyval/dist/esm-compat'; ``` -------------------------------- ### Delete User Sessions with delMany Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/delMany.md Example of deleting multiple user session keys using delMany. ```typescript import { delMany } from 'idb-keyval'; const userSessions = ['session:user1', 'session:user2', 'session:user3']; await delMany(userSessions); ``` -------------------------------- ### Create and Use Custom Stores in idb-keyval Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Illustrates the limitation of creating multiple stores within a single database and the correct approach using separate databases. ```typescript // ❌ Will fail const store1 = createStore('db', 'store1'); const store2 = createStore('db', 'store2'); // ✓ Use different databases instead const store1 = createStore('db1', 'data'); const store2 = createStore('db2', 'data'); ``` -------------------------------- ### Checking Connection State Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Shows how to create a store and notes that the database connection is established after use. It also mentions that Safari might close the connection, leading to a reconnection on the next operation. ```typescript const store = createStore('test', 'store'); // After use, database is connected // Safari may close it, causing reconnection on next use ``` -------------------------------- ### Creating and Using Custom Stores Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Create isolated stores with different database and store names using createStore. Imports for createStore and set are required. ```typescript import { createStore, set } from 'idb-keyval'; const myStore = createStore('my-db', 'my-store'); await set('key', 'value', myStore); ``` -------------------------------- ### Custom Store Implementation Source: https://github.com/jakearchibald/idb-keyval/blob/main/custom-stores.md Provides the internal implementation of `createStore` for `idb-keyval`. This function manages IndexedDB opening, schema creation on upgrade, and transaction handling for a specified store name. ```javascript import { promisifyRequest } from 'idb-keyval'; function createStore(dbName, storeName) { const request = indexedDB.open(dbName); request.onupgradeneeded = () => request.result.createObjectStore(storeName); const dbp = promisifyRequest(request); return (txMode, callback) => dbp.then((db) => callback(db.transaction(storeName, txMode).objectStore(storeName)), ); } ``` -------------------------------- ### Error Handling for Keys Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/keys.md Demonstrates how to use a try-catch block to handle potential errors when retrieving keys from the store. This ensures graceful failure and provides informative error messages. ```typescript import { keys } from 'idb-keyval'; try { const allKeys = await keys(); console.log(`Store has ${allKeys.length} keys`); } catch (err) { console.error('Failed to retrieve keys:', err); } ``` -------------------------------- ### Multiple Custom Stores in Different Databases Source: https://github.com/jakearchibald/idb-keyval/blob/main/custom-stores.md Demonstrates that `createStore` allows creating multiple stores as long as they reside in different database names. Each `createStore` call with a unique `dbName` is valid. ```javascript // This won't work: const customStore = createStore('custom-db-name', 'custom-store-name'); const customStore2 = createStore('custom-db-name', 'custom-store-2'); // But this is ok, because the database name is different: const customStore3 = createStore('db3', 'keyval'); const customStore4 = createStore('db4', 'keyval'); ``` -------------------------------- ### Cleanup After Expiration Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/del.md An example of using `del` within a function to clean up expired data. This pattern is useful for managing time-sensitive information. ```typescript import { del } from 'idb-keyval'; async function checkAndDelete(key, expiryTime) { const value = await get(key); if (value && value.timestamp < expiryTime) { await del(key); } } ``` -------------------------------- ### Define a Custom Store with createStore() Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Use `createStore()` to create a `UseStore` function for a specific database and store name. This function lazily opens the database, caches the connection, and automatically creates the store if it doesn't exist. ```typescript import { createStore, set, get } from 'idb-keyval'; const myStore = createStore('my-database', 'my-store'); await set('key', 'value', myStore); const value = await get('key', myStore); ``` -------------------------------- ### Organize Data by Feature Using Custom Stores Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Employ `createStore()` to establish dedicated stores for different application features, such as authentication, preferences, or synchronization queues. Each feature can then manage its data independently. ```typescript import { createStore, set, update } from 'idb-keyval'; // Separate stores for different features const features = { auth: createStore('auth', 'data'), preferences: createStore('preferences', 'data'), syncQueue: createStore('sync', 'queue'), offlineMode: createStore('offline', 'data') }; // Each feature uses its store independently await set('credentials', creds, features.auth); await update('sync-count', n => (n || 0) + 1, features.syncQueue); ``` -------------------------------- ### Implement Custom Metrics Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Create a custom store that measures and reports transaction durations and status. This involves using `performance.now()` and a callback for metric reporting. ```typescript import { promisifyRequest } from 'idb-keyval'; function createMetricsStore(dbName, storeName, onMetric) { let dbPromise; const getDB = () => { if (dbPromise) return dbPromise; const request = indexedDB.open(dbName); request.onupgradeneeded = () => { request.result.createObjectStore(storeName); }; dbPromise = promisifyRequest(request); return dbPromise; }; return async (txMode, callback) => { const start = performance.now(); try { const db = await getDB(); const tx = db.transaction(storeName, txMode); const store = tx.objectStore(storeName); const result = callback(store); await promisifyRequest(tx); const duration = performance.now() - start; onMetric({ txMode, duration, status: 'success' }); return result; } catch (err) { const duration = performance.now() - start; onMetric({ txMode, duration, status: 'error', error: err.message }); throw err; } }; } const metricsStore = createMetricsStore('app', 'data', (metric) => { console.log(`${metric.txMode} took ${metric.duration.toFixed(2)}ms`); }); ``` -------------------------------- ### Using generic types for typed data Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/overview.md Specifies generic types for functions like get and set to ensure type safety for stored values. ```typescript import { get, set } from 'idb-keyval'; interface User { id: number; name: string; } const user = await get('user:123'); // TypeScript knows user is User | undefined await set('user:123', { id: 123, name: 'Alice' }); ``` -------------------------------- ### Import Specific Functions from idb-keyval Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/README.md Demonstrates how to import only the specific functions needed from the idb-keyval library to reduce bundle size. ```typescript // Or specific functions import { get, set } from 'idb-keyval'; ``` -------------------------------- ### Default Store Initialization Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/architecture.md Manages a default store singleton, opening an IndexedDB database named 'keyval-store' with an object store named 'keyval' on first use. All exported functions use this store unless a custom one is provided. ```typescript let defaultGetStoreFunc: UseStore | undefined; function defaultGetStore() { if (!defaultGetStoreFunc) { defaultGetStoreFunc = createStore('keyval-store', 'keyval'); } return defaultGetStoreFunc; } ``` -------------------------------- ### Error Handling for entries() Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/entries.md Demonstrates how to use a try-catch block to handle potential errors when retrieving entries from the store. ```typescript import { entries } from 'idb-keyval'; try { const allEntries = await entries(); console.log(`Store has ${allEntries.length} entries`); } catch (err) { console.error('Failed to retrieve entries:', err); } ``` -------------------------------- ### Logging Store Operations Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Provides a utility function to log the start, success, or failure of store operations. This helps in debugging and tracking data modifications. ```typescript async function logStore(txMode, callback, dbName, storeName) { console.log(`Starting ${txMode} on ${dbName}.${storeName}`); try { const result = await callback(...); console.log(`Success`); return result; } catch (err) { console.error(`Failed: ${err.message}`); throw err; } } ``` -------------------------------- ### Initializing Store with Multiple Values Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/setMany.md Use setMany to efficiently initialize a store with a set of default settings. ```typescript import { setMany } from 'idb-keyval'; const defaultSettings = [ ['theme', 'light'], ['language', 'en'], ['autoSave', true], ['fontSize', 14] ]; await setMany(defaultSettings); ``` -------------------------------- ### Using a Custom Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/getMany.md Retrieve values from a non-default database or store by providing a custom store configuration created with createStore. ```typescript import { getMany, createStore } from 'idb-keyval'; const cache = createStore('cache-db', 'entries'); const values = await getMany([1, 2, 3, 4, 5], cache); ``` -------------------------------- ### Handling Missing Keys Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/getMany.md Demonstrates how getMany handles keys that do not exist in the store, returning undefined for those entries. You can filter out undefined values to get only the present ones. ```typescript import { getMany } from 'idb-keyval'; const values = await getMany(['exists', 'missing', 'exists-too']); console.log(values); // [someValue, undefined, someValue] // Filter out undefined const present = values.filter(v => v !== undefined); ``` -------------------------------- ### Handling Missing Keys with get Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/get.md Check if the retrieved value is undefined to handle cases where a key might not exist in the store. This prevents errors and allows for fallback logic. ```typescript import { get } from 'idb-keyval'; const cached = await get('maybe-missing'); if (cached === undefined) { console.log('Key not found, using default'); const defaultValue = 'default'; } else { console.log('Found:', cached); } ``` -------------------------------- ### Implement Transparent Store Selection Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Create a class to abstract store creation based on conditions, such as environment variables. This ensures the correct store is used without explicit checks in application logic. ```typescript import { createStore, set, get } from 'idb-keyval'; class AppStore { constructor(private readonly isTestMode: boolean) { this.store = createStore( isTestMode ? 'app-test' : 'app-prod', 'data' ); } private readonly store; async set(key, value) { return set(key, value, this.store); } async get(key) { return get(key, this.store); } } const store = new AppStore(process.env.TEST_MODE === 'true'); ``` -------------------------------- ### Backup all data Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/entries.md Creates a backup of all data in the store, including a timestamp, the entries themselves, and their count. ```typescript import { entries } from 'idb-keyval'; async function backupData() { const allEntries = await entries(); const backup = { timestamp: new Date().toISOString(), entries: allEntries, count: allEntries.length }; return backup; } ``` -------------------------------- ### Incrementing a counter atomically Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/update.md Safely increments a counter value. The `updater` function handles cases where the value might be undefined, ensuring a correct starting point of 0. ```typescript import { update } from 'idb-keyval'; // Safe: Both updates will execute sequentially await update('counter', (val) => (val || 0) + 1); await update('counter', (val) => (val || 0) + 1); // counter is now 2, even if both updates are initiated together // Without update, both might see 0: // const val = await get('counter'); // both get 0 // await set('counter', val + 1); // both set to 1 ``` -------------------------------- ### Import all functions from idb-keyval Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/overview.md Import all available functions from the main idb-keyval export for use in your project. ```typescript import { get, set, setMany, getMany, update, del, delMany, clear, keys, values, entries, createStore, promisifyRequest, UseStore } from 'idb-keyval'; ``` -------------------------------- ### Get Store Statistics with idb-key-val Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/advanced-patterns.md Calculates and returns statistics about the current key-value store, including the number of entries, types of keys and values, and an estimated size of the stored data. ```typescript import { keys, values } from 'idb-keyval'; async function getStoreStats() { const allKeys = await keys(); const allValues = await values(); const stats = { entryCount: allKeys.length, keyTypes: { string: allKeys.filter(k => typeof k === 'string').length, number: allKeys.filter(k => typeof k === 'number').length, other: allKeys.filter(k => typeof k !== 'string' && typeof k !== 'number').length }, valueTypes: { object: allValues.filter(v => typeof v === 'object').length, string: allValues.filter(v => typeof v === 'string').length, number: allValues.filter(v => typeof v === 'number').length, other: allValues.filter(v => !['object', 'string', 'number'].includes(typeof v)).length }, estimatedSize: JSON.stringify(Object.fromEntries( allKeys.map((k, i) => [k, allValues[i]]) )).length }; return stats; } ``` -------------------------------- ### Atomically update a value Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Use the `update` function for atomic value transformations, preventing race conditions that can occur with separate `get` and `set` operations. Updates are queued automatically. ```js import { update } from 'idb-keyval'; // Instead: // get('counter').then((val) => set('counter', (val || 0) + 1)); // get('counter').then((val) => set('counter', (val || 0) + 1)); // Use update for atomic operations: update('counter', (val) => (val || 0) + 1); update('counter', (val) => (val || 0) + 1); ``` -------------------------------- ### Implement Custom Logging Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Build a custom store wrapper that logs transaction details using lower-level IndexedDB APIs. This requires manual handling of database opening and transactions. ```typescript import { promisifyRequest } from 'idb-keyval'; // Custom implementation with logging function createLoggingStore(dbName, storeName) { let dbPromise; const getDB = () => { if (dbPromise) return dbPromise; const request = indexedDB.open(dbName); request.onupgradeneeded = () => { request.result.createObjectStore(storeName); }; dbPromise = promisifyRequest(request); return dbPromise; }; return async (txMode, callback) => { console.log(`Starting ${txMode} transaction`); try { const db = await getDB(); const result = await callback(db.transaction(storeName, txMode).objectStore(storeName)); console.log(`Transaction complete`); return result; } catch (err) { console.error(`Transaction failed: ${err.message}`); throw err; } }; } ``` -------------------------------- ### With type parameters Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/entries.md Demonstrates using generic type parameters with entries() to specify the types for keys and values, enhancing type safety. ```typescript import { entries } from 'idb-keyval'; interface User { id: number; name: string; } const userEntries = await entries(); // TypeScript knows: [string, User][] ``` -------------------------------- ### Multiple separate databases Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/createStore.md Illustrates creating entirely separate databases for different purposes, ensuring complete data isolation between them. Each database uses a common object store name ('keyval'). ```typescript import { createStore, set, get } from 'idb-keyval'; const userDatabase = createStore('users-db', 'keyval'); const settingsDatabase = createStore('settings-db', 'keyval'); await set('user-id', 123, userDatabase); await set('theme', 'dark', settingsDatabase); const userId = await get('user-id', userDatabase); const theme = await get('theme', settingsDatabase); ``` -------------------------------- ### Create an Instrumented Store Wrapper Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/advanced-patterns.md Wraps an idb-key-val store to track read/write operations and errors. This is useful for monitoring store activity and debugging. ```typescript import { createStore } from 'idb-keyval'; function createInstrumentedStore(dbName: string, storeName: string) { const store = createStore(dbName, storeName); const metrics = { reads: 0, writes: 0, errors: 0 }; return { async exec(txMode, callback) { try { const result = await store(txMode, callback); if (txMode === 'readonly') metrics.reads++; else metrics.writes++; return result; } catch (err) { metrics.errors++; throw err; } }, getMetrics() { return { ...metrics }; } }; } ``` -------------------------------- ### Time-Based Cache Expiration Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/advanced-patterns.md Implement time-based expiration for cached data using `get` and `set`. The `getCached` function checks the age of an entry against a maximum age and deletes expired entries. ```typescript import { get, set, del } from 'idb-keyval'; interface CachedValue { value: T; timestamp: number; ttl: number; // milliseconds } async function getCached(key: string, maxAge: number): Promise { const entry = await get>(key); if (!entry) return null; const age = Date.now() - entry.timestamp; if (age > maxAge) { await del(key); // Cleanup expired entry return null; } return entry.value; } async function setCached(key: string, value: T, ttl: number): Promise { await set(key, { value, timestamp: Date.now(), ttl }); } // Usage const cached = await getCached('user:1', 1000 * 60 * 5); // 5 min TTL if (!cached) { const fresh = await fetchFromAPI(); await setCached('user:1', fresh, 1000 * 60 * 5); } ``` -------------------------------- ### Create Versioned Data Stores Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Use different store names to manage different versions of your data. This allows for data migration by reading from an old store and writing to a new one. ```typescript import { createStore, set, get, entries } from 'idb-keyval'; // Store current and previous versions const currentStore = createStore('app-v3', 'data'); const legacyStore = createStore('app-v2', 'data'); // On upgrade, migrate from old to new async function migrateToV3() { const oldData = await entries(legacyStore); const migratedData = oldData.map(([key, value]) => [ key, migrateValueToV3(value) ]); await setMany(migratedData, currentStore); } ``` -------------------------------- ### Include via CDN (ES Module) Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Include the ES module version of idb-keyval via CDN for modern browsers. ```html ``` -------------------------------- ### Filter Keys by Pattern Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/keys.md Retrieves all keys and then filters them using JavaScript's `filter` method to find keys that start with a specific pattern. This is useful for organizing and accessing related data. ```typescript import { keys } from 'idb-keyval'; const allKeys = await keys(); const userKeys = allKeys.filter(k => k.startsWith('user:')); console.log('User keys:', userKeys); ``` -------------------------------- ### Basic usage with default store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/overview.md Demonstrates storing and retrieving a single value using the default IndexedDB store. ```typescript import { get, set } from 'idb-keyval'; // Store a value await set('username', 'alice'); // Retrieve it const username = await get('username'); console.log(username); // 'alice' ``` -------------------------------- ### get Function Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/get.md Retrieves a single value from the IndexedDB object store by its key. If the key does not exist, the promise resolves with `undefined` rather than rejecting. The generic type parameter `T` allows you to specify the expected value type. ```APIDOC ## get(key: IDBValidKey, customStore?: UseStore): Promise ### Description Retrieves a single value from the IndexedDB object store by its key. If the key does not exist, the promise resolves with `undefined` rather than rejecting. The generic type parameter `T` allows you to specify the expected value type. ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Method This is a JavaScript function call, not an HTTP request. ### Endpoint N/A ### Parameters #### Path Parameters - None #### Query Parameters - None #### Request Body - None ### Parameters - **key** (`IDBValidKey`) - Required - The key to retrieve. Can be a string, number, Date, or buffer. - **customStore** (`UseStore`) - Optional - Custom store function for using non-default database/store names. Defaults to `defaultGetStore()`. ### Returns `Promise` — Promise resolving to the stored value, or `undefined` if the key does not exist. ### Request Example ```javascript import { get } from 'idb-keyval'; const value = await get('username'); console.log(value); ``` ### Response #### Success Response - **value** (`T | undefined`) - The stored value associated with the key, or `undefined` if the key does not exist. #### Response Example ```json { "example": "storedValue or undefined" } ``` ``` -------------------------------- ### Error Handling with createStore Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/createStore.md Demonstrates how to implement error handling when using a custom store created with createStore. This is crucial for managing potential issues during data operations. ```typescript import { createStore, set } from 'idb-keyval'; const store = createStore('my-db', 'my-store'); try { await set('key', 'value', store); } catch (err) { console.error('Failed to store:', err); } ``` -------------------------------- ### Cursor Iteration for Keys, Values, and Entries Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/architecture.md This code illustrates the cursor iteration method used in older browsers for operations like keys(), values(), and entries(). It shows how to open a cursor, process results, and continue to the next item. ```javascript store.openCursor().onsuccess = function() { if (!this.result) return; // Done callback(this.result); this.result.continue(); // Next }; ``` -------------------------------- ### getMany Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/getMany.md Retrieves multiple values from the store by their keys in a single transaction. This is significantly faster than calling `get()` multiple times. The returned array has the same length as the input array, with `undefined` for any missing keys. Values are returned in the same order as the keys provided. ```APIDOC ## getMany ### Description Retrieves multiple values from the store in a single read-only transaction. This is significantly faster than calling `get()` multiple times. The returned array has the same length as the input array, with `undefined` for any missing keys. Values are returned in the same order as the keys provided. ### Method ``` function getMany( keys: IDBValidKey[], customStore?: UseStore, ): Promise ``` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Parameters - **keys** (`IDBValidKey[]`) - Required - Array of keys to retrieve. - **customStore** (`UseStore`) - Optional - Custom store function for using non-default database/store names. Defaults to `defaultGetStore()`. ### Returns `Promise` — Promise resolving to an array of values in the same order as the input keys. Missing keys resolve to `undefined`. ### Request Example ```typescript import { getMany } from 'idb-keyval'; const values = await getMany(['key1', 'key2', 'key3']); console.log(values); // [value1, value2, value3] ``` ### Response #### Success Response (200) An array of values corresponding to the input keys. `undefined` is used for missing keys. The order of values matches the order of input keys. #### Response Example ```json ["value1", "value2", undefined] ``` ``` -------------------------------- ### Organize Application Data with Separate Stores Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Utilize `createStore()` to define distinct stores for different application concerns like user data, cache, and session information. This allows for independent management and clearing of data subsets. ```typescript import { createStore, set, get, setMany, clear } from 'idb-keyval'; // Separate stores for different concerns const userData = createStore('app', 'users'); const appCache = createStore('app-cache', 'data'); const sessionData = createStore('session', 'data'); // Store user data await set('current-user', { id: 123, name: 'Alice' }, userData); // Store cache (can be cleared independently) await setMany([ ['api:users', [...]], ['api:posts', [...]] ], appCache); // Store session info await setMany([ ['token', 'abc123xyz'], ['expires', Date.now() + 3600000] ], sessionData); // Clear cache without affecting user data await clear(appCache); ``` -------------------------------- ### With custom store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/entries.md Retrieves entries from a custom-defined store using the createStore() function. ```typescript import { entries, createStore } from 'idb-keyval'; const cache = createStore('cache-db', 'entries'); const cacheEntries = await entries(cache); ``` -------------------------------- ### Use Custom Store for Keys Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/keys.md Retrieves keys from a custom-defined object store using the `createStore` function. This allows for managing multiple databases or stores within the same origin. ```typescript import { keys, createStore } from 'idb-keyval'; const cache = createStore('cache-db', 'entries'); const cacheKeys = await keys(cache); console.log('Cache contains:', cacheKeys); ``` -------------------------------- ### Integrate Third-Party Libraries with Isolated Stores Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/custom-stores-guide.md Create separate stores for your application and third-party libraries using `createStore()`. This ensures that their data operations remain isolated and do not interfere with each other. ```typescript import { createStore } from 'idb-keyval'; // Your app's store const appStore = createStore('my-app', 'data'); // Third-party library creates its own isolated store const thirdPartyStore = createStore('third-party-lib', 'cache'); // They never interfere with each other ``` -------------------------------- ### Batch Storage with Custom Store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/setMany.md Utilize setMany with a custom store configuration, allowing for non-default database and store names. ```typescript import { setMany, createStore } from 'idb-keyval'; const cache = createStore('cache-db', 'entries'); const entries = [ [1, 'first'], [2, 'second'], [3, 'third'] ]; await setMany(entries, cache); ``` -------------------------------- ### Clear with custom store Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/clear.md This snippet shows how to clear a specific, non-default store by providing a custom store instance created with `createStore`. Import `clear` and `createStore` from 'idb-keyval'. ```typescript import { clear, createStore } from 'idb-keyval'; const sessionStore = createStore('session-db', 'session-data'); await clear(sessionStore); console.log('Session store cleared'); ``` -------------------------------- ### Include via CDN (UMD) Source: https://github.com/jakearchibald/idb-keyval/blob/main/README.md Include the UMD bundle of idb-keyval using a CDN script tag for browser environments. ```html ``` -------------------------------- ### Check if Key Exists Source: https://github.com/jakearchibald/idb-keyval/blob/main/_autodocs/api-reference/keys.md Retrieves all keys and then uses JavaScript's `includes` method to check for the existence of a specific key. This is a simple way to verify if a key is present in the store. ```typescript import { keys } from 'idb-keyval'; const allKeys = await keys(); const exists = allKeys.includes('my-key'); console.log('Key exists:', exists); ```