@cacheable/memory 2.0.7 → 2.0.9

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 CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  > High Performance Layer 1 / Layer 2 Caching with Keyv Storage
4
4
 
5
- [![codecov](https://codecov.io/gh/jaredwray/cacheable/graph/badge.svg?token=lWZ9OBQ7GM)](https://codecov.io/gh/jaredwray/cacheable)
5
+ [![codecov](https://codecov.io/gh/jaredwray/cacheable/branch/main/graph/badge.svg?token=lWZ9OBQ7GM)](https://codecov.io/gh/jaredwray/cacheable)
6
6
  [![tests](https://github.com/jaredwray/cacheable/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/cacheable/actions/workflows/tests.yml)
7
7
  [![npm](https://img.shields.io/npm/dm/@cacheable/memory.svg)](https://www.npmjs.com/package/@cacheable/memory)
8
8
  [![npm](https://img.shields.io/npm/v/@cacheable/memory.svg)](https://www.npmjs.com/package/@cacheable/memory)
9
9
  [![license](https://img.shields.io/github/license/jaredwray/cacheable)](https://github.com/jaredwray/cacheable/blob/main/LICENSE)
10
10
 
11
- You can use `CacheableMemory` as a standalone cache or as a primary store for `cacheable`. You can also set the `useClones` property to `false` if you want to use the same reference for the values. This is useful if you are using large objects and want to save memory. The `lruSize` property is the size of the LRU cache and is set to `0` by default which is unlimited. When setting the `lruSize` property it will limit the number of keys in the cache.
11
+ You can use `CacheableMemory` as a standalone cache or as a primary store for `cacheable`. You can also set the `useClones` property to `false` if you want to use the same reference for the values. This is useful if you are using large objects and want to save memory. The `lruSize` property is the size of the LRU cache and is set to `0` by default, which disables the LRU cache (no LRU eviction is performed and the cache size is bounded only by the underlying `Map` stores). When the `lruSize` property is set to a value greater than `0`, it limits the number of keys in the cache and evicts the least recently used entries when full.
12
12
 
13
13
  This simple in-memory cache uses multiple Map objects and a with `expiration` and `lru` policies if set to manage the in memory cache at scale.
14
14
 
@@ -188,11 +188,11 @@ const value = cache.get('key'); // value
188
188
 
189
189
  You can enable the LRU (Least Recently Used) feature in `CacheableMemory` by setting the `lruSize` property in the options. This will limit the number of keys in the cache to the size you set. When the cache reaches the limit it will remove the least recently used keys from the cache. This is useful if you want to limit the memory usage of the cache.
190
190
 
191
- When you set the `lruSize` we use a double linked list to manage the LRU cache and also set the `hashStoreSize` to `1` which means we will only use a single `Map` object for the LRU cache. This is because the LRU cache is managed by the double linked list and it is not possible to have more than `16,777,216 (2^24) keys` in a single `Map` object.
191
+ When you set the `lruSize`, we use a doubly linked list to track the LRU order across the underlying `Map` stores. The `lruSize` itself is capped at `16,777,216 (2^24) keys` values above this limit are rejected and an `error` event is emitted. Setting `lruSize` does not change `storeHashSize`; the underlying stores keep whatever `storeHashSize` you configured (default `16`).
192
192
 
193
193
  ```javascript
194
194
  import { CacheableMemory } from 'cacheable';
195
- const cache = new CacheableMemory({ lruSize: 1 }); // sets the LRU cache size to 1000 keys and hashStoreSize to 1
195
+ const cache = new CacheableMemory({ lruSize: 1 }); // sets the LRU cache size to 1 key
196
196
  cache.set('key1', 'value1');
197
197
  cache.set('key2', 'value2');
198
198
  const value1 = cache.get('key1');
@@ -230,7 +230,7 @@ As you can see from the benchmarks `CacheableMemory` is on par with other cachin
230
230
 
231
231
  * `ttl`: The time to live for the cache in milliseconds. Default is `undefined` which is means indefinitely.
232
232
  * `useClones`: If the cache should use clones for the values. Default is `true`.
233
- * `lruSize`: The size of the LRU cache. Default is `0` which is unlimited.
233
+ * `lruSize`: The size of the LRU cache. Default is `0`, which disables the LRU cache (no LRU eviction is performed). Maximum is `16,777,216 (2^24)`.
234
234
  * `checkInterval`: The interval to check for expired keys in milliseconds. Default is `0` which is disabled.
235
235
  * `storeHashSize`: The number of `Map` objects to use for the cache. Default is `16`.
236
236
  * `storeHashAlgorithm`: The hashing algorithm to use for the cache. Default is `djb2`. Supported: DJB2, FNV1, MURMER, CRC32.
@@ -253,7 +253,7 @@ As you can see from the benchmarks `CacheableMemory` is on par with other cachin
253
253
  * `clear()`: Clears the cache.
254
254
  * `ttl`: The default time to live for the cache in milliseconds. Default is `undefined` which is disabled.
255
255
  * `useClones`: If the cache should use clones for the values. Default is `true`.
256
- * `lruSize`: The size of the LRU cache. Default is `0` which is unlimited.
256
+ * `lruSize`: The size of the LRU cache. Default is `0`, which disables the LRU cache (no LRU eviction is performed). Maximum is `16,777,216 (2^24)`.
257
257
  * `size`: The number of keys in the cache.
258
258
  * `checkInterval`: The interval to check for expired keys in milliseconds. Default is `0` which is disabled.
259
259
  * `storeHashSize`: The number of `Map` objects to use for the cache. Default is `16`.
package/dist/index.cjs CHANGED
@@ -100,6 +100,31 @@ var DoublyLinkedList = class {
100
100
  this.nodesMap.delete(oldValue);
101
101
  return oldValue;
102
102
  }
103
+ // Remove a specific node by value
104
+ remove(value) {
105
+ const node = this.nodesMap.get(value);
106
+ if (!node) {
107
+ return false;
108
+ }
109
+ if (node.prev) {
110
+ node.prev.next = node.next;
111
+ } else {
112
+ this.head = node.next;
113
+ if (this.head) {
114
+ this.head.prev = void 0;
115
+ }
116
+ }
117
+ if (node.next) {
118
+ node.next.prev = node.prev;
119
+ } else {
120
+ this.tail = node.prev;
121
+ if (this.tail) {
122
+ this.tail.next = void 0;
123
+ }
124
+ }
125
+ this.nodesMap.delete(value);
126
+ return true;
127
+ }
103
128
  get size() {
104
129
  return this.nodesMap.size;
105
130
  }
@@ -387,6 +412,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
387
412
  const item = store.get(key);
388
413
  if (item && this.hasExpired(item)) {
389
414
  store.delete(key);
415
+ this.lruRemove(key);
390
416
  continue;
391
417
  }
392
418
  keys.push(key);
@@ -404,6 +430,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
404
430
  for (const item of store.values()) {
405
431
  if (this.hasExpired(item)) {
406
432
  store.delete(item.key);
433
+ this.lruRemove(item.key);
407
434
  continue;
408
435
  }
409
436
  items.push(item);
@@ -431,6 +458,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
431
458
  }
432
459
  if (item.expires && Date.now() > item.expires) {
433
460
  store.delete(key);
461
+ this.lruRemove(key);
434
462
  return void 0;
435
463
  }
436
464
  this.lruMoveToFront(key);
@@ -464,6 +492,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
464
492
  }
465
493
  if (item.expires && item.expires && Date.now() > item.expires) {
466
494
  store.delete(key);
495
+ this.lruRemove(key);
467
496
  return void 0;
468
497
  }
469
498
  this.lruMoveToFront(key);
@@ -593,6 +622,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
593
622
  delete(key) {
594
623
  const store = this.getStore(key);
595
624
  store.delete(key);
625
+ this.lruRemove(key);
596
626
  }
597
627
  /**
598
628
  * Delete the keys
@@ -680,6 +710,17 @@ var CacheableMemory = class extends import_hookified.Hookified {
680
710
  }
681
711
  this._lru.moveToFront(key);
682
712
  }
713
+ /**
714
+ * Remove a key from the LRU cache. This is for internal use
715
+ * @param {string} key - The key to remove
716
+ * @returns {void}
717
+ */
718
+ lruRemove(key) {
719
+ if (this._lruSize === 0) {
720
+ return;
721
+ }
722
+ this._lru.remove(key);
723
+ }
683
724
  /**
684
725
  * Resize the LRU cache. This is for internal use.
685
726
  * @returns {void}
@@ -702,6 +743,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
702
743
  for (const item of store.values()) {
703
744
  if (item.expires && Date.now() > item.expires) {
704
745
  store.delete(item.key);
746
+ this.lruRemove(item.key);
705
747
  }
706
748
  }
707
749
  }
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { HashAlgorithm, CacheableStoreItem, CacheableItem, WrapFunctionOptions } from '@cacheable/utils';
2
2
  export { CacheableItem, CacheableStoreItem, HashAlgorithm, hash, hashToNumber } from '@cacheable/utils';
3
3
  import { Hookified } from 'hookified';
4
- import { Keyv, KeyvStoreAdapter, StoredData } from 'keyv';
4
+ import { KeyvStoreAdapter, StoredData, Keyv } from 'keyv';
5
5
 
6
6
  type KeyvCacheableMemoryOptions = CacheableMemoryOptions & {
7
7
  namespace?: string;
@@ -269,6 +269,12 @@ declare class CacheableMemory extends Hookified {
269
269
  * @returns {void}
270
270
  */
271
271
  lruMoveToFront(key: string): void;
272
+ /**
273
+ * Remove a key from the LRU cache. This is for internal use
274
+ * @param {string} key - The key to remove
275
+ * @returns {void}
276
+ */
277
+ lruRemove(key: string): void;
272
278
  /**
273
279
  * Resize the LRU cache. This is for internal use.
274
280
  * @returns {void}
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { HashAlgorithm, CacheableStoreItem, CacheableItem, WrapFunctionOptions } from '@cacheable/utils';
2
2
  export { CacheableItem, CacheableStoreItem, HashAlgorithm, hash, hashToNumber } from '@cacheable/utils';
3
3
  import { Hookified } from 'hookified';
4
- import { Keyv, KeyvStoreAdapter, StoredData } from 'keyv';
4
+ import { KeyvStoreAdapter, StoredData, Keyv } from 'keyv';
5
5
 
6
6
  type KeyvCacheableMemoryOptions = CacheableMemoryOptions & {
7
7
  namespace?: string;
@@ -269,6 +269,12 @@ declare class CacheableMemory extends Hookified {
269
269
  * @returns {void}
270
270
  */
271
271
  lruMoveToFront(key: string): void;
272
+ /**
273
+ * Remove a key from the LRU cache. This is for internal use
274
+ * @param {string} key - The key to remove
275
+ * @returns {void}
276
+ */
277
+ lruRemove(key: string): void;
272
278
  /**
273
279
  * Resize the LRU cache. This is for internal use.
274
280
  * @returns {void}
package/dist/index.js CHANGED
@@ -74,6 +74,31 @@ var DoublyLinkedList = class {
74
74
  this.nodesMap.delete(oldValue);
75
75
  return oldValue;
76
76
  }
77
+ // Remove a specific node by value
78
+ remove(value) {
79
+ const node = this.nodesMap.get(value);
80
+ if (!node) {
81
+ return false;
82
+ }
83
+ if (node.prev) {
84
+ node.prev.next = node.next;
85
+ } else {
86
+ this.head = node.next;
87
+ if (this.head) {
88
+ this.head.prev = void 0;
89
+ }
90
+ }
91
+ if (node.next) {
92
+ node.next.prev = node.prev;
93
+ } else {
94
+ this.tail = node.prev;
95
+ if (this.tail) {
96
+ this.tail.next = void 0;
97
+ }
98
+ }
99
+ this.nodesMap.delete(value);
100
+ return true;
101
+ }
77
102
  get size() {
78
103
  return this.nodesMap.size;
79
104
  }
@@ -365,6 +390,7 @@ var CacheableMemory = class extends Hookified {
365
390
  const item = store.get(key);
366
391
  if (item && this.hasExpired(item)) {
367
392
  store.delete(key);
393
+ this.lruRemove(key);
368
394
  continue;
369
395
  }
370
396
  keys.push(key);
@@ -382,6 +408,7 @@ var CacheableMemory = class extends Hookified {
382
408
  for (const item of store.values()) {
383
409
  if (this.hasExpired(item)) {
384
410
  store.delete(item.key);
411
+ this.lruRemove(item.key);
385
412
  continue;
386
413
  }
387
414
  items.push(item);
@@ -409,6 +436,7 @@ var CacheableMemory = class extends Hookified {
409
436
  }
410
437
  if (item.expires && Date.now() > item.expires) {
411
438
  store.delete(key);
439
+ this.lruRemove(key);
412
440
  return void 0;
413
441
  }
414
442
  this.lruMoveToFront(key);
@@ -442,6 +470,7 @@ var CacheableMemory = class extends Hookified {
442
470
  }
443
471
  if (item.expires && item.expires && Date.now() > item.expires) {
444
472
  store.delete(key);
473
+ this.lruRemove(key);
445
474
  return void 0;
446
475
  }
447
476
  this.lruMoveToFront(key);
@@ -571,6 +600,7 @@ var CacheableMemory = class extends Hookified {
571
600
  delete(key) {
572
601
  const store = this.getStore(key);
573
602
  store.delete(key);
603
+ this.lruRemove(key);
574
604
  }
575
605
  /**
576
606
  * Delete the keys
@@ -658,6 +688,17 @@ var CacheableMemory = class extends Hookified {
658
688
  }
659
689
  this._lru.moveToFront(key);
660
690
  }
691
+ /**
692
+ * Remove a key from the LRU cache. This is for internal use
693
+ * @param {string} key - The key to remove
694
+ * @returns {void}
695
+ */
696
+ lruRemove(key) {
697
+ if (this._lruSize === 0) {
698
+ return;
699
+ }
700
+ this._lru.remove(key);
701
+ }
661
702
  /**
662
703
  * Resize the LRU cache. This is for internal use.
663
704
  * @returns {void}
@@ -680,6 +721,7 @@ var CacheableMemory = class extends Hookified {
680
721
  for (const item of store.values()) {
681
722
  if (item.expires && Date.now() > item.expires) {
682
723
  store.delete(item.key);
724
+ this.lruRemove(item.key);
683
725
  }
684
726
  }
685
727
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cacheable/memory",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "description": "High Performance In-Memory Cache for Node.js",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -27,20 +27,14 @@
27
27
  "license": "MIT",
28
28
  "private": false,
29
29
  "devDependencies": {
30
- "@biomejs/biome": "^2.3.10",
31
- "@faker-js/faker": "^10.1.0",
32
- "@types/node": "^25.0.3",
33
- "@vitest/coverage-v8": "^4.0.16",
34
- "rimraf": "^6.1.2",
35
30
  "tsup": "^8.5.1",
36
- "typescript": "^5.9.3",
37
- "vitest": "^4.0.16"
31
+ "typescript": "^5.9.3"
38
32
  },
39
33
  "dependencies": {
40
- "@keyv/bigmap": "^1.3.0",
41
- "hookified": "^1.14.0",
42
- "keyv": "^5.5.5",
43
- "@cacheable/utils": "^2.3.3"
34
+ "@keyv/bigmap": "^1.3.1",
35
+ "hookified": "^1.15.1",
36
+ "keyv": "^5.6.0",
37
+ "@cacheable/utils": "^2.4.1"
44
38
  },
45
39
  "keywords": [
46
40
  "cacheable",
@@ -63,7 +57,6 @@
63
57
  ],
64
58
  "scripts": {
65
59
  "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean",
66
- "prepublish": "pnpm build",
67
60
  "lint": "biome check --write --error-on-warnings",
68
61
  "test": "pnpm lint && vitest run --coverage",
69
62
  "test:ci": "biome check --error-on-warnings && vitest run --coverage",