Skip to content

Commit adf8846

Browse files
committed
refactor: README
1 parent 3b5fd28 commit adf8846

File tree

1 file changed

+152
-1
lines changed

1 file changed

+152
-1
lines changed

packages/idb-cache/README.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/idb-cache/README.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# idb-cache
2+
3+
IndexedDB-based caching library with encryption and chunked storage, designed for performance and security. Implements AsyncStorage interface.
4+
5+
```typescript
6+
interface AsyncStorage {
7+
getItem: (key: string) => Promise<string | null>;
8+
setItem: (key: string, value: string) => Promise<unknown>;
9+
removeItem: (key: string) => Promise<void>;
10+
clear: () => Promise<void>;
11+
}
12+
```
13+
14+
## Why encrypt data in IndexedDB?
15+
16+
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.
17+
18+
## Installation
19+
20+
```bash
21+
npm install @instructure/idb-cache
22+
```
23+
24+
## Usage
25+
26+
```typescript
27+
import { IDBCache } from '@instructure/idb-cache';
28+
29+
// Initialize the cache
30+
const cache = new IDBCache({
31+
cacheKey: 'your-secure-key',
32+
cacheBuster: 'unique-cache-buster',
33+
// chunkSize?: number;
34+
// cleanupInterval?: number;
35+
// dbName?: string;
36+
// debug?: boolean,
37+
// gcTime?: number;
38+
// maxTotalChunks?: number
39+
// pbkdf2Iterations?: number;
40+
// priority?: "normal" | "low"
41+
});
42+
43+
// Store an item
44+
await cache.setItem('key', 'value');
45+
46+
// Retrieve an item
47+
const token = await cache.getItem('key');
48+
console.log(token); // Outputs: 'value'
49+
50+
// Remove an item
51+
await cache.removeItem('key');
52+
53+
// Count stored chunks
54+
const totalChunks = await cache.count();
55+
56+
// Removes expired items, busted items, and limits chunks
57+
// Runs at interval
58+
await cache.cleanup();
59+
60+
// Clears all items from cache
61+
await cache.clear();
62+
63+
// Destroy the cache instance
64+
await cache.destroy();
65+
```
66+
67+
## Features
68+
69+
- **Web Worker**: Offloads encryption and decryption tasks to prevent blocking the main thread.
70+
- **Chunking**: Efficiently handles large data by splitting it into chunks.
71+
- **Encryption**: Secures data using AES-GCM with PBKDF2 key derivation.
72+
- **Garbage collection**: Expires and cleans up outdated cache entries.
73+
- **Task processing**: Uses parallelism and queue to mitigate crypto/CPU overload.
74+
75+
## Usage with TanStack Query
76+
77+
Integrate idb-cache as an AsyncStorage persister for TanStack Query.
78+
79+
```typescript
80+
import { QueryClient } from '@tanstack/query-core';
81+
import { experimental_createPersister } from '@tanstack/query-persist-client-core';
82+
import { IDBCache } from 'idb-cache';
83+
84+
const cacheBuster = 'my_salt'; // Doubles as salt for encryption
85+
86+
const idbCache = new IDBCache({
87+
cacheKey: 'user_cache_key',
88+
cacheBuster,
89+
});
90+
91+
// Create the persister
92+
const persister = experimental_createPersister({
93+
storage: idbCache,
94+
maxAge: 1000 * 60 * 60 * 24 * 7, // 7 days
95+
buster: cacheBuster,
96+
});
97+
98+
// Initialize the QueryClient with the persister
99+
export const queryClient = new QueryClient({
100+
defaultOptions: {
101+
queries: {
102+
staleTime: 1000 * 60 * 60, // 1 hour
103+
gcTime: 1000 * 60 * 60 * 24 * 7, // 7 days
104+
persister,
105+
},
106+
},
107+
});
108+
```
109+
110+
## Data flow
111+
112+
### setItem
113+
114+
```mermaid
115+
flowchart TD
116+
Application([Client app]) --> |".setItem()"| IDBCache[[IDBCache]]
117+
IDBCache -.-> |"Unencrypted chunks"| WebWorker{{Web Worker}}
118+
WebWorker -.-> |"Encrypted chunks"| IDBCache
119+
IDBCache -.-> |"Encrypted chunks"| IndexedDB[(IndexedDB)]
120+
```
121+
122+
### getItem
123+
124+
```mermaid
125+
flowchart TD
126+
Application([Client app]) --> |".getItem()"| IDBCache[[IDBCache]]
127+
IDBCache --> |Get chunks| IndexedDB[(IndexedDB)]
128+
IndexedDB -.-> |Encrypted chunks| IDBCache
129+
IDBCache -.-> |Encrypted chunks| WebWorker{{Web Worker}}
130+
WebWorker -.-> |Decrypted chunks| IDBCache
131+
IDBCache --> |"Item"| Application
132+
```
133+
134+
## Technologies used
135+
136+
- [IndexedDB](https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)
137+
- [Web Workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API)
138+
- [SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker)
139+
- [MessageChannel](https://developer.mozilla.org/en-US/docs/Web/API/MessageChannel)
140+
- [MessagePort](https://developer.mozilla.org/en-US/docs/Web/API/MessagePort)
141+
- [Transferable objects](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Transferable_objects)
142+
- [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)
143+
- [SubtleCrypto](https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto)
144+
- [AES-GCM](https://developer.mozilla.org/en-US/docs/Web/API/AesGcmParams)
145+
- [PBKDF2](https://developer.mozilla.org/en-US/docs/Web/API/Pbkdf2Params)
146+
- [ArrayBuffer](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer)
147+
148+
## Related reading
149+
150+
- [Is postMessage slow?](https://surma.dev/things/is-postmessage-slow/)
151+
- [Measure performance with the RAIL model](https://web.dev/articles/rail)
152+
- [LocalStorage vs. IndexedDB vs. Cookies vs. OPFS vs. WASM-SQLite](https://rxdb.info/articles/localstorage-indexeddb-cookies-opfs-sqlite-wasm.html)

0 commit comments

Comments
 (0)