@cacheable/node-cache 1.5.6 → 1.5.8

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 CHANGED
@@ -13,18 +13,18 @@
13
13
  `@cacheable/node-cache` is compatible with the [node-cache](https://www.npmjs.com/package/node-cache) package with regular maintenance and additional functionality (async/await and storage adapters). The only thing not implemented is the `enableLegacyCallbacks` option and functions. If you need them we are happy to take a PR to add them.
14
14
 
15
15
  * Fully Compatible with `node-cache` using `{NodeCache}`
16
+ * Faster than the original `node-cache` package 🚀
16
17
  * Async/Await functionality with `{NodeCacheStore}`
17
18
  * Storage Adapters via [Keyv](https://keyv.org) with `{NodeCacheStore}`
18
19
  * Maintained and Updated Regularly! 🎉
19
20
 
20
- Note: `NodeCache` is ready and available for use. `NodeCacheStore` is in progress and will be available soon. Please do not use it until it is released.
21
-
22
21
  # Table of Contents
23
22
  * [Getting Started](#getting-started)
24
23
  * [Basic Usage](#basic-usage)
25
- * [Advanced Usage](#advanced-usage)
24
+ * [NodeCache Performance](#nodecache-performance)
25
+ * [NodeCache API](#nodecache-api)
26
26
  * [NodeCacheStore](#nodecachestore)
27
- * [API](#api)
27
+ * [NodeCacheStore API](#nodecachestore-api)
28
28
  * [How to Contribute](#how-to-contribute)
29
29
  * [License and Copyright](#license-and-copyright)
30
30
 
@@ -50,7 +50,7 @@ cache.del('foo'); // true
50
50
  cache.set('bar', 'baz', '35m'); // 35 minutes using shorthand
51
51
  ```
52
52
 
53
- # NodeCache Not Default Export
53
+ The `NodeCache` is not the default export, so you need to import it like this:
54
54
 
55
55
  ```javascript
56
56
  import {NodeCache} from '@cacheable/node-cache';
@@ -60,77 +60,16 @@ cache.set('foo', 'bar');
60
60
  cache.get('foo'); // 'bar'
61
61
  ```
62
62
 
63
- # Advanced Usage
64
-
65
- ```javascript
66
- import {NodeStorageCache} from '@cacheable/node-cache';
67
- import {Keyv} from 'keyv';
68
- import {KeyvRedis} from '@keyv/redis';
69
-
70
- const storage = new Keyv({store: new KeyvRedis('redis://user:pass@localhost:6379')});
71
- const cache = new NodeStorageCache(storage);
72
-
73
- // with storage you have the same functionality as the NodeCache but will be using async/await
74
- await cache.set('foo', 'bar');
75
- await cache.get('foo'); // 'bar'
76
-
77
- // if you call getStats() this will now only be for the single instance of the adapter as it is in memory
78
- cache.getStats(); // {hits: 1, misses: 1, keys: 1, ksize: 2, vsize: 3}
79
- ```
80
-
81
- # NodeCacheStore
82
-
83
- The `NodeCacheStore` is a class that extends the `NodeCache` and adds the ability to use storage adapters. This is based on the `cacheable` engine and allows you to do layer 1 and layer 2 caching. The storage adapters are based on the [Keyv](https://keyv.org) package. This allows you to use any of the storage adapters that are available.
84
-
85
- ```javascript
86
- import {NodeCacheStore} from '@cacheable/node-cache';
87
-
88
- const cache = new NodeCacheStore();
89
- cache.set('foo', 'bar');
90
- cache.get('foo'); // 'bar'
91
- ```
92
-
93
- ## NodeCacheStoreOptions
94
-
95
- When initializing the cache you can pass in the options below:
96
-
97
- ```javascript
98
- export type NodeCacheStoreOptions = {
99
- ttl?: number; // The standard ttl as number in milliseconds for every generated cache element. 0 = unlimited
100
- primary?: Keyv; // The primary storage adapter
101
- secondary?: Keyv; // The secondary storage adapter
102
- maxKeys?: number; // Default is 0 (unlimited). If this is set it will throw and error if you try to set more keys than the max.
103
- stats?: boolean; // Default is true, if this is set to false it will not track stats
104
- };
105
- ```
106
-
107
- Note: the `ttl` is now in milliseconds and not seconds like `stdTTL` in `NodeCache`. You can learn more about using shorthand also in the [cacheable documentation](https://github.com/jaredwray/cacheable/blob/main/packages/cacheable/README.md#shorthand-for-time-to-live-ttl). as it is fulling supported. Here is an example:
63
+ # NodeCache Performance
108
64
 
109
- ```javascript
110
- const cache = new NodeCacheStore({ttl: 60000 }); // 1 minute as it defaults to milliseconds
111
- cache.set('foo', 'bar', '1h'); // 1 hour
112
- cache.set('longfoo', 'bar', '1d'); // 1 day
113
- ```
114
-
115
- ## Node Cache Store API
65
+ The performance is comparable if not faster to the original `node-cache` package, but with additional features and improvements.
116
66
 
117
- * `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 0 (no ttl)
118
- * `mset(data: Array<NodeCacheItem>): Promise<boolean>` - Set multiple key value pairs at once
119
- * `get<T>(key: string | number): Promise<T>` - Get a value from the cache by key
120
- * `mget(keys: Array<string | number>): Promise<Record<string, unknown>>` - Get multiple values from the cache by keys
121
- * `take<T>(key: string | number): Promise<T>` - Get a value from the cache by key and delete it
122
- * `del(key: string | number): Promise<boolean>` - Delete a key
123
- * `mdel(keys: Array<string | number>): Promise<boolean>` - Delete multiple keys
124
- * `clear(): Promise<void>` - Clear the cache
125
- * `setTtl(key: string | number, ttl: number): Promise<boolean>` - Set the ttl of a key
126
- * `disconnect(): Promise<void>` - Disconnect the storage adapters
127
- * `stats`: `NodeCacheStats` - Get the stats of the cache
128
- * `ttl`: `number` | `string` - The standard ttl as number in seconds for every generated cache element. `< 0` or `undefined` = unlimited
129
- * `primary`: `Keyv` - The primary storage adapter
130
- * `secondary`: `Keyv` - The secondary storage adapter
131
- * `maxKeys`: `number` - If this is set it will throw and error if you try to set more keys than the max
67
+ | name | summary | ops/sec | time/op | margin | samples |
68
+ |-----------------------------------|:---------:|----------:|----------:|:--------:|----------:|
69
+ | Cacheable NodeCache - set / get | 🥇 | 117K | 9µs | ±1.01% | 111K |
70
+ | Node Cache - set / get | -4.6% | 112K | 9µs | ±1.31% | 106K |
132
71
 
133
- # API
72
+ # NodeCache API
134
73
 
135
74
  ## `constructor(options?: NodeCacheOptions)`
136
75
 
@@ -138,14 +77,24 @@ Create a new cache instance. You can pass in options to set the configuration:
138
77
 
139
78
  ```javascript
140
79
  export type NodeCacheOptions = {
141
- stdTTL?: number; // The standard ttl as number in seconds for every generated cache element. 0 = unlimited. If string, it will be parsed as shorthand and default to milliseconds if it is a number as a string.
142
- checkperiod?: number; // Default is 600, 0 means no periodic check
143
- useClones?: boolean; // Default is true
144
- deleteOnExpire?: boolean; // Default is true, if false it will keep the key and not delete during an interval check and the value on get() will be undefined
145
- maxKeys?: number; // Default is -1 (unlimited). If this is set it will throw and error if you try to set more keys than the max.
80
+ stdTTL?: number;
81
+ checkperiod?: number;
82
+ useClones?: boolean;
83
+ deleteOnExpire?: boolean;
84
+ maxKeys?: number;
146
85
  };
147
86
  ```
148
87
 
88
+ Here is a description of the options:
89
+
90
+ | Option | Default Setting | Description |
91
+ |--------|----------------|-------------|
92
+ | `stdTTL` | `0` | The standard time to live (TTL) in seconds for every generated cache element. If set to `0`, it means unlimited. If a string is provided, it will be parsed as shorthand and default to milliseconds if it is a number as a string. |
93
+ | `checkperiod` | `600` | The interval in seconds to check for expired keys. If set to `0`, it means no periodic check will be performed. |
94
+ | `useClones` | `true` | If set to `true`, the cache will clone the returned items via `get()` functions. This means that every time you set a value into the cache, `node-cache` makes a deep clone of it. When you get that value back, you receive another deep clone. This mimics the behavior of an external cache like Redis or Memcached, meaning mutations to the returned object do not affect the cached copy (and vice versa). If set to `false`, the original object will be returned, and mutations will affect the cached copy. |
95
+ | `deleteOnExpire` | `true` | If set to `true`, the key will be deleted when it expires. If set to `false`, the key will remain in the cache, but the value returned by `get()` will be `undefined`. You can manage the key with the `on('expired')` event. |
96
+ | `maxKeys` | `-1` | If set to a positive number, it will limit the number of keys in the cache. If the number of keys exceeds this limit, it will throw an error when trying to set more keys than the maximum. If set to `-1`, it means unlimited keys are allowed. |
97
+
149
98
  When initializing the cache you can pass in the options to set the configuration like the example below where we set the `stdTTL` to 10 seconds and `checkperiod` to 5 seconds.:
150
99
 
151
100
  ```javascript
@@ -161,7 +110,7 @@ cache.on('expired', (key, value) => {
161
110
  });
162
111
  ```
163
112
 
164
- ## `.set(key: string | number, value: any, ttl?: number): boolean`
113
+ ## `set(key: string | number, value: any, ttl?: number): boolean`
165
114
 
166
115
  Set a key value pair with an optional ttl (in seconds). Will return true on success. If the ttl is not set it will default to 0 (no ttl).
167
116
 
@@ -169,7 +118,7 @@ Set a key value pair with an optional ttl (in seconds). Will return true on succ
169
118
  cache.set('foo', 'bar', 10); // true
170
119
  ```
171
120
 
172
- ## `.mset(data: Array<NodeCacheItem>): boolean`
121
+ ## `mset(data: Array<NodeCacheItem>): boolean`
173
122
 
174
123
  Set multiple key value pairs at once. This will take an array of objects with the key, value, and optional ttl.
175
124
 
@@ -187,7 +136,7 @@ export type NodeCacheItem = {
187
136
  };
188
137
  ```
189
138
 
190
- ## `.get(key: string | number): any`
139
+ ## `get<T>(key: string | number): T | undefined`
191
140
 
192
141
  Get a value from the cache by key. If the key does not exist it will return `undefined`.
193
142
 
@@ -195,7 +144,7 @@ Get a value from the cache by key. If the key does not exist it will return `und
195
144
  cache.get('foo'); // 'bar'
196
145
  ```
197
146
 
198
- ## `mget(keys: Array<string | number>): Record<string, unknown>`
147
+ ## `mget<T>(keys: Array<string | number>): Record<string, T | undefined>`
199
148
 
200
149
  Get multiple values from the cache by keys. This will return an object with the keys and values.
201
150
 
@@ -207,7 +156,7 @@ cache.set('my2', obj2);
207
156
  cache.mget(['my', 'my2']); // { my: { my: 'value', my2: 'value2' }, my2: { special: 'value3', life: 'value4' } }
208
157
  ```
209
158
 
210
- ## `take(key: string | number): any`
159
+ ## `take<T>(key: string | number): T | undefined`
211
160
 
212
161
  Get a value from the cache by key and delete it. If the key does not exist it will return `undefined`.
213
162
 
@@ -231,7 +180,7 @@ passing in an array of keys:
231
180
  cache.del(['foo', 'bar']); // true
232
181
  ```
233
182
 
234
- ## `.mdel(keys: Array<string | number>): number`
183
+ ## `mdel(keys: Array<string | number>): number`
235
184
 
236
185
  Delete multiple keys from the cache. Will return the number of deleted entries and never fail.
237
186
 
@@ -239,7 +188,7 @@ Delete multiple keys from the cache. Will return the number of deleted entries a
239
188
  cache.mdel(['foo', 'bar']); // true
240
189
  ```
241
190
 
242
- ## `.ttl(key: string | number, ttl?: number): boolean`
191
+ ## `ttl(key: string | number, ttl?: number): boolean`
243
192
 
244
193
  Redefine the ttl of a key. Returns true if the key has been found and changed. Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used.
245
194
 
@@ -264,12 +213,12 @@ cache.set('foo', 'bar');
264
213
  cache.has('foo'); // true
265
214
  ```
266
215
 
267
- ## `keys(): Array<string>`
216
+ ## `keys(): string[]`
268
217
 
269
218
  Get all keys from the cache.
270
219
 
271
220
  ```javascript
272
- cache.keys(); // ['foo', 'bar']
221
+ await cache.keys(); // ['foo', 'bar']
273
222
  ```
274
223
 
275
224
  ## `getStats(): NodeCacheStats`
@@ -286,7 +235,7 @@ Flush the cache. Will remove all keys and reset the stats.
286
235
 
287
236
  ```javascript
288
237
  cache.flushAll();
289
- cache.keys(); // []
238
+ await cache.keys(); // []
290
239
  cache.getStats(); // {hits: 0, misses: 0, keys: 0, ksize: 0, vsize: 0}
291
240
  ```
292
241
 
@@ -295,18 +244,10 @@ cache.getStats(); // {hits: 0, misses: 0, keys: 0, ksize: 0, vsize: 0}
295
244
  Flush the stats. Will reset the stats but keep the keys.
296
245
 
297
246
  ```javascript
298
- cache.set('foo', 'bar');
247
+ await cache.set('foo', 'bar');
299
248
  cache.flushStats();
300
249
  cache.getStats(); // {hits: 0, misses: 0, keys: 0, ksize: 0, vsize: 0}
301
- cache.keys(); // ['foo']
302
- ```
303
-
304
- ## `close(): void`
305
-
306
- this will stop the interval that is running for the `checkperiod` and `deleteOnExpire` options.
307
-
308
- ```javascript
309
- cache.close();
250
+ await cache.keys(); // ['foo']
310
251
  ```
311
252
 
312
253
  ## `on(event: string, callback: Function): void`
@@ -324,9 +265,78 @@ cache.on('set', (key, value) => {
324
265
  });
325
266
  ```
326
267
 
268
+ # NodeCacheStore
269
+
270
+ `NodeCacheStore` has a similar API to `NodeCache` but it is using `async / await` as it uses the `Keyv` storage adapters under the hood. This means that you can use all the storage adapters that are 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).
271
+
272
+ ```javascript
273
+ import {NodeCacheStore} from '@cacheable/node-cache';
274
+
275
+ const cache = new NodeCacheStore();
276
+ await cache.set('foo', 'bar');
277
+ await cache.get('foo'); // 'bar'
278
+ ```
279
+
280
+ Here is an example of how to use the `NodeCacheStore` with a primary and secondary storage adapter:
281
+
282
+ ```javascript
283
+ import {NodeStorageCache} from '@cacheable/node-cache';
284
+ import {Keyv} from 'keyv';
285
+ import {KeyvRedis} from '@keyv/redis';
286
+
287
+ const primary = new Keyv(); // In-memory storage as primary
288
+ const secondary = new Keyv({store: new KeyvRedis('redis://user:pass@localhost:6379')});
289
+ const cache = new NodeStorageCache({primary, secondary});
290
+
291
+ // with storage you have the same functionality as the NodeCache but will be using async/await
292
+ await cache.set('foo', 'bar');
293
+ await cache.get('foo'); // 'bar'
294
+
295
+ // if you call getStats() this will now only be for the single instance of the adapter as it is in memory
296
+ cache.getStats(); // {hits: 1, misses: 1, keys: 1, ksize: 2, vsize: 3}
297
+ ```
298
+
299
+ When initializing the cache you can pass in the options below:
300
+
301
+ ```javascript
302
+ export type NodeCacheStoreOptions = {
303
+ ttl?: number; // The standard ttl as number in milliseconds for every generated cache element. 0 = unlimited
304
+ primary?: Keyv; // The primary storage adapter
305
+ secondary?: Keyv; // The secondary storage adapter
306
+ maxKeys?: number; // Default is 0 (unlimited). If this is set it will throw and error if you try to set more keys than the max.
307
+ stats?: boolean; // Default is true, if this is set to false it will not track stats
308
+ };
309
+ ```
310
+
311
+ Note: the `ttl` is now in milliseconds and not seconds like `stdTTL` in `NodeCache`. You can learn more about using shorthand also in the [cacheable documentation](https://github.com/jaredwray/cacheable/blob/main/packages/cacheable/README.md#shorthand-for-time-to-live-ttl) as it is fully supported. Here is an example:
312
+
313
+ ```javascript
314
+ const cache = new NodeCacheStore({ttl: 60000 }); // 1 minute as it defaults to milliseconds
315
+ await cache.set('foo', 'bar', '1h'); // 1 hour
316
+ await cache.set('longfoo', 'bar', '1d'); // 1 day
317
+ ```
318
+
319
+ ## NodeCacheStore API
320
+
321
+ * `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 0 (no ttl)
322
+ * `mset(data: Array<NodeCacheItem>): Promise<boolean>` - Set multiple key value pairs at once
323
+ * `get<T>(key: string | number): Promise<T>` - Get a value from the cache by key
324
+ * `mget(keys: Array<string | number>): Promise<Record<string, unknown>>` - Get multiple values from the cache by keys
325
+ * `take<T>(key: string | number): Promise<T>` - Get a value from the cache by key and delete it
326
+ * `del(key: string | number): Promise<boolean>` - Delete a key
327
+ * `mdel(keys: Array<string | number>): Promise<boolean>` - Delete multiple keys
328
+ * `clear(): Promise<void>` - Clear the cache
329
+ * `setTtl(key: string | number, ttl: number): Promise<boolean>` - Set the ttl of a key
330
+ * `disconnect(): Promise<void>` - Disconnect the storage adapters
331
+ * `stats`: `NodeCacheStats` - Get the stats of the cache
332
+ * `ttl`: `number` | `string` - The standard ttl as number in seconds for every generated cache element. `< 0` or `undefined` = unlimited
333
+ * `primary`: `Keyv` - The primary storage adapter
334
+ * `secondary`: `Keyv` - The secondary storage adapter
335
+ * `maxKeys`: `number` - If this is set it will throw and error if you try to set more keys than the max
336
+
327
337
  # How to Contribute
328
338
 
329
339
  You can contribute by forking the repo and submitting a pull request. Please make sure to add tests and update the documentation. To learn more about how to contribute go to our main README [https://github.com/jaredwray/cacheable](https://github.com/jaredwray/cacheable). This will talk about how to `Open a Pull Request`, `Ask a Question`, or `Post an Issue`.
330
340
 
331
341
  # License and Copyright
332
- [MIT © Jared Wray](./LICENSE)
342
+ [MIT © Jared Wray](./LICENSE)
package/dist/index.cjs CHANGED
@@ -215,7 +215,7 @@ var NodeCacheStore = class extends import_hookified.Hookified {
215
215
  /**
216
216
  * Check if a key exists in the cache. If it does exist it will get the value and delete the item from the cache.
217
217
  * @param {string | number} key
218
- * @returns {any | undefined}
218
+ * @returns {T | undefined}
219
219
  */
220
220
  async take(key) {
221
221
  return this._cache.take(key.toString());
package/dist/index.d.cts CHANGED
@@ -134,7 +134,7 @@ declare class NodeCacheStore extends Hookified {
134
134
  /**
135
135
  * Check if a key exists in the cache. If it does exist it will get the value and delete the item from the cache.
136
136
  * @param {string | number} key
137
- * @returns {any | undefined}
137
+ * @returns {T | undefined}
138
138
  */
139
139
  take<T>(key: string | number): Promise<T | undefined>;
140
140
  /**
@@ -154,7 +154,12 @@ type NodeCacheOptions = {
154
154
  */
155
155
  checkperiod?: number;
156
156
  /**
157
- * Clones the returned items via get functions. Default is true.
157
+ * If set to true (Default Setting), the cache will clone the returned items via get() functions.
158
+ * This means that every time you set a value into the cache, node-cache makes a deep clone of it.
159
+ * When you get that value back, you receive another deep clone.
160
+ * This mimics the behavior of an external cache like Redis or Memcached, meaning mutations to the
161
+ * returned object do not affect the cached copy (and vice versa). If set to false, the original
162
+ * object will be returned, and mutations will affect the cached copy.
158
163
  */
159
164
  useClones?: boolean;
160
165
  /**
package/dist/index.d.ts CHANGED
@@ -134,7 +134,7 @@ declare class NodeCacheStore extends Hookified {
134
134
  /**
135
135
  * Check if a key exists in the cache. If it does exist it will get the value and delete the item from the cache.
136
136
  * @param {string | number} key
137
- * @returns {any | undefined}
137
+ * @returns {T | undefined}
138
138
  */
139
139
  take<T>(key: string | number): Promise<T | undefined>;
140
140
  /**
@@ -154,7 +154,12 @@ type NodeCacheOptions = {
154
154
  */
155
155
  checkperiod?: number;
156
156
  /**
157
- * Clones the returned items via get functions. Default is true.
157
+ * If set to true (Default Setting), the cache will clone the returned items via get() functions.
158
+ * This means that every time you set a value into the cache, node-cache makes a deep clone of it.
159
+ * When you get that value back, you receive another deep clone.
160
+ * This mimics the behavior of an external cache like Redis or Memcached, meaning mutations to the
161
+ * returned object do not affect the cached copy (and vice versa). If set to false, the original
162
+ * object will be returned, and mutations will affect the cached copy.
158
163
  */
159
164
  useClones?: boolean;
160
165
  /**
package/dist/index.js CHANGED
@@ -188,7 +188,7 @@ var NodeCacheStore = class extends Hookified {
188
188
  /**
189
189
  * Check if a key exists in the cache. If it does exist it will get the value and delete the item from the cache.
190
190
  * @param {string | number} key
191
- * @returns {any | undefined}
191
+ * @returns {T | undefined}
192
192
  */
193
193
  async take(key) {
194
194
  return this._cache.take(key.toString());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cacheable/node-cache",
3
- "version": "1.5.6",
3
+ "version": "1.5.8",
4
4
  "description": "Simple and Maintained fast NodeJS internal caching",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -31,18 +31,19 @@
31
31
  "cacheable-node"
32
32
  ],
33
33
  "devDependencies": {
34
- "@types/node": "^22.15.30",
35
- "@vitest/coverage-v8": "^3.2.2",
34
+ "@types/eslint": "^9.6.1",
35
+ "@types/node": "^24.0.7",
36
+ "@vitest/coverage-v8": "^3.2.4",
36
37
  "rimraf": "^6.0.1",
37
38
  "tsup": "^8.5.0",
38
39
  "typescript": "^5.8.3",
39
- "vitest": "^3.2.2",
40
- "xo": "^1.1.0"
40
+ "vitest": "^3.2.4",
41
+ "xo": "^1.1.1"
41
42
  },
42
43
  "dependencies": {
43
- "hookified": "^1.9.1",
44
- "keyv": "^5.3.3",
45
- "cacheable": "^1.10.0"
44
+ "hookified": "^1.10.0",
45
+ "keyv": "^5.3.4",
46
+ "cacheable": "^1.10.1"
46
47
  },
47
48
  "files": [
48
49
  "dist",
@@ -52,7 +53,7 @@
52
53
  "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean",
53
54
  "prepublish": "pnpm build",
54
55
  "test": "xo --fix && vitest run --coverage",
55
- "test:ci": "xo && vitest run",
56
+ "test:ci": "xo && vitest run --coverage",
56
57
  "clean": "rimraf ./dist ./coverage ./node_modules"
57
58
  }
58
59
  }