@cacheable/node-cache 0.8.0 → 1.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 CHANGED
@@ -22,6 +22,7 @@ Note: `NodeCache` is ready and available for use. `NodeCacheStore` is in progres
22
22
  * [Getting Started](#getting-started)
23
23
  * [Basic Usage](#basic-usage)
24
24
  * [Advanced Usage](#advanced-usage)
25
+ * [NodeCacheStore](#nodecachestore)
25
26
  * [API](#api)
26
27
  * [How to Contribute](#how-to-contribute)
27
28
  * [License and Copyright](#license-and-copyright)
@@ -60,6 +61,46 @@ await cache.get('foo'); // 'bar'
60
61
  cache.getStats(); // {hits: 1, misses: 1, keys: 1, ksize: 2, vsize: 3}
61
62
  ```
62
63
 
64
+ ## NodeCacheStore
65
+
66
+ 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.
67
+
68
+ ```javascript
69
+ import {NodeCacheStore} from '@cacheable/node-cache';
70
+
71
+ const cache = new NodeCacheStore();
72
+ cache.set('foo', 'bar');
73
+ cache.get('foo'); // 'bar'
74
+ ```
75
+
76
+ ### NodeCacheStoreOptions
77
+
78
+ When initializing the cache you can pass in the options below:
79
+
80
+ ```javascript
81
+ export type NodeCacheStoreOptions = {
82
+ ttl?: number; // The standard ttl as number in seconds for every generated cache element. 0 = unlimited
83
+ primary?: Keyv; // The primary storage adapter
84
+ secondary?: Keyv; // The secondary storage adapter
85
+ 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.
86
+ };
87
+ ```
88
+
89
+ ### Node Cache Store API
90
+
91
+ * `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)
92
+ * `mset(data: Array<NodeCacheItem>): Promise<boolean>` - Set multiple key value pairs at once
93
+ * `get(key: string | number): Promise<any>` - Get a value from the cache by key
94
+ * `mget(keys: Array<string | number>): Promise<Record<string, unknown>>` - Get multiple values from the cache by keys
95
+ * `del(key: string | number): Promise<boolean>` - Delete a key
96
+ * `mdel(keys: Array<string | number>): Promise<boolean>` - Delete multiple keys
97
+ * `clear(): Promise<void>` - Clear the cache
98
+ * `stats`: `NodeCacheStats` - Get the stats of the cache
99
+ * `ttl`: `number` - The standard ttl as number in seconds for every generated cache element. 0 = unlimited
100
+ * `primary`: `Keyv` - The primary storage adapter
101
+ * `secondary`: `Keyv` - The secondary storage adapter
102
+ * `maxKeys`: `number` - If this is set it will throw and error if you try to set more keys than the max
103
+
63
104
  ## API
64
105
 
65
106
  ### `constructor(options?: NodeCacheOptions)`
package/dist/index.cjs CHANGED
@@ -31,10 +31,105 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
31
31
  var src_exports = {};
32
32
  __export(src_exports, {
33
33
  NodeCacheErrors: () => NodeCacheErrors,
34
+ NodeCacheStore: () => NodeCacheStore,
34
35
  default: () => NodeCache
35
36
  });
36
37
  module.exports = __toCommonJS(src_exports);
37
38
  var import_eventemitter3 = __toESM(require("eventemitter3"), 1);
39
+ var import_cacheable2 = require("cacheable");
40
+
41
+ // src/store.ts
42
+ var import_cacheable = require("cacheable");
43
+ var import_keyv = require("keyv");
44
+ var NodeCacheStore = class {
45
+ _maxKeys = 0;
46
+ _cache = new import_cacheable.Cacheable({ primary: new import_keyv.Keyv({ store: new import_cacheable.CacheableMemory() }) });
47
+ constructor(options) {
48
+ if (options) {
49
+ const cacheOptions = {
50
+ ttl: options.ttl,
51
+ primary: options.primary,
52
+ secondary: options.secondary
53
+ };
54
+ this._cache = new import_cacheable.Cacheable(cacheOptions);
55
+ if (options.maxKeys) {
56
+ this._maxKeys = options.maxKeys;
57
+ if (this._maxKeys > 0) {
58
+ this._cache.stats.enabled = true;
59
+ }
60
+ }
61
+ }
62
+ }
63
+ get cache() {
64
+ return this._cache;
65
+ }
66
+ get ttl() {
67
+ return this._cache.ttl;
68
+ }
69
+ set ttl(ttl) {
70
+ this._cache.ttl = ttl;
71
+ }
72
+ get primary() {
73
+ return this._cache.primary;
74
+ }
75
+ set primary(primary) {
76
+ this._cache.primary = primary;
77
+ }
78
+ get secondary() {
79
+ return this._cache.secondary;
80
+ }
81
+ set secondary(secondary) {
82
+ this._cache.secondary = secondary;
83
+ }
84
+ get maxKeys() {
85
+ return this._maxKeys;
86
+ }
87
+ set maxKeys(maxKeys) {
88
+ this._maxKeys = maxKeys;
89
+ if (this._maxKeys > 0) {
90
+ this._cache.stats.enabled = true;
91
+ }
92
+ }
93
+ async set(key, value, ttl) {
94
+ if (this._maxKeys > 0) {
95
+ console.log(this._cache.stats.count, this._maxKeys);
96
+ if (this._cache.stats.count >= this._maxKeys) {
97
+ return false;
98
+ }
99
+ }
100
+ const finalTtl = ttl ?? this._cache.ttl;
101
+ await this._cache.set(key.toString(), value, finalTtl);
102
+ return true;
103
+ }
104
+ async mset(list) {
105
+ const items = new Array();
106
+ for (const item of list) {
107
+ items.push({ key: item.key.toString(), value: item.value, ttl: item.ttl });
108
+ }
109
+ await this._cache.setMany(items);
110
+ }
111
+ async get(key) {
112
+ return this._cache.get(key.toString());
113
+ }
114
+ async mget(keys) {
115
+ const result = {};
116
+ for (const key of keys) {
117
+ result[key.toString()] = await this._cache.get(key.toString());
118
+ }
119
+ return result;
120
+ }
121
+ async del(key) {
122
+ return this._cache.delete(key.toString());
123
+ }
124
+ async mdel(keys) {
125
+ return this._cache.deleteMany(keys.map((key) => key.toString()));
126
+ }
127
+ async clear() {
128
+ return this._cache.clear();
129
+ }
130
+ };
131
+
132
+ // src/index.ts
38
133
  var NodeCacheErrors = /* @__PURE__ */ ((NodeCacheErrors2) => {
39
134
  NodeCacheErrors2["ECACHEFULL"] = "Cache max keys amount exceeded";
40
135
  NodeCacheErrors2["EKEYTYPE"] = "The key argument has to be of type `string` or `number`. Found: `__key`";
@@ -52,13 +147,8 @@ var NodeCache = class extends import_eventemitter3.default {
52
147
  maxKeys: -1
53
148
  };
54
149
  store = /* @__PURE__ */ new Map();
55
- _stats = {
56
- keys: 0,
57
- hits: 0,
58
- misses: 0,
59
- ksize: 0,
60
- vsize: 0
61
- };
150
+ _stats = new import_cacheable2.CacheableStats({ enabled: true });
151
+ _cacheable = new import_cacheable2.CacheableMemory();
62
152
  intervalId = 0;
63
153
  constructor(options) {
64
154
  super();
@@ -89,9 +179,9 @@ var NodeCache = class extends import_eventemitter3.default {
89
179
  }
90
180
  this.store.set(keyValue, { key: keyValue, value, ttl: expirationTimestamp });
91
181
  this.emit("set", keyValue, value, ttlValue);
92
- this._stats.ksize += this.roughSizeOfKey(keyValue);
93
- this._stats.vsize += this.roughSizeOfObject(value);
94
- this._stats.keys = this.store.size;
182
+ this._stats.incrementKSize(keyValue);
183
+ this._stats.incrementVSize(value);
184
+ this._stats.setCount(this.store.size);
95
185
  return true;
96
186
  }
97
187
  // Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success.
@@ -113,23 +203,23 @@ var NodeCache = class extends import_eventemitter3.default {
113
203
  if (this.options.deleteOnExpire) {
114
204
  this.del(key);
115
205
  }
116
- this.addMiss();
206
+ this._stats.incrementMisses();
117
207
  this.emit("expired", this.formatKey(key), result.value);
118
208
  return void 0;
119
209
  }
120
- this.addHit();
210
+ this._stats.incrementHits();
121
211
  if (this.options.useClones) {
122
- return this.clone(result.value);
212
+ return this._cacheable.clone(result.value);
123
213
  }
124
214
  return result.value;
125
215
  }
126
- this.addHit();
216
+ this._stats.incrementHits();
127
217
  if (this.options.useClones) {
128
- return this.clone(result.value);
218
+ return this._cacheable.clone(result.value);
129
219
  }
130
220
  return result.value;
131
221
  }
132
- this.addMiss();
222
+ this._stats.incrementMisses();
133
223
  return void 0;
134
224
  }
135
225
  /*
@@ -156,7 +246,7 @@ var NodeCache = class extends import_eventemitter3.default {
156
246
  if (result) {
157
247
  this.del(key);
158
248
  if (this.options.useClones) {
159
- return this.clone(result);
249
+ return this._cacheable.clone(result);
160
250
  }
161
251
  return result;
162
252
  }
@@ -172,9 +262,9 @@ var NodeCache = class extends import_eventemitter3.default {
172
262
  const keyValue = this.formatKey(key);
173
263
  this.store.delete(keyValue);
174
264
  this.emit("del", keyValue, result.value);
175
- this._stats.ksize -= this.roughSizeOfKey(keyValue);
176
- this._stats.vsize -= this.roughSizeOfObject(result.value);
177
- this._stats.keys = this.store.size;
265
+ this._stats.decreaseKSize(keyValue);
266
+ this._stats.decreaseVSize(result.value);
267
+ this._stats.setCount(this.store.size);
178
268
  return 1;
179
269
  }
180
270
  return 0;
@@ -233,7 +323,14 @@ var NodeCache = class extends import_eventemitter3.default {
233
323
  }
234
324
  // Gets the stats of the cache.
235
325
  getStats() {
236
- return this._stats;
326
+ const stats = {
327
+ keys: this._stats.count,
328
+ hits: this._stats.hits,
329
+ misses: this._stats.misses,
330
+ ksize: this._stats.ksize,
331
+ vsize: this._stats.vsize
332
+ };
333
+ return stats;
237
334
  }
238
335
  // Flush the whole data.
239
336
  flushAll() {
@@ -243,13 +340,7 @@ var NodeCache = class extends import_eventemitter3.default {
243
340
  }
244
341
  // Flush the stats
245
342
  flushStats() {
246
- this._stats = {
247
- keys: 0,
248
- hits: 0,
249
- misses: 0,
250
- ksize: 0,
251
- vsize: 0
252
- };
343
+ this._stats = new import_cacheable2.CacheableStats({ enabled: true });
253
344
  this.emit("flush_stats");
254
345
  }
255
346
  // Close the cache. This will clear the interval timeout which is set on check period option.
@@ -269,37 +360,6 @@ var NodeCache = class extends import_eventemitter3.default {
269
360
  const expirationTimestamp = currentTimestamp + ttlInMilliseconds;
270
361
  return expirationTimestamp;
271
362
  }
272
- addHit() {
273
- this._stats.hits++;
274
- }
275
- addMiss() {
276
- this._stats.misses++;
277
- }
278
- roughSizeOfKey(key) {
279
- return this.formatKey(key).toString().length * 2;
280
- }
281
- roughSizeOfObject(object) {
282
- const objectList = [];
283
- const stack = [object];
284
- let bytes = 0;
285
- while (stack.length > 0) {
286
- const value = stack.pop();
287
- if (typeof value === "boolean") {
288
- bytes += 4;
289
- } else if (typeof value === "string") {
290
- bytes += value.length * 2;
291
- } else if (typeof value === "number") {
292
- bytes += 8;
293
- } else if (typeof value === "object" && value !== null && !objectList.includes(value)) {
294
- objectList.push(value);
295
- for (const key in value) {
296
- bytes += key.length * 2;
297
- stack.push(value[key]);
298
- }
299
- }
300
- }
301
- return bytes;
302
- }
303
363
  startInterval() {
304
364
  if (this.options.checkperiod && this.options.checkperiod > 0) {
305
365
  const checkPeriodinSeconds = this.options.checkperiod * 1e3;
@@ -330,24 +390,9 @@ var NodeCache = class extends import_eventemitter3.default {
330
390
  }
331
391
  return new Error(error);
332
392
  }
333
- isPrimitive(value) {
334
- const result = false;
335
- if (value === null || value === void 0) {
336
- return true;
337
- }
338
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
339
- return true;
340
- }
341
- return result;
342
- }
343
- clone(value) {
344
- if (this.isPrimitive(value)) {
345
- return value;
346
- }
347
- return structuredClone(value);
348
- }
349
393
  };
350
394
  // Annotate the CommonJS export names for ESM import in node:
351
395
  0 && (module.exports = {
352
- NodeCacheErrors
396
+ NodeCacheErrors,
397
+ NodeCacheStore
353
398
  });
package/dist/index.d.cts CHANGED
@@ -1,4 +1,34 @@
1
1
  import eventemitter from 'eventemitter3';
2
+ import { Cacheable } from 'cacheable';
3
+ import { Keyv } from 'keyv';
4
+
5
+ type NodeCacheStoreOptions = {
6
+ ttl?: number;
7
+ maxKeys?: number;
8
+ primary?: Keyv;
9
+ secondary?: Keyv;
10
+ };
11
+ declare class NodeCacheStore {
12
+ private _maxKeys;
13
+ private readonly _cache;
14
+ constructor(options?: NodeCacheStoreOptions);
15
+ get cache(): Cacheable;
16
+ get ttl(): number | undefined;
17
+ set ttl(ttl: number | undefined);
18
+ get primary(): Keyv;
19
+ set primary(primary: Keyv);
20
+ get secondary(): Keyv | undefined;
21
+ set secondary(secondary: Keyv | undefined);
22
+ get maxKeys(): number;
23
+ set maxKeys(maxKeys: number);
24
+ set(key: string | number, value: any, ttl?: number): Promise<boolean>;
25
+ mset(list: NodeCacheItem[]): Promise<void>;
26
+ get<T>(key: string | number): Promise<T | undefined>;
27
+ mget<T>(keys: Array<string | number>): Promise<Record<string, T | undefined>>;
28
+ del(key: string | number): Promise<boolean>;
29
+ mdel(keys: Array<string | number>): Promise<boolean>;
30
+ clear(): Promise<void>;
31
+ }
2
32
 
3
33
  type NodeCacheOptions = {
4
34
  stdTTL?: number;
@@ -29,6 +59,7 @@ declare class NodeCache extends eventemitter {
29
59
  readonly options: NodeCacheOptions;
30
60
  readonly store: Map<string, any>;
31
61
  private _stats;
62
+ private readonly _cacheable;
32
63
  private intervalId;
33
64
  constructor(options?: NodeCacheOptions);
34
65
  set(key: string | number, value: any, ttl?: number): boolean;
@@ -49,16 +80,10 @@ declare class NodeCache extends eventemitter {
49
80
  getIntervalId(): number | NodeJS.Timeout;
50
81
  private formatKey;
51
82
  private getExpirationTimestamp;
52
- private addHit;
53
- private addMiss;
54
- private roughSizeOfKey;
55
- private roughSizeOfObject;
56
83
  private startInterval;
57
84
  private checkData;
58
85
  private stopInterval;
59
86
  private createError;
60
- private isPrimitive;
61
- private clone;
62
87
  }
63
88
 
64
- export { NodeCacheErrors, type NodeCacheItem, type NodeCacheOptions, type NodeCacheStats, NodeCache as default };
89
+ export { NodeCacheErrors, type NodeCacheItem, type NodeCacheOptions, type NodeCacheStats, NodeCacheStore, type NodeCacheStoreOptions, NodeCache as default };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,34 @@
1
1
  import eventemitter from 'eventemitter3';
2
+ import { Cacheable } from 'cacheable';
3
+ import { Keyv } from 'keyv';
4
+
5
+ type NodeCacheStoreOptions = {
6
+ ttl?: number;
7
+ maxKeys?: number;
8
+ primary?: Keyv;
9
+ secondary?: Keyv;
10
+ };
11
+ declare class NodeCacheStore {
12
+ private _maxKeys;
13
+ private readonly _cache;
14
+ constructor(options?: NodeCacheStoreOptions);
15
+ get cache(): Cacheable;
16
+ get ttl(): number | undefined;
17
+ set ttl(ttl: number | undefined);
18
+ get primary(): Keyv;
19
+ set primary(primary: Keyv);
20
+ get secondary(): Keyv | undefined;
21
+ set secondary(secondary: Keyv | undefined);
22
+ get maxKeys(): number;
23
+ set maxKeys(maxKeys: number);
24
+ set(key: string | number, value: any, ttl?: number): Promise<boolean>;
25
+ mset(list: NodeCacheItem[]): Promise<void>;
26
+ get<T>(key: string | number): Promise<T | undefined>;
27
+ mget<T>(keys: Array<string | number>): Promise<Record<string, T | undefined>>;
28
+ del(key: string | number): Promise<boolean>;
29
+ mdel(keys: Array<string | number>): Promise<boolean>;
30
+ clear(): Promise<void>;
31
+ }
2
32
 
3
33
  type NodeCacheOptions = {
4
34
  stdTTL?: number;
@@ -29,6 +59,7 @@ declare class NodeCache extends eventemitter {
29
59
  readonly options: NodeCacheOptions;
30
60
  readonly store: Map<string, any>;
31
61
  private _stats;
62
+ private readonly _cacheable;
32
63
  private intervalId;
33
64
  constructor(options?: NodeCacheOptions);
34
65
  set(key: string | number, value: any, ttl?: number): boolean;
@@ -49,16 +80,10 @@ declare class NodeCache extends eventemitter {
49
80
  getIntervalId(): number | NodeJS.Timeout;
50
81
  private formatKey;
51
82
  private getExpirationTimestamp;
52
- private addHit;
53
- private addMiss;
54
- private roughSizeOfKey;
55
- private roughSizeOfObject;
56
83
  private startInterval;
57
84
  private checkData;
58
85
  private stopInterval;
59
86
  private createError;
60
- private isPrimitive;
61
- private clone;
62
87
  }
63
88
 
64
- export { NodeCacheErrors, type NodeCacheItem, type NodeCacheOptions, type NodeCacheStats, NodeCache as default };
89
+ export { NodeCacheErrors, type NodeCacheItem, type NodeCacheOptions, type NodeCacheStats, NodeCacheStore, type NodeCacheStoreOptions, NodeCache as default };
package/dist/index.js CHANGED
@@ -1,5 +1,99 @@
1
1
  // src/index.ts
2
2
  import eventemitter from "eventemitter3";
3
+ import { CacheableMemory as CacheableMemory2, CacheableStats } from "cacheable";
4
+
5
+ // src/store.ts
6
+ import { Cacheable, CacheableMemory } from "cacheable";
7
+ import { Keyv } from "keyv";
8
+ var NodeCacheStore = class {
9
+ _maxKeys = 0;
10
+ _cache = new Cacheable({ primary: new Keyv({ store: new CacheableMemory() }) });
11
+ constructor(options) {
12
+ if (options) {
13
+ const cacheOptions = {
14
+ ttl: options.ttl,
15
+ primary: options.primary,
16
+ secondary: options.secondary
17
+ };
18
+ this._cache = new Cacheable(cacheOptions);
19
+ if (options.maxKeys) {
20
+ this._maxKeys = options.maxKeys;
21
+ if (this._maxKeys > 0) {
22
+ this._cache.stats.enabled = true;
23
+ }
24
+ }
25
+ }
26
+ }
27
+ get cache() {
28
+ return this._cache;
29
+ }
30
+ get ttl() {
31
+ return this._cache.ttl;
32
+ }
33
+ set ttl(ttl) {
34
+ this._cache.ttl = ttl;
35
+ }
36
+ get primary() {
37
+ return this._cache.primary;
38
+ }
39
+ set primary(primary) {
40
+ this._cache.primary = primary;
41
+ }
42
+ get secondary() {
43
+ return this._cache.secondary;
44
+ }
45
+ set secondary(secondary) {
46
+ this._cache.secondary = secondary;
47
+ }
48
+ get maxKeys() {
49
+ return this._maxKeys;
50
+ }
51
+ set maxKeys(maxKeys) {
52
+ this._maxKeys = maxKeys;
53
+ if (this._maxKeys > 0) {
54
+ this._cache.stats.enabled = true;
55
+ }
56
+ }
57
+ async set(key, value, ttl) {
58
+ if (this._maxKeys > 0) {
59
+ console.log(this._cache.stats.count, this._maxKeys);
60
+ if (this._cache.stats.count >= this._maxKeys) {
61
+ return false;
62
+ }
63
+ }
64
+ const finalTtl = ttl ?? this._cache.ttl;
65
+ await this._cache.set(key.toString(), value, finalTtl);
66
+ return true;
67
+ }
68
+ async mset(list) {
69
+ const items = new Array();
70
+ for (const item of list) {
71
+ items.push({ key: item.key.toString(), value: item.value, ttl: item.ttl });
72
+ }
73
+ await this._cache.setMany(items);
74
+ }
75
+ async get(key) {
76
+ return this._cache.get(key.toString());
77
+ }
78
+ async mget(keys) {
79
+ const result = {};
80
+ for (const key of keys) {
81
+ result[key.toString()] = await this._cache.get(key.toString());
82
+ }
83
+ return result;
84
+ }
85
+ async del(key) {
86
+ return this._cache.delete(key.toString());
87
+ }
88
+ async mdel(keys) {
89
+ return this._cache.deleteMany(keys.map((key) => key.toString()));
90
+ }
91
+ async clear() {
92
+ return this._cache.clear();
93
+ }
94
+ };
95
+
96
+ // src/index.ts
3
97
  var NodeCacheErrors = /* @__PURE__ */ ((NodeCacheErrors2) => {
4
98
  NodeCacheErrors2["ECACHEFULL"] = "Cache max keys amount exceeded";
5
99
  NodeCacheErrors2["EKEYTYPE"] = "The key argument has to be of type `string` or `number`. Found: `__key`";
@@ -17,13 +111,8 @@ var NodeCache = class extends eventemitter {
17
111
  maxKeys: -1
18
112
  };
19
113
  store = /* @__PURE__ */ new Map();
20
- _stats = {
21
- keys: 0,
22
- hits: 0,
23
- misses: 0,
24
- ksize: 0,
25
- vsize: 0
26
- };
114
+ _stats = new CacheableStats({ enabled: true });
115
+ _cacheable = new CacheableMemory2();
27
116
  intervalId = 0;
28
117
  constructor(options) {
29
118
  super();
@@ -54,9 +143,9 @@ var NodeCache = class extends eventemitter {
54
143
  }
55
144
  this.store.set(keyValue, { key: keyValue, value, ttl: expirationTimestamp });
56
145
  this.emit("set", keyValue, value, ttlValue);
57
- this._stats.ksize += this.roughSizeOfKey(keyValue);
58
- this._stats.vsize += this.roughSizeOfObject(value);
59
- this._stats.keys = this.store.size;
146
+ this._stats.incrementKSize(keyValue);
147
+ this._stats.incrementVSize(value);
148
+ this._stats.setCount(this.store.size);
60
149
  return true;
61
150
  }
62
151
  // Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success.
@@ -78,23 +167,23 @@ var NodeCache = class extends eventemitter {
78
167
  if (this.options.deleteOnExpire) {
79
168
  this.del(key);
80
169
  }
81
- this.addMiss();
170
+ this._stats.incrementMisses();
82
171
  this.emit("expired", this.formatKey(key), result.value);
83
172
  return void 0;
84
173
  }
85
- this.addHit();
174
+ this._stats.incrementHits();
86
175
  if (this.options.useClones) {
87
- return this.clone(result.value);
176
+ return this._cacheable.clone(result.value);
88
177
  }
89
178
  return result.value;
90
179
  }
91
- this.addHit();
180
+ this._stats.incrementHits();
92
181
  if (this.options.useClones) {
93
- return this.clone(result.value);
182
+ return this._cacheable.clone(result.value);
94
183
  }
95
184
  return result.value;
96
185
  }
97
- this.addMiss();
186
+ this._stats.incrementMisses();
98
187
  return void 0;
99
188
  }
100
189
  /*
@@ -121,7 +210,7 @@ var NodeCache = class extends eventemitter {
121
210
  if (result) {
122
211
  this.del(key);
123
212
  if (this.options.useClones) {
124
- return this.clone(result);
213
+ return this._cacheable.clone(result);
125
214
  }
126
215
  return result;
127
216
  }
@@ -137,9 +226,9 @@ var NodeCache = class extends eventemitter {
137
226
  const keyValue = this.formatKey(key);
138
227
  this.store.delete(keyValue);
139
228
  this.emit("del", keyValue, result.value);
140
- this._stats.ksize -= this.roughSizeOfKey(keyValue);
141
- this._stats.vsize -= this.roughSizeOfObject(result.value);
142
- this._stats.keys = this.store.size;
229
+ this._stats.decreaseKSize(keyValue);
230
+ this._stats.decreaseVSize(result.value);
231
+ this._stats.setCount(this.store.size);
143
232
  return 1;
144
233
  }
145
234
  return 0;
@@ -198,7 +287,14 @@ var NodeCache = class extends eventemitter {
198
287
  }
199
288
  // Gets the stats of the cache.
200
289
  getStats() {
201
- return this._stats;
290
+ const stats = {
291
+ keys: this._stats.count,
292
+ hits: this._stats.hits,
293
+ misses: this._stats.misses,
294
+ ksize: this._stats.ksize,
295
+ vsize: this._stats.vsize
296
+ };
297
+ return stats;
202
298
  }
203
299
  // Flush the whole data.
204
300
  flushAll() {
@@ -208,13 +304,7 @@ var NodeCache = class extends eventemitter {
208
304
  }
209
305
  // Flush the stats
210
306
  flushStats() {
211
- this._stats = {
212
- keys: 0,
213
- hits: 0,
214
- misses: 0,
215
- ksize: 0,
216
- vsize: 0
217
- };
307
+ this._stats = new CacheableStats({ enabled: true });
218
308
  this.emit("flush_stats");
219
309
  }
220
310
  // Close the cache. This will clear the interval timeout which is set on check period option.
@@ -234,37 +324,6 @@ var NodeCache = class extends eventemitter {
234
324
  const expirationTimestamp = currentTimestamp + ttlInMilliseconds;
235
325
  return expirationTimestamp;
236
326
  }
237
- addHit() {
238
- this._stats.hits++;
239
- }
240
- addMiss() {
241
- this._stats.misses++;
242
- }
243
- roughSizeOfKey(key) {
244
- return this.formatKey(key).toString().length * 2;
245
- }
246
- roughSizeOfObject(object) {
247
- const objectList = [];
248
- const stack = [object];
249
- let bytes = 0;
250
- while (stack.length > 0) {
251
- const value = stack.pop();
252
- if (typeof value === "boolean") {
253
- bytes += 4;
254
- } else if (typeof value === "string") {
255
- bytes += value.length * 2;
256
- } else if (typeof value === "number") {
257
- bytes += 8;
258
- } else if (typeof value === "object" && value !== null && !objectList.includes(value)) {
259
- objectList.push(value);
260
- for (const key in value) {
261
- bytes += key.length * 2;
262
- stack.push(value[key]);
263
- }
264
- }
265
- }
266
- return bytes;
267
- }
268
327
  startInterval() {
269
328
  if (this.options.checkperiod && this.options.checkperiod > 0) {
270
329
  const checkPeriodinSeconds = this.options.checkperiod * 1e3;
@@ -295,24 +354,9 @@ var NodeCache = class extends eventemitter {
295
354
  }
296
355
  return new Error(error);
297
356
  }
298
- isPrimitive(value) {
299
- const result = false;
300
- if (value === null || value === void 0) {
301
- return true;
302
- }
303
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
304
- return true;
305
- }
306
- return result;
307
- }
308
- clone(value) {
309
- if (this.isPrimitive(value)) {
310
- return value;
311
- }
312
- return structuredClone(value);
313
- }
314
357
  };
315
358
  export {
316
359
  NodeCacheErrors,
360
+ NodeCacheStore,
317
361
  NodeCache as default
318
362
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cacheable/node-cache",
3
- "version": "0.8.0",
3
+ "version": "1.0.0",
4
4
  "description": "Simple and Maintained fast NodeJS internal caching",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -30,14 +30,15 @@
30
30
  "@types/node": "^22.5.5",
31
31
  "@vitest/coverage-v8": "^2.1.1",
32
32
  "rimraf": "^6.0.1",
33
- "tsup": "^8.2.4",
33
+ "tsup": "^8.3.0",
34
34
  "typescript": "^5.6.2",
35
35
  "vitest": "^2.1.1",
36
36
  "xo": "^0.59.3"
37
37
  },
38
38
  "dependencies": {
39
- "cacheable": "^0.8.0",
40
- "eventemitter3": "^5.0.1"
39
+ "cacheable": "^1.2.0",
40
+ "eventemitter3": "^5.0.1",
41
+ "keyv": "^5.0.1"
41
42
  },
42
43
  "files": [
43
44
  "dist",