cacheable 1.9.0 → 1.10.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 +149 -5
- package/dist/index.cjs +184 -124
- package/dist/index.d.cts +62 -33
- package/dist/index.d.ts +62 -33
- package/dist/index.js +185 -125
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -78,7 +78,7 @@ import {
|
|
|
78
78
|
import { Hookified } from "hookified";
|
|
79
79
|
|
|
80
80
|
// src/hash.ts
|
|
81
|
-
import * as crypto from "
|
|
81
|
+
import * as crypto from "crypto";
|
|
82
82
|
function hash(object, algorithm = "sha256") {
|
|
83
83
|
const objectString = JSON.stringify(object);
|
|
84
84
|
if (!crypto.getHashes().includes(algorithm)) {
|
|
@@ -88,6 +88,26 @@ function hash(object, algorithm = "sha256") {
|
|
|
88
88
|
hasher.update(objectString);
|
|
89
89
|
return hasher.digest("hex");
|
|
90
90
|
}
|
|
91
|
+
function hashToNumber(object, min = 0, max = 10, algorithm = "sha256") {
|
|
92
|
+
const objectString = JSON.stringify(object);
|
|
93
|
+
if (!crypto.getHashes().includes(algorithm)) {
|
|
94
|
+
throw new Error(`Unsupported hash algorithm: '${algorithm}'`);
|
|
95
|
+
}
|
|
96
|
+
const hasher = crypto.createHash(algorithm);
|
|
97
|
+
hasher.update(objectString);
|
|
98
|
+
const hashHex = hasher.digest("hex");
|
|
99
|
+
const hashNumber = Number.parseInt(hashHex, 16);
|
|
100
|
+
const range = max - min + 1;
|
|
101
|
+
return min + hashNumber % range;
|
|
102
|
+
}
|
|
103
|
+
function djb2Hash(string_, min = 0, max = 10) {
|
|
104
|
+
let hash2 = 5381;
|
|
105
|
+
for (let i = 0; i < string_.length; i++) {
|
|
106
|
+
hash2 = hash2 * 33 ^ string_.charCodeAt(i);
|
|
107
|
+
}
|
|
108
|
+
const range = max - min + 1;
|
|
109
|
+
return min + Math.abs(hash2) % range;
|
|
110
|
+
}
|
|
91
111
|
|
|
92
112
|
// src/coalesce-async.ts
|
|
93
113
|
var callbacks = /* @__PURE__ */ new Map();
|
|
@@ -164,29 +184,31 @@ function wrapSync(function_, options) {
|
|
|
164
184
|
return value;
|
|
165
185
|
};
|
|
166
186
|
}
|
|
187
|
+
async function getOrSet(key, function_, options) {
|
|
188
|
+
let value = await options.cache.get(key);
|
|
189
|
+
if (value === void 0) {
|
|
190
|
+
const cacheId = options.cacheId ?? "default";
|
|
191
|
+
const coalesceKey = `${cacheId}::${key}`;
|
|
192
|
+
value = await coalesceAsync(coalesceKey, async () => {
|
|
193
|
+
try {
|
|
194
|
+
const result = await function_();
|
|
195
|
+
await options.cache.set(key, result, options.ttl);
|
|
196
|
+
return result;
|
|
197
|
+
} catch (error) {
|
|
198
|
+
options.cache.emit("error", error);
|
|
199
|
+
if (options.cacheErrors) {
|
|
200
|
+
await options.cache.set(key, error, options.ttl);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
return value;
|
|
206
|
+
}
|
|
167
207
|
function wrap(function_, options) {
|
|
168
|
-
const {
|
|
208
|
+
const { keyPrefix, cache } = options;
|
|
169
209
|
return async function(...arguments_) {
|
|
170
|
-
let value;
|
|
171
210
|
const cacheKey = createWrapKey(function_, arguments_, keyPrefix);
|
|
172
|
-
|
|
173
|
-
if (value === void 0) {
|
|
174
|
-
const cacheId = options.cacheId ?? "default";
|
|
175
|
-
const coalesceKey = `${cacheId}::${cacheKey}`;
|
|
176
|
-
value = await coalesceAsync(coalesceKey, async () => {
|
|
177
|
-
try {
|
|
178
|
-
const result = await function_(...arguments_);
|
|
179
|
-
await cache.set(cacheKey, result, ttl);
|
|
180
|
-
return result;
|
|
181
|
-
} catch (error) {
|
|
182
|
-
cache.emit("error", error);
|
|
183
|
-
if (options.cacheErrors) {
|
|
184
|
-
await cache.set(cacheKey, error, ttl);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
return value;
|
|
211
|
+
return cache.getOrSet(cacheKey, async () => function_(...arguments_), options);
|
|
190
212
|
};
|
|
191
213
|
}
|
|
192
214
|
function createWrapKey(function_, arguments_, keyPrefix) {
|
|
@@ -270,19 +292,14 @@ var DoublyLinkedList = class {
|
|
|
270
292
|
};
|
|
271
293
|
|
|
272
294
|
// src/memory.ts
|
|
295
|
+
var defaultStoreHashSize = 16;
|
|
296
|
+
var maximumMapSize = 16777216;
|
|
273
297
|
var CacheableMemory = class extends Hookified {
|
|
274
298
|
_lru = new DoublyLinkedList();
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
_hash3 = /* @__PURE__ */ new Map();
|
|
280
|
-
_hash4 = /* @__PURE__ */ new Map();
|
|
281
|
-
_hash5 = /* @__PURE__ */ new Map();
|
|
282
|
-
_hash6 = /* @__PURE__ */ new Map();
|
|
283
|
-
_hash7 = /* @__PURE__ */ new Map();
|
|
284
|
-
_hash8 = /* @__PURE__ */ new Map();
|
|
285
|
-
_hash9 = /* @__PURE__ */ new Map();
|
|
299
|
+
_storeHashSize = defaultStoreHashSize;
|
|
300
|
+
_storeHashAlgorithm = "djb2Hash" /* djb2Hash */;
|
|
301
|
+
// Default is djb2Hash
|
|
302
|
+
_store = Array.from({ length: this._storeHashSize }, () => /* @__PURE__ */ new Map());
|
|
286
303
|
_ttl;
|
|
287
304
|
// Turned off by default
|
|
288
305
|
_useClone = true;
|
|
@@ -305,12 +322,23 @@ var CacheableMemory = class extends Hookified {
|
|
|
305
322
|
if (options?.useClone !== void 0) {
|
|
306
323
|
this._useClone = options.useClone;
|
|
307
324
|
}
|
|
325
|
+
if (options?.storeHashSize && options.storeHashSize > 0) {
|
|
326
|
+
this._storeHashSize = options.storeHashSize;
|
|
327
|
+
}
|
|
308
328
|
if (options?.lruSize) {
|
|
309
|
-
|
|
329
|
+
if (options.lruSize > maximumMapSize) {
|
|
330
|
+
this.emit("error", new Error(`LRU size cannot be larger than ${maximumMapSize} due to Map limitations.`));
|
|
331
|
+
} else {
|
|
332
|
+
this._lruSize = options.lruSize;
|
|
333
|
+
}
|
|
310
334
|
}
|
|
311
335
|
if (options?.checkInterval) {
|
|
312
336
|
this._checkInterval = options.checkInterval;
|
|
313
337
|
}
|
|
338
|
+
if (options?.storeHashAlgorithm) {
|
|
339
|
+
this._storeHashAlgorithm = options.storeHashAlgorithm;
|
|
340
|
+
}
|
|
341
|
+
this._store = Array.from({ length: this._storeHashSize }, () => /* @__PURE__ */ new Map());
|
|
314
342
|
this.startIntervalCheck();
|
|
315
343
|
}
|
|
316
344
|
/**
|
|
@@ -343,17 +371,25 @@ var CacheableMemory = class extends Hookified {
|
|
|
343
371
|
}
|
|
344
372
|
/**
|
|
345
373
|
* Gets the size of the LRU cache
|
|
346
|
-
* @returns {number} - The size of the LRU cache. If set to 0, it will not use LRU cache. Default is 0.
|
|
374
|
+
* @returns {number} - The size of the LRU cache. If set to 0, it will not use LRU cache. Default is 0. If you are using LRU then the limit is based on Map() size 17mm.
|
|
347
375
|
*/
|
|
348
376
|
get lruSize() {
|
|
349
377
|
return this._lruSize;
|
|
350
378
|
}
|
|
351
379
|
/**
|
|
352
380
|
* Sets the size of the LRU cache
|
|
353
|
-
* @param {number} value - The size of the LRU cache. If set to 0, it will not use LRU cache. Default is 0.
|
|
381
|
+
* @param {number} value - The size of the LRU cache. If set to 0, it will not use LRU cache. Default is 0. If you are using LRU then the limit is based on Map() size 17mm.
|
|
354
382
|
*/
|
|
355
383
|
set lruSize(value) {
|
|
384
|
+
if (value > maximumMapSize) {
|
|
385
|
+
this.emit("error", new Error(`LRU size cannot be larger than ${maximumMapSize} due to Map limitations.`));
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
356
388
|
this._lruSize = value;
|
|
389
|
+
if (this._lruSize === 0) {
|
|
390
|
+
this._lru = new DoublyLinkedList();
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
357
393
|
this.lruResize();
|
|
358
394
|
}
|
|
359
395
|
/**
|
|
@@ -375,21 +411,85 @@ var CacheableMemory = class extends Hookified {
|
|
|
375
411
|
* @returns {number} - The size of the cache
|
|
376
412
|
*/
|
|
377
413
|
get size() {
|
|
378
|
-
|
|
414
|
+
let size = 0;
|
|
415
|
+
for (const store of this._store) {
|
|
416
|
+
size += store.size;
|
|
417
|
+
}
|
|
418
|
+
return size;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Gets the number of hash stores
|
|
422
|
+
* @returns {number} - The number of hash stores
|
|
423
|
+
*/
|
|
424
|
+
get storeHashSize() {
|
|
425
|
+
return this._storeHashSize;
|
|
426
|
+
}
|
|
427
|
+
/**
|
|
428
|
+
* Sets the number of hash stores. This will recreate the store and all data will be cleared
|
|
429
|
+
* @param {number} value - The number of hash stores
|
|
430
|
+
*/
|
|
431
|
+
set storeHashSize(value) {
|
|
432
|
+
if (value === this._storeHashSize) {
|
|
433
|
+
return;
|
|
434
|
+
}
|
|
435
|
+
this._storeHashSize = value;
|
|
436
|
+
this._store = Array.from({ length: this._storeHashSize }, () => /* @__PURE__ */ new Map());
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Gets the store hash algorithm
|
|
440
|
+
* @returns {StoreHashAlgorithm | StoreHashAlgorithmFunction} - The store hash algorithm
|
|
441
|
+
*/
|
|
442
|
+
get storeHashAlgorithm() {
|
|
443
|
+
return this._storeHashAlgorithm;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Sets the store hash algorithm. This will recreate the store and all data will be cleared
|
|
447
|
+
* @param {StoreHashAlgorithm | StoreHashAlgorithmFunction} value - The store hash algorithm
|
|
448
|
+
*/
|
|
449
|
+
set storeHashAlgorithm(value) {
|
|
450
|
+
this._storeHashAlgorithm = value;
|
|
379
451
|
}
|
|
380
452
|
/**
|
|
381
453
|
* Gets the keys
|
|
382
454
|
* @returns {IterableIterator<string>} - The keys
|
|
383
455
|
*/
|
|
384
456
|
get keys() {
|
|
385
|
-
|
|
457
|
+
const keys = new Array();
|
|
458
|
+
for (const store of this._store) {
|
|
459
|
+
for (const key of store.keys()) {
|
|
460
|
+
const item = store.get(key);
|
|
461
|
+
if (item && this.hasExpired(item)) {
|
|
462
|
+
store.delete(key);
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
465
|
+
keys.push(key);
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
return keys.values();
|
|
386
469
|
}
|
|
387
470
|
/**
|
|
388
471
|
* Gets the items
|
|
389
472
|
* @returns {IterableIterator<CacheableStoreItem>} - The items
|
|
390
473
|
*/
|
|
391
474
|
get items() {
|
|
392
|
-
|
|
475
|
+
const items = new Array();
|
|
476
|
+
for (const store of this._store) {
|
|
477
|
+
for (const item of store.values()) {
|
|
478
|
+
if (this.hasExpired(item)) {
|
|
479
|
+
store.delete(item.key);
|
|
480
|
+
continue;
|
|
481
|
+
}
|
|
482
|
+
items.push(item);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return items.values();
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Gets the store
|
|
489
|
+
* @returns {Array<Map<string, CacheableStoreItem>>} - The store
|
|
490
|
+
*/
|
|
491
|
+
get store() {
|
|
492
|
+
return this._store;
|
|
393
493
|
}
|
|
394
494
|
/**
|
|
395
495
|
* Gets the value of the key
|
|
@@ -402,7 +502,7 @@ var CacheableMemory = class extends Hookified {
|
|
|
402
502
|
if (!item) {
|
|
403
503
|
return void 0;
|
|
404
504
|
}
|
|
405
|
-
if (item.expires &&
|
|
505
|
+
if (item.expires && Date.now() > item.expires) {
|
|
406
506
|
store.delete(key);
|
|
407
507
|
return void 0;
|
|
408
508
|
}
|
|
@@ -569,7 +669,6 @@ var CacheableMemory = class extends Hookified {
|
|
|
569
669
|
delete(key) {
|
|
570
670
|
const store = this.getStore(key);
|
|
571
671
|
store.delete(key);
|
|
572
|
-
this._hashCache.delete(key);
|
|
573
672
|
}
|
|
574
673
|
/**
|
|
575
674
|
* Delete the keys
|
|
@@ -586,17 +685,7 @@ var CacheableMemory = class extends Hookified {
|
|
|
586
685
|
* @returns {void}
|
|
587
686
|
*/
|
|
588
687
|
clear() {
|
|
589
|
-
this.
|
|
590
|
-
this._hash1.clear();
|
|
591
|
-
this._hash2.clear();
|
|
592
|
-
this._hash3.clear();
|
|
593
|
-
this._hash4.clear();
|
|
594
|
-
this._hash5.clear();
|
|
595
|
-
this._hash6.clear();
|
|
596
|
-
this._hash7.clear();
|
|
597
|
-
this._hash8.clear();
|
|
598
|
-
this._hash9.clear();
|
|
599
|
-
this._hashCache.clear();
|
|
688
|
+
this._store = Array.from({ length: this._storeHashSize }, () => /* @__PURE__ */ new Map());
|
|
600
689
|
this._lru = new DoublyLinkedList();
|
|
601
690
|
}
|
|
602
691
|
/**
|
|
@@ -605,66 +694,27 @@ var CacheableMemory = class extends Hookified {
|
|
|
605
694
|
* @returns {CacheableHashStore} - The store
|
|
606
695
|
*/
|
|
607
696
|
getStore(key) {
|
|
608
|
-
const hash2 = this.
|
|
609
|
-
|
|
697
|
+
const hash2 = this.getKeyStoreHash(key);
|
|
698
|
+
this._store[hash2] ||= /* @__PURE__ */ new Map();
|
|
699
|
+
return this._store[hash2];
|
|
610
700
|
}
|
|
611
701
|
/**
|
|
612
|
-
*
|
|
613
|
-
* @param {
|
|
614
|
-
*
|
|
702
|
+
* Hash the key for which store to go to (internal use)
|
|
703
|
+
* @param {string} key - The key to hash
|
|
704
|
+
* Available algorithms are: SHA256, SHA1, MD5, and djb2Hash.
|
|
705
|
+
* @returns {number} - The hashed key as a number
|
|
615
706
|
*/
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
return this._hash1;
|
|
620
|
-
}
|
|
621
|
-
case 2: {
|
|
622
|
-
return this._hash2;
|
|
623
|
-
}
|
|
624
|
-
case 3: {
|
|
625
|
-
return this._hash3;
|
|
626
|
-
}
|
|
627
|
-
case 4: {
|
|
628
|
-
return this._hash4;
|
|
629
|
-
}
|
|
630
|
-
case 5: {
|
|
631
|
-
return this._hash5;
|
|
632
|
-
}
|
|
633
|
-
case 6: {
|
|
634
|
-
return this._hash6;
|
|
635
|
-
}
|
|
636
|
-
case 7: {
|
|
637
|
-
return this._hash7;
|
|
638
|
-
}
|
|
639
|
-
case 8: {
|
|
640
|
-
return this._hash8;
|
|
641
|
-
}
|
|
642
|
-
case 9: {
|
|
643
|
-
return this._hash9;
|
|
644
|
-
}
|
|
645
|
-
default: {
|
|
646
|
-
return this._hash0;
|
|
647
|
-
}
|
|
707
|
+
getKeyStoreHash(key) {
|
|
708
|
+
if (this._store.length === 1) {
|
|
709
|
+
return 0;
|
|
648
710
|
}
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
* Hash the key (internal use)
|
|
652
|
-
* @param key
|
|
653
|
-
* @returns {number} from 0 to 9
|
|
654
|
-
*/
|
|
655
|
-
hashKey(key) {
|
|
656
|
-
const cacheHashNumber = this._hashCache.get(key);
|
|
657
|
-
if (typeof cacheHashNumber === "number") {
|
|
658
|
-
return cacheHashNumber;
|
|
711
|
+
if (this._storeHashAlgorithm === "djb2Hash" /* djb2Hash */) {
|
|
712
|
+
return djb2Hash(key, 0, this._storeHashSize);
|
|
659
713
|
}
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
for (let i = 0; i < key.length; i++) {
|
|
663
|
-
hash2 = hash2 * primeMultiplier + key.charCodeAt(i);
|
|
714
|
+
if (typeof this._storeHashAlgorithm === "function") {
|
|
715
|
+
return this._storeHashAlgorithm(key, this._storeHashSize);
|
|
664
716
|
}
|
|
665
|
-
|
|
666
|
-
this._hashCache.set(key, result);
|
|
667
|
-
return result;
|
|
717
|
+
return hashToNumber(key, 0, this._storeHashSize, this._storeHashAlgorithm);
|
|
668
718
|
}
|
|
669
719
|
/**
|
|
670
720
|
* Clone the value. This is for internal use
|
|
@@ -700,13 +750,10 @@ var CacheableMemory = class extends Hookified {
|
|
|
700
750
|
this._lru.moveToFront(key);
|
|
701
751
|
}
|
|
702
752
|
/**
|
|
703
|
-
* Resize the LRU cache. This is for internal use
|
|
753
|
+
* Resize the LRU cache. This is for internal use.
|
|
704
754
|
* @returns {void}
|
|
705
755
|
*/
|
|
706
756
|
lruResize() {
|
|
707
|
-
if (this._lruSize === 0) {
|
|
708
|
-
return;
|
|
709
|
-
}
|
|
710
757
|
while (this._lru.size > this._lruSize) {
|
|
711
758
|
const oldestKey = this._lru.getOldest();
|
|
712
759
|
if (oldestKey) {
|
|
@@ -720,10 +767,11 @@ var CacheableMemory = class extends Hookified {
|
|
|
720
767
|
* @returns {void}
|
|
721
768
|
*/
|
|
722
769
|
checkExpiration() {
|
|
723
|
-
const
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
770
|
+
for (const store of this._store) {
|
|
771
|
+
for (const item of store.values()) {
|
|
772
|
+
if (item.expires && Date.now() > item.expires) {
|
|
773
|
+
store.delete(item.key);
|
|
774
|
+
}
|
|
727
775
|
}
|
|
728
776
|
}
|
|
729
777
|
}
|
|
@@ -752,15 +800,6 @@ var CacheableMemory = class extends Hookified {
|
|
|
752
800
|
this._interval = 0;
|
|
753
801
|
this._checkInterval = 0;
|
|
754
802
|
}
|
|
755
|
-
/**
|
|
756
|
-
* Hash the object. This is for internal use
|
|
757
|
-
* @param {any} object - The object to hash
|
|
758
|
-
* @param {string} [algorithm='sha256'] - The algorithm to hash
|
|
759
|
-
* @returns {string} - The hashed string
|
|
760
|
-
*/
|
|
761
|
-
hash(object, algorithm = "sha256") {
|
|
762
|
-
return hash(object, algorithm);
|
|
763
|
-
}
|
|
764
803
|
/**
|
|
765
804
|
* Wrap the function for caching
|
|
766
805
|
* @param {Function} function_ - The function to wrap
|
|
@@ -785,9 +824,6 @@ var CacheableMemory = class extends Hookified {
|
|
|
785
824
|
}
|
|
786
825
|
return result;
|
|
787
826
|
}
|
|
788
|
-
concatStores() {
|
|
789
|
-
return new Map([...this._hash0, ...this._hash1, ...this._hash2, ...this._hash3, ...this._hash4, ...this._hash5, ...this._hash6, ...this._hash7, ...this._hash8, ...this._hash9]);
|
|
790
|
-
}
|
|
791
827
|
setTtl(ttl) {
|
|
792
828
|
if (typeof ttl === "string" || ttl === void 0) {
|
|
793
829
|
this._ttl = ttl;
|
|
@@ -797,6 +833,12 @@ var CacheableMemory = class extends Hookified {
|
|
|
797
833
|
this._ttl = void 0;
|
|
798
834
|
}
|
|
799
835
|
}
|
|
836
|
+
hasExpired(item) {
|
|
837
|
+
if (item.expires && Date.now() > item.expires) {
|
|
838
|
+
return true;
|
|
839
|
+
}
|
|
840
|
+
return false;
|
|
841
|
+
}
|
|
800
842
|
};
|
|
801
843
|
|
|
802
844
|
// src/keyv-memory.ts
|
|
@@ -1659,6 +1701,24 @@ var Cacheable = class extends Hookified2 {
|
|
|
1659
1701
|
};
|
|
1660
1702
|
return wrap(function_, wrapOptions);
|
|
1661
1703
|
}
|
|
1704
|
+
/**
|
|
1705
|
+
* Retrieves the value associated with the given key from the cache. If the key is not found,
|
|
1706
|
+
* invokes the provided function to calculate the value, stores it in the cache, and then returns it.
|
|
1707
|
+
*
|
|
1708
|
+
* @param {string} key - The key to retrieve or set in the cache.
|
|
1709
|
+
* @param {() => Promise<T>} function_ - The asynchronous function that computes the value to be cached if the key does not exist.
|
|
1710
|
+
* @param {WrapFunctionOptions} [options] - Optional settings for caching, such as the time to live (TTL) or whether to cache errors.
|
|
1711
|
+
* @return {Promise<T | undefined>} - A promise that resolves to the cached or newly computed value, or undefined if an error occurs and caching is not configured for errors.
|
|
1712
|
+
*/
|
|
1713
|
+
async getOrSet(key, function_, options) {
|
|
1714
|
+
const getOrSetOptions = {
|
|
1715
|
+
cache: this,
|
|
1716
|
+
cacheId: this._cacheId,
|
|
1717
|
+
ttl: options?.ttl ?? this._ttl,
|
|
1718
|
+
cacheErrors: options?.cacheErrors
|
|
1719
|
+
};
|
|
1720
|
+
return getOrSet(key, function_, getOrSetOptions);
|
|
1721
|
+
}
|
|
1662
1722
|
/**
|
|
1663
1723
|
* Will hash an object using the specified algorithm. The default algorithm is 'sha256'.
|
|
1664
1724
|
* @param {any} object the object to hash
|