1 | /*
|
2 | * node-cache 5.1.0 ( 2019-12-08 )
|
3 | * https://github.com/mpneuried/nodecache
|
4 | *
|
5 | * Released under the MIT license
|
6 | * https://github.com/mpneuried/nodecache/blob/master/LICENSE
|
7 | *
|
8 | * Maintained by ( )
|
9 | */
|
10 | (function() {
|
11 | var EventEmitter, NodeCache, clone,
|
12 | splice = [].splice,
|
13 | boundMethodCheck = function(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new Error('Bound instance method accessed before binding'); } },
|
14 | indexOf = [].indexOf;
|
15 |
|
16 | clone = require("clone");
|
17 |
|
18 | EventEmitter = require('events').EventEmitter;
|
19 |
|
20 | // generate superclass
|
21 | module.exports = NodeCache = (function() {
|
22 | class NodeCache extends EventEmitter {
|
23 | constructor(options = {}) {
|
24 | super();
|
25 | // ## get
|
26 |
|
27 | // get a cached key and change the stats
|
28 |
|
29 | // **Parameters:**
|
30 |
|
31 | // * `key` ( String | Number ): cache key
|
32 |
|
33 | // **Example:**
|
34 |
|
35 | // myCache.get "myKey", ( err, val )
|
36 |
|
37 | this.get = this.get.bind(this);
|
38 | // ## mget
|
39 |
|
40 | // get multiple cached keys at once and change the stats
|
41 |
|
42 | // **Parameters:**
|
43 |
|
44 | // * `keys` ( String|Number[] ): an array of keys
|
45 |
|
46 | // **Example:**
|
47 |
|
48 | // myCache.mget [ "foo", "bar" ]
|
49 |
|
50 | this.mget = this.mget.bind(this);
|
51 | // ## set
|
52 |
|
53 | // set a cached key and change the stats
|
54 |
|
55 | // **Parameters:**
|
56 |
|
57 | // * `key` ( String | Number ): cache key
|
58 | // * `value` ( Any ): A element to cache. If the option `option.forceString` is `true` the module trys to translate it to a serialized JSON
|
59 | // * `[ ttl ]` ( Number | String ): ( optional ) The time to live in seconds.
|
60 |
|
61 | // **Example:**
|
62 |
|
63 | // myCache.set "myKey", "my_String Value"
|
64 |
|
65 | // myCache.set "myKey", "my_String Value", 10
|
66 |
|
67 | this.set = this.set.bind(this);
|
68 |
|
69 | // ## mset
|
70 |
|
71 | // set multiple keys at once
|
72 |
|
73 | // **Parameters:**
|
74 |
|
75 | // * `keyValueSet` ( Object[] ): an array of object which includes key,value and ttl
|
76 |
|
77 | // **Example:**
|
78 |
|
79 | // myCache.mset(
|
80 | // [
|
81 | // {
|
82 | // key: "myKey",
|
83 | // val: "myValue",
|
84 | // ttl: [ttl in seconds]
|
85 | // }
|
86 | // ])
|
87 |
|
88 | this.mset = this.mset.bind(this);
|
89 | // ## del
|
90 |
|
91 | // remove keys
|
92 |
|
93 | // **Parameters:**
|
94 |
|
95 | // * `keys` ( String | Number | String|Number[] ): cache key to delete or a array of cache keys
|
96 |
|
97 | // **Return**
|
98 |
|
99 | // ( Number ): Number of deleted keys
|
100 |
|
101 | // **Example:**
|
102 |
|
103 | // myCache.del( "myKey" )
|
104 |
|
105 | this.del = this.del.bind(this);
|
106 | // ## take
|
107 |
|
108 | // get the cached value and remove the key from the cache.
|
109 | // Equivalent to calling `get(key)` + `del(key)`.
|
110 | // Useful for implementing `single use` mechanism such as OTP, where once a value is read it will become obsolete.
|
111 |
|
112 | // **Parameters:**
|
113 |
|
114 | // * `key` ( String | Number ): cache key
|
115 |
|
116 | // **Example:**
|
117 |
|
118 | // myCache.take "myKey", ( err, val )
|
119 |
|
120 | this.take = this.take.bind(this);
|
121 | // ## ttl
|
122 |
|
123 | // reset or redefine the ttl of a key. `ttl` = 0 means infinite lifetime.
|
124 | // If `ttl` is not passed the default ttl is used.
|
125 | // If `ttl` < 0 the key will be deleted.
|
126 |
|
127 | // **Parameters:**
|
128 |
|
129 | // * `key` ( String | Number ): cache key to reset the ttl value
|
130 | // * `ttl` ( Number ): ( optional -> options.stdTTL || 0 ) The time to live in seconds
|
131 |
|
132 | // **Return**
|
133 |
|
134 | // ( Boolen ): key found and ttl set
|
135 |
|
136 | // **Example:**
|
137 |
|
138 | // myCache.ttl( "myKey" ) // will set ttl to default ttl
|
139 |
|
140 | // myCache.ttl( "myKey", 1000 )
|
141 |
|
142 | this.ttl = this.ttl.bind(this);
|
143 | // ## getTtl
|
144 |
|
145 | // receive the ttl of a key.
|
146 |
|
147 | // **Parameters:**
|
148 |
|
149 | // * `key` ( String | Number ): cache key to check the ttl value
|
150 |
|
151 | // **Return**
|
152 |
|
153 | // ( Number|undefined ): The timestamp in ms when the key will expire, 0 if it will never expire or undefined if it not exists
|
154 |
|
155 | // **Example:**
|
156 |
|
157 | // myCache.getTtl( "myKey" )
|
158 |
|
159 | this.getTtl = this.getTtl.bind(this);
|
160 | // ## keys
|
161 |
|
162 | // list all keys within this cache
|
163 |
|
164 | // **Return**
|
165 |
|
166 | // ( Array ): An array of all keys
|
167 |
|
168 | // **Example:**
|
169 |
|
170 | // _keys = myCache.keys()
|
171 |
|
172 | // # [ "foo", "bar", "fizz", "buzz", "anotherKeys" ]
|
173 |
|
174 | this.keys = this.keys.bind(this);
|
175 | // ## has
|
176 |
|
177 | // Check if a key is cached
|
178 |
|
179 | // **Parameters:**
|
180 |
|
181 | // * `key` ( String | Number ): cache key to check the ttl value
|
182 |
|
183 | // **Return**
|
184 |
|
185 | // ( Boolean ): A boolean that indicates if the key is cached
|
186 |
|
187 | // **Example:**
|
188 |
|
189 | // _exists = myCache.has('myKey')
|
190 |
|
191 | // # true
|
192 |
|
193 | this.has = this.has.bind(this);
|
194 | // ## getStats
|
195 |
|
196 | // get the stats
|
197 |
|
198 | // **Parameters:**
|
199 |
|
200 | // -
|
201 |
|
202 | // **Return**
|
203 |
|
204 | // ( Object ): Stats data
|
205 |
|
206 | // **Example:**
|
207 |
|
208 | // myCache.getStats()
|
209 | // # {
|
210 | // # hits: 0,
|
211 | // # misses: 0,
|
212 | // # keys: 0,
|
213 | // # ksize: 0,
|
214 | // # vsize: 0
|
215 | // # }
|
216 |
|
217 | this.getStats = this.getStats.bind(this);
|
218 | // ## flushAll
|
219 |
|
220 | // flush the whole data and reset the stats
|
221 |
|
222 | // **Example:**
|
223 |
|
224 | // myCache.flushAll()
|
225 |
|
226 | // myCache.getStats()
|
227 | // # {
|
228 | // # hits: 0,
|
229 | // # misses: 0,
|
230 | // # keys: 0,
|
231 | // # ksize: 0,
|
232 | // # vsize: 0
|
233 | // # }
|
234 |
|
235 | this.flushAll = this.flushAll.bind(this);
|
236 |
|
237 | // ## flushStats
|
238 |
|
239 | // flush the stats and reset all counters to 0
|
240 |
|
241 | // **Example:**
|
242 |
|
243 | // myCache.flushStats()
|
244 |
|
245 | // myCache.getStats()
|
246 | // # {
|
247 | // # hits: 0,
|
248 | // # misses: 0,
|
249 | // # keys: 0,
|
250 | // # ksize: 0,
|
251 | // # vsize: 0
|
252 | // # }
|
253 |
|
254 | this.flushStats = this.flushStats.bind(this);
|
255 | // ## close
|
256 |
|
257 | // This will clear the interval timeout which is set on checkperiod option.
|
258 |
|
259 | // **Example:**
|
260 |
|
261 | // myCache.close()
|
262 |
|
263 | this.close = this.close.bind(this);
|
264 | // ## _checkData
|
265 |
|
266 | // internal housekeeping method.
|
267 | // Check all the cached data and delete the invalid values
|
268 | this._checkData = this._checkData.bind(this);
|
269 | // ## _check
|
270 |
|
271 | // internal method the check the value. If it's not valid any more delete it
|
272 | this._check = this._check.bind(this);
|
273 | // ## _isInvalidKey
|
274 |
|
275 | // internal method to check if the type of a key is either `number` or `string`
|
276 | this._isInvalidKey = this._isInvalidKey.bind(this);
|
277 | // ## _wrap
|
278 |
|
279 | // internal method to wrap a value in an object with some metadata
|
280 | this._wrap = this._wrap.bind(this);
|
281 | // ## _getValLength
|
282 |
|
283 | // internal method to calculate the value length
|
284 | this._getValLength = this._getValLength.bind(this);
|
285 | // ## _error
|
286 |
|
287 | // internal method to handle an error message
|
288 | this._error = this._error.bind(this);
|
289 | // ## _initErrors
|
290 |
|
291 | // internal method to generate error message templates
|
292 | this._initErrors = this._initErrors.bind(this);
|
293 | this.options = options;
|
294 | this._initErrors();
|
295 | // container for cached data
|
296 | this.data = {};
|
297 | // module options
|
298 | this.options = Object.assign({
|
299 | // convert all elements to string
|
300 | forceString: false,
|
301 | // used standard size for calculating value size
|
302 | objectValueSize: 80,
|
303 | promiseValueSize: 80,
|
304 | arrayValueSize: 40,
|
305 | // standard time to live in seconds. 0 = infinity;
|
306 | stdTTL: 0,
|
307 | // time in seconds to check all data and delete expired keys
|
308 | checkperiod: 600,
|
309 | // en/disable cloning of variables. If `true` you'll get a copy of the cached variable. If `false` you'll save and get just the reference
|
310 | useClones: true,
|
311 | // whether values should be deleted automatically at expiration
|
312 | deleteOnExpire: true,
|
313 | // enable legacy callbacks
|
314 | enableLegacyCallbacks: false,
|
315 | // max amount of keys that are being stored
|
316 | maxKeys: -1
|
317 | }, this.options);
|
318 | // generate functions with callbacks (legacy)
|
319 | if (this.options.enableLegacyCallbacks) {
|
320 | console.warn("WARNING! node-cache legacy callback support will drop in v6.x");
|
321 | ["get", "mget", "set", "del", "ttl", "getTtl", "keys", "has"].forEach((methodKey) => {
|
322 | var oldMethod;
|
323 | // reference real function
|
324 | oldMethod = this[methodKey];
|
325 | this[methodKey] = function(...args) {
|
326 | var cb, err, ref, res;
|
327 | ref = args, [...args] = ref, [cb] = splice.call(args, -1);
|
328 | // return a callback if cb is defined and a function
|
329 | if (typeof cb === "function") {
|
330 | try {
|
331 | res = oldMethod(...args);
|
332 | cb(null, res);
|
333 | } catch (error1) {
|
334 | err = error1;
|
335 | cb(err);
|
336 | }
|
337 | } else {
|
338 | return oldMethod(...args, cb);
|
339 | }
|
340 | };
|
341 | });
|
342 | }
|
343 | // statistics container
|
344 | this.stats = {
|
345 | hits: 0,
|
346 | misses: 0,
|
347 | keys: 0,
|
348 | ksize: 0,
|
349 | vsize: 0
|
350 | };
|
351 | // pre allocate valid keytypes array
|
352 | this.validKeyTypes = ["string", "number"];
|
353 | // initalize checking period
|
354 | this._checkData();
|
355 | return;
|
356 | }
|
357 |
|
358 | get(key) {
|
359 | var _ret, err;
|
360 | boundMethodCheck(this, NodeCache);
|
361 | // handle invalid key types
|
362 | if ((err = this._isInvalidKey(key)) != null) {
|
363 | throw err;
|
364 | }
|
365 | // get data and incremet stats
|
366 | if ((this.data[key] != null) && this._check(key, this.data[key])) {
|
367 | this.stats.hits++;
|
368 | _ret = this._unwrap(this.data[key]);
|
369 | // return data
|
370 | return _ret;
|
371 | } else {
|
372 | // if not found return undefined
|
373 | this.stats.misses++;
|
374 | return void 0;
|
375 | }
|
376 | }
|
377 |
|
378 | mget(keys) {
|
379 | var _err, err, i, key, len, oRet;
|
380 | boundMethodCheck(this, NodeCache);
|
381 | // convert a string to an array of one key
|
382 | if (!Array.isArray(keys)) {
|
383 | _err = this._error("EKEYSTYPE");
|
384 | throw _err;
|
385 | }
|
386 | // define return
|
387 | oRet = {};
|
388 | for (i = 0, len = keys.length; i < len; i++) {
|
389 | key = keys[i];
|
390 | // handle invalid key types
|
391 | if ((err = this._isInvalidKey(key)) != null) {
|
392 | throw err;
|
393 | }
|
394 | // get data and increment stats
|
395 | if ((this.data[key] != null) && this._check(key, this.data[key])) {
|
396 | this.stats.hits++;
|
397 | oRet[key] = this._unwrap(this.data[key]);
|
398 | } else {
|
399 | // if not found return a error
|
400 | this.stats.misses++;
|
401 | }
|
402 | }
|
403 | // return all found keys
|
404 | return oRet;
|
405 | }
|
406 |
|
407 | set(key, value, ttl) {
|
408 | var _err, err, existent;
|
409 | boundMethodCheck(this, NodeCache);
|
410 | // check if cache is overflowing
|
411 | if (this.options.maxKeys > -1 && this.stats.keys >= this.options.maxKeys) {
|
412 | _err = this._error("ECACHEFULL");
|
413 | throw _err;
|
414 | }
|
415 | // force the data to string
|
416 | if (this.options.forceString && !typeof value === "string") {
|
417 | value = JSON.stringify(value);
|
418 | }
|
419 | // set default ttl if not passed
|
420 | if (ttl == null) {
|
421 | ttl = this.options.stdTTL;
|
422 | }
|
423 | // handle invalid key types
|
424 | if ((err = this._isInvalidKey(key)) != null) {
|
425 | throw err;
|
426 | }
|
427 | // internal helper variables
|
428 | existent = false;
|
429 | // remove existing data from stats
|
430 | if (this.data[key]) {
|
431 | existent = true;
|
432 | this.stats.vsize -= this._getValLength(this._unwrap(this.data[key], false));
|
433 | }
|
434 | // set the value
|
435 | this.data[key] = this._wrap(value, ttl);
|
436 | this.stats.vsize += this._getValLength(value);
|
437 | // only add the keys and key-size if the key is new
|
438 | if (!existent) {
|
439 | this.stats.ksize += this._getKeyLength(key);
|
440 | this.stats.keys++;
|
441 | }
|
442 | this.emit("set", key, value);
|
443 | // return true
|
444 | return true;
|
445 | }
|
446 |
|
447 | mset(keyValueSet) {
|
448 | var _err, err, i, j, key, keyValuePair, len, len1, ttl, val;
|
449 | boundMethodCheck(this, NodeCache);
|
450 | // check if cache is overflowing
|
451 | if (this.options.maxKeys > -1 && this.stats.keys + keyValueSet.length >= this.options.maxKeys) {
|
452 | _err = this._error("ECACHEFULL");
|
453 | throw _err;
|
454 | }
|
455 |
|
456 | // loop over keyValueSet to validate key and ttl
|
457 | for (i = 0, len = keyValueSet.length; i < len; i++) {
|
458 | keyValuePair = keyValueSet[i];
|
459 | ({key, val, ttl} = keyValuePair);
|
460 | // check if there is ttl and it's a number
|
461 | if (ttl && typeof ttl !== "number") {
|
462 | _err = this._error("ETTLTYPE");
|
463 | throw _err;
|
464 | }
|
465 | // handle invalid key types
|
466 | if ((err = this._isInvalidKey(key)) != null) {
|
467 | throw err;
|
468 | }
|
469 | }
|
470 | for (j = 0, len1 = keyValueSet.length; j < len1; j++) {
|
471 | keyValuePair = keyValueSet[j];
|
472 | ({key, val, ttl} = keyValuePair);
|
473 | this.set(key, val, ttl);
|
474 | }
|
475 | return true;
|
476 | }
|
477 |
|
478 | del(keys) {
|
479 | var delCount, err, i, key, len, oldVal;
|
480 | boundMethodCheck(this, NodeCache);
|
481 | // convert keys to an array of itself
|
482 | if (!Array.isArray(keys)) {
|
483 | keys = [keys];
|
484 | }
|
485 | delCount = 0;
|
486 | for (i = 0, len = keys.length; i < len; i++) {
|
487 | key = keys[i];
|
488 | // handle invalid key types
|
489 | if ((err = this._isInvalidKey(key)) != null) {
|
490 | throw err;
|
491 | }
|
492 | // only delete if existent
|
493 | if (this.data[key] != null) {
|
494 | // calc the stats
|
495 | this.stats.vsize -= this._getValLength(this._unwrap(this.data[key], false));
|
496 | this.stats.ksize -= this._getKeyLength(key);
|
497 | this.stats.keys--;
|
498 | delCount++;
|
499 | // delete the value
|
500 | oldVal = this.data[key];
|
501 | delete this.data[key];
|
502 | // return true
|
503 | this.emit("del", key, oldVal.v);
|
504 | }
|
505 | }
|
506 | return delCount;
|
507 | }
|
508 |
|
509 | take(key) {
|
510 | var _ret;
|
511 | boundMethodCheck(this, NodeCache);
|
512 | _ret = this.get(key);
|
513 | if ((_ret != null)) {
|
514 | this.del(key);
|
515 | }
|
516 | return _ret;
|
517 | }
|
518 |
|
519 | ttl(key, ttl) {
|
520 | var err;
|
521 | boundMethodCheck(this, NodeCache);
|
522 | ttl || (ttl = this.options.stdTTL);
|
523 | if (!key) {
|
524 | return false;
|
525 | }
|
526 | // handle invalid key types
|
527 | if ((err = this._isInvalidKey(key)) != null) {
|
528 | throw err;
|
529 | }
|
530 | // check for existent data and update the ttl value
|
531 | if ((this.data[key] != null) && this._check(key, this.data[key])) {
|
532 | // if ttl < 0 delete the key. otherwise reset the value
|
533 | if (ttl >= 0) {
|
534 | this.data[key] = this._wrap(this.data[key].v, ttl, false);
|
535 | } else {
|
536 | this.del(key);
|
537 | }
|
538 | return true;
|
539 | } else {
|
540 | // return false if key has not been found
|
541 | return false;
|
542 | }
|
543 | }
|
544 |
|
545 | getTtl(key) {
|
546 | var _ttl, err;
|
547 | boundMethodCheck(this, NodeCache);
|
548 | if (!key) {
|
549 | return void 0;
|
550 | }
|
551 | // handle invalid key types
|
552 | if ((err = this._isInvalidKey(key)) != null) {
|
553 | throw err;
|
554 | }
|
555 | // check for existant data and update the ttl value
|
556 | if ((this.data[key] != null) && this._check(key, this.data[key])) {
|
557 | _ttl = this.data[key].t;
|
558 | return _ttl;
|
559 | } else {
|
560 | // return undefined if key has not been found
|
561 | return void 0;
|
562 | }
|
563 | }
|
564 |
|
565 | keys() {
|
566 | var _keys;
|
567 | boundMethodCheck(this, NodeCache);
|
568 | _keys = Object.keys(this.data);
|
569 | return _keys;
|
570 | }
|
571 |
|
572 | has(key) {
|
573 | var _exists;
|
574 | boundMethodCheck(this, NodeCache);
|
575 | _exists = (this.data[key] != null) && this._check(key, this.data[key]);
|
576 | return _exists;
|
577 | }
|
578 |
|
579 | getStats() {
|
580 | boundMethodCheck(this, NodeCache);
|
581 | return this.stats;
|
582 | }
|
583 |
|
584 | flushAll(_startPeriod = true) {
|
585 | boundMethodCheck(this, NodeCache);
|
586 | // parameter just for testing
|
587 |
|
588 | // set data empty
|
589 | this.data = {};
|
590 | // reset stats
|
591 | this.stats = {
|
592 | hits: 0,
|
593 | misses: 0,
|
594 | keys: 0,
|
595 | ksize: 0,
|
596 | vsize: 0
|
597 | };
|
598 | // reset check period
|
599 | this._killCheckPeriod();
|
600 | this._checkData(_startPeriod);
|
601 | this.emit("flush");
|
602 | }
|
603 |
|
604 | flushStats() {
|
605 | boundMethodCheck(this, NodeCache);
|
606 | // reset stats
|
607 | this.stats = {
|
608 | hits: 0,
|
609 | misses: 0,
|
610 | keys: 0,
|
611 | ksize: 0,
|
612 | vsize: 0
|
613 | };
|
614 | this.emit("flush_stats");
|
615 | }
|
616 |
|
617 | close() {
|
618 | boundMethodCheck(this, NodeCache);
|
619 | this._killCheckPeriod();
|
620 | }
|
621 |
|
622 | _checkData(startPeriod = true) {
|
623 | var key, ref, value;
|
624 | boundMethodCheck(this, NodeCache);
|
625 | ref = this.data;
|
626 | // run the housekeeping method
|
627 | for (key in ref) {
|
628 | value = ref[key];
|
629 | this._check(key, value);
|
630 | }
|
631 | if (startPeriod && this.options.checkperiod > 0) {
|
632 | this.checkTimeout = setTimeout(this._checkData, this.options.checkperiod * 1000, startPeriod);
|
633 | if (this.checkTimeout.unref != null) {
|
634 | this.checkTimeout.unref();
|
635 | }
|
636 | }
|
637 | }
|
638 |
|
639 | // ## _killCheckPeriod
|
640 |
|
641 | // stop the checkdata period. Only needed to abort the script in testing mode.
|
642 | _killCheckPeriod() {
|
643 | if (this.checkTimeout != null) {
|
644 | return clearTimeout(this.checkTimeout);
|
645 | }
|
646 | }
|
647 |
|
648 | _check(key, data) {
|
649 | var _retval;
|
650 | boundMethodCheck(this, NodeCache);
|
651 | _retval = true;
|
652 | // data is invalid if the ttl is too old and is not 0
|
653 | // console.log data.t < Date.now(), data.t, Date.now()
|
654 | if (data.t !== 0 && data.t < Date.now()) {
|
655 | if (this.options.deleteOnExpire) {
|
656 | _retval = false;
|
657 | this.del(key);
|
658 | }
|
659 | this.emit("expired", key, this._unwrap(data));
|
660 | }
|
661 | return _retval;
|
662 | }
|
663 |
|
664 | _isInvalidKey(key) {
|
665 | var ref;
|
666 | boundMethodCheck(this, NodeCache);
|
667 | if (ref = typeof key, indexOf.call(this.validKeyTypes, ref) < 0) {
|
668 | return this._error("EKEYTYPE", {
|
669 | type: typeof key
|
670 | });
|
671 | }
|
672 | }
|
673 |
|
674 | _wrap(value, ttl, asClone = true) {
|
675 | var livetime, now, oReturn, ttlMultiplicator;
|
676 | boundMethodCheck(this, NodeCache);
|
677 | if (!this.options.useClones) {
|
678 | asClone = false;
|
679 | }
|
680 | // define the time to live
|
681 | now = Date.now();
|
682 | livetime = 0;
|
683 | ttlMultiplicator = 1000;
|
684 | // use given ttl
|
685 | if (ttl === 0) {
|
686 | livetime = 0;
|
687 | } else if (ttl) {
|
688 | livetime = now + (ttl * ttlMultiplicator);
|
689 | } else {
|
690 | // use standard ttl
|
691 | if (this.options.stdTTL === 0) {
|
692 | livetime = this.options.stdTTL;
|
693 | } else {
|
694 | livetime = now + (this.options.stdTTL * ttlMultiplicator);
|
695 | }
|
696 | }
|
697 | // return the wrapped value
|
698 | return oReturn = {
|
699 | t: livetime,
|
700 | v: asClone ? clone(value) : value
|
701 | };
|
702 | }
|
703 |
|
704 | // ## _unwrap
|
705 |
|
706 | // internal method to extract get the value out of the wrapped value
|
707 | _unwrap(value, asClone = true) {
|
708 | if (!this.options.useClones) {
|
709 | asClone = false;
|
710 | }
|
711 | if (value.v != null) {
|
712 | if (asClone) {
|
713 | return clone(value.v);
|
714 | } else {
|
715 | return value.v;
|
716 | }
|
717 | }
|
718 | return null;
|
719 | }
|
720 |
|
721 | // ## _getKeyLength
|
722 |
|
723 | // internal method the calculate the key length
|
724 | _getKeyLength(key) {
|
725 | return key.toString().length;
|
726 | }
|
727 |
|
728 | _getValLength(value) {
|
729 | boundMethodCheck(this, NodeCache);
|
730 | if (typeof value === "string") {
|
731 | // if the value is a String get the real length
|
732 | return value.length;
|
733 | } else if (this.options.forceString) {
|
734 | // force string if it's defined and not passed
|
735 | return JSON.stringify(value).length;
|
736 | } else if (Array.isArray(value)) {
|
737 | // if the data is an Array multiply each element with a defined default length
|
738 | return this.options.arrayValueSize * value.length;
|
739 | } else if (typeof value === "number") {
|
740 | return 8;
|
741 | } else if (typeof (value != null ? value.then : void 0) === "function") {
|
742 | // if the data is a Promise, use defined default
|
743 | // (can't calculate actual/resolved value size synchronously)
|
744 | return this.options.promiseValueSize;
|
745 | } else if ((value != null) && typeof value === "object") {
|
746 | // if the data is an Object multiply each element with a defined default length
|
747 | return this.options.objectValueSize * Object.keys(value).length;
|
748 | } else if (typeof value === "boolean") {
|
749 | return 8;
|
750 | } else {
|
751 | // default fallback
|
752 | return 0;
|
753 | }
|
754 | }
|
755 |
|
756 | _error(type, data = {}) {
|
757 | var error;
|
758 | boundMethodCheck(this, NodeCache);
|
759 | // generate the error object
|
760 | error = new Error();
|
761 | error.name = type;
|
762 | error.errorcode = type;
|
763 | error.message = this.ERRORS[type] != null ? this.ERRORS[type](data) : "-";
|
764 | error.data = data;
|
765 | // return the error object
|
766 | return error;
|
767 | }
|
768 |
|
769 | _initErrors() {
|
770 | var _errMsg, _errT, ref;
|
771 | boundMethodCheck(this, NodeCache);
|
772 | this.ERRORS = {};
|
773 | ref = this._ERRORS;
|
774 | for (_errT in ref) {
|
775 | _errMsg = ref[_errT];
|
776 | this.ERRORS[_errT] = this.createErrorMessage(_errMsg);
|
777 | }
|
778 | }
|
779 |
|
780 | createErrorMessage(errMsg) {
|
781 | return function(args) {
|
782 | return errMsg.replace("__key", args.type);
|
783 | };
|
784 | }
|
785 |
|
786 | };
|
787 |
|
788 | NodeCache.prototype._ERRORS = {
|
789 | "ENOTFOUND": "Key `__key` not found",
|
790 | "ECACHEFULL": "Cache max key size exceeded",
|
791 | "EKEYTYPE": "The key argument has to be of type `string` or `number`. Found: `__key`",
|
792 | "EKEYSTYPE": "The keys argument has to be an array.",
|
793 | "ETTLTYPE": "The ttl argument has to be a number."
|
794 | };
|
795 |
|
796 | return NodeCache;
|
797 |
|
798 | }).call(this);
|
799 |
|
800 | }).call(this);
|