keyv 5.2.2 → 5.3.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 CHANGED
@@ -144,7 +144,15 @@ await cache.get('foo'); // 'cache'
144
144
 
145
145
  # Events
146
146
 
147
- Keyv is a custom `EventEmitter` and will emit an `'error'` event if there is an error. In addition it will emit a `clear` and `disconnect` event when the corresponding methods are called.
147
+ Keyv is a custom `EventEmitter` and will emit an `'error'` event if there is an error.
148
+ If there is no listener for the `'error'` event, an uncaught exception will be thrown.
149
+ To disable the `'error'` event, pass `emitErrors: false` in the constructor options.
150
+
151
+ ```js
152
+ const keyv = new Keyv({ emitErrors: false });
153
+ ```
154
+
155
+ In addition it will emit `clear` and `disconnect` events when the corresponding methods are called.
148
156
 
149
157
  ```js
150
158
  const keyv = new Keyv();
@@ -281,14 +289,30 @@ The following are third-party storage adapters compatible with Keyv:
281
289
 
282
290
  # Compression
283
291
 
284
- Keyv supports `gzip` and `brotli` compression. To enable compression, pass the `compress` option to the constructor.
292
+ Keyv supports `gzip`, `brotli` and `lz4` compression. To enable compression, pass the `compress` option to the constructor.
285
293
 
286
294
  ```js
287
295
  import Keyv from 'keyv';
288
296
  import KeyvGzip from '@keyv/compress-gzip';
289
297
 
290
298
  const keyvGzip = new KeyvGzip();
291
- const keyv = new Keyv({ compression: KeyvGzip });
299
+ const keyv = new Keyv({ compression: keyvGzip });
300
+ ```
301
+
302
+ ```js
303
+ import Keyv from 'keyv';
304
+ import KeyvBrotli from '@keyv/compress-brotli';
305
+
306
+ const keyvBrotli = new KeyvBrotli();
307
+ const keyv = new Keyv({ compression: keyvBrotli });
308
+ ```
309
+
310
+ ```js
311
+ import Keyv from 'keyv';
312
+ import KeyvLz4 from '@keyv/compress-lz4';
313
+
314
+ const keyvLz4 = new KeyvLz4();
315
+ const keyv = new Keyv({ compression: keyvLz4 });
292
316
  ```
293
317
 
294
318
  You can also pass a custom compression function to the `compression` option. Following the pattern of the official compression adapters.
@@ -399,10 +423,18 @@ By default keys are persistent. You can set an expiry TTL in milliseconds.
399
423
 
400
424
  Returns a promise which resolves to `true`.
401
425
 
426
+ ## .setMany(entries)
427
+
428
+ Set multiple values using KeyvEntrys `{ key: string, value: any, ttl?: number }`.
429
+
402
430
  ## .get(key, [options])
403
431
 
404
432
  Returns a promise which resolves to the retrieved value.
405
433
 
434
+ ## .getMany(keys, [options])
435
+
436
+ Returns a promise which resolves to an array of retrieved values.
437
+
406
438
  ### options.raw
407
439
 
408
440
  Type: `Boolean`<br />
@@ -418,6 +450,10 @@ Deletes an entry.
418
450
 
419
451
  Returns a promise which resolves to `true` if the key existed, `false` if not.
420
452
 
453
+ ## .deleteMany(keys)
454
+ Deletes multiple entries.
455
+ Returns a promise which resolves to an array of booleans indicating if the key existed or not.
456
+
421
457
  ## .clear()
422
458
 
423
459
  Delete all entries in the current namespace.
package/dist/index.cjs CHANGED
@@ -18,13 +18,13 @@ var __copyProps = (to, from, except, desc) => {
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
19
 
20
20
  // src/index.ts
21
- var src_exports = {};
22
- __export(src_exports, {
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
23
  Keyv: () => Keyv,
24
24
  KeyvHooks: () => KeyvHooks,
25
- default: () => src_default
25
+ default: () => index_default
26
26
  });
27
- module.exports = __toCommonJS(src_exports);
27
+ module.exports = __toCommonJS(index_exports);
28
28
  var import_serialize = require("@keyv/serialize");
29
29
 
30
30
  // src/event-manager.ts
@@ -293,7 +293,7 @@ var Keyv = class extends event_manager_default {
293
293
  if (!this._isValidStorageAdapter(this._store)) {
294
294
  throw new Error("Invalid storage adapter");
295
295
  }
296
- if (typeof this._store.on === "function" && this.opts.emitErrors) {
296
+ if (typeof this._store.on === "function") {
297
297
  this._store.on("error", (error) => this.emit("error", error));
298
298
  }
299
299
  this._store.namespace = this._namespace;
@@ -327,7 +327,7 @@ var Keyv = class extends event_manager_default {
327
327
  if (this._isValidStorageAdapter(store)) {
328
328
  this._store = store;
329
329
  this.opts.store = store;
330
- if (typeof store.on === "function" && this.opts.emitErrors) {
330
+ if (typeof store.on === "function") {
331
331
  store.on("error", (error) => this.emit("error", error));
332
332
  }
333
333
  if (this._namespace) {
@@ -488,52 +488,10 @@ var Keyv = class extends event_manager_default {
488
488
  const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key);
489
489
  const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
490
490
  if (isArray) {
491
- this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys: keyPrefixed });
492
- if (store.getMany === void 0) {
493
- const promises = keyPrefixed.map(async (key2) => {
494
- const rawData3 = await store.get(key2);
495
- const deserializedRow = typeof rawData3 === "string" || this.opts.compression ? await this.deserializeData(rawData3) : rawData3;
496
- if (deserializedRow === void 0 || deserializedRow === null) {
497
- return void 0;
498
- }
499
- if (isDataExpired(deserializedRow)) {
500
- await this.delete(key2);
501
- return void 0;
502
- }
503
- return options?.raw ? deserializedRow : deserializedRow.value;
504
- });
505
- const deserializedRows = await Promise.allSettled(promises);
506
- const result2 = deserializedRows.map((row) => row.value);
507
- this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
508
- if (result2.length > 0) {
509
- this.stats.hit();
510
- }
511
- return result2;
491
+ if (options?.raw === true) {
492
+ return this.getMany(key, { raw: true });
512
493
  }
513
- const rawData2 = await store.getMany(keyPrefixed);
514
- const result = [];
515
- for (const index in rawData2) {
516
- let row = rawData2[index];
517
- if (typeof row === "string") {
518
- row = await this.deserializeData(row);
519
- }
520
- if (row === void 0 || row === null) {
521
- result.push(void 0);
522
- continue;
523
- }
524
- if (isDataExpired(row)) {
525
- await this.delete(key[index]);
526
- result.push(void 0);
527
- continue;
528
- }
529
- const value = options?.raw ? row : row.value;
530
- result.push(value);
531
- }
532
- this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
533
- if (result.length > 0) {
534
- this.stats.hit();
535
- }
536
- return result;
494
+ return this.getMany(key, { raw: false });
537
495
  }
538
496
  this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });
539
497
  const rawData = await store.get(keyPrefixed);
@@ -551,17 +509,64 @@ var Keyv = class extends event_manager_default {
551
509
  this.stats.hit();
552
510
  return options?.raw ? deserializedData : deserializedData.value;
553
511
  }
554
- /**
555
- * Set an item to the store
556
- * @param {string} key the key to use
557
- * @param {Value} value the value of the key
558
- * @param {number} [ttl] time to live in milliseconds
559
- * @returns {boolean} if it sets then it will return a true. On failure will return false.
560
- */
512
+ async getMany(keys, options) {
513
+ const { store } = this.opts;
514
+ const keyPrefixed = this._getKeyPrefixArray(keys);
515
+ const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
516
+ this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys: keyPrefixed });
517
+ if (store.getMany === void 0) {
518
+ const promises = keyPrefixed.map(async (key) => {
519
+ const rawData2 = await store.get(key);
520
+ const deserializedRow = typeof rawData2 === "string" || this.opts.compression ? await this.deserializeData(rawData2) : rawData2;
521
+ if (deserializedRow === void 0 || deserializedRow === null) {
522
+ return void 0;
523
+ }
524
+ if (isDataExpired(deserializedRow)) {
525
+ await this.delete(key);
526
+ return void 0;
527
+ }
528
+ return options?.raw ? deserializedRow : deserializedRow.value;
529
+ });
530
+ const deserializedRows = await Promise.allSettled(promises);
531
+ const result2 = deserializedRows.map((row) => row.value);
532
+ this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
533
+ if (result2.length > 0) {
534
+ this.stats.hit();
535
+ }
536
+ return result2;
537
+ }
538
+ const rawData = await store.getMany(keyPrefixed);
539
+ const result = [];
540
+ for (const index in rawData) {
541
+ let row = rawData[index];
542
+ if (typeof row === "string") {
543
+ row = await this.deserializeData(row);
544
+ }
545
+ if (row === void 0 || row === null) {
546
+ result.push(void 0);
547
+ continue;
548
+ }
549
+ if (isDataExpired(row)) {
550
+ await this.delete(keys[index]);
551
+ result.push(void 0);
552
+ continue;
553
+ }
554
+ const value = options?.raw ? row : row.value;
555
+ result.push(value);
556
+ }
557
+ this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
558
+ if (result.length > 0) {
559
+ this.stats.hit();
560
+ }
561
+ return result;
562
+ }
561
563
  async set(key, value, ttl) {
564
+ if (Array.isArray(key)) {
565
+ return this.setMany(key);
566
+ }
562
567
  this.hooks.trigger("preSet" /* PRE_SET */, { key, value, ttl });
563
568
  const keyPrefixed = this._getKeyPrefix(key);
564
- if (typeof ttl === "undefined") {
569
+ if (ttl === void 0) {
565
570
  ttl = this._ttl;
566
571
  }
567
572
  if (ttl === 0) {
@@ -576,7 +581,10 @@ var Keyv = class extends event_manager_default {
576
581
  const serializedValue = await this.serializeData(formattedValue);
577
582
  let result = true;
578
583
  try {
579
- await store.set(keyPrefixed, serializedValue, ttl);
584
+ const value2 = await store.set(keyPrefixed, serializedValue, ttl);
585
+ if (typeof value2 === "boolean") {
586
+ result = value2;
587
+ }
580
588
  } catch (error) {
581
589
  result = false;
582
590
  this.emit("error", error);
@@ -585,6 +593,30 @@ var Keyv = class extends event_manager_default {
585
593
  this.stats.set();
586
594
  return result;
587
595
  }
596
+ /**
597
+ * Set many items to the store
598
+ * @param {Array<KeyvEntry>} entries the entries to set
599
+ * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
600
+ */
601
+ async setMany(entries) {
602
+ let results = [];
603
+ try {
604
+ if (this._store.setMany !== void 0) {
605
+ results = await this._store.setMany(entries);
606
+ return results;
607
+ }
608
+ const promises = [];
609
+ for (const entry of entries) {
610
+ promises.push(this.set(entry.key, entry.value, entry.ttl));
611
+ }
612
+ const promiseResults = await Promise.allSettled(promises);
613
+ results = promiseResults.map((result) => result.value);
614
+ } catch (error) {
615
+ this.emit("error", error);
616
+ results = entries.map(() => false);
617
+ }
618
+ return results;
619
+ }
588
620
  /**
589
621
  * Delete an Entry
590
622
  * @param {string | string[]} key the key to be deleted. if an array it will delete many items
@@ -593,24 +625,47 @@ var Keyv = class extends event_manager_default {
593
625
  async delete(key) {
594
626
  const { store } = this.opts;
595
627
  if (Array.isArray(key)) {
596
- const keyPrefixed2 = this._getKeyPrefixArray(key);
597
- this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed2 });
598
- if (store.deleteMany !== void 0) {
599
- return store.deleteMany(keyPrefixed2);
600
- }
601
- const promises = keyPrefixed2.map(async (key2) => store.delete(key2));
602
- const results = await Promise.allSettled(promises);
603
- const returnResult = results.every((x) => x.value === true);
604
- this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed2, value: returnResult });
605
- return returnResult;
628
+ return this.deleteMany(key);
606
629
  }
607
630
  const keyPrefixed = this._getKeyPrefix(key);
608
631
  this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed });
609
- const result = await store.delete(keyPrefixed);
632
+ let result = true;
633
+ try {
634
+ const value = await store.delete(keyPrefixed);
635
+ if (typeof value === "boolean") {
636
+ result = value;
637
+ }
638
+ } catch (error) {
639
+ result = false;
640
+ this.emit("error", error);
641
+ }
610
642
  this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: result });
611
643
  this.stats.delete();
612
644
  return result;
613
645
  }
646
+ /**
647
+ * Delete many items from the store
648
+ * @param {string[]} keys the keys to be deleted
649
+ * @returns {boolean} will return true if item or items are deleted. false if there is an error
650
+ */
651
+ async deleteMany(keys) {
652
+ try {
653
+ const { store } = this.opts;
654
+ const keyPrefixed = this._getKeyPrefixArray(keys);
655
+ this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed });
656
+ if (store.deleteMany !== void 0) {
657
+ return await store.deleteMany(keyPrefixed);
658
+ }
659
+ const promises = keyPrefixed.map(async (key) => store.delete(key));
660
+ const results = await Promise.allSettled(promises);
661
+ const returnResult = results.every((x) => x.value === true);
662
+ this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: returnResult });
663
+ return returnResult;
664
+ } catch (error) {
665
+ this.emit("error", error);
666
+ return false;
667
+ }
668
+ }
614
669
  /**
615
670
  * Clear the store
616
671
  * @returns {void}
@@ -618,20 +673,27 @@ var Keyv = class extends event_manager_default {
618
673
  async clear() {
619
674
  this.emit("clear");
620
675
  const { store } = this.opts;
621
- await store.clear();
676
+ try {
677
+ await store.clear();
678
+ } catch (error) {
679
+ this.emit("error", error);
680
+ }
622
681
  }
623
- /**
624
- * Has a key
625
- * @param {string} key the key to check
626
- * @returns {boolean} will return true if the key exists
627
- */
628
682
  async has(key) {
683
+ if (Array.isArray(key)) {
684
+ return this.hasMany(key);
685
+ }
629
686
  const keyPrefixed = this._getKeyPrefix(key);
630
687
  const { store } = this.opts;
631
688
  if (store.has !== void 0 && !(store instanceof Map)) {
632
689
  return store.has(keyPrefixed);
633
690
  }
634
- const rawData = await store.get(keyPrefixed);
691
+ let rawData;
692
+ try {
693
+ rawData = await store.get(keyPrefixed);
694
+ } catch (error) {
695
+ this.emit("error", error);
696
+ }
635
697
  if (rawData) {
636
698
  const data = await this.deserializeData(rawData);
637
699
  if (data) {
@@ -643,6 +705,23 @@ var Keyv = class extends event_manager_default {
643
705
  }
644
706
  return false;
645
707
  }
708
+ /**
709
+ * Check if many keys exist
710
+ * @param {string[]} keys the keys to check
711
+ * @returns {boolean[]} will return an array of booleans if the keys exist
712
+ */
713
+ async hasMany(keys) {
714
+ const keyPrefixed = this._getKeyPrefixArray(keys);
715
+ const { store } = this.opts;
716
+ if (store.hasMany !== void 0) {
717
+ return store.hasMany(keyPrefixed);
718
+ }
719
+ const results = [];
720
+ for (const key of keyPrefixed) {
721
+ results.push(await this.has(key));
722
+ }
723
+ return results;
724
+ }
646
725
  /**
647
726
  * Will disconnect the store. This is only available if the store has a disconnect method
648
727
  * @returns {Promise<void>}
@@ -654,6 +733,12 @@ var Keyv = class extends event_manager_default {
654
733
  return store.disconnect();
655
734
  }
656
735
  }
736
+ emit(event, ...arguments_) {
737
+ if (event === "error" && !this.opts.emitErrors) {
738
+ return;
739
+ }
740
+ super.emit(event, ...arguments_);
741
+ }
657
742
  async serializeData(data) {
658
743
  if (!this._serialize) {
659
744
  return data;
@@ -677,7 +762,7 @@ var Keyv = class extends event_manager_default {
677
762
  return void 0;
678
763
  }
679
764
  };
680
- var src_default = Keyv;
765
+ var index_default = Keyv;
681
766
  // Annotate the CommonJS export names for ESM import in node:
682
767
  0 && (module.exports = {
683
768
  Keyv,
package/dist/index.d.cts CHANGED
@@ -44,12 +44,12 @@ type DeserializedData<Value> = {
44
44
  value?: Value;
45
45
  expires?: number | null;
46
46
  };
47
- interface CompressionAdapter {
47
+ type CompressionAdapter = {
48
48
  compress(value: any, options?: any): Promise<any>;
49
49
  decompress(value: any, options?: any): Promise<any>;
50
50
  serialize<Value>(data: DeserializedData<Value>): Promise<string> | string;
51
51
  deserialize<Value>(data: string): Promise<DeserializedData<Value> | undefined> | DeserializedData<Value> | undefined;
52
- }
52
+ };
53
53
  type Serialize = <Value>(data: DeserializedData<Value>) => Promise<string> | string;
54
54
  type Deserialize = <Value>(data: string) => Promise<DeserializedData<Value> | undefined> | DeserializedData<Value> | undefined;
55
55
  declare enum KeyvHooks {
@@ -62,13 +62,27 @@ declare enum KeyvHooks {
62
62
  PRE_DELETE = "preDelete",
63
63
  POST_DELETE = "postDelete"
64
64
  }
65
+ type KeyvEntry = {
66
+ /**
67
+ * Key to set.
68
+ */
69
+ key: string;
70
+ /**
71
+ * Value to set.
72
+ */
73
+ value: any;
74
+ /**
75
+ * Time to live in milliseconds.
76
+ */
77
+ ttl?: number;
78
+ };
65
79
  type StoredDataNoRaw<Value> = Value | undefined;
66
80
  type StoredDataRaw<Value> = DeserializedData<Value> | undefined;
67
81
  type StoredData<Value> = StoredDataNoRaw<Value> | StoredDataRaw<Value>;
68
- interface IEventEmitter {
69
- on(event: string, listener: (...arguments_: any[]) => void): this;
70
- }
71
- interface KeyvStoreAdapter extends IEventEmitter {
82
+ type IEventEmitter = {
83
+ on(event: string, listener: (...arguments_: any[]) => void): IEventEmitter;
84
+ };
85
+ type KeyvStoreAdapter = {
72
86
  opts: any;
73
87
  namespace?: string;
74
88
  get<Value>(key: string): Promise<StoredData<Value> | undefined>;
@@ -76,11 +90,13 @@ interface KeyvStoreAdapter extends IEventEmitter {
76
90
  delete(key: string): Promise<boolean>;
77
91
  clear(): Promise<void>;
78
92
  has?(key: string): Promise<boolean>;
93
+ hasMany?(keys: string[]): Promise<boolean[]>;
79
94
  getMany?<Value>(keys: string[]): Promise<Array<StoredData<Value | undefined>>>;
80
95
  disconnect?(): Promise<void>;
81
96
  deleteMany?(key: string[]): Promise<boolean>;
97
+ setMany?(data: KeyvEntry[]): Promise<boolean[]>;
82
98
  iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
83
- }
99
+ } & IEventEmitter;
84
100
  type KeyvOptions = {
85
101
  /** Emit errors */
86
102
  emitErrors?: boolean;
@@ -216,7 +232,7 @@ declare class Keyv<GenericValue = any> extends EventManager {
216
232
  /**
217
233
  * Get the Value of a Key
218
234
  * @param {string | string[]} key passing in a single key or multiple as an array
219
- * @param [options] can pass in to return the raw value by setting { raw: true }
235
+ * @param {{raw: boolean} | undefined} options can pass in to return the raw value by setting { raw: true }
220
236
  */
221
237
  get<Value = GenericValue>(key: string, options?: {
222
238
  raw: false;
@@ -230,20 +246,44 @@ declare class Keyv<GenericValue = any> extends EventManager {
230
246
  get<Value = GenericValue>(key: string[], options?: {
231
247
  raw: true;
232
248
  }): Promise<Array<StoredDataRaw<Value>>>;
249
+ /**
250
+ * Get many values of keys
251
+ * @param {string[]} keys passing in a single key or multiple as an array
252
+ * @param {{raw: boolean} | undefined} options can pass in to return the raw value by setting { raw: true }
253
+ */
254
+ getMany<Value = GenericValue>(keys: string[], options?: {
255
+ raw: false;
256
+ }): Promise<Array<StoredDataNoRaw<Value>>>;
257
+ getMany<Value = GenericValue>(keys: string[], options?: {
258
+ raw: true;
259
+ }): Promise<Array<StoredDataRaw<Value>>>;
233
260
  /**
234
261
  * Set an item to the store
235
- * @param {string} key the key to use
262
+ * @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
236
263
  * @param {Value} value the value of the key
237
264
  * @param {number} [ttl] time to live in milliseconds
238
265
  * @returns {boolean} if it sets then it will return a true. On failure will return false.
239
266
  */
267
+ set<Value = GenericValue>(key: KeyvEntry[]): Promise<boolean[]>;
240
268
  set<Value = GenericValue>(key: string, value: Value, ttl?: number): Promise<boolean>;
269
+ /**
270
+ * Set many items to the store
271
+ * @param {Array<KeyvEntry>} entries the entries to set
272
+ * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
273
+ */
274
+ setMany<Value = GenericValue>(entries: KeyvEntry[]): Promise<boolean[]>;
241
275
  /**
242
276
  * Delete an Entry
243
277
  * @param {string | string[]} key the key to be deleted. if an array it will delete many items
244
278
  * @returns {boolean} will return true if item or items are deleted. false if there is an error
245
279
  */
246
280
  delete(key: string | string[]): Promise<boolean>;
281
+ /**
282
+ * Delete many items from the store
283
+ * @param {string[]} keys the keys to be deleted
284
+ * @returns {boolean} will return true if item or items are deleted. false if there is an error
285
+ */
286
+ deleteMany(keys: string[]): Promise<boolean>;
247
287
  /**
248
288
  * Clear the store
249
289
  * @returns {void}
@@ -254,14 +294,22 @@ declare class Keyv<GenericValue = any> extends EventManager {
254
294
  * @param {string} key the key to check
255
295
  * @returns {boolean} will return true if the key exists
256
296
  */
297
+ has(key: string[]): Promise<boolean[]>;
257
298
  has(key: string): Promise<boolean>;
299
+ /**
300
+ * Check if many keys exist
301
+ * @param {string[]} keys the keys to check
302
+ * @returns {boolean[]} will return an array of booleans if the keys exist
303
+ */
304
+ hasMany(keys: string[]): Promise<boolean[]>;
258
305
  /**
259
306
  * Will disconnect the store. This is only available if the store has a disconnect method
260
307
  * @returns {Promise<void>}
261
308
  */
262
309
  disconnect(): Promise<void>;
310
+ emit(event: string, ...arguments_: any[]): void;
263
311
  serializeData<T>(data: DeserializedData<T>): Promise<string | DeserializedData<T>>;
264
312
  deserializeData<T>(data: string | DeserializedData<T>): Promise<DeserializedData<T> | undefined>;
265
313
  }
266
314
 
267
- export { type CompressionAdapter, type Deserialize, type DeserializedData, type IEventEmitter, Keyv, KeyvHooks, type KeyvOptions, type KeyvStoreAdapter, type Serialize, type StoredData, type StoredDataNoRaw, type StoredDataRaw, Keyv as default };
315
+ export { type CompressionAdapter, type Deserialize, type DeserializedData, type IEventEmitter, Keyv, type KeyvEntry, KeyvHooks, type KeyvOptions, type KeyvStoreAdapter, type Serialize, type StoredData, type StoredDataNoRaw, type StoredDataRaw, Keyv as default };
package/dist/index.d.ts CHANGED
@@ -44,12 +44,12 @@ type DeserializedData<Value> = {
44
44
  value?: Value;
45
45
  expires?: number | null;
46
46
  };
47
- interface CompressionAdapter {
47
+ type CompressionAdapter = {
48
48
  compress(value: any, options?: any): Promise<any>;
49
49
  decompress(value: any, options?: any): Promise<any>;
50
50
  serialize<Value>(data: DeserializedData<Value>): Promise<string> | string;
51
51
  deserialize<Value>(data: string): Promise<DeserializedData<Value> | undefined> | DeserializedData<Value> | undefined;
52
- }
52
+ };
53
53
  type Serialize = <Value>(data: DeserializedData<Value>) => Promise<string> | string;
54
54
  type Deserialize = <Value>(data: string) => Promise<DeserializedData<Value> | undefined> | DeserializedData<Value> | undefined;
55
55
  declare enum KeyvHooks {
@@ -62,13 +62,27 @@ declare enum KeyvHooks {
62
62
  PRE_DELETE = "preDelete",
63
63
  POST_DELETE = "postDelete"
64
64
  }
65
+ type KeyvEntry = {
66
+ /**
67
+ * Key to set.
68
+ */
69
+ key: string;
70
+ /**
71
+ * Value to set.
72
+ */
73
+ value: any;
74
+ /**
75
+ * Time to live in milliseconds.
76
+ */
77
+ ttl?: number;
78
+ };
65
79
  type StoredDataNoRaw<Value> = Value | undefined;
66
80
  type StoredDataRaw<Value> = DeserializedData<Value> | undefined;
67
81
  type StoredData<Value> = StoredDataNoRaw<Value> | StoredDataRaw<Value>;
68
- interface IEventEmitter {
69
- on(event: string, listener: (...arguments_: any[]) => void): this;
70
- }
71
- interface KeyvStoreAdapter extends IEventEmitter {
82
+ type IEventEmitter = {
83
+ on(event: string, listener: (...arguments_: any[]) => void): IEventEmitter;
84
+ };
85
+ type KeyvStoreAdapter = {
72
86
  opts: any;
73
87
  namespace?: string;
74
88
  get<Value>(key: string): Promise<StoredData<Value> | undefined>;
@@ -76,11 +90,13 @@ interface KeyvStoreAdapter extends IEventEmitter {
76
90
  delete(key: string): Promise<boolean>;
77
91
  clear(): Promise<void>;
78
92
  has?(key: string): Promise<boolean>;
93
+ hasMany?(keys: string[]): Promise<boolean[]>;
79
94
  getMany?<Value>(keys: string[]): Promise<Array<StoredData<Value | undefined>>>;
80
95
  disconnect?(): Promise<void>;
81
96
  deleteMany?(key: string[]): Promise<boolean>;
97
+ setMany?(data: KeyvEntry[]): Promise<boolean[]>;
82
98
  iterator?<Value>(namespace?: string): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;
83
- }
99
+ } & IEventEmitter;
84
100
  type KeyvOptions = {
85
101
  /** Emit errors */
86
102
  emitErrors?: boolean;
@@ -216,7 +232,7 @@ declare class Keyv<GenericValue = any> extends EventManager {
216
232
  /**
217
233
  * Get the Value of a Key
218
234
  * @param {string | string[]} key passing in a single key or multiple as an array
219
- * @param [options] can pass in to return the raw value by setting { raw: true }
235
+ * @param {{raw: boolean} | undefined} options can pass in to return the raw value by setting { raw: true }
220
236
  */
221
237
  get<Value = GenericValue>(key: string, options?: {
222
238
  raw: false;
@@ -230,20 +246,44 @@ declare class Keyv<GenericValue = any> extends EventManager {
230
246
  get<Value = GenericValue>(key: string[], options?: {
231
247
  raw: true;
232
248
  }): Promise<Array<StoredDataRaw<Value>>>;
249
+ /**
250
+ * Get many values of keys
251
+ * @param {string[]} keys passing in a single key or multiple as an array
252
+ * @param {{raw: boolean} | undefined} options can pass in to return the raw value by setting { raw: true }
253
+ */
254
+ getMany<Value = GenericValue>(keys: string[], options?: {
255
+ raw: false;
256
+ }): Promise<Array<StoredDataNoRaw<Value>>>;
257
+ getMany<Value = GenericValue>(keys: string[], options?: {
258
+ raw: true;
259
+ }): Promise<Array<StoredDataRaw<Value>>>;
233
260
  /**
234
261
  * Set an item to the store
235
- * @param {string} key the key to use
262
+ * @param {string | Array<KeyvEntry>} key the key to use. If you pass in an array of KeyvEntry it will set many items
236
263
  * @param {Value} value the value of the key
237
264
  * @param {number} [ttl] time to live in milliseconds
238
265
  * @returns {boolean} if it sets then it will return a true. On failure will return false.
239
266
  */
267
+ set<Value = GenericValue>(key: KeyvEntry[]): Promise<boolean[]>;
240
268
  set<Value = GenericValue>(key: string, value: Value, ttl?: number): Promise<boolean>;
269
+ /**
270
+ * Set many items to the store
271
+ * @param {Array<KeyvEntry>} entries the entries to set
272
+ * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
273
+ */
274
+ setMany<Value = GenericValue>(entries: KeyvEntry[]): Promise<boolean[]>;
241
275
  /**
242
276
  * Delete an Entry
243
277
  * @param {string | string[]} key the key to be deleted. if an array it will delete many items
244
278
  * @returns {boolean} will return true if item or items are deleted. false if there is an error
245
279
  */
246
280
  delete(key: string | string[]): Promise<boolean>;
281
+ /**
282
+ * Delete many items from the store
283
+ * @param {string[]} keys the keys to be deleted
284
+ * @returns {boolean} will return true if item or items are deleted. false if there is an error
285
+ */
286
+ deleteMany(keys: string[]): Promise<boolean>;
247
287
  /**
248
288
  * Clear the store
249
289
  * @returns {void}
@@ -254,14 +294,22 @@ declare class Keyv<GenericValue = any> extends EventManager {
254
294
  * @param {string} key the key to check
255
295
  * @returns {boolean} will return true if the key exists
256
296
  */
297
+ has(key: string[]): Promise<boolean[]>;
257
298
  has(key: string): Promise<boolean>;
299
+ /**
300
+ * Check if many keys exist
301
+ * @param {string[]} keys the keys to check
302
+ * @returns {boolean[]} will return an array of booleans if the keys exist
303
+ */
304
+ hasMany(keys: string[]): Promise<boolean[]>;
258
305
  /**
259
306
  * Will disconnect the store. This is only available if the store has a disconnect method
260
307
  * @returns {Promise<void>}
261
308
  */
262
309
  disconnect(): Promise<void>;
310
+ emit(event: string, ...arguments_: any[]): void;
263
311
  serializeData<T>(data: DeserializedData<T>): Promise<string | DeserializedData<T>>;
264
312
  deserializeData<T>(data: string | DeserializedData<T>): Promise<DeserializedData<T> | undefined>;
265
313
  }
266
314
 
267
- export { type CompressionAdapter, type Deserialize, type DeserializedData, type IEventEmitter, Keyv, KeyvHooks, type KeyvOptions, type KeyvStoreAdapter, type Serialize, type StoredData, type StoredDataNoRaw, type StoredDataRaw, Keyv as default };
315
+ export { type CompressionAdapter, type Deserialize, type DeserializedData, type IEventEmitter, Keyv, type KeyvEntry, KeyvHooks, type KeyvOptions, type KeyvStoreAdapter, type Serialize, type StoredData, type StoredDataNoRaw, type StoredDataRaw, Keyv as default };
package/dist/index.js CHANGED
@@ -267,7 +267,7 @@ var Keyv = class extends event_manager_default {
267
267
  if (!this._isValidStorageAdapter(this._store)) {
268
268
  throw new Error("Invalid storage adapter");
269
269
  }
270
- if (typeof this._store.on === "function" && this.opts.emitErrors) {
270
+ if (typeof this._store.on === "function") {
271
271
  this._store.on("error", (error) => this.emit("error", error));
272
272
  }
273
273
  this._store.namespace = this._namespace;
@@ -301,7 +301,7 @@ var Keyv = class extends event_manager_default {
301
301
  if (this._isValidStorageAdapter(store)) {
302
302
  this._store = store;
303
303
  this.opts.store = store;
304
- if (typeof store.on === "function" && this.opts.emitErrors) {
304
+ if (typeof store.on === "function") {
305
305
  store.on("error", (error) => this.emit("error", error));
306
306
  }
307
307
  if (this._namespace) {
@@ -462,52 +462,10 @@ var Keyv = class extends event_manager_default {
462
462
  const keyPrefixed = isArray ? this._getKeyPrefixArray(key) : this._getKeyPrefix(key);
463
463
  const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
464
464
  if (isArray) {
465
- this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys: keyPrefixed });
466
- if (store.getMany === void 0) {
467
- const promises = keyPrefixed.map(async (key2) => {
468
- const rawData3 = await store.get(key2);
469
- const deserializedRow = typeof rawData3 === "string" || this.opts.compression ? await this.deserializeData(rawData3) : rawData3;
470
- if (deserializedRow === void 0 || deserializedRow === null) {
471
- return void 0;
472
- }
473
- if (isDataExpired(deserializedRow)) {
474
- await this.delete(key2);
475
- return void 0;
476
- }
477
- return options?.raw ? deserializedRow : deserializedRow.value;
478
- });
479
- const deserializedRows = await Promise.allSettled(promises);
480
- const result2 = deserializedRows.map((row) => row.value);
481
- this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
482
- if (result2.length > 0) {
483
- this.stats.hit();
484
- }
485
- return result2;
465
+ if (options?.raw === true) {
466
+ return this.getMany(key, { raw: true });
486
467
  }
487
- const rawData2 = await store.getMany(keyPrefixed);
488
- const result = [];
489
- for (const index in rawData2) {
490
- let row = rawData2[index];
491
- if (typeof row === "string") {
492
- row = await this.deserializeData(row);
493
- }
494
- if (row === void 0 || row === null) {
495
- result.push(void 0);
496
- continue;
497
- }
498
- if (isDataExpired(row)) {
499
- await this.delete(key[index]);
500
- result.push(void 0);
501
- continue;
502
- }
503
- const value = options?.raw ? row : row.value;
504
- result.push(value);
505
- }
506
- this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
507
- if (result.length > 0) {
508
- this.stats.hit();
509
- }
510
- return result;
468
+ return this.getMany(key, { raw: false });
511
469
  }
512
470
  this.hooks.trigger("preGet" /* PRE_GET */, { key: keyPrefixed });
513
471
  const rawData = await store.get(keyPrefixed);
@@ -525,17 +483,64 @@ var Keyv = class extends event_manager_default {
525
483
  this.stats.hit();
526
484
  return options?.raw ? deserializedData : deserializedData.value;
527
485
  }
528
- /**
529
- * Set an item to the store
530
- * @param {string} key the key to use
531
- * @param {Value} value the value of the key
532
- * @param {number} [ttl] time to live in milliseconds
533
- * @returns {boolean} if it sets then it will return a true. On failure will return false.
534
- */
486
+ async getMany(keys, options) {
487
+ const { store } = this.opts;
488
+ const keyPrefixed = this._getKeyPrefixArray(keys);
489
+ const isDataExpired = (data) => typeof data.expires === "number" && Date.now() > data.expires;
490
+ this.hooks.trigger("preGetMany" /* PRE_GET_MANY */, { keys: keyPrefixed });
491
+ if (store.getMany === void 0) {
492
+ const promises = keyPrefixed.map(async (key) => {
493
+ const rawData2 = await store.get(key);
494
+ const deserializedRow = typeof rawData2 === "string" || this.opts.compression ? await this.deserializeData(rawData2) : rawData2;
495
+ if (deserializedRow === void 0 || deserializedRow === null) {
496
+ return void 0;
497
+ }
498
+ if (isDataExpired(deserializedRow)) {
499
+ await this.delete(key);
500
+ return void 0;
501
+ }
502
+ return options?.raw ? deserializedRow : deserializedRow.value;
503
+ });
504
+ const deserializedRows = await Promise.allSettled(promises);
505
+ const result2 = deserializedRows.map((row) => row.value);
506
+ this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result2);
507
+ if (result2.length > 0) {
508
+ this.stats.hit();
509
+ }
510
+ return result2;
511
+ }
512
+ const rawData = await store.getMany(keyPrefixed);
513
+ const result = [];
514
+ for (const index in rawData) {
515
+ let row = rawData[index];
516
+ if (typeof row === "string") {
517
+ row = await this.deserializeData(row);
518
+ }
519
+ if (row === void 0 || row === null) {
520
+ result.push(void 0);
521
+ continue;
522
+ }
523
+ if (isDataExpired(row)) {
524
+ await this.delete(keys[index]);
525
+ result.push(void 0);
526
+ continue;
527
+ }
528
+ const value = options?.raw ? row : row.value;
529
+ result.push(value);
530
+ }
531
+ this.hooks.trigger("postGetMany" /* POST_GET_MANY */, result);
532
+ if (result.length > 0) {
533
+ this.stats.hit();
534
+ }
535
+ return result;
536
+ }
535
537
  async set(key, value, ttl) {
538
+ if (Array.isArray(key)) {
539
+ return this.setMany(key);
540
+ }
536
541
  this.hooks.trigger("preSet" /* PRE_SET */, { key, value, ttl });
537
542
  const keyPrefixed = this._getKeyPrefix(key);
538
- if (typeof ttl === "undefined") {
543
+ if (ttl === void 0) {
539
544
  ttl = this._ttl;
540
545
  }
541
546
  if (ttl === 0) {
@@ -550,7 +555,10 @@ var Keyv = class extends event_manager_default {
550
555
  const serializedValue = await this.serializeData(formattedValue);
551
556
  let result = true;
552
557
  try {
553
- await store.set(keyPrefixed, serializedValue, ttl);
558
+ const value2 = await store.set(keyPrefixed, serializedValue, ttl);
559
+ if (typeof value2 === "boolean") {
560
+ result = value2;
561
+ }
554
562
  } catch (error) {
555
563
  result = false;
556
564
  this.emit("error", error);
@@ -559,6 +567,30 @@ var Keyv = class extends event_manager_default {
559
567
  this.stats.set();
560
568
  return result;
561
569
  }
570
+ /**
571
+ * Set many items to the store
572
+ * @param {Array<KeyvEntry>} entries the entries to set
573
+ * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false.
574
+ */
575
+ async setMany(entries) {
576
+ let results = [];
577
+ try {
578
+ if (this._store.setMany !== void 0) {
579
+ results = await this._store.setMany(entries);
580
+ return results;
581
+ }
582
+ const promises = [];
583
+ for (const entry of entries) {
584
+ promises.push(this.set(entry.key, entry.value, entry.ttl));
585
+ }
586
+ const promiseResults = await Promise.allSettled(promises);
587
+ results = promiseResults.map((result) => result.value);
588
+ } catch (error) {
589
+ this.emit("error", error);
590
+ results = entries.map(() => false);
591
+ }
592
+ return results;
593
+ }
562
594
  /**
563
595
  * Delete an Entry
564
596
  * @param {string | string[]} key the key to be deleted. if an array it will delete many items
@@ -567,24 +599,47 @@ var Keyv = class extends event_manager_default {
567
599
  async delete(key) {
568
600
  const { store } = this.opts;
569
601
  if (Array.isArray(key)) {
570
- const keyPrefixed2 = this._getKeyPrefixArray(key);
571
- this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed2 });
572
- if (store.deleteMany !== void 0) {
573
- return store.deleteMany(keyPrefixed2);
574
- }
575
- const promises = keyPrefixed2.map(async (key2) => store.delete(key2));
576
- const results = await Promise.allSettled(promises);
577
- const returnResult = results.every((x) => x.value === true);
578
- this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed2, value: returnResult });
579
- return returnResult;
602
+ return this.deleteMany(key);
580
603
  }
581
604
  const keyPrefixed = this._getKeyPrefix(key);
582
605
  this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed });
583
- const result = await store.delete(keyPrefixed);
606
+ let result = true;
607
+ try {
608
+ const value = await store.delete(keyPrefixed);
609
+ if (typeof value === "boolean") {
610
+ result = value;
611
+ }
612
+ } catch (error) {
613
+ result = false;
614
+ this.emit("error", error);
615
+ }
584
616
  this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: result });
585
617
  this.stats.delete();
586
618
  return result;
587
619
  }
620
+ /**
621
+ * Delete many items from the store
622
+ * @param {string[]} keys the keys to be deleted
623
+ * @returns {boolean} will return true if item or items are deleted. false if there is an error
624
+ */
625
+ async deleteMany(keys) {
626
+ try {
627
+ const { store } = this.opts;
628
+ const keyPrefixed = this._getKeyPrefixArray(keys);
629
+ this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed });
630
+ if (store.deleteMany !== void 0) {
631
+ return await store.deleteMany(keyPrefixed);
632
+ }
633
+ const promises = keyPrefixed.map(async (key) => store.delete(key));
634
+ const results = await Promise.allSettled(promises);
635
+ const returnResult = results.every((x) => x.value === true);
636
+ this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed, value: returnResult });
637
+ return returnResult;
638
+ } catch (error) {
639
+ this.emit("error", error);
640
+ return false;
641
+ }
642
+ }
588
643
  /**
589
644
  * Clear the store
590
645
  * @returns {void}
@@ -592,20 +647,27 @@ var Keyv = class extends event_manager_default {
592
647
  async clear() {
593
648
  this.emit("clear");
594
649
  const { store } = this.opts;
595
- await store.clear();
650
+ try {
651
+ await store.clear();
652
+ } catch (error) {
653
+ this.emit("error", error);
654
+ }
596
655
  }
597
- /**
598
- * Has a key
599
- * @param {string} key the key to check
600
- * @returns {boolean} will return true if the key exists
601
- */
602
656
  async has(key) {
657
+ if (Array.isArray(key)) {
658
+ return this.hasMany(key);
659
+ }
603
660
  const keyPrefixed = this._getKeyPrefix(key);
604
661
  const { store } = this.opts;
605
662
  if (store.has !== void 0 && !(store instanceof Map)) {
606
663
  return store.has(keyPrefixed);
607
664
  }
608
- const rawData = await store.get(keyPrefixed);
665
+ let rawData;
666
+ try {
667
+ rawData = await store.get(keyPrefixed);
668
+ } catch (error) {
669
+ this.emit("error", error);
670
+ }
609
671
  if (rawData) {
610
672
  const data = await this.deserializeData(rawData);
611
673
  if (data) {
@@ -617,6 +679,23 @@ var Keyv = class extends event_manager_default {
617
679
  }
618
680
  return false;
619
681
  }
682
+ /**
683
+ * Check if many keys exist
684
+ * @param {string[]} keys the keys to check
685
+ * @returns {boolean[]} will return an array of booleans if the keys exist
686
+ */
687
+ async hasMany(keys) {
688
+ const keyPrefixed = this._getKeyPrefixArray(keys);
689
+ const { store } = this.opts;
690
+ if (store.hasMany !== void 0) {
691
+ return store.hasMany(keyPrefixed);
692
+ }
693
+ const results = [];
694
+ for (const key of keyPrefixed) {
695
+ results.push(await this.has(key));
696
+ }
697
+ return results;
698
+ }
620
699
  /**
621
700
  * Will disconnect the store. This is only available if the store has a disconnect method
622
701
  * @returns {Promise<void>}
@@ -628,6 +707,12 @@ var Keyv = class extends event_manager_default {
628
707
  return store.disconnect();
629
708
  }
630
709
  }
710
+ emit(event, ...arguments_) {
711
+ if (event === "error" && !this.opts.emitErrors) {
712
+ return;
713
+ }
714
+ super.emit(event, ...arguments_);
715
+ }
631
716
  async serializeData(data) {
632
717
  if (!this._serialize) {
633
718
  return data;
@@ -651,9 +736,9 @@ var Keyv = class extends event_manager_default {
651
736
  return void 0;
652
737
  }
653
738
  };
654
- var src_default = Keyv;
739
+ var index_default = Keyv;
655
740
  export {
656
741
  Keyv,
657
742
  KeyvHooks,
658
- src_default as default
743
+ index_default as default
659
744
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keyv",
3
- "version": "5.2.2",
3
+ "version": "5.3.0",
4
4
  "description": "Simple key-value storage with support for multiple backends",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -14,27 +14,12 @@
14
14
  },
15
15
  "xo": {
16
16
  "rules": {
17
- "import/no-named-as-default": "off",
18
- "unicorn/prefer-module": "off",
19
- "unicorn/prefer-node-protocol": "off",
20
- "@typescript-eslint/consistent-type-definitions": "off",
21
- "unicorn/no-typeof-undefined": "off",
22
- "unicorn/prefer-event-target": "off",
23
- "import/no-extraneous-dependencies": "off",
24
- "import/extensions": "off",
25
17
  "@typescript-eslint/ban-ts-comment": "off",
26
18
  "@typescript-eslint/no-unsafe-call": "off",
27
- "@typescript-eslint/no-for-in-array": "off",
28
- "guard-for-in": "off",
29
- "no-await-in-loop": "off",
30
19
  "@typescript-eslint/no-unsafe-return": "off",
31
20
  "@typescript-eslint/no-unsafe-assignment": "off",
32
21
  "@typescript-eslint/no-unsafe-argument": "off",
33
- "@typescript-eslint/naming-convention": "off",
34
- "@typescript-eslint/consistent-type-assertions": "off",
35
- "@typescript-eslint/no-confusing-void-expression": "off",
36
- "@typescript-eslint/no-var-requires": "off",
37
- "@typescript-eslint/prefer-ts-expect-error": "off"
22
+ "@typescript-eslint/no-confusing-void-expression": "off"
38
23
  }
39
24
  },
40
25
  "repository": {
@@ -69,19 +54,23 @@
69
54
  },
70
55
  "homepage": "https://github.com/jaredwray/keyv",
71
56
  "dependencies": {
72
- "@keyv/serialize": "^1.0.1"
57
+ "@keyv/serialize": "^1.0.3"
73
58
  },
74
59
  "devDependencies": {
60
+ "@faker-js/faker": "^9.5.1",
61
+ "@vitest/coverage-v8": "^3.0.7",
75
62
  "rimraf": "^6.0.1",
76
63
  "timekeeper": "^2.3.1",
77
64
  "tsd": "^0.31.2",
65
+ "vitest": "^3.0.7",
78
66
  "xo": "^0.60.0",
79
- "@keyv/mongo": "^3.0.1",
67
+ "@keyv/compress-brotli": "^2.0.3",
80
68
  "@keyv/compress-gzip": "^2.0.2",
81
- "@keyv/test-suite": "^2.0.3",
82
- "@keyv/sqlite": "^4.0.1",
83
69
  "@keyv/memcache": "^2.0.1",
84
- "@keyv/compress-brotli": "^2.0.2"
70
+ "@keyv/compress-lz4": "^1.0.0",
71
+ "@keyv/mongo": "^3.0.1",
72
+ "@keyv/sqlite": "^4.0.1",
73
+ "@keyv/test-suite": "^2.0.5"
85
74
  },
86
75
  "tsd": {
87
76
  "directory": "test"