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/dist/index.js 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
- cache;
217
+ map;
209
218
  max;
210
219
  constructor(options = {}) {
211
220
  super(options);
212
- this.cache = options.cache ?? /* @__PURE__ */ new Map();
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.cache.get(key);
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.cache.get(key);
225
- if (this.cache.size >= this.max && previousValue === void 0) this.evict(1);
226
- this.cache.set(key, value);
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.cache.get(key);
233
- this.cache.delete(key);
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.cache.has(key)).length;
240
- if (this.cache.size + newEntries > this.max) this.evict(this.cache.size + newEntries - this.max);
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.cache.get(key);
243
- this.cache.set(key, value);
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.cache.keys()) this.onDispose(key, this.cache.get(key), "delete");
250
- this.cache.clear();
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.cache.keys();
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.cache.get(key.value);
262
- this.cache.delete(key.value);
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, { type: "json" });
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 || "";
@@ -1215,5 +1390,5 @@ var MetricsCollectingCache = class {
1215
1390
  };
1216
1391
 
1217
1392
  //#endregion
1218
- export { AsyncLazyCache, BaseCache, CoalescingCache, IORedisCache, JitteringCache, KeyTransformingCache, KeyvCache, LocalLRUCache, LocalMapCache, LocalTTLCache, MemJSCache, MemcacheCache, MetricsCollectingCache, NoOpCache, RedisCache, SWRCache, TieredCache, ValkeyGlideCache, WorkersKVCache };
1393
+ export { AsyncLazyCache, BaseCache, BaseLocalCache, CoalescingCache, DeepCloningCache, IORedisCache, JitteringCache, KeyTransformingCache, KeyvCache, LocalLRUCache, LocalMapCache, LocalTTLCache, MemJSCache, MemcacheCache, MetricsCollectingCache, NoOpCache, RedisCache, SWRCache, TieredCache, ValkeyGlideCache, WeakCache, WorkersKVCache };
1219
1394
  //# sourceMappingURL=index.js.map