cacheable 1.3.0 → 1.6.0
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 +20 -9
- package/dist/index.cjs +274 -178
- package/dist/index.d.cts +25 -2
- package/dist/index.d.ts +25 -2
- package/dist/index.js +272 -177
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
[](https://www.npmjs.com/package/cacheable)
|
|
10
10
|
[](https://www.npmjs.com/package/cacheable)
|
|
11
11
|
|
|
12
|
-
`cacheable` is a high performance layer 1 / layer 2 caching engine that is focused on distributed caching with enterprise features such as `CacheSync
|
|
12
|
+
`cacheable` is a high performance layer 1 / layer 2 caching engine that is focused on distributed caching with enterprise features such as `CacheSync` (coming soon). It is built on top of the robust storage engine [Keyv](https://keyv.org) and provides a simple API to cache and retrieve data.
|
|
13
13
|
|
|
14
14
|
* Simple to use with robust API
|
|
15
15
|
* Not bloated with additional modules
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
## Getting Started
|
|
27
27
|
|
|
28
|
-
`cacheable` is primarily used as an extension to you caching engine with a robust storage backend [Keyv](https://keyv.org), Memonization, Hooks, Events, and Statistics.
|
|
28
|
+
`cacheable` is primarily used as an extension to you caching engine with a robust storage backend [Keyv](https://keyv.org), Memonization (Wrap), Hooks, Events, and Statistics.
|
|
29
29
|
|
|
30
30
|
```bash
|
|
31
31
|
npm install cacheable
|
|
@@ -115,7 +115,6 @@ const cache = new Cacheable({secondary, nonBlocking: true});
|
|
|
115
115
|
|
|
116
116
|
`cacheable` has a feature called `CacheSync` that is coming soon. This feature will allow you to have distributed caching with Pub/Sub. This will allow you to have multiple instances of `cacheable` running and when a value is set, deleted, or cleared it will update all instances of `cacheable` with the same value. Current plan is to support the following:
|
|
117
117
|
|
|
118
|
-
* [Google Pub/Sub](https://cloud.google.com/pubsub)
|
|
119
118
|
* [AWS SQS](https://aws.amazon.com/sqs)
|
|
120
119
|
* [RabbitMQ](https://www.rabbitmq.com)
|
|
121
120
|
* [Nats](https://nats.io)
|
|
@@ -153,15 +152,15 @@ _This does not enable statistics for your layer 2 cache as that is a distributed
|
|
|
153
152
|
|
|
154
153
|
## API
|
|
155
154
|
|
|
156
|
-
* `set(key, value, ttl?
|
|
155
|
+
* `set(key, value, ttl?)`: Sets a value in the cache.
|
|
157
156
|
* `setMany([{key, value, ttl?}])`: Sets multiple values in the cache.
|
|
158
|
-
* `get(key
|
|
157
|
+
* `get(key)`: Gets a value from the cache.
|
|
159
158
|
* `getMany([keys])`: Gets multiple values from the cache.
|
|
160
|
-
* `has(key
|
|
159
|
+
* `has(key)`: Checks if a value exists in the cache.
|
|
161
160
|
* `hasMany([keys])`: Checks if multiple values exist in the cache.
|
|
162
161
|
* `take(key)`: Takes a value from the cache and deletes it.
|
|
163
162
|
* `takeMany([keys])`: Takes multiple values from the cache and deletes them.
|
|
164
|
-
* `delete(key
|
|
163
|
+
* `delete(key)`: Deletes a value from the cache.
|
|
165
164
|
* `deleteMany([keys])`: Deletes multiple values from the cache.
|
|
166
165
|
* `clear()`: Clears the cache stores. Be careful with this as it will clear both layer 1 and layer 2.
|
|
167
166
|
* `wrap(function, options)`: Wraps a function in a cache. (coming soon)
|
|
@@ -187,14 +186,23 @@ const options = {
|
|
|
187
186
|
lruSize: 1000, // the size of the LRU cache (default is 0 which is unlimited)
|
|
188
187
|
}
|
|
189
188
|
const cache = new CacheableMemory(options);
|
|
190
|
-
|
|
191
|
-
const value =
|
|
189
|
+
cache.set('key', 'value');
|
|
190
|
+
const value = cache.get('key'); // value
|
|
192
191
|
```
|
|
193
192
|
|
|
194
193
|
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.
|
|
195
194
|
|
|
196
195
|
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.
|
|
197
196
|
|
|
197
|
+
By default we use lazy expiration deletion which means on `get` and `getMany` type functions we look if it is expired and then delete it. If you want to have a more aggressive expiration policy you can set the `checkInterval` property to a value greater than `0` which will check for expired keys at the interval you set.
|
|
198
|
+
|
|
199
|
+
### CacheableMemory Options
|
|
200
|
+
|
|
201
|
+
* `ttl`: The time to live for the cache in milliseconds.
|
|
202
|
+
* `useClones`: If the cache should use clones for the values. Default is `true`.
|
|
203
|
+
* `lruSize`: The size of the LRU cache. Default is `0` which is unlimited.
|
|
204
|
+
* `checkInterval`: The interval to check for expired keys in milliseconds. Default is `0` which is disabled.
|
|
205
|
+
|
|
198
206
|
### CacheableMemory API
|
|
199
207
|
|
|
200
208
|
* `set(key, value, ttl?)`: Sets a value in the cache.
|
|
@@ -204,6 +212,9 @@ This simple in-memory cache uses multiple Map objects and a with `expiration` an
|
|
|
204
212
|
* `clear()`: Clears the cache.
|
|
205
213
|
* `size()`: The number of keys in the cache.
|
|
206
214
|
* `keys()`: The keys in the cache.
|
|
215
|
+
* `checkExpired()`: Checks for expired keys in the cache. This is used by the `checkInterval` property.
|
|
216
|
+
* `startIntervalCheck()`: Starts the interval check for expired keys if `checkInterval` is above 0 ms.
|
|
217
|
+
* `stopIntervalCheck()`: Stops the interval check for expired keys.
|
|
207
218
|
|
|
208
219
|
|
|
209
220
|
## How to Contribute
|
package/dist/index.cjs
CHANGED
|
@@ -24,187 +24,13 @@ __export(src_exports, {
|
|
|
24
24
|
CacheableEvents: () => CacheableEvents,
|
|
25
25
|
CacheableHooks: () => CacheableHooks,
|
|
26
26
|
CacheableMemory: () => CacheableMemory,
|
|
27
|
-
CacheableStats: () => CacheableStats
|
|
27
|
+
CacheableStats: () => CacheableStats,
|
|
28
|
+
KeyvCacheableMemory: () => KeyvCacheableMemory
|
|
28
29
|
});
|
|
29
30
|
module.exports = __toCommonJS(src_exports);
|
|
30
31
|
var import_keyv = require("keyv");
|
|
31
32
|
var import_hookified = require("hookified");
|
|
32
33
|
|
|
33
|
-
// src/stats.ts
|
|
34
|
-
var CacheableStats = class {
|
|
35
|
-
_hits = 0;
|
|
36
|
-
_misses = 0;
|
|
37
|
-
_gets = 0;
|
|
38
|
-
_sets = 0;
|
|
39
|
-
_deletes = 0;
|
|
40
|
-
_clears = 0;
|
|
41
|
-
_vsize = 0;
|
|
42
|
-
_ksize = 0;
|
|
43
|
-
_count = 0;
|
|
44
|
-
_enabled = false;
|
|
45
|
-
constructor(options) {
|
|
46
|
-
if (options?.enabled) {
|
|
47
|
-
this._enabled = options.enabled;
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
get enabled() {
|
|
51
|
-
return this._enabled;
|
|
52
|
-
}
|
|
53
|
-
set enabled(enabled) {
|
|
54
|
-
this._enabled = enabled;
|
|
55
|
-
}
|
|
56
|
-
get hits() {
|
|
57
|
-
return this._hits;
|
|
58
|
-
}
|
|
59
|
-
get misses() {
|
|
60
|
-
return this._misses;
|
|
61
|
-
}
|
|
62
|
-
get gets() {
|
|
63
|
-
return this._gets;
|
|
64
|
-
}
|
|
65
|
-
get sets() {
|
|
66
|
-
return this._sets;
|
|
67
|
-
}
|
|
68
|
-
get deletes() {
|
|
69
|
-
return this._deletes;
|
|
70
|
-
}
|
|
71
|
-
get clears() {
|
|
72
|
-
return this._clears;
|
|
73
|
-
}
|
|
74
|
-
get vsize() {
|
|
75
|
-
return this._vsize;
|
|
76
|
-
}
|
|
77
|
-
get ksize() {
|
|
78
|
-
return this._ksize;
|
|
79
|
-
}
|
|
80
|
-
get count() {
|
|
81
|
-
return this._count;
|
|
82
|
-
}
|
|
83
|
-
incrementHits() {
|
|
84
|
-
if (!this._enabled) {
|
|
85
|
-
return;
|
|
86
|
-
}
|
|
87
|
-
this._hits++;
|
|
88
|
-
}
|
|
89
|
-
incrementMisses() {
|
|
90
|
-
if (!this._enabled) {
|
|
91
|
-
return;
|
|
92
|
-
}
|
|
93
|
-
this._misses++;
|
|
94
|
-
}
|
|
95
|
-
incrementGets() {
|
|
96
|
-
if (!this._enabled) {
|
|
97
|
-
return;
|
|
98
|
-
}
|
|
99
|
-
this._gets++;
|
|
100
|
-
}
|
|
101
|
-
incrementSets() {
|
|
102
|
-
if (!this._enabled) {
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
this._sets++;
|
|
106
|
-
}
|
|
107
|
-
incrementDeletes() {
|
|
108
|
-
if (!this._enabled) {
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
this._deletes++;
|
|
112
|
-
}
|
|
113
|
-
incrementClears() {
|
|
114
|
-
if (!this._enabled) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
this._clears++;
|
|
118
|
-
}
|
|
119
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
120
|
-
incrementVSize(value) {
|
|
121
|
-
if (!this._enabled) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
this._vsize += this.roughSizeOfObject(value);
|
|
125
|
-
}
|
|
126
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
127
|
-
decreaseVSize(value) {
|
|
128
|
-
if (!this._enabled) {
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
this._vsize -= this.roughSizeOfObject(value);
|
|
132
|
-
}
|
|
133
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
134
|
-
incrementKSize(key) {
|
|
135
|
-
if (!this._enabled) {
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
this._ksize += this.roughSizeOfString(key);
|
|
139
|
-
}
|
|
140
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
141
|
-
decreaseKSize(key) {
|
|
142
|
-
if (!this._enabled) {
|
|
143
|
-
return;
|
|
144
|
-
}
|
|
145
|
-
this._ksize -= this.roughSizeOfString(key);
|
|
146
|
-
}
|
|
147
|
-
incrementCount() {
|
|
148
|
-
if (!this._enabled) {
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
this._count++;
|
|
152
|
-
}
|
|
153
|
-
decreaseCount() {
|
|
154
|
-
if (!this._enabled) {
|
|
155
|
-
return;
|
|
156
|
-
}
|
|
157
|
-
this._count--;
|
|
158
|
-
}
|
|
159
|
-
setCount(count) {
|
|
160
|
-
if (!this._enabled) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
this._count = count;
|
|
164
|
-
}
|
|
165
|
-
roughSizeOfString(value) {
|
|
166
|
-
return value.length * 2;
|
|
167
|
-
}
|
|
168
|
-
roughSizeOfObject(object) {
|
|
169
|
-
const objectList = [];
|
|
170
|
-
const stack = [object];
|
|
171
|
-
let bytes = 0;
|
|
172
|
-
while (stack.length > 0) {
|
|
173
|
-
const value = stack.pop();
|
|
174
|
-
if (typeof value === "boolean") {
|
|
175
|
-
bytes += 4;
|
|
176
|
-
} else if (typeof value === "string") {
|
|
177
|
-
bytes += value.length * 2;
|
|
178
|
-
} else if (typeof value === "number") {
|
|
179
|
-
bytes += 8;
|
|
180
|
-
} else if (typeof value === "object" && value !== null && !objectList.includes(value)) {
|
|
181
|
-
objectList.push(value);
|
|
182
|
-
for (const key in value) {
|
|
183
|
-
bytes += key.length * 2;
|
|
184
|
-
stack.push(value[key]);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
return bytes;
|
|
189
|
-
}
|
|
190
|
-
reset() {
|
|
191
|
-
this._hits = 0;
|
|
192
|
-
this._misses = 0;
|
|
193
|
-
this._gets = 0;
|
|
194
|
-
this._sets = 0;
|
|
195
|
-
this._deletes = 0;
|
|
196
|
-
this._clears = 0;
|
|
197
|
-
this._vsize = 0;
|
|
198
|
-
this._ksize = 0;
|
|
199
|
-
this._count = 0;
|
|
200
|
-
}
|
|
201
|
-
resetStoreValues() {
|
|
202
|
-
this._vsize = 0;
|
|
203
|
-
this._ksize = 0;
|
|
204
|
-
this._count = 0;
|
|
205
|
-
}
|
|
206
|
-
};
|
|
207
|
-
|
|
208
34
|
// src/memory-lru.ts
|
|
209
35
|
var ListNode = class {
|
|
210
36
|
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
|
@@ -293,8 +119,15 @@ var CacheableMemory = class {
|
|
|
293
119
|
_hash9 = /* @__PURE__ */ new Map();
|
|
294
120
|
_lru = new DoublyLinkedList();
|
|
295
121
|
_ttl = 0;
|
|
122
|
+
// Turned off by default
|
|
296
123
|
_useClone = true;
|
|
124
|
+
// Turned on by default
|
|
297
125
|
_lruSize = 0;
|
|
126
|
+
// Turned off by default
|
|
127
|
+
_checkInterval = 0;
|
|
128
|
+
// Turned off by default
|
|
129
|
+
_interval = 0;
|
|
130
|
+
// Turned off by default
|
|
298
131
|
constructor(options) {
|
|
299
132
|
if (options?.ttl) {
|
|
300
133
|
this._ttl = options.ttl;
|
|
@@ -305,6 +138,10 @@ var CacheableMemory = class {
|
|
|
305
138
|
if (options?.lruSize) {
|
|
306
139
|
this._lruSize = options.lruSize;
|
|
307
140
|
}
|
|
141
|
+
if (options?.checkInterval) {
|
|
142
|
+
this._checkInterval = options.checkInterval;
|
|
143
|
+
}
|
|
144
|
+
this.startIntervalCheck();
|
|
308
145
|
}
|
|
309
146
|
get ttl() {
|
|
310
147
|
return this._ttl;
|
|
@@ -325,6 +162,12 @@ var CacheableMemory = class {
|
|
|
325
162
|
this._lruSize = value;
|
|
326
163
|
this.lruResize();
|
|
327
164
|
}
|
|
165
|
+
get checkInterval() {
|
|
166
|
+
return this._checkInterval;
|
|
167
|
+
}
|
|
168
|
+
set checkInterval(value) {
|
|
169
|
+
this._checkInterval = value;
|
|
170
|
+
}
|
|
328
171
|
get size() {
|
|
329
172
|
return this._hash0.size + this._hash1.size + this._hash2.size + this._hash3.size + this._hash4.size + this._hash5.size + this._hash6.size + this._hash7.size + this._hash8.size + this._hash9.size;
|
|
330
173
|
}
|
|
@@ -482,6 +325,28 @@ var CacheableMemory = class {
|
|
|
482
325
|
}
|
|
483
326
|
}
|
|
484
327
|
}
|
|
328
|
+
checkExpiration() {
|
|
329
|
+
const stores = this.concatStores();
|
|
330
|
+
for (const item of stores.values()) {
|
|
331
|
+
if (item.expires && Date.now() > item.expires) {
|
|
332
|
+
this.delete(item.key);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
startIntervalCheck() {
|
|
337
|
+
if (this._checkInterval > 0) {
|
|
338
|
+
this._interval = setInterval(() => {
|
|
339
|
+
this.checkExpiration();
|
|
340
|
+
}, this._checkInterval);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
stopIntervalCheck() {
|
|
344
|
+
if (this._interval) {
|
|
345
|
+
clearInterval(this._interval);
|
|
346
|
+
}
|
|
347
|
+
this._interval = 0;
|
|
348
|
+
this._checkInterval = 0;
|
|
349
|
+
}
|
|
485
350
|
isPrimitive(value) {
|
|
486
351
|
const result = false;
|
|
487
352
|
if (value === null || value === void 0) {
|
|
@@ -498,6 +363,236 @@ var CacheableMemory = class {
|
|
|
498
363
|
}
|
|
499
364
|
};
|
|
500
365
|
|
|
366
|
+
// src/keyv-memory.ts
|
|
367
|
+
var KeyvCacheableMemory = class {
|
|
368
|
+
opts = {
|
|
369
|
+
ttl: 0,
|
|
370
|
+
useClone: true,
|
|
371
|
+
lruSize: 0,
|
|
372
|
+
checkInterval: 0
|
|
373
|
+
};
|
|
374
|
+
namespace;
|
|
375
|
+
_cache = new CacheableMemory();
|
|
376
|
+
constructor(options) {
|
|
377
|
+
if (options) {
|
|
378
|
+
this.opts = options;
|
|
379
|
+
this._cache = new CacheableMemory(options);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
async get(key) {
|
|
383
|
+
const result = this._cache.get(key);
|
|
384
|
+
console.log("result", result);
|
|
385
|
+
if (result) {
|
|
386
|
+
return result;
|
|
387
|
+
}
|
|
388
|
+
return void 0;
|
|
389
|
+
}
|
|
390
|
+
set(key, value, ttl) {
|
|
391
|
+
this._cache.set(key, value, ttl);
|
|
392
|
+
}
|
|
393
|
+
async delete(key) {
|
|
394
|
+
this._cache.delete(key);
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
async clear() {
|
|
398
|
+
this._cache.clear();
|
|
399
|
+
}
|
|
400
|
+
async has(key) {
|
|
401
|
+
return this._cache.has(key);
|
|
402
|
+
}
|
|
403
|
+
async getMany(keys) {
|
|
404
|
+
const result = [];
|
|
405
|
+
for (const key of keys) {
|
|
406
|
+
result.push(this._cache.get(key));
|
|
407
|
+
}
|
|
408
|
+
return result;
|
|
409
|
+
}
|
|
410
|
+
async deleteMany(key) {
|
|
411
|
+
for (const k of key) {
|
|
412
|
+
this._cache.delete(k);
|
|
413
|
+
}
|
|
414
|
+
return true;
|
|
415
|
+
}
|
|
416
|
+
on(event, listener) {
|
|
417
|
+
return this;
|
|
418
|
+
}
|
|
419
|
+
};
|
|
420
|
+
|
|
421
|
+
// src/stats.ts
|
|
422
|
+
var CacheableStats = class {
|
|
423
|
+
_hits = 0;
|
|
424
|
+
_misses = 0;
|
|
425
|
+
_gets = 0;
|
|
426
|
+
_sets = 0;
|
|
427
|
+
_deletes = 0;
|
|
428
|
+
_clears = 0;
|
|
429
|
+
_vsize = 0;
|
|
430
|
+
_ksize = 0;
|
|
431
|
+
_count = 0;
|
|
432
|
+
_enabled = false;
|
|
433
|
+
constructor(options) {
|
|
434
|
+
if (options?.enabled) {
|
|
435
|
+
this._enabled = options.enabled;
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
get enabled() {
|
|
439
|
+
return this._enabled;
|
|
440
|
+
}
|
|
441
|
+
set enabled(enabled) {
|
|
442
|
+
this._enabled = enabled;
|
|
443
|
+
}
|
|
444
|
+
get hits() {
|
|
445
|
+
return this._hits;
|
|
446
|
+
}
|
|
447
|
+
get misses() {
|
|
448
|
+
return this._misses;
|
|
449
|
+
}
|
|
450
|
+
get gets() {
|
|
451
|
+
return this._gets;
|
|
452
|
+
}
|
|
453
|
+
get sets() {
|
|
454
|
+
return this._sets;
|
|
455
|
+
}
|
|
456
|
+
get deletes() {
|
|
457
|
+
return this._deletes;
|
|
458
|
+
}
|
|
459
|
+
get clears() {
|
|
460
|
+
return this._clears;
|
|
461
|
+
}
|
|
462
|
+
get vsize() {
|
|
463
|
+
return this._vsize;
|
|
464
|
+
}
|
|
465
|
+
get ksize() {
|
|
466
|
+
return this._ksize;
|
|
467
|
+
}
|
|
468
|
+
get count() {
|
|
469
|
+
return this._count;
|
|
470
|
+
}
|
|
471
|
+
incrementHits() {
|
|
472
|
+
if (!this._enabled) {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
this._hits++;
|
|
476
|
+
}
|
|
477
|
+
incrementMisses() {
|
|
478
|
+
if (!this._enabled) {
|
|
479
|
+
return;
|
|
480
|
+
}
|
|
481
|
+
this._misses++;
|
|
482
|
+
}
|
|
483
|
+
incrementGets() {
|
|
484
|
+
if (!this._enabled) {
|
|
485
|
+
return;
|
|
486
|
+
}
|
|
487
|
+
this._gets++;
|
|
488
|
+
}
|
|
489
|
+
incrementSets() {
|
|
490
|
+
if (!this._enabled) {
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
this._sets++;
|
|
494
|
+
}
|
|
495
|
+
incrementDeletes() {
|
|
496
|
+
if (!this._enabled) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
this._deletes++;
|
|
500
|
+
}
|
|
501
|
+
incrementClears() {
|
|
502
|
+
if (!this._enabled) {
|
|
503
|
+
return;
|
|
504
|
+
}
|
|
505
|
+
this._clears++;
|
|
506
|
+
}
|
|
507
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
508
|
+
incrementVSize(value) {
|
|
509
|
+
if (!this._enabled) {
|
|
510
|
+
return;
|
|
511
|
+
}
|
|
512
|
+
this._vsize += this.roughSizeOfObject(value);
|
|
513
|
+
}
|
|
514
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
515
|
+
decreaseVSize(value) {
|
|
516
|
+
if (!this._enabled) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
this._vsize -= this.roughSizeOfObject(value);
|
|
520
|
+
}
|
|
521
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
522
|
+
incrementKSize(key) {
|
|
523
|
+
if (!this._enabled) {
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
this._ksize += this.roughSizeOfString(key);
|
|
527
|
+
}
|
|
528
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
529
|
+
decreaseKSize(key) {
|
|
530
|
+
if (!this._enabled) {
|
|
531
|
+
return;
|
|
532
|
+
}
|
|
533
|
+
this._ksize -= this.roughSizeOfString(key);
|
|
534
|
+
}
|
|
535
|
+
incrementCount() {
|
|
536
|
+
if (!this._enabled) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
this._count++;
|
|
540
|
+
}
|
|
541
|
+
decreaseCount() {
|
|
542
|
+
if (!this._enabled) {
|
|
543
|
+
return;
|
|
544
|
+
}
|
|
545
|
+
this._count--;
|
|
546
|
+
}
|
|
547
|
+
setCount(count) {
|
|
548
|
+
if (!this._enabled) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
this._count = count;
|
|
552
|
+
}
|
|
553
|
+
roughSizeOfString(value) {
|
|
554
|
+
return value.length * 2;
|
|
555
|
+
}
|
|
556
|
+
roughSizeOfObject(object) {
|
|
557
|
+
const objectList = [];
|
|
558
|
+
const stack = [object];
|
|
559
|
+
let bytes = 0;
|
|
560
|
+
while (stack.length > 0) {
|
|
561
|
+
const value = stack.pop();
|
|
562
|
+
if (typeof value === "boolean") {
|
|
563
|
+
bytes += 4;
|
|
564
|
+
} else if (typeof value === "string") {
|
|
565
|
+
bytes += value.length * 2;
|
|
566
|
+
} else if (typeof value === "number") {
|
|
567
|
+
bytes += 8;
|
|
568
|
+
} else if (typeof value === "object" && value !== null && !objectList.includes(value)) {
|
|
569
|
+
objectList.push(value);
|
|
570
|
+
for (const key in value) {
|
|
571
|
+
bytes += key.length * 2;
|
|
572
|
+
stack.push(value[key]);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
return bytes;
|
|
577
|
+
}
|
|
578
|
+
reset() {
|
|
579
|
+
this._hits = 0;
|
|
580
|
+
this._misses = 0;
|
|
581
|
+
this._gets = 0;
|
|
582
|
+
this._sets = 0;
|
|
583
|
+
this._deletes = 0;
|
|
584
|
+
this._clears = 0;
|
|
585
|
+
this._vsize = 0;
|
|
586
|
+
this._ksize = 0;
|
|
587
|
+
this._count = 0;
|
|
588
|
+
}
|
|
589
|
+
resetStoreValues() {
|
|
590
|
+
this._vsize = 0;
|
|
591
|
+
this._ksize = 0;
|
|
592
|
+
this._count = 0;
|
|
593
|
+
}
|
|
594
|
+
};
|
|
595
|
+
|
|
501
596
|
// src/index.ts
|
|
502
597
|
var CacheableHooks = /* @__PURE__ */ ((CacheableHooks2) => {
|
|
503
598
|
CacheableHooks2["BEFORE_SET"] = "BEFORE_SET";
|
|
@@ -515,7 +610,7 @@ var CacheableEvents = /* @__PURE__ */ ((CacheableEvents2) => {
|
|
|
515
610
|
return CacheableEvents2;
|
|
516
611
|
})(CacheableEvents || {});
|
|
517
612
|
var Cacheable = class extends import_hookified.Hookified {
|
|
518
|
-
_primary = new import_keyv.Keyv({ store: new
|
|
613
|
+
_primary = new import_keyv.Keyv({ store: new KeyvCacheableMemory() });
|
|
519
614
|
_secondary;
|
|
520
615
|
_nonBlocking = false;
|
|
521
616
|
_ttl;
|
|
@@ -823,5 +918,6 @@ var Cacheable = class extends import_hookified.Hookified {
|
|
|
823
918
|
CacheableEvents,
|
|
824
919
|
CacheableHooks,
|
|
825
920
|
CacheableMemory,
|
|
826
|
-
CacheableStats
|
|
921
|
+
CacheableStats,
|
|
922
|
+
KeyvCacheableMemory
|
|
827
923
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { KeyvStoreAdapter, StoredData, Keyv } from 'keyv';
|
|
2
2
|
import { Hookified } from 'hookified';
|
|
3
3
|
|
|
4
4
|
type CacheableOptions$1 = {
|
|
@@ -50,6 +50,7 @@ type CacheableMemoryOptions = {
|
|
|
50
50
|
ttl?: number;
|
|
51
51
|
useClone?: boolean;
|
|
52
52
|
lruSize?: number;
|
|
53
|
+
checkInterval?: number;
|
|
53
54
|
};
|
|
54
55
|
declare class CacheableMemory {
|
|
55
56
|
private readonly _hashCache;
|
|
@@ -67,6 +68,8 @@ declare class CacheableMemory {
|
|
|
67
68
|
private _ttl;
|
|
68
69
|
private _useClone;
|
|
69
70
|
private _lruSize;
|
|
71
|
+
private _checkInterval;
|
|
72
|
+
private _interval;
|
|
70
73
|
constructor(options?: CacheableMemoryOptions);
|
|
71
74
|
get ttl(): number;
|
|
72
75
|
set ttl(value: number);
|
|
@@ -74,6 +77,8 @@ declare class CacheableMemory {
|
|
|
74
77
|
set useClone(value: boolean);
|
|
75
78
|
get lruSize(): number;
|
|
76
79
|
set lruSize(value: number);
|
|
80
|
+
get checkInterval(): number;
|
|
81
|
+
set checkInterval(value: number);
|
|
77
82
|
get size(): number;
|
|
78
83
|
get keys(): IterableIterator<string>;
|
|
79
84
|
get<T>(key: string): any;
|
|
@@ -88,10 +93,28 @@ declare class CacheableMemory {
|
|
|
88
93
|
lruAddToFront(key: string): void;
|
|
89
94
|
lruMoveToFront(key: string): void;
|
|
90
95
|
lruResize(): void;
|
|
96
|
+
checkExpiration(): void;
|
|
97
|
+
startIntervalCheck(): void;
|
|
98
|
+
stopIntervalCheck(): void;
|
|
91
99
|
private isPrimitive;
|
|
92
100
|
private concatStores;
|
|
93
101
|
}
|
|
94
102
|
|
|
103
|
+
declare class KeyvCacheableMemory implements KeyvStoreAdapter {
|
|
104
|
+
opts: CacheableMemoryOptions;
|
|
105
|
+
namespace?: string | undefined;
|
|
106
|
+
private readonly _cache;
|
|
107
|
+
constructor(options?: CacheableMemoryOptions);
|
|
108
|
+
get<Value>(key: string): Promise<StoredData<Value> | undefined>;
|
|
109
|
+
set(key: string, value: any, ttl?: number): void;
|
|
110
|
+
delete(key: string): Promise<boolean>;
|
|
111
|
+
clear(): Promise<void>;
|
|
112
|
+
has?(key: string): Promise<boolean>;
|
|
113
|
+
getMany?<Value>(keys: string[]): Promise<Array<StoredData<Value | undefined>>>;
|
|
114
|
+
deleteMany?(key: string[]): Promise<boolean>;
|
|
115
|
+
on(event: string, listener: (...arguments_: any[]) => void): this;
|
|
116
|
+
}
|
|
117
|
+
|
|
95
118
|
declare enum CacheableHooks {
|
|
96
119
|
BEFORE_SET = "BEFORE_SET",
|
|
97
120
|
AFTER_SET = "AFTER_SET",
|
|
@@ -152,4 +175,4 @@ declare class Cacheable extends Hookified {
|
|
|
152
175
|
private hasManyKeyv;
|
|
153
176
|
}
|
|
154
177
|
|
|
155
|
-
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats };
|
|
178
|
+
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { KeyvStoreAdapter, StoredData, Keyv } from 'keyv';
|
|
2
2
|
import { Hookified } from 'hookified';
|
|
3
3
|
|
|
4
4
|
type CacheableOptions$1 = {
|
|
@@ -50,6 +50,7 @@ type CacheableMemoryOptions = {
|
|
|
50
50
|
ttl?: number;
|
|
51
51
|
useClone?: boolean;
|
|
52
52
|
lruSize?: number;
|
|
53
|
+
checkInterval?: number;
|
|
53
54
|
};
|
|
54
55
|
declare class CacheableMemory {
|
|
55
56
|
private readonly _hashCache;
|
|
@@ -67,6 +68,8 @@ declare class CacheableMemory {
|
|
|
67
68
|
private _ttl;
|
|
68
69
|
private _useClone;
|
|
69
70
|
private _lruSize;
|
|
71
|
+
private _checkInterval;
|
|
72
|
+
private _interval;
|
|
70
73
|
constructor(options?: CacheableMemoryOptions);
|
|
71
74
|
get ttl(): number;
|
|
72
75
|
set ttl(value: number);
|
|
@@ -74,6 +77,8 @@ declare class CacheableMemory {
|
|
|
74
77
|
set useClone(value: boolean);
|
|
75
78
|
get lruSize(): number;
|
|
76
79
|
set lruSize(value: number);
|
|
80
|
+
get checkInterval(): number;
|
|
81
|
+
set checkInterval(value: number);
|
|
77
82
|
get size(): number;
|
|
78
83
|
get keys(): IterableIterator<string>;
|
|
79
84
|
get<T>(key: string): any;
|
|
@@ -88,10 +93,28 @@ declare class CacheableMemory {
|
|
|
88
93
|
lruAddToFront(key: string): void;
|
|
89
94
|
lruMoveToFront(key: string): void;
|
|
90
95
|
lruResize(): void;
|
|
96
|
+
checkExpiration(): void;
|
|
97
|
+
startIntervalCheck(): void;
|
|
98
|
+
stopIntervalCheck(): void;
|
|
91
99
|
private isPrimitive;
|
|
92
100
|
private concatStores;
|
|
93
101
|
}
|
|
94
102
|
|
|
103
|
+
declare class KeyvCacheableMemory implements KeyvStoreAdapter {
|
|
104
|
+
opts: CacheableMemoryOptions;
|
|
105
|
+
namespace?: string | undefined;
|
|
106
|
+
private readonly _cache;
|
|
107
|
+
constructor(options?: CacheableMemoryOptions);
|
|
108
|
+
get<Value>(key: string): Promise<StoredData<Value> | undefined>;
|
|
109
|
+
set(key: string, value: any, ttl?: number): void;
|
|
110
|
+
delete(key: string): Promise<boolean>;
|
|
111
|
+
clear(): Promise<void>;
|
|
112
|
+
has?(key: string): Promise<boolean>;
|
|
113
|
+
getMany?<Value>(keys: string[]): Promise<Array<StoredData<Value | undefined>>>;
|
|
114
|
+
deleteMany?(key: string[]): Promise<boolean>;
|
|
115
|
+
on(event: string, listener: (...arguments_: any[]) => void): this;
|
|
116
|
+
}
|
|
117
|
+
|
|
95
118
|
declare enum CacheableHooks {
|
|
96
119
|
BEFORE_SET = "BEFORE_SET",
|
|
97
120
|
AFTER_SET = "AFTER_SET",
|
|
@@ -152,4 +175,4 @@ declare class Cacheable extends Hookified {
|
|
|
152
175
|
private hasManyKeyv;
|
|
153
176
|
}
|
|
154
177
|
|
|
155
|
-
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats };
|
|
178
|
+
export { Cacheable, CacheableEvents, CacheableHooks, type CacheableItem, CacheableMemory, type CacheableOptions, CacheableStats, KeyvCacheableMemory };
|
package/dist/index.js
CHANGED
|
@@ -2,181 +2,6 @@
|
|
|
2
2
|
import { Keyv } from "keyv";
|
|
3
3
|
import { Hookified } from "hookified";
|
|
4
4
|
|
|
5
|
-
// src/stats.ts
|
|
6
|
-
var CacheableStats = class {
|
|
7
|
-
_hits = 0;
|
|
8
|
-
_misses = 0;
|
|
9
|
-
_gets = 0;
|
|
10
|
-
_sets = 0;
|
|
11
|
-
_deletes = 0;
|
|
12
|
-
_clears = 0;
|
|
13
|
-
_vsize = 0;
|
|
14
|
-
_ksize = 0;
|
|
15
|
-
_count = 0;
|
|
16
|
-
_enabled = false;
|
|
17
|
-
constructor(options) {
|
|
18
|
-
if (options?.enabled) {
|
|
19
|
-
this._enabled = options.enabled;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
get enabled() {
|
|
23
|
-
return this._enabled;
|
|
24
|
-
}
|
|
25
|
-
set enabled(enabled) {
|
|
26
|
-
this._enabled = enabled;
|
|
27
|
-
}
|
|
28
|
-
get hits() {
|
|
29
|
-
return this._hits;
|
|
30
|
-
}
|
|
31
|
-
get misses() {
|
|
32
|
-
return this._misses;
|
|
33
|
-
}
|
|
34
|
-
get gets() {
|
|
35
|
-
return this._gets;
|
|
36
|
-
}
|
|
37
|
-
get sets() {
|
|
38
|
-
return this._sets;
|
|
39
|
-
}
|
|
40
|
-
get deletes() {
|
|
41
|
-
return this._deletes;
|
|
42
|
-
}
|
|
43
|
-
get clears() {
|
|
44
|
-
return this._clears;
|
|
45
|
-
}
|
|
46
|
-
get vsize() {
|
|
47
|
-
return this._vsize;
|
|
48
|
-
}
|
|
49
|
-
get ksize() {
|
|
50
|
-
return this._ksize;
|
|
51
|
-
}
|
|
52
|
-
get count() {
|
|
53
|
-
return this._count;
|
|
54
|
-
}
|
|
55
|
-
incrementHits() {
|
|
56
|
-
if (!this._enabled) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
this._hits++;
|
|
60
|
-
}
|
|
61
|
-
incrementMisses() {
|
|
62
|
-
if (!this._enabled) {
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
this._misses++;
|
|
66
|
-
}
|
|
67
|
-
incrementGets() {
|
|
68
|
-
if (!this._enabled) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
this._gets++;
|
|
72
|
-
}
|
|
73
|
-
incrementSets() {
|
|
74
|
-
if (!this._enabled) {
|
|
75
|
-
return;
|
|
76
|
-
}
|
|
77
|
-
this._sets++;
|
|
78
|
-
}
|
|
79
|
-
incrementDeletes() {
|
|
80
|
-
if (!this._enabled) {
|
|
81
|
-
return;
|
|
82
|
-
}
|
|
83
|
-
this._deletes++;
|
|
84
|
-
}
|
|
85
|
-
incrementClears() {
|
|
86
|
-
if (!this._enabled) {
|
|
87
|
-
return;
|
|
88
|
-
}
|
|
89
|
-
this._clears++;
|
|
90
|
-
}
|
|
91
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
92
|
-
incrementVSize(value) {
|
|
93
|
-
if (!this._enabled) {
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
this._vsize += this.roughSizeOfObject(value);
|
|
97
|
-
}
|
|
98
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
99
|
-
decreaseVSize(value) {
|
|
100
|
-
if (!this._enabled) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
this._vsize -= this.roughSizeOfObject(value);
|
|
104
|
-
}
|
|
105
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
106
|
-
incrementKSize(key) {
|
|
107
|
-
if (!this._enabled) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
this._ksize += this.roughSizeOfString(key);
|
|
111
|
-
}
|
|
112
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
113
|
-
decreaseKSize(key) {
|
|
114
|
-
if (!this._enabled) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
this._ksize -= this.roughSizeOfString(key);
|
|
118
|
-
}
|
|
119
|
-
incrementCount() {
|
|
120
|
-
if (!this._enabled) {
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
this._count++;
|
|
124
|
-
}
|
|
125
|
-
decreaseCount() {
|
|
126
|
-
if (!this._enabled) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
this._count--;
|
|
130
|
-
}
|
|
131
|
-
setCount(count) {
|
|
132
|
-
if (!this._enabled) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
this._count = count;
|
|
136
|
-
}
|
|
137
|
-
roughSizeOfString(value) {
|
|
138
|
-
return value.length * 2;
|
|
139
|
-
}
|
|
140
|
-
roughSizeOfObject(object) {
|
|
141
|
-
const objectList = [];
|
|
142
|
-
const stack = [object];
|
|
143
|
-
let bytes = 0;
|
|
144
|
-
while (stack.length > 0) {
|
|
145
|
-
const value = stack.pop();
|
|
146
|
-
if (typeof value === "boolean") {
|
|
147
|
-
bytes += 4;
|
|
148
|
-
} else if (typeof value === "string") {
|
|
149
|
-
bytes += value.length * 2;
|
|
150
|
-
} else if (typeof value === "number") {
|
|
151
|
-
bytes += 8;
|
|
152
|
-
} else if (typeof value === "object" && value !== null && !objectList.includes(value)) {
|
|
153
|
-
objectList.push(value);
|
|
154
|
-
for (const key in value) {
|
|
155
|
-
bytes += key.length * 2;
|
|
156
|
-
stack.push(value[key]);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
return bytes;
|
|
161
|
-
}
|
|
162
|
-
reset() {
|
|
163
|
-
this._hits = 0;
|
|
164
|
-
this._misses = 0;
|
|
165
|
-
this._gets = 0;
|
|
166
|
-
this._sets = 0;
|
|
167
|
-
this._deletes = 0;
|
|
168
|
-
this._clears = 0;
|
|
169
|
-
this._vsize = 0;
|
|
170
|
-
this._ksize = 0;
|
|
171
|
-
this._count = 0;
|
|
172
|
-
}
|
|
173
|
-
resetStoreValues() {
|
|
174
|
-
this._vsize = 0;
|
|
175
|
-
this._ksize = 0;
|
|
176
|
-
this._count = 0;
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
|
|
180
5
|
// src/memory-lru.ts
|
|
181
6
|
var ListNode = class {
|
|
182
7
|
// eslint-disable-next-line @typescript-eslint/parameter-properties
|
|
@@ -265,8 +90,15 @@ var CacheableMemory = class {
|
|
|
265
90
|
_hash9 = /* @__PURE__ */ new Map();
|
|
266
91
|
_lru = new DoublyLinkedList();
|
|
267
92
|
_ttl = 0;
|
|
93
|
+
// Turned off by default
|
|
268
94
|
_useClone = true;
|
|
95
|
+
// Turned on by default
|
|
269
96
|
_lruSize = 0;
|
|
97
|
+
// Turned off by default
|
|
98
|
+
_checkInterval = 0;
|
|
99
|
+
// Turned off by default
|
|
100
|
+
_interval = 0;
|
|
101
|
+
// Turned off by default
|
|
270
102
|
constructor(options) {
|
|
271
103
|
if (options?.ttl) {
|
|
272
104
|
this._ttl = options.ttl;
|
|
@@ -277,6 +109,10 @@ var CacheableMemory = class {
|
|
|
277
109
|
if (options?.lruSize) {
|
|
278
110
|
this._lruSize = options.lruSize;
|
|
279
111
|
}
|
|
112
|
+
if (options?.checkInterval) {
|
|
113
|
+
this._checkInterval = options.checkInterval;
|
|
114
|
+
}
|
|
115
|
+
this.startIntervalCheck();
|
|
280
116
|
}
|
|
281
117
|
get ttl() {
|
|
282
118
|
return this._ttl;
|
|
@@ -297,6 +133,12 @@ var CacheableMemory = class {
|
|
|
297
133
|
this._lruSize = value;
|
|
298
134
|
this.lruResize();
|
|
299
135
|
}
|
|
136
|
+
get checkInterval() {
|
|
137
|
+
return this._checkInterval;
|
|
138
|
+
}
|
|
139
|
+
set checkInterval(value) {
|
|
140
|
+
this._checkInterval = value;
|
|
141
|
+
}
|
|
300
142
|
get size() {
|
|
301
143
|
return this._hash0.size + this._hash1.size + this._hash2.size + this._hash3.size + this._hash4.size + this._hash5.size + this._hash6.size + this._hash7.size + this._hash8.size + this._hash9.size;
|
|
302
144
|
}
|
|
@@ -454,6 +296,28 @@ var CacheableMemory = class {
|
|
|
454
296
|
}
|
|
455
297
|
}
|
|
456
298
|
}
|
|
299
|
+
checkExpiration() {
|
|
300
|
+
const stores = this.concatStores();
|
|
301
|
+
for (const item of stores.values()) {
|
|
302
|
+
if (item.expires && Date.now() > item.expires) {
|
|
303
|
+
this.delete(item.key);
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
startIntervalCheck() {
|
|
308
|
+
if (this._checkInterval > 0) {
|
|
309
|
+
this._interval = setInterval(() => {
|
|
310
|
+
this.checkExpiration();
|
|
311
|
+
}, this._checkInterval);
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
stopIntervalCheck() {
|
|
315
|
+
if (this._interval) {
|
|
316
|
+
clearInterval(this._interval);
|
|
317
|
+
}
|
|
318
|
+
this._interval = 0;
|
|
319
|
+
this._checkInterval = 0;
|
|
320
|
+
}
|
|
457
321
|
isPrimitive(value) {
|
|
458
322
|
const result = false;
|
|
459
323
|
if (value === null || value === void 0) {
|
|
@@ -470,6 +334,236 @@ var CacheableMemory = class {
|
|
|
470
334
|
}
|
|
471
335
|
};
|
|
472
336
|
|
|
337
|
+
// src/keyv-memory.ts
|
|
338
|
+
var KeyvCacheableMemory = class {
|
|
339
|
+
opts = {
|
|
340
|
+
ttl: 0,
|
|
341
|
+
useClone: true,
|
|
342
|
+
lruSize: 0,
|
|
343
|
+
checkInterval: 0
|
|
344
|
+
};
|
|
345
|
+
namespace;
|
|
346
|
+
_cache = new CacheableMemory();
|
|
347
|
+
constructor(options) {
|
|
348
|
+
if (options) {
|
|
349
|
+
this.opts = options;
|
|
350
|
+
this._cache = new CacheableMemory(options);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
async get(key) {
|
|
354
|
+
const result = this._cache.get(key);
|
|
355
|
+
console.log("result", result);
|
|
356
|
+
if (result) {
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
return void 0;
|
|
360
|
+
}
|
|
361
|
+
set(key, value, ttl) {
|
|
362
|
+
this._cache.set(key, value, ttl);
|
|
363
|
+
}
|
|
364
|
+
async delete(key) {
|
|
365
|
+
this._cache.delete(key);
|
|
366
|
+
return true;
|
|
367
|
+
}
|
|
368
|
+
async clear() {
|
|
369
|
+
this._cache.clear();
|
|
370
|
+
}
|
|
371
|
+
async has(key) {
|
|
372
|
+
return this._cache.has(key);
|
|
373
|
+
}
|
|
374
|
+
async getMany(keys) {
|
|
375
|
+
const result = [];
|
|
376
|
+
for (const key of keys) {
|
|
377
|
+
result.push(this._cache.get(key));
|
|
378
|
+
}
|
|
379
|
+
return result;
|
|
380
|
+
}
|
|
381
|
+
async deleteMany(key) {
|
|
382
|
+
for (const k of key) {
|
|
383
|
+
this._cache.delete(k);
|
|
384
|
+
}
|
|
385
|
+
return true;
|
|
386
|
+
}
|
|
387
|
+
on(event, listener) {
|
|
388
|
+
return this;
|
|
389
|
+
}
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
// src/stats.ts
|
|
393
|
+
var CacheableStats = class {
|
|
394
|
+
_hits = 0;
|
|
395
|
+
_misses = 0;
|
|
396
|
+
_gets = 0;
|
|
397
|
+
_sets = 0;
|
|
398
|
+
_deletes = 0;
|
|
399
|
+
_clears = 0;
|
|
400
|
+
_vsize = 0;
|
|
401
|
+
_ksize = 0;
|
|
402
|
+
_count = 0;
|
|
403
|
+
_enabled = false;
|
|
404
|
+
constructor(options) {
|
|
405
|
+
if (options?.enabled) {
|
|
406
|
+
this._enabled = options.enabled;
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
get enabled() {
|
|
410
|
+
return this._enabled;
|
|
411
|
+
}
|
|
412
|
+
set enabled(enabled) {
|
|
413
|
+
this._enabled = enabled;
|
|
414
|
+
}
|
|
415
|
+
get hits() {
|
|
416
|
+
return this._hits;
|
|
417
|
+
}
|
|
418
|
+
get misses() {
|
|
419
|
+
return this._misses;
|
|
420
|
+
}
|
|
421
|
+
get gets() {
|
|
422
|
+
return this._gets;
|
|
423
|
+
}
|
|
424
|
+
get sets() {
|
|
425
|
+
return this._sets;
|
|
426
|
+
}
|
|
427
|
+
get deletes() {
|
|
428
|
+
return this._deletes;
|
|
429
|
+
}
|
|
430
|
+
get clears() {
|
|
431
|
+
return this._clears;
|
|
432
|
+
}
|
|
433
|
+
get vsize() {
|
|
434
|
+
return this._vsize;
|
|
435
|
+
}
|
|
436
|
+
get ksize() {
|
|
437
|
+
return this._ksize;
|
|
438
|
+
}
|
|
439
|
+
get count() {
|
|
440
|
+
return this._count;
|
|
441
|
+
}
|
|
442
|
+
incrementHits() {
|
|
443
|
+
if (!this._enabled) {
|
|
444
|
+
return;
|
|
445
|
+
}
|
|
446
|
+
this._hits++;
|
|
447
|
+
}
|
|
448
|
+
incrementMisses() {
|
|
449
|
+
if (!this._enabled) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
this._misses++;
|
|
453
|
+
}
|
|
454
|
+
incrementGets() {
|
|
455
|
+
if (!this._enabled) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
this._gets++;
|
|
459
|
+
}
|
|
460
|
+
incrementSets() {
|
|
461
|
+
if (!this._enabled) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
this._sets++;
|
|
465
|
+
}
|
|
466
|
+
incrementDeletes() {
|
|
467
|
+
if (!this._enabled) {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
this._deletes++;
|
|
471
|
+
}
|
|
472
|
+
incrementClears() {
|
|
473
|
+
if (!this._enabled) {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
this._clears++;
|
|
477
|
+
}
|
|
478
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
479
|
+
incrementVSize(value) {
|
|
480
|
+
if (!this._enabled) {
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
this._vsize += this.roughSizeOfObject(value);
|
|
484
|
+
}
|
|
485
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
486
|
+
decreaseVSize(value) {
|
|
487
|
+
if (!this._enabled) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
this._vsize -= this.roughSizeOfObject(value);
|
|
491
|
+
}
|
|
492
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
493
|
+
incrementKSize(key) {
|
|
494
|
+
if (!this._enabled) {
|
|
495
|
+
return;
|
|
496
|
+
}
|
|
497
|
+
this._ksize += this.roughSizeOfString(key);
|
|
498
|
+
}
|
|
499
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
500
|
+
decreaseKSize(key) {
|
|
501
|
+
if (!this._enabled) {
|
|
502
|
+
return;
|
|
503
|
+
}
|
|
504
|
+
this._ksize -= this.roughSizeOfString(key);
|
|
505
|
+
}
|
|
506
|
+
incrementCount() {
|
|
507
|
+
if (!this._enabled) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
this._count++;
|
|
511
|
+
}
|
|
512
|
+
decreaseCount() {
|
|
513
|
+
if (!this._enabled) {
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
this._count--;
|
|
517
|
+
}
|
|
518
|
+
setCount(count) {
|
|
519
|
+
if (!this._enabled) {
|
|
520
|
+
return;
|
|
521
|
+
}
|
|
522
|
+
this._count = count;
|
|
523
|
+
}
|
|
524
|
+
roughSizeOfString(value) {
|
|
525
|
+
return value.length * 2;
|
|
526
|
+
}
|
|
527
|
+
roughSizeOfObject(object) {
|
|
528
|
+
const objectList = [];
|
|
529
|
+
const stack = [object];
|
|
530
|
+
let bytes = 0;
|
|
531
|
+
while (stack.length > 0) {
|
|
532
|
+
const value = stack.pop();
|
|
533
|
+
if (typeof value === "boolean") {
|
|
534
|
+
bytes += 4;
|
|
535
|
+
} else if (typeof value === "string") {
|
|
536
|
+
bytes += value.length * 2;
|
|
537
|
+
} else if (typeof value === "number") {
|
|
538
|
+
bytes += 8;
|
|
539
|
+
} else if (typeof value === "object" && value !== null && !objectList.includes(value)) {
|
|
540
|
+
objectList.push(value);
|
|
541
|
+
for (const key in value) {
|
|
542
|
+
bytes += key.length * 2;
|
|
543
|
+
stack.push(value[key]);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
return bytes;
|
|
548
|
+
}
|
|
549
|
+
reset() {
|
|
550
|
+
this._hits = 0;
|
|
551
|
+
this._misses = 0;
|
|
552
|
+
this._gets = 0;
|
|
553
|
+
this._sets = 0;
|
|
554
|
+
this._deletes = 0;
|
|
555
|
+
this._clears = 0;
|
|
556
|
+
this._vsize = 0;
|
|
557
|
+
this._ksize = 0;
|
|
558
|
+
this._count = 0;
|
|
559
|
+
}
|
|
560
|
+
resetStoreValues() {
|
|
561
|
+
this._vsize = 0;
|
|
562
|
+
this._ksize = 0;
|
|
563
|
+
this._count = 0;
|
|
564
|
+
}
|
|
565
|
+
};
|
|
566
|
+
|
|
473
567
|
// src/index.ts
|
|
474
568
|
var CacheableHooks = /* @__PURE__ */ ((CacheableHooks2) => {
|
|
475
569
|
CacheableHooks2["BEFORE_SET"] = "BEFORE_SET";
|
|
@@ -487,7 +581,7 @@ var CacheableEvents = /* @__PURE__ */ ((CacheableEvents2) => {
|
|
|
487
581
|
return CacheableEvents2;
|
|
488
582
|
})(CacheableEvents || {});
|
|
489
583
|
var Cacheable = class extends Hookified {
|
|
490
|
-
_primary = new Keyv({ store: new
|
|
584
|
+
_primary = new Keyv({ store: new KeyvCacheableMemory() });
|
|
491
585
|
_secondary;
|
|
492
586
|
_nonBlocking = false;
|
|
493
587
|
_ttl;
|
|
@@ -794,5 +888,6 @@ export {
|
|
|
794
888
|
CacheableEvents,
|
|
795
889
|
CacheableHooks,
|
|
796
890
|
CacheableMemory,
|
|
797
|
-
CacheableStats
|
|
891
|
+
CacheableStats,
|
|
892
|
+
KeyvCacheableMemory
|
|
798
893
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cacheable",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Simple Caching Engine using Keyv",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"private": false,
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@keyv/redis": "^3.0.1",
|
|
21
|
+
"@types/node": "^22.6.1",
|
|
21
22
|
"@vitest/coverage-v8": "^2.1.1",
|
|
22
23
|
"lru-cache": "^11.0.1",
|
|
23
24
|
"rimraf": "^6.0.1",
|