keyv 5.3.4 → 5.4.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 +47 -10
- package/dist/index.cjs +61 -11
- package/dist/index.d.cts +52 -9
- package/dist/index.d.ts +52 -9
- package/dist/index.js +61 -11
- package/package.json +13 -13
package/README.md
CHANGED
|
@@ -53,14 +53,6 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
|
|
|
53
53
|
- [.deleteMany(keys)](#deletemanykeys)
|
|
54
54
|
- [.clear()](#clear)
|
|
55
55
|
- [.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
56
|
- [How to Contribute](#how-to-contribute)
|
|
65
57
|
- [License](#license)
|
|
66
58
|
|
|
@@ -83,6 +75,7 @@ npm install --save @keyv/postgres
|
|
|
83
75
|
npm install --save @keyv/mysql
|
|
84
76
|
npm install --save @keyv/etcd
|
|
85
77
|
npm install --save @keyv/memcache
|
|
78
|
+
npm install --save @keyv/dynamo
|
|
86
79
|
```
|
|
87
80
|
|
|
88
81
|
First, create a new Keyv instance.
|
|
@@ -233,7 +226,7 @@ keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data) => console.log(`Setting key ${da
|
|
|
233
226
|
|
|
234
227
|
//POST_SET hook
|
|
235
228
|
const keyv = new Keyv();
|
|
236
|
-
keyv.hooks.addHandler(KeyvHooks.POST_SET, (key, value) => console.log(`Set key ${key} to ${value}`));
|
|
229
|
+
keyv.hooks.addHandler(KeyvHooks.POST_SET, ({key, value}) => console.log(`Set key ${key} to ${value}`));
|
|
237
230
|
```
|
|
238
231
|
|
|
239
232
|
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 +279,7 @@ PostgreSQL | [@keyv/postgres](https://github.com/jaredwray/keyv/tree/master/pack
|
|
|
286
279
|
MySQL | [@keyv/mysql](https://github.com/jaredwray/keyv/tree/master/packages/mysql) | No
|
|
287
280
|
Etcd | [@keyv/etcd](https://github.com/jaredwray/keyv/tree/master/packages/etcd) | Yes
|
|
288
281
|
Memcache | [@keyv/memcache](https://github.com/jaredwray/keyv/tree/master/packages/memcache) | Yes
|
|
282
|
+
DynamoDB | [@keyv/dynamo](https://github.com/jaredwray/keyv/tree/master/packages/dynamo) | Yes
|
|
289
283
|
|
|
290
284
|
# Third-party Storage Adapters
|
|
291
285
|
|
|
@@ -318,7 +312,6 @@ The following are third-party storage adapters compatible with Keyv:
|
|
|
318
312
|
|
|
319
313
|
- [quick-lru](https://github.com/sindresorhus/quick-lru) - Simple "Least Recently Used" (LRU) cache
|
|
320
314
|
- [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
315
|
- [keyv-lru](https://www.npmjs.com/package/keyv-lru) - LRU storage adapter for Keyv
|
|
323
316
|
- [keyv-null](https://www.npmjs.com/package/keyv-null) - Null storage adapter for Keyv
|
|
324
317
|
- [keyv-firestore ](https://github.com/goto-bus-stop/keyv-firestore) – Firebase Cloud Firestore adapter for Keyv
|
|
@@ -623,6 +616,50 @@ keyv.useKeyPrefix = true;
|
|
|
623
616
|
console.log(keyv.useKeyPrefix); // true
|
|
624
617
|
```
|
|
625
618
|
|
|
619
|
+
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`:
|
|
620
|
+
|
|
621
|
+
```js
|
|
622
|
+
import Keyv from 'keyv';
|
|
623
|
+
import KeyvSqlite from '@keyv/sqlite';
|
|
624
|
+
|
|
625
|
+
const store = new KeyvSqlite('sqlite://path/to/database.sqlite');
|
|
626
|
+
const keyv = new Keyv({ store });
|
|
627
|
+
keyv.useKeyPrefix = false; // disable key prefixing
|
|
628
|
+
store.namespace = undefined; // disable namespacing in the storage adapter
|
|
629
|
+
|
|
630
|
+
await keyv.set('foo', 'bar'); // true
|
|
631
|
+
await keyv.get('foo'); // 'bar'
|
|
632
|
+
await keyv.clear();
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
## .throwOnErrors
|
|
636
|
+
|
|
637
|
+
Type: `Boolean`<br />
|
|
638
|
+
Default: `false`
|
|
639
|
+
|
|
640
|
+
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.
|
|
641
|
+
|
|
642
|
+
```js
|
|
643
|
+
const keyv = new Keyv({ throwOnErrors: true });
|
|
644
|
+
console.log(keyv.throwOnErrors); // true
|
|
645
|
+
keyv.throwOnErrors = false;
|
|
646
|
+
console.log(keyv.throwOnErrors); // false
|
|
647
|
+
```
|
|
648
|
+
|
|
649
|
+
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:
|
|
650
|
+
|
|
651
|
+
```js
|
|
652
|
+
import Keyv from 'keyv';
|
|
653
|
+
import KeyvRedis from '@keyv/redis';
|
|
654
|
+
|
|
655
|
+
// create redis instance that will throw on connection error
|
|
656
|
+
const keyvRedis = new KeyvRedis('redis://user:pass@localhost:6379', { throwOnConnectErrors: true });
|
|
657
|
+
|
|
658
|
+
const keyv = new Keyv({ store: keyvRedis, throwOnErrors: true });
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
What this does is it only throw on connection errors with the Redis client.
|
|
662
|
+
|
|
626
663
|
# How to Contribute
|
|
627
664
|
|
|
628
665
|
We welcome contributions to Keyv! 🎉 Here are some guides to get you started with contributing:
|
package/dist/index.cjs
CHANGED
|
@@ -237,6 +237,7 @@ var Keyv = class extends event_manager_default {
|
|
|
237
237
|
_deserialize = import_serialize.defaultDeserialize;
|
|
238
238
|
_compression;
|
|
239
239
|
_useKeyPrefix = true;
|
|
240
|
+
_throwOnErrors = false;
|
|
240
241
|
/**
|
|
241
242
|
* Keyv Constructor
|
|
242
243
|
* @param {KeyvStoreAdapter | KeyvOptions} store
|
|
@@ -293,6 +294,9 @@ var Keyv = class extends event_manager_default {
|
|
|
293
294
|
if (this.opts.useKeyPrefix !== void 0) {
|
|
294
295
|
this._useKeyPrefix = this.opts.useKeyPrefix;
|
|
295
296
|
}
|
|
297
|
+
if (this.opts.throwOnErrors !== void 0) {
|
|
298
|
+
this._throwOnErrors = this.opts.throwOnErrors;
|
|
299
|
+
}
|
|
296
300
|
}
|
|
297
301
|
/**
|
|
298
302
|
* Get the current store
|
|
@@ -417,6 +421,21 @@ var Keyv = class extends event_manager_default {
|
|
|
417
421
|
this._useKeyPrefix = value;
|
|
418
422
|
this.opts.useKeyPrefix = value;
|
|
419
423
|
}
|
|
424
|
+
/**
|
|
425
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
426
|
+
* @return {boolean} The current throwOnErrors value.
|
|
427
|
+
*/
|
|
428
|
+
get throwOnErrors() {
|
|
429
|
+
return this._throwOnErrors;
|
|
430
|
+
}
|
|
431
|
+
/**
|
|
432
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
433
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
434
|
+
*/
|
|
435
|
+
set throwOnErrors(value) {
|
|
436
|
+
this._throwOnErrors = value;
|
|
437
|
+
this.opts.throwOnErrors = value;
|
|
438
|
+
}
|
|
420
439
|
generateIterator(iterator) {
|
|
421
440
|
const function_ = async function* () {
|
|
422
441
|
for await (const [key, raw] of typeof iterator === "function" ? iterator(this._store.namespace) : iterator) {
|
|
@@ -476,7 +495,14 @@ var Keyv = class extends event_manager_default {
|
|
|
476
495
|
return this.getMany(key, { raw: false });
|
|
477
496
|
}
|
|
478
497
|
this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });
|
|
479
|
-
|
|
498
|
+
let rawData;
|
|
499
|
+
try {
|
|
500
|
+
rawData = await store.get(keyPrefixed);
|
|
501
|
+
} catch (error) {
|
|
502
|
+
if (this.throwOnErrors) {
|
|
503
|
+
throw error;
|
|
504
|
+
}
|
|
505
|
+
}
|
|
480
506
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
481
507
|
if (deserializedData === void 0 || deserializedData === null) {
|
|
482
508
|
this.stats.miss();
|
|
@@ -519,6 +545,7 @@ var Keyv = class extends event_manager_default {
|
|
|
519
545
|
}
|
|
520
546
|
const rawData = await store.getMany(keyPrefixed);
|
|
521
547
|
const result = [];
|
|
548
|
+
const expiredKeys = [];
|
|
522
549
|
for (const index in rawData) {
|
|
523
550
|
let row = rawData[index];
|
|
524
551
|
if (typeof row === "string") {
|
|
@@ -529,13 +556,16 @@ var Keyv = class extends event_manager_default {
|
|
|
529
556
|
continue;
|
|
530
557
|
}
|
|
531
558
|
if (isDataExpired(row)) {
|
|
532
|
-
|
|
559
|
+
expiredKeys.push(keys[index]);
|
|
533
560
|
result.push(void 0);
|
|
534
561
|
continue;
|
|
535
562
|
}
|
|
536
563
|
const value = options?.raw ? row : row.value;
|
|
537
564
|
result.push(value);
|
|
538
565
|
}
|
|
566
|
+
if (expiredKeys.length > 0) {
|
|
567
|
+
await this.deleteMany(expiredKeys);
|
|
568
|
+
}
|
|
539
569
|
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
|
|
540
570
|
if (result.length > 0) {
|
|
541
571
|
this.stats.hit();
|
|
@@ -574,6 +604,9 @@ var Keyv = class extends event_manager_default {
|
|
|
574
604
|
} catch (error) {
|
|
575
605
|
result = false;
|
|
576
606
|
this.emit("error", error);
|
|
607
|
+
if (this._throwOnErrors) {
|
|
608
|
+
throw error;
|
|
609
|
+
}
|
|
577
610
|
}
|
|
578
611
|
this.hooks.trigger("postSet" /* POST_SET */, { key: keyPrefixed, value: serializedValue, ttl });
|
|
579
612
|
this.stats.set();
|
|
@@ -587,7 +620,14 @@ var Keyv = class extends event_manager_default {
|
|
|
587
620
|
async setMany(entries) {
|
|
588
621
|
let results = [];
|
|
589
622
|
try {
|
|
590
|
-
if (this._store.setMany
|
|
623
|
+
if (this._store.setMany === void 0) {
|
|
624
|
+
const promises = [];
|
|
625
|
+
for (const entry of entries) {
|
|
626
|
+
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
627
|
+
}
|
|
628
|
+
const promiseResults = await Promise.all(promises);
|
|
629
|
+
results = promiseResults;
|
|
630
|
+
} else {
|
|
591
631
|
const serializedEntries = await Promise.all(entries.map(async ({ key, value, ttl }) => {
|
|
592
632
|
ttl ??= this._ttl;
|
|
593
633
|
if (ttl === 0) {
|
|
@@ -604,14 +644,11 @@ var Keyv = class extends event_manager_default {
|
|
|
604
644
|
}));
|
|
605
645
|
results = await this._store.setMany(serializedEntries);
|
|
606
646
|
}
|
|
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
647
|
} catch (error) {
|
|
614
648
|
this.emit("error", error);
|
|
649
|
+
if (this._throwOnErrors) {
|
|
650
|
+
throw error;
|
|
651
|
+
}
|
|
615
652
|
results = entries.map(() => false);
|
|
616
653
|
}
|
|
617
654
|
return results;
|
|
@@ -637,6 +674,9 @@ var Keyv = class extends event_manager_default {
|
|
|
637
674
|
} catch (error) {
|
|
638
675
|
result = false;
|
|
639
676
|
this.emit("error", error);
|
|
677
|
+
if (this._throwOnErrors) {
|
|
678
|
+
throw error;
|
|
679
|
+
}
|
|
640
680
|
}
|
|
641
681
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: result });
|
|
642
682
|
this.stats.delete();
|
|
@@ -656,12 +696,15 @@ var Keyv = class extends event_manager_default {
|
|
|
656
696
|
return await store.deleteMany(keyPrefixed);
|
|
657
697
|
}
|
|
658
698
|
const promises = keyPrefixed.map(async (key) => store.delete(key));
|
|
659
|
-
const results = await Promise.
|
|
660
|
-
const returnResult = results.every(
|
|
699
|
+
const results = await Promise.all(promises);
|
|
700
|
+
const returnResult = results.every(Boolean);
|
|
661
701
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: returnResult });
|
|
662
702
|
return returnResult;
|
|
663
703
|
} catch (error) {
|
|
664
704
|
this.emit("error", error);
|
|
705
|
+
if (this._throwOnErrors) {
|
|
706
|
+
throw error;
|
|
707
|
+
}
|
|
665
708
|
return false;
|
|
666
709
|
}
|
|
667
710
|
}
|
|
@@ -676,6 +719,9 @@ var Keyv = class extends event_manager_default {
|
|
|
676
719
|
await store.clear();
|
|
677
720
|
} catch (error) {
|
|
678
721
|
this.emit("error", error);
|
|
722
|
+
if (this._throwOnErrors) {
|
|
723
|
+
throw error;
|
|
724
|
+
}
|
|
679
725
|
}
|
|
680
726
|
}
|
|
681
727
|
async has(key) {
|
|
@@ -692,6 +738,10 @@ var Keyv = class extends event_manager_default {
|
|
|
692
738
|
rawData = await store.get(keyPrefixed);
|
|
693
739
|
} catch (error) {
|
|
694
740
|
this.emit("error", error);
|
|
741
|
+
if (this._throwOnErrors) {
|
|
742
|
+
throw error;
|
|
743
|
+
}
|
|
744
|
+
return false;
|
|
695
745
|
}
|
|
696
746
|
if (rawData) {
|
|
697
747
|
const data = await this.deserializeData(rawData);
|
package/dist/index.d.cts
CHANGED
|
@@ -102,24 +102,56 @@ type KeyvStoreAdapter = {
|
|
|
102
102
|
iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
|
|
103
103
|
} & IEventEmitter;
|
|
104
104
|
type KeyvOptions = {
|
|
105
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Emit errors
|
|
107
|
+
* @default true
|
|
108
|
+
*/
|
|
106
109
|
emitErrors?: boolean;
|
|
107
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Namespace for the current instance.
|
|
112
|
+
* @default 'keyv'
|
|
113
|
+
*/
|
|
108
114
|
namespace?: string;
|
|
109
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* A custom serialization function.
|
|
117
|
+
* @default defaultSerialize using JSON.stringify
|
|
118
|
+
*/
|
|
110
119
|
serialize?: Serialize;
|
|
111
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* A custom deserialization function.
|
|
122
|
+
* @default defaultDeserialize using JSON.parse
|
|
123
|
+
*/
|
|
112
124
|
deserialize?: Deserialize;
|
|
113
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* The storage adapter instance to be used by Keyv.
|
|
127
|
+
* @default new Map() - in-memory store
|
|
128
|
+
*/
|
|
114
129
|
store?: KeyvStoreAdapter | Map<any, any> | any;
|
|
115
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* Default TTL. Can be overridden by specifying a TTL on `.set()`.
|
|
132
|
+
* @default undefined
|
|
133
|
+
*/
|
|
116
134
|
ttl?: number;
|
|
117
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Enable compression option
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
118
139
|
compression?: CompressionAdapter | any;
|
|
119
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Enable or disable statistics (default is false)
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
120
144
|
stats?: boolean;
|
|
121
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* Enable or disable key prefixing (default is true)
|
|
147
|
+
* @default true
|
|
148
|
+
*/
|
|
122
149
|
useKeyPrefix?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Will enable throwing errors on methods in addition to emitting them.
|
|
152
|
+
* @default false
|
|
153
|
+
*/
|
|
154
|
+
throwOnErrors?: boolean;
|
|
123
155
|
};
|
|
124
156
|
type KeyvOptions_ = Omit<KeyvOptions, 'store'> & {
|
|
125
157
|
store: KeyvStoreAdapter | Map<any, any> & KeyvStoreAdapter;
|
|
@@ -146,6 +178,7 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
146
178
|
private _deserialize;
|
|
147
179
|
private _compression;
|
|
148
180
|
private _useKeyPrefix;
|
|
181
|
+
private _throwOnErrors;
|
|
149
182
|
/**
|
|
150
183
|
* Keyv Constructor
|
|
151
184
|
* @param {KeyvStoreAdapter | KeyvOptions | Map<any, any>} store to be provided or just the options
|
|
@@ -227,6 +260,16 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
227
260
|
* @param {boolean} value The useKeyPrefix value to set.
|
|
228
261
|
*/
|
|
229
262
|
set useKeyPrefix(value: boolean);
|
|
263
|
+
/**
|
|
264
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
265
|
+
* @return {boolean} The current throwOnErrors value.
|
|
266
|
+
*/
|
|
267
|
+
get throwOnErrors(): boolean;
|
|
268
|
+
/**
|
|
269
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
270
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
271
|
+
*/
|
|
272
|
+
set throwOnErrors(value: boolean);
|
|
230
273
|
generateIterator(iterator: IteratorFunction): IteratorFunction;
|
|
231
274
|
_checkIterableAdapter(): boolean;
|
|
232
275
|
_getKeyPrefix(key: string): string;
|
package/dist/index.d.ts
CHANGED
|
@@ -102,24 +102,56 @@ type KeyvStoreAdapter = {
|
|
|
102
102
|
iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
|
|
103
103
|
} & IEventEmitter;
|
|
104
104
|
type KeyvOptions = {
|
|
105
|
-
/**
|
|
105
|
+
/**
|
|
106
|
+
* Emit errors
|
|
107
|
+
* @default true
|
|
108
|
+
*/
|
|
106
109
|
emitErrors?: boolean;
|
|
107
|
-
/**
|
|
110
|
+
/**
|
|
111
|
+
* Namespace for the current instance.
|
|
112
|
+
* @default 'keyv'
|
|
113
|
+
*/
|
|
108
114
|
namespace?: string;
|
|
109
|
-
/**
|
|
115
|
+
/**
|
|
116
|
+
* A custom serialization function.
|
|
117
|
+
* @default defaultSerialize using JSON.stringify
|
|
118
|
+
*/
|
|
110
119
|
serialize?: Serialize;
|
|
111
|
-
/**
|
|
120
|
+
/**
|
|
121
|
+
* A custom deserialization function.
|
|
122
|
+
* @default defaultDeserialize using JSON.parse
|
|
123
|
+
*/
|
|
112
124
|
deserialize?: Deserialize;
|
|
113
|
-
/**
|
|
125
|
+
/**
|
|
126
|
+
* The storage adapter instance to be used by Keyv.
|
|
127
|
+
* @default new Map() - in-memory store
|
|
128
|
+
*/
|
|
114
129
|
store?: KeyvStoreAdapter | Map<any, any> | any;
|
|
115
|
-
/**
|
|
130
|
+
/**
|
|
131
|
+
* Default TTL. Can be overridden by specifying a TTL on `.set()`.
|
|
132
|
+
* @default undefined
|
|
133
|
+
*/
|
|
116
134
|
ttl?: number;
|
|
117
|
-
/**
|
|
135
|
+
/**
|
|
136
|
+
* Enable compression option
|
|
137
|
+
* @default false
|
|
138
|
+
*/
|
|
118
139
|
compression?: CompressionAdapter | any;
|
|
119
|
-
/**
|
|
140
|
+
/**
|
|
141
|
+
* Enable or disable statistics (default is false)
|
|
142
|
+
* @default false
|
|
143
|
+
*/
|
|
120
144
|
stats?: boolean;
|
|
121
|
-
/**
|
|
145
|
+
/**
|
|
146
|
+
* Enable or disable key prefixing (default is true)
|
|
147
|
+
* @default true
|
|
148
|
+
*/
|
|
122
149
|
useKeyPrefix?: boolean;
|
|
150
|
+
/**
|
|
151
|
+
* Will enable throwing errors on methods in addition to emitting them.
|
|
152
|
+
* @default false
|
|
153
|
+
*/
|
|
154
|
+
throwOnErrors?: boolean;
|
|
123
155
|
};
|
|
124
156
|
type KeyvOptions_ = Omit<KeyvOptions, 'store'> & {
|
|
125
157
|
store: KeyvStoreAdapter | Map<any, any> & KeyvStoreAdapter;
|
|
@@ -146,6 +178,7 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
146
178
|
private _deserialize;
|
|
147
179
|
private _compression;
|
|
148
180
|
private _useKeyPrefix;
|
|
181
|
+
private _throwOnErrors;
|
|
149
182
|
/**
|
|
150
183
|
* Keyv Constructor
|
|
151
184
|
* @param {KeyvStoreAdapter | KeyvOptions | Map<any, any>} store to be provided or just the options
|
|
@@ -227,6 +260,16 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
227
260
|
* @param {boolean} value The useKeyPrefix value to set.
|
|
228
261
|
*/
|
|
229
262
|
set useKeyPrefix(value: boolean);
|
|
263
|
+
/**
|
|
264
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
265
|
+
* @return {boolean} The current throwOnErrors value.
|
|
266
|
+
*/
|
|
267
|
+
get throwOnErrors(): boolean;
|
|
268
|
+
/**
|
|
269
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
270
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
271
|
+
*/
|
|
272
|
+
set throwOnErrors(value: boolean);
|
|
230
273
|
generateIterator(iterator: IteratorFunction): IteratorFunction;
|
|
231
274
|
_checkIterableAdapter(): boolean;
|
|
232
275
|
_getKeyPrefix(key: string): string;
|
package/dist/index.js
CHANGED
|
@@ -211,6 +211,7 @@ var Keyv = class extends event_manager_default {
|
|
|
211
211
|
_deserialize = defaultDeserialize;
|
|
212
212
|
_compression;
|
|
213
213
|
_useKeyPrefix = true;
|
|
214
|
+
_throwOnErrors = false;
|
|
214
215
|
/**
|
|
215
216
|
* Keyv Constructor
|
|
216
217
|
* @param {KeyvStoreAdapter | KeyvOptions} store
|
|
@@ -267,6 +268,9 @@ var Keyv = class extends event_manager_default {
|
|
|
267
268
|
if (this.opts.useKeyPrefix !== void 0) {
|
|
268
269
|
this._useKeyPrefix = this.opts.useKeyPrefix;
|
|
269
270
|
}
|
|
271
|
+
if (this.opts.throwOnErrors !== void 0) {
|
|
272
|
+
this._throwOnErrors = this.opts.throwOnErrors;
|
|
273
|
+
}
|
|
270
274
|
}
|
|
271
275
|
/**
|
|
272
276
|
* Get the current store
|
|
@@ -391,6 +395,21 @@ var Keyv = class extends event_manager_default {
|
|
|
391
395
|
this._useKeyPrefix = value;
|
|
392
396
|
this.opts.useKeyPrefix = value;
|
|
393
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* Get the current throwErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
400
|
+
* @return {boolean} The current throwOnErrors value.
|
|
401
|
+
*/
|
|
402
|
+
get throwOnErrors() {
|
|
403
|
+
return this._throwOnErrors;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Set the current throwOnErrors value. This will enable or disable throwing errors on methods in addition to emitting them.
|
|
407
|
+
* @param {boolean} value The throwOnErrors value to set.
|
|
408
|
+
*/
|
|
409
|
+
set throwOnErrors(value) {
|
|
410
|
+
this._throwOnErrors = value;
|
|
411
|
+
this.opts.throwOnErrors = value;
|
|
412
|
+
}
|
|
394
413
|
generateIterator(iterator) {
|
|
395
414
|
const function_ = async function* () {
|
|
396
415
|
for await (const [key, raw] of typeof iterator === "function" ? iterator(this._store.namespace) : iterator) {
|
|
@@ -450,7 +469,14 @@ var Keyv = class extends event_manager_default {
|
|
|
450
469
|
return this.getMany(key, { raw: false });
|
|
451
470
|
}
|
|
452
471
|
this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });
|
|
453
|
-
|
|
472
|
+
let rawData;
|
|
473
|
+
try {
|
|
474
|
+
rawData = await store.get(keyPrefixed);
|
|
475
|
+
} catch (error) {
|
|
476
|
+
if (this.throwOnErrors) {
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
}
|
|
454
480
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
455
481
|
if (deserializedData === void 0 || deserializedData === null) {
|
|
456
482
|
this.stats.miss();
|
|
@@ -493,6 +519,7 @@ var Keyv = class extends event_manager_default {
|
|
|
493
519
|
}
|
|
494
520
|
const rawData = await store.getMany(keyPrefixed);
|
|
495
521
|
const result = [];
|
|
522
|
+
const expiredKeys = [];
|
|
496
523
|
for (const index in rawData) {
|
|
497
524
|
let row = rawData[index];
|
|
498
525
|
if (typeof row === "string") {
|
|
@@ -503,13 +530,16 @@ var Keyv = class extends event_manager_default {
|
|
|
503
530
|
continue;
|
|
504
531
|
}
|
|
505
532
|
if (isDataExpired(row)) {
|
|
506
|
-
|
|
533
|
+
expiredKeys.push(keys[index]);
|
|
507
534
|
result.push(void 0);
|
|
508
535
|
continue;
|
|
509
536
|
}
|
|
510
537
|
const value = options?.raw ? row : row.value;
|
|
511
538
|
result.push(value);
|
|
512
539
|
}
|
|
540
|
+
if (expiredKeys.length > 0) {
|
|
541
|
+
await this.deleteMany(expiredKeys);
|
|
542
|
+
}
|
|
513
543
|
this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
|
|
514
544
|
if (result.length > 0) {
|
|
515
545
|
this.stats.hit();
|
|
@@ -548,6 +578,9 @@ var Keyv = class extends event_manager_default {
|
|
|
548
578
|
} catch (error) {
|
|
549
579
|
result = false;
|
|
550
580
|
this.emit("error", error);
|
|
581
|
+
if (this._throwOnErrors) {
|
|
582
|
+
throw error;
|
|
583
|
+
}
|
|
551
584
|
}
|
|
552
585
|
this.hooks.trigger("postSet" /* POST_SET */, { key: keyPrefixed, value: serializedValue, ttl });
|
|
553
586
|
this.stats.set();
|
|
@@ -561,7 +594,14 @@ var Keyv = class extends event_manager_default {
|
|
|
561
594
|
async setMany(entries) {
|
|
562
595
|
let results = [];
|
|
563
596
|
try {
|
|
564
|
-
if (this._store.setMany
|
|
597
|
+
if (this._store.setMany === void 0) {
|
|
598
|
+
const promises = [];
|
|
599
|
+
for (const entry of entries) {
|
|
600
|
+
promises.push(this.set(entry.key, entry.value, entry.ttl));
|
|
601
|
+
}
|
|
602
|
+
const promiseResults = await Promise.all(promises);
|
|
603
|
+
results = promiseResults;
|
|
604
|
+
} else {
|
|
565
605
|
const serializedEntries = await Promise.all(entries.map(async ({ key, value, ttl }) => {
|
|
566
606
|
ttl ??= this._ttl;
|
|
567
607
|
if (ttl === 0) {
|
|
@@ -578,14 +618,11 @@ var Keyv = class extends event_manager_default {
|
|
|
578
618
|
}));
|
|
579
619
|
results = await this._store.setMany(serializedEntries);
|
|
580
620
|
}
|
|
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
621
|
} catch (error) {
|
|
588
622
|
this.emit("error", error);
|
|
623
|
+
if (this._throwOnErrors) {
|
|
624
|
+
throw error;
|
|
625
|
+
}
|
|
589
626
|
results = entries.map(() => false);
|
|
590
627
|
}
|
|
591
628
|
return results;
|
|
@@ -611,6 +648,9 @@ var Keyv = class extends event_manager_default {
|
|
|
611
648
|
} catch (error) {
|
|
612
649
|
result = false;
|
|
613
650
|
this.emit("error", error);
|
|
651
|
+
if (this._throwOnErrors) {
|
|
652
|
+
throw error;
|
|
653
|
+
}
|
|
614
654
|
}
|
|
615
655
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: result });
|
|
616
656
|
this.stats.delete();
|
|
@@ -630,12 +670,15 @@ var Keyv = class extends event_manager_default {
|
|
|
630
670
|
return await store.deleteMany(keyPrefixed);
|
|
631
671
|
}
|
|
632
672
|
const promises = keyPrefixed.map(async (key) => store.delete(key));
|
|
633
|
-
const results = await Promise.
|
|
634
|
-
const returnResult = results.every(
|
|
673
|
+
const results = await Promise.all(promises);
|
|
674
|
+
const returnResult = results.every(Boolean);
|
|
635
675
|
this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: returnResult });
|
|
636
676
|
return returnResult;
|
|
637
677
|
} catch (error) {
|
|
638
678
|
this.emit("error", error);
|
|
679
|
+
if (this._throwOnErrors) {
|
|
680
|
+
throw error;
|
|
681
|
+
}
|
|
639
682
|
return false;
|
|
640
683
|
}
|
|
641
684
|
}
|
|
@@ -650,6 +693,9 @@ var Keyv = class extends event_manager_default {
|
|
|
650
693
|
await store.clear();
|
|
651
694
|
} catch (error) {
|
|
652
695
|
this.emit("error", error);
|
|
696
|
+
if (this._throwOnErrors) {
|
|
697
|
+
throw error;
|
|
698
|
+
}
|
|
653
699
|
}
|
|
654
700
|
}
|
|
655
701
|
async has(key) {
|
|
@@ -666,6 +712,10 @@ var Keyv = class extends event_manager_default {
|
|
|
666
712
|
rawData = await store.get(keyPrefixed);
|
|
667
713
|
} catch (error) {
|
|
668
714
|
this.emit("error", error);
|
|
715
|
+
if (this._throwOnErrors) {
|
|
716
|
+
throw error;
|
|
717
|
+
}
|
|
718
|
+
return false;
|
|
669
719
|
}
|
|
670
720
|
if (rawData) {
|
|
671
721
|
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.4.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.1.
|
|
67
|
-
"@keyv/
|
|
65
|
+
"vitest": "^3.2.4",
|
|
66
|
+
"xo": "^1.1.1",
|
|
67
|
+
"@keyv/memcache": "^2.0.2",
|
|
68
68
|
"@keyv/compress-gzip": "^2.0.3",
|
|
69
|
-
"@keyv/
|
|
70
|
-
"@keyv/
|
|
71
|
-
"@keyv/
|
|
72
|
-
"@keyv/
|
|
73
|
-
"@keyv/
|
|
69
|
+
"@keyv/compress-lz4": "^1.0.1",
|
|
70
|
+
"@keyv/compress-brotli": "^2.0.5",
|
|
71
|
+
"@keyv/mongo": "^3.0.3",
|
|
72
|
+
"@keyv/test-suite": "^2.0.9",
|
|
73
|
+
"@keyv/sqlite": "^4.0.5"
|
|
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
|
}
|