keyv 5.2.3 → 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
@@ -289,14 +289,30 @@ The following are third-party storage adapters compatible with Keyv:
289
289
 
290
290
  # Compression
291
291
 
292
- 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.
293
293
 
294
294
  ```js
295
295
  import Keyv from 'keyv';
296
296
  import KeyvGzip from '@keyv/compress-gzip';
297
297
 
298
298
  const keyvGzip = new KeyvGzip();
299
- 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 });
300
316
  ```
301
317
 
302
318
  You can also pass a custom compression function to the `compression` option. Following the pattern of the official compression adapters.
@@ -407,10 +423,18 @@ By default keys are persistent. You can set an expiry TTL in milliseconds.
407
423
 
408
424
  Returns a promise which resolves to `true`.
409
425
 
426
+ ## .setMany(entries)
427
+
428
+ Set multiple values using KeyvEntrys `{ key: string, value: any, ttl?: number }`.
429
+
410
430
  ## .get(key, [options])
411
431
 
412
432
  Returns a promise which resolves to the retrieved value.
413
433
 
434
+ ## .getMany(keys, [options])
435
+
436
+ Returns a promise which resolves to an array of retrieved values.
437
+
414
438
  ### options.raw
415
439
 
416
440
  Type: `Boolean`<br />
@@ -426,6 +450,10 @@ Deletes an entry.
426
450
 
427
451
  Returns a promise which resolves to `true` if the key existed, `false` if not.
428
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
+
429
457
  ## .clear()
430
458
 
431
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
@@ -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;
512
- }
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();
491
+ if (options?.raw === true) {
492
+ return this.getMany(key, { raw: true });
535
493
  }
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) {
@@ -588,6 +593,30 @@ var Keyv = class extends event_manager_default {
588
593
  this.stats.set();
589
594
  return result;
590
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
+ }
591
620
  /**
592
621
  * Delete an Entry
593
622
  * @param {string | string[]} key the key to be deleted. if an array it will delete many items
@@ -596,16 +625,7 @@ var Keyv = class extends event_manager_default {
596
625
  async delete(key) {
597
626
  const { store } = this.opts;
598
627
  if (Array.isArray(key)) {
599
- const keyPrefixed2 = this._getKeyPrefixArray(key);
600
- this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed2 });
601
- if (store.deleteMany !== void 0) {
602
- return store.deleteMany(keyPrefixed2);
603
- }
604
- const promises = keyPrefixed2.map(async (key2) => store.delete(key2));
605
- const results = await Promise.allSettled(promises);
606
- const returnResult = results.every((x) => x.value === true);
607
- this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed2, value: returnResult });
608
- return returnResult;
628
+ return this.deleteMany(key);
609
629
  }
610
630
  const keyPrefixed = this._getKeyPrefix(key);
611
631
  this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed });
@@ -623,6 +643,29 @@ var Keyv = class extends event_manager_default {
623
643
  this.stats.delete();
624
644
  return result;
625
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
+ }
626
669
  /**
627
670
  * Clear the store
628
671
  * @returns {void}
@@ -636,12 +679,10 @@ var Keyv = class extends event_manager_default {
636
679
  this.emit("error", error);
637
680
  }
638
681
  }
639
- /**
640
- * Has a key
641
- * @param {string} key the key to check
642
- * @returns {boolean} will return true if the key exists
643
- */
644
682
  async has(key) {
683
+ if (Array.isArray(key)) {
684
+ return this.hasMany(key);
685
+ }
645
686
  const keyPrefixed = this._getKeyPrefix(key);
646
687
  const { store } = this.opts;
647
688
  if (store.has !== void 0 && !(store instanceof Map)) {
@@ -664,6 +705,23 @@ var Keyv = class extends event_manager_default {
664
705
  }
665
706
  return false;
666
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
+ }
667
725
  /**
668
726
  * Will disconnect the store. This is only available if the store has a disconnect method
669
727
  * @returns {Promise<void>}
@@ -704,7 +762,7 @@ var Keyv = class extends event_manager_default {
704
762
  return void 0;
705
763
  }
706
764
  };
707
- var src_default = Keyv;
765
+ var index_default = Keyv;
708
766
  // Annotate the CommonJS export names for ESM import in node:
709
767
  0 && (module.exports = {
710
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,7 +294,14 @@ 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>}
@@ -265,4 +312,4 @@ declare class Keyv<GenericValue = any> extends EventManager {
265
312
  deserializeData<T>(data: string | DeserializedData<T>): Promise<DeserializedData<T> | undefined>;
266
313
  }
267
314
 
268
- 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,7 +294,14 @@ 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>}
@@ -265,4 +312,4 @@ declare class Keyv<GenericValue = any> extends EventManager {
265
312
  deserializeData<T>(data: string | DeserializedData<T>): Promise<DeserializedData<T> | undefined>;
266
313
  }
267
314
 
268
- 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
@@ -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;
486
- }
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();
465
+ if (options?.raw === true) {
466
+ return this.getMany(key, { raw: true });
509
467
  }
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) {
@@ -562,6 +567,30 @@ var Keyv = class extends event_manager_default {
562
567
  this.stats.set();
563
568
  return result;
564
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
+ }
565
594
  /**
566
595
  * Delete an Entry
567
596
  * @param {string | string[]} key the key to be deleted. if an array it will delete many items
@@ -570,16 +599,7 @@ var Keyv = class extends event_manager_default {
570
599
  async delete(key) {
571
600
  const { store } = this.opts;
572
601
  if (Array.isArray(key)) {
573
- const keyPrefixed2 = this._getKeyPrefixArray(key);
574
- this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed2 });
575
- if (store.deleteMany !== void 0) {
576
- return store.deleteMany(keyPrefixed2);
577
- }
578
- const promises = keyPrefixed2.map(async (key2) => store.delete(key2));
579
- const results = await Promise.allSettled(promises);
580
- const returnResult = results.every((x) => x.value === true);
581
- this.hooks.trigger("postDelete" /* POST_DELETE */, { key: keyPrefixed2, value: returnResult });
582
- return returnResult;
602
+ return this.deleteMany(key);
583
603
  }
