cachimbo 0.0.3 → 0.0.5
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/README.md +12 -3
- package/dist/index.cjs +201 -23
- package/dist/index.d.cts +136 -17
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +136 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +199 -24
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
package/README.md
CHANGED
|
@@ -4,7 +4,10 @@
|
|
|
4
4
|
|
|
5
5
|
<h1 align="center">Cachimbo</h1>
|
|
6
6
|
|
|
7
|
-
Cachimbo is
|
|
7
|
+
Cachimbo is a composable caching library that allows layering different strategies in order to maximize the performance.
|
|
8
|
+
|
|
9
|
+
[](https://www.npmjs.com/package/cachimbo)
|
|
10
|
+
[](https://app.codecov.io/gh/Guichaguri/cachimbo)
|
|
8
11
|
|
|
9
12
|
## Features
|
|
10
13
|
|
|
@@ -18,7 +21,8 @@ Cachimbo is an advanced caching library that allows you to layer different strat
|
|
|
18
21
|
- Least Recently Used (LRU) eviction
|
|
19
22
|
- Time-based (TTL) eviction
|
|
20
23
|
- FIFO eviction
|
|
21
|
-
-
|
|
24
|
+
- Weak References (garbage collectable cached items)
|
|
25
|
+
- Supports composable cache strategies
|
|
22
26
|
- Request coalescing (deduplication)
|
|
23
27
|
- Multi-layer caching (tiered cache)
|
|
24
28
|
- Stale-While-Revalidate
|
|
@@ -78,7 +82,9 @@ External caches (like Redis, Memcached, etc) provide fast, scalable, shared stor
|
|
|
78
82
|
|
|
79
83
|
## Cache Layers
|
|
80
84
|
|
|
81
|
-
|
|
85
|
+
Cache layers are composable components that sit between your code and the cache store. While cache stores define *where* data is stored, cache layers define *how* the cache is accessed.
|
|
86
|
+
|
|
87
|
+
Each layer intercepts cache operations to add behavior. Layers can be stacked to form a pipeline, allowing advanced caching strategies to be reused across different cache backends.
|
|
82
88
|
|
|
83
89
|
- [Request Coalescing](/docs/layers/request-coalescing.md) (deduplication)
|
|
84
90
|
- [Tiered Caching](/docs/layers/tiered.md) (multi-layer caching)
|
|
@@ -89,6 +95,9 @@ These layers work just like "middlewares" but for caches, they customize how a c
|
|
|
89
95
|
- [Metrics Collection](/docs/layers/metrics-collection.md)
|
|
90
96
|
|
|
91
97
|
## Guides
|
|
98
|
+
- [Getting Started](/docs/guides/getting-started.md)
|
|
92
99
|
- [Choosing the right combination of layers](/docs/guides/choosing-layers.md)
|
|
93
100
|
- [Disabling cache](/docs/guides/disabling.md)
|
|
101
|
+
- [Testing](/docs/guides/testing.md)
|
|
94
102
|
- [Extending](/docs/guides/extending.md)
|
|
103
|
+
- [Samples](/samples)
|
package/dist/index.cjs
CHANGED
|
@@ -46,21 +46,18 @@ var BaseLocalCache = class extends BaseCache {
|
|
|
46
46
|
disposeListeners = [];
|
|
47
47
|
/**
|
|
48
48
|
* Reads cached resources by their keys. (synchronous version)
|
|
49
|
-
* @protected
|
|
50
49
|
*/
|
|
51
50
|
_getMany(keys) {
|
|
52
51
|
return Object.fromEntries(keys.map((key) => [key, this._get(key)]));
|
|
53
52
|
}
|
|
54
53
|
/**
|
|
55
54
|
* Writes resources into cache. (synchronous version)
|
|
56
|
-
* @protected
|
|
57
55
|
*/
|
|
58
56
|
_setMany(data, options) {
|
|
59
57
|
for (const [key, value] of Object.entries(data)) this._set(key, value, options);
|
|
60
58
|
}
|
|
61
59
|
/**
|
|
62
60
|
* Deletes many cached resources by their keys. (synchronous version)
|
|
63
|
-
* @protected
|
|
64
61
|
*/
|
|
65
62
|
_deleteMany(keys) {
|
|
66
63
|
for (const key of keys) this._delete(key);
|
|
@@ -69,29 +66,41 @@ var BaseLocalCache = class extends BaseCache {
|
|
|
69
66
|
* Adds a listener that will be called when a cached item is disposed.
|
|
70
67
|
*
|
|
71
68
|
* @param listener The listener function to add.
|
|
72
|
-
* @protected
|
|
73
69
|
*/
|
|
74
70
|
_addDisposeListener(listener) {
|
|
75
71
|
this.disposeListeners.push(listener);
|
|
76
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* Gets access to the internal synchronous methods.
|
|
75
|
+
* @experimental
|
|
76
|
+
*/
|
|
77
|
+
get internal() {
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
/** @sealed **/
|
|
77
81
|
get(key) {
|
|
78
82
|
return Promise.resolve(this._get(key));
|
|
79
83
|
}
|
|
84
|
+
/** @sealed **/
|
|
80
85
|
set(key, value, options) {
|
|
81
86
|
this._set(key, value, options);
|
|
82
87
|
return Promise.resolve();
|
|
83
88
|
}
|
|
89
|
+
/** @sealed **/
|
|
84
90
|
delete(key) {
|
|
85
91
|
this._delete(key);
|
|
86
92
|
return Promise.resolve();
|
|
87
93
|
}
|
|
94
|
+
/** @sealed **/
|
|
88
95
|
getMany(keys) {
|
|
89
96
|
return Promise.resolve(this._getMany(keys));
|
|
90
97
|
}
|
|
98
|
+
/** @sealed **/
|
|
91
99
|
setMany(data, options) {
|
|
92
100
|
this._setMany(data, options);
|
|
93
101
|
return Promise.resolve();
|
|
94
102
|
}
|
|
103
|
+
/** @sealed **/
|
|
95
104
|
deleteMany(keys) {
|
|
96
105
|
this._deleteMany(keys);
|
|
97
106
|
return Promise.resolve();
|
|
@@ -205,66 +214,229 @@ var LocalTTLCache = class extends BaseLocalCache {
|
|
|
205
214
|
* Once the limit of items is reached, the first inserted keys will be purged.
|
|
206
215
|
*/
|
|
207
216
|
var LocalMapCache = class extends BaseLocalCache {
|
|
208
|
-
|
|
217
|
+
map;
|
|
209
218
|
max;
|
|
210
219
|
constructor(options = {}) {
|
|
211
220
|
super(options);
|
|
212
|
-
this.
|
|
221
|
+
this.map = options.map ?? /* @__PURE__ */ new Map();
|
|
213
222
|
this.max = options.max ?? Infinity;
|
|
214
223
|
}
|
|
215
224
|
/** @internal */
|
|
216
225
|
_get(key) {
|
|
217
226
|
this.logger?.debug(this.name, "[get]", "key =", key);
|
|
218
|
-
const data = this.
|
|
227
|
+
const data = this.map.get(key);
|
|
219
228
|
return data === void 0 ? null : data;
|
|
220
229
|
}
|
|
221
230
|
/** @internal */
|
|
222
231
|
_set(key, value, options) {
|
|
223
232
|
this.logger?.debug(this.name, "[set]", "key =", key);
|
|
224
|
-
const previousValue = this.
|
|
225
|
-
if (this.
|
|
226
|
-
this.
|
|
233
|
+
const previousValue = this.map.get(key);
|
|
234
|
+
if (this.map.size >= this.max && previousValue === void 0) this.evict(1);
|
|
235
|
+
this.map.set(key, value);
|
|
227
236
|
this.onDispose(key, previousValue, "set");
|
|
228
237
|
}
|
|
229
238
|
/** @internal */
|
|
230
239
|
_delete(key) {
|
|
231
240
|
this.logger?.debug(this.name, "[delete]", "key =", key);
|
|
232
|
-
const previousValue = this.
|
|
233
|
-
this.
|
|
241
|
+
const previousValue = this.map.get(key);
|
|
242
|
+
this.map.delete(key);
|
|
234
243
|
this.onDispose(key, previousValue, "delete");
|
|
235
244
|
}
|
|
236
245
|
async setMany(data, options) {
|
|
237
246
|
this.logger?.debug(this.name, "[setMany]", "data =", data);
|
|
238
247
|
const entries = Object.entries(data);
|
|
239
|
-
const newEntries = entries.filter(([key]) => !this.
|
|
240
|
-
if (this.
|
|
248
|
+
const newEntries = entries.filter(([key]) => !this.map.has(key)).length;
|
|
249
|
+
if (this.map.size + newEntries > this.max) this.evict(this.map.size + newEntries - this.max);
|
|
241
250
|
for (const [key, value] of entries) {
|
|
242
|
-
const previousValue = this.
|
|
243
|
-
this.
|
|
251
|
+
const previousValue = this.map.get(key);
|
|
252
|
+
this.map.set(key, value);
|
|
244
253
|
this.onDispose(key, previousValue, "set");
|
|
245
254
|
}
|
|
246
255
|
}
|
|
247
256
|
clear() {
|
|
248
257
|
this.logger?.debug(this.name, "[clear]");
|
|
249
|
-
for (const key of this.
|
|
250
|
-
this.
|
|
258
|
+
for (const key of this.map.keys()) this.onDispose(key, this.map.get(key), "delete");
|
|
259
|
+
this.map.clear();
|
|
251
260
|
}
|
|
252
261
|
onDispose(key, value, reason) {
|
|
253
262
|
if (value !== void 0) super.onDispose(key, value, reason);
|
|
254
263
|
}
|
|
255
264
|
evict(length) {
|
|
256
|
-
const keys = this.
|
|
265
|
+
const keys = this.map.keys();
|
|
257
266
|
for (let i = 0; i < length; i++) {
|
|
258
267
|
const key = keys.next();
|
|
259
268
|
if (key.done) break;
|
|
260
269
|
this.logger?.debug(this.name, "[evict]", "key = ", key);
|
|
261
|
-
const previousValue = this.
|
|
262
|
-
this.
|
|
270
|
+
const previousValue = this.map.get(key.value);
|
|
271
|
+
this.map.delete(key.value);
|
|
263
272
|
this.onDispose(key.value, previousValue, "evict");
|
|
264
273
|
}
|
|
265
274
|
}
|
|
266
275
|
};
|
|
267
276
|
|
|
277
|
+
//#endregion
|
|
278
|
+
//#region src/local/weak/index.ts
|
|
279
|
+
/**
|
|
280
|
+
* A cache layer that stores objects as weak references.
|
|
281
|
+
*
|
|
282
|
+
* When an object is garbage collected, its entry is automatically removed from the underlying cache.
|
|
283
|
+
*
|
|
284
|
+
* This implementation requires support for both `WeakRef` and `FinalizationRegistry`.
|
|
285
|
+
*
|
|
286
|
+
* @see https://caniuse.com/mdn-javascript_builtins_finalizationregistry
|
|
287
|
+
* @see https://caniuse.com/mdn-javascript_builtins_weakref
|
|
288
|
+
*/
|
|
289
|
+
var WeakCache = class extends BaseLocalCache {
|
|
290
|
+
cache;
|
|
291
|
+
cacheInternal;
|
|
292
|
+
registry;
|
|
293
|
+
constructor(options) {
|
|
294
|
+
super(options);
|
|
295
|
+
this.cache = options.cache;
|
|
296
|
+
this.cacheInternal = options.cache.internal;
|
|
297
|
+
this.cacheInternal._addDisposeListener(this.onCacheDispose);
|
|
298
|
+
this.registry = new FinalizationRegistry(this.onGarbageCollect);
|
|
299
|
+
}
|
|
300
|
+
onGarbageCollect = (key) => this.cacheInternal._delete(key);
|
|
301
|
+
onCacheDispose = (key, value, reason) => {
|
|
302
|
+
this.unregister(value);
|
|
303
|
+
this.onDispose(key, this.unwrap(value), reason);
|
|
304
|
+
};
|
|
305
|
+
/** @internal */
|
|
306
|
+
_get(key) {
|
|
307
|
+
return this.unwrap(this.cacheInternal._get(key));
|
|
308
|
+
}
|
|
309
|
+
/** @internal */
|
|
310
|
+
_set(key, value, options) {
|
|
311
|
+
this.cacheInternal._set(key, this.wrapAndRegister(key, value), options);
|
|
312
|
+
}
|
|
313
|
+
/** @internal */
|
|
314
|
+
_delete(key) {
|
|
315
|
+
this.unregisterByKey(key);
|
|
316
|
+
this.cacheInternal._delete(key);
|
|
317
|
+
}
|
|
318
|
+
/** @internal */
|
|
319
|
+
_getMany(keys) {
|
|
320
|
+
const data = this.cacheInternal._getMany(keys);
|
|
321
|
+
for (const key of keys) data[key] = this.unwrap(data[key]);
|
|
322
|
+
return data;
|
|
323
|
+
}
|
|
324
|
+
/** @internal */
|
|
325
|
+
_setMany(data, options) {
|
|
326
|
+
Object.keys(data).forEach((key) => this.unregisterByKey(key));
|
|
327
|
+
const wrappedData = {};
|
|
328
|
+
for (const [key, value] of Object.entries(data)) wrappedData[key] = this.wrapAndRegister(key, value);
|
|
329
|
+
this.cacheInternal._setMany(wrappedData, options);
|
|
330
|
+
}
|
|
331
|
+
/** @internal */
|
|
332
|
+
_deleteMany(keys) {
|
|
333
|
+
keys.forEach((key) => this.unregisterByKey(key));
|
|
334
|
+
this.cacheInternal._deleteMany(keys);
|
|
335
|
+
}
|
|
336
|
+
async getOrLoad(key, load, options) {
|
|
337
|
+
const wrappedLoad = async () => this.wrapAndRegister(key, await load());
|
|
338
|
+
return this.unwrap(await this.cache.getOrLoad(key, wrappedLoad, options));
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Wraps the value in a WeakRef and registers it in the FinalizationRegistry if it's an object.
|
|
342
|
+
*
|
|
343
|
+
* @param key The key to reference the value in the FinalizationRegistry
|
|
344
|
+
* @param value The value to wrap
|
|
345
|
+
* @returns The wrapped value
|
|
346
|
+
*/
|
|
347
|
+
wrapAndRegister(key, value) {
|
|
348
|
+
this.unregisterByKey(key);
|
|
349
|
+
if (value !== null && typeof value === "object") {
|
|
350
|
+
this.registry.register(value, key);
|
|
351
|
+
return {
|
|
352
|
+
v: new WeakRef(value),
|
|
353
|
+
w: true
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
return {
|
|
357
|
+
v: value,
|
|
358
|
+
w: false
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Unwraps the value from a WeakRef if it's an object.
|
|
363
|
+
*
|
|
364
|
+
* @param data The data to unwrap
|
|
365
|
+
* @returns The unwrapped value
|
|
366
|
+
*/
|
|
367
|
+
unwrap(data) {
|
|
368
|
+
if (data === null) return null;
|
|
369
|
+
if (data.w) return data.v.deref() ?? null;
|
|
370
|
+
return data.v;
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* Unregisters the value from the FinalizationRegistry if it's an object.
|
|
374
|
+
*
|
|
375
|
+
* @param value The value to unregister
|
|
376
|
+
*/
|
|
377
|
+
unregister(value) {
|
|
378
|
+
if (value && value.w) this.registry.unregister(value.v);
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* Unregisters the value associated with the given key from the FinalizationRegistry.
|
|
382
|
+
*
|
|
383
|
+
* @param key The key
|
|
384
|
+
*/
|
|
385
|
+
unregisterByKey(key) {
|
|
386
|
+
this.unregister(this.cacheInternal._get(key));
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
//#endregion
|
|
391
|
+
//#region src/local/cloning/index.ts
|
|
392
|
+
/**
|
|
393
|
+
* A cache layer that deep clones data when reading and writing.
|
|
394
|
+
*
|
|
395
|
+
* This is useful when you mutate the objects retrieved from cache,
|
|
396
|
+
* and you don't want them to also change in cache.
|
|
397
|
+
*
|
|
398
|
+
* Do not use this layer if you do not intend to mutate cached objects,
|
|
399
|
+
* as the cloning process adds unnecessary overhead.
|
|
400
|
+
*/
|
|
401
|
+
var DeepCloningCache = class extends BaseLocalCache {
|
|
402
|
+
cache;
|
|
403
|
+
cacheInternal;
|
|
404
|
+
deepClone;
|
|
405
|
+
constructor(options) {
|
|
406
|
+
super(options);
|
|
407
|
+
this.cache = options.cache;
|
|
408
|
+
this.cacheInternal = options.cache.internal;
|
|
409
|
+
if (options.deepClone) this.deepClone = options.deepClone;
|
|
410
|
+
else if (typeof structuredClone === "function") this.deepClone = structuredClone;
|
|
411
|
+
else this.deepClone = (data) => JSON.parse(JSON.stringify(data));
|
|
412
|
+
}
|
|
413
|
+
_get(key) {
|
|
414
|
+
return this.deepClone(this.cacheInternal._get(key));
|
|
415
|
+
}
|
|
416
|
+
_set(key, value, options) {
|
|
417
|
+
this.cacheInternal._set(key, this.deepClone(value), options);
|
|
418
|
+
}
|
|
419
|
+
_delete(key) {
|
|
420
|
+
this.cacheInternal._delete(key);
|
|
421
|
+
}
|
|
422
|
+
_getMany(keys) {
|
|
423
|
+
return this.deepClone(this.cacheInternal._getMany(keys));
|
|
424
|
+
}
|
|
425
|
+
_setMany(data, options) {
|
|
426
|
+
this.cacheInternal._setMany(this.deepClone(data), options);
|
|
427
|
+
}
|
|
428
|
+
_deleteMany(keys) {
|
|
429
|
+
this.cacheInternal._deleteMany(keys);
|
|
430
|
+
}
|
|
431
|
+
_addDisposeListener(listener) {
|
|
432
|
+
this.cacheInternal._addDisposeListener(listener);
|
|
433
|
+
}
|
|
434
|
+
async getOrLoad(key, load, options) {
|
|
435
|
+
const loadWrapped = async () => this.deepClone(await load());
|
|
436
|
+
return this.deepClone(await this.cache.getOrLoad(key, loadWrapped, options));
|
|
437
|
+
}
|
|
438
|
+
};
|
|
439
|
+
|
|
268
440
|
//#endregion
|
|
269
441
|
//#region src/local/noop/index.ts
|
|
270
442
|
/**
|
|
@@ -568,7 +740,10 @@ var WorkersKVCache = class extends BaseCache {
|
|
|
568
740
|
return this.kv.delete(key);
|
|
569
741
|
}
|
|
570
742
|
async getMany(keys) {
|
|
571
|
-
const data = await this.kv.get(keys, {
|
|
743
|
+
const data = await this.kv.get(keys, {
|
|
744
|
+
type: "json",
|
|
745
|
+
cacheTtl: this.edgeCacheTTL
|
|
746
|
+
});
|
|
572
747
|
return Object.fromEntries(data);
|
|
573
748
|
}
|
|
574
749
|
};
|
|
@@ -862,7 +1037,7 @@ var KeyTransformingCache = class {
|
|
|
862
1037
|
transform;
|
|
863
1038
|
constructor(options) {
|
|
864
1039
|
this.cache = options.cache;
|
|
865
|
-
if ("transform" in options) this.transform = options.transform;
|
|
1040
|
+
if ("transform" in options && typeof options.transform === "function") this.transform = options.transform;
|
|
866
1041
|
else {
|
|
867
1042
|
const prefix = options.prefix || "";
|
|
868
1043
|
const suffix = options.suffix || "";
|
|
@@ -1217,7 +1392,9 @@ var MetricsCollectingCache = class {
|
|
|
1217
1392
|
//#endregion
|
|
1218
1393
|
exports.AsyncLazyCache = AsyncLazyCache;
|
|
1219
1394
|
exports.BaseCache = BaseCache;
|
|
1395
|
+
exports.BaseLocalCache = BaseLocalCache;
|
|
1220
1396
|
exports.CoalescingCache = CoalescingCache;
|
|
1397
|
+
exports.DeepCloningCache = DeepCloningCache;
|
|
1221
1398
|
exports.IORedisCache = IORedisCache;
|
|
1222
1399
|
exports.JitteringCache = JitteringCache;
|
|
1223
1400
|
exports.KeyTransformingCache = KeyTransformingCache;
|
|
@@ -1233,4 +1410,5 @@ exports.RedisCache = RedisCache;
|
|
|
1233
1410
|
exports.SWRCache = SWRCache;
|
|
1234
1411
|
exports.TieredCache = TieredCache;
|
|
1235
1412
|
exports.ValkeyGlideCache = ValkeyGlideCache;
|
|
1413
|
+
exports.WeakCache = WeakCache;
|
|
1236
1414
|
exports.WorkersKVCache = WorkersKVCache;
|
package/dist/index.d.cts
CHANGED
|
@@ -121,50 +121,67 @@ declare abstract class BaseCache implements ICache {
|
|
|
121
121
|
//#endregion
|
|
122
122
|
//#region src/base/local.d.ts
|
|
123
123
|
type LocalCacheDisposeListener<T = any> = (key: string, value: T, reason?: string) => void;
|
|
124
|
+
/**
|
|
125
|
+
* Internal methods for synchronous cache operations.
|
|
126
|
+
* @experimental
|
|
127
|
+
*/
|
|
128
|
+
interface LocalCacheInternal {
|
|
129
|
+
_get<T>(key: string): T | null;
|
|
130
|
+
_set<T>(key: string, value: T, options?: SetCacheOptions): void;
|
|
131
|
+
_delete(key: string): void;
|
|
132
|
+
_getMany<T>(keys: string[]): Record<string, T | null>;
|
|
133
|
+
_setMany<T>(data: Record<string, T>, options?: SetCacheOptions): void;
|
|
134
|
+
_deleteMany(keys: string[]): void;
|
|
135
|
+
_addDisposeListener(listener: LocalCacheDisposeListener): void;
|
|
136
|
+
}
|
|
124
137
|
declare abstract class BaseLocalCache extends BaseCache {
|
|
125
138
|
protected disposeListeners: LocalCacheDisposeListener[];
|
|
126
139
|
/**
|
|
127
140
|
* Reads the cached resource from a key (synchronous version)
|
|
128
|
-
* @protected
|
|
129
141
|
*/
|
|
130
|
-
abstract _get<T>(key: string): T | null;
|
|
142
|
+
protected abstract _get<T>(key: string): T | null;
|
|
131
143
|
/**
|
|
132
144
|
* Writes a resource into cache (synchronous version)
|
|
133
|
-
* @protected
|
|
134
145
|
*/
|
|
135
|
-
abstract _set<T>(key: string, value: T, options?: SetCacheOptions): void;
|
|
146
|
+
protected abstract _set<T>(key: string, value: T, options?: SetCacheOptions): void;
|
|
136
147
|
/**
|
|
137
148
|
* Deletes a cached resource by a key. (synchronous version)
|
|
138
|
-
* @protected
|
|
139
149
|
*/
|
|
140
|
-
abstract _delete(key: string): void;
|
|
150
|
+
protected abstract _delete(key: string): void;
|
|
141
151
|
/**
|
|
142
152
|
* Reads cached resources by their keys. (synchronous version)
|
|
143
|
-
* @protected
|
|
144
153
|
*/
|
|
145
|
-
_getMany<T>(keys: string[]): Record<string, T | null>;
|
|
154
|
+
protected _getMany<T>(keys: string[]): Record<string, T | null>;
|
|
146
155
|
/**
|
|
147
156
|
* Writes resources into cache. (synchronous version)
|
|
148
|
-
* @protected
|
|
149
157
|
*/
|
|
150
|
-
_setMany<T>(data: Record<string, T>, options?: SetCacheOptions): void;
|
|
158
|
+
protected _setMany<T>(data: Record<string, T>, options?: SetCacheOptions): void;
|
|
151
159
|
/**
|
|
152
160
|
* Deletes many cached resources by their keys. (synchronous version)
|
|
153
|
-
* @protected
|
|
154
161
|
*/
|
|
155
|
-
_deleteMany(keys: string[]): void;
|
|
162
|
+
protected _deleteMany(keys: string[]): void;
|
|
156
163
|
/**
|
|
157
164
|
* Adds a listener that will be called when a cached item is disposed.
|
|
158
165
|
*
|
|
159
166
|
* @param listener The listener function to add.
|
|
160
|
-
* @protected
|
|
161
167
|
*/
|
|
162
|
-
_addDisposeListener(listener: LocalCacheDisposeListener): void;
|
|
168
|
+
protected _addDisposeListener(listener: LocalCacheDisposeListener): void;
|
|
169
|
+
/**
|
|
170
|
+
* Gets access to the internal synchronous methods.
|
|
171
|
+
* @experimental
|
|
172
|
+
*/
|
|
173
|
+
get internal(): LocalCacheInternal;
|
|
174
|
+
/** @sealed **/
|
|
163
175
|
get<T>(key: string): Promise<T | null>;
|
|
176
|
+
/** @sealed **/
|
|
164
177
|
set<T>(key: string, value: T, options?: SetCacheOptions): Promise<void>;
|
|
178
|
+
/** @sealed **/
|
|
165
179
|
delete(key: string): Promise<void>;
|
|
180
|
+
/** @sealed **/
|
|
166
181
|
getMany<T>(keys: string[]): Promise<Record<string, T | null>>;
|
|
182
|
+
/** @sealed **/
|
|
167
183
|
setMany<T>(data: Record<string, T>, options?: SetCacheOptions): Promise<void>;
|
|
184
|
+
/** @sealed **/
|
|
168
185
|
deleteMany(keys: string[]): Promise<void>;
|
|
169
186
|
protected onDispose(key: string, value: any, reason?: string): void;
|
|
170
187
|
}
|
|
@@ -243,7 +260,7 @@ interface LocalMapCacheOptions extends BaseCacheOptions {
|
|
|
243
260
|
/**
|
|
244
261
|
* The underlying map.
|
|
245
262
|
*/
|
|
246
|
-
|
|
263
|
+
map?: MapLike<string, any>;
|
|
247
264
|
/**
|
|
248
265
|
* The maximum size of the cache.
|
|
249
266
|
* When not set, the cache can grow indefinitely.
|
|
@@ -268,7 +285,7 @@ interface MapLike<K, V> {
|
|
|
268
285
|
* Once the limit of items is reached, the first inserted keys will be purged.
|
|
269
286
|
*/
|
|
270
287
|
declare class LocalMapCache extends BaseLocalCache {
|
|
271
|
-
protected readonly
|
|
288
|
+
protected readonly map: MapLike<string, any>;
|
|
272
289
|
protected max: number;
|
|
273
290
|
constructor(options?: LocalMapCacheOptions);
|
|
274
291
|
setMany(data: Record<string, any>, options?: SetCacheOptions): Promise<void>;
|
|
@@ -277,6 +294,108 @@ declare class LocalMapCache extends BaseLocalCache {
|
|
|
277
294
|
protected evict(length: number): void;
|
|
278
295
|
}
|
|
279
296
|
//#endregion
|
|
297
|
+
//#region src/local/weak/index.d.ts
|
|
298
|
+
interface WeakCacheOptions extends BaseCacheOptions {
|
|
299
|
+
/**
|
|
300
|
+
* The underlying cache. This must be an in-memory cache.
|
|
301
|
+
*/
|
|
302
|
+
cache: BaseLocalCache;
|
|
303
|
+
}
|
|
304
|
+
type WeakValue = {
|
|
305
|
+
v: WeakRef<any>;
|
|
306
|
+
w: true;
|
|
307
|
+
} | {
|
|
308
|
+
v: any;
|
|
309
|
+
w: false;
|
|
310
|
+
};
|
|
311
|
+
/**
|
|
312
|
+
* A cache layer that stores objects as weak references.
|
|
313
|
+
*
|
|
314
|
+
* When an object is garbage collected, its entry is automatically removed from the underlying cache.
|
|
315
|
+
*
|
|
316
|
+
* This implementation requires support for both `WeakRef` and `FinalizationRegistry`.
|
|
317
|
+
*
|
|
318
|
+
* @see https://caniuse.com/mdn-javascript_builtins_finalizationregistry
|
|
319
|
+
* @see https://caniuse.com/mdn-javascript_builtins_weakref
|
|
320
|
+
*/
|
|
321
|
+
declare class WeakCache extends BaseLocalCache {
|
|
322
|
+
protected readonly cache: BaseLocalCache;
|
|
323
|
+
protected readonly cacheInternal: LocalCacheInternal;
|
|
324
|
+
protected readonly registry: FinalizationRegistry<string>;
|
|
325
|
+
constructor(options: WeakCacheOptions);
|
|
326
|
+
protected onGarbageCollect: (key: string) => void;
|
|
327
|
+
protected onCacheDispose: (key: string, value: any, reason?: string) => void;
|
|
328
|
+
getOrLoad<T>(key: string, load: () => Promise<T>, options?: SetCacheOptions): Promise<T>;
|
|
329
|
+
/**
|
|
330
|
+
* Wraps the value in a WeakRef and registers it in the FinalizationRegistry if it's an object.
|
|
331
|
+
*
|
|
332
|
+
* @param key The key to reference the value in the FinalizationRegistry
|
|
333
|
+
* @param value The value to wrap
|
|
334
|
+
* @returns The wrapped value
|
|
335
|
+
*/
|
|
336
|
+
protected wrapAndRegister(key: string, value: any): WeakValue;
|
|
337
|
+
/**
|
|
338
|
+
* Unwraps the value from a WeakRef if it's an object.
|
|
339
|
+
*
|
|
340
|
+
* @param data The data to unwrap
|
|
341
|
+
* @returns The unwrapped value
|
|
342
|
+
*/
|
|
343
|
+
protected unwrap<T>(data: WeakValue | null): T | null;
|
|
344
|
+
/**
|
|
345
|
+
* Unregisters the value from the FinalizationRegistry if it's an object.
|
|
346
|
+
*
|
|
347
|
+
* @param value The value to unregister
|
|
348
|
+
*/
|
|
349
|
+
protected unregister(value: WeakValue | null): void;
|
|
350
|
+
/**
|
|
351
|
+
* Unregisters the value associated with the given key from the FinalizationRegistry.
|
|
352
|
+
*
|
|
353
|
+
* @param key The key
|
|
354
|
+
*/
|
|
355
|
+
protected unregisterByKey(key: string): void;
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/local/cloning/index.d.ts
|
|
359
|
+
interface DeepCloningCacheOptions extends BaseCacheOptions {
|
|
360
|
+
/**
|
|
361
|
+
* The underlying cache. This must be an in-memory cache.
|
|
362
|
+
*/
|
|
363
|
+
cache: BaseLocalCache;
|
|
364
|
+
/**
|
|
365
|
+
* The deep clone function to use.
|
|
366
|
+
*
|
|
367
|
+
* By default, it will try to use `structuredClone()` if available,
|
|
368
|
+
* otherwise it will use a JSON.parse/stringify-based implementation.
|
|
369
|
+
*
|
|
370
|
+
* @param data The data to deep clone
|
|
371
|
+
* @returns The cloned data
|
|
372
|
+
*/
|
|
373
|
+
deepClone?: <T>(data: T) => T;
|
|
374
|
+
}
|
|
375
|
+
/**
|
|
376
|
+
* A cache layer that deep clones data when reading and writing.
|
|
377
|
+
*
|
|
378
|
+
* This is useful when you mutate the objects retrieved from cache,
|
|
379
|
+
* and you don't want them to also change in cache.
|
|
380
|
+
*
|
|
381
|
+
* Do not use this layer if you do not intend to mutate cached objects,
|
|
382
|
+
* as the cloning process adds unnecessary overhead.
|
|
383
|
+
*/
|
|
384
|
+
declare class DeepCloningCache extends BaseLocalCache {
|
|
385
|
+
protected readonly cache: BaseLocalCache;
|
|
386
|
+
protected readonly cacheInternal: LocalCacheInternal;
|
|
387
|
+
protected deepClone: <T>(data: T) => T;
|
|
388
|
+
constructor(options: DeepCloningCacheOptions);
|
|
389
|
+
protected _get<T>(key: string): T | null;
|
|
390
|
+
protected _set<T>(key: string, value: T, options?: SetCacheOptions): void;
|
|
391
|
+
protected _delete(key: string): void;
|
|
392
|
+
protected _getMany<T>(keys: string[]): Record<string, T | null>;
|
|
393
|
+
protected _setMany<T>(data: Record<string, T>, options?: SetCacheOptions): void;
|
|
394
|
+
protected _deleteMany(keys: string[]): void;
|
|
395
|
+
protected _addDisposeListener(listener: any): void;
|
|
396
|
+
getOrLoad<T>(key: string, load: () => Promise<T>, options?: SetCacheOptions): Promise<T>;
|
|
397
|
+
}
|
|
398
|
+
//#endregion
|
|
280
399
|
//#region src/local/noop/index.d.ts
|
|
281
400
|
/**
|
|
282
401
|
* A cache implementation that does nothing.
|
|
@@ -830,5 +949,5 @@ declare class MetricsCollectingCache implements ICache {
|
|
|
830
949
|
resetMetrics(): void;
|
|
831
950
|
}
|
|
832
951
|
//#endregion
|
|
833
|
-
export { AsyncLazyCache, AsyncLazyCacheOptions, BaseCache, BaseCacheOptions, CacheMetrics, CacheTier, CoalescingCache, CoalescingCacheOptions, ExistingLRUCacheOptions, ExistingTTLCacheOptions, ICache, IORedisCache, IORedisCacheOptions, JitteringCache, JitteringCacheOptions, KeyTransformingCache, KeyTransformingCacheOptions, KeyvCache, KeyvCacheOptions, LocalLRUCache, LocalLRUCacheOptions, LocalMapCache, LocalMapCacheOptions, LocalTTLCache, LocalTTLCacheOptions, Logger, MapLike, MemJSCache, MemJSCacheOptions, MemcacheCache, MemcacheCacheOptions, MetricsCollectingCache, MetricsCollectingCacheOptions, NoOpCache, RedisCache, RedisCacheOptions, SWRCache, SWRCacheOptions, SetCacheOptions, TieredCache, TieredCacheOptions, ValkeyGlideCache, ValkeyGlideCacheOptions, WorkersKVCache, WorkersKVCacheOptions };
|
|
952
|
+
export { AsyncLazyCache, AsyncLazyCacheOptions, BaseCache, BaseCacheOptions, BaseLocalCache, CacheMetrics, CacheTier, CoalescingCache, CoalescingCacheOptions, DeepCloningCache, DeepCloningCacheOptions, ExistingLRUCacheOptions, ExistingTTLCacheOptions, ICache, IORedisCache, IORedisCacheOptions, JitteringCache, JitteringCacheOptions, KeyTransformingCache, KeyTransformingCacheOptions, KeyvCache, KeyvCacheOptions, LocalCacheInternal, LocalLRUCache, LocalLRUCacheOptions, LocalMapCache, LocalMapCacheOptions, LocalTTLCache, LocalTTLCacheOptions, Logger, MapLike, MemJSCache, MemJSCacheOptions, MemcacheCache, MemcacheCacheOptions, MetricsCollectingCache, MetricsCollectingCacheOptions, NoOpCache, RedisCache, RedisCacheOptions, SWRCache, SWRCacheOptions, SetCacheOptions, TieredCache, TieredCacheOptions, ValkeyGlideCache, ValkeyGlideCacheOptions, WeakCache, WeakCacheOptions, WorkersKVCache, WorkersKVCacheOptions };
|
|
834
953
|
//# sourceMappingURL=index.d.cts.map
|