@dynlabs/react-native-immutable-file-cache 1.0.0-alpha.1
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.
- package/LICENSE +21 -0
- package/README.md +415 -0
- package/lib/commonjs/adapters/memoryAdapter.js +266 -0
- package/lib/commonjs/adapters/memoryAdapter.js.map +1 -0
- package/lib/commonjs/adapters/rnfsAdapter.js +259 -0
- package/lib/commonjs/adapters/rnfsAdapter.js.map +1 -0
- package/lib/commonjs/adapters/webAdapter.js +432 -0
- package/lib/commonjs/adapters/webAdapter.js.map +1 -0
- package/lib/commonjs/core/adapter.js +2 -0
- package/lib/commonjs/core/adapter.js.map +1 -0
- package/lib/commonjs/core/cacheEngine.js +578 -0
- package/lib/commonjs/core/cacheEngine.js.map +1 -0
- package/lib/commonjs/core/errors.js +83 -0
- package/lib/commonjs/core/errors.js.map +1 -0
- package/lib/commonjs/core/hash.js +83 -0
- package/lib/commonjs/core/hash.js.map +1 -0
- package/lib/commonjs/core/indexStore.js +175 -0
- package/lib/commonjs/core/indexStore.js.map +1 -0
- package/lib/commonjs/core/mutex.js +143 -0
- package/lib/commonjs/core/mutex.js.map +1 -0
- package/lib/commonjs/core/prune.js +127 -0
- package/lib/commonjs/core/prune.js.map +1 -0
- package/lib/commonjs/core/types.js +6 -0
- package/lib/commonjs/core/types.js.map +1 -0
- package/lib/commonjs/factory.js +56 -0
- package/lib/commonjs/factory.js.map +1 -0
- package/lib/commonjs/index.js +110 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/index.native.js +74 -0
- package/lib/commonjs/index.native.js.map +1 -0
- package/lib/commonjs/index.web.js +75 -0
- package/lib/commonjs/index.web.js.map +1 -0
- package/lib/commonjs/types/react-native-fs.d.js +2 -0
- package/lib/commonjs/types/react-native-fs.d.js.map +1 -0
- package/lib/module/adapters/memoryAdapter.js +261 -0
- package/lib/module/adapters/memoryAdapter.js.map +1 -0
- package/lib/module/adapters/rnfsAdapter.js +251 -0
- package/lib/module/adapters/rnfsAdapter.js.map +1 -0
- package/lib/module/adapters/webAdapter.js +426 -0
- package/lib/module/adapters/webAdapter.js.map +1 -0
- package/lib/module/core/adapter.js +2 -0
- package/lib/module/core/adapter.js.map +1 -0
- package/lib/module/core/cacheEngine.js +571 -0
- package/lib/module/core/cacheEngine.js.map +1 -0
- package/lib/module/core/errors.js +71 -0
- package/lib/module/core/errors.js.map +1 -0
- package/lib/module/core/hash.js +76 -0
- package/lib/module/core/hash.js.map +1 -0
- package/lib/module/core/indexStore.js +168 -0
- package/lib/module/core/indexStore.js.map +1 -0
- package/lib/module/core/mutex.js +135 -0
- package/lib/module/core/mutex.js.map +1 -0
- package/lib/module/core/prune.js +116 -0
- package/lib/module/core/prune.js.map +1 -0
- package/lib/module/core/types.js +2 -0
- package/lib/module/core/types.js.map +1 -0
- package/lib/module/factory.js +49 -0
- package/lib/module/factory.js.map +1 -0
- package/lib/module/index.js +41 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/index.native.js +54 -0
- package/lib/module/index.native.js.map +1 -0
- package/lib/module/index.web.js +55 -0
- package/lib/module/index.web.js.map +1 -0
- package/lib/module/types/react-native-fs.d.js +2 -0
- package/lib/module/types/react-native-fs.d.js.map +1 -0
- package/lib/typescript/src/adapters/memoryAdapter.d.ts +23 -0
- package/lib/typescript/src/adapters/memoryAdapter.d.ts.map +1 -0
- package/lib/typescript/src/adapters/rnfsAdapter.d.ts +18 -0
- package/lib/typescript/src/adapters/rnfsAdapter.d.ts.map +1 -0
- package/lib/typescript/src/adapters/webAdapter.d.ts +30 -0
- package/lib/typescript/src/adapters/webAdapter.d.ts.map +1 -0
- package/lib/typescript/src/core/adapter.d.ts +105 -0
- package/lib/typescript/src/core/adapter.d.ts.map +1 -0
- package/lib/typescript/src/core/cacheEngine.d.ts +99 -0
- package/lib/typescript/src/core/cacheEngine.d.ts.map +1 -0
- package/lib/typescript/src/core/errors.d.ts +54 -0
- package/lib/typescript/src/core/errors.d.ts.map +1 -0
- package/lib/typescript/src/core/hash.d.ts +20 -0
- package/lib/typescript/src/core/hash.d.ts.map +1 -0
- package/lib/typescript/src/core/indexStore.d.ts +34 -0
- package/lib/typescript/src/core/indexStore.d.ts.map +1 -0
- package/lib/typescript/src/core/mutex.d.ts +49 -0
- package/lib/typescript/src/core/mutex.d.ts.map +1 -0
- package/lib/typescript/src/core/prune.d.ts +39 -0
- package/lib/typescript/src/core/prune.d.ts.map +1 -0
- package/lib/typescript/src/core/types.d.ts +109 -0
- package/lib/typescript/src/core/types.d.ts.map +1 -0
- package/lib/typescript/src/factory.d.ts +46 -0
- package/lib/typescript/src/factory.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +20 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/index.native.d.ts +37 -0
- package/lib/typescript/src/index.native.d.ts.map +1 -0
- package/lib/typescript/src/index.web.d.ts +38 -0
- package/lib/typescript/src/index.web.d.ts.map +1 -0
- package/package.json +125 -0
- package/src/adapters/memoryAdapter.ts +307 -0
- package/src/adapters/rnfsAdapter.ts +283 -0
- package/src/adapters/webAdapter.ts +480 -0
- package/src/core/adapter.ts +128 -0
- package/src/core/cacheEngine.ts +634 -0
- package/src/core/errors.ts +82 -0
- package/src/core/hash.ts +78 -0
- package/src/core/indexStore.ts +184 -0
- package/src/core/mutex.ts +134 -0
- package/src/core/prune.ts +145 -0
- package/src/core/types.ts +165 -0
- package/src/factory.ts +60 -0
- package/src/index.native.ts +58 -0
- package/src/index.ts +82 -0
- package/src/index.web.ts +59 -0
- package/src/types/react-native-fs.d.ts +75 -0
|
@@ -0,0 +1,578 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.CacheEngine = void 0;
|
|
7
|
+
var _indexStore = require("./indexStore");
|
|
8
|
+
var _mutex = require("./mutex");
|
|
9
|
+
var _hash = require("./hash");
|
|
10
|
+
var _prune = require("./prune");
|
|
11
|
+
/* eslint-disable @typescript-eslint/require-await */
|
|
12
|
+
|
|
13
|
+
const ENTRIES_DIR = "entries";
|
|
14
|
+
const INDEX_FILE = "index.json";
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Main cache engine implementation.
|
|
18
|
+
* Coordinates all cache operations through the storage adapter.
|
|
19
|
+
*/
|
|
20
|
+
class CacheEngine {
|
|
21
|
+
_indexMutex = new _mutex.Mutex();
|
|
22
|
+
_keyMutex = new _mutex.KeyedMutex();
|
|
23
|
+
_index = (0, _prune.createEmptyIndex)();
|
|
24
|
+
_initialized = false;
|
|
25
|
+
constructor(config, adapter) {
|
|
26
|
+
this._config = {
|
|
27
|
+
namespace: "default",
|
|
28
|
+
autoPruneExpired: true,
|
|
29
|
+
...config
|
|
30
|
+
};
|
|
31
|
+
this._adapter = adapter;
|
|
32
|
+
this._indexStore = new _indexStore.IndexStore(adapter, INDEX_FILE);
|
|
33
|
+
this._hashFn = config.hashFn ?? _hash.hash;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Initialize cache (ensure directories, load index).
|
|
38
|
+
*/
|
|
39
|
+
async init() {
|
|
40
|
+
if (this._initialized) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
await this._indexMutex.runExclusive(async () => {
|
|
44
|
+
// Ensure entries directory exists
|
|
45
|
+
await this._adapter.ensureDir(ENTRIES_DIR);
|
|
46
|
+
|
|
47
|
+
// Load or rebuild index
|
|
48
|
+
try {
|
|
49
|
+
this._index = await this._indexStore.load();
|
|
50
|
+
} catch {
|
|
51
|
+
// Index is corrupt, rebuild from filesystem
|
|
52
|
+
this._index = await this._indexStore.rebuild(ENTRIES_DIR);
|
|
53
|
+
}
|
|
54
|
+
this._initialized = true;
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// ─────────────────────────────────────────────────────────────────
|
|
59
|
+
// Put Operations (Immutable - no overwrites)
|
|
60
|
+
// ─────────────────────────────────────────────────────────────────
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Store content from URL.
|
|
64
|
+
* Returns {status: "exists"} if key already exists.
|
|
65
|
+
*/
|
|
66
|
+
async putFromUrl(key, url, options) {
|
|
67
|
+
const source = {
|
|
68
|
+
type: "url",
|
|
69
|
+
url,
|
|
70
|
+
headers: options?.headers
|
|
71
|
+
};
|
|
72
|
+
return this._put(key, source, options);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Store content from local file path (native only).
|
|
77
|
+
*/
|
|
78
|
+
async putFromFile(key, filePath, options) {
|
|
79
|
+
const source = {
|
|
80
|
+
type: "file",
|
|
81
|
+
filePath
|
|
82
|
+
};
|
|
83
|
+
return this._put(key, source, options);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Store content from Blob (web only).
|
|
88
|
+
*/
|
|
89
|
+
async putFromBlob(key, blob, options) {
|
|
90
|
+
const source = {
|
|
91
|
+
type: "blob",
|
|
92
|
+
blob
|
|
93
|
+
};
|
|
94
|
+
return this._put(key, source, options);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Store content from raw bytes.
|
|
99
|
+
*/
|
|
100
|
+
async putFromBytes(key, bytes, options) {
|
|
101
|
+
const source = {
|
|
102
|
+
type: "bytes",
|
|
103
|
+
bytes
|
|
104
|
+
};
|
|
105
|
+
return this._put(key, source, options);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Internal put implementation.
|
|
110
|
+
*/
|
|
111
|
+
async _put(key, source, options) {
|
|
112
|
+
this._ensureInitialized();
|
|
113
|
+
|
|
114
|
+
// Use keyed mutex to serialize operations on the same key
|
|
115
|
+
return this._keyMutex.runExclusive(key, async () => {
|
|
116
|
+
// Check if key already exists
|
|
117
|
+
const existingEntry = this._index.entries[key];
|
|
118
|
+
if (existingEntry) {
|
|
119
|
+
// Check if expired
|
|
120
|
+
const now = Date.now();
|
|
121
|
+
if (existingEntry.expiresAt === undefined || existingEntry.expiresAt >= now) {
|
|
122
|
+
// Entry exists and is not expired, return exists
|
|
123
|
+
const entry = this._entryWithPath(existingEntry);
|
|
124
|
+
return {
|
|
125
|
+
status: "exists",
|
|
126
|
+
entry
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// Entry is expired, remove it first
|
|
130
|
+
await this._removeEntry(key);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Compute hash
|
|
134
|
+
const hashValue = await this._hashFn(key);
|
|
135
|
+
|
|
136
|
+
// Determine extension
|
|
137
|
+
const ext = options?.ext ?? this._extractExtension(source);
|
|
138
|
+
|
|
139
|
+
// Build entry path
|
|
140
|
+
const entryPath = `${ENTRIES_DIR}/${hashValue}${ext}`;
|
|
141
|
+
|
|
142
|
+
// Write binary content
|
|
143
|
+
const writeResult = await this._adapter.writeBinaryAtomic(entryPath, source, {
|
|
144
|
+
onProgress: options?.onProgress,
|
|
145
|
+
headers: options?.headers
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Calculate expiration
|
|
149
|
+
const now = Date.now();
|
|
150
|
+
const ttlMs = options?.ttlMs ?? this._config.defaultTtlMs;
|
|
151
|
+
const expiresAt = ttlMs !== undefined ? now + ttlMs : undefined;
|
|
152
|
+
|
|
153
|
+
// Create entry metadata
|
|
154
|
+
const entryMeta = {
|
|
155
|
+
key,
|
|
156
|
+
hash: hashValue,
|
|
157
|
+
ext,
|
|
158
|
+
sizeBytes: writeResult.sizeBytes,
|
|
159
|
+
contentType: writeResult.contentType,
|
|
160
|
+
createdAt: now,
|
|
161
|
+
lastAccessedAt: now,
|
|
162
|
+
expiresAt,
|
|
163
|
+
metadata: options?.metadata
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
// Update index atomically
|
|
167
|
+
await this._indexMutex.runExclusive(async () => {
|
|
168
|
+
this._index = (0, _prune.addEntryToIndex)(this._index, entryMeta);
|
|
169
|
+
await this._indexStore.save(this._index);
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// Auto-prune if configured
|
|
173
|
+
if (this._config.autoPruneExpired) {
|
|
174
|
+
// Don't await - run in background
|
|
175
|
+
this._autoPrune().catch(() => {
|
|
176
|
+
// Ignore prune errors
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
const entry = this._entryWithPath(entryMeta);
|
|
180
|
+
return {
|
|
181
|
+
status: "created",
|
|
182
|
+
entry
|
|
183
|
+
};
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ─────────────────────────────────────────────────────────────────
|
|
188
|
+
// Get Operations
|
|
189
|
+
// ─────────────────────────────────────────────────────────────────
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Get entry by key. Returns null if not found or expired.
|
|
193
|
+
* Updates lastAccessedAt.
|
|
194
|
+
*/
|
|
195
|
+
async get(key) {
|
|
196
|
+
this._ensureInitialized();
|
|
197
|
+
const entryMeta = this._index.entries[key];
|
|
198
|
+
if (!entryMeta) {
|
|
199
|
+
return null;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Check expiration
|
|
203
|
+
const now = Date.now();
|
|
204
|
+
if (entryMeta.expiresAt !== undefined && entryMeta.expiresAt < now) {
|
|
205
|
+
// Entry is expired
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Update lastAccessedAt
|
|
210
|
+
await this._indexMutex.runExclusive(async () => {
|
|
211
|
+
this._index = (0, _prune.touchEntry)(this._index, key, now);
|
|
212
|
+
await this._indexStore.save(this._index);
|
|
213
|
+
});
|
|
214
|
+
const entry = this._entryWithPath(entryMeta);
|
|
215
|
+
const uri = await this._adapter.getPublicUri(entry.path);
|
|
216
|
+
return {
|
|
217
|
+
entry,
|
|
218
|
+
uri
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Check if key exists and is not expired.
|
|
224
|
+
*/
|
|
225
|
+
async has(key) {
|
|
226
|
+
this._ensureInitialized();
|
|
227
|
+
const entryMeta = this._index.entries[key];
|
|
228
|
+
if (!entryMeta) {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// Check expiration
|
|
233
|
+
const now = Date.now();
|
|
234
|
+
if (entryMeta.expiresAt !== undefined && entryMeta.expiresAt < now) {
|
|
235
|
+
return false;
|
|
236
|
+
}
|
|
237
|
+
return true;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Get entry metadata without updating lastAccessedAt.
|
|
242
|
+
*/
|
|
243
|
+
async peek(key) {
|
|
244
|
+
this._ensureInitialized();
|
|
245
|
+
const entryMeta = this._index.entries[key];
|
|
246
|
+
if (!entryMeta) {
|
|
247
|
+
return null;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Check expiration
|
|
251
|
+
const now = Date.now();
|
|
252
|
+
if (entryMeta.expiresAt !== undefined && entryMeta.expiresAt < now) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
return this._entryWithPath(entryMeta);
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// ─────────────────────────────────────────────────────────────────
|
|
259
|
+
// List/Query Operations
|
|
260
|
+
// ─────────────────────────────────────────────────────────────────
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* List entries with sorting, filtering, pagination.
|
|
264
|
+
*/
|
|
265
|
+
async list(options) {
|
|
266
|
+
this._ensureInitialized();
|
|
267
|
+
const now = Date.now();
|
|
268
|
+
let entries = Object.values(this._index.entries)
|
|
269
|
+
// Filter out expired entries
|
|
270
|
+
.filter(e => e.expiresAt === undefined || e.expiresAt >= now)
|
|
271
|
+
// Apply custom filter if provided
|
|
272
|
+
.filter(e => options?.filter ? options.filter(e) : true);
|
|
273
|
+
|
|
274
|
+
// Sort
|
|
275
|
+
const sortBy = options?.sortBy ?? "createdAt";
|
|
276
|
+
const order = options?.order ?? "desc";
|
|
277
|
+
const multiplier = order === "desc" ? -1 : 1;
|
|
278
|
+
entries.sort((a, b) => {
|
|
279
|
+
let comparison = 0;
|
|
280
|
+
switch (sortBy) {
|
|
281
|
+
case "createdAt":
|
|
282
|
+
comparison = a.createdAt - b.createdAt;
|
|
283
|
+
break;
|
|
284
|
+
case "lastAccessedAt":
|
|
285
|
+
comparison = a.lastAccessedAt - b.lastAccessedAt;
|
|
286
|
+
break;
|
|
287
|
+
case "sizeBytes":
|
|
288
|
+
comparison = a.sizeBytes - b.sizeBytes;
|
|
289
|
+
break;
|
|
290
|
+
case "key":
|
|
291
|
+
comparison = a.key.localeCompare(b.key);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
return comparison * multiplier;
|
|
295
|
+
});
|
|
296
|
+
|
|
297
|
+
// Pagination
|
|
298
|
+
if (options?.offset !== undefined) {
|
|
299
|
+
entries = entries.slice(options.offset);
|
|
300
|
+
}
|
|
301
|
+
if (options?.limit !== undefined) {
|
|
302
|
+
entries = entries.slice(0, options.limit);
|
|
303
|
+
}
|
|
304
|
+
return entries.map(e => this._entryWithPath(e));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Get cache statistics.
|
|
309
|
+
*/
|
|
310
|
+
async stats() {
|
|
311
|
+
this._ensureInitialized();
|
|
312
|
+
const now = Date.now();
|
|
313
|
+
const validEntries = Object.values(this._index.entries).filter(e => e.expiresAt === undefined || e.expiresAt >= now);
|
|
314
|
+
if (validEntries.length === 0) {
|
|
315
|
+
return {
|
|
316
|
+
entryCount: 0,
|
|
317
|
+
totalSizeBytes: 0
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
// Find oldest and newest by createdAt
|
|
322
|
+
let oldest = validEntries[0];
|
|
323
|
+
let newest = validEntries[0];
|
|
324
|
+
for (const entry of validEntries) {
|
|
325
|
+
if (entry.createdAt < oldest.createdAt) {
|
|
326
|
+
oldest = entry;
|
|
327
|
+
}
|
|
328
|
+
if (entry.createdAt > newest.createdAt) {
|
|
329
|
+
newest = entry;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
const totalSizeBytes = validEntries.reduce((sum, e) => sum + e.sizeBytes, 0);
|
|
333
|
+
return {
|
|
334
|
+
entryCount: validEntries.length,
|
|
335
|
+
totalSizeBytes,
|
|
336
|
+
oldestEntry: oldest,
|
|
337
|
+
newestEntry: newest
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// ─────────────────────────────────────────────────────────────────
|
|
342
|
+
// Remove/Prune Operations
|
|
343
|
+
// ─────────────────────────────────────────────────────────────────
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Remove specific entry by key.
|
|
347
|
+
*/
|
|
348
|
+
async remove(key) {
|
|
349
|
+
this._ensureInitialized();
|
|
350
|
+
return this._keyMutex.runExclusive(key, async () => {
|
|
351
|
+
return this._removeEntry(key);
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Internal remove implementation (must be called within keyed mutex).
|
|
357
|
+
*/
|
|
358
|
+
async _removeEntry(key) {
|
|
359
|
+
const entryMeta = this._index.entries[key];
|
|
360
|
+
if (!entryMeta) {
|
|
361
|
+
return false;
|
|
362
|
+
}
|
|
363
|
+
const entryPath = `${ENTRIES_DIR}/${entryMeta.hash}${entryMeta.ext}`;
|
|
364
|
+
|
|
365
|
+
// Remove file
|
|
366
|
+
await this._adapter.remove(entryPath);
|
|
367
|
+
|
|
368
|
+
// Update index
|
|
369
|
+
await this._indexMutex.runExclusive(async () => {
|
|
370
|
+
this._index = (0, _prune.removeEntriesFromIndex)(this._index, [key]);
|
|
371
|
+
await this._indexStore.save(this._index);
|
|
372
|
+
});
|
|
373
|
+
return true;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/**
|
|
377
|
+
* Remove all expired entries.
|
|
378
|
+
*/
|
|
379
|
+
async removeExpired() {
|
|
380
|
+
this._ensureInitialized();
|
|
381
|
+
const now = Date.now();
|
|
382
|
+
const expired = (0, _prune.getExpiredEntries)(this._index, now);
|
|
383
|
+
if (expired.length === 0) {
|
|
384
|
+
return {
|
|
385
|
+
removedCount: 0,
|
|
386
|
+
freedBytes: 0,
|
|
387
|
+
removedKeys: []
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
return this._removeEntries(expired);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
/**
|
|
394
|
+
* Prune to fit within size limit using LRU.
|
|
395
|
+
*/
|
|
396
|
+
async pruneLru(maxSizeBytes) {
|
|
397
|
+
this._ensureInitialized();
|
|
398
|
+
const targets = (0, _prune.getLruPruneTargets)(this._index, maxSizeBytes);
|
|
399
|
+
if (targets.length === 0) {
|
|
400
|
+
return {
|
|
401
|
+
removedCount: 0,
|
|
402
|
+
freedBytes: 0,
|
|
403
|
+
removedKeys: []
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
return this._removeEntries(targets);
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Remove multiple entries.
|
|
411
|
+
*/
|
|
412
|
+
async _removeEntries(entries) {
|
|
413
|
+
const removedKeys = [];
|
|
414
|
+
let freedBytes = 0;
|
|
415
|
+
for (const entry of entries) {
|
|
416
|
+
const entryPath = `${ENTRIES_DIR}/${entry.hash}${entry.ext}`;
|
|
417
|
+
try {
|
|
418
|
+
await this._adapter.remove(entryPath);
|
|
419
|
+
removedKeys.push(entry.key);
|
|
420
|
+
freedBytes += entry.sizeBytes;
|
|
421
|
+
} catch {
|
|
422
|
+
// Ignore removal errors
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// Update index atomically
|
|
427
|
+
if (removedKeys.length > 0) {
|
|
428
|
+
await this._indexMutex.runExclusive(async () => {
|
|
429
|
+
this._index = (0, _prune.removeEntriesFromIndex)(this._index, removedKeys);
|
|
430
|
+
await this._indexStore.save(this._index);
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
removedCount: removedKeys.length,
|
|
435
|
+
freedBytes,
|
|
436
|
+
removedKeys
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Clear all entries.
|
|
442
|
+
*/
|
|
443
|
+
async clear() {
|
|
444
|
+
this._ensureInitialized();
|
|
445
|
+
await this._indexMutex.runExclusive(async () => {
|
|
446
|
+
// Remove all entry files
|
|
447
|
+
try {
|
|
448
|
+
await this._adapter.removeDir(ENTRIES_DIR);
|
|
449
|
+
} catch {
|
|
450
|
+
// Ignore errors
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// Recreate entries directory
|
|
454
|
+
await this._adapter.ensureDir(ENTRIES_DIR);
|
|
455
|
+
|
|
456
|
+
// Clear index
|
|
457
|
+
this._index = (0, _prune.createEmptyIndex)();
|
|
458
|
+
await this._indexStore.save(this._index);
|
|
459
|
+
});
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// ─────────────────────────────────────────────────────────────────
|
|
463
|
+
// Maintenance
|
|
464
|
+
// ─────────────────────────────────────────────────────────────────
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Validate index against filesystem and rebuild if needed.
|
|
468
|
+
*/
|
|
469
|
+
async validateAndRepair() {
|
|
470
|
+
this._ensureInitialized();
|
|
471
|
+
const issues = [];
|
|
472
|
+
await this._indexMutex.runExclusive(async () => {
|
|
473
|
+
// Check each entry in index exists on filesystem
|
|
474
|
+
for (const entry of Object.values(this._index.entries)) {
|
|
475
|
+
const entryPath = `${ENTRIES_DIR}/${entry.hash}${entry.ext}`;
|
|
476
|
+
const exists = await this._adapter.exists(entryPath);
|
|
477
|
+
if (!exists) {
|
|
478
|
+
issues.push(`Missing file for entry "${entry.key}"`);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
// Check for orphan files not in index
|
|
483
|
+
try {
|
|
484
|
+
const files = await this._adapter.listDir(ENTRIES_DIR);
|
|
485
|
+
const indexedHashes = new Set(Object.values(this._index.entries).map(e => `${e.hash}${e.ext}`));
|
|
486
|
+
for (const file of files) {
|
|
487
|
+
if (!indexedHashes.has(file)) {
|
|
488
|
+
issues.push(`Orphan file "${file}" not in index`);
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
} catch {
|
|
492
|
+
issues.push("Could not list entries directory");
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
// If there are issues, rebuild index
|
|
497
|
+
if (issues.length > 0) {
|
|
498
|
+
await this._indexMutex.runExclusive(async () => {
|
|
499
|
+
this._index = await this._indexStore.rebuild(ENTRIES_DIR);
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
return {
|
|
503
|
+
repaired: issues.length > 0,
|
|
504
|
+
issues
|
|
505
|
+
};
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// ─────────────────────────────────────────────────────────────────
|
|
509
|
+
// Private Helpers
|
|
510
|
+
// ─────────────────────────────────────────────────────────────────
|
|
511
|
+
|
|
512
|
+
_ensureInitialized() {
|
|
513
|
+
if (!this._initialized) {
|
|
514
|
+
throw new Error("CacheEngine not initialized. Call init() first.");
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
_entryWithPath(meta) {
|
|
518
|
+
return {
|
|
519
|
+
...meta,
|
|
520
|
+
path: `${ENTRIES_DIR}/${meta.hash}${meta.ext}`
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
_extractExtension(source) {
|
|
524
|
+
switch (source.type) {
|
|
525
|
+
case "url":
|
|
526
|
+
{
|
|
527
|
+
const url = new URL(source.url);
|
|
528
|
+
const pathname = url.pathname;
|
|
529
|
+
const lastDot = pathname.lastIndexOf(".");
|
|
530
|
+
if (lastDot > 0 && lastDot > pathname.lastIndexOf("/")) {
|
|
531
|
+
return pathname.substring(lastDot);
|
|
532
|
+
}
|
|
533
|
+
return "";
|
|
534
|
+
}
|
|
535
|
+
case "file":
|
|
536
|
+
{
|
|
537
|
+
const lastDot = source.filePath.lastIndexOf(".");
|
|
538
|
+
const lastSlash = Math.max(source.filePath.lastIndexOf("/"), source.filePath.lastIndexOf("\\"));
|
|
539
|
+
if (lastDot > 0 && lastDot > lastSlash) {
|
|
540
|
+
return source.filePath.substring(lastDot);
|
|
541
|
+
}
|
|
542
|
+
return "";
|
|
543
|
+
}
|
|
544
|
+
case "blob":
|
|
545
|
+
{
|
|
546
|
+
// Try to extract from MIME type
|
|
547
|
+
const mime = source.blob.type;
|
|
548
|
+
if (mime) {
|
|
549
|
+
const mimeToExt = {
|
|
550
|
+
"image/jpeg": ".jpg",
|
|
551
|
+
"image/png": ".png",
|
|
552
|
+
"image/gif": ".gif",
|
|
553
|
+
"image/webp": ".webp",
|
|
554
|
+
"application/json": ".json",
|
|
555
|
+
"text/plain": ".txt",
|
|
556
|
+
"text/html": ".html",
|
|
557
|
+
"application/pdf": ".pdf"
|
|
558
|
+
};
|
|
559
|
+
return mimeToExt[mime] ?? "";
|
|
560
|
+
}
|
|
561
|
+
return "";
|
|
562
|
+
}
|
|
563
|
+
case "bytes":
|
|
564
|
+
return "";
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
async _autoPrune() {
|
|
568
|
+
// Remove expired entries
|
|
569
|
+
await this.removeExpired();
|
|
570
|
+
|
|
571
|
+
// LRU prune if max size configured
|
|
572
|
+
if (this._config.maxSizeBytes !== undefined) {
|
|
573
|
+
await this.pruneLru(this._config.maxSizeBytes);
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
exports.CacheEngine = CacheEngine;
|
|
578
|
+
//# sourceMappingURL=cacheEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_indexStore","require","_mutex","_hash","_prune","ENTRIES_DIR","INDEX_FILE","CacheEngine","_indexMutex","Mutex","_keyMutex","KeyedMutex","_index","createEmptyIndex","_initialized","constructor","config","adapter","_config","namespace","autoPruneExpired","_adapter","IndexStore","_hashFn","hashFn","defaultHash","init","runExclusive","ensureDir","load","rebuild","putFromUrl","key","url","options","source","type","headers","_put","putFromFile","filePath","putFromBlob","blob","putFromBytes","bytes","_ensureInitialized","existingEntry","entries","now","Date","expiresAt","undefined","entry","_entryWithPath","status","_removeEntry","hashValue","ext","_extractExtension","entryPath","writeResult","writeBinaryAtomic","onProgress","ttlMs","defaultTtlMs","entryMeta","hash","sizeBytes","contentType","createdAt","lastAccessedAt","metadata","addEntryToIndex","save","_autoPrune","catch","get","touchEntry","uri","getPublicUri","path","has","peek","list","Object","values","filter","e","sortBy","order","multiplier","sort","a","b","comparison","localeCompare","offset","slice","limit","map","stats","validEntries","length","entryCount","totalSizeBytes","oldest","newest","reduce","sum","oldestEntry","newestEntry","remove","removeEntriesFromIndex","removeExpired","expired","getExpiredEntries","removedCount","freedBytes","removedKeys","_removeEntries","pruneLru","maxSizeBytes","targets","getLruPruneTargets","push","clear","removeDir","validateAndRepair","issues","exists","files","listDir","indexedHashes","Set","file","repaired","Error","meta","URL","pathname","lastDot","lastIndexOf","substring","lastSlash","Math","max","mime","mimeToExt","exports"],"sourceRoot":"../../../src","sources":["core/cacheEngine.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.UnsupportedSourceError = exports.ImmutableConflictError = exports.EntryNotFoundError = exports.CorruptIndexError = exports.CacheError = exports.AdapterIOError = void 0;
|
|
7
|
+
/**
|
|
8
|
+
* Base error class for cache operations.
|
|
9
|
+
*/
|
|
10
|
+
class CacheError extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = this.constructor.name;
|
|
14
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Thrown when an adapter receives a TBinarySource type it cannot handle.
|
|
20
|
+
*/
|
|
21
|
+
exports.CacheError = CacheError;
|
|
22
|
+
class UnsupportedSourceError extends CacheError {
|
|
23
|
+
code = "UNSUPPORTED_SOURCE";
|
|
24
|
+
constructor(sourceType, adapterKind) {
|
|
25
|
+
super(`Adapter "${adapterKind}" does not support source type "${sourceType}"`);
|
|
26
|
+
this.sourceType = sourceType;
|
|
27
|
+
this.adapterKind = adapterKind;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Thrown when an adapter I/O operation fails.
|
|
33
|
+
*/
|
|
34
|
+
exports.UnsupportedSourceError = UnsupportedSourceError;
|
|
35
|
+
class AdapterIOError extends CacheError {
|
|
36
|
+
code = "ADAPTER_IO_ERROR";
|
|
37
|
+
constructor(operation, path, cause) {
|
|
38
|
+
super(`Adapter I/O error during "${operation}" at path "${path}": ${cause?.message ?? "unknown"}`);
|
|
39
|
+
this.operation = operation;
|
|
40
|
+
this.path = path;
|
|
41
|
+
this.cause = cause;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Thrown when the cache index is corrupt and cannot be parsed.
|
|
47
|
+
*/
|
|
48
|
+
exports.AdapterIOError = AdapterIOError;
|
|
49
|
+
class CorruptIndexError extends CacheError {
|
|
50
|
+
code = "CORRUPT_INDEX";
|
|
51
|
+
constructor(reason, cause) {
|
|
52
|
+
super(`Cache index is corrupt: ${reason}`);
|
|
53
|
+
this.reason = reason;
|
|
54
|
+
this.cause = cause;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Internal error when attempting to overwrite an immutable entry.
|
|
60
|
+
* Public API converts this to {status: "exists"} response.
|
|
61
|
+
*/
|
|
62
|
+
exports.CorruptIndexError = CorruptIndexError;
|
|
63
|
+
class ImmutableConflictError extends CacheError {
|
|
64
|
+
code = "IMMUTABLE_CONFLICT";
|
|
65
|
+
constructor(key) {
|
|
66
|
+
super(`Cannot overwrite immutable entry with key "${key}"`);
|
|
67
|
+
this.key = key;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Thrown when a required entry is not found.
|
|
73
|
+
*/
|
|
74
|
+
exports.ImmutableConflictError = ImmutableConflictError;
|
|
75
|
+
class EntryNotFoundError extends CacheError {
|
|
76
|
+
code = "ENTRY_NOT_FOUND";
|
|
77
|
+
constructor(key) {
|
|
78
|
+
super(`Cache entry not found for key "${key}"`);
|
|
79
|
+
this.key = key;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
exports.EntryNotFoundError = EntryNotFoundError;
|
|
83
|
+
//# sourceMappingURL=errors.js.map
|