584
604
  const keyPrefixed = this._getKeyPrefix(key);
585
605
  this.hooks.trigger("preDelete" /* PRE_DELETE */, { key: keyPrefixed });
@@ -597,6 +617,29 @@ var Keyv = class extends event_manager_default {
597
617
  this.stats.delete();
598
618
  return result;
599
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
+ }
600
643
  /**
601
644
  * Clear the store
602
645
  * @returns {void}
@@ -610,12 +653,10 @@ var Keyv = class extends event_manager_default {
610
653
  this.emit("error", error);
611
654
  }
612
655
  }
613
- /**
614
- * Has a key
615
- * @param {string} key the key to check
616
- * @returns {boolean} will return true if the key exists
617
- */
618
656
  async has(key) {
657
+ if (Array.isArray(key)) {
658
+ return this.hasMany(key);
659
+ }
619
660
  const keyPrefixed = this._getKeyPrefix(key);
620
661
  const { store } = this.opts;
621
662
  if (store.has !== void 0 && !(store instanceof Map)) {
@@ -638,6 +679,23 @@ var Keyv = class extends event_manager_default {
638
679
  }
639
680
  return false;
640
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
+ }
641
699
  /**
642
700
  * Will disconnect the store. This is only available if the store has a disconnect method
643
701
  * @returns {Promise<void>}
@@ -678,9 +736,9 @@ var Keyv = class extends event_manager_default {
678
736
  return void 0;
679
737
  }
680
738
  };
681
- var src_default = Keyv;
739
+ var index_default = Keyv;
682
740
  export {
683
741
  Keyv,
684
742
  KeyvHooks,
685
- src_default as default
743
+ index_default as default
686
744
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keyv",
3
- "version": "5.2.3",
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.2"
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/compress-brotli": "^2.0.2",
67
+ "@keyv/compress-brotli": "^2.0.3",
80
68
  "@keyv/compress-gzip": "^2.0.2",
81
69
  "@keyv/memcache": "^2.0.1",
70
+ "@keyv/compress-lz4": "^1.0.0",
82
71
  "@keyv/mongo": "^3.0.1",
83
72
  "@keyv/sqlite": "^4.0.1",
84
- "@keyv/test-suite": "^2.0.3"
73
+ "@keyv/test-suite": "^2.0.5"
85
74
  },
86
75
  "tsd": {
87
76
  "directory": "test"