cacheable 1.10.2 → 1.10.4
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 +1 -1
- package/dist/index.cjs +184 -141
- package/dist/index.d.cts +50 -50
- package/dist/index.d.ts +50 -50
- package/dist/index.js +185 -147
- package/package.json +12 -13
package/README.md
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
|
|
52
52
|
# Getting Started
|
|
53
53
|
|
|
54
|
-
`cacheable` is primarily used as an extension to
|
|
54
|
+
`cacheable` is primarily used as an extension to your caching engine with a robust storage backend [Keyv](https://keyv.org), Memoization (Wrap), Hooks, Events, and Statistics.
|
|
55
55
|
|
|
56
56
|
```bash
|
|
57
57
|
npm install cacheable
|
package/dist/index.cjs
CHANGED
|
@@ -46,8 +46,118 @@ __export(index_exports, {
|
|
|
46
46
|
wrapSync: () => wrapSync
|
|
47
47
|
});
|
|
48
48
|
module.exports = __toCommonJS(index_exports);
|
|
49
|
-
var import_keyv2 = require("keyv");
|
|
50
49
|
var import_hookified2 = require("hookified");
|
|
50
|
+
var import_keyv2 = require("keyv");
|
|
51
|
+
|
|
52
|
+
// src/hash.ts
|
|
53
|
+
var crypto = __toESM(require("crypto"), 1);
|
|
54
|
+
function hash(object, algorithm = "sha256") {
|
|
55
|
+
const objectString = JSON.stringify(object);
|
|
56
|
+
if (!crypto.getHashes().includes(algorithm)) {
|
|
57
|
+
throw new Error(`Unsupported hash algorithm: '${algorithm}'`);
|
|
58
|
+
}
|
|
59
|
+
const hasher = crypto.createHash(algorithm);
|
|
60
|
+
hasher.update(objectString);
|
|
61
|
+
return hasher.digest("hex");
|
|
62
|
+
}
|
|
63
|
+
function hashToNumber(object, min = 0, max = 10, algorithm = "sha256") {
|
|
64
|
+
const objectString = JSON.stringify(object);
|
|
65
|
+
if (!crypto.getHashes().includes(algorithm)) {
|
|
66
|
+
throw new Error(`Unsupported hash algorithm: '${algorithm}'`);
|
|
67
|
+
}
|
|
68
|
+
const hasher = crypto.createHash(algorithm);
|
|
69
|
+
hasher.update(objectString);
|
|
70
|
+
const hashHex = hasher.digest("hex");
|
|
71
|
+
const hashNumber = Number.parseInt(hashHex, 16);
|
|
72
|
+
const range = max - min + 1;
|
|
73
|
+
return min + hashNumber % range;
|
|
74
|
+
}
|
|
75
|
+
function djb2Hash(string_, min = 0, max = 10) {
|
|
76
|
+
let hash2 = 5381;
|
|
77
|
+
for (let i = 0; i < string_.length; i++) {
|
|
78
|
+
hash2 = hash2 * 33 ^ string_.charCodeAt(i);
|
|
79
|
+
}
|
|
80
|
+
const range = max - min + 1;
|
|
81
|
+
return min + Math.abs(hash2) % range;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// src/keyv-memory.ts
|
|
85
|
+
var import_keyv = require("keyv");
|
|
86
|
+
|
|
87
|
+
// src/memory.ts
|
|
88
|
+
var import_hookified = require("hookified");
|
|
89
|
+
|
|
90
|
+
// src/memory-lru.ts
|
|
91
|
+
var ListNode = class {
|
|
92
|
+
value;
|
|
93
|
+
prev = void 0;
|
|
94
|
+
next = void 0;
|
|
95
|
+
constructor(value) {
|
|
96
|
+
this.value = value;
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
var DoublyLinkedList = class {
|
|
100
|
+
head = void 0;
|
|
101
|
+
tail = void 0;
|
|
102
|
+
nodesMap = /* @__PURE__ */ new Map();
|
|
103
|
+
// Add a new node to the front (most recently used)
|
|
104
|
+
addToFront(value) {
|
|
105
|
+
const newNode = new ListNode(value);
|
|
106
|
+
if (this.head) {
|
|
107
|
+
newNode.next = this.head;
|
|
108
|
+
this.head.prev = newNode;
|
|
109
|
+
this.head = newNode;
|
|
110
|
+
} else {
|
|
111
|
+
this.head = this.tail = newNode;
|
|
112
|
+
}
|
|
113
|
+
this.nodesMap.set(value, newNode);
|
|
114
|
+
}
|
|
115
|
+
// Move an existing node to the front (most recently used)
|
|
116
|
+
moveToFront(value) {
|
|
117
|
+
const node = this.nodesMap.get(value);
|
|
118
|
+
if (!node || this.head === node) {
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
if (node.prev) {
|
|
122
|
+
node.prev.next = node.next;
|
|
123
|
+
}
|
|
124
|
+
if (node.next) {
|
|
125
|
+
node.next.prev = node.prev;
|
|
126
|
+
}
|
|
127
|
+
if (node === this.tail) {
|
|
128
|
+
this.tail = node.prev;
|
|
129
|
+
}
|
|
130
|
+
node.prev = void 0;
|
|
131
|
+
node.next = this.head;
|
|
132
|
+
if (this.head) {
|
|
133
|
+
this.head.prev = node;
|
|
134
|
+
}
|
|
135
|
+
this.head = node;
|
|
136
|
+
this.tail ??= node;
|
|
137
|
+
}
|
|
138
|
+
// Get the oldest node (tail)
|
|
139
|
+
getOldest() {
|
|
140
|
+
return this.tail ? this.tail.value : void 0;
|
|
141
|
+
}
|
|
142
|
+
// Remove the oldest node (tail)
|
|
143
|
+
removeOldest() {
|
|
144
|
+
if (!this.tail) {
|
|
145
|
+
return void 0;
|
|
146
|
+
}
|
|
147
|
+
const oldValue = this.tail.value;
|
|
148
|
+
if (this.tail.prev) {
|
|
149
|
+
this.tail = this.tail.prev;
|
|
150
|
+
this.tail.next = void 0;
|
|
151
|
+
} else {
|
|
152
|
+
this.head = this.tail = void 0;
|
|
153
|
+
}
|
|
154
|
+
this.nodesMap.delete(oldValue);
|
|
155
|
+
return oldValue;
|
|
156
|
+
}
|
|
157
|
+
get size() {
|
|
158
|
+
return this.nodesMap.size;
|
|
159
|
+
}
|
|
160
|
+
};
|
|
51
161
|
|
|
52
162
|
// src/shorthand-time.ts
|
|
53
163
|
var shorthandToMilliseconds = (shorthand) => {
|
|
@@ -62,7 +172,9 @@ var shorthandToMilliseconds = (shorthand) => {
|
|
|
62
172
|
if (Number.isNaN(Number(shorthand))) {
|
|
63
173
|
const match = /^([\d.]+)\s*(ms|s|m|h|hr|d)$/i.exec(shorthand);
|
|
64
174
|
if (!match) {
|
|
65
|
-
throw new Error(
|
|
175
|
+
throw new Error(
|
|
176
|
+
`Unsupported time format: "${shorthand}". Use 'ms', 's', 'm', 'h', 'hr', or 'd'.`
|
|
177
|
+
);
|
|
66
178
|
}
|
|
67
179
|
const [, value, unit] = match;
|
|
68
180
|
const numericValue = Number.parseFloat(value);
|
|
@@ -114,44 +226,6 @@ var shorthandToTime = (shorthand, fromDate) => {
|
|
|
114
226
|
return fromDate.getTime() + milliseconds;
|
|
115
227
|
};
|
|
116
228
|
|
|
117
|
-
// src/keyv-memory.ts
|
|
118
|
-
var import_keyv = require("keyv");
|
|
119
|
-
|
|
120
|
-
// src/memory.ts
|
|
121
|
-
var import_hookified = require("hookified");
|
|
122
|
-
|
|
123
|
-
// src/hash.ts
|
|
124
|
-
var crypto = __toESM(require("crypto"), 1);
|
|
125
|
-
function hash(object, algorithm = "sha256") {
|
|
126
|
-
const objectString = JSON.stringify(object);
|
|
127
|
-
if (!crypto.getHashes().includes(algorithm)) {
|
|
128
|
-
throw new Error(`Unsupported hash algorithm: '${algorithm}'`);
|
|
129
|
-
}
|
|
130
|
-
const hasher = crypto.createHash(algorithm);
|
|
131
|
-
hasher.update(objectString);
|
|
132
|
-
return hasher.digest("hex");
|
|
133
|
-
}
|
|
134
|
-
function hashToNumber(object, min = 0, max = 10, algorithm = "sha256") {
|
|
135
|
-
const objectString = JSON.stringify(object);
|
|
136
|
-
if (!crypto.getHashes().includes(algorithm)) {
|
|
137
|
-
throw new Error(`Unsupported hash algorithm: '${algorithm}'`);
|
|
138
|
-
}
|
|
139
|
-
const hasher = crypto.createHash(algorithm);
|
|
140
|
-
hasher.update(objectString);
|
|
141
|
-
const hashHex = hasher.digest("hex");
|
|
142
|
-
const hashNumber = Number.parseInt(hashHex, 16);
|
|
143
|
-
const range = max - min + 1;
|
|
144
|
-
return min + hashNumber % range;
|
|
145
|
-
}
|
|
146
|
-
function djb2Hash(string_, min = 0, max = 10) {
|
|
147
|
-
let hash2 = 5381;
|
|
148
|
-
for (let i = 0; i < string_.length; i++) {
|
|
149
|
-
hash2 = hash2 * 33 ^ string_.charCodeAt(i);
|
|
150
|
-
}
|
|
151
|
-
const range = max - min + 1;
|
|
152
|
-
return min + Math.abs(hash2) % range;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
229
|
// src/coalesce-async.ts
|
|
156
230
|
var callbacks = /* @__PURE__ */ new Map();
|
|
157
231
|
function hasKey(key) {
|
|
@@ -210,7 +284,7 @@ async function coalesceAsync(key, fnc) {
|
|
|
210
284
|
// src/wrap.ts
|
|
211
285
|
function wrapSync(function_, options) {
|
|
212
286
|
const { ttl, keyPrefix, cache } = options;
|
|
213
|
-
return
|
|
287
|
+
return (...arguments_) => {
|
|
214
288
|
let cacheKey = createWrapKey(function_, arguments_, keyPrefix);
|
|
215
289
|
if (options.createKey) {
|
|
216
290
|
cacheKey = options.createKey(function_, arguments_, options);
|
|
@@ -256,12 +330,16 @@ async function getOrSet(key, function_, options) {
|
|
|
256
330
|
}
|
|
257
331
|
function wrap(function_, options) {
|
|
258
332
|
const { keyPrefix, cache } = options;
|
|
259
|
-
return async
|
|
333
|
+
return async (...arguments_) => {
|
|
260
334
|
let cacheKey = createWrapKey(function_, arguments_, keyPrefix);
|
|
261
335
|
if (options.createKey) {
|
|
262
336
|
cacheKey = options.createKey(function_, arguments_, options);
|
|
263
337
|
}
|
|
264
|
-
return cache.getOrSet(
|
|
338
|
+
return cache.getOrSet(
|
|
339
|
+
cacheKey,
|
|
340
|
+
async () => function_(...arguments_),
|
|
341
|
+
options
|
|
342
|
+
);
|
|
265
343
|
};
|
|
266
344
|
}
|
|
267
345
|
function createWrapKey(function_, arguments_, keyPrefix) {
|
|
@@ -271,79 +349,6 @@ function createWrapKey(function_, arguments_, keyPrefix) {
|
|
|
271
349
|
return `${keyPrefix}::${function_.name}::${hash(arguments_)}`;
|
|
272
350
|
}
|
|
273
351
|
|
|
274
|
-
// src/memory-lru.ts
|
|
275
|
-
var ListNode = class {
|
|
276
|
-
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
|
277
|
-
value;
|
|
278
|
-
prev = void 0;
|
|
279
|
-
next = void 0;
|
|
280
|
-
constructor(value) {
|
|
281
|
-
this.value = value;
|
|
282
|
-
}
|
|
283
|
-
};
|
|
284
|
-
var DoublyLinkedList = class {
|
|
285
|
-
head = void 0;
|
|
286
|
-
tail = void 0;
|
|
287
|
-
nodesMap = /* @__PURE__ */ new Map();
|
|
288
|
-
// Add a new node to the front (most recently used)
|
|
289
|
-
addToFront(value) {
|
|
290
|
-
const newNode = new ListNode(value);
|
|
291
|
-
if (this.head) {
|
|
292
|
-
newNode.next = this.head;
|
|
293
|
-
this.head.prev = newNode;
|
|
294
|
-
this.head = newNode;
|
|
295
|
-
} else {
|
|
296
|
-
this.head = this.tail = newNode;
|
|
297
|
-
}
|
|
298
|
-
this.nodesMap.set(value, newNode);
|
|
299
|
-
}
|
|
300
|
-
// Move an existing node to the front (most recently used)
|
|
301
|
-
moveToFront(value) {
|
|
302
|
-
const node = this.nodesMap.get(value);
|
|
303
|
-
if (!node || this.head === node) {
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
if (node.prev) {
|
|
307
|
-
node.prev.next = node.next;
|
|
308
|
-
}
|
|
309
|
-
if (node.next) {
|
|
310
|
-
node.next.prev = node.prev;
|
|
311
|
-
}
|
|
312
|
-
if (node === this.tail) {
|
|
313
|
-
this.tail = node.prev;
|
|
314
|
-
}
|
|
315
|
-
node.prev = void 0;
|
|
316
|
-
node.next = this.head;
|
|
317
|
-
if (this.head) {
|
|
318
|
-
this.head.prev = node;
|
|
319
|
-
}
|
|
320
|
-
this.head = node;
|
|
321
|
-
this.tail ??= node;
|
|
322
|
-
}
|
|
323
|
-
// Get the oldest node (tail)
|
|
324
|
-
getOldest() {
|
|
325
|
-
return this.tail ? this.tail.value : void 0;
|
|
326
|
-
}
|
|
327
|
-
// Remove the oldest node (tail)
|
|
328
|
-
removeOldest() {
|
|
329
|
-
if (!this.tail) {
|
|
330
|
-
return void 0;
|
|
331
|
-
}
|
|
332
|
-
const oldValue = this.tail.value;
|
|
333
|
-
if (this.tail.prev) {
|
|
334
|
-
this.tail = this.tail.prev;
|
|
335
|
-
this.tail.next = void 0;
|
|
336
|
-
} else {
|
|
337
|
-
this.head = this.tail = void 0;
|
|
338
|
-
}
|
|
339
|
-
this.nodesMap.delete(oldValue);
|
|
340
|
-
return oldValue;
|
|
341
|
-
}
|
|
342
|
-
get size() {
|
|
343
|
-
return this.nodesMap.size;
|
|
344
|
-
}
|
|
345
|
-
};
|
|
346
|
-
|
|
347
352
|
// src/memory.ts
|
|
348
353
|
var defaultStoreHashSize = 16;
|
|
349
354
|
var maximumMapSize = 16777216;
|
|
@@ -352,7 +357,10 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
352
357
|
_storeHashSize = defaultStoreHashSize;
|
|
353
358
|
_storeHashAlgorithm = "djb2Hash" /* djb2Hash */;
|
|
354
359
|
// Default is djb2Hash
|
|
355
|
-
_store = Array.from(
|
|
360
|
+
_store = Array.from(
|
|
361
|
+
{ length: this._storeHashSize },
|
|
362
|
+
() => /* @__PURE__ */ new Map()
|
|
363
|
+
);
|
|
356
364
|
_ttl;
|
|
357
365
|
// Turned off by default
|
|
358
366
|
_useClone = true;
|
|
@@ -380,7 +388,12 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
380
388
|
}
|
|
381
389
|
if (options?.lruSize) {
|
|
382
390
|
if (options.lruSize > maximumMapSize) {
|
|
383
|
-
this.emit(
|
|
391
|
+
this.emit(
|
|
392
|
+
"error",
|
|
393
|
+
new Error(
|
|
394
|
+
`LRU size cannot be larger than ${maximumMapSize} due to Map limitations.`
|
|
395
|
+
)
|
|
396
|
+
);
|
|
384
397
|
} else {
|
|
385
398
|
this._lruSize = options.lruSize;
|
|
386
399
|
}
|
|
@@ -391,7 +404,10 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
391
404
|
if (options?.storeHashAlgorithm) {
|
|
392
405
|
this._storeHashAlgorithm = options.storeHashAlgorithm;
|
|
393
406
|
}
|
|
394
|
-
this._store = Array.from(
|
|
407
|
+
this._store = Array.from(
|
|
408
|
+
{ length: this._storeHashSize },
|
|
409
|
+
() => /* @__PURE__ */ new Map()
|
|
410
|
+
);
|
|
395
411
|
this.startIntervalCheck();
|
|
396
412
|
}
|
|
397
413
|
/**
|
|
@@ -435,7 +451,12 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
435
451
|
*/
|
|
436
452
|
set lruSize(value) {
|
|
437
453
|
if (value > maximumMapSize) {
|
|
438
|
-
this.emit(
|
|
454
|
+
this.emit(
|
|
455
|
+
"error",
|
|
456
|
+
new Error(
|
|
457
|
+
`LRU size cannot be larger than ${maximumMapSize} due to Map limitations.`
|
|
458
|
+
)
|
|
459
|
+
);
|
|
439
460
|
return;
|
|
440
461
|
}
|
|
441
462
|
this._lruSize = value;
|
|
@@ -486,7 +507,10 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
486
507
|
return;
|
|
487
508
|
}
|
|
488
509
|
this._storeHashSize = value;
|
|
489
|
-
this._store = Array.from(
|
|
510
|
+
this._store = Array.from(
|
|
511
|
+
{ length: this._storeHashSize },
|
|
512
|
+
() => /* @__PURE__ */ new Map()
|
|
513
|
+
);
|
|
490
514
|
}
|
|
491
515
|
/**
|
|
492
516
|
* Gets the store hash algorithm
|
|
@@ -507,7 +531,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
507
531
|
* @returns {IterableIterator<string>} - The keys
|
|
508
532
|
*/
|
|
509
533
|
get keys() {
|
|
510
|
-
const keys =
|
|
534
|
+
const keys = [];
|
|
511
535
|
for (const store of this._store) {
|
|
512
536
|
for (const key of store.keys()) {
|
|
513
537
|
const item = store.get(key);
|
|
@@ -525,7 +549,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
525
549
|
* @returns {IterableIterator<CacheableStoreItem>} - The items
|
|
526
550
|
*/
|
|
527
551
|
get items() {
|
|
528
|
-
const items =
|
|
552
|
+
const items = [];
|
|
529
553
|
for (const store of this._store) {
|
|
530
554
|
for (const item of store.values()) {
|
|
531
555
|
if (this.hasExpired(item)) {
|
|
@@ -571,7 +595,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
571
595
|
* @returns {T[]} - The values of the keys
|
|
572
596
|
*/
|
|
573
597
|
getMany(keys) {
|
|
574
|
-
const result =
|
|
598
|
+
const result = [];
|
|
575
599
|
for (const key of keys) {
|
|
576
600
|
result.push(this.get(key));
|
|
577
601
|
}
|
|
@@ -601,7 +625,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
601
625
|
* @returns {CacheableStoreItem[]} - The raw values of the keys
|
|
602
626
|
*/
|
|
603
627
|
getManyRaw(keys) {
|
|
604
|
-
const result =
|
|
628
|
+
const result = [];
|
|
605
629
|
for (const key of keys) {
|
|
606
630
|
result.push(this.getRaw(key));
|
|
607
631
|
}
|
|
@@ -652,10 +676,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
652
676
|
}
|
|
653
677
|
}
|
|
654
678
|
const item = { key, value, expires };
|
|
655
|
-
store.set(
|
|
656
|
-
key,
|
|
657
|
-
item
|
|
658
|
-
);
|
|
679
|
+
store.set(key, item);
|
|
659
680
|
}
|
|
660
681
|
/**
|
|
661
682
|
* Sets the values of the keys
|
|
@@ -682,7 +703,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
682
703
|
* @returns {boolean[]} - If true, the key exists. If false, the key does not exist.
|
|
683
704
|
*/
|
|
684
705
|
hasMany(keys) {
|
|
685
|
-
const result =
|
|
706
|
+
const result = [];
|
|
686
707
|
for (const key of keys) {
|
|
687
708
|
const item = this.get(key);
|
|
688
709
|
result.push(Boolean(item));
|
|
@@ -708,7 +729,7 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
708
729
|
* @returns {T[]} - The values of the keys
|
|
709
730
|
*/
|
|
710
731
|
takeMany(keys) {
|
|
711
|
-
const result =
|
|
732
|
+
const result = [];
|
|
712
733
|
for (const key of keys) {
|
|
713
734
|
result.push(this.take(key));
|
|
714
735
|
}
|
|
@@ -738,7 +759,10 @@ var CacheableMemory = class extends import_hookified.Hookified {
|
|
|
738
759
|
* @returns {void}
|
|
739
760
|
*/
|
|
740
761
|
clear() {
|
|
741
|
-
this._store = Array.from(
|
|
762
|
+
this._store = Array.from(
|
|
763
|
+
{ length: this._storeHashSize },
|
|
764
|
+
() => /* @__PURE__ */ new Map()
|
|
765
|
+
);
|
|
742
766
|
this._lru = new DoublyLinkedList();
|
|
743
767
|
}
|
|
744
768
|
/**
|
|
@@ -1110,28 +1134,24 @@ var CacheableStats = class {
|
|
|
1110
1134
|
}
|
|
1111
1135
|
this._clears++;
|
|
1112
1136
|
}
|
|
1113
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1114
1137
|
incrementVSize(value) {
|
|
1115
1138
|
if (!this._enabled) {
|
|
1116
1139
|
return;
|
|
1117
1140
|
}
|
|
1118
1141
|
this._vsize += this.roughSizeOfObject(value);
|
|
1119
1142
|
}
|
|
1120
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1121
1143
|
decreaseVSize(value) {
|
|
1122
1144
|
if (!this._enabled) {
|
|
1123
1145
|
return;
|
|
1124
1146
|
}
|
|
1125
1147
|
this._vsize -= this.roughSizeOfObject(value);
|
|
1126
1148
|
}
|
|
1127
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1128
1149
|
incrementKSize(key) {
|
|
1129
1150
|
if (!this._enabled) {
|
|
1130
1151
|
return;
|
|
1131
1152
|
}
|
|
1132
1153
|
this._ksize += this.roughSizeOfString(key);
|
|
1133
1154
|
}
|
|
1134
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
1135
1155
|
decreaseKSize(key) {
|
|
1136
1156
|
if (!this._enabled) {
|
|
1137
1157
|
return;
|
|
@@ -1450,11 +1470,26 @@ var Cacheable = class extends import_hookified2.Hookified {
|
|
|
1450
1470
|
this.emit("error" /* ERROR */, error);
|
|
1451
1471
|
});
|
|
1452
1472
|
}
|
|
1473
|
+
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
1453
1474
|
isKeyvInstance(keyv) {
|
|
1454
1475
|
if (keyv instanceof import_keyv2.Keyv) {
|
|
1455
1476
|
return true;
|
|
1456
1477
|
}
|
|
1457
|
-
const keyvMethods = [
|
|
1478
|
+
const keyvMethods = [
|
|
1479
|
+
"generateIterator",
|
|
1480
|
+
"get",
|
|
1481
|
+
"getMany",
|
|
1482
|
+
"set",
|
|
1483
|
+
"setMany",
|
|
1484
|
+
"delete",
|
|
1485
|
+
"deleteMany",
|
|
1486
|
+
"has",
|
|
1487
|
+
"hasMany",
|
|
1488
|
+
"clear",
|
|
1489
|
+
"disconnect",
|
|
1490
|
+
"serialize",
|
|
1491
|
+
"deserialize"
|
|
1492
|
+
];
|
|
1458
1493
|
return keyvMethods.every((method) => typeof keyv[method] === "function");
|
|
1459
1494
|
}
|
|
1460
1495
|
getNameSpace() {
|
|
@@ -1478,7 +1513,10 @@ var Cacheable = class extends import_hookified2.Hookified {
|
|
|
1478
1513
|
const expires = secondaryResult.expires ?? void 0;
|
|
1479
1514
|
ttl = calculateTtlFromExpiration(cascadeTtl, expires);
|
|
1480
1515
|
const setItem = { key, value: result.value, ttl };
|
|
1481
|
-
await this.hook(
|
|
1516
|
+
await this.hook(
|
|
1517
|
+
"BEFORE_SECONDARY_SETS_PRIMARY" /* BEFORE_SECONDARY_SETS_PRIMARY */,
|
|
1518
|
+
setItem
|
|
1519
|
+
);
|
|
1482
1520
|
await this._primary.set(setItem.key, setItem.value, setItem.ttl);
|
|
1483
1521
|
}
|
|
1484
1522
|
}
|
|
@@ -1520,7 +1558,10 @@ var Cacheable = class extends import_hookified2.Hookified {
|
|
|
1520
1558
|
}
|
|
1521
1559
|
const ttl = calculateTtlFromExpiration(cascadeTtl, expires);
|
|
1522
1560
|
const setItem = { key, value: result[i].value, ttl };
|
|
1523
|
-
await this.hook(
|
|
1561
|
+
await this.hook(
|
|
1562
|
+
"BEFORE_SECONDARY_SETS_PRIMARY" /* BEFORE_SECONDARY_SETS_PRIMARY */,
|
|
1563
|
+
setItem
|
|
1564
|
+
);
|
|
1524
1565
|
await this._primary.set(setItem.key, setItem.value, setItem.ttl);
|
|
1525
1566
|
}
|
|
1526
1567
|
}
|
|
@@ -1662,7 +1703,7 @@ var Cacheable = class extends import_hookified2.Hookified {
|
|
|
1662
1703
|
}
|
|
1663
1704
|
if (missingKeys.length > 0 && this._secondary) {
|
|
1664
1705
|
const secondary = await this.hasManyKeyv(this._secondary, keys);
|
|
1665
|
-
for (const [i,
|
|
1706
|
+
for (const [i, _key] of keys.entries()) {
|
|
1666
1707
|
if (!result[i] && secondary[i]) {
|
|
1667
1708
|
result[i] = secondary[i];
|
|
1668
1709
|
}
|
|
@@ -1760,6 +1801,7 @@ var Cacheable = class extends import_hookified2.Hookified {
|
|
|
1760
1801
|
* @param {WrapOptions} [options] The options for the wrap function
|
|
1761
1802
|
* @returns {Function} The wrapped function
|
|
1762
1803
|
*/
|
|
1804
|
+
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
1763
1805
|
wrap(function_, options) {
|
|
1764
1806
|
const wrapOptions = {
|
|
1765
1807
|
ttl: options?.ttl ?? this._ttl,
|
|
@@ -1795,6 +1837,7 @@ var Cacheable = class extends import_hookified2.Hookified {
|
|
|
1795
1837
|
* @param {string} algorithm the hash algorithm to use. The default is 'sha256'
|
|
1796
1838
|
* @returns {string} the hash of the object
|
|
1797
1839
|
*/
|
|
1840
|
+
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
1798
1841
|
hash(object, algorithm = "sha256") {
|
|
1799
1842
|
return hash(object, algorithm);
|
|
1800
1843
|
}
|
|
@@ -1806,7 +1849,7 @@ var Cacheable = class extends import_hookified2.Hookified {
|
|
|
1806
1849
|
return result;
|
|
1807
1850
|
}
|
|
1808
1851
|
async getManySecondaryRawResults(keys) {
|
|
1809
|
-
let result =
|
|
1852
|
+
let result = [];
|
|
1810
1853
|
if (this._secondary) {
|
|
1811
1854
|
result = await this._secondary.get(keys, { raw: true });
|
|
1812
1855
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,26 @@
|
|
|
1
|
-
import { KeyvStoreAdapter, StoredData, Keyv, StoredDataRaw } from 'keyv';
|
|
2
|
-
export { Keyv, KeyvHooks, KeyvOptions, KeyvStoreAdapter } from 'keyv';
|
|
3
1
|
import { Hookified } from 'hookified';
|
|
2
|
+
import { Keyv, KeyvStoreAdapter, StoredData, StoredDataRaw } from 'keyv';
|
|
3
|
+
export { Keyv, KeyvHooks, KeyvOptions, KeyvStoreAdapter } from 'keyv';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* CacheableItem
|
|
7
|
+
* @typedef {Object} CacheableItem
|
|
8
|
+
* @property {string} key - The key of the cacheable item
|
|
9
|
+
* @property {any} value - The value of the cacheable item
|
|
10
|
+
* @property {number|string} [ttl] - Time to Live - If you set a number it is miliseconds, if you set a string it is a human-readable
|
|
11
|
+
* format such as `1s` for 1 second or `1h` for 1 hour. Setting undefined means that it will use the default time-to-live. If both are
|
|
12
|
+
* undefined then it will not have a time-to-live.
|
|
13
|
+
*/
|
|
14
|
+
type CacheableItem = {
|
|
15
|
+
key: string;
|
|
16
|
+
value: any;
|
|
17
|
+
ttl?: number | string;
|
|
18
|
+
};
|
|
19
|
+
type CacheableStoreItem = {
|
|
20
|
+
key: string;
|
|
21
|
+
value: any;
|
|
22
|
+
expires?: number;
|
|
23
|
+
};
|
|
4
24
|
|
|
5
25
|
type CacheableOptions$1 = {
|
|
6
26
|
enabled?: boolean;
|
|
@@ -89,26 +109,6 @@ declare class CacheableStats {
|
|
|
89
109
|
resetStoreValues(): void;
|
|
90
110
|
}
|
|
91
111
|
|
|
92
|
-
/**
|
|
93
|
-
* CacheableItem
|
|
94
|
-
* @typedef {Object} CacheableItem
|
|
95
|
-
* @property {string} key - The key of the cacheable item
|
|
96
|
-
* @property {any} value - The value of the cacheable item
|
|
97
|
-
* @property {number|string} [ttl] - Time to Live - If you set a number it is miliseconds, if you set a string it is a human-readable
|
|
98
|
-
* format such as `1s` for 1 second or `1h` for 1 hour. Setting undefined means that it will use the default time-to-live. If both are
|
|
99
|
-
* undefined then it will not have a time-to-live.
|
|
100
|
-
*/
|
|
101
|
-
type CacheableItem = {
|
|
102
|
-
key: string;
|
|
103
|
-
value: any;
|
|
104
|
-
ttl?: number | string;
|
|
105
|
-
};
|
|
106
|
-
type CacheableStoreItem = {
|
|
107
|
-
key: string;
|
|
108
|
-
value: any;
|
|
109
|
-
expires?: number;
|
|
110
|
-
};
|
|
111
|
-
|
|
112
112
|
type GetOrSetKey = string | ((options?: GetOrSetOptions) => string);
|
|
113
113
|
type GetOrSetFunctionOptions = {
|
|
114
114
|
ttl?: number | string;
|
|
@@ -144,7 +144,7 @@ declare enum StoreHashAlgorithm {
|
|
|
144
144
|
MD5 = "md5",
|
|
145
145
|
djb2Hash = "djb2Hash"
|
|
146
146
|
}
|
|
147
|
-
type StoreHashAlgorithmFunction = (
|
|
147
|
+
type StoreHashAlgorithmFunction = (key: string, storeHashSize: number) => number;
|
|
148
148
|
/**
|
|
149
149
|
* @typedef {Object} CacheableMemoryOptions
|
|
150
150
|
* @property {number|string} [ttl] - Time to Live - If you set a number it is miliseconds, if you set a string it is a human-readable
|
|
@@ -623,19 +623,19 @@ declare class Cacheable extends Hookified {
|
|
|
623
623
|
isKeyvInstance(keyv: any): boolean;
|
|
624
624
|
getNameSpace(): string | undefined;
|
|
625
625
|
/**
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
626
|
+
* Retrieves an entry from the cache, with an optional “raw” mode.
|
|
627
|
+
*
|
|
628
|
+
* Checks the primary store first; if not found and a secondary store is configured,
|
|
629
|
+
* it will fetch from the secondary, repopulate the primary, and return the result.
|
|
630
|
+
*
|
|
631
|
+
* @typeParam T - The expected type of the stored value.
|
|
632
|
+
* @param {string} key - The cache key to retrieve.
|
|
633
|
+
* @param {{ raw?: boolean }} [opts] - Options for retrieval.
|
|
634
|
+
* @param {boolean} [opts.raw=false] - If `true`, returns the full raw data object
|
|
635
|
+
* (`StoredDataRaw<T>`); otherwise returns just the value.
|
|
636
|
+
* @returns {Promise<T | StoredDataRaw<T> | undefined>}
|
|
637
|
+
* A promise that resolves to the cached value (or raw data) if found, or `undefined`.
|
|
638
|
+
*/
|
|
639
639
|
get<T>(key: string, options?: {
|
|
640
640
|
raw?: false;
|
|
641
641
|
}): Promise<T | undefined>;
|
|
@@ -643,20 +643,20 @@ declare class Cacheable extends Hookified {
|
|
|
643
643
|
raw: true;
|
|
644
644
|
}): Promise<StoredDataRaw<T>>;
|
|
645
645
|
/**
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
646
|
+
* Retrieves multiple entries from the cache.
|
|
647
|
+
* Checks the primary store for each key; if a key is missing and a secondary store is configured,
|
|
648
|
+
* it will fetch from the secondary store, repopulate the primary store, and return the results.
|
|
649
|
+
*
|
|
650
|
+
* @typeParam T - The expected type of the stored values.
|
|
651
|
+
* @param {string[]} keys - The cache keys to retrieve.
|
|
652
|
+
* @param {{ raw?: boolean }} [options] - Options for retrieval.
|
|
653
|
+
* @param {boolean} [options.raw=false] - When `true`, returns an array of raw data objects (`StoredDataRaw<T>`);
|
|
654
|
+
* when `false`, returns an array of unwrapped values (`T`) or `undefined` for misses.
|
|
655
|
+
* @returns {Promise<Array<T | undefined>> | Promise<Array<StoredDataRaw<T>>>}
|
|
656
|
+
* A promise that resolves to:
|
|
657
|
+
* - `Array<T | undefined>` if `raw` is `false` (default).
|
|
658
|
+
* - `Array<StoredDataRaw<T>>` if `raw` is `true`.
|
|
659
|
+
*/
|
|
660
660
|
getMany<T>(keys: string[], options?: {
|
|
661
661
|
raw?: false;
|
|
662
662
|
}): Promise<Array<T | undefined>>;
|