keyv 5.3.4 → 5.5.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 +60 -11
- package/dist/index.cjs +148 -11
- package/dist/index.d.cts +69 -9
- package/dist/index.d.ts +69 -9
- package/dist/index.js +148 -11
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -49,18 +49,12 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
|
|
|
49
49
|
- [.setMany(entries)](#setmanyentries)
|
|
50
50
|
- [.get(key, [options])](#getkey-options)
|
|
51
51
|
- [.getMany(keys, [options])](#getmanykeys-options)
|
|
52
|
+
- [.getRaw(key)](#getrawkey)
|
|
53
|
+
- [.getManyRaw(keys)](#getmanyrawkeys)
|
|
52
54
|
- [.delete(key)](#deletekey)
|
|
53
55
|
- [.deleteMany(keys)](#deletemanykeys)
|
|
54
56
|
- [.clear()](#clear)
|
|
55
57
|
- [.iterator()](#iterator)
|
|
56
|
-
- [API - Properties](#api---properties)
|
|
57
|
-
- [.namespace](#namespace-1)
|
|
58
|
-
- [.ttl](#ttl-1)
|
|
59
|
-
- [.store](#store-1)
|
|
60
|
-
- [.serialize](#serialize-1)
|
|
61
|
-
- [.deserialize](#deserialize-1)
|
|
62
|
-
- [.compression](#compression-1)
|
|
63
|
-
- [.useKeyPrefix](#usekeyprefix-1)
|
|
64
58
|
- [How to Contribute](#how-to-contribute)
|
|
65
59
|
- [License](#license)
|
|
66
60
|
|
|
@@ -83,6 +77,7 @@ npm install --save @keyv/postgres
|
|
|
83
77
|
npm install --save @keyv/mysql
|
|
84
78
|
npm install --save @keyv/etcd
|
|
85
79
|
npm install --save @keyv/memcache
|
|
80
|
+
npm install --save @keyv/dynamo
|
|
86
81
|
```
|
|
87
82
|
|
|
88
83
|
First, create a new Keyv instance.
|
|
@@ -233,7 +228,7 @@ keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data) => console.log(`Setting key ${da
|
|
|
233
228
|
|
|
234
229
|
//POST_SET hook
|
|
235
230
|
const keyv = new Keyv();
|
|
236
|
-
keyv.hooks.addHandler(KeyvHooks.POST_SET, (key, value) => console.log(`Set key ${key} to ${value}`));
|
|
231
|
+
keyv.hooks.addHandler(KeyvHooks.POST_SET, ({key, value}) => console.log(`Set key ${key} to ${value}`));
|
|
237
232
|
```
|
|
238
233
|
|
|
239
234
|
In these examples you can also manipulate the value before it is set. For example, you could add a prefix to all keys.
|
|
@@ -286,6 +281,7 @@ PostgreSQL | [@keyv/postgres](https://github.com/jaredwray/keyv/tree/master/pack
|
|
|
286
281
|
MySQL | [@keyv/mysql](https://github.com/jaredwray/keyv/tree/master/packages/mysql) | No
|
|
287
282
|
Etcd | [@keyv/etcd](https://github.com/jaredwray/keyv/tree/master/packages/etcd) | Yes
|
|
288
283
|
Memcache | [@keyv/memcache](https://github.com/jaredwray/keyv/tree/master/packages/memcache) | Yes
|
|
284
|
+
DynamoDB | [@keyv/dynamo](https://github.com/jaredwray/keyv/tree/master/packages/dynamo) | Yes
|
|
289
285
|
|
|
290
286
|
# Third-party Storage Adapters
|
|
291
287
|
|
|
@@ -318,7 +314,6 @@ The following are third-party storage adapters compatible with Keyv:
|
|
|
318
314
|
|
|
319
315
|
- [quick-lru](https://github.com/sindresorhus/quick-lru) - Simple "Least Recently Used" (LRU) cache
|
|
320
316
|
- [keyv-file](https://github.com/zaaack/keyv-file) - File system storage adapter for Keyv
|
|
321
|
-
- [keyv-dynamodb](https://www.npmjs.com/package/keyv-dynamodb) - DynamoDB storage adapter for Keyv
|
|
322
317
|
- [keyv-lru](https://www.npmjs.com/package/keyv-lru) - LRU storage adapter for Keyv
|
|
323
318
|
- [keyv-null](https://www.npmjs.com/package/keyv-null) - Null storage adapter for Keyv
|
|
324
319
|
- [keyv-firestore ](https://github.com/goto-bus-stop/keyv-firestore) – Firebase Cloud Firestore adapter for Keyv
|
|
@@ -476,7 +471,7 @@ Returns a promise which resolves to the retrieved value.
|
|
|
476
471
|
|
|
477
472
|
Returns a promise which resolves to an array of retrieved values.
|
|
478
473
|
|
|
479
|
-
### options.raw
|
|
474
|
+
### options.raw - (Will be deprecated in v6)
|
|
480
475
|
|
|
481
476
|
Type: `Boolean`<br />
|
|
482
477
|
Default: `false`
|
|
@@ -485,6 +480,16 @@ If set to true the raw DB object Keyv stores internally will be returned instead
|
|
|
485
480
|
|
|
486
481
|
This contains the TTL timestamp.
|
|
487
482
|
|
|
483
|
+
NOTE: This option will be deprecated in v6 and replaced with `.getRaw()` and `.getManyRaw()` methods.
|
|
484
|
+
|
|
485
|
+
## .getRaw(key)
|
|
486
|
+
|
|
487
|
+
Returns a promise which resolves to the raw stored data for the key or `undefined` if the key does not exist or is expired.
|
|
488
|
+
|
|
489
|
+
## .getManyRaw(keys)
|
|
490
|
+
|
|
491
|
+
Returns a promise which resolves to an array of raw stored data for the keys or `undefined` if the key does not exist or is expired.
|
|
492
|
+
|
|
488
493
|
## .delete(key)
|
|
489
494
|
|
|
490
495
|
Deletes an entry.
|
|
@@ -623,6 +628,50 @@ keyv.useKeyPrefix = true;
|
|
|
623
628
|
console.log(keyv.useKeyPrefix); // true
|
|
624
629
|
```
|
|
625
630
|
|
|
631
|
+
With many of the storage adapters you will also need to set the `namespace` option to `undefined` to have it work correctly. This is because in `v5` we started the transition to having the storage adapter handle the namespacing and `Keyv` will no longer handle it internally via KeyPrefixing. Here is an example of doing ith with `KeyvSqlite`:
|
|
632
|
+
|
|
633
|
+
```js
|
|
634
|
+
import Keyv from 'keyv';
|
|
635
|
+
import KeyvSqlite from '@keyv/sqlite';
|
|
636
|
+
|
|
637
|
+
const store = new KeyvSqlite('sqlite://path/to/database.sqlite');
|
|
638
|
+
const keyv = new Keyv({ store });
|
|
639
|
+
keyv.useKeyPrefix = false; // disable key prefixing
|
|
640
|
+
store.namespace = undefined; // disable namespacing in the storage adapter
|
|
641
|
+
|
|
642
|
+
await keyv.set('foo', 'bar'); // true
|
|
643
|
+
await keyv.get('foo'); // 'bar'
|
|
644
|
+
await keyv.clear();
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
## .throwOnErrors
|
|
648
|
+
|
|
649
|
+
Type: `Boolean`<br />
|
|
650
|
+
Default: `false`
|
|
651
|
+
|
|
652
|
+
If set to `true`, Keyv will throw an error if any operation fails. This is useful if you want to ensure that all operations are successful and you want to handle errors.
|
|
653
|
+
|
|
654
|
+
```js
|
|
655
|
+
const keyv = new Keyv({ throwOnErrors: true });
|
|
656
|
+
console.log(keyv.throwOnErrors); // true
|
|
657
|
+
keyv.throwOnErrors = false;
|
|
658
|
+
console.log(keyv.throwOnErrors); // false
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
A good example of this is with the `@keyv/redis` storage adapter. If you want to handle connection errors, retries, and timeouts more gracefully, you can use the `throwOnErrors` option. This will throw an error if any operation fails, allowing you to catch it and handle it accordingly:
|
|
662
|
+
|
|
663
|
+
```js
|
|
664
|
+
import Keyv from 'keyv';
|
|
665
|
+
import KeyvRedis from '@keyv/redis';
|
|
666
|
+
|
|
667
|
+
// create redis instance that will throw on connection error
|
|
668
|
+
const keyvRedis = new KeyvRedis('redis://user:pass@localhost:6379', { throwOnConnectErrors: true });
|
|
669
|
+
|
|
670
|
+
const keyv = new Keyv({ store: keyvRedis, throwOnErrors: true });
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
What this does is it only throw on connection errors with the Redis client.
|
|
674
|
+
|
|
626
675
|
# How to Contribute
|
|
627
676
|
|
|
628
677
|
We welcome contributions to Keyv! 🎉 Here are some guides to get you started with contributing:
|
package/dist/index.cjs
CHANGED
|
@@ -185,6 +185,15 @@ var StatsManager = class extends event_manager_default {
|
|
|
185
185
|
this.deletes++;
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
+
hitsOrMisses(array) {
|
|
189
|
+
for (const item of array) {
|
|
190
|
+
if (item === void 0) {
|
|
191
|
+
this.miss();
|
|
192
|
+
} else {
|
|
193
|
+
this.hit();
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
188
197
|
reset() {
|
|
189
198
|
this.hits = 0;
|
|
190
199
|
this.misses = 0;
|
|
@@ -203,6 +212,10 @@ var KeyvHooks = /* @__PURE__ */ ((KeyvHooks2) => {
|
|
|
203
212
|
KeyvHooks2["POST_GET"] = "postGet";
|
|
204
213
|
KeyvHooks2["PRE_GET_MANY"] = "preGetMany";
|
|
205
214
|
KeyvHooks2["POST_GET_MANY"] = "postGetMany";
|
|
215
|
+
KeyvHooks2["PRE_GET_RAW"] = "preGetRaw";
|
|
216
|
+
KeyvHooks2["POST_GET_RAW"] = "postGetRaw";
|
|
217
|
+
KeyvHooks2["PRE_GET_MANY_RAW"] = "preGetManyRaw";
|
|
218
|
+
KeyvHooks2["POST_GET_MANY_RAW"] = "postGetManyRaw";
|
|
206
219
|
KeyvHooks2["PRE_DELETE"] = "preDelete";
|
|
207
220
|
KeyvHooks2["POST_DELETE"] = "postDelete";
|
|
208
221
|
return KeyvHooks2;
|
|
@@ -237,6 +250,7 @@ var Keyv = class extends event_manager_default {
|
|
|
237
250
|
_deserialize = import_serialize.defaultDeserialize;
|
|
238
251
|
_compression;
|
|
239
252
|
_useKeyPrefix = true;
|
|
253
|
+
_throwOnErrors = false;
|
|
240
254
|
/**
|
|
241
255
|
* Keyv Constructor
|
|
242
256
|
* @param {KeyvStoreAdapter | KeyvOptions} store
|
|
@@ -293,6 +307,9 @@ var Keyv = class extends event_manager_default {
|
|
|
293
307
|
if (this.opts.useKeyPrefix !== void 0) {
|
|
294
308
|
this._useKeyPrefix = this.opts.useKeyPrefix;
|
|
295
309
|
}
|
|
310
|
+
if (this.opts.throwOnErrors !== void 0) {
|
|
311
|
+
this._throwOnErrors = this.opts.throwOnErrors;
|
|
312
|
+
}
|
|
296
313
|
}
|
|
297
314
|
/**
|
|
298
315
|
* Get the current store
|
|
@@ -417,6 +434,21 @@ var Keyv = class extends event_manager_default {
|
|
|
417
434
|
this._useKeyPrefix = value;
|
|
418
435
|
this.opts.useKeyPrefix = value;
|
|
419
436
|
}
|
|
437
|
+
/**
|
|
438
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
439
|
+
* @return {boolean} The current throwOnErrors value.
|
|
440
|
+
*/
|
|
441
|
+
get throwOnErrors() {
|
|
442
|
+
return this._throwOnErrors;
|
|
443
|
+
}
|
|
444
|
+
/**
|
|
445
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
446
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
447
|
+
*/
|
|
448
|
+
set throwOnErrors(value) {
|
|
449
|
+
this._throwOnErrors = value;
|
|
450
|
+
this.opts.throwOnErrors = value;
|
|
451
|
+
}
|
|
420
452
|
generateIterator(iterator) {
|
|
421
453
|
const function_ = async function* () {
|
|
422
454
|
for await (const [key, raw] of typeof iterator === "function" ? iterator(this._store.namespace) : iterator) {
|
|
@@ -476,7 +508,14 @@ var Keyv = class extends event_manager_default {
|
|
|
476
508
|
return this.getMany(key, { raw: false });
|
|
477
509
|
}
|
|
478
510
|
this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });
|
|
479
|
-
|
|
511
|
+
let rawData;
|
|
512
|
+
try {
|
|
513
|
+
rawData = await store.get(keyPrefixed);
|
|
514
|
+
} catch (error) {
|
|
515
|
+
if (this.throwOnErrors) {
|
|
516
|
+
throw error;
|
|
517
|
+
}
|
|
518
|
+
}
|
|
480
519
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
481
520
|
if (deserializedData === void 0 || deserializedData === null) {
|
|
482
521
|
this.stats.miss();
|
|
@@ -519,6 +558,7 @@ var Keyv = class extends event_manager_default {
|
|
|
519
558
|
}
|
|
520
559
|
const rawData = await store.getMany(keyPrefixed);
|
|
521
560
|
const result = [];
|
|
561
|
+
const expiredKeys = [];
|
|
522
562
|
for (const index in rawData) {
|
|
523
563
|
let row = rawData[index];
|
|
524
564
|
if (typeof row === "string") {
|
|
@@ -529,19 +569,96 @@ var Keyv = class extends event_manager_default {
|
|
|
529
569
|
continue;
|
|
530
570
|
}
|
|
531
571
|
if (isDataExpired(row)) {
|
|
532
|
-
|
|
572
|
+
expiredKeys.push(keys[index]);
|
|
533
573
|
result.push(void 0);
|
|
534
574
|
continue;
|
|
535
575
|
}
|
|
536
576
|
const value = options?.raw ? row : row.value;
|
|
537
577
|
result.push(value);
|
|
538
578
|
}
|
|
579
|
+
if (expiredKeys.length > 0) {
|
|
580
|
+
await this.deleteMany(expiredKeys);
|
|
581
|
+
}
|
|
539
582
|
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
|
|
540
583
|
if (result.length > 0) {
|
|
541
584
|
this.stats.hit();
|
|
542
585
|
}
|
|
543
586
|
return result;
|
|
544
587
|
}
|
|
588
|
+
/**
|
|
589
|
+
* Get the raw value of a key. This is the replacement for setting raw to true in the get() method.
|
|
590
|
+
* @param {string} key the key to get
|
|
591
|
+
* @returns {Promise<StoredDataRaw<Value> | undefined>} will return a StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
592
|
+
*/
|
|
593
|
+
async getRaw(key) {
|
|
594
|
+
const { store } = this.opts;
|
|
595
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
596
|
+
this.hooks.trigger("preGetRaw" /* PRE_GET_RAW */, { key: keyPrefixed });
|
|
597
|
+
const rawData = await store.get(keyPrefixed);
|
|
598
|
+
if (rawData === void 0 || rawData === null) {
|
|
599
|
+
this.stats.miss();
|
|
600
|
+
return void 0;
|
|
601
|
+
}
|
|
602
|
+
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
603
|
+
if (deserializedData !== void 0 && deserializedData.expires !== void 0 && deserializedData.expires !== null && deserializedData.expires < Date.now()) {
|
|
604
|
+
this.stats.miss();
|
|
605
|
+
await this.delete(key);
|
|
606
|
+
return void 0;
|
|
607
|
+
}
|
|
608
|
+
this.stats.hit();
|
|
609
|
+
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, { key: keyPrefixed, value: deserializedData });
|
|
610
|
+
return deserializedData;
|
|
611
|
+
}
|
|
612
|
+
/**
|
|
613
|
+
* Get the raw values of many keys. This is the replacement for setting raw to true in the getMany() method.
|
|
614
|
+
* @param {string[]} keys the keys to get
|
|
615
|
+
* @returns {Promise<Array<StoredDataRaw<Value>>>} will return an array of StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
616
|
+
*/
|
|
617
|
+
async getManyRaw(keys) {
|
|
618
|
+
const { store } = this.opts;
|
|
619
|
+
const keyPrefixed = this._getKeyPrefixArray(keys);
|
|
620
|
+
if (keys.length === 0) {
|
|
621
|
+
const result2 = Array.from({ length: keys.length }).fill(void 0);
|
|
622
|
+
this.stats.misses += keys.length;
|
|
623
|
+
this.hooks.trigger("postGetManyRaw" /* POST_GET_MANY_RAW */, { keys: keyPrefixed, values: result2 });
|
|
624
|
+
return result2;
|
|
625
|
+
}
|
|
626
|
+
let result = [];
|
|
627
|
+
if (store.getMany === void 0) {
|
|
628
|
+
const promises = keyPrefixed.map(async (key) => {
|
|
629
|
+
const rawData = await store.get(key);
|
|
630
|
+
if (rawData !== void 0 && rawData !== null) {
|
|
631
|
+
return this.deserializeData(rawData);
|
|
632
|
+
}
|
|
633
|
+
return void 0;
|
|
634
|
+
});
|
|
635
|
+
const deserializedRows = await Promise.allSettled(promises);
|
|
636
|
+
result = deserializedRows.map((row) => row.value);
|
|
637
|
+
} else {
|
|
638
|
+
const rawData = await store.getMany(keyPrefixed);
|
|
639
|
+
for (const row of rawData) {
|
|
640
|
+
if (row !== void 0 && row !== null) {
|
|
641
|
+
result.push(await this.deserializeData(row));
|
|
642
|
+
} else {
|
|
643
|
+
result.push(void 0);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
const expiredKeys = [];
|
|
648
|
+
const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
|
|
649
|
+
for (const [index, row] of result.entries()) {
|
|
650
|
+
if (row !== void 0 && isDataExpired(row)) {
|
|
651
|
+
expiredKeys.push(keyPrefixed[index]);
|
|
652
|
+
result[index] = void 0;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
if (expiredKeys.length > 0) {
|
|
656
|
+
await this.deleteMany(expiredKeys);
|
|
657
|
+
}
|
|
658
|
+
this.stats.hitsOrMisses(result);
|
|
659
|
+
this.hooks.trigger("postGetManyRaw" /* POST_GET_MANY_RAW */, { keys: keyPrefixed, values: result });
|
|
660
|
+
return result;
|
|
661
|
+
}
|
|
545
662
|
/**
|
|
546
663
|
* Set an item to the store
|
|
547
664
|
* @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
|
|
@@ -574,6 +691,9 @@ var Keyv = class extends event_manager_default {
|
|
|
574
691
|
} catch (error) {
|
|
575
692
|
result = false;
|
|
576
693
|
this.emit("error", error);
|
|
694
|
+
if (this._throwOnErrors) {
|
|
695
|
+
throw error;
|
|
696
|
+
}
|
|
577
697
|
}
|
|
578
698
|
this.hooks.trigger("postSet" /* POST_SET */, { key: keyPrefixed, value: serializedValue, ttl });
|
|
579
699
|
this.stats.set();
|
|
@@ -587,7 +707,14 @@ var Keyv = class extends event_manager_default {
|
|
|
587
707
|
async setMany(entries) {
|
|
588
708
|
let results = [];
|
|
589
709
|
try {
|
|
590
|
-
if (this._store.setMany
|
|
710
|
+
if (this._store.setMany === void 0) {
|
|
711
|
+
const promises = [];
|
|
712
|
+
for (const entry of entries) {
|
|
713
|
+
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
714
|
+
}
|
|
715
|
+
const promiseResults = await Promise.all(promises);
|
|
716
|
+
results = promiseResults;
|
|
717
|
+
} else {
|
|
591
718
|
const serializedEntries = await Promise.all(entries.map(async ({ key, value, ttl }) => {
|
|
592
719
|
ttl ??= this._ttl;
|
|
593
720
|
if (ttl === 0) {
|
|
@@ -604,14 +731,11 @@ var Keyv = class extends event_manager_default {
|
|
|
604
731
|
}));
|
|
605
732
|
results = await this._store.setMany(serializedEntries);
|
|
606
733
|
}
|
|
607
|
-
const promises = [];
|
|
608
|
-
for (const entry of entries) {
|
|
609
|
-
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
610
|
-
}
|
|
611
|
-
const promiseResults = await Promise.allSettled(promises);
|
|
612
|
-
results = promiseResults.map((result) => result.value);
|
|
613
734
|
} catch (error) {
|
|
614
735
|
this.emit("error", error);
|
|
736
|
+
if (this._throwOnErrors) {
|
|
737
|
+
throw error;
|
|
738
|
+
}
|
|
615
739
|
results = entries.map(() => false);
|
|
616
740
|
}
|
|
617
741
|
return results;
|
|
@@ -637,6 +761,9 @@ var Keyv = class extends event_manager_default {
|
|
|
637
761
|
} catch (error) {
|
|
638
762
|
result = false;
|
|
639
763
|
this.emit("error", error);
|
|
764
|
+
if (this._throwOnErrors) {
|
|
765
|
+
throw error;
|
|
766
|
+
}
|
|
640
767
|
}
|
|
641
768
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: result });
|
|
642
769
|
this.stats.delete();
|
|
@@ -656,12 +783,15 @@ var Keyv = class extends event_manager_default {
|
|
|
656
783
|
return await store.deleteMany(keyPrefixed);
|
|
657
784
|
}
|
|
658
785
|
const promises = keyPrefixed.map(async (key) => store.delete(key));
|
|
659
|
-
const results = await Promise.
|
|
660
|
-
const returnResult = results.every(
|
|
786
|
+
const results = await Promise.all(promises);
|
|
787
|
+
const returnResult = results.every(Boolean);
|
|
661
788
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: returnResult });
|
|
662
789
|
return returnResult;
|
|
663
790
|
} catch (error) {
|
|
664
791
|
this.emit("error", error);
|
|
792
|
+
if (this._throwOnErrors) {
|
|
793
|
+
throw error;
|
|
794
|
+
}
|
|
665
795
|
return false;
|
|
666
796
|
}
|
|
667
797
|
}
|
|
@@ -676,6 +806,9 @@ var Keyv = class extends event_manager_default {
|
|
|
676
806
|
await store.clear();
|
|
677
807
|
} catch (error) {
|
|
678
808
|
this.emit("error", error);
|
|
809
|
+
if (this._throwOnErrors) {
|
|
810
|
+
throw error;
|
|
811
|
+
}
|
|
679
812
|
}
|
|
680
813
|
}
|
|
681
814
|
async has(key) {
|
|
@@ -692,6 +825,10 @@ var Keyv = class extends event_manager_default {
|
|
|
692
825
|
rawData = await store.get(keyPrefixed);
|
|
693
826
|
} catch (error) {
|
|
694
827
|
this.emit("error", error);
|
|
828
|
+
if (this._throwOnErrors) {
|
|
829
|
+
throw error;
|
|
830
|
+
}
|
|
831
|
+
return false;
|
|
695
832
|
}
|
|
696
833
|
if (rawData) {
|
|
697
834
|
const data = await this.deserializeData(rawData);
|
package/dist/index.d.cts
CHANGED
|
@@ -37,6 +37,7 @@ declare class StatsManager extends EventManager {
|
|
|
37
37
|
miss(): void;
|
|
38
38
|
set(): void;
|
|
39
39
|
delete(): void;
|
|
40
|
+
hitsOrMisses<T>(array: Array<T | undefined>): void;
|
|
40
41
|
reset(): void;
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -59,6 +60,10 @@ declare enum KeyvHooks {
|
|
|
59
60
|
POST_GET = "postGet",
|
|
60
61
|
PRE_GET_MANY = "preGetMany",
|
|
61
62
|
POST_GET_MANY = "postGetMany",
|
|
63
|
+
PRE_GET_RAW = "preGetRaw",
|
|
64
|
+
POST_GET_RAW = "postGetRaw",
|
|
65
|
+
PRE_GET_MANY_RAW = "preGetManyRaw",
|
|
66
|
+
POST_GET_MANY_RAW = "postGetManyRaw",
|
|
62
67
|
PRE_DELETE = "preDelete",
|
|
63
68
|
POST_DELETE = "postDelete"
|
|
64
69
|
}
|
|
@@ -102,24 +107,56 @@ type KeyvStoreAdapter = {
|
|
|
102
107
|
iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
|
|
103
108
|
} & IEventEmitter;
|
|
104
109
|
type KeyvOptions = {
|
|
105
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Emit errors
|
|
112
|
+
* @default true
|
|
113
|
+
*/
|
|
106
114
|
emitErrors?: boolean;
|
|
107
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Namespace for the current instance.
|
|
117
|
+
* @default 'keyv'
|
|
118
|
+
*/
|
|
108
119
|
namespace?: string;
|
|
109
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* A custom serialization function.
|
|
122
|
+
* @default defaultSerialize using JSON.stringify
|
|
123
|
+
*/
|
|
110
124
|
serialize?: Serialize;
|
|
111
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* A custom deserialization function.
|
|
127
|
+
* @default defaultDeserialize using JSON.parse
|
|
128
|
+
*/
|
|
112
129
|
deserialize?: Deserialize;
|
|
113
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* The storage adapter instance to be used by Keyv.
|
|
132
|
+
* @default new Map() - in-memory store
|
|
133
|
+
*/
|
|
114
134
|
store?: KeyvStoreAdapter | Map<any, any> | any;
|
|
115
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Default TTL. Can be overridden by specifying a TTL on `.set()`.
|
|
137
|
+
* @default undefined
|
|
138
|
+
*/
|
|
116
139
|
ttl?: number;
|
|
117
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Enable compression option
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
118
144
|
compression?: CompressionAdapter | any;
|
|
119
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* Enable or disable statistics (default is false)
|
|
147
|
+
* @default false
|
|
148
|
+
*/
|
|
120
149
|
stats?: boolean;
|
|
121
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Enable or disable key prefixing (default is true)
|
|
152
|
+
* @default true
|
|
153
|
+
*/
|
|
122
154
|
useKeyPrefix?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Will enable throwing errors on methods in addition to emitting them.
|
|
157
|
+
* @default false
|
|
158
|
+
*/
|
|
159
|
+
throwOnErrors?: boolean;
|
|
123
160
|
};
|
|
124
161
|
type KeyvOptions_ = Omit<KeyvOptions, 'store'> & {
|
|
125
162
|
store: KeyvStoreAdapter | Map<any, any> & KeyvStoreAdapter;
|
|
@@ -146,6 +183,7 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
146
183
|
private _deserialize;
|
|
147
184
|
private _compression;
|
|
148
185
|
private _useKeyPrefix;
|
|
186
|
+
private _throwOnErrors;
|
|
149
187
|
/**
|
|
150
188
|
* Keyv Constructor
|
|
151
189
|
* @param {KeyvStoreAdapter | KeyvOptions | Map<any, any>} store to be provided or just the options
|
|
@@ -227,6 +265,16 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
227
265
|
* @param {boolean} value The useKeyPrefix value to set.
|
|
228
266
|
*/
|
|
229
267
|
set useKeyPrefix(value: boolean);
|
|
268
|
+
/**
|
|
269
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
270
|
+
* @return {boolean} The current throwOnErrors value.
|
|
271
|
+
*/
|
|
272
|
+
get throwOnErrors(): boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
275
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
276
|
+
*/
|
|
277
|
+
set throwOnErrors(value: boolean);
|
|
230
278
|
generateIterator(iterator: IteratorFunction): IteratorFunction;
|
|
231
279
|
_checkIterableAdapter(): boolean;
|
|
232
280
|
_getKeyPrefix(key: string): string;
|
|
@@ -261,6 +309,18 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
261
309
|
getMany<Value = GenericValue>(keys: string[], options?: {
|
|
262
310
|
raw: true;
|
|
263
311
|
}): Promise<Array<StoredDataRaw<Value>>>;
|
|
312
|
+
/**
|
|
313
|
+
* Get the raw value of a key. This is the replacement for setting raw to true in the get() method.
|
|
314
|
+
* @param {string} key the key to get
|
|
315
|
+
* @returns {Promise<StoredDataRaw<Value> | undefined>} will return a StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
316
|
+
*/
|
|
317
|
+
getRaw<Value = GenericValue>(key: string): Promise<StoredDataRaw<Value> | undefined>;
|
|
318
|
+
/**
|
|
319
|
+
* Get the raw values of many keys. This is the replacement for setting raw to true in the getMany() method.
|
|
320
|
+
* @param {string[]} keys the keys to get
|
|
321
|
+
* @returns {Promise<Array<StoredDataRaw<Value>>>} will return an array of StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
322
|
+
*/
|
|
323
|
+
getManyRaw<Value = GenericValue>(keys: string[]): Promise<Array<StoredDataRaw<Value>>>;
|
|
264
324
|
/**
|
|
265
325
|
* Set an item to the store
|
|
266
326
|
* @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
|
package/dist/index.d.ts
CHANGED
|
@@ -37,6 +37,7 @@ declare class StatsManager extends EventManager {
|
|
|
37
37
|
miss(): void;
|
|
38
38
|
set(): void;
|
|
39
39
|
delete(): void;
|
|
40
|
+
hitsOrMisses<T>(array: Array<T | undefined>): void;
|
|
40
41
|
reset(): void;
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -59,6 +60,10 @@ declare enum KeyvHooks {
|
|
|
59
60
|
POST_GET = "postGet",
|
|
60
61
|
PRE_GET_MANY = "preGetMany",
|
|
61
62
|
POST_GET_MANY = "postGetMany",
|
|
63
|
+
PRE_GET_RAW = "preGetRaw",
|
|
64
|
+
POST_GET_RAW = "postGetRaw",
|
|
65
|
+
PRE_GET_MANY_RAW = "preGetManyRaw",
|
|
66
|
+
POST_GET_MANY_RAW = "postGetManyRaw",
|
|
62
67
|
PRE_DELETE = "preDelete",
|
|
63
68
|
POST_DELETE = "postDelete"
|
|
64
69
|
}
|
|
@@ -102,24 +107,56 @@ type KeyvStoreAdapter = {
|
|
|
102
107
|
iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
|
|
103
108
|
} & IEventEmitter;
|
|
104
109
|
type KeyvOptions = {
|
|
105
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Emit errors
|
|
112
|
+
* @default true
|
|
113
|
+
*/
|
|
106
114
|
emitErrors?: boolean;
|
|
107
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* Namespace for the current instance.
|
|
117
|
+
* @default 'keyv'
|
|
118
|
+
*/
|
|
108
119
|
namespace?: string;
|
|
109
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* A custom serialization function.
|
|
122
|
+
* @default defaultSerialize using JSON.stringify
|
|
123
|
+
*/
|
|
110
124
|
serialize?: Serialize;
|
|
111
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* A custom deserialization function.
|
|
127
|
+
* @default defaultDeserialize using JSON.parse
|
|
128
|
+
*/
|
|
112
129
|
deserialize?: Deserialize;
|
|
113
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* The storage adapter instance to be used by Keyv.
|
|
132
|
+
* @default new Map() - in-memory store
|
|
133
|
+
*/
|
|
114
134
|
store?: KeyvStoreAdapter | Map<any, any> | any;
|
|
115
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Default TTL. Can be overridden by specifying a TTL on `.set()`.
|
|
137
|
+
* @default undefined
|
|
138
|
+
*/
|
|
116
139
|
ttl?: number;
|
|
117
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Enable compression option
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
118
144
|
compression?: CompressionAdapter | any;
|
|
119
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* Enable or disable statistics (default is false)
|
|
147
|
+
* @default false
|
|
148
|
+
*/
|
|
120
149
|
stats?: boolean;
|
|
121
|
-
/**
|
|
150
|
+
/**
|
|
151
|
+
* Enable or disable key prefixing (default is true)
|
|
152
|
+
* @default true
|
|
153
|
+
*/
|
|
122
154
|
useKeyPrefix?: boolean;
|
|
155
|
+
/**
|
|
156
|
+
* Will enable throwing errors on methods in addition to emitting them.
|
|
157
|
+
* @default false
|
|
158
|
+
*/
|
|
159
|
+
throwOnErrors?: boolean;
|
|
123
160
|
};
|
|
124
161
|
type KeyvOptions_ = Omit<KeyvOptions, 'store'> & {
|
|
125
162
|
store: KeyvStoreAdapter | Map<any, any> & KeyvStoreAdapter;
|
|
@@ -146,6 +183,7 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
146
183
|
private _deserialize;
|
|
147
184
|
private _compression;
|
|
148
185
|
private _useKeyPrefix;
|
|
186
|
+
private _throwOnErrors;
|
|
149
187
|
/**
|
|
150
188
|
* Keyv Constructor
|
|
151
189
|
* @param {KeyvStoreAdapter | KeyvOptions | Map<any, any>} store to be provided or just the options
|
|
@@ -227,6 +265,16 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
227
265
|
* @param {boolean} value The useKeyPrefix value to set.
|
|
228
266
|
*/
|
|
229
267
|
set useKeyPrefix(value: boolean);
|
|
268
|
+
/**
|
|
269
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
270
|
+
* @return {boolean} The current throwOnErrors value.
|
|
271
|
+
*/
|
|
272
|
+
get throwOnErrors(): boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
275
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
276
|
+
*/
|
|
277
|
+
set throwOnErrors(value: boolean);
|
|
230
278
|
generateIterator(iterator: IteratorFunction): IteratorFunction;
|
|
231
279
|
_checkIterableAdapter(): boolean;
|
|
232
280
|
_getKeyPrefix(key: string): string;
|
|
@@ -261,6 +309,18 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
261
309
|
getMany<Value = GenericValue>(keys: string[], options?: {
|
|
262
310
|
raw: true;
|
|
263
311
|
}): Promise<Array<StoredDataRaw<Value>>>;
|
|
312
|
+
/**
|
|
313
|
+
* Get the raw value of a key. This is the replacement for setting raw to true in the get() method.
|
|
314
|
+
* @param {string} key the key to get
|
|
315
|
+
* @returns {Promise<StoredDataRaw<Value> | undefined>} will return a StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
316
|
+
*/
|
|
317
|
+
getRaw<Value = GenericValue>(key: string): Promise<StoredDataRaw<Value> | undefined>;
|
|
318
|
+
/**
|
|
319
|
+
* Get the raw values of many keys. This is the replacement for setting raw to true in the getMany() method.
|
|
320
|
+
* @param {string[]} keys the keys to get
|
|
321
|
+
* @returns {Promise<Array<StoredDataRaw<Value>>>} will return an array of StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
322
|
+
*/
|
|
323
|
+
getManyRaw<Value = GenericValue>(keys: string[]): Promise<Array<StoredDataRaw<Value>>>;
|
|
264
324
|
/**
|
|
265
325
|
* Set an item to the store
|
|
266
326
|
* @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
|
package/dist/index.js
CHANGED
|
@@ -159,6 +159,15 @@ var StatsManager = class extends event_manager_default {
|
|
|
159
159
|
this.deletes++;
|
|
160
160
|
}
|
|
161
161
|
}
|
|
162
|
+
hitsOrMisses(array) {
|
|
163
|
+
for (const item of array) {
|
|
164
|
+
if (item === void 0) {
|
|
165
|
+
this.miss();
|
|
166
|
+
} else {
|
|
167
|
+
this.hit();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
162
171
|
reset() {
|
|
163
172
|
this.hits = 0;
|
|
164
173
|
this.misses = 0;
|
|
@@ -177,6 +186,10 @@ var KeyvHooks = /* @__PURE__ */ ((KeyvHooks2) => {
|
|
|
177
186
|
KeyvHooks2["POST_GET"] = "postGet";
|
|
178
187
|
KeyvHooks2["PRE_GET_MANY"] = "preGetMany";
|
|
179
188
|
KeyvHooks2["POST_GET_MANY"] = "postGetMany";
|
|
189
|
+
KeyvHooks2["PRE_GET_RAW"] = "preGetRaw";
|
|
190
|
+
KeyvHooks2["POST_GET_RAW"] = "postGetRaw";
|
|
191
|
+
KeyvHooks2["PRE_GET_MANY_RAW"] = "preGetManyRaw";
|
|
192
|
+
KeyvHooks2["POST_GET_MANY_RAW"] = "postGetManyRaw";
|
|
180
193
|
KeyvHooks2["PRE_DELETE"] = "preDelete";
|
|
181
194
|
KeyvHooks2["POST_DELETE"] = "postDelete";
|
|
182
195
|
return KeyvHooks2;
|
|
@@ -211,6 +224,7 @@ var Keyv = class extends event_manager_default {
|
|
|
211
224
|
_deserialize = defaultDeserialize;
|
|
212
225
|
_compression;
|
|
213
226
|
_useKeyPrefix = true;
|
|
227
|
+
_throwOnErrors = false;
|
|
214
228
|
/**
|
|
215
229
|
* Keyv Constructor
|
|
216
230
|
* @param {KeyvStoreAdapter | KeyvOptions} store
|
|
@@ -267,6 +281,9 @@ var Keyv = class extends event_manager_default {
|
|
|
267
281
|
if (this.opts.useKeyPrefix !== void 0) {
|
|
268
282
|
this._useKeyPrefix = this.opts.useKeyPrefix;
|
|
269
283
|
}
|
|
284
|
+
if (this.opts.throwOnErrors !== void 0) {
|
|
285
|
+
this._throwOnErrors = this.opts.throwOnErrors;
|
|
286
|
+
}
|
|
270
287
|
}
|
|
271
288
|
/**
|
|
272
289
|
* Get the current store
|
|
@@ -391,6 +408,21 @@ var Keyv = class extends event_manager_default {
|
|
|
391
408
|
this._useKeyPrefix = value;
|
|
392
409
|
this.opts.useKeyPrefix = value;
|
|
393
410
|
}
|
|
411
|
+
/**
|
|
412
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
413
|
+
* @return {boolean} The current throwOnErrors value.
|
|
414
|
+
*/
|
|
415
|
+
get throwOnErrors() {
|
|
416
|
+
return this._throwOnErrors;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
420
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
421
|
+
*/
|
|
422
|
+
set throwOnErrors(value) {
|
|
423
|
+
this._throwOnErrors = value;
|
|
424
|
+
this.opts.throwOnErrors = value;
|
|
425
|
+
}
|
|
394
426
|
generateIterator(iterator) {
|
|
395
427
|
const function_ = async function* () {
|
|
396
428
|
for await (const [key, raw] of typeof iterator === "function" ? iterator(this._store.namespace) : iterator) {
|
|
@@ -450,7 +482,14 @@ var Keyv = class extends event_manager_default {
|
|
|
450
482
|
return this.getMany(key, { raw: false });
|
|
451
483
|
}
|
|
452
484
|
this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });
|
|
453
|
-
|
|
485
|
+
let rawData;
|
|
486
|
+
try {
|
|
487
|
+
rawData = await store.get(keyPrefixed);
|
|
488
|
+
} catch (error) {
|
|
489
|
+
if (this.throwOnErrors) {
|
|
490
|
+
throw error;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
454
493
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
455
494
|
if (deserializedData === void 0 || deserializedData === null) {
|
|
456
495
|
this.stats.miss();
|
|
@@ -493,6 +532,7 @@ var Keyv = class extends event_manager_default {
|
|
|
493
532
|
}
|
|
494
533
|
const rawData = await store.getMany(keyPrefixed);
|
|
495
534
|
const result = [];
|
|
535
|
+
const expiredKeys = [];
|
|
496
536
|
for (const index in rawData) {
|
|
497
537
|
let row = rawData[index];
|
|
498
538
|
if (typeof row === "string") {
|
|
@@ -503,19 +543,96 @@ var Keyv = class extends event_manager_default {
|
|
|
503
543
|
continue;
|
|
504
544
|
}
|
|
505
545
|
if (isDataExpired(row)) {
|
|
506
|
-
|
|
546
|
+
expiredKeys.push(keys[index]);
|
|
507
547
|
result.push(void 0);
|
|
508
548
|
continue;
|
|
509
549
|
}
|
|
510
550
|
const value = options?.raw ? row : row.value;
|
|
511
551
|
result.push(value);
|
|
512
552
|
}
|
|
553
|
+
if (expiredKeys.length > 0) {
|
|
554
|
+
await this.deleteMany(expiredKeys);
|
|
555
|
+
}
|
|
513
556
|
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
|
|
514
557
|
if (result.length > 0) {
|
|
515
558
|
this.stats.hit();
|
|
516
559
|
}
|
|
517
560
|
return result;
|
|
518
561
|
}
|
|
562
|
+
/**
|
|
563
|
+
* Get the raw value of a key. This is the replacement for setting raw to true in the get() method.
|
|
564
|
+
* @param {string} key the key to get
|
|
565
|
+
* @returns {Promise<StoredDataRaw<Value> | undefined>} will return a StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
566
|
+
*/
|
|
567
|
+
async getRaw(key) {
|
|
568
|
+
const { store } = this.opts;
|
|
569
|
+
const keyPrefixed = this._getKeyPrefix(key);
|
|
570
|
+
this.hooks.trigger("preGetRaw" /* PRE_GET_RAW */, { key: keyPrefixed });
|
|
571
|
+
const rawData = await store.get(keyPrefixed);
|
|
572
|
+
if (rawData === void 0 || rawData === null) {
|
|
573
|
+
this.stats.miss();
|
|
574
|
+
return void 0;
|
|
575
|
+
}
|
|
576
|
+
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
577
|
+
if (deserializedData !== void 0 && deserializedData.expires !== void 0 && deserializedData.expires !== null && deserializedData.expires < Date.now()) {
|
|
578
|
+
this.stats.miss();
|
|
579
|
+
await this.delete(key);
|
|
580
|
+
return void 0;
|
|
581
|
+
}
|
|
582
|
+
this.stats.hit();
|
|
583
|
+
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, { key: keyPrefixed, value: deserializedData });
|
|
584
|
+
return deserializedData;
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Get the raw values of many keys. This is the replacement for setting raw to true in the getMany() method.
|
|
588
|
+
* @param {string[]} keys the keys to get
|
|
589
|
+
* @returns {Promise<Array<StoredDataRaw<Value>>>} will return an array of StoredDataRaw<Value> or undefined if the key does not exist or is expired.
|
|
590
|
+
*/
|
|
591
|
+
async getManyRaw(keys) {
|
|
592
|
+
const { store } = this.opts;
|
|
593
|
+
const keyPrefixed = this._getKeyPrefixArray(keys);
|
|
594
|
+
if (keys.length === 0) {
|
|
595
|
+
const result2 = Array.from({ length: keys.length }).fill(void 0);
|
|
596
|
+
this.stats.misses += keys.length;
|
|
597
|
+
this.hooks.trigger("postGetManyRaw" /* POST_GET_MANY_RAW */, { keys: keyPrefixed, values: result2 });
|
|
598
|
+
return result2;
|
|
599
|
+
}
|
|
600
|
+
let result = [];
|
|
601
|
+
if (store.getMany === void 0) {
|
|
602
|
+
const promises = keyPrefixed.map(async (key) => {
|
|
603
|
+
const rawData = await store.get(key);
|
|
604
|
+
if (rawData !== void 0 && rawData !== null) {
|
|
605
|
+
return this.deserializeData(rawData);
|
|
606
|
+
}
|
|
607
|
+
return void 0;
|
|
608
|
+
});
|
|
609
|
+
const deserializedRows = await Promise.allSettled(promises);
|
|
610
|
+
result = deserializedRows.map((row) => row.value);
|
|
611
|
+
} else {
|
|
612
|
+
const rawData = await store.getMany(keyPrefixed);
|
|
613
|
+
for (const row of rawData) {
|
|
614
|
+
if (row !== void 0 && row !== null) {
|
|
615
|
+
result.push(await this.deserializeData(row));
|
|
616
|
+
} else {
|
|
617
|
+
result.push(void 0);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
const expiredKeys = [];
|
|
622
|
+
const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
|
|
623
|
+
for (const [index, row] of result.entries()) {
|
|
624
|
+
if (row !== void 0 && isDataExpired(row)) {
|
|
625
|
+
expiredKeys.push(keyPrefixed[index]);
|
|
626
|
+
result[index] = void 0;
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
if (expiredKeys.length > 0) {
|
|
630
|
+
await this.deleteMany(expiredKeys);
|
|
631
|
+
}
|
|
632
|
+
this.stats.hitsOrMisses(result);
|
|
633
|
+
this.hooks.trigger("postGetManyRaw" /* POST_GET_MANY_RAW */, { keys: keyPrefixed, values: result });
|
|
634
|
+
return result;
|
|
635
|
+
}
|
|
519
636
|
/**
|
|
520
637
|
* Set an item to the store
|
|
521
638
|
* @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
|
|
@@ -548,6 +665,9 @@ var Keyv = class extends event_manager_default {
|
|
|
548
665
|
} catch (error) {
|
|
549
666
|
result = false;
|
|
550
667
|
this.emit("error", error);
|
|
668
|
+
if (this._throwOnErrors) {
|
|
669
|
+
throw error;
|
|
670
|
+
}
|
|
551
671
|
}
|
|
552
672
|
this.hooks.trigger("postSet" /* POST_SET */, { key: keyPrefixed, value: serializedValue, ttl });
|
|
553
673
|
this.stats.set();
|
|
@@ -561,7 +681,14 @@ var Keyv = class extends event_manager_default {
|
|
|
561
681
|
async setMany(entries) {
|
|
562
682
|
let results = [];
|
|
563
683
|
try {
|
|
564
|
-
if (this._store.setMany
|
|
684
|
+
if (this._store.setMany === void 0) {
|
|
685
|
+
const promises = [];
|
|
686
|
+
for (const entry of entries) {
|
|
687
|
+
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
688
|
+
}
|
|
689
|
+
const promiseResults = await Promise.all(promises);
|
|
690
|
+
results = promiseResults;
|
|
691
|
+
} else {
|
|
565
692
|
const serializedEntries = await Promise.all(entries.map(async ({ key, value, ttl }) => {
|
|
566
693
|
ttl ??= this._ttl;
|
|
567
694
|
if (ttl === 0) {
|
|
@@ -578,14 +705,11 @@ var Keyv = class extends event_manager_default {
|
|
|
578
705
|
}));
|
|
579
706
|
results = await this._store.setMany(serializedEntries);
|
|
580
707
|
}
|
|
581
|
-
const promises = [];
|
|
582
|
-
for (const entry of entries) {
|
|
583
|
-
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
584
|
-
}
|
|
585
|
-
const promiseResults = await Promise.allSettled(promises);
|
|
586
|
-
results = promiseResults.map((result) => result.value);
|
|
587
708
|
} catch (error) {
|
|
588
709
|
this.emit("error", error);
|
|
710
|
+
if (this._throwOnErrors) {
|
|
711
|
+
throw error;
|
|
712
|
+
}
|
|
589
713
|
results = entries.map(() => false);
|
|
590
714
|
}
|
|
591
715
|
return results;
|
|
@@ -611,6 +735,9 @@ var Keyv = class extends event_manager_default {
|
|
|
611
735
|
} catch (error) {
|
|
612
736
|
result = false;
|
|
613
737
|
this.emit("error", error);
|
|
738
|
+
if (this._throwOnErrors) {
|
|
739
|
+
throw error;
|
|
740
|
+
}
|
|
614
741
|
}
|
|
615
742
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: result });
|
|
616
743
|
this.stats.delete();
|
|
@@ -630,12 +757,15 @@ var Keyv = class extends event_manager_default {
|
|
|
630
757
|
return await store.deleteMany(keyPrefixed);
|
|
631
758
|
}
|
|
632
759
|
const promises = keyPrefixed.map(async (key) => store.delete(key));
|
|
633
|
-
const results = await Promise.
|
|
634
|
-
const returnResult = results.every(
|
|
760
|
+
const results = await Promise.all(promises);
|
|
761
|
+
const returnResult = results.every(Boolean);
|
|
635
762
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: returnResult });
|
|
636
763
|
return returnResult;
|
|
637
764
|
} catch (error) {
|
|
638
765
|
this.emit("error", error);
|
|
766
|
+
if (this._throwOnErrors) {
|
|
767
|
+
throw error;
|
|
768
|
+
}
|
|
639
769
|
return false;
|
|
640
770
|
}
|
|
641
771
|
}
|
|
@@ -650,6 +780,9 @@ var Keyv = class extends event_manager_default {
|
|
|
650
780
|
await store.clear();
|
|
651
781
|
} catch (error) {
|
|
652
782
|
this.emit("error", error);
|
|
783
|
+
if (this._throwOnErrors) {
|
|
784
|
+
throw error;
|
|
785
|
+
}
|
|
653
786
|
}
|
|
654
787
|
}
|
|
655
788
|
async has(key) {
|
|
@@ -666,6 +799,10 @@ var Keyv = class extends event_manager_default {
|
|
|
666
799
|
rawData = await store.get(keyPrefixed);
|
|
667
800
|
} catch (error) {
|
|
668
801
|
this.emit("error", error);
|
|
802
|
+
if (this._throwOnErrors) {
|
|
803
|
+
throw error;
|
|
804
|
+
}
|
|
805
|
+
return false;
|
|
669
806
|
}
|
|
670
807
|
if (rawData) {
|
|
671
808
|
const data = await this.deserializeData(rawData);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyv",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0",
|
|
4
4
|
"description": "Simple key-value storage with support for multiple backends",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -54,23 +54,23 @@
|
|
|
54
54
|
},
|
|
55
55
|
"homepage": "https://github.com/jaredwray/keyv",
|
|
56
56
|
"dependencies": {
|
|
57
|
-
"@keyv/serialize": "^1.0
|
|
57
|
+
"@keyv/serialize": "^1.1.0"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@faker-js/faker": "^9.
|
|
61
|
-
"@vitest/coverage-v8": "^3.2.
|
|
60
|
+
"@faker-js/faker": "^9.9.0",
|
|
61
|
+
"@vitest/coverage-v8": "^3.2.4",
|
|
62
62
|
"rimraf": "^6.0.1",
|
|
63
63
|
"timekeeper": "^2.3.1",
|
|
64
64
|
"tsd": "^0.32.0",
|
|
65
|
-
"vitest": "^3.2.
|
|
66
|
-
"xo": "^1.
|
|
67
|
-
"@keyv/compress-brotli": "^2.0.
|
|
65
|
+
"vitest": "^3.2.4",
|
|
66
|
+
"xo": "^1.2.0",
|
|
67
|
+
"@keyv/compress-brotli": "^2.0.5",
|
|
68
68
|
"@keyv/compress-gzip": "^2.0.3",
|
|
69
|
-
"@keyv/
|
|
70
|
-
"@keyv/
|
|
71
|
-
"@keyv/
|
|
72
|
-
"@keyv/
|
|
73
|
-
"@keyv/
|
|
69
|
+
"@keyv/memcache": "^2.0.2",
|
|
70
|
+
"@keyv/compress-lz4": "^1.0.1",
|
|
71
|
+
"@keyv/mongo": "^3.0.3",
|
|
72
|
+
"@keyv/sqlite": "^4.0.5",
|
|
73
|
+
"@keyv/test-suite": "^2.1.0"
|
|
74
74
|
},
|
|
75
75
|
"tsd": {
|
|
76
76
|
"directory": "test"
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"scripts": {
|
|
83
83
|
"build": "rimraf ./dist && tsup src/index.ts --format cjs,esm --dts --clean",
|
|
84
84
|
"test": "xo --fix && vitest run --coverage",
|
|
85
|
-
"test:ci": "xo && vitest --run --sequence.setupFiles=list",
|
|
85
|
+
"test:ci": "xo && vitest --run --sequence.setupFiles=list --coverage",
|
|
86
86
|
"clean": "rimraf ./node_modules ./coverage ./test/testdb.sqlite ./dist"
|
|
87
87
|
}
|
|
88
88
|
}
|