IndexedDB-based caching library with encryption and chunked storage, designed for performance and security. Implements AsyncStorage interface.
interfaceAsyncStorage{getItem: (key: string)=>Promise<string|null>;setItem: (key: string,value: string)=>Promise<unknown>;removeItem: (key: string)=>Promise<void>;clear: ()=>Promise<void>;}Encryption keeps data in IndexedDB private, even when a browser profile is shared on the same device. Only one with access to the cacheKey can decrypt the data.
npm install @instructure/idb-cacheimport{IDBCache}from'@instructure/idb-cache';// Initialize the cacheconstcache=newIDBCache({cacheKey: 'your-secure-key',cacheBuster: 'unique-cache-buster',// chunkSize?: number;// cleanupInterval?: number;// dbName?: string;// debug?: boolean,// gcTime?: number;// maxTotalChunks?: number// pbkdf2Iterations?: number;// priority?: "normal" | "low"});// Store an itemawaitcache.setItem('key','value');// Retrieve an itemconsttoken=awaitcache.getItem('key');console.log(token);// Outputs: 'value'// Remove an itemawaitcache.removeItem('key');// Count stored chunksconsttotalChunks=awaitcache.count();// Removes expired items, busted items, and limits chunks// Runs at intervalawaitcache.cleanup();// Clears all items from cacheawaitcache.clear();// Destroy the cache instanceawaitcache.destroy();- Web Worker: Offloads encryption and decryption tasks to prevent blocking the main thread.
- Chunking: Efficiently handles large data by splitting it into chunks.
- Encryption: Secures data using AES-GCM with PBKDF2 key derivation.
- Garbage collection: Expires and cleans up outdated cache entries.
- Task processing: Uses parallelism and queue to mitigate crypto/CPU overload.
Integrate idb-cache as an AsyncStorage persister for TanStack Query.
import{QueryClient}from'@tanstack/query-core';import{experimental_createPersisterascreatePersister}from'@tanstack/query-persist-client-core';import{IDBCache}from'@instructure/idb-cache';constidbCache=newIDBCache({cacheKey: 'user_cache_key',});constpersister=createPersister({storage: idbCache,maxAge: 1000*60*60*24*7,// 7 days});exportconstqueryClient=newQueryClient({defaultOptions: {queries: {staleTime: 1000*60*60,// 1 hourgcTime: 1000*60*60*24*7,// 7 days persister,},},});flowchart TD subgraph Browser["Browser"] IDBCache[["IDBCache"]] Application(["Client app"]) WebWorker{{"Web Worker"}} IndexedDB[("IndexedDB")] end Application -- ".setItem()" --> IDBCache IDBCache -. Unencrypted chunks .-> WebWorker WebWorker -. Encrypted chunks .-> IDBCache IDBCache -. Encrypted chunks .-> IndexedDB flowchart TD subgraph Browser["Browser"] Application([Client app]) --> |".getItem()"| IDBCache[[IDBCache]] IDBCache --> |Get chunks| IndexedDB[(IndexedDB)] IndexedDB -.-> |Encrypted chunks| IDBCache IDBCache -.-> |Encrypted chunks| WebWorker{{Web Worker}} WebWorker -.-> |Decrypted chunks| IDBCache IDBCache --> |"Item"| Application end