@cacheable/node-cache 0.5.0 → 0.8.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/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- MIT License
1
+ MIT License & © Jared Wray
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining a copy
4
4
  of this software and associated documentation files (the "Software"), to
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  > Simple and Maintained fast Node.js caching
6
6
 
7
- [![codecov](https://codecov.io/gh/jaredwray/cacheable/branch/master/graph/badge.svg?token=LDLaqe4PsI)](https://codecov.io/gh/jaredwray/cacheable)
7
+ [![codecov](https://codecov.io/gh/jaredwray/cacheable/graph/badge.svg?token=lWZ9OBQ7GM)](https://codecov.io/gh/jaredwray/cacheable)
8
8
  [![tests](https://github.com/jaredwray/cacheable/actions/workflows/tests.yml/badge.svg)](https://github.com/jaredwray/cacheable/actions/workflows/tests.yml)
9
9
  [![npm](https://img.shields.io/npm/dm/cacheable.svg)](https://www.npmjs.com/package/cacheable)
10
10
  [![npm](https://img.shields.io/npm/v/cacheable)](https://www.npmjs.com/package/cacheable)
@@ -259,4 +259,4 @@ cache.on('set', (key, value) => {
259
259
  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`.
260
260
 
261
261
  ## License and Copyright
262
- [MIT © Jared Wray](https://github.com/jaredwray/cacheable/blob/main/LICENSE)
262
+ [MIT © Jared Wray](./LICENSE)
package/dist/index.cjs ADDED
@@ -0,0 +1,353 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
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
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ NodeCacheErrors: () => NodeCacheErrors,
34
+ default: () => NodeCache
35
+ });
36
+ module.exports = __toCommonJS(src_exports);
37
+ var import_eventemitter3 = __toESM(require("eventemitter3"), 1);
38
+ var NodeCacheErrors = /* @__PURE__ */ ((NodeCacheErrors2) => {
39
+ NodeCacheErrors2["ECACHEFULL"] = "Cache max keys amount exceeded";
40
+ NodeCacheErrors2["EKEYTYPE"] = "The key argument has to be of type `string` or `number`. Found: `__key`";
41
+ NodeCacheErrors2["EKEYSTYPE"] = "The keys argument has to be an array.";
42
+ NodeCacheErrors2["ETTLTYPE"] = "The ttl argument has to be a number.";
43
+ return NodeCacheErrors2;
44
+ })(NodeCacheErrors || {});
45
+ var NodeCache = class extends import_eventemitter3.default {
46
+ options = {
47
+ // eslint-disable-next-line @typescript-eslint/naming-convention
48
+ stdTTL: 0,
49
+ checkperiod: 600,
50
+ useClones: true,
51
+ deleteOnExpire: true,
52
+ maxKeys: -1
53
+ };
54
+ store = /* @__PURE__ */ new Map();
55
+ _stats = {
56
+ keys: 0,
57
+ hits: 0,
58
+ misses: 0,
59
+ ksize: 0,
60
+ vsize: 0
61
+ };
62
+ intervalId = 0;
63
+ constructor(options) {
64
+ super();
65
+ if (options) {
66
+ this.options = { ...this.options, ...options };
67
+ }
68
+ this.startInterval();
69
+ }
70
+ // Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success.
71
+ set(key, value, ttl) {
72
+ if (typeof key !== "string" && typeof key !== "number") {
73
+ throw this.createError("The key argument has to be of type `string` or `number`. Found: `__key`" /* EKEYTYPE */, key);
74
+ }
75
+ if (ttl && typeof ttl !== "number") {
76
+ throw this.createError("The ttl argument has to be a number." /* ETTLTYPE */, this.formatKey(key));
77
+ }
78
+ const keyValue = this.formatKey(key);
79
+ const ttlValue = ttl ?? this.options.stdTTL;
80
+ let expirationTimestamp = 0;
81
+ if (ttlValue && ttlValue > 0) {
82
+ expirationTimestamp = this.getExpirationTimestamp(ttlValue);
83
+ }
84
+ if (this.options.maxKeys) {
85
+ const maxKeys = this.options.maxKeys;
86
+ if (maxKeys > -1 && this.store.size >= maxKeys) {
87
+ throw this.createError("Cache max keys amount exceeded" /* ECACHEFULL */, this.formatKey(key));
88
+ }
89
+ }
90
+ this.store.set(keyValue, { key: keyValue, value, ttl: expirationTimestamp });
91
+ 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;
95
+ return true;
96
+ }
97
+ // Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success.
98
+ mset(data) {
99
+ if (!Array.isArray(data)) {
100
+ throw this.createError("The keys argument has to be an array." /* EKEYSTYPE */);
101
+ }
102
+ for (const item of data) {
103
+ this.set(item.key, item.value, item.ttl);
104
+ }
105
+ return true;
106
+ }
107
+ // Gets a saved value from the cache. Returns a undefined if not found or expired. If the value was found it returns the value.
108
+ get(key) {
109
+ const result = this.store.get(this.formatKey(key));
110
+ if (result) {
111
+ if (result.ttl > 0) {
112
+ if (result.ttl < Date.now()) {
113
+ if (this.options.deleteOnExpire) {
114
+ this.del(key);
115
+ }
116
+ this.addMiss();
117
+ this.emit("expired", this.formatKey(key), result.value);
118
+ return void 0;
119
+ }
120
+ this.addHit();
121
+ if (this.options.useClones) {
122
+ return this.clone(result.value);
123
+ }
124
+ return result.value;
125
+ }
126
+ this.addHit();
127
+ if (this.options.useClones) {
128
+ return this.clone(result.value);
129
+ }
130
+ return result.value;
131
+ }
132
+ this.addMiss();
133
+ return void 0;
134
+ }
135
+ /*
136
+ Gets multiple saved values from the cache. Returns an empty object {} if not found or expired.
137
+ If the value was found it returns an object with the key value pair.
138
+ */
139
+ mget(keys) {
140
+ const result = {};
141
+ for (const key of keys) {
142
+ const value = this.get(key);
143
+ if (value) {
144
+ result[this.formatKey(key)] = value;
145
+ }
146
+ }
147
+ return result;
148
+ }
149
+ /*
150
+ Get the cached value and remove the key from the cache.
151
+ Equivalent to calling get(key) + del(key).
152
+ Useful for implementing single use mechanism such as OTP, where once a value is read it will become obsolete.
153
+ */
154
+ take(key) {
155
+ const result = this.get(key);
156
+ if (result) {
157
+ this.del(key);
158
+ if (this.options.useClones) {
159
+ return this.clone(result);
160
+ }
161
+ return result;
162
+ }
163
+ return void 0;
164
+ }
165
+ // Delete a key. Returns the number of deleted entries. A delete will never fail.
166
+ del(key) {
167
+ if (Array.isArray(key)) {
168
+ return this.mdel(key);
169
+ }
170
+ const result = this.store.get(this.formatKey(key));
171
+ if (result) {
172
+ const keyValue = this.formatKey(key);
173
+ this.store.delete(keyValue);
174
+ 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;
178
+ return 1;
179
+ }
180
+ return 0;
181
+ }
182
+ // Delete all keys in Array that exist. Returns the number of deleted entries.
183
+ mdel(keys) {
184
+ let result = 0;
185
+ for (const key of keys) {
186
+ result += this.del(key);
187
+ }
188
+ return result;
189
+ }
190
+ // Redefine the ttl of a key. Returns true if the key has been found and changed.
191
+ // Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used.
192
+ ttl(key, ttl) {
193
+ const result = this.store.get(this.formatKey(key));
194
+ if (result) {
195
+ const ttlValue = ttl ?? this.options.stdTTL;
196
+ result.ttl = this.getExpirationTimestamp(ttlValue);
197
+ this.store.set(this.formatKey(key), result);
198
+ return true;
199
+ }
200
+ return false;
201
+ }
202
+ /*
203
+ Receive the ttl of a key. You will get:
204
+
205
+ undefined if the key does not exist
206
+ 0 if this key has no ttl
207
+ a timestamp in ms representing the time at which the key will expire
208
+ */
209
+ getTtl(key) {
210
+ const result = this.store.get(this.formatKey(key));
211
+ if (result) {
212
+ if (result.ttl === 0) {
213
+ return 0;
214
+ }
215
+ return result.ttl;
216
+ }
217
+ return void 0;
218
+ }
219
+ /*
220
+ Returns an array of all existing keys.
221
+ [ "all", "my", "keys", "foo", "bar" ]
222
+ */
223
+ keys() {
224
+ const result = [];
225
+ for (const key of this.store.keys()) {
226
+ result.push(key);
227
+ }
228
+ return result;
229
+ }
230
+ // Returns boolean indicating if the key is cached.
231
+ has(key) {
232
+ return this.store.has(this.formatKey(key));
233
+ }
234
+ // Gets the stats of the cache.
235
+ getStats() {
236
+ return this._stats;
237
+ }
238
+ // Flush the whole data.
239
+ flushAll() {
240
+ this.store.clear();
241
+ this.flushStats();
242
+ this.emit("flush");
243
+ }
244
+ // Flush the stats
245
+ flushStats() {
246
+ this._stats = {
247
+ keys: 0,
248
+ hits: 0,
249
+ misses: 0,
250
+ ksize: 0,
251
+ vsize: 0
252
+ };
253
+ this.emit("flush_stats");
254
+ }
255
+ // Close the cache. This will clear the interval timeout which is set on check period option.
256
+ close() {
257
+ this.stopInterval();
258
+ }
259
+ // Get the interval id
260
+ getIntervalId() {
261
+ return this.intervalId;
262
+ }
263
+ formatKey(key) {
264
+ return key.toString();
265
+ }
266
+ getExpirationTimestamp(ttlInSeconds) {
267
+ const currentTimestamp = Date.now();
268
+ const ttlInMilliseconds = ttlInSeconds * 1e3;
269
+ const expirationTimestamp = currentTimestamp + ttlInMilliseconds;
270
+ return expirationTimestamp;
271
+ }
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
+ startInterval() {
304
+ if (this.options.checkperiod && this.options.checkperiod > 0) {
305
+ const checkPeriodinSeconds = this.options.checkperiod * 1e3;
306
+ this.intervalId = setInterval(() => {
307
+ this.checkData();
308
+ }, checkPeriodinSeconds);
309
+ return;
310
+ }
311
+ this.intervalId = 0;
312
+ }
313
+ checkData() {
314
+ for (const [key, value] of this.store.entries()) {
315
+ if (value.ttl > 0 && value.ttl < Date.now()) {
316
+ this.del(key);
317
+ }
318
+ }
319
+ }
320
+ stopInterval() {
321
+ if (this.intervalId !== 0) {
322
+ clearInterval(this.intervalId);
323
+ this.intervalId = 0;
324
+ }
325
+ }
326
+ createError(errorCode, key) {
327
+ let error = errorCode;
328
+ if (key) {
329
+ error = error.replace("__key", key);
330
+ }
331
+ return new Error(error);
332
+ }
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
+ };
350
+ // Annotate the CommonJS export names for ESM import in node:
351
+ 0 && (module.exports = {
352
+ NodeCacheErrors
353
+ });
@@ -0,0 +1,64 @@
1
+ import eventemitter from 'eventemitter3';
2
+
3
+ type NodeCacheOptions = {
4
+ stdTTL?: number;
5
+ checkperiod?: number;
6
+ useClones?: boolean;
7
+ deleteOnExpire?: boolean;
8
+ maxKeys?: number;
9
+ };
10
+ type NodeCacheItem = {
11
+ key: string | number;
12
+ value: any;
13
+ ttl?: number;
14
+ };
15
+ declare enum NodeCacheErrors {
16
+ ECACHEFULL = "Cache max keys amount exceeded",
17
+ EKEYTYPE = "The key argument has to be of type `string` or `number`. Found: `__key`",
18
+ EKEYSTYPE = "The keys argument has to be an array.",
19
+ ETTLTYPE = "The ttl argument has to be a number."
20
+ }
21
+ type NodeCacheStats = {
22
+ keys: number;
23
+ hits: number;
24
+ misses: number;
25
+ ksize: number;
26
+ vsize: number;
27
+ };
28
+ declare class NodeCache extends eventemitter {
29
+ readonly options: NodeCacheOptions;
30
+ readonly store: Map<string, any>;
31
+ private _stats;
32
+ private intervalId;
33
+ constructor(options?: NodeCacheOptions);
34
+ set(key: string | number, value: any, ttl?: number): boolean;
35
+ mset(data: NodeCacheItem[]): boolean;
36
+ get(key: string | number): any;
37
+ mget(keys: Array<string | number>): Record<string, unknown>;
38
+ take(key: string | number): any;
39
+ del(key: string | number | Array<string | number>): number;
40
+ mdel(keys: Array<string | number>): number;
41
+ ttl(key: string | number, ttl?: number): boolean;
42
+ getTtl(key: string | number): number | undefined;
43
+ keys(): string[];
44
+ has(key: string | number): boolean;
45
+ getStats(): NodeCacheStats;
46
+ flushAll(): void;
47
+ flushStats(): void;
48
+ close(): void;
49
+ getIntervalId(): number | NodeJS.Timeout;
50
+ private formatKey;
51
+ private getExpirationTimestamp;
52
+ private addHit;
53
+ private addMiss;
54
+ private roughSizeOfKey;
55
+ private roughSizeOfObject;
56
+ private startInterval;
57
+ private checkData;
58
+ private stopInterval;
59
+ private createError;
60
+ private isPrimitive;
61
+ private clone;
62
+ }
63
+
64
+ export { NodeCacheErrors, type NodeCacheItem, type NodeCacheOptions, type NodeCacheStats, NodeCache as default };
package/dist/index.d.ts CHANGED
@@ -1,30 +1,31 @@
1
1
  import eventemitter from 'eventemitter3';
2
- export type NodeCacheOptions = {
2
+
3
+ type NodeCacheOptions = {
3
4
  stdTTL?: number;
4
5
  checkperiod?: number;
5
6
  useClones?: boolean;
6
7
  deleteOnExpire?: boolean;
7
8
  maxKeys?: number;
8
9
  };
9
- export type NodeCacheItem = {
10
+ type NodeCacheItem = {
10
11
  key: string | number;
11
12
  value: any;
12
13
  ttl?: number;
13
14
  };
14
- export declare enum NodeCacheErrors {
15
+ declare enum NodeCacheErrors {
15
16
  ECACHEFULL = "Cache max keys amount exceeded",
16
17
  EKEYTYPE = "The key argument has to be of type `string` or `number`. Found: `__key`",
17
18
  EKEYSTYPE = "The keys argument has to be an array.",
18
19
  ETTLTYPE = "The ttl argument has to be a number."
19
20
  }
20
- export type NodeCacheStats = {
21
+ type NodeCacheStats = {
21
22
  keys: number;
22
23
  hits: number;
23
24
  misses: number;
24
25
  ksize: number;
25
26
  vsize: number;
26
27
  };
27
- export default class NodeCache extends eventemitter {
28
+ declare class NodeCache extends eventemitter {
28
29
  readonly options: NodeCacheOptions;
29
30
  readonly store: Map<string, any>;
30
31
  private _stats;
@@ -59,4 +60,5 @@ export default class NodeCache extends eventemitter {
59
60
  private isPrimitive;
60
61
  private clone;
61
62
  }
62
- //# sourceMappingURL=index.d.ts.map
63
+
64
+ export { NodeCacheErrors, type NodeCacheItem, type NodeCacheOptions, type NodeCacheStats, NodeCache as default };
package/dist/index.js CHANGED
@@ -1,344 +1,318 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.NodeCacheErrors = void 0;
7
- /* eslint-disable @typescript-eslint/no-unsafe-assignment */
8
- const eventemitter3_1 = __importDefault(require("eventemitter3"));
9
- var NodeCacheErrors;
10
- (function (NodeCacheErrors) {
11
- NodeCacheErrors["ECACHEFULL"] = "Cache max keys amount exceeded";
12
- NodeCacheErrors["EKEYTYPE"] = "The key argument has to be of type `string` or `number`. Found: `__key`";
13
- NodeCacheErrors["EKEYSTYPE"] = "The keys argument has to be an array.";
14
- NodeCacheErrors["ETTLTYPE"] = "The ttl argument has to be a number.";
15
- })(NodeCacheErrors || (exports.NodeCacheErrors = NodeCacheErrors = {}));
16
- class NodeCache extends eventemitter3_1.default {
17
- constructor(options) {
18
- super();
19
- this.options = {
20
- // eslint-disable-next-line @typescript-eslint/naming-convention
21
- stdTTL: 0,
22
- checkperiod: 600,
23
- useClones: true,
24
- deleteOnExpire: true,
25
- maxKeys: -1,
26
- };
27
- this.store = new Map();
28
- this._stats = {
29
- keys: 0,
30
- hits: 0,
31
- misses: 0,
32
- ksize: 0,
33
- vsize: 0,
34
- };
35
- this.intervalId = 0;
36
- if (options) {
37
- this.options = Object.assign(Object.assign({}, this.options), options);
38
- }
39
- this.startInterval();
1
+ // src/index.ts
2
+ import eventemitter from "eventemitter3";
3
+ var NodeCacheErrors = /* @__PURE__ */ ((NodeCacheErrors2) => {
4
+ NodeCacheErrors2["ECACHEFULL"] = "Cache max keys amount exceeded";
5
+ NodeCacheErrors2["EKEYTYPE"] = "The key argument has to be of type `string` or `number`. Found: `__key`";
6
+ NodeCacheErrors2["EKEYSTYPE"] = "The keys argument has to be an array.";
7
+ NodeCacheErrors2["ETTLTYPE"] = "The ttl argument has to be a number.";
8
+ return NodeCacheErrors2;
9
+ })(NodeCacheErrors || {});
10
+ var NodeCache = class extends eventemitter {
11
+ options = {
12
+ // eslint-disable-next-line @typescript-eslint/naming-convention
13
+ stdTTL: 0,
14
+ checkperiod: 600,
15
+ useClones: true,
16
+ deleteOnExpire: true,
17
+ maxKeys: -1
18
+ };
19
+ store = /* @__PURE__ */ new Map();
20
+ _stats = {
21
+ keys: 0,
22
+ hits: 0,
23
+ misses: 0,
24
+ ksize: 0,
25
+ vsize: 0
26
+ };
27
+ intervalId = 0;
28
+ constructor(options) {
29
+ super();
30
+ if (options) {
31
+ this.options = { ...this.options, ...options };
40
32
  }
41
- // Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success.
42
- set(key, value, ttl) {
43
- // Check on key type
44
- /* c8 ignore next 3 */
45
- if (typeof key !== 'string' && typeof key !== 'number') {
46
- throw this.createError(NodeCacheErrors.EKEYTYPE, key);
47
- }
48
- // Check on ttl type
49
- /* c8 ignore next 3 */
50
- if (ttl && typeof ttl !== 'number') {
51
- throw this.createError(NodeCacheErrors.ETTLTYPE, this.formatKey(key));
52
- }
53
- const keyValue = this.formatKey(key);
54
- const ttlValue = ttl !== null && ttl !== void 0 ? ttl : this.options.stdTTL;
55
- let expirationTimestamp = 0; // Never delete
56
- if (ttlValue && ttlValue > 0) {
57
- expirationTimestamp = this.getExpirationTimestamp(ttlValue);
58
- }
59
- // Check on max key size
60
- if (this.options.maxKeys) {
61
- const maxKeys = this.options.maxKeys;
62
- if (maxKeys > -1 && this.store.size >= maxKeys) {
63
- throw this.createError(NodeCacheErrors.ECACHEFULL, this.formatKey(key));
64
- }
65
- }
66
- this.store.set(keyValue, { key: keyValue, value, ttl: expirationTimestamp });
67
- // Event
68
- this.emit('set', keyValue, value, ttlValue);
69
- // Add the bytes to the stats
70
- this._stats.ksize += this.roughSizeOfKey(keyValue);
71
- this._stats.vsize += this.roughSizeOfObject(value);
72
- this._stats.keys = this.store.size;
73
- return true;
74
- }
75
- // Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success.
76
- mset(data) {
77
- // Check on keys type
78
- /* c8 ignore next 3 */
79
- if (!Array.isArray(data)) {
80
- throw this.createError(NodeCacheErrors.EKEYSTYPE);
81
- }
82
- for (const item of data) {
83
- this.set(item.key, item.value, item.ttl);
84
- }
85
- return true;
33
+ this.startInterval();
34
+ }
35
+ // Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success.
36
+ set(key, value, ttl) {
37
+ if (typeof key !== "string" && typeof key !== "number") {
38
+ throw this.createError("The key argument has to be of type `string` or `number`. Found: `__key`" /* EKEYTYPE */, key);
86
39
  }
87
- // Gets a saved value from the cache. Returns a undefined if not found or expired. If the value was found it returns the value.
88
- get(key) {
89
- const result = this.store.get(this.formatKey(key));
90
- if (result) {
91
- if (result.ttl > 0) {
92
- if (result.ttl < Date.now()) {
93
- if (this.options.deleteOnExpire) {
94
- this.del(key);
95
- }
96
- this.addMiss();
97
- // Event
98
- this.emit('expired', this.formatKey(key), result.value);
99
- return undefined;
100
- }
101
- this.addHit();
102
- if (this.options.useClones) {
103
- return this.clone(result.value);
104
- }
105
- return result.value;
106
- }
107
- this.addHit();
108
- if (this.options.useClones) {
109
- return this.clone(result.value);
110
- }
111
- return result.value;
112
- }
113
- this.addMiss();
114
- return undefined;
40
+ if (ttl && typeof ttl !== "number") {
41
+ throw this.createError("The ttl argument has to be a number." /* ETTLTYPE */, this.formatKey(key));
115
42
  }
116
- /*
117
- Gets multiple saved values from the cache. Returns an empty object {} if not found or expired.
118
- If the value was found it returns an object with the key value pair.
119
- */
120
- mget(keys) {
121
- const result = {};
122
- for (const key of keys) {
123
- const value = this.get(key);
124
- if (value) {
125
- result[this.formatKey(key)] = value;
126
- }
127
- }
128
- return result;
43
+ const keyValue = this.formatKey(key);
44
+ const ttlValue = ttl ?? this.options.stdTTL;
45
+ let expirationTimestamp = 0;
46
+ if (ttlValue && ttlValue > 0) {
47
+ expirationTimestamp = this.getExpirationTimestamp(ttlValue);
129
48
  }
130
- /*
131
- Get the cached value and remove the key from the cache.
132
- Equivalent to calling get(key) + del(key).
133
- Useful for implementing single use mechanism such as OTP, where once a value is read it will become obsolete.
134
- */
135
- take(key) {
136
- const result = this.get(key);
137
- if (result) {
138
- this.del(key);
139
- if (this.options.useClones) {
140
- return this.clone(result);
141
- }
142
- return result;
143
- }
144
- return undefined;
49
+ if (this.options.maxKeys) {
50
+ const maxKeys = this.options.maxKeys;
51
+ if (maxKeys > -1 && this.store.size >= maxKeys) {
52
+ throw this.createError("Cache max keys amount exceeded" /* ECACHEFULL */, this.formatKey(key));
53
+ }
145
54
  }
146
- // Delete a key. Returns the number of deleted entries. A delete will never fail.
147
- del(key) {
148
- if (Array.isArray(key)) {
149
- return this.mdel(key);
150
- }
151
- const result = this.store.get(this.formatKey(key));
152
- if (result) {
153
- const keyValue = this.formatKey(key);
154
- this.store.delete(keyValue);
155
- // Event
156
- this.emit('del', keyValue, result.value);
157
- // Remove the bytes from the stats
158
- this._stats.ksize -= this.roughSizeOfKey(keyValue);
159
- this._stats.vsize -= this.roughSizeOfObject(result.value);
160
- this._stats.keys = this.store.size;
161
- return 1;
162
- }
163
- return 0;
55
+ this.store.set(keyValue, { key: keyValue, value, ttl: expirationTimestamp });
56
+ 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;
60
+ return true;
61
+ }
62
+ // Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success.
63
+ mset(data) {
64
+ if (!Array.isArray(data)) {
65
+ throw this.createError("The keys argument has to be an array." /* EKEYSTYPE */);
164
66
  }
165
- // Delete all keys in Array that exist. Returns the number of deleted entries.
166
- mdel(keys) {
167
- let result = 0;
168
- for (const key of keys) {
169
- result += this.del(key);
170
- }
171
- return result;
67
+ for (const item of data) {
68
+ this.set(item.key, item.value, item.ttl);
172
69
  }
173
- // Redefine the ttl of a key. Returns true if the key has been found and changed.
174
- // Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used.
175
- ttl(key, ttl) {
176
- const result = this.store.get(this.formatKey(key));
177
- if (result) {
178
- const ttlValue = ttl !== null && ttl !== void 0 ? ttl : this.options.stdTTL;
179
- result.ttl = this.getExpirationTimestamp(ttlValue);
180
- this.store.set(this.formatKey(key), result);
181
- return true;
182
- }
183
- return false;
184
- }
185
- /*
186
- Receive the ttl of a key. You will get:
187
-
188
- undefined if the key does not exist
189
- 0 if this key has no ttl
190
- a timestamp in ms representing the time at which the key will expire
191
- */
192
- getTtl(key) {
193
- const result = this.store.get(this.formatKey(key));
194
- if (result) {
195
- if (result.ttl === 0) {
196
- return 0;
197
- }
198
- return result.ttl;
70
+ return true;
71
+ }
72
+ // Gets a saved value from the cache. Returns a undefined if not found or expired. If the value was found it returns the value.
73
+ get(key) {
74
+ const result = this.store.get(this.formatKey(key));
75
+ if (result) {
76
+ if (result.ttl > 0) {
77
+ if (result.ttl < Date.now()) {
78
+ if (this.options.deleteOnExpire) {
79
+ this.del(key);
80
+ }
81
+ this.addMiss();
82
+ this.emit("expired", this.formatKey(key), result.value);
83
+ return void 0;
199
84
  }
200
- return undefined;
201
- }
202
- /*
203
- Returns an array of all existing keys.
204
- [ "all", "my", "keys", "foo", "bar" ]
205
- */
206
- keys() {
207
- const result = [];
208
- for (const key of this.store.keys()) {
209
- result.push(key);
85
+ this.addHit();
86
+ if (this.options.useClones) {
87
+ return this.clone(result.value);
210
88
  }
211
- return result;
212
- }
213
- // Returns boolean indicating if the key is cached.
214
- has(key) {
215
- return this.store.has(this.formatKey(key));
216
- }
217
- // Gets the stats of the cache.
218
- getStats() {
219
- return this._stats;
89
+ return result.value;
90
+ }
91
+ this.addHit();
92
+ if (this.options.useClones) {
93
+ return this.clone(result.value);
94
+ }
95
+ return result.value;
220
96
  }
221
- // Flush the whole data.
222
- flushAll() {
223
- this.store.clear();
224
- this.flushStats();
225
- // Event
226
- this.emit('flush');
97
+ this.addMiss();
98
+ return void 0;
99
+ }
100
+ /*
101
+ Gets multiple saved values from the cache. Returns an empty object {} if not found or expired.
102
+ If the value was found it returns an object with the key value pair.
103
+ */
104
+ mget(keys) {
105
+ const result = {};
106
+ for (const key of keys) {
107
+ const value = this.get(key);
108
+ if (value) {
109
+ result[this.formatKey(key)] = value;
110
+ }
227
111
  }
228
- // Flush the stats
229
- flushStats() {
230
- this._stats = {
231
- keys: 0,
232
- hits: 0,
233
- misses: 0,
234
- ksize: 0,
235
- vsize: 0,
236
- };
237
- // Event
238
- this.emit('flush_stats');
112
+ return result;
113
+ }
114
+ /*
115
+ Get the cached value and remove the key from the cache.
116
+ Equivalent to calling get(key) + del(key).
117
+ Useful for implementing single use mechanism such as OTP, where once a value is read it will become obsolete.
118
+ */
119
+ take(key) {
120
+ const result = this.get(key);
121
+ if (result) {
122
+ this.del(key);
123
+ if (this.options.useClones) {
124
+ return this.clone(result);
125
+ }
126
+ return result;
239
127
  }
240
- // Close the cache. This will clear the interval timeout which is set on check period option.
241
- close() {
242
- this.stopInterval();
128
+ return void 0;
129
+ }
130
+ // Delete a key. Returns the number of deleted entries. A delete will never fail.
131
+ del(key) {
132
+ if (Array.isArray(key)) {
133
+ return this.mdel(key);
243
134
  }
244
- // Get the interval id
245
- getIntervalId() {
246
- return this.intervalId;
135
+ const result = this.store.get(this.formatKey(key));
136
+ if (result) {
137
+ const keyValue = this.formatKey(key);
138
+ this.store.delete(keyValue);
139
+ 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;
143
+ return 1;
247
144
  }
248
- formatKey(key) {
249
- return key.toString();
145
+ return 0;
146
+ }
147
+ // Delete all keys in Array that exist. Returns the number of deleted entries.
148
+ mdel(keys) {
149
+ let result = 0;
150
+ for (const key of keys) {
151
+ result += this.del(key);
250
152
  }
251
- getExpirationTimestamp(ttlInSeconds) {
252
- const currentTimestamp = Date.now(); // Current time in milliseconds
253
- const ttlInMilliseconds = ttlInSeconds * 1000; // Convert TTL to milliseconds
254
- const expirationTimestamp = currentTimestamp + ttlInMilliseconds;
255
- return expirationTimestamp;
153
+ return result;
154
+ }
155
+ // Redefine the ttl of a key. Returns true if the key has been found and changed.
156
+ // Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used.
157
+ ttl(key, ttl) {
158
+ const result = this.store.get(this.formatKey(key));
159
+ if (result) {
160
+ const ttlValue = ttl ?? this.options.stdTTL;
161
+ result.ttl = this.getExpirationTimestamp(ttlValue);
162
+ this.store.set(this.formatKey(key), result);
163
+ return true;
256
164
  }
257
- addHit() {
258
- this._stats.hits++;
259
- }
260
- addMiss() {
261
- this._stats.misses++;
165
+ return false;
166
+ }
167
+ /*
168
+ Receive the ttl of a key. You will get:
169
+
170
+ undefined if the key does not exist
171
+ 0 if this key has no ttl
172
+ a timestamp in ms representing the time at which the key will expire
173
+ */
174
+ getTtl(key) {
175
+ const result = this.store.get(this.formatKey(key));
176
+ if (result) {
177
+ if (result.ttl === 0) {
178
+ return 0;
179
+ }
180
+ return result.ttl;
262
181
  }
263
- roughSizeOfKey(key) {
264
- // Keys are strings (UTF-16)
265
- return this.formatKey(key).toString().length * 2;
182
+ return void 0;
183
+ }
184
+ /*
185
+ Returns an array of all existing keys.
186
+ [ "all", "my", "keys", "foo", "bar" ]
187
+ */
188
+ keys() {
189
+ const result = [];
190
+ for (const key of this.store.keys()) {
191
+ result.push(key);
266
192
  }
267
- roughSizeOfObject(object) {
268
- const objectList = [];
269
- const stack = [object];
270
- let bytes = 0;
271
- while (stack.length > 0) {
272
- const value = stack.pop();
273
- if (typeof value === 'boolean') {
274
- bytes += 4; // Booleans are 4 bytes
275
- }
276
- else if (typeof value === 'string') {
277
- bytes += value.length * 2; // Each character is 2 bytes (UTF-16 encoding)
278
- }
279
- else if (typeof value === 'number') {
280
- bytes += 8; // Numbers are 8 bytes (IEEE 754 format)
281
- }
282
- else if (typeof value === 'object' && value !== null && !objectList.includes(value)) {
283
- objectList.push(value);
284
- // Estimate object overhead, and then recursively estimate the size of properties
285
- // eslint-disable-next-line guard-for-in
286
- for (const key in value) {
287
- bytes += key.length * 2; // Keys are strings (UTF-16)
288
- stack.push(value[key]); // Add values to the stack to compute their size
289
- }
290
- }
193
+ return result;
194
+ }
195
+ // Returns boolean indicating if the key is cached.
196
+ has(key) {
197
+ return this.store.has(this.formatKey(key));
198
+ }
199
+ // Gets the stats of the cache.
200
+ getStats() {
201
+ return this._stats;
202
+ }
203
+ // Flush the whole data.
204
+ flushAll() {
205
+ this.store.clear();
206
+ this.flushStats();
207
+ this.emit("flush");
208
+ }
209
+ // Flush the stats
210
+ flushStats() {
211
+ this._stats = {
212
+ keys: 0,
213
+ hits: 0,
214
+ misses: 0,
215
+ ksize: 0,
216
+ vsize: 0
217
+ };
218
+ this.emit("flush_stats");
219
+ }
220
+ // Close the cache. This will clear the interval timeout which is set on check period option.
221
+ close() {
222
+ this.stopInterval();
223
+ }
224
+ // Get the interval id
225
+ getIntervalId() {
226
+ return this.intervalId;
227
+ }
228
+ formatKey(key) {
229
+ return key.toString();
230
+ }
231
+ getExpirationTimestamp(ttlInSeconds) {
232
+ const currentTimestamp = Date.now();
233
+ const ttlInMilliseconds = ttlInSeconds * 1e3;
234
+ const expirationTimestamp = currentTimestamp + ttlInMilliseconds;
235
+ return expirationTimestamp;
236
+ }
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]);
291
263
  }
292
- return bytes;
264
+ }
293
265
  }
294
- startInterval() {
295
- if (this.options.checkperiod && this.options.checkperiod > 0) {
296
- const checkPeriodinSeconds = this.options.checkperiod * 1000;
297
- this.intervalId = setInterval(() => {
298
- this.checkData();
299
- }, checkPeriodinSeconds);
300
- return;
301
- }
302
- this.intervalId = 0;
266
+ return bytes;
267
+ }
268
+ startInterval() {
269
+ if (this.options.checkperiod && this.options.checkperiod > 0) {
270
+ const checkPeriodinSeconds = this.options.checkperiod * 1e3;
271
+ this.intervalId = setInterval(() => {
272
+ this.checkData();
273
+ }, checkPeriodinSeconds);
274
+ return;
303
275
  }
304
- checkData() {
305
- for (const [key, value] of this.store.entries()) {
306
- if (value.ttl > 0 && value.ttl < Date.now()) {
307
- this.del(key);
308
- }
309
- }
276
+ this.intervalId = 0;
277
+ }
278
+ checkData() {
279
+ for (const [key, value] of this.store.entries()) {
280
+ if (value.ttl > 0 && value.ttl < Date.now()) {
281
+ this.del(key);
282
+ }
310
283
  }
311
- stopInterval() {
312
- if (this.intervalId !== 0) {
313
- clearInterval(this.intervalId);
314
- this.intervalId = 0;
315
- }
284
+ }
285
+ stopInterval() {
286
+ if (this.intervalId !== 0) {
287
+ clearInterval(this.intervalId);
288
+ this.intervalId = 0;
316
289
  }
317
- createError(errorCode, key) {
318
- let error = errorCode;
319
- /* c8 ignore next 3 */
320
- if (key) {
321
- error = error.replace('__key', key);
322
- }
323
- return new Error(error);
290
+ }
291
+ createError(errorCode, key) {
292
+ let error = errorCode;
293
+ if (key) {
294
+ error = error.replace("__key", key);
324
295
  }
325
- isPrimitive(value) {
326
- const result = false;
327
- /* c8 ignore next 3 */
328
- if (value === null || value === undefined) {
329
- return true;
330
- }
331
- if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
332
- return true;
333
- }
334
- return result;
296
+ return new Error(error);
297
+ }
298
+ isPrimitive(value) {
299
+ const result = false;
300
+ if (value === null || value === void 0) {
301
+ return true;
335
302
  }
336
- clone(value) {
337
- if (this.isPrimitive(value)) {
338
- return value;
339
- }
340
- return structuredClone(value);
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;
341
311
  }
342
- }
343
- exports.default = NodeCache;
344
- //# sourceMappingURL=index.js.map
312
+ return structuredClone(value);
313
+ }
314
+ };
315
+ export {
316
+ NodeCacheErrors,
317
+ NodeCache as default
318
+ };
package/package.json CHANGED
@@ -1,9 +1,17 @@
1
1
  {
2
2
  "name": "@cacheable/node-cache",
3
- "version": "0.5.0",
3
+ "version": "0.8.0",
4
4
  "description": "Simple and Maintained fast NodeJS internal caching",
5
- "main": "./dist/index.js",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
6
8
  "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "require": "./dist/index.cjs",
12
+ "import": "./dist/index.js"
13
+ }
14
+ },
7
15
  "repository": "https://github.com/jaredwray/cacheable.git",
8
16
  "author": "Jared Wray <me@jaredwray.com>",
9
17
  "license": "MIT",
@@ -19,15 +27,16 @@
19
27
  "cacheable-node"
20
28
  ],
21
29
  "devDependencies": {
22
- "@types/node": "^22.5.4",
23
- "@vitest/coverage-v8": "^2.0.5",
30
+ "@types/node": "^22.5.5",
31
+ "@vitest/coverage-v8": "^2.1.1",
24
32
  "rimraf": "^6.0.1",
25
- "typescript": "^5.5.4",
26
- "vitest": "^2.0.5",
33
+ "tsup": "^8.2.4",
34
+ "typescript": "^5.6.2",
35
+ "vitest": "^2.1.1",
27
36
  "xo": "^0.59.3"
28
37
  },
29
38
  "dependencies": {
30
- "cacheable": "^0.3.0",
39
+ "cacheable": "^0.8.0",
31
40
  "eventemitter3": "^5.0.1"
32
41
  },
33
42
  "files": [
@@ -35,7 +44,7 @@
35
44
  "license"
36
45
  ],
37
46
  "scripts": {
38
- "build": "rimraf ./dist && tsc -p tsconfig.build.json",
47
+ "build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean",
39
48
  "test": "xo --fix && vitest run --coverage",
40
49
  "test:ci": "xo && vitest run",
41
50
  "clean": "rimraf ./dist ./coverage ./node_modules"
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,YAAY,MAAM,eAAe,CAAC;AAEzC,MAAM,MAAM,gBAAgB,GAAG;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC3B,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,KAAK,EAAE,GAAG,CAAC;IACX,GAAG,CAAC,EAAE,MAAM,CAAC;CACb,CAAC;AAEF,oBAAY,eAAe;IAC1B,UAAU,mCAAmC;IAC7C,QAAQ,4EAA4E;IACpF,SAAS,0CAA0C;IACnD,QAAQ,yCAAyC;CACjD;AAED,MAAM,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,CAAC,OAAO,OAAO,SAAU,SAAQ,YAAY;IAClD,SAAgB,OAAO,EAAE,gBAAgB,CAOvC;IAEF,SAAgB,KAAK,mBAA0B;IAE/C,OAAO,CAAC,MAAM,CAMZ;IAEF,OAAO,CAAC,UAAU,CAA8B;gBAEpC,OAAO,CAAC,EAAE,gBAAgB;IAW/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO;IAyC5D,IAAI,CAAC,IAAI,EAAE,aAAa,EAAE,GAAG,OAAO;IAepC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG;IAuC9B,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAkB3D,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,GAAG;IAgB/B,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM;IAwB1D,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM;IAW1C,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO;IAoBhD,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS;IAiBhD,IAAI,IAAI,MAAM,EAAE;IAWhB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO;IAKlC,QAAQ,IAAI,cAAc;IAK1B,QAAQ,IAAI,IAAI;IAQhB,UAAU,IAAI,IAAI;IAclB,KAAK,IAAI,IAAI;IAKb,aAAa,IAAI,MAAM,GAAG,MAAM,CAAC,OAAO;IAI/C,OAAO,CAAC,SAAS;IAIjB,OAAO,CAAC,sBAAsB;IAO9B,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,OAAO;IAIf,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,iBAAiB;IA6BzB,OAAO,CAAC,aAAa;IAarB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,YAAY;IAOpB,OAAO,CAAC,WAAW;IAUnB,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,KAAK;CAOb"}
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\nimport eventemitter from 'eventemitter3';\n\nexport type NodeCacheOptions = {\n\tstdTTL?: number; // The standard ttl as number in seconds for every generated cache element. 0 = unlimited\n\tcheckperiod?: number; // Default is 600\n\tuseClones?: boolean; // Default is true\n\tdeleteOnExpire?: boolean; // Default is true\n\tmaxKeys?: number; // Default is -1\n};\n\nexport type NodeCacheItem = {\n\tkey: string | number;\n\tvalue: any;\n\tttl?: number;\n};\n\nexport enum NodeCacheErrors {\n\tECACHEFULL = 'Cache max keys amount exceeded',\n\tEKEYTYPE = 'The key argument has to be of type `string` or `number`. Found: `__key`',\n\tEKEYSTYPE = 'The keys argument has to be an array.',\n\tETTLTYPE = 'The ttl argument has to be a number.',\n}\n\nexport type NodeCacheStats = {\n\tkeys: number; // global key count\n\thits: number; // global hit count\n\tmisses: number; // global miss count\n\tksize: number; // global key size count in approximately bytes\n\tvsize: number; // global value size count in approximately bytes\n};\n\nexport default class NodeCache extends eventemitter {\n\tpublic readonly options: NodeCacheOptions = {\n\t\t// eslint-disable-next-line @typescript-eslint/naming-convention\n\t\tstdTTL: 0,\n\t\tcheckperiod: 600,\n\t\tuseClones: true,\n\t\tdeleteOnExpire: true,\n\t\tmaxKeys: -1,\n\t};\n\n\tpublic readonly store = new Map<string, any>();\n\n\tprivate _stats: NodeCacheStats = {\n\t\tkeys: 0,\n\t\thits: 0,\n\t\tmisses: 0,\n\t\tksize: 0,\n\t\tvsize: 0,\n\t};\n\n\tprivate intervalId: number | NodeJS.Timeout = 0;\n\n\tconstructor(options?: NodeCacheOptions) {\n\t\tsuper();\n\n\t\tif (options) {\n\t\t\tthis.options = {...this.options, ...options};\n\t\t}\n\n\t\tthis.startInterval();\n\t}\n\n\t// Sets a key value pair. It is possible to define a ttl (in seconds). Returns true on success.\n\tpublic set(key: string | number, value: any, ttl?: number): boolean {\n\t\t// Check on key type\n\t\t/* c8 ignore next 3 */\n\t\tif (typeof key !== 'string' && typeof key !== 'number') {\n\t\t\tthrow this.createError(NodeCacheErrors.EKEYTYPE, key);\n\t\t}\n\n\t\t// Check on ttl type\n\t\t/* c8 ignore next 3 */\n\t\tif (ttl && typeof ttl !== 'number') {\n\t\t\tthrow this.createError(NodeCacheErrors.ETTLTYPE, this.formatKey(key));\n\t\t}\n\n\t\tconst keyValue = this.formatKey(key);\n\t\tconst ttlValue = ttl ?? this.options.stdTTL;\n\t\tlet expirationTimestamp = 0; // Never delete\n\t\tif (ttlValue && ttlValue > 0) {\n\t\t\texpirationTimestamp = this.getExpirationTimestamp(ttlValue);\n\t\t}\n\n\t\t// Check on max key size\n\t\tif (this.options.maxKeys) {\n\t\t\tconst maxKeys = this.options.maxKeys;\n\t\t\tif (maxKeys > -1 && this.store.size >= maxKeys) {\n\t\t\t\tthrow this.createError(NodeCacheErrors.ECACHEFULL, this.formatKey(key));\n\t\t\t}\n\t\t}\n\n\t\tthis.store.set(keyValue, {key: keyValue, value, ttl: expirationTimestamp});\n\n\t\t// Event\n\t\tthis.emit('set', keyValue, value, ttlValue);\n\n\t\t// Add the bytes to the stats\n\t\tthis._stats.ksize += this.roughSizeOfKey(keyValue);\n\t\tthis._stats.vsize += this.roughSizeOfObject(value);\n\t\tthis._stats.keys = this.store.size;\n\t\treturn true;\n\t}\n\n\t// Sets multiple key val pairs. It is possible to define a ttl (seconds). Returns true on success.\n\tpublic mset(data: NodeCacheItem[]): boolean {\n\t\t// Check on keys type\n\t\t/* c8 ignore next 3 */\n\t\tif (!Array.isArray(data)) {\n\t\t\tthrow this.createError(NodeCacheErrors.EKEYSTYPE);\n\t\t}\n\n\t\tfor (const item of data) {\n\t\t\tthis.set(item.key, item.value, item.ttl);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t// Gets a saved value from the cache. Returns a undefined if not found or expired. If the value was found it returns the value.\n\tpublic get(key: string | number): any {\n\t\tconst result = this.store.get(this.formatKey(key));\n\t\tif (result) {\n\t\t\tif (result.ttl > 0) {\n\t\t\t\tif (result.ttl < Date.now()) {\n\t\t\t\t\tif (this.options.deleteOnExpire) {\n\t\t\t\t\t\tthis.del(key);\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.addMiss();\n\t\t\t\t\t// Event\n\t\t\t\t\tthis.emit('expired', this.formatKey(key), result.value);\n\t\t\t\t\treturn undefined;\n\t\t\t\t}\n\n\t\t\t\tthis.addHit();\n\t\t\t\tif (this.options.useClones) {\n\t\t\t\t\treturn this.clone(result.value);\n\t\t\t\t}\n\n\t\t\t\treturn result.value;\n\t\t\t}\n\n\t\t\tthis.addHit();\n\t\t\tif (this.options.useClones) {\n\t\t\t\treturn this.clone(result.value);\n\t\t\t}\n\n\t\t\treturn result.value;\n\t\t}\n\n\t\tthis.addMiss();\n\t\treturn undefined;\n\t}\n\n\t/*\n\t\tGets multiple saved values from the cache. Returns an empty object {} if not found or expired.\n\t\tIf the value was found it returns an object with the key value pair.\n\t*/\n\tpublic mget(keys: Array<string | number>): Record<string, unknown> {\n\t\tconst result: Record<string, unknown> = {};\n\n\t\tfor (const key of keys) {\n\t\t\tconst value = this.get(key);\n\t\t\tif (value) {\n\t\t\t\tresult[this.formatKey(key)] = value;\n\t\t\t}\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/*\n\t\tGet the cached value and remove the key from the cache.\n\t\tEquivalent to calling get(key) + del(key).\n\t\tUseful for implementing single use mechanism such as OTP, where once a value is read it will become obsolete.\n\t*/\n\tpublic take(key: string | number): any {\n\t\tconst result = this.get(key);\n\n\t\tif (result) {\n\t\t\tthis.del(key);\n\t\t\tif (this.options.useClones) {\n\t\t\t\treturn this.clone(result);\n\t\t\t}\n\n\t\t\treturn result;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t// Delete a key. Returns the number of deleted entries. A delete will never fail.\n\tpublic del(key: string | number | Array<string | number>): number {\n\t\tif (Array.isArray(key)) {\n\t\t\treturn this.mdel(key);\n\t\t}\n\n\t\tconst result = this.store.get(this.formatKey(key));\n\t\tif (result) {\n\t\t\tconst keyValue = this.formatKey(key);\n\t\t\tthis.store.delete(keyValue);\n\n\t\t\t// Event\n\t\t\tthis.emit('del', keyValue, result.value);\n\n\t\t\t// Remove the bytes from the stats\n\t\t\tthis._stats.ksize -= this.roughSizeOfKey(keyValue);\n\t\t\tthis._stats.vsize -= this.roughSizeOfObject(result.value);\n\t\t\tthis._stats.keys = this.store.size;\n\t\t\treturn 1;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t// Delete all keys in Array that exist. Returns the number of deleted entries.\n\tpublic mdel(keys: Array<string | number>): number {\n\t\tlet result = 0;\n\t\tfor (const key of keys) {\n\t\t\tresult += this.del(key);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// Redefine the ttl of a key. Returns true if the key has been found and changed.\n\t// Otherwise returns false. If the ttl-argument isn't passed the default-TTL will be used.\n\tpublic ttl(key: string | number, ttl?: number): boolean {\n\t\tconst result = this.store.get(this.formatKey(key));\n\t\tif (result) {\n\t\t\tconst ttlValue = ttl ?? this.options.stdTTL!;\n\t\t\tresult.ttl = this.getExpirationTimestamp(ttlValue);\n\t\t\tthis.store.set(this.formatKey(key), result);\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/*\n\t\tReceive the ttl of a key. You will get:\n\n\t\tundefined if the key does not exist\n\t\t0 if this key has no ttl\n\t\ta timestamp in ms representing the time at which the key will expire\n\t*/\n\n\tpublic getTtl(key: string | number): number | undefined {\n\t\tconst result = this.store.get(this.formatKey(key));\n\t\tif (result) {\n\t\t\tif (result.ttl === 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\n\t\t\treturn result.ttl as number;\n\t\t}\n\n\t\treturn undefined;\n\t}\n\n\t/*\n\t\tReturns an array of all existing keys.\n\t\t[ \"all\", \"my\", \"keys\", \"foo\", \"bar\" ]\n\t*/\n\tpublic keys(): string[] {\n\t\tconst result: string[] = [];\n\n\t\tfor (const key of this.store.keys()) {\n\t\t\tresult.push(key);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t// Returns boolean indicating if the key is cached.\n\tpublic has(key: string | number): boolean {\n\t\treturn this.store.has(this.formatKey(key));\n\t}\n\n\t// Gets the stats of the cache.\n\tpublic getStats(): NodeCacheStats {\n\t\treturn this._stats;\n\t}\n\n\t// Flush the whole data.\n\tpublic flushAll(): void {\n\t\tthis.store.clear();\n\t\tthis.flushStats();\n\t\t// Event\n\t\tthis.emit('flush');\n\t}\n\n\t// Flush the stats\n\tpublic flushStats(): void {\n\t\tthis._stats = {\n\t\t\tkeys: 0,\n\t\t\thits: 0,\n\t\t\tmisses: 0,\n\t\t\tksize: 0,\n\t\t\tvsize: 0,\n\t\t};\n\n\t\t// Event\n\t\tthis.emit('flush_stats');\n\t}\n\n\t// Close the cache. This will clear the interval timeout which is set on check period option.\n\tpublic close(): void {\n\t\tthis.stopInterval();\n\t}\n\n\t// Get the interval id\n\tpublic getIntervalId(): number | NodeJS.Timeout {\n\t\treturn this.intervalId;\n\t}\n\n\tprivate formatKey(key: string | number): string {\n\t\treturn key.toString();\n\t}\n\n\tprivate getExpirationTimestamp(ttlInSeconds: number): number {\n\t\tconst currentTimestamp = Date.now(); // Current time in milliseconds\n\t\tconst ttlInMilliseconds = ttlInSeconds * 1000; // Convert TTL to milliseconds\n\t\tconst expirationTimestamp = currentTimestamp + ttlInMilliseconds;\n\t\treturn expirationTimestamp;\n\t}\n\n\tprivate addHit(): void {\n\t\tthis._stats.hits++;\n\t}\n\n\tprivate addMiss(): void {\n\t\tthis._stats.misses++;\n\t}\n\n\tprivate roughSizeOfKey(key: string): number {\n\t\t// Keys are strings (UTF-16)\n\t\treturn this.formatKey(key).toString().length * 2;\n\t}\n\n\tprivate roughSizeOfObject(object: any): number {\n\t\tconst objectList: any[] = [];\n\t\tconst stack: any[] = [object];\n\t\tlet bytes = 0;\n\n\t\twhile (stack.length > 0) {\n\t\t\tconst value = stack.pop();\n\n\t\t\tif (typeof value === 'boolean') {\n\t\t\t\tbytes += 4; // Booleans are 4 bytes\n\t\t\t} else if (typeof value === 'string') {\n\t\t\t\tbytes += value.length * 2; // Each character is 2 bytes (UTF-16 encoding)\n\t\t\t} else if (typeof value === 'number') {\n\t\t\t\tbytes += 8; // Numbers are 8 bytes (IEEE 754 format)\n\t\t\t} else if (typeof value === 'object' && value !== null && !objectList.includes(value)) {\n\t\t\t\tobjectList.push(value);\n\n\t\t\t\t// Estimate object overhead, and then recursively estimate the size of properties\n\t\t\t\t// eslint-disable-next-line guard-for-in\n\t\t\t\tfor (const key in value) {\n\t\t\t\t\tbytes += key.length * 2; // Keys are strings (UTF-16)\n\t\t\t\t\tstack.push(value[key]); // Add values to the stack to compute their size\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn bytes;\n\t}\n\n\tprivate startInterval(): void {\n\t\tif (this.options.checkperiod && this.options.checkperiod > 0) {\n\t\t\tconst checkPeriodinSeconds = this.options.checkperiod * 1000;\n\t\t\tthis.intervalId = setInterval(() => {\n\t\t\t\tthis.checkData();\n\t\t\t}, checkPeriodinSeconds);\n\n\t\t\treturn;\n\t\t}\n\n\t\tthis.intervalId = 0;\n\t}\n\n\tprivate checkData(): void {\n\t\tfor (const [key, value] of this.store.entries()) {\n\t\t\tif (value.ttl > 0 && value.ttl < Date.now()) {\n\t\t\t\tthis.del(key);\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate stopInterval(): void {\n\t\tif (this.intervalId !== 0) {\n\t\t\tclearInterval(this.intervalId);\n\t\t\tthis.intervalId = 0;\n\t\t}\n\t}\n\n\tprivate createError(errorCode: string, key?: string): Error {\n\t\tlet error = errorCode;\n\t\t/* c8 ignore next 3 */\n\t\tif (key) {\n\t\t\terror = error.replace('__key', key);\n\t\t}\n\n\t\treturn new Error(error);\n\t}\n\n\tprivate isPrimitive(value: any): boolean {\n\t\tconst result = false;\n\n\t\t/* c8 ignore next 3 */\n\t\tif (value === null || value === undefined) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn result;\n\t}\n\n\tprivate clone(value: any): any {\n\t\tif (this.isPrimitive(value)) {\n\t\t\treturn value;\n\t\t}\n\n\t\treturn structuredClone(value);\n\t}\n}\n\n"]}