@cacheable/node-cache 1.7.5 → 2.0.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 +22 -28
- package/dist/index.cjs +129 -95
- package/dist/index.d.cts +22 -42
- package/dist/index.d.ts +22 -42
- package/dist/index.js +118 -94
- package/package.json +18 -12
package/README.md
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* Faster than the original `node-cache` package 🚀
|
|
17
17
|
* Async/Await functionality with `{NodeCacheStore}`
|
|
18
18
|
* Storage Adapters via [Keyv](https://keyv.org) with `{NodeCacheStore}`
|
|
19
|
+
* Lightweight - uses `@cacheable/utils` for utilities
|
|
19
20
|
* Maintained and Updated Regularly! 🎉
|
|
20
21
|
|
|
21
22
|
# Table of Contents
|
|
@@ -277,7 +278,7 @@ cache.on('set', (key, value) => {
|
|
|
277
278
|
|
|
278
279
|
# NodeCacheStore
|
|
279
280
|
|
|
280
|
-
`NodeCacheStore` has a similar API to `NodeCache` but it is using `async / await` as it uses
|
|
281
|
+
`NodeCacheStore` has a similar API to `NodeCache` but it is using `async / await` as it uses [Keyv](https://keyv.org) under the hood. This means that you can use any storage adapter that is available in `Keyv` and it will work seamlessly with the `NodeCacheStore`. To learn more about the `Keyv` storage adapters you can check out the [Keyv documentation](https://keyv.org).
|
|
281
282
|
|
|
282
283
|
```javascript
|
|
283
284
|
import {NodeCacheStore} from '@cacheable/node-cache';
|
|
@@ -287,38 +288,33 @@ await cache.set('foo', 'bar');
|
|
|
287
288
|
await cache.get('foo'); // 'bar'
|
|
288
289
|
```
|
|
289
290
|
|
|
290
|
-
Here is an example of how to use the `NodeCacheStore` with a
|
|
291
|
+
Here is an example of how to use the `NodeCacheStore` with a Redis storage adapter:
|
|
291
292
|
|
|
292
293
|
```javascript
|
|
293
294
|
import {NodeCacheStore} from '@cacheable/node-cache';
|
|
294
|
-
import
|
|
295
|
-
import
|
|
295
|
+
import Keyv from 'keyv';
|
|
296
|
+
import KeyvRedis from '@keyv/redis';
|
|
296
297
|
|
|
297
|
-
const
|
|
298
|
-
const
|
|
299
|
-
const cache = new NodeCacheStore({primary, secondary});
|
|
298
|
+
const keyv = new Keyv({store: new KeyvRedis('redis://user:pass@localhost:6379')});
|
|
299
|
+
const cache = new NodeCacheStore({store: keyv});
|
|
300
300
|
|
|
301
301
|
// with storage you have the same functionality as the NodeCache but will be using async/await
|
|
302
302
|
await cache.set('foo', 'bar');
|
|
303
303
|
await cache.get('foo'); // 'bar'
|
|
304
|
-
|
|
305
|
-
// if you call getStats() this will now only be for the single instance of the adapter as it is in memory
|
|
306
|
-
cache.getStats(); // {hits: 1, misses: 1, keys: 1, ksize: 2, vsize: 3}
|
|
307
304
|
```
|
|
308
305
|
|
|
309
306
|
When initializing the cache you can pass in the options below:
|
|
310
307
|
|
|
311
308
|
```javascript
|
|
312
309
|
export type NodeCacheStoreOptions = {
|
|
313
|
-
ttl?: number; // The standard ttl as number in milliseconds for every generated cache element. 0 = unlimited
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
stats?: boolean; // Default is true, if this is set to false it will not track stats
|
|
310
|
+
ttl?: number | string; // The standard ttl as number in milliseconds for every generated cache element. 0 = unlimited. Supports shorthand like '1h' for 1 hour.
|
|
311
|
+
store?: Keyv; // The storage adapter (defaults to in-memory Keyv)
|
|
312
|
+
maxKeys?: number; // Default is 0 (unlimited). If this is set it will return false when trying to set more keys than the max.
|
|
313
|
+
stats?: boolean; // Default is true, if this is set to false it will not track stats internally
|
|
318
314
|
};
|
|
319
315
|
```
|
|
320
316
|
|
|
321
|
-
Note: the `ttl` is now in milliseconds and not seconds like `stdTTL` in `NodeCache`. You can
|
|
317
|
+
Note: the `ttl` is now in milliseconds and not seconds like `stdTTL` in `NodeCache`. You can also use shorthand notation for TTL values. Here is an example:
|
|
322
318
|
|
|
323
319
|
```javascript
|
|
324
320
|
const cache = new NodeCacheStore({ttl: 60000 }); // 1 minute as it defaults to milliseconds
|
|
@@ -328,21 +324,19 @@ await cache.set('longfoo', 'bar', '1d'); // 1 day
|
|
|
328
324
|
|
|
329
325
|
## NodeCacheStore API
|
|
330
326
|
|
|
331
|
-
* `set(key: string | number, value: any, ttl?: number): Promise<boolean>` - Set a key value pair with an optional ttl (in milliseconds). Will return true on success. If the ttl is not set it will default to
|
|
332
|
-
* `mset(data: Array<NodeCacheItem>): Promise<
|
|
333
|
-
* `get<T>(key: string | number): Promise<T>` - Get a value from the cache by key
|
|
334
|
-
* `mget(keys: Array<string | number>): Promise<Record<string,
|
|
335
|
-
* `take<T>(key: string | number): Promise<T>` - Get a value from the cache by key and delete it
|
|
327
|
+
* `set(key: string | number, value: any, ttl?: number | string): Promise<boolean>` - Set a key value pair with an optional ttl (in milliseconds or shorthand string). Will return true on success, false if maxKeys limit is reached. If the ttl is not set it will default to the instance ttl or no expiration.
|
|
328
|
+
* `mset(data: Array<NodeCacheItem>): Promise<void>` - Set multiple key value pairs at once
|
|
329
|
+
* `get<T>(key: string | number): Promise<T | undefined>` - Get a value from the cache by key
|
|
330
|
+
* `mget<T>(keys: Array<string | number>): Promise<Record<string, T | undefined>>` - Get multiple values from the cache by keys
|
|
331
|
+
* `take<T>(key: string | number): Promise<T | undefined>` - Get a value from the cache by key and delete it
|
|
336
332
|
* `del(key: string | number): Promise<boolean>` - Delete a key
|
|
337
333
|
* `mdel(keys: Array<string | number>): Promise<boolean>` - Delete multiple keys
|
|
338
334
|
* `clear(): Promise<void>` - Clear the cache
|
|
339
|
-
* `setTtl(key: string | number, ttl
|
|
340
|
-
* `disconnect(): Promise<void>` - Disconnect the storage
|
|
341
|
-
* `
|
|
342
|
-
* `
|
|
343
|
-
* `
|
|
344
|
-
* `secondary`: `Keyv` - The secondary storage adapter
|
|
345
|
-
* `maxKeys`: `number` - If this is set it will throw and error if you try to set more keys than the max
|
|
335
|
+
* `setTtl(key: string | number, ttl?: number): Promise<boolean>` - Set the ttl of an existing key
|
|
336
|
+
* `disconnect(): Promise<void>` - Disconnect the storage adapter
|
|
337
|
+
* `ttl`: `number | string | undefined` - The standard ttl for every generated cache element. `undefined` = unlimited
|
|
338
|
+
* `store`: `Keyv` - The storage adapter (read-only)
|
|
339
|
+
* `maxKeys`: `number` - If this is set it will return false when trying to set more keys than the max
|
|
346
340
|
|
|
347
341
|
# How to Contribute
|
|
348
342
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
5
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
8
|
var __export = (target, all) => {
|
|
7
9
|
for (var name in all)
|
|
@@ -15,6 +17,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
15
17
|
}
|
|
16
18
|
return to;
|
|
17
19
|
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
18
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
29
|
|
|
20
30
|
// src/index.ts
|
|
@@ -26,86 +36,52 @@ __export(index_exports, {
|
|
|
26
36
|
default: () => index_default
|
|
27
37
|
});
|
|
28
38
|
module.exports = __toCommonJS(index_exports);
|
|
29
|
-
var
|
|
39
|
+
var import_utils2 = require("@cacheable/utils");
|
|
30
40
|
var import_hookified2 = require("hookified");
|
|
31
41
|
|
|
32
42
|
// src/store.ts
|
|
33
|
-
var
|
|
43
|
+
var import_utils = require("@cacheable/utils");
|
|
34
44
|
var import_hookified = require("hookified");
|
|
45
|
+
var import_keyv = __toESM(require("keyv"), 1);
|
|
35
46
|
var NodeCacheStore = class extends import_hookified.Hookified {
|
|
36
47
|
_maxKeys = 0;
|
|
37
|
-
|
|
48
|
+
_keyv;
|
|
49
|
+
_stats;
|
|
50
|
+
_ttl;
|
|
38
51
|
constructor(options) {
|
|
39
52
|
super();
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
stats: options.stats ?? true
|
|
46
|
-
};
|
|
47
|
-
this._cache = new import_cacheable.Cacheable(cacheOptions);
|
|
48
|
-
if (options.maxKeys) {
|
|
49
|
-
this._maxKeys = options.maxKeys;
|
|
50
|
-
}
|
|
53
|
+
this._stats = new import_utils.Stats({ enabled: options?.stats ?? true });
|
|
54
|
+
this._ttl = options?.ttl;
|
|
55
|
+
this._keyv = options?.store ?? new import_keyv.default();
|
|
56
|
+
if (options?.maxKeys) {
|
|
57
|
+
this._maxKeys = options.maxKeys;
|
|
51
58
|
}
|
|
52
|
-
this.
|
|
59
|
+
this._keyv.on("error", (error) => {
|
|
53
60
|
this.emit("error", error);
|
|
54
61
|
});
|
|
55
62
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Cacheable instance.
|
|
58
|
-
* @returns {Cacheable}
|
|
59
|
-
* @readonly
|
|
60
|
-
*/
|
|
61
|
-
get cache() {
|
|
62
|
-
return this._cache;
|
|
63
|
-
}
|
|
64
63
|
/**
|
|
65
64
|
* Time to live in milliseconds.
|
|
66
65
|
* @returns {number | string | undefined}
|
|
67
66
|
* @readonly
|
|
68
67
|
*/
|
|
69
68
|
get ttl() {
|
|
70
|
-
return this.
|
|
69
|
+
return this._ttl;
|
|
71
70
|
}
|
|
72
71
|
/**
|
|
73
72
|
* Time to live in milliseconds.
|
|
74
73
|
* @param {number | string | undefined} ttl
|
|
75
74
|
*/
|
|
76
75
|
set ttl(ttl) {
|
|
77
|
-
this.
|
|
76
|
+
this._ttl = ttl;
|
|
78
77
|
}
|
|
79
78
|
/**
|
|
80
|
-
*
|
|
79
|
+
* The Keyv store instance.
|
|
81
80
|
* @returns {Keyv<T>}
|
|
82
81
|
* @readonly
|
|
83
82
|
*/
|
|
84
|
-
get
|
|
85
|
-
return this.
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Primary cache store.
|
|
89
|
-
* @param {Keyv<T>} primary
|
|
90
|
-
*/
|
|
91
|
-
set primary(primary) {
|
|
92
|
-
this._cache.primary = primary;
|
|
93
|
-
}
|
|
94
|
-
/**
|
|
95
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
96
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
97
|
-
* @returns {Keyv<T> | undefined}
|
|
98
|
-
*/
|
|
99
|
-
get secondary() {
|
|
100
|
-
return this._cache.secondary;
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
104
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
105
|
-
* @param {Keyv | undefined} secondary
|
|
106
|
-
*/
|
|
107
|
-
set secondary(secondary) {
|
|
108
|
-
this._cache.secondary = secondary;
|
|
83
|
+
get store() {
|
|
84
|
+
return this._keyv;
|
|
109
85
|
}
|
|
110
86
|
/**
|
|
111
87
|
* Maximum number of keys to store in the cache. if this is set to a value greater than 0,
|
|
@@ -124,7 +100,7 @@ var NodeCacheStore = class extends import_hookified.Hookified {
|
|
|
124
100
|
set maxKeys(maxKeys) {
|
|
125
101
|
this._maxKeys = maxKeys;
|
|
126
102
|
if (this._maxKeys > 0) {
|
|
127
|
-
this.
|
|
103
|
+
this._stats.enabled = true;
|
|
128
104
|
}
|
|
129
105
|
}
|
|
130
106
|
/**
|
|
@@ -136,11 +112,13 @@ var NodeCacheStore = class extends import_hookified.Hookified {
|
|
|
136
112
|
*/
|
|
137
113
|
async set(key, value, ttl) {
|
|
138
114
|
if (this._maxKeys > 0) {
|
|
139
|
-
if (this.
|
|
115
|
+
if (this._stats.count >= this._maxKeys) {
|
|
140
116
|
return false;
|
|
141
117
|
}
|
|
142
118
|
}
|
|
143
|
-
|
|
119
|
+
const finalTtl = this.resolveTtl(ttl);
|
|
120
|
+
await this._keyv.set(key.toString(), value, finalTtl);
|
|
121
|
+
this._stats.incrementCount();
|
|
144
122
|
return true;
|
|
145
123
|
}
|
|
146
124
|
/**
|
|
@@ -149,15 +127,11 @@ var NodeCacheStore = class extends import_hookified.Hookified {
|
|
|
149
127
|
* @returns {void}
|
|
150
128
|
*/
|
|
151
129
|
async mset(list) {
|
|
152
|
-
const items = [];
|
|
153
130
|
for (const item of list) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
ttl: item.ttl
|
|
158
|
-
});
|
|
131
|
+
const finalTtl = this.resolveTtl(item.ttl);
|
|
132
|
+
await this._keyv.set(item.key.toString(), item.value, finalTtl);
|
|
133
|
+
this._stats.incrementCount();
|
|
159
134
|
}
|
|
160
|
-
await this._cache.setMany(items);
|
|
161
135
|
}
|
|
162
136
|
/**
|
|
163
137
|
* Get a value from the cache.
|
|
@@ -165,7 +139,13 @@ var NodeCacheStore = class extends import_hookified.Hookified {
|
|
|
165
139
|
* @returns {any | undefined}
|
|
166
140
|
*/
|
|
167
141
|
async get(key) {
|
|
168
|
-
|
|
142
|
+
const result = await this._keyv.get(key.toString());
|
|
143
|
+
if (result !== void 0) {
|
|
144
|
+
this._stats.incrementHits();
|
|
145
|
+
} else {
|
|
146
|
+
this._stats.incrementMisses();
|
|
147
|
+
}
|
|
148
|
+
return result;
|
|
169
149
|
}
|
|
170
150
|
/**
|
|
171
151
|
* Get multiple values from the cache.
|
|
@@ -175,7 +155,13 @@ var NodeCacheStore = class extends import_hookified.Hookified {
|
|
|
175
155
|
async mget(keys) {
|
|
176
156
|
const result = {};
|
|
177
157
|
for (const key of keys) {
|
|
178
|
-
|
|
158
|
+
const value = await this._keyv.get(key.toString());
|
|
159
|
+
if (value !== void 0) {
|
|
160
|
+
this._stats.incrementHits();
|
|
161
|
+
} else {
|
|
162
|
+
this._stats.incrementMisses();
|
|
163
|
+
}
|
|
164
|
+
result[key.toString()] = value;
|
|
179
165
|
}
|
|
180
166
|
return result;
|
|
181
167
|
}
|
|
@@ -185,7 +171,11 @@ var NodeCacheStore = class extends import_hookified.Hookified {
|
|
|
185
171
|
* @returns {boolean}
|
|
186
172
|
*/
|
|
187
173
|
async del(key) {
|
|
188
|
-
|
|
174
|
+
const deleted = await this._keyv.delete(key.toString());
|
|
175
|
+
if (deleted) {
|
|
176
|
+
this._stats.decreaseCount();
|
|
177
|
+
}
|
|
178
|
+
return deleted;
|
|
189
179
|
}
|
|
190
180
|
/**
|
|
191
181
|
* Delete multiple keys from the cache.
|
|
@@ -193,42 +183,77 @@ var NodeCacheStore = class extends import_hookified.Hookified {
|
|
|
193
183
|
* @returns {boolean}
|
|
194
184
|
*/
|
|
195
185
|
async mdel(keys) {
|
|
196
|
-
|
|
186
|
+
const deleted = await this._keyv.delete(keys.map((key) => key.toString()));
|
|
187
|
+
if (deleted) {
|
|
188
|
+
for (const _ of keys) {
|
|
189
|
+
this._stats.decreaseCount();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return deleted;
|
|
197
193
|
}
|
|
198
194
|
/**
|
|
199
195
|
* Clear the cache.
|
|
200
196
|
* @returns {void}
|
|
201
197
|
*/
|
|
202
198
|
async clear() {
|
|
203
|
-
|
|
199
|
+
await this._keyv.clear();
|
|
200
|
+
this._stats.resetStoreValues();
|
|
204
201
|
}
|
|
205
202
|
/**
|
|
206
|
-
*
|
|
203
|
+
* Set the TTL of an existing key in the cache.
|
|
207
204
|
* @param {string | number} key
|
|
205
|
+
* @param {number | string} [ttl]
|
|
208
206
|
* @returns {boolean}
|
|
209
207
|
*/
|
|
210
208
|
async setTtl(key, ttl) {
|
|
211
|
-
const item = await this.
|
|
209
|
+
const item = await this._keyv.get(key.toString());
|
|
212
210
|
if (item) {
|
|
213
|
-
|
|
211
|
+
const finalTtl = this.resolveTtl(ttl);
|
|
212
|
+
await this._keyv.set(key.toString(), item, finalTtl);
|
|
214
213
|
return true;
|
|
215
214
|
}
|
|
216
215
|
return false;
|
|
217
216
|
}
|
|
218
217
|
/**
|
|
219
|
-
*
|
|
218
|
+
* Get a key from the cache and delete it. If it does exist it will get the value and delete the item from the cache.
|
|
220
219
|
* @param {string | number} key
|
|
221
220
|
* @returns {T | undefined}
|
|
222
221
|
*/
|
|
223
222
|
async take(key) {
|
|
224
|
-
|
|
223
|
+
const result = await this._keyv.get(key.toString());
|
|
224
|
+
if (result !== void 0) {
|
|
225
|
+
this._stats.incrementHits();
|
|
226
|
+
await this._keyv.delete(key.toString());
|
|
227
|
+
this._stats.decreaseCount();
|
|
228
|
+
} else {
|
|
229
|
+
this._stats.incrementMisses();
|
|
230
|
+
}
|
|
231
|
+
return result;
|
|
225
232
|
}
|
|
226
233
|
/**
|
|
227
234
|
* Disconnect from the cache.
|
|
228
235
|
* @returns {void}
|
|
229
236
|
*/
|
|
230
237
|
async disconnect() {
|
|
231
|
-
await this.
|
|
238
|
+
await this._keyv.disconnect();
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Resolve the TTL to milliseconds.
|
|
242
|
+
* @param {number | string | undefined} ttl
|
|
243
|
+
* @returns {number | undefined}
|
|
244
|
+
*/
|
|
245
|
+
resolveTtl(ttl) {
|
|
246
|
+
const effectiveTtl = ttl ?? this._ttl;
|
|
247
|
+
if (effectiveTtl === void 0) {
|
|
248
|
+
return void 0;
|
|
249
|
+
}
|
|
250
|
+
if (typeof effectiveTtl === "string") {
|
|
251
|
+
return (0, import_utils.shorthandToMilliseconds)(effectiveTtl);
|
|
252
|
+
}
|
|
253
|
+
if (effectiveTtl === 0) {
|
|
254
|
+
return void 0;
|
|
255
|
+
}
|
|
256
|
+
return effectiveTtl;
|
|
232
257
|
}
|
|
233
258
|
};
|
|
234
259
|
|
|
@@ -249,8 +274,7 @@ var NodeCache = class extends import_hookified2.Hookified {
|
|
|
249
274
|
maxKeys: -1
|
|
250
275
|
};
|
|
251
276
|
store = /* @__PURE__ */ new Map();
|
|
252
|
-
_stats = new
|
|
253
|
-
_cacheable = new import_cacheable2.CacheableMemory();
|
|
277
|
+
_stats = new import_utils2.Stats({ enabled: true });
|
|
254
278
|
intervalId = 0;
|
|
255
279
|
constructor(options) {
|
|
256
280
|
super();
|
|
@@ -335,13 +359,13 @@ var NodeCache = class extends import_hookified2.Hookified {
|
|
|
335
359
|
}
|
|
336
360
|
this._stats.incrementHits();
|
|
337
361
|
if (this.options.useClones) {
|
|
338
|
-
return this.
|
|
362
|
+
return this.clone(result.value);
|
|
339
363
|
}
|
|
340
364
|
return result.value;
|
|
341
365
|
}
|
|
342
366
|
this._stats.incrementHits();
|
|
343
367
|
if (this.options.useClones) {
|
|
344
|
-
return this.
|
|
368
|
+
return this.clone(result.value);
|
|
345
369
|
}
|
|
346
370
|
return result.value;
|
|
347
371
|
}
|
|
@@ -375,7 +399,7 @@ var NodeCache = class extends import_hookified2.Hookified {
|
|
|
375
399
|
if (result) {
|
|
376
400
|
this.del(key);
|
|
377
401
|
if (this.options.useClones) {
|
|
378
|
-
return this.
|
|
402
|
+
return this.clone(result);
|
|
379
403
|
}
|
|
380
404
|
return result;
|
|
381
405
|
}
|
|
@@ -494,7 +518,7 @@ var NodeCache = class extends import_hookified2.Hookified {
|
|
|
494
518
|
* @returns {void}
|
|
495
519
|
*/
|
|
496
520
|
flushStats() {
|
|
497
|
-
this._stats = new
|
|
521
|
+
this._stats = new import_utils2.Stats({ enabled: true });
|
|
498
522
|
this.emit("flush_stats");
|
|
499
523
|
}
|
|
500
524
|
/**
|
|
@@ -511,28 +535,44 @@ var NodeCache = class extends import_hookified2.Hookified {
|
|
|
511
535
|
getIntervalId() {
|
|
512
536
|
return this.intervalId;
|
|
513
537
|
}
|
|
538
|
+
startInterval() {
|
|
539
|
+
if (this.options.checkperiod && this.options.checkperiod > 0) {
|
|
540
|
+
const checkPeriodinSeconds = this.options.checkperiod * 1e3;
|
|
541
|
+
this.intervalId = setInterval(() => {
|
|
542
|
+
this.checkData();
|
|
543
|
+
}, checkPeriodinSeconds).unref();
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
this.intervalId = 0;
|
|
547
|
+
}
|
|
548
|
+
stopInterval() {
|
|
549
|
+
if (this.intervalId !== 0) {
|
|
550
|
+
clearInterval(this.intervalId);
|
|
551
|
+
this.intervalId = 0;
|
|
552
|
+
}
|
|
553
|
+
}
|
|
514
554
|
formatKey(key) {
|
|
515
555
|
return key.toString();
|
|
516
556
|
}
|
|
557
|
+
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
558
|
+
clone(value) {
|
|
559
|
+
if (value === null || value === void 0) {
|
|
560
|
+
return value;
|
|
561
|
+
}
|
|
562
|
+
if (typeof value !== "object") {
|
|
563
|
+
return value;
|
|
564
|
+
}
|
|
565
|
+
return structuredClone(value);
|
|
566
|
+
}
|
|
517
567
|
getExpirationTimestamp(ttlInSeconds) {
|
|
518
568
|
if (typeof ttlInSeconds === "string") {
|
|
519
|
-
return (0,
|
|
569
|
+
return (0, import_utils2.shorthandToTime)(ttlInSeconds);
|
|
520
570
|
}
|
|
521
571
|
const currentTimestamp = Date.now();
|
|
522
572
|
const ttlInMilliseconds = ttlInSeconds * 1e3;
|
|
523
573
|
const expirationTimestamp = currentTimestamp + ttlInMilliseconds;
|
|
524
574
|
return expirationTimestamp;
|
|
525
575
|
}
|
|
526
|
-
startInterval() {
|
|
527
|
-
if (this.options.checkperiod && this.options.checkperiod > 0) {
|
|
528
|
-
const checkPeriodinSeconds = this.options.checkperiod * 1e3;
|
|
529
|
-
this.intervalId = setInterval(() => {
|
|
530
|
-
this.checkData();
|
|
531
|
-
}, checkPeriodinSeconds).unref();
|
|
532
|
-
return;
|
|
533
|
-
}
|
|
534
|
-
this.intervalId = 0;
|
|
535
|
-
}
|
|
536
576
|
checkData() {
|
|
537
577
|
for (const [key, value] of this.store.entries()) {
|
|
538
578
|
if (value.ttl > 0 && value.ttl < Date.now()) {
|
|
@@ -543,12 +583,6 @@ var NodeCache = class extends import_hookified2.Hookified {
|
|
|
543
583
|
}
|
|
544
584
|
}
|
|
545
585
|
}
|
|
546
|
-
stopInterval() {
|
|
547
|
-
if (this.intervalId !== 0) {
|
|
548
|
-
clearInterval(this.intervalId);
|
|
549
|
-
this.intervalId = 0;
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
586
|
createError(errorCode, key) {
|
|
553
587
|
let error = errorCode;
|
|
554
588
|
if (key) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Hookified } from 'hookified';
|
|
2
|
-
import
|
|
3
|
-
import { Keyv } from 'keyv';
|
|
2
|
+
import Keyv from 'keyv';
|
|
4
3
|
|
|
5
4
|
type NodeCacheStoreOptions<T> = {
|
|
6
5
|
/**
|
|
@@ -12,14 +11,9 @@ type NodeCacheStoreOptions<T> = {
|
|
|
12
11
|
*/
|
|
13
12
|
maxKeys?: number;
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
14
|
+
* The Keyv store instance.
|
|
16
15
|
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Secondary cache store. Learn more about the secondary cache store in the cacheable documentation.
|
|
20
|
-
* [storage-tiering-and-caching](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching)
|
|
21
|
-
*/
|
|
22
|
-
secondary?: Keyv<T>;
|
|
16
|
+
store?: Keyv<T>;
|
|
23
17
|
/**
|
|
24
18
|
* Enable stats tracking. This is a breaking change from the original NodeCache.
|
|
25
19
|
*/
|
|
@@ -27,14 +21,10 @@ type NodeCacheStoreOptions<T> = {
|
|
|
27
21
|
};
|
|
28
22
|
declare class NodeCacheStore<T> extends Hookified {
|
|
29
23
|
private _maxKeys;
|
|
30
|
-
private
|
|
24
|
+
private _keyv;
|
|
25
|
+
private readonly _stats;
|
|
26
|
+
private _ttl?;
|
|
31
27
|
constructor(options?: NodeCacheStoreOptions<T>);
|
|
32
|
-
/**
|
|
33
|
-
* Cacheable instance.
|
|
34
|
-
* @returns {Cacheable}
|
|
35
|
-
* @readonly
|
|
36
|
-
*/
|
|
37
|
-
get cache(): Cacheable;
|
|
38
28
|
/**
|
|
39
29
|
* Time to live in milliseconds.
|
|
40
30
|
* @returns {number | string | undefined}
|
|
@@ -47,28 +37,11 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
47
37
|
*/
|
|
48
38
|
set ttl(ttl: number | string | undefined);
|
|
49
39
|
/**
|
|
50
|
-
*
|
|
40
|
+
* The Keyv store instance.
|
|
51
41
|
* @returns {Keyv<T>}
|
|
52
42
|
* @readonly
|
|
53
43
|
*/
|
|
54
|
-
get
|
|
55
|
-
/**
|
|
56
|
-
* Primary cache store.
|
|
57
|
-
* @param {Keyv<T>} primary
|
|
58
|
-
*/
|
|
59
|
-
set primary(primary: Keyv<T>);
|
|
60
|
-
/**
|
|
61
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
62
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
63
|
-
* @returns {Keyv<T> | undefined}
|
|
64
|
-
*/
|
|
65
|
-
get secondary(): Keyv<T> | undefined;
|
|
66
|
-
/**
|
|
67
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
68
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
69
|
-
* @param {Keyv | undefined} secondary
|
|
70
|
-
*/
|
|
71
|
-
set secondary(secondary: Keyv | undefined);
|
|
44
|
+
get store(): Keyv<T>;
|
|
72
45
|
/**
|
|
73
46
|
* Maximum number of keys to store in the cache. if this is set to a value greater than 0,
|
|
74
47
|
* the cache will keep track of the number of keys and will not store more than the specified number of keys.
|
|
@@ -89,7 +62,7 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
89
62
|
* @param {number} [ttl]
|
|
90
63
|
* @returns {boolean}
|
|
91
64
|
*/
|
|
92
|
-
set(key: string | number, value: T, ttl?: number): Promise<boolean>;
|
|
65
|
+
set(key: string | number, value: T, ttl?: number | string): Promise<boolean>;
|
|
93
66
|
/**
|
|
94
67
|
* Set multiple key/value pairs in the cache.
|
|
95
68
|
* @param {PartialNodeCacheItem[]} list
|
|
@@ -126,13 +99,14 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
126
99
|
*/
|
|
127
100
|
clear(): Promise<void>;
|
|
128
101
|
/**
|
|
129
|
-
*
|
|
102
|
+
* Set the TTL of an existing key in the cache.
|
|
130
103
|
* @param {string | number} key
|
|
104
|
+
* @param {number | string} [ttl]
|
|
131
105
|
* @returns {boolean}
|
|
132
106
|
*/
|
|
133
|
-
setTtl(key: string | number, ttl?: number): Promise<boolean>;
|
|
107
|
+
setTtl(key: string | number, ttl?: number | string): Promise<boolean>;
|
|
134
108
|
/**
|
|
135
|
-
*
|
|
109
|
+
* Get a key from the cache and delete it. If it does exist it will get the value and delete the item from the cache.
|
|
136
110
|
* @param {string | number} key
|
|
137
111
|
* @returns {T | undefined}
|
|
138
112
|
*/
|
|
@@ -142,6 +116,12 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
142
116
|
* @returns {void}
|
|
143
117
|
*/
|
|
144
118
|
disconnect(): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Resolve the TTL to milliseconds.
|
|
121
|
+
* @param {number | string | undefined} ttl
|
|
122
|
+
* @returns {number | undefined}
|
|
123
|
+
*/
|
|
124
|
+
private resolveTtl;
|
|
145
125
|
}
|
|
146
126
|
|
|
147
127
|
type NodeCacheOptions = {
|
|
@@ -224,7 +204,6 @@ declare class NodeCache<T> extends Hookified {
|
|
|
224
204
|
readonly options: NodeCacheOptions;
|
|
225
205
|
readonly store: Map<string, NodeCacheItem<T>>;
|
|
226
206
|
private _stats;
|
|
227
|
-
private readonly _cacheable;
|
|
228
207
|
private intervalId;
|
|
229
208
|
constructor(options?: NodeCacheOptions);
|
|
230
209
|
/**
|
|
@@ -324,11 +303,12 @@ declare class NodeCache<T> extends Hookified {
|
|
|
324
303
|
* @returns {number | NodeJS.Timeout} the interval id
|
|
325
304
|
*/
|
|
326
305
|
getIntervalId(): number | NodeJS.Timeout;
|
|
306
|
+
startInterval(): void;
|
|
307
|
+
stopInterval(): void;
|
|
327
308
|
private formatKey;
|
|
309
|
+
private clone;
|
|
328
310
|
private getExpirationTimestamp;
|
|
329
|
-
private startInterval;
|
|
330
311
|
private checkData;
|
|
331
|
-
private stopInterval;
|
|
332
312
|
private createError;
|
|
333
313
|
}
|
|
334
314
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Hookified } from 'hookified';
|
|
2
|
-
import
|
|
3
|
-
import { Keyv } from 'keyv';
|
|
2
|
+
import Keyv from 'keyv';
|
|
4
3
|
|
|
5
4
|
type NodeCacheStoreOptions<T> = {
|
|
6
5
|
/**
|
|
@@ -12,14 +11,9 @@ type NodeCacheStoreOptions<T> = {
|
|
|
12
11
|
*/
|
|
13
12
|
maxKeys?: number;
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
14
|
+
* The Keyv store instance.
|
|
16
15
|
*/
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Secondary cache store. Learn more about the secondary cache store in the cacheable documentation.
|
|
20
|
-
* [storage-tiering-and-caching](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching)
|
|
21
|
-
*/
|
|
22
|
-
secondary?: Keyv<T>;
|
|
16
|
+
store?: Keyv<T>;
|
|
23
17
|
/**
|
|
24
18
|
* Enable stats tracking. This is a breaking change from the original NodeCache.
|
|
25
19
|
*/
|
|
@@ -27,14 +21,10 @@ type NodeCacheStoreOptions<T> = {
|
|
|
27
21
|
};
|
|
28
22
|
declare class NodeCacheStore<T> extends Hookified {
|
|
29
23
|
private _maxKeys;
|
|
30
|
-
private
|
|
24
|
+
private _keyv;
|
|
25
|
+
private readonly _stats;
|
|
26
|
+
private _ttl?;
|
|
31
27
|
constructor(options?: NodeCacheStoreOptions<T>);
|
|
32
|
-
/**
|
|
33
|
-
* Cacheable instance.
|
|
34
|
-
* @returns {Cacheable}
|
|
35
|
-
* @readonly
|
|
36
|
-
*/
|
|
37
|
-
get cache(): Cacheable;
|
|
38
28
|
/**
|
|
39
29
|
* Time to live in milliseconds.
|
|
40
30
|
* @returns {number | string | undefined}
|
|
@@ -47,28 +37,11 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
47
37
|
*/
|
|
48
38
|
set ttl(ttl: number | string | undefined);
|
|
49
39
|
/**
|
|
50
|
-
*
|
|
40
|
+
* The Keyv store instance.
|
|
51
41
|
* @returns {Keyv<T>}
|
|
52
42
|
* @readonly
|
|
53
43
|
*/
|
|
54
|
-
get
|
|
55
|
-
/**
|
|
56
|
-
* Primary cache store.
|
|
57
|
-
* @param {Keyv<T>} primary
|
|
58
|
-
*/
|
|
59
|
-
set primary(primary: Keyv<T>);
|
|
60
|
-
/**
|
|
61
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
62
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
63
|
-
* @returns {Keyv<T> | undefined}
|
|
64
|
-
*/
|
|
65
|
-
get secondary(): Keyv<T> | undefined;
|
|
66
|
-
/**
|
|
67
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
68
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
69
|
-
* @param {Keyv | undefined} secondary
|
|
70
|
-
*/
|
|
71
|
-
set secondary(secondary: Keyv | undefined);
|
|
44
|
+
get store(): Keyv<T>;
|
|
72
45
|
/**
|
|
73
46
|
* Maximum number of keys to store in the cache. if this is set to a value greater than 0,
|
|
74
47
|
* the cache will keep track of the number of keys and will not store more than the specified number of keys.
|
|
@@ -89,7 +62,7 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
89
62
|
* @param {number} [ttl]
|
|
90
63
|
* @returns {boolean}
|
|
91
64
|
*/
|
|
92
|
-
set(key: string | number, value: T, ttl?: number): Promise<boolean>;
|
|
65
|
+
set(key: string | number, value: T, ttl?: number | string): Promise<boolean>;
|
|
93
66
|
/**
|
|
94
67
|
* Set multiple key/value pairs in the cache.
|
|
95
68
|
* @param {PartialNodeCacheItem[]} list
|
|
@@ -126,13 +99,14 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
126
99
|
*/
|
|
127
100
|
clear(): Promise<void>;
|
|
128
101
|
/**
|
|
129
|
-
*
|
|
102
|
+
* Set the TTL of an existing key in the cache.
|
|
130
103
|
* @param {string | number} key
|
|
104
|
+
* @param {number | string} [ttl]
|
|
131
105
|
* @returns {boolean}
|
|
132
106
|
*/
|
|
133
|
-
setTtl(key: string | number, ttl?: number): Promise<boolean>;
|
|
107
|
+
setTtl(key: string | number, ttl?: number | string): Promise<boolean>;
|
|
134
108
|
/**
|
|
135
|
-
*
|
|
109
|
+
* Get a key from the cache and delete it. If it does exist it will get the value and delete the item from the cache.
|
|
136
110
|
* @param {string | number} key
|
|
137
111
|
* @returns {T | undefined}
|
|
138
112
|
*/
|
|
@@ -142,6 +116,12 @@ declare class NodeCacheStore<T> extends Hookified {
|
|
|
142
116
|
* @returns {void}
|
|
143
117
|
*/
|
|
144
118
|
disconnect(): Promise<void>;
|
|
119
|
+
/**
|
|
120
|
+
* Resolve the TTL to milliseconds.
|
|
121
|
+
* @param {number | string | undefined} ttl
|
|
122
|
+
* @returns {number | undefined}
|
|
123
|
+
*/
|
|
124
|
+
private resolveTtl;
|
|
145
125
|
}
|
|
146
126
|
|
|
147
127
|
type NodeCacheOptions = {
|
|
@@ -224,7 +204,6 @@ declare class NodeCache<T> extends Hookified {
|
|
|
224
204
|
readonly options: NodeCacheOptions;
|
|
225
205
|
readonly store: Map<string, NodeCacheItem<T>>;
|
|
226
206
|
private _stats;
|
|
227
|
-
private readonly _cacheable;
|
|
228
207
|
private intervalId;
|
|
229
208
|
constructor(options?: NodeCacheOptions);
|
|
230
209
|
/**
|
|
@@ -324,11 +303,12 @@ declare class NodeCache<T> extends Hookified {
|
|
|
324
303
|
* @returns {number | NodeJS.Timeout} the interval id
|
|
325
304
|
*/
|
|
326
305
|
getIntervalId(): number | NodeJS.Timeout;
|
|
306
|
+
startInterval(): void;
|
|
307
|
+
stopInterval(): void;
|
|
327
308
|
private formatKey;
|
|
309
|
+
private clone;
|
|
328
310
|
private getExpirationTimestamp;
|
|
329
|
-
private startInterval;
|
|
330
311
|
private checkData;
|
|
331
|
-
private stopInterval;
|
|
332
312
|
private createError;
|
|
333
313
|
}
|
|
334
314
|
|
package/dist/index.js
CHANGED
|
@@ -1,84 +1,50 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import {
|
|
2
|
+
import { Stats as Stats2, shorthandToTime } from "@cacheable/utils";
|
|
3
3
|
import { Hookified as Hookified2 } from "hookified";
|
|
4
4
|
|
|
5
5
|
// src/store.ts
|
|
6
|
-
import {
|
|
6
|
+
import { Stats, shorthandToMilliseconds } from "@cacheable/utils";
|
|
7
7
|
import { Hookified } from "hookified";
|
|
8
|
+
import Keyv from "keyv";
|
|
8
9
|
var NodeCacheStore = class extends Hookified {
|
|
9
10
|
_maxKeys = 0;
|
|
10
|
-
|
|
11
|
+
_keyv;
|
|
12
|
+
_stats;
|
|
13
|
+
_ttl;
|
|
11
14
|
constructor(options) {
|
|
12
15
|
super();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
stats: options.stats ?? true
|
|
19
|
-
};
|
|
20
|
-
this._cache = new Cacheable(cacheOptions);
|
|
21
|
-
if (options.maxKeys) {
|
|
22
|
-
this._maxKeys = options.maxKeys;
|
|
23
|
-
}
|
|
16
|
+
this._stats = new Stats({ enabled: options?.stats ?? true });
|
|
17
|
+
this._ttl = options?.ttl;
|
|
18
|
+
this._keyv = options?.store ?? new Keyv();
|
|
19
|
+
if (options?.maxKeys) {
|
|
20
|
+
this._maxKeys = options.maxKeys;
|
|
24
21
|
}
|
|
25
|
-
this.
|
|
22
|
+
this._keyv.on("error", (error) => {
|
|
26
23
|
this.emit("error", error);
|
|
27
24
|
});
|
|
28
25
|
}
|
|
29
|
-
/**
|
|
30
|
-
* Cacheable instance.
|
|
31
|
-
* @returns {Cacheable}
|
|
32
|
-
* @readonly
|
|
33
|
-
*/
|
|
34
|
-
get cache() {
|
|
35
|
-
return this._cache;
|
|
36
|
-
}
|
|
37
26
|
/**
|
|
38
27
|
* Time to live in milliseconds.
|
|
39
28
|
* @returns {number | string | undefined}
|
|
40
29
|
* @readonly
|
|
41
30
|
*/
|
|
42
31
|
get ttl() {
|
|
43
|
-
return this.
|
|
32
|
+
return this._ttl;
|
|
44
33
|
}
|
|
45
34
|
/**
|
|
46
35
|
* Time to live in milliseconds.
|
|
47
36
|
* @param {number | string | undefined} ttl
|
|
48
37
|
*/
|
|
49
38
|
set ttl(ttl) {
|
|
50
|
-
this.
|
|
39
|
+
this._ttl = ttl;
|
|
51
40
|
}
|
|
52
41
|
/**
|
|
53
|
-
*
|
|
42
|
+
* The Keyv store instance.
|
|
54
43
|
* @returns {Keyv<T>}
|
|
55
44
|
* @readonly
|
|
56
45
|
*/
|
|
57
|
-
get
|
|
58
|
-
return this.
|
|
59
|
-
}
|
|
60
|
-
/**
|
|
61
|
-
* Primary cache store.
|
|
62
|
-
* @param {Keyv<T>} primary
|
|
63
|
-
*/
|
|
64
|
-
set primary(primary) {
|
|
65
|
-
this._cache.primary = primary;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
69
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
70
|
-
* @returns {Keyv<T> | undefined}
|
|
71
|
-
*/
|
|
72
|
-
get secondary() {
|
|
73
|
-
return this._cache.secondary;
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Secondary cache store. Learn more about the secondary cache store in the
|
|
77
|
-
* [cacheable](https://github.com/jaredwray/cacheable/tree/main/packages/cacheable#storage-tiering-and-caching) documentation.
|
|
78
|
-
* @param {Keyv | undefined} secondary
|
|
79
|
-
*/
|
|
80
|
-
set secondary(secondary) {
|
|
81
|
-
this._cache.secondary = secondary;
|
|
46
|
+
get store() {
|
|
47
|
+
return this._keyv;
|
|
82
48
|
}
|
|
83
49
|
/**
|
|
84
50
|
* Maximum number of keys to store in the cache. if this is set to a value greater than 0,
|
|
@@ -97,7 +63,7 @@ var NodeCacheStore = class extends Hookified {
|
|
|
97
63
|
set maxKeys(maxKeys) {
|
|
98
64
|
this._maxKeys = maxKeys;
|
|
99
65
|
if (this._maxKeys > 0) {
|
|
100
|
-
this.
|
|
66
|
+
this._stats.enabled = true;
|
|
101
67
|
}
|
|
102
68
|
}
|
|
103
69
|
/**
|
|
@@ -109,11 +75,13 @@ var NodeCacheStore = class extends Hookified {
|
|
|
109
75
|
*/
|
|
110
76
|
async set(key, value, ttl) {
|
|
111
77
|
if (this._maxKeys > 0) {
|
|
112
|
-
if (this.
|
|
78
|
+
if (this._stats.count >= this._maxKeys) {
|
|
113
79
|
return false;
|
|
114
80
|
}
|
|
115
81
|
}
|
|
116
|
-
|
|
82
|
+
const finalTtl = this.resolveTtl(ttl);
|
|
83
|
+
await this._keyv.set(key.toString(), value, finalTtl);
|
|
84
|
+
this._stats.incrementCount();
|
|
117
85
|
return true;
|
|
118
86
|
}
|
|
119
87
|
/**
|
|
@@ -122,15 +90,11 @@ var NodeCacheStore = class extends Hookified {
|
|
|
122
90
|
* @returns {void}
|
|
123
91
|
*/
|
|
124
92
|
async mset(list) {
|
|
125
|
-
const items = [];
|
|
126
93
|
for (const item of list) {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
ttl: item.ttl
|
|
131
|
-
});
|
|
94
|
+
const finalTtl = this.resolveTtl(item.ttl);
|
|
95
|
+
await this._keyv.set(item.key.toString(), item.value, finalTtl);
|
|
96
|
+
this._stats.incrementCount();
|
|
132
97
|
}
|
|
133
|
-
await this._cache.setMany(items);
|
|
134
98
|
}
|
|
135
99
|
/**
|
|
136
100
|
* Get a value from the cache.
|
|
@@ -138,7 +102,13 @@ var NodeCacheStore = class extends Hookified {
|
|
|
138
102
|
* @returns {any | undefined}
|
|
139
103
|
*/
|
|
140
104
|
async get(key) {
|
|
141
|
-
|
|
105
|
+
const result = await this._keyv.get(key.toString());
|
|
106
|
+
if (result !== void 0) {
|
|
107
|
+
this._stats.incrementHits();
|
|
108
|
+
} else {
|
|
109
|
+
this._stats.incrementMisses();
|
|
110
|
+
}
|
|
111
|
+
return result;
|
|
142
112
|
}
|
|
143
113
|
/**
|
|
144
114
|
* Get multiple values from the cache.
|
|
@@ -148,7 +118,13 @@ var NodeCacheStore = class extends Hookified {
|
|
|
148
118
|
async mget(keys) {
|
|
149
119
|
const result = {};
|
|
150
120
|
for (const key of keys) {
|
|
151
|
-
|
|
121
|
+
const value = await this._keyv.get(key.toString());
|
|
122
|
+
if (value !== void 0) {
|
|
123
|
+
this._stats.incrementHits();
|
|
124
|
+
} else {
|
|
125
|
+
this._stats.incrementMisses();
|
|
126
|
+
}
|
|
127
|
+
result[key.toString()] = value;
|
|
152
128
|
}
|
|
153
129
|
return result;
|
|
154
130
|
}
|
|
@@ -158,7 +134,11 @@ var NodeCacheStore = class extends Hookified {
|
|
|
158
134
|
* @returns {boolean}
|
|
159
135
|
*/
|
|
160
136
|
async del(key) {
|
|
161
|
-
|
|
137
|
+
const deleted = await this._keyv.delete(key.toString());
|
|
138
|
+
if (deleted) {
|
|
139
|
+
this._stats.decreaseCount();
|
|
140
|
+
}
|
|
141
|
+
return deleted;
|
|
162
142
|
}
|
|
163
143
|
/**
|
|
164
144
|
* Delete multiple keys from the cache.
|
|
@@ -166,42 +146,77 @@ var NodeCacheStore = class extends Hookified {
|
|
|
166
146
|
* @returns {boolean}
|
|
167
147
|
*/
|
|
168
148
|
async mdel(keys) {
|
|
169
|
-
|
|
149
|
+
const deleted = await this._keyv.delete(keys.map((key) => key.toString()));
|
|
150
|
+
if (deleted) {
|
|
151
|
+
for (const _ of keys) {
|
|
152
|
+
this._stats.decreaseCount();
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
return deleted;
|
|
170
156
|
}
|
|
171
157
|
/**
|
|
172
158
|
* Clear the cache.
|
|
173
159
|
* @returns {void}
|
|
174
160
|
*/
|
|
175
161
|
async clear() {
|
|
176
|
-
|
|
162
|
+
await this._keyv.clear();
|
|
163
|
+
this._stats.resetStoreValues();
|
|
177
164
|
}
|
|
178
165
|
/**
|
|
179
|
-
*
|
|
166
|
+
* Set the TTL of an existing key in the cache.
|
|
180
167
|
* @param {string | number} key
|
|
168
|
+
* @param {number | string} [ttl]
|
|
181
169
|
* @returns {boolean}
|
|
182
170
|
*/
|
|
183
171
|
async setTtl(key, ttl) {
|
|
184
|
-
const item = await this.
|
|
172
|
+
const item = await this._keyv.get(key.toString());
|
|
185
173
|
if (item) {
|
|
186
|
-
|
|
174
|
+
const finalTtl = this.resolveTtl(ttl);
|
|
175
|
+
await this._keyv.set(key.toString(), item, finalTtl);
|
|
187
176
|
return true;
|
|
188
177
|
}
|
|
189
178
|
return false;
|
|
190
179
|
}
|
|
191
180
|
/**
|
|
192
|
-
*
|
|
181
|
+
* Get a key from the cache and delete it. If it does exist it will get the value and delete the item from the cache.
|
|
193
182
|
* @param {string | number} key
|
|
194
183
|
* @returns {T | undefined}
|
|
195
184
|
*/
|
|
196
185
|
async take(key) {
|
|
197
|
-
|
|
186
|
+
const result = await this._keyv.get(key.toString());
|
|
187
|
+
if (result !== void 0) {
|
|
188
|
+
this._stats.incrementHits();
|
|
189
|
+
await this._keyv.delete(key.toString());
|
|
190
|
+
this._stats.decreaseCount();
|
|
191
|
+
} else {
|
|
192
|
+
this._stats.incrementMisses();
|
|
193
|
+
}
|
|
194
|
+
return result;
|
|
198
195
|
}
|
|
199
196
|
/**
|
|
200
197
|
* Disconnect from the cache.
|
|
201
198
|
* @returns {void}
|
|
202
199
|
*/
|
|
203
200
|
async disconnect() {
|
|
204
|
-
await this.
|
|
201
|
+
await this._keyv.disconnect();
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Resolve the TTL to milliseconds.
|
|
205
|
+
* @param {number | string | undefined} ttl
|
|
206
|
+
* @returns {number | undefined}
|
|
207
|
+
*/
|
|
208
|
+
resolveTtl(ttl) {
|
|
209
|
+
const effectiveTtl = ttl ?? this._ttl;
|
|
210
|
+
if (effectiveTtl === void 0) {
|
|
211
|
+
return void 0;
|
|
212
|
+
}
|
|
213
|
+
if (typeof effectiveTtl === "string") {
|
|
214
|
+
return shorthandToMilliseconds(effectiveTtl);
|
|
215
|
+
}
|
|
216
|
+
if (effectiveTtl === 0) {
|
|
217
|
+
return void 0;
|
|
218
|
+
}
|
|
219
|
+
return effectiveTtl;
|
|
205
220
|
}
|
|
206
221
|
};
|
|
207
222
|
|
|
@@ -222,8 +237,7 @@ var NodeCache = class extends Hookified2 {
|
|
|
222
237
|
maxKeys: -1
|
|
223
238
|
};
|
|
224
239
|
store = /* @__PURE__ */ new Map();
|
|
225
|
-
_stats = new
|
|
226
|
-
_cacheable = new CacheableMemory();
|
|
240
|
+
_stats = new Stats2({ enabled: true });
|
|
227
241
|
intervalId = 0;
|
|
228
242
|
constructor(options) {
|
|
229
243
|
super();
|
|
@@ -308,13 +322,13 @@ var NodeCache = class extends Hookified2 {
|
|
|
308
322
|
}
|
|
309
323
|
this._stats.incrementHits();
|
|
310
324
|
if (this.options.useClones) {
|
|
311
|
-
return this.
|
|
325
|
+
return this.clone(result.value);
|
|
312
326
|
}
|
|
313
327
|
return result.value;
|
|
314
328
|
}
|
|
315
329
|
this._stats.incrementHits();
|
|
316
330
|
if (this.options.useClones) {
|
|
317
|
-
return this.
|
|
331
|
+
return this.clone(result.value);
|
|
318
332
|
}
|
|
319
333
|
return result.value;
|
|
320
334
|
}
|
|
@@ -348,7 +362,7 @@ var NodeCache = class extends Hookified2 {
|
|
|
348
362
|
if (result) {
|
|
349
363
|
this.del(key);
|
|
350
364
|
if (this.options.useClones) {
|
|
351
|
-
return this.
|
|
365
|
+
return this.clone(result);
|
|
352
366
|
}
|
|
353
367
|
return result;
|
|
354
368
|
}
|
|
@@ -467,7 +481,7 @@ var NodeCache = class extends Hookified2 {
|
|
|
467
481
|
* @returns {void}
|
|
468
482
|
*/
|
|
469
483
|
flushStats() {
|
|
470
|
-
this._stats = new
|
|
484
|
+
this._stats = new Stats2({ enabled: true });
|
|
471
485
|
this.emit("flush_stats");
|
|
472
486
|
}
|
|
473
487
|
/**
|
|
@@ -484,9 +498,35 @@ var NodeCache = class extends Hookified2 {
|
|
|
484
498
|
getIntervalId() {
|
|
485
499
|
return this.intervalId;
|
|
486
500
|
}
|
|
501
|
+
startInterval() {
|
|
502
|
+
if (this.options.checkperiod && this.options.checkperiod > 0) {
|
|
503
|
+
const checkPeriodinSeconds = this.options.checkperiod * 1e3;
|
|
504
|
+
this.intervalId = setInterval(() => {
|
|
505
|
+
this.checkData();
|
|
506
|
+
}, checkPeriodinSeconds).unref();
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
this.intervalId = 0;
|
|
510
|
+
}
|
|
511
|
+
stopInterval() {
|
|
512
|
+
if (this.intervalId !== 0) {
|
|
513
|
+
clearInterval(this.intervalId);
|
|
514
|
+
this.intervalId = 0;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
487
517
|
formatKey(key) {
|
|
488
518
|
return key.toString();
|
|
489
519
|
}
|
|
520
|
+
// biome-ignore lint/suspicious/noExplicitAny: type format
|
|
521
|
+
clone(value) {
|
|
522
|
+
if (value === null || value === void 0) {
|
|
523
|
+
return value;
|
|
524
|
+
}
|
|
525
|
+
if (typeof value !== "object") {
|
|
526
|
+
return value;
|
|
527
|
+
}
|
|
528
|
+
return structuredClone(value);
|
|
529
|
+
}
|
|
490
530
|
getExpirationTimestamp(ttlInSeconds) {
|
|
491
531
|
if (typeof ttlInSeconds === "string") {
|
|
492
532
|
return shorthandToTime(ttlInSeconds);
|
|
@@ -496,16 +536,6 @@ var NodeCache = class extends Hookified2 {
|
|
|
496
536
|
const expirationTimestamp = currentTimestamp + ttlInMilliseconds;
|
|
497
537
|
return expirationTimestamp;
|
|
498
538
|
}
|
|
499
|
-
startInterval() {
|
|
500
|
-
if (this.options.checkperiod && this.options.checkperiod > 0) {
|
|
501
|
-
const checkPeriodinSeconds = this.options.checkperiod * 1e3;
|
|
502
|
-
this.intervalId = setInterval(() => {
|
|
503
|
-
this.checkData();
|
|
504
|
-
}, checkPeriodinSeconds).unref();
|
|
505
|
-
return;
|
|
506
|
-
}
|
|
507
|
-
this.intervalId = 0;
|
|
508
|
-
}
|
|
509
539
|
checkData() {
|
|
510
540
|
for (const [key, value] of this.store.entries()) {
|
|
511
541
|
if (value.ttl > 0 && value.ttl < Date.now()) {
|
|
@@ -516,12 +546,6 @@ var NodeCache = class extends Hookified2 {
|
|
|
516
546
|
}
|
|
517
547
|
}
|
|
518
548
|
}
|
|
519
|
-
stopInterval() {
|
|
520
|
-
if (this.intervalId !== 0) {
|
|
521
|
-
clearInterval(this.intervalId);
|
|
522
|
-
this.intervalId = 0;
|
|
523
|
-
}
|
|
524
|
-
}
|
|
525
549
|
createError(errorCode, key) {
|
|
526
550
|
let error = errorCode;
|
|
527
551
|
if (key) {
|
package/package.json
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cacheable/node-cache",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Simple and Maintained fast NodeJS internal caching",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/index.
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
7
|
"module": "./dist/index.js",
|
|
8
8
|
"types": "./dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"
|
|
12
|
-
|
|
11
|
+
"import": {
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
},
|
|
15
|
+
"require": {
|
|
16
|
+
"types": "./dist/index.d.cts",
|
|
17
|
+
"default": "./dist/index.cjs"
|
|
18
|
+
}
|
|
13
19
|
}
|
|
14
20
|
},
|
|
15
21
|
"engines": {
|
|
@@ -34,19 +40,19 @@
|
|
|
34
40
|
"cacheable-node"
|
|
35
41
|
],
|
|
36
42
|
"devDependencies": {
|
|
37
|
-
"@biomejs/biome": "^2.3.
|
|
43
|
+
"@biomejs/biome": "^2.3.8",
|
|
38
44
|
"@faker-js/faker": "^10.1.0",
|
|
39
|
-
"@types/node": "^
|
|
40
|
-
"@vitest/coverage-v8": "^4.0.
|
|
41
|
-
"rimraf": "^6.1.
|
|
45
|
+
"@types/node": "^25.0.2",
|
|
46
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
47
|
+
"rimraf": "^6.1.2",
|
|
42
48
|
"tsup": "^8.5.1",
|
|
43
49
|
"typescript": "^5.9.3",
|
|
44
|
-
"vitest": "^4.0.
|
|
50
|
+
"vitest": "^4.0.15"
|
|
45
51
|
},
|
|
46
52
|
"dependencies": {
|
|
47
|
-
"hookified": "^1.
|
|
48
|
-
"keyv": "^5.5.
|
|
49
|
-
"cacheable": "^2.
|
|
53
|
+
"hookified": "^1.14.0",
|
|
54
|
+
"keyv": "^5.5.5",
|
|
55
|
+
"@cacheable/utils": "^2.3.3"
|
|
50
56
|
},
|
|
51
57
|
"files": [
|
|
52
58
|
"dist",
|