@dynlabs/react-native-immutable-file-cache 1.0.0-alpha.1 → 1.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/README.md +183 -261
  2. package/lib/commonjs/adapters/memoryAdapter.js +1 -0
  3. package/lib/commonjs/adapters/memoryAdapter.js.map +1 -1
  4. package/lib/commonjs/adapters/rnfsAdapter.js +9 -4
  5. package/lib/commonjs/adapters/rnfsAdapter.js.map +1 -1
  6. package/lib/commonjs/adapters/webAdapter.js +1 -0
  7. package/lib/commonjs/adapters/webAdapter.js.map +1 -1
  8. package/lib/commonjs/core/adapter.js +54 -0
  9. package/lib/commonjs/core/adapter.js.map +1 -1
  10. package/lib/commonjs/core/cacheEngine.js +452 -59
  11. package/lib/commonjs/core/cacheEngine.js.map +1 -1
  12. package/lib/commonjs/core/errors.js +9 -6
  13. package/lib/commonjs/core/errors.js.map +1 -1
  14. package/lib/commonjs/core/hash.js +3 -3
  15. package/lib/commonjs/core/hash.js.map +1 -1
  16. package/lib/commonjs/core/indexStore.js +85 -8
  17. package/lib/commonjs/core/indexStore.js.map +1 -1
  18. package/lib/commonjs/core/prune.js +42 -11
  19. package/lib/commonjs/core/prune.js.map +1 -1
  20. package/lib/commonjs/core/types.js +132 -0
  21. package/lib/commonjs/core/types.js.map +1 -1
  22. package/lib/commonjs/index.js +33 -0
  23. package/lib/commonjs/index.js.map +1 -1
  24. package/lib/module/adapters/memoryAdapter.js +1 -0
  25. package/lib/module/adapters/memoryAdapter.js.map +1 -1
  26. package/lib/module/adapters/rnfsAdapter.js +9 -4
  27. package/lib/module/adapters/rnfsAdapter.js.map +1 -1
  28. package/lib/module/adapters/webAdapter.js +1 -0
  29. package/lib/module/adapters/webAdapter.js.map +1 -1
  30. package/lib/module/core/adapter.js +48 -0
  31. package/lib/module/core/adapter.js.map +1 -1
  32. package/lib/module/core/cacheEngine.js +453 -60
  33. package/lib/module/core/cacheEngine.js.map +1 -1
  34. package/lib/module/core/errors.js +9 -6
  35. package/lib/module/core/errors.js.map +1 -1
  36. package/lib/module/core/hash.js +3 -3
  37. package/lib/module/core/hash.js.map +1 -1
  38. package/lib/module/core/indexStore.js +86 -8
  39. package/lib/module/core/indexStore.js.map +1 -1
  40. package/lib/module/core/prune.js +40 -11
  41. package/lib/module/core/prune.js.map +1 -1
  42. package/lib/module/core/types.js +130 -1
  43. package/lib/module/core/types.js.map +1 -1
  44. package/lib/module/index.js +4 -0
  45. package/lib/module/index.js.map +1 -1
  46. package/lib/typescript/src/adapters/memoryAdapter.d.ts.map +1 -1
  47. package/lib/typescript/src/adapters/rnfsAdapter.d.ts.map +1 -1
  48. package/lib/typescript/src/adapters/webAdapter.d.ts.map +1 -1
  49. package/lib/typescript/src/core/adapter.d.ts +16 -0
  50. package/lib/typescript/src/core/adapter.d.ts.map +1 -1
  51. package/lib/typescript/src/core/cacheEngine.d.ts +120 -1
  52. package/lib/typescript/src/core/cacheEngine.d.ts.map +1 -1
  53. package/lib/typescript/src/core/errors.d.ts +6 -5
  54. package/lib/typescript/src/core/errors.d.ts.map +1 -1
  55. package/lib/typescript/src/core/indexStore.d.ts +7 -0
  56. package/lib/typescript/src/core/indexStore.d.ts.map +1 -1
  57. package/lib/typescript/src/core/prune.d.ts +22 -8
  58. package/lib/typescript/src/core/prune.d.ts.map +1 -1
  59. package/lib/typescript/src/core/types.d.ts +153 -0
  60. package/lib/typescript/src/core/types.d.ts.map +1 -1
  61. package/lib/typescript/src/index.d.ts +5 -2
  62. package/lib/typescript/src/index.d.ts.map +1 -1
  63. package/package.json +1 -1
  64. package/src/adapters/memoryAdapter.ts +3 -0
  65. package/src/adapters/rnfsAdapter.ts +11 -4
  66. package/src/adapters/webAdapter.ts +1 -0
  67. package/src/core/adapter.ts +28 -0
  68. package/src/core/cacheEngine.ts +476 -62
  69. package/src/core/errors.ts +8 -6
  70. package/src/core/hash.ts +3 -3
  71. package/src/core/indexStore.ts +99 -11
  72. package/src/core/prune.ts +44 -14
  73. package/src/core/types.ts +194 -0
  74. package/src/index.ts +22 -0
package/README.md CHANGED
@@ -1,19 +1,41 @@
1
- # @dynlabs/react-native-immutable-file-cache
2
-
3
- [![CI](https://github.com/dienp/react-native-immutable-file-cache/actions/workflows/ci.yml/badge.svg)](https://github.com/dienp/react-native-immutable-file-cache/actions/workflows/ci.yml)
4
- [![npm version](https://img.shields.io/npm/v/@dynlabs/react-native-immutable-file-cache.svg)](https://www.npmjs.com/package/@dynlabs/react-native-immutable-file-cache)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
-
7
- A cross-platform immutable file cache for React Native and Web with pluggable storage adapters.
1
+ <p align="center">
2
+ <h1 align="center">react-native-immutable-file-cache</h1>
3
+ </p>
4
+
5
+ <p align="center">
6
+ <strong>Cross-platform immutable file cache for React Native and Web</strong>
7
+ </p>
8
+
9
+ <p align="center">
10
+ <a href="https://github.com/dienp/react-native-immutable-file-cache/actions/workflows/ci.yml">
11
+ <img src="https://github.com/dienp/react-native-immutable-file-cache/actions/workflows/ci.yml/badge.svg" alt="CI" />
12
+ </a>
13
+ <a href="https://www.npmjs.com/package/@dynlabs/react-native-immutable-file-cache">
14
+ <img src="https://img.shields.io/npm/v/@dynlabs/react-native-immutable-file-cache.svg" alt="npm version" />
15
+ </a>
16
+ <a href="https://opensource.org/licenses/MIT">
17
+ <img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" />
18
+ </a>
19
+ </p>
20
+
21
+ <p align="center">
22
+ <a href="#installation">Installation</a> •
23
+ <a href="#quick-start">Quick Start</a> •
24
+ <a href="#api">API</a> •
25
+ <a href="#adapters">Adapters</a> •
26
+ <a href="#contributing">Contributing</a>
27
+ </p>
28
+
29
+ ---
8
30
 
9
31
  ## Features
10
32
 
11
- - **Immutable entries** - Once cached, entries cannot be overwritten
12
- - **Cross-platform** - Works on iOS, Android, and Web
13
- - **Pluggable adapters** - Swap storage backends without changing application code
14
- - **TTL & LRU pruning** - Automatic cache management
15
- - **Atomic writes** - Crash-safe file operations
16
- - **TypeScript first** - Full type safety with strict types
33
+ - **Immutable entries** Once cached, entries cannot be overwritten
34
+ - **Cross-platform** iOS, Android, and Web support
35
+ - **Pluggable adapters** Swap storage backends without code changes
36
+ - **TTL & LRU pruning** Automatic cache management
37
+ - **Atomic writes** Crash-safe file operations
38
+ - **TypeScript first** Full type safety
17
39
 
18
40
  ## Installation
19
41
 
@@ -21,328 +43,222 @@ A cross-platform immutable file cache for React Native and Web with pluggable st
21
43
  npm install @dynlabs/react-native-immutable-file-cache
22
44
  ```
23
45
 
24
- ### React Native (iOS/Android)
25
-
26
- Also install the filesystem dependency:
46
+ #### React Native
27
47
 
28
48
  ```bash
29
49
  npm install react-native-fs
30
50
  cd ios && pod install
31
51
  ```
32
52
 
33
- ### Web
53
+ #### Web
34
54
 
35
- No additional dependencies required - uses Cache Storage and IndexedDB.
55
+ No additional dependencies required uses Cache Storage and IndexedDB.
36
56
 
37
57
  ## Quick Start
38
58
 
39
59
  ```typescript
40
60
  import { createImmutableFileCache } from "@dynlabs/react-native-immutable-file-cache";
41
61
 
42
- // Create cache instance
43
62
  const cache = await createImmutableFileCache({
44
63
  namespace: "images",
45
64
  defaultTtlMs: 7 * 24 * 60 * 60 * 1000, // 7 days
46
65
  maxSizeBytes: 100 * 1024 * 1024, // 100 MB
47
66
  });
48
67
 
49
- // Cache an image from URL
50
- const result = await cache.putFromUrl(
51
- "avatar-123",
52
- "https://example.com/avatar.jpg"
53
- );
68
+ // Cache from URL
69
+ const result = await cache.putFromUrl("avatar-123", "https://example.com/avatar.jpg");
54
70
 
55
71
  if (result.status === "created") {
56
- console.log("Cached new image:", result.entry.sizeBytes, "bytes");
57
- } else {
58
- console.log("Image already cached");
72
+ console.log("Cached:", result.entry.sizeBytes, "bytes");
59
73
  }
60
74
 
61
- // Retrieve cached entry
75
+ // Retrieve
62
76
  const entry = await cache.get("avatar-123");
63
77
  if (entry) {
64
- // Use entry.uri in Image component
65
78
  <Image source={{ uri: entry.uri }} />
66
79
  }
67
80
  ```
68
81
 
69
- ## Architecture
70
-
71
- The package uses a three-layer architecture:
72
-
73
- ```
74
- src/
75
- ├── core/ # Platform-agnostic cache engine
76
- ├── adapters/ # Platform-specific storage adapters
77
- └── index.*.ts # Platform entrypoints
78
- ```
79
-
80
- ### Core Layer
82
+ ## API
81
83
 
82
- Contains all cache logic (immutability rules, TTL, LRU pruning, indexing) without any platform-specific code. The core depends only on the `IStorageAdapter` interface.
83
-
84
- ### Adapters Layer
85
-
86
- Platform-specific implementations of `IStorageAdapter`:
87
-
88
- - **RNFS Adapter** - Uses `react-native-fs` for native platforms
89
- - **Web Adapter** - Uses Cache Storage + IndexedDB for browsers
90
- - **Memory Adapter** - In-memory storage for testing
91
-
92
- ### Public API
93
-
94
- Platform entrypoints automatically select the appropriate adapter:
95
-
96
- - `index.native.ts` - React Native (iOS/Android)
97
- - `index.web.ts` - Web browsers
98
-
99
- ## Adapters
100
-
101
- ### Using the Default Adapter
102
-
103
- ```typescript
104
- // React Native - automatically uses RNFS adapter
105
- import { createImmutableFileCache } from "@dynlabs/react-native-immutable-file-cache";
106
-
107
- // Web - automatically uses Web adapter
108
- import { createImmutableFileCache } from "@dynlabs/react-native-immutable-file-cache/web";
109
- ```
110
-
111
- ### Injecting a Custom Adapter
84
+ ### Configuration
112
85
 
113
86
  ```typescript
114
- import { createImmutableFileCache, createRnfsAdapter } from "@dynlabs/react-native-immutable-file-cache";
115
-
116
- const customAdapter = createRnfsAdapter({
117
- baseDir: "/custom/path",
118
- namespace: "my-app",
119
- });
120
-
121
- const cache = await createImmutableFileCache({
122
- adapter: customAdapter,
87
+ createImmutableFileCache({
88
+ namespace: "default", // Cache isolation namespace
89
+ defaultTtlMs: undefined, // Default TTL (ms), undefined = no expiry
90
+ maxSizeBytes: undefined, // Max size, triggers LRU when exceeded
91
+ autoPruneExpired: true, // Auto-remove expired entries
92
+ adapter: undefined, // Custom storage adapter
93
+ hashFn: undefined, // Custom hash function (default: SHA-256)
94
+ onEvent: undefined, // Event handler for observability
123
95
  });
124
96
  ```
125
97
 
126
- ### Building a Custom Adapter
127
-
128
- Implement the `IStorageAdapter` interface:
129
-
130
- ```typescript
131
- import type { IStorageAdapter, TBinarySource, IBinaryWriteResult } from "@dynlabs/react-native-immutable-file-cache";
132
-
133
- const myAdapter: IStorageAdapter = {
134
- kind: "my-storage",
135
- rootId: "my-root",
136
-
137
- async ensureDir(path) { /* Create directory */ },
138
- async exists(path) { /* Check if exists */ },
139
- async remove(path) { /* Remove file */ },
140
- async removeDir(path) { /* Remove directory recursively */ },
141
- async listDir(path) { /* List directory contents */ },
142
- async readText(path, encoding) { /* Read text file */ },
143
- async writeTextAtomic(path, content, encoding) { /* Write text atomically */ },
144
- async stat(path) { /* Get file stats */ },
145
- async writeBinaryAtomic(path, source, options) { /* Write binary atomically */ },
146
- async getPublicUri(path) { /* Get URI for file */ },
147
- };
148
- ```
149
-
150
- ### Supported Binary Sources by Adapter
151
-
152
- | Source Type | RNFS Adapter | Web Adapter | Memory Adapter |
153
- |-------------|--------------|-------------|----------------|
154
- | `url` | ✅ | ✅ | ✅ |
155
- | `file` | ✅ | ❌ | ✅ (simulated) |
156
- | `blob` | ❌ | ✅ | ✅ |
157
- | `bytes` | ✅ | ✅ | ✅ |
158
-
159
- ## API Reference
160
-
161
- ### `createImmutableFileCache(options?)`
162
-
163
- Creates a new cache instance.
164
-
165
- #### Options
166
-
167
- | Option | Type | Default | Description |
168
- |--------|------|---------|-------------|
169
- | `namespace` | `string` | `"default"` | Cache namespace for isolation |
170
- | `adapter` | `IStorageAdapter` | auto-detected | Custom storage adapter |
171
- | `defaultTtlMs` | `number` | `undefined` | Default TTL for entries |
172
- | `maxSizeBytes` | `number` | `undefined` | Max cache size (triggers LRU) |
173
- | `autoPruneExpired` | `boolean` | `true` | Auto-prune on operations |
174
- | `hashFn` | `(input: string) => string \| Promise<string>` | SHA-256 | Custom hash function |
175
-
176
98
  ### Put Operations
177
99
 
178
- All put operations are immutable - they return `{ status: "exists" }` if the key already exists.
179
-
180
- #### `putFromUrl(key, url, options?)`
181
-
182
- Cache content from a URL.
183
-
184
- ```typescript
185
- const result = await cache.putFromUrl("image-key", "https://example.com/image.jpg", {
186
- ttlMs: 86400000, // 1 day
187
- ext: ".jpg",
188
- metadata: { source: "cdn" },
189
- onProgress: (pct) => console.log(`${pct}% downloaded`),
190
- headers: { Authorization: "Bearer token" },
191
- });
192
- ```
193
-
194
- #### `putFromFile(key, filePath, options?)` (Native only)
195
-
196
- Cache content from a local file.
100
+ All put operations are immutable returns `{ status: "exists" }` if the key already exists.
197
101
 
198
102
  ```typescript
199
- const result = await cache.putFromFile("doc-key", "/path/to/document.pdf", {
200
- ext: ".pdf",
201
- });
202
- ```
103
+ // From URL
104
+ await cache.putFromUrl(key, url, { ttlMs, ext, metadata, headers, onProgress });
203
105
 
204
- #### `putFromBlob(key, blob, options?)` (Web only)
106
+ // From file (Native only)
107
+ await cache.putFromFile(key, filePath, options);
205
108
 
206
- Cache content from a Blob.
109
+ // From Blob (Web only)
110
+ await cache.putFromBlob(key, blob, options);
207
111
 
208
- ```typescript
209
- const blob = await response.blob();
210
- const result = await cache.putFromBlob("data-key", blob);
211
- ```
212
-
213
- #### `putFromBytes(key, bytes, options?)`
214
-
215
- Cache raw bytes.
216
-
217
- ```typescript
218
- const result = await cache.putFromBytes("raw-key", new Uint8Array([1, 2, 3]));
112
+ // From bytes
113
+ await cache.putFromBytes(key, new Uint8Array([...]), options);
219
114
  ```
220
115
 
221
116
  ### Get Operations
222
117
 
223
- #### `get(key)`
224
-
225
- Get entry with URI. Updates `lastAccessedAt`.
226
-
227
118
  ```typescript
228
- const result = await cache.get("image-key");
229
- if (result) {
230
- console.log("URI:", result.uri);
231
- console.log("Size:", result.entry.sizeBytes);
232
- }
233
- ```
119
+ // Get with URI (updates lastAccessedAt)
120
+ const result = await cache.get(key);
121
+ // => { entry, uri } | null
234
122
 
235
- #### `has(key)`
123
+ // Check existence
124
+ const exists = await cache.has(key);
236
125
 
237
- Check if key exists and is not expired.
126
+ // Peek without updating access time
127
+ const entry = await cache.peek(key);
238
128
 
239
- ```typescript
240
- if (await cache.has("image-key")) {
241
- // Entry exists
242
- }
243
- ```
129
+ // Get URI only
130
+ const uri = await cache.getUri(key);
244
131
 
245
- #### `peek(key)`
246
-
247
- Get entry metadata without updating `lastAccessedAt`.
248
-
249
- ```typescript
250
- const entry = await cache.peek("image-key");
132
+ // Read-through cache
133
+ const result = await cache.getOrPut(key, async (k) => ({
134
+ bytes: new Uint8Array([...]),
135
+ ttlMs: 86400000,
136
+ ext: ".json",
137
+ }));
251
138
  ```
252
139
 
253
- ### List/Query Operations
254
-
255
- #### `list(options?)`
256
-
257
- List entries with sorting, filtering, and pagination.
140
+ ### List & Stats
258
141
 
259
142
  ```typescript
143
+ // List entries
260
144
  const entries = await cache.list({
261
- sortBy: "createdAt", // "createdAt" | "lastAccessedAt" | "sizeBytes" | "key"
262
- order: "desc", // "asc" | "desc"
145
+ sortBy: "createdAt", // "createdAt" | "lastAccessedAt" | "sizeBytes" | "key"
146
+ order: "desc", // "asc" | "desc"
263
147
  limit: 10,
264
148
  offset: 0,
265
- filter: (entry) => entry.sizeBytes > 1000,
149
+ filter: (e) => e.sizeBytes > 1000,
266
150
  });
267
- ```
268
151
 
269
- #### `stats()`
152
+ // Get all keys
153
+ const keys = await cache.keys();
270
154
 
271
- Get cache statistics.
155
+ // Count entries
156
+ const count = await cache.count();
272
157
 
273
- ```typescript
158
+ // Statistics
274
159
  const stats = await cache.stats();
275
- console.log(`${stats.entryCount} entries, ${stats.totalSizeBytes} bytes`);
160
+ // => { entryCount, totalSizeBytes, oldestEntry?, newestEntry? }
276
161
  ```
277
162
 
278
- ### Remove/Prune Operations
163
+ ### Cache Management
279
164
 
280
- #### `remove(key)`
165
+ ```typescript
166
+ // Remove single entry
167
+ await cache.remove(key);
281
168
 
282
- Remove specific entry.
169
+ // Remove expired entries
170
+ await cache.removeExpired();
171
+ // => { removedCount, freedBytes, removedKeys }
283
172
 
284
- ```typescript
285
- const removed = await cache.remove("image-key");
286
- ```
173
+ // LRU prune to size limit
174
+ await cache.pruneLru(50 * 1024 * 1024);
287
175
 
288
- #### `removeExpired()`
176
+ // Clear all
177
+ await cache.clear();
289
178
 
290
- Remove all expired entries.
179
+ // Validate & repair index
180
+ await cache.validateAndRepair();
291
181
 
292
- ```typescript
293
- const result = await cache.removeExpired();
294
- console.log(`Removed ${result.removedCount} entries, freed ${result.freedBytes} bytes`);
182
+ // TTL management
183
+ await cache.touch(key); // Refresh access time
184
+ await cache.setTtl(key, 86400000); // Set new TTL
185
+ await cache.extendTtl(key, 3600000); // Extend TTL
295
186
  ```
296
187
 
297
- #### `pruneLru(maxSizeBytes)`
298
-
299
- Prune to fit size limit using LRU.
188
+ ### Lifecycle
300
189
 
301
190
  ```typescript
302
- await cache.pruneLru(50 * 1024 * 1024); // Prune to 50MB
191
+ // Flush pending writes (when using debounce)
192
+ await cache.flush();
193
+
194
+ // Destroy and release resources
195
+ await cache.destroy();
303
196
  ```
304
197
 
305
- #### `clear()`
198
+ ## Adapters
306
199
 
307
- Remove all entries.
200
+ The library uses a pluggable adapter architecture:
308
201
 
309
- ```typescript
310
- await cache.clear();
311
- ```
202
+ | Adapter | Platform | Storage |
203
+ |---------|----------|---------|
204
+ | **RNFS** | iOS/Android | `react-native-fs` |
205
+ | **Web** | Browser | Cache Storage + IndexedDB |
206
+ | **Memory** | All | In-memory (testing) |
312
207
 
313
- ### Maintenance
208
+ ### Default Adapter (Auto-selected)
314
209
 
315
- #### `validateAndRepair()`
210
+ ```typescript
211
+ // React Native — uses RNFS adapter
212
+ import { createImmutableFileCache } from "@dynlabs/react-native-immutable-file-cache";
316
213
 
317
- Validate index against filesystem and rebuild if needed.
214
+ // Web uses Web adapter
215
+ import { createImmutableFileCache } from "@dynlabs/react-native-immutable-file-cache/web";
216
+ ```
217
+
218
+ ### Custom Adapter
318
219
 
319
220
  ```typescript
320
- const result = await cache.validateAndRepair();
321
- if (result.repaired) {
322
- console.log("Fixed issues:", result.issues);
323
- }
324
- ```
221
+ import { createImmutableFileCache, createRnfsAdapter } from "@dynlabs/react-native-immutable-file-cache";
325
222
 
326
- ## Web-Specific: Blob URL Cleanup
223
+ const cache = await createImmutableFileCache({
224
+ adapter: createRnfsAdapter({ baseDir: "/custom/path", namespace: "my-app" }),
225
+ });
226
+ ```
327
227
 
328
- On web, `getPublicUri()` returns `blob:` URLs. To prevent memory leaks, clean up URLs when done:
228
+ ### Supported Sources
329
229
 
330
- ```typescript
331
- import { createWebAdapter, IWebAdapterWithCleanup } from "@dynlabs/react-native-immutable-file-cache";
230
+ | Source | RNFS | Web | Memory |
231
+ |--------|------|-----|--------|
232
+ | `url` | ✓ | ✓ | ✓ |
233
+ | `file` | ✓ | — | ✓ |
234
+ | `blob` | — | ✓ | ✓ |
235
+ | `bytes` | ✓ | ✓ | ✓ |
332
236
 
333
- const adapter = createWebAdapter() as IWebAdapterWithCleanup;
237
+ ### Implementing Custom Adapters
334
238
 
335
- // When done with a specific URL
336
- adapter.revokeUri(entry.uri);
239
+ ```typescript
240
+ import type { IStorageAdapter } from "@dynlabs/react-native-immutable-file-cache";
337
241
 
338
- // Or revoke all URLs
339
- adapter.revokeAllUris();
242
+ const myAdapter: IStorageAdapter = {
243
+ kind: "my-storage",
244
+ rootId: "my-root",
245
+ supportedSources: new Set(["url", "bytes"]),
246
+
247
+ async ensureDir(path) { /* ... */ },
248
+ async exists(path) { /* ... */ },
249
+ async remove(path) { /* ... */ },
250
+ async removeDir(path) { /* ... */ },
251
+ async listDir(path) { /* ... */ },
252
+ async readText(path, encoding) { /* ... */ },
253
+ async writeTextAtomic(path, content, encoding) { /* ... */ },
254
+ async stat(path) { /* ... */ },
255
+ async writeBinaryAtomic(path, source, options) { /* ... */ },
256
+ async getPublicUri(path) { /* ... */ },
257
+ };
340
258
  ```
341
259
 
342
260
  ## Error Handling
343
261
 
344
- The package provides typed errors:
345
-
346
262
  ```typescript
347
263
  import {
348
264
  CacheError,
@@ -362,23 +278,32 @@ try {
362
278
  }
363
279
  ```
364
280
 
365
- ## Future Adapters
366
-
367
- The adapter architecture makes it easy to add support for:
368
-
369
- - `react-native-blob-util`
370
- - `expo-file-system`
371
- - S3-backed remote cache
372
- - SQLite-based storage
373
- - Custom encrypted storage
281
+ ## Observability
374
282
 
375
- To add a new adapter, implement `IStorageAdapter` and pass it to `createImmutableFileCache({ adapter })`.
376
-
377
- See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed instructions on adding adapters.
283
+ ```typescript
284
+ const cache = await createImmutableFileCache({
285
+ onEvent: (event) => {
286
+ switch (event.type) {
287
+ case "cache_hit":
288
+ console.log(`HIT: ${event.key} (${event.ageMs}ms old)`);
289
+ break;
290
+ case "cache_miss":
291
+ console.log(`MISS: ${event.key} (${event.reason})`);
292
+ break;
293
+ case "cache_write":
294
+ console.log(`WRITE: ${event.key} (${event.sizeBytes} bytes)`);
295
+ break;
296
+ case "cache_prune":
297
+ console.log(`PRUNE: removed ${event.removedCount} entries`);
298
+ break;
299
+ }
300
+ },
301
+ });
302
+ ```
378
303
 
379
304
  ## Testing
380
305
 
381
- The package includes a `MemoryAdapter` for testing:
306
+ Use the memory adapter for unit tests:
382
307
 
383
308
  ```typescript
384
309
  import { CacheEngine, createMemoryAdapter } from "@dynlabs/react-native-immutable-file-cache";
@@ -389,27 +314,24 @@ await cache.init();
389
314
 
390
315
  // Run tests...
391
316
 
392
- // Clean up
393
- adapter._reset();
317
+ adapter._reset(); // Clean up
394
318
  ```
395
319
 
396
320
  ## Contributing
397
321
 
398
- Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details.
399
-
400
322
  ```bash
401
- # Clone and install
402
323
  git clone https://github.com/dienp/react-native-immutable-file-cache.git
403
324
  cd react-native-immutable-file-cache
404
325
  npm install
405
326
 
406
- # Development
407
327
  npm run typecheck # Type check
408
328
  npm run lint # Lint
409
329
  npm test # Run tests
410
330
  npm run build # Build
411
331
  ```
412
332
 
333
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
334
+
413
335
  ## License
414
336
 
415
- MIT
337
+ [MIT](LICENSE)
@@ -49,6 +49,7 @@ function createMemoryAdapter(namespace) {
49
49
  const adapter = {
50
50
  kind: "memory",
51
51
  rootId,
52
+ supportedSources: new Set(["url", "file", "blob", "bytes"]),
52
53
  // ─────────────────────────────────────────────────────────────────
53
54
  // Directory Management
54
55
  // ─────────────────────────────────────────────────────────────────
@@ -1 +1 @@
1
- {"version":3,"names":["_errors","require","createMemoryAdapter","namespace","ns","rootId","files","Map","directories","Set","blobUrls","normalizePath","path","replace","getParentDir","lastSlash","lastIndexOf","substring","adapter","kind","ensureDir","normalized","add","parent","exists","has","remove","delete","removeDir","prefix","key","keys","startsWith","dir","listDir","entries","relativePath","slice","length","firstSlash","indexOf","Array","from","readText","_encoding","entry","get","AdapterIOError","Error","decoder","TextDecoder","decode","content","writeTextAtomic","encoder","TextEncoder","bytes","encode","set","mtime","Date","now","contentType","stat","sizeBytes","mtimeMs","writeBinaryAtomic","source","options","type","response","fetch","url","headers","ok","status","undefined","buffer","arrayBuffer","Uint8Array","onProgress","error","filePath","blob","_exhaustive","getPublicUri","existing","Blob","URL","createObjectURL","_reset","clear","values","revokeObjectURL","_getContent","_getAllPaths"],"sourceRoot":"../../../src","sources":["adapters/memoryAdapter.ts"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"names":["_errors","require","createMemoryAdapter","namespace","ns","rootId","files","Map","directories","Set","blobUrls","normalizePath","path","replace","getParentDir","lastSlash","lastIndexOf","substring","adapter","kind","supportedSources","ensureDir","normalized","add","parent","exists","has","remove","delete","removeDir","prefix","key","keys","startsWith","dir","listDir","entries","relativePath","slice","length","firstSlash","indexOf","Array","from","readText","_encoding","entry","get","AdapterIOError","Error","decoder","TextDecoder","decode","content","writeTextAtomic","encoder","TextEncoder","bytes","encode","set","mtime","Date","now","contentType","stat","sizeBytes","mtimeMs","writeBinaryAtomic","source","options","type","response","fetch","url","headers","ok","status","undefined","buffer","arrayBuffer","Uint8Array","onProgress","error","filePath","blob","_exhaustive","getPublicUri","existing","Blob","URL","createObjectURL","_reset","clear","values","revokeObjectURL","_getContent","_getAllPaths"],"sourceRoot":"../../../src","sources":["adapters/memoryAdapter.ts"],"mappings":"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","ignoreList":[]}
@@ -47,6 +47,7 @@ function createRnfsAdapter(options) {
47
47
  const adapter = {
48
48
  kind: "native-fs",
49
49
  rootId: rootPath,
50
+ supportedSources: new Set(["url", "file", "bytes"]),
50
51
  // ─────────────────────────────────────────────────────────────────
51
52
  // Directory Management
52
53
  // ─────────────────────────────────────────────────────────────────
@@ -248,12 +249,16 @@ function createRnfsAdapter(options) {
248
249
 
249
250
  /**
250
251
  * Converts Uint8Array to base64 string.
252
+ * Uses chunked approach for better performance with large arrays.
251
253
  */
252
254
  function uint8ArrayToBase64(bytes) {
253
- let binary = "";
254
- for (let i = 0; i < bytes.length; i++) {
255
- binary += String.fromCharCode(bytes[i]);
255
+ // Process in chunks to avoid call stack issues with large arrays
256
+ const CHUNK_SIZE = 0x8000; // 32KB chunks
257
+ const chunks = [];
258
+ for (let i = 0; i < bytes.length; i += CHUNK_SIZE) {
259
+ const chunk = bytes.subarray(i, i + CHUNK_SIZE);
260
+ chunks.push(String.fromCharCode.apply(null, chunk));
256
261
  }
257
- return btoa(binary);
262
+ return btoa(chunks.join(""));
258
263
  }
259
264
  //# sourceMappingURL=rnfsAdapter.js.map