@cacheable/memory 2.0.3 → 2.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.cjs CHANGED
@@ -1 +1,788 @@
1
- "use strict";var p=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var z=(i,e)=>{for(var t in e)p(i,t,{get:e[t],enumerable:!0})},x=(i,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of C(e))!T.call(i,s)&&s!==t&&p(i,s,{get:()=>e[s],enumerable:!(r=S(e,s))||r.enumerable});return i};var H=i=>x(p({},"__esModule",{value:!0}),i);var M={};z(M,{CacheableMemory:()=>a,HashAlgorithm:()=>l.HashAlgorithm,KeyvCacheableMemory:()=>u,createKeyv:()=>g,defaultStoreHashSize:()=>y,hash:()=>l.hash,hashToNumber:()=>l.hashToNumber,maximumMapSize:()=>c});module.exports=H(M);var b=require("@cacheable/memoize"),o=require("@cacheable/utils"),_=require("hookified");var m=class{value;prev=void 0;next=void 0;constructor(e){this.value=e}},h=class{head=void 0;tail=void 0;nodesMap=new Map;addToFront(e){let t=new m(e);this.head?(t.next=this.head,this.head.prev=t,this.head=t):this.head=this.tail=t,this.nodesMap.set(e,t)}moveToFront(e){let t=this.nodesMap.get(e);!t||this.head===t||(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.tail&&(this.tail=t.prev),t.prev=void 0,t.next=this.head,this.head&&(this.head.prev=t),this.head=t,this.tail??=t)}getOldest(){return this.tail?this.tail.value:void 0}removeOldest(){if(!this.tail)return;let e=this.tail.value;return this.tail.prev?(this.tail=this.tail.prev,this.tail.next=void 0):this.head=this.tail=void 0,this.nodesMap.delete(e),e}get size(){return this.nodesMap.size}};var l=require("@cacheable/utils");var f=require("keyv");var u=class{opts={ttl:0,useClone:!0,lruSize:0,checkInterval:0};_defaultCache=new a;_nCache=new Map;_namespace;constructor(e){e&&(this.opts=e,this._defaultCache=new a(e),e.namespace&&(this._namespace=e.namespace,this._nCache.set(this._namespace,new a(e))))}get namespace(){return this._namespace}set namespace(e){this._namespace=e}get store(){return this.getStore(this._namespace)}async get(e){let t=this.getStore(this._namespace).get(e);if(t)return t}async getMany(e){return this.getStore(this._namespace).getMany(e)}async set(e,t,r){this.getStore(this._namespace).set(e,t,r)}async setMany(e){this.getStore(this._namespace).setMany(e)}async delete(e){return this.getStore(this._namespace).delete(e),!0}async deleteMany(e){return this.getStore(this._namespace).deleteMany(e),!0}async clear(){this.getStore(this._namespace).clear()}async has(e){return this.getStore(this._namespace).has(e)}on(e,t){return this.getStore(this._namespace).on(e,t),this}getStore(e){return e?(this._nCache.has(e)||this._nCache.set(e,new a(this.opts)),this._nCache.get(e)):this._defaultCache}};function g(i){let e=new u(i),t=i?.namespace,r;i?.ttl&&Number.isInteger(i.ttl)&&(r=i?.ttl);let s=new f.Keyv({store:e,namespace:t,ttl:r});return s.serialize=void 0,s.deserialize=void 0,s}var y=16,c=16777216,a=class extends _.Hookified{_lru=new h;_storeHashSize=y;_storeHashAlgorithm=o.HashAlgorithm.DJB2;_store=Array.from({length:this._storeHashSize},()=>new Map);_ttl;_useClone=!0;_lruSize=0;_checkInterval=0;_interval=0;constructor(e){super(),e?.ttl&&this.setTtl(e.ttl),e?.useClone!==void 0&&(this._useClone=e.useClone),e?.storeHashSize&&e.storeHashSize>0&&(this._storeHashSize=e.storeHashSize),e?.lruSize&&(e.lruSize>c?this.emit("error",new Error(`LRU size cannot be larger than ${c} due to Map limitations.`)):this._lruSize=e.lruSize),e?.checkInterval&&(this._checkInterval=e.checkInterval),e?.storeHashAlgorithm&&(this._storeHashAlgorithm=e.storeHashAlgorithm),this._store=Array.from({length:this._storeHashSize},()=>new Map),this.startIntervalCheck()}get ttl(){return this._ttl}set ttl(e){this.setTtl(e)}get useClone(){return this._useClone}set useClone(e){this._useClone=e}get lruSize(){return this._lruSize}set lruSize(e){if(e>c){this.emit("error",new Error(`LRU size cannot be larger than ${c} due to Map limitations.`));return}if(this._lruSize=e,this._lruSize===0){this._lru=new h;return}this.lruResize()}get checkInterval(){return this._checkInterval}set checkInterval(e){this._checkInterval=e}get size(){let e=0;for(let t of this._store)e+=t.size;return e}get storeHashSize(){return this._storeHashSize}set storeHashSize(e){e!==this._storeHashSize&&(this._storeHashSize=e,this._store=Array.from({length:this._storeHashSize},()=>new Map))}get storeHashAlgorithm(){return this._storeHashAlgorithm}set storeHashAlgorithm(e){this._storeHashAlgorithm=e}get keys(){let e=[];for(let t of this._store)for(let r of t.keys()){let s=t.get(r);if(s&&this.hasExpired(s)){t.delete(r);continue}e.push(r)}return e.values()}get items(){let e=[];for(let t of this._store)for(let r of t.values()){if(this.hasExpired(r)){t.delete(r.key);continue}e.push(r)}return e.values()}get store(){return this._store}get(e){let t=this.getStore(e),r=t.get(e);if(r){if(r.expires&&Date.now()>r.expires){t.delete(e);return}return this.lruMoveToFront(e),this._useClone?this.clone(r.value):r.value}}getMany(e){let t=[];for(let r of e)t.push(this.get(r));return t}getRaw(e){let t=this.getStore(e),r=t.get(e);if(r){if(r.expires&&r.expires&&Date.now()>r.expires){t.delete(e);return}return this.lruMoveToFront(e),r}}getManyRaw(e){let t=[];for(let r of e)t.push(this.getRaw(r));return t}set(e,t,r){let s=this.getStore(e),d;if(r!==void 0||this._ttl!==void 0)if(typeof r=="object"){if(r.expire&&(d=typeof r.expire=="number"?r.expire:r.expire.getTime()),r.ttl){let n=(0,o.shorthandToTime)(r.ttl);n!==void 0&&(d=n)}}else{let n=(0,o.shorthandToTime)(r??this._ttl);n!==void 0&&(d=n)}if(this._lruSize>0){if(s.has(e))this.lruMoveToFront(e);else if(this.lruAddToFront(e),this._lru.size>this._lruSize){let n=this._lru.getOldest();n&&(this._lru.removeOldest(),this.delete(n))}}let v={key:e,value:t,expires:d};s.set(e,v)}setMany(e){for(let t of e)this.set(t.key,t.value,t.ttl)}has(e){return!!this.get(e)}hasMany(e){let t=[];for(let r of e){let s=this.get(r);t.push(!!s)}return t}take(e){let t=this.get(e);if(t)return this.delete(e),t}takeMany(e){let t=[];for(let r of e)t.push(this.take(r));return t}delete(e){this.getStore(e).delete(e)}deleteMany(e){for(let t of e)this.delete(t)}clear(){this._store=Array.from({length:this._storeHashSize},()=>new Map),this._lru=new h}getStore(e){let t=this.getKeyStoreHash(e);return this._store[t]||=new Map,this._store[t]}getKeyStoreHash(e){if(this._store.length===1)return 0;if(typeof this._storeHashAlgorithm=="function")return this._storeHashAlgorithm(e,this._storeHashSize);let t=this._storeHashSize-1;return(0,o.hashToNumber)(e,{min:0,max:t,algorithm:this._storeHashAlgorithm})}clone(e){return this.isPrimitive(e)?e:structuredClone(e)}lruAddToFront(e){this._lruSize!==0&&this._lru.addToFront(e)}lruMoveToFront(e){this._lruSize!==0&&this._lru.moveToFront(e)}lruResize(){for(;this._lru.size>this._lruSize;){let e=this._lru.getOldest();e&&(this._lru.removeOldest(),this.delete(e))}}checkExpiration(){for(let e of this._store)for(let t of e.values())t.expires&&Date.now()>t.expires&&e.delete(t.key)}startIntervalCheck(){this._checkInterval>0&&(this._interval&&clearInterval(this._interval),this._interval=setInterval(()=>{this.checkExpiration()},this._checkInterval).unref())}stopIntervalCheck(){this._interval&&clearInterval(this._interval),this._interval=0,this._checkInterval=0}wrap(e,t){let r={ttl:t?.ttl??this._ttl,keyPrefix:t?.keyPrefix,createKey:t?.createKey,cache:this};return(0,b.wrapSync)(e,r)}isPrimitive(e){return e==null||typeof e=="string"||typeof e=="number"||typeof e=="boolean"}setTtl(e){typeof e=="string"||e===void 0?this._ttl=e:e>0?this._ttl=e:this._ttl=void 0}hasExpired(e){return!!(e.expires&&Date.now()>e.expires)}};0&&(module.exports={CacheableMemory,HashAlgorithm,KeyvCacheableMemory,createKeyv,defaultStoreHashSize,hash,hashToNumber,maximumMapSize});
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ CacheableMemory: () => CacheableMemory,
24
+ HashAlgorithm: () => import_utils2.HashAlgorithm,
25
+ KeyvCacheableMemory: () => KeyvCacheableMemory,
26
+ createKeyv: () => createKeyv,
27
+ defaultStoreHashSize: () => defaultStoreHashSize,
28
+ hash: () => import_utils2.hash,
29
+ hashToNumber: () => import_utils2.hashToNumber,
30
+ maximumMapSize: () => maximumMapSize
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+ var import_utils = require("@cacheable/utils");
34
+ var import_hookified = require("hookified");
35
+
36
+ // src/memory-lru.ts
37
+ var ListNode = class {
38
+ value;
39
+ prev = void 0;
40
+ next = void 0;
41
+ constructor(value) {
42
+ this.value = value;
43
+ }
44
+ };
45
+ var DoublyLinkedList = class {
46
+ head = void 0;
47
+ tail = void 0;
48
+ nodesMap = /* @__PURE__ */ new Map();
49
+ // Add a new node to the front (most recently used)
50
+ addToFront(value) {
51
+ const newNode = new ListNode(value);
52
+ if (this.head) {
53
+ newNode.next = this.head;
54
+ this.head.prev = newNode;
55
+ this.head = newNode;
56
+ } else {
57
+ this.head = this.tail = newNode;
58
+ }
59
+ this.nodesMap.set(value, newNode);
60
+ }
61
+ // Move an existing node to the front (most recently used)
62
+ moveToFront(value) {
63
+ const node = this.nodesMap.get(value);
64
+ if (!node || this.head === node) {
65
+ return;
66
+ }
67
+ if (node.prev) {
68
+ node.prev.next = node.next;
69
+ }
70
+ if (node.next) {
71
+ node.next.prev = node.prev;
72
+ }
73
+ if (node === this.tail) {
74
+ this.tail = node.prev;
75
+ }
76
+ node.prev = void 0;
77
+ node.next = this.head;
78
+ if (this.head) {
79
+ this.head.prev = node;
80
+ }
81
+ this.head = node;
82
+ this.tail ??= node;
83
+ }
84
+ // Get the oldest node (tail)
85
+ getOldest() {
86
+ return this.tail ? this.tail.value : void 0;
87
+ }
88
+ // Remove the oldest node (tail)
89
+ removeOldest() {
90
+ if (!this.tail) {
91
+ return void 0;
92
+ }
93
+ const oldValue = this.tail.value;
94
+ if (this.tail.prev) {
95
+ this.tail = this.tail.prev;
96
+ this.tail.next = void 0;
97
+ } else {
98
+ this.head = this.tail = void 0;
99
+ }
100
+ this.nodesMap.delete(oldValue);
101
+ return oldValue;
102
+ }
103
+ get size() {
104
+ return this.nodesMap.size;
105
+ }
106
+ };
107
+
108
+ // src/index.ts
109
+ var import_utils2 = require("@cacheable/utils");
110
+
111
+ // src/keyv-memory.ts
112
+ var import_keyv = require("keyv");
113
+ var KeyvCacheableMemory = class {
114
+ opts = {
115
+ ttl: 0,
116
+ useClone: true,
117
+ lruSize: 0,
118
+ checkInterval: 0
119
+ };
120
+ _defaultCache = new CacheableMemory();
121
+ _nCache = /* @__PURE__ */ new Map();
122
+ _namespace;
123
+ constructor(options) {
124
+ if (options) {
125
+ this.opts = options;
126
+ this._defaultCache = new CacheableMemory(options);
127
+ if (options.namespace) {
128
+ this._namespace = options.namespace;
129
+ this._nCache.set(this._namespace, new CacheableMemory(options));
130
+ }
131
+ }
132
+ }
133
+ get namespace() {
134
+ return this._namespace;
135
+ }
136
+ set namespace(value) {
137
+ this._namespace = value;
138
+ }
139
+ get store() {
140
+ return this.getStore(this._namespace);
141
+ }
142
+ async get(key) {
143
+ const result = this.getStore(this._namespace).get(key);
144
+ if (result) {
145
+ return result;
146
+ }
147
+ return void 0;
148
+ }
149
+ async getMany(keys) {
150
+ const result = this.getStore(this._namespace).getMany(keys);
151
+ return result;
152
+ }
153
+ // biome-ignore lint/suspicious/noExplicitAny: type format
154
+ async set(key, value, ttl) {
155
+ this.getStore(this._namespace).set(key, value, ttl);
156
+ }
157
+ async setMany(values) {
158
+ this.getStore(this._namespace).setMany(values);
159
+ }
160
+ async delete(key) {
161
+ this.getStore(this._namespace).delete(key);
162
+ return true;
163
+ }
164
+ async deleteMany(key) {
165
+ this.getStore(this._namespace).deleteMany(key);
166
+ return true;
167
+ }
168
+ async clear() {
169
+ this.getStore(this._namespace).clear();
170
+ }
171
+ async has(key) {
172
+ return this.getStore(this._namespace).has(key);
173
+ }
174
+ // biome-ignore lint/suspicious/noExplicitAny: type format
175
+ on(event, listener) {
176
+ this.getStore(this._namespace).on(event, listener);
177
+ return this;
178
+ }
179
+ getStore(namespace) {
180
+ if (!namespace) {
181
+ return this._defaultCache;
182
+ }
183
+ if (!this._nCache.has(namespace)) {
184
+ this._nCache.set(namespace, new CacheableMemory(this.opts));
185
+ }
186
+ return this._nCache.get(namespace);
187
+ }
188
+ };
189
+ function createKeyv(options) {
190
+ const store = new KeyvCacheableMemory(options);
191
+ const namespace = options?.namespace;
192
+ let ttl;
193
+ if (options?.ttl && Number.isInteger(options.ttl)) {
194
+ ttl = options?.ttl;
195
+ }
196
+ const keyv = new import_keyv.Keyv({ store, namespace, ttl });
197
+ keyv.serialize = void 0;
198
+ keyv.deserialize = void 0;
199
+ return keyv;
200
+ }
201
+
202
+ // src/index.ts
203
+ var defaultStoreHashSize = 16;
204
+ var maximumMapSize = 16777216;
205
+ var CacheableMemory = class extends import_hookified.Hookified {
206
+ _lru = new DoublyLinkedList();
207
+ _storeHashSize = defaultStoreHashSize;
208
+ _storeHashAlgorithm = import_utils.HashAlgorithm.DJB2;
209
+ // Default is djb2Hash
210
+ _store = Array.from(
211
+ { length: this._storeHashSize },
212
+ () => /* @__PURE__ */ new Map()
213
+ );
214
+ _ttl;
215
+ // Turned off by default
216
+ _useClone = true;
217
+ // Turned on by default
218
+ _lruSize = 0;
219
+ // Turned off by default
220
+ _checkInterval = 0;
221
+ // Turned off by default
222
+ _interval = 0;
223
+ // Turned off by default
224
+ /**
225
+ * @constructor
226
+ * @param {CacheableMemoryOptions} [options] - The options for the CacheableMemory
227
+ */
228
+ constructor(options) {
229
+ super();
230
+ if (options?.ttl) {
231
+ this.setTtl(options.ttl);
232
+ }
233
+ if (options?.useClone !== void 0) {
234
+ this._useClone = options.useClone;
235
+ }
236
+ if (options?.storeHashSize && options.storeHashSize > 0) {
237
+ this._storeHashSize = options.storeHashSize;
238
+ }
239
+ if (options?.lruSize) {
240
+ if (options.lruSize > maximumMapSize) {
241
+ this.emit(
242
+ "error",
243
+ new Error(
244
+ `LRU size cannot be larger than ${maximumMapSize} due to Map limitations.`
245
+ )
246
+ );
247
+ } else {
248
+ this._lruSize = options.lruSize;
249
+ }
250
+ }
251
+ if (options?.checkInterval) {
252
+ this._checkInterval = options.checkInterval;
253
+ }
254
+ if (options?.storeHashAlgorithm) {
255
+ this._storeHashAlgorithm = options.storeHashAlgorithm;
256
+ }
257
+ this._store = Array.from(
258
+ { length: this._storeHashSize },
259
+ () => /* @__PURE__ */ new Map()
260
+ );
261
+ this.startIntervalCheck();
262
+ }
263
+ /**
264
+ * Gets the time-to-live
265
+ * @returns {number|string|undefined} - The time-to-live in miliseconds or a human-readable format. If undefined, it will not have a time-to-live.
266
+ */
267
+ get ttl() {
268
+ return this._ttl;
269
+ }
270
+ /**
271
+ * Sets the time-to-live
272
+ * @param {number|string|undefined} value - The time-to-live in miliseconds or a human-readable format (example '1s' = 1 second, '1h' = 1 hour). If undefined, it will not have a time-to-live.
273
+ */
274
+ set ttl(value) {
275
+ this.setTtl(value);
276
+ }
277
+ /**
278
+ * Gets whether to use clone
279
+ * @returns {boolean} - If true, it will clone the value before returning it. If false, it will return the value directly. Default is true.
280
+ */
281
+ get useClone() {
282
+ return this._useClone;
283
+ }
284
+ /**
285
+ * Sets whether to use clone
286
+ * @param {boolean} value - If true, it will clone the value before returning it. If false, it will return the value directly. Default is true.
287
+ */
288
+ set useClone(value) {
289
+ this._useClone = value;
290
+ }
291
+ /**
292
+ * Gets the size of the LRU cache
293
+ * @returns {number} - The size of the LRU cache. If set to 0, it will not use LRU cache. Default is 0. If you are using LRU then the limit is based on Map() size 17mm.
294
+ */
295
+ get lruSize() {
296
+ return this._lruSize;
297
+ }
298
+ /**
299
+ * Sets the size of the LRU cache
300
+ * @param {number} value - The size of the LRU cache. If set to 0, it will not use LRU cache. Default is 0. If you are using LRU then the limit is based on Map() size 17mm.
301
+ */
302
+ set lruSize(value) {
303
+ if (value > maximumMapSize) {
304
+ this.emit(
305
+ "error",
306
+ new Error(
307
+ `LRU size cannot be larger than ${maximumMapSize} due to Map limitations.`
308
+ )
309
+ );
310
+ return;
311
+ }
312
+ this._lruSize = value;
313
+ if (this._lruSize === 0) {
314
+ this._lru = new DoublyLinkedList();
315
+ return;
316
+ }
317
+ this.lruResize();
318
+ }
319
+ /**
320
+ * Gets the check interval
321
+ * @returns {number} - The interval to check for expired items. If set to 0, it will not check for expired items. Default is 0.
322
+ */
323
+ get checkInterval() {
324
+ return this._checkInterval;
325
+ }
326
+ /**
327
+ * Sets the check interval
328
+ * @param {number} value - The interval to check for expired items. If set to 0, it will not check for expired items. Default is 0.
329
+ */
330
+ set checkInterval(value) {
331
+ this._checkInterval = value;
332
+ }
333
+ /**
334
+ * Gets the size of the cache
335
+ * @returns {number} - The size of the cache
336
+ */
337
+ get size() {
338
+ let size = 0;
339
+ for (const store of this._store) {
340
+ size += store.size;
341
+ }
342
+ return size;
343
+ }
344
+ /**
345
+ * Gets the number of hash stores
346
+ * @returns {number} - The number of hash stores
347
+ */
348
+ get storeHashSize() {
349
+ return this._storeHashSize;
350
+ }
351
+ /**
352
+ * Sets the number of hash stores. This will recreate the store and all data will be cleared
353
+ * @param {number} value - The number of hash stores
354
+ */
355
+ set storeHashSize(value) {
356
+ if (value === this._storeHashSize) {
357
+ return;
358
+ }
359
+ this._storeHashSize = value;
360
+ this._store = Array.from(
361
+ { length: this._storeHashSize },
362
+ () => /* @__PURE__ */ new Map()
363
+ );
364
+ }
365
+ /**
366
+ * Gets the store hash algorithm
367
+ * @returns {HashAlgorithm | StoreHashAlgorithmFunction} - The store hash algorithm
368
+ */
369
+ get storeHashAlgorithm() {
370
+ return this._storeHashAlgorithm;
371
+ }
372
+ /**
373
+ * Sets the store hash algorithm. This will recreate the store and all data will be cleared
374
+ * @param {HashAlgorithm | HashAlgorithmFunction} value - The store hash algorithm
375
+ */
376
+ set storeHashAlgorithm(value) {
377
+ this._storeHashAlgorithm = value;
378
+ }
379
+ /**
380
+ * Gets the keys
381
+ * @returns {IterableIterator<string>} - The keys
382
+ */
383
+ get keys() {
384
+ const keys = [];
385
+ for (const store of this._store) {
386
+ for (const key of store.keys()) {
387
+ const item = store.get(key);
388
+ if (item && this.hasExpired(item)) {
389
+ store.delete(key);
390
+ continue;
391
+ }
392
+ keys.push(key);
393
+ }
394
+ }
395
+ return keys.values();
396
+ }
397
+ /**
398
+ * Gets the items
399
+ * @returns {IterableIterator<CacheableStoreItem>} - The items
400
+ */
401
+ get items() {
402
+ const items = [];
403
+ for (const store of this._store) {
404
+ for (const item of store.values()) {
405
+ if (this.hasExpired(item)) {
406
+ store.delete(item.key);
407
+ continue;
408
+ }
409
+ items.push(item);
410
+ }
411
+ }
412
+ return items.values();
413
+ }
414
+ /**
415
+ * Gets the store
416
+ * @returns {Array<Map<string, CacheableStoreItem>>} - The store
417
+ */
418
+ get store() {
419
+ return this._store;
420
+ }
421
+ /**
422
+ * Gets the value of the key
423
+ * @param {string} key - The key to get the value
424
+ * @returns {T | undefined} - The value of the key
425
+ */
426
+ get(key) {
427
+ const store = this.getStore(key);
428
+ const item = store.get(key);
429
+ if (!item) {
430
+ return void 0;
431
+ }
432
+ if (item.expires && Date.now() > item.expires) {
433
+ store.delete(key);
434
+ return void 0;
435
+ }
436
+ this.lruMoveToFront(key);
437
+ if (!this._useClone) {
438
+ return item.value;
439
+ }
440
+ return this.clone(item.value);
441
+ }
442
+ /**
443
+ * Gets the values of the keys
444
+ * @param {string[]} keys - The keys to get the values
445
+ * @returns {T[]} - The values of the keys
446
+ */
447
+ getMany(keys) {
448
+ const result = [];
449
+ for (const key of keys) {
450
+ result.push(this.get(key));
451
+ }
452
+ return result;
453
+ }
454
+ /**
455
+ * Gets the raw value of the key
456
+ * @param {string} key - The key to get the value
457
+ * @returns {CacheableStoreItem | undefined} - The raw value of the key
458
+ */
459
+ getRaw(key) {
460
+ const store = this.getStore(key);
461
+ const item = store.get(key);
462
+ if (!item) {
463
+ return void 0;
464
+ }
465
+ if (item.expires && item.expires && Date.now() > item.expires) {
466
+ store.delete(key);
467
+ return void 0;
468
+ }
469
+ this.lruMoveToFront(key);
470
+ return item;
471
+ }
472
+ /**
473
+ * Gets the raw values of the keys
474
+ * @param {string[]} keys - The keys to get the values
475
+ * @returns {CacheableStoreItem[]} - The raw values of the keys
476
+ */
477
+ getManyRaw(keys) {
478
+ const result = [];
479
+ for (const key of keys) {
480
+ result.push(this.getRaw(key));
481
+ }
482
+ return result;
483
+ }
484
+ /**
485
+ * Sets the value of the key
486
+ * @param {string} key - The key to set the value
487
+ * @param {any} value - The value to set
488
+ * @param {number|string|SetOptions} [ttl] - Time to Live - If you set a number it is miliseconds, if you set a string it is a human-readable.
489
+ * If you want to set expire directly you can do that by setting the expire property in the SetOptions.
490
+ * If you set undefined, it will use the default time-to-live. If both are undefined then it will not have a time-to-live.
491
+ * @returns {void}
492
+ */
493
+ set(key, value, ttl) {
494
+ const store = this.getStore(key);
495
+ let expires;
496
+ if (ttl !== void 0 || this._ttl !== void 0) {
497
+ if (typeof ttl === "object") {
498
+ if (ttl.expire) {
499
+ expires = typeof ttl.expire === "number" ? ttl.expire : ttl.expire.getTime();
500
+ }
501
+ if (ttl.ttl) {
502
+ const finalTtl = (0, import_utils.shorthandToTime)(ttl.ttl);
503
+ if (finalTtl !== void 0) {
504
+ expires = finalTtl;
505
+ }
506
+ }
507
+ } else {
508
+ const finalTtl = (0, import_utils.shorthandToTime)(ttl ?? this._ttl);
509
+ if (finalTtl !== void 0) {
510
+ expires = finalTtl;
511
+ }
512
+ }
513
+ }
514
+ if (this._lruSize > 0) {
515
+ if (store.has(key)) {
516
+ this.lruMoveToFront(key);
517
+ } else {
518
+ this.lruAddToFront(key);
519
+ if (this._lru.size > this._lruSize) {
520
+ const oldestKey = this._lru.getOldest();
521
+ if (oldestKey) {
522
+ this._lru.removeOldest();
523
+ this.delete(oldestKey);
524
+ }
525
+ }
526
+ }
527
+ }
528
+ const item = { key, value, expires };
529
+ store.set(key, item);
530
+ }
531
+ /**
532
+ * Sets the values of the keys
533
+ * @param {CacheableItem[]} items - The items to set
534
+ * @returns {void}
535
+ */
536
+ setMany(items) {
537
+ for (const item of items) {
538
+ this.set(item.key, item.value, item.ttl);
539
+ }
540
+ }
541
+ /**
542
+ * Checks if the key exists
543
+ * @param {string} key - The key to check
544
+ * @returns {boolean} - If true, the key exists. If false, the key does not exist.
545
+ */
546
+ has(key) {
547
+ const item = this.get(key);
548
+ return Boolean(item);
549
+ }
550
+ /**
551
+ * @function hasMany
552
+ * @param {string[]} keys - The keys to check
553
+ * @returns {boolean[]} - If true, the key exists. If false, the key does not exist.
554
+ */
555
+ hasMany(keys) {
556
+ const result = [];
557
+ for (const key of keys) {
558
+ const item = this.get(key);
559
+ result.push(Boolean(item));
560
+ }
561
+ return result;
562
+ }
563
+ /**
564
+ * Take will get the key and delete the entry from cache
565
+ * @param {string} key - The key to take
566
+ * @returns {T | undefined} - The value of the key
567
+ */
568
+ take(key) {
569
+ const item = this.get(key);
570
+ if (!item) {
571
+ return void 0;
572
+ }
573
+ this.delete(key);
574
+ return item;
575
+ }
576
+ /**
577
+ * TakeMany will get the keys and delete the entries from cache
578
+ * @param {string[]} keys - The keys to take
579
+ * @returns {T[]} - The values of the keys
580
+ */
581
+ takeMany(keys) {
582
+ const result = [];
583
+ for (const key of keys) {
584
+ result.push(this.take(key));
585
+ }
586
+ return result;
587
+ }
588
+ /**
589
+ * Delete the key
590
+ * @param {string} key - The key to delete
591
+ * @returns {void}
592
+ */
593
+ delete(key) {
594
+ const store = this.getStore(key);
595
+ store.delete(key);
596
+ }
597
+ /**
598
+ * Delete the keys
599
+ * @param {string[]} keys - The keys to delete
600
+ * @returns {void}
601
+ */
602
+ deleteMany(keys) {
603
+ for (const key of keys) {
604
+ this.delete(key);
605
+ }
606
+ }
607
+ /**
608
+ * Clear the cache
609
+ * @returns {void}
610
+ */
611
+ clear() {
612
+ this._store = Array.from(
613
+ { length: this._storeHashSize },
614
+ () => /* @__PURE__ */ new Map()
615
+ );
616
+ this._lru = new DoublyLinkedList();
617
+ }
618
+ /**
619
+ * Get the store based on the key (internal use)
620
+ * @param {string} key - The key to get the store
621
+ * @returns {CacheableHashStore} - The store
622
+ */
623
+ getStore(key) {
624
+ const hash2 = this.getKeyStoreHash(key);
625
+ this._store[hash2] ||= /* @__PURE__ */ new Map();
626
+ return this._store[hash2];
627
+ }
628
+ /**
629
+ * Hash the key for which store to go to (internal use)
630
+ * @param {string} key - The key to hash
631
+ * Available algorithms are: SHA256, SHA1, MD5, and djb2Hash.
632
+ * @returns {number} - The hashed key as a number
633
+ */
634
+ getKeyStoreHash(key) {
635
+ if (this._store.length === 1) {
636
+ return 0;
637
+ }
638
+ if (typeof this._storeHashAlgorithm === "function") {
639
+ return this._storeHashAlgorithm(key, this._storeHashSize);
640
+ }
641
+ const storeHashSize = this._storeHashSize - 1;
642
+ const hash2 = (0, import_utils.hashToNumberSync)(key, {
643
+ min: 0,
644
+ max: storeHashSize,
645
+ algorithm: this._storeHashAlgorithm
646
+ });
647
+ return hash2;
648
+ }
649
+ /**
650
+ * Clone the value. This is for internal use
651
+ * @param {any} value - The value to clone
652
+ * @returns {any} - The cloned value
653
+ */
654
+ // biome-ignore lint/suspicious/noExplicitAny: type format
655
+ clone(value) {
656
+ if (this.isPrimitive(value)) {
657
+ return value;
658
+ }
659
+ return structuredClone(value);
660
+ }
661
+ /**
662
+ * Add to the front of the LRU cache. This is for internal use
663
+ * @param {string} key - The key to add to the front
664
+ * @returns {void}
665
+ */
666
+ lruAddToFront(key) {
667
+ if (this._lruSize === 0) {
668
+ return;
669
+ }
670
+ this._lru.addToFront(key);
671
+ }
672
+ /**
673
+ * Move to the front of the LRU cache. This is for internal use
674
+ * @param {string} key - The key to move to the front
675
+ * @returns {void}
676
+ */
677
+ lruMoveToFront(key) {
678
+ if (this._lruSize === 0) {
679
+ return;
680
+ }
681
+ this._lru.moveToFront(key);
682
+ }
683
+ /**
684
+ * Resize the LRU cache. This is for internal use.
685
+ * @returns {void}
686
+ */
687
+ lruResize() {
688
+ while (this._lru.size > this._lruSize) {
689
+ const oldestKey = this._lru.getOldest();
690
+ if (oldestKey) {
691
+ this._lru.removeOldest();
692
+ this.delete(oldestKey);
693
+ }
694
+ }
695
+ }
696
+ /**
697
+ * Check for expiration. This is for internal use
698
+ * @returns {void}
699
+ */
700
+ checkExpiration() {
701
+ for (const store of this._store) {
702
+ for (const item of store.values()) {
703
+ if (item.expires && Date.now() > item.expires) {
704
+ store.delete(item.key);
705
+ }
706
+ }
707
+ }
708
+ }
709
+ /**
710
+ * Start the interval check. This is for internal use
711
+ * @returns {void}
712
+ */
713
+ startIntervalCheck() {
714
+ if (this._checkInterval > 0) {
715
+ if (this._interval) {
716
+ clearInterval(this._interval);
717
+ }
718
+ this._interval = setInterval(() => {
719
+ this.checkExpiration();
720
+ }, this._checkInterval).unref();
721
+ }
722
+ }
723
+ /**
724
+ * Stop the interval check. This is for internal use
725
+ * @returns {void}
726
+ */
727
+ stopIntervalCheck() {
728
+ if (this._interval) {
729
+ clearInterval(this._interval);
730
+ }
731
+ this._interval = 0;
732
+ this._checkInterval = 0;
733
+ }
734
+ /**
735
+ * Wrap the function for caching
736
+ * @param {Function} function_ - The function to wrap
737
+ * @param {Object} [options] - The options to wrap
738
+ * @returns {Function} - The wrapped function
739
+ */
740
+ // biome-ignore lint/suspicious/noExplicitAny: type format
741
+ wrap(function_, options) {
742
+ const wrapOptions = {
743
+ ttl: options?.ttl ?? this._ttl,
744
+ keyPrefix: options?.keyPrefix,
745
+ createKey: options?.createKey,
746
+ cache: this
747
+ };
748
+ return (0, import_utils.wrapSync)(function_, wrapOptions);
749
+ }
750
+ // biome-ignore lint/suspicious/noExplicitAny: type format
751
+ isPrimitive(value) {
752
+ const result = false;
753
+ if (value === null || value === void 0) {
754
+ return true;
755
+ }
756
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
757
+ return true;
758
+ }
759
+ return result;
760
+ }
761
+ setTtl(ttl) {
762
+ if (typeof ttl === "string" || ttl === void 0) {
763
+ this._ttl = ttl;
764
+ } else if (ttl > 0) {
765
+ this._ttl = ttl;
766
+ } else {
767
+ this._ttl = void 0;
768
+ }
769
+ }
770
+ hasExpired(item) {
771
+ if (item.expires && Date.now() > item.expires) {
772
+ return true;
773
+ }
774
+ return false;
775
+ }
776
+ };
777
+ // Annotate the CommonJS export names for ESM import in node:
778
+ 0 && (module.exports = {
779
+ CacheableMemory,
780
+ HashAlgorithm,
781
+ KeyvCacheableMemory,
782
+ createKeyv,
783
+ defaultStoreHashSize,
784
+ hash,
785
+ hashToNumber,
786
+ maximumMapSize
787
+ });
788
+ /* v8 ignore next -- @preserve */