@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 +6 -6
- package/dist/index.cjs +42 -0
- package/dist/index.d.cts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +42 -0
- package/package.json +6 -13
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
|
-
[](https://codecov.io/gh/jaredwray/cacheable)
|
|
5
|
+
[](https://codecov.io/gh/jaredwray/cacheable)
|
|
6
6
|
[](https://github.com/jaredwray/cacheable/actions/workflows/tests.yml)
|
|
7
7
|
[](https://www.npmjs.com/package/@cacheable/memory)
|
|
8
8
|
[](https://www.npmjs.com/package/@cacheable/memory)
|
|
9
9
|
[](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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 {
|
|
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 {
|
|
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.
|
|
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.
|
|
41
|
-
"hookified": "^1.
|
|
42
|
-
"keyv": "^5.
|
|
43
|
-
"@cacheable/utils": "^2.
|
|
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",
|