keyv 6.0.0-alpha.2 → 6.0.0-alpha.3

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
@@ -19,7 +19,7 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
19
19
  - Suitable as a TTL based cache or persistent key-value store
20
20
  - [Easily embeddable](#add-cache-support-to-your-module) inside another module
21
21
  - Works with any storage that implements the [`Map`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map) API
22
- - Handles all JSON types plus `Buffer`
22
+ - Handles all JSON types plus `Buffer` and `BigInt` via the built-in `KeyvJsonSerializer`
23
23
  - Supports namespaces
24
24
  - Wide range of [**efficient, well tested**](#official-storage-adapters) storage adapters
25
25
  - Connection errors are passed through (db failures won't kill your app)
@@ -32,7 +32,7 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
32
32
  - [Namespaces](#namespaces)
33
33
  - [Events](#events)
34
34
  - [Hooks](#hooks)
35
- - [Custom Serializers](#custom-serializers)
35
+ - [Serialization](#serialization)
36
36
  - [Official Storage Adapters](#official-storage-adapters)
37
37
  - [Third-party Storage Adapters](#third-party-storage-adapters)
38
38
  - [Using BigMap to Scale](#using-bigmap-to-scale)
@@ -42,10 +42,11 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
42
42
  - [.namespace](#namespace)
43
43
  - [.ttl](#ttl)
44
44
  - [.store](#store)
45
- - [.serialize](#serialize)
46
- - [.deserialize](#deserialize)
45
+ - [.serialization](#serialization-1)
47
46
  - [.compression](#compression)
48
47
  - [.useKeyPrefix](#usekeyprefix)
48
+ - [.emitErrors](#emiterrors)
49
+ - [.throwOnErrors](#throwonerrors)
49
50
  - [.stats](#stats)
50
51
  - [Keyv Instance](#keyv-instance)
51
52
  - [.set(key, value, [ttl])](#setkey-value-ttl)
@@ -54,9 +55,14 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
54
55
  - [.getMany(keys, [options])](#getmanykeys-options)
55
56
  - [.getRaw(key)](#getrawkey)
56
57
  - [.getManyRaw(keys)](#getmanyrawkeys)
58
+ - [.setRaw(key, value, [ttl])](#setrawkey-value-ttl)
59
+ - [.setManyRaw(entries)](#setmanyrawentries)
57
60
  - [.delete(key)](#deletekey)
58
61
  - [.deleteMany(keys)](#deletemanykeys)
59
62
  - [.clear()](#clear)
63
+ - [.has(key)](#haskey)
64
+ - [.hasMany(keys)](#hasmanykeys)
65
+ - [.disconnect()](#disconnect)
60
66
  - [.iterator()](#iterator)
61
67
  - [Bun Support](#bun-support)
62
68
  - [How to Contribute](#how-to-contribute)
@@ -219,6 +225,10 @@ PRE_GET_MANY_RAW
219
225
  POST_GET_MANY_RAW
220
226
  PRE_SET
221
227
  POST_SET
228
+ PRE_SET_RAW
229
+ POST_SET_RAW
230
+ PRE_SET_MANY_RAW
231
+ POST_SET_MANY_RAW
222
232
  PRE_DELETE
223
233
  POST_DELETE
224
234
  ```
@@ -288,26 +298,60 @@ Now this key will have prefix- added to it before it is set.
288
298
  In `PRE_DELETE` and `POST_DELETE` hooks, the value could be a single item or an `Array`. This is based on the fact that `delete` can accept a single key or an `Array` of keys.
289
299
 
290
300
 
291
- # Custom Serializers
301
+ # Serialization
292
302
 
293
- Keyv uses [`buffer`](https://nodejs.org/api/buffer.html) for data serialization to ensure consistency across different backends.
303
+ By default, Keyv uses its built-in `KeyvJsonSerializer` — a JSON-based serializer with support for `Buffer` and `BigInt` types. This works out of the box with all storage adapters.
294
304
 
295
- You can optionally provide your own serialization functions to support extra data types or to serialize to something other than JSON.
305
+ ## Custom Serializers
306
+
307
+ You can provide your own serializer by implementing the `KeyvSerializationAdapter` interface:
308
+
309
+ ```typescript
310
+ interface KeyvSerializationAdapter {
311
+ stringify: (object: unknown) => string | Promise<string>;
312
+ parse: <T>(data: string) => T | Promise<T>;
313
+ }
314
+ ```
315
+
316
+ For example, using the built-in `JSON` object:
296
317
 
297
318
  ```js
298
- const keyv = new Keyv({ serialize: JSON.stringify, deserialize: JSON.parse });
319
+ const keyv = new Keyv({
320
+ serialization: { stringify: JSON.stringify, parse: JSON.parse },
321
+ });
322
+ ```
323
+
324
+ Or a custom async serializer:
325
+
326
+ ```js
327
+ const keyv = new Keyv({
328
+ serialization: {
329
+ stringify: async (value) => JSON.stringify(value),
330
+ parse: async (data) => JSON.parse(data),
331
+ },
332
+ });
299
333
  ```
300
334
 
301
- **Warning:** Using custom serializers means you lose any guarantee of data consistency. You should do extensive testing with your serialisation functions and chosen storage engine.
335
+ **Warning:** Using custom serializers means you lose any guarantee of data consistency. You should do extensive testing with your serialization functions and chosen storage engine.
302
336
 
303
- If you do not want to use serialization you can set the `serialize` and `deserialize` functions to `undefined`. This will also turn off compression.
337
+ ## Disabling Serialization
338
+
339
+ You can disable serialization entirely by passing `false`. This stores data as raw objects, which works for in-memory `Map` storage where string conversion is not needed:
304
340
 
305
341
  ```js
306
- const keyv = new Keyv();
307
- keyv.serialize = undefined;
308
- keyv.deserialize = undefined;
342
+ const keyv = new Keyv({ serialization: false });
309
343
  ```
310
344
 
345
+ ## Pipeline
346
+
347
+ When serialization and/or compression are configured, Keyv applies them in this order:
348
+
349
+ **On set:** serialize (optional) → compress (optional) → store
350
+
351
+ **On get:** store → decompress (optional) → parse (optional) → value
352
+
353
+ If compression is configured without a serializer, Keyv will use `JSON.stringify`/`JSON.parse` as a minimum fallback since compression adapters require string input.
354
+
311
355
  # Official Storage Adapters
312
356
 
313
357
  The official storage adapters are covered by [over 150 integration tests](https://github.com/jaredwray/keyv/actions/workflows/tests.yaml) to guarantee consistent behaviour. They are lightweight, efficient wrappers over the DB clients making use of indexes and native TTLs where available.
@@ -411,7 +455,7 @@ await keyv.delete('user:1');
411
455
  await keyv.clear();
412
456
  ```
413
457
 
414
- For more details about BigMap, see the [@keyv/bigmap documentation](https://github.com/jaredwray/keyv/tree/main/storage/bigmap).
458
+ For more details about BigMap, see the [@keyv/bigmap documentation](https://github.com/jaredwray/keyv/tree/main/core/bigmap).
415
459
 
416
460
  # Compression
417
461
 
@@ -443,16 +487,14 @@ const keyv = new Keyv({ compression: keyvLz4 });
443
487
 
444
488
  You can also pass a custom compression function to the `compression` option. Following the pattern of the official compression adapters.
445
489
 
446
- ## Want to build your own CompressionAdapter?
490
+ ## Want to build your own KeyvCompressionAdapter?
447
491
 
448
492
  Great! Keyv is designed to be easily extended. You can build your own compression adapter by following the pattern of the official compression adapters based on this interface:
449
493
 
450
494
  ```typescript
451
- interface CompressionAdapter {
452
- async compress(value: any, options?: any);
453
- async decompress(value: any, options?: any);
454
- async serialize(value: any);
455
- async deserialize(value: any);
495
+ interface KeyvCompressionAdapter {
496
+ compress(value: any, options?: any): Promise<any>;
497
+ decompress(value: any, options?: any): Promise<any>;
456
498
  }
457
499
  ```
458
500
 
@@ -465,6 +507,17 @@ import KeyvGzip from '@keyv/compress-gzip';
465
507
  keyvCompresstionTests(test, new KeyvGzip());
466
508
  ```
467
509
 
510
+ # Encryption
511
+
512
+ Keyv provides a `KeyvEncryptionAdapter` interface for encryption support. This interface is available for custom implementations but is not yet wired into the core pipeline.
513
+
514
+ ```typescript
515
+ interface KeyvEncryptionAdapter {
516
+ encrypt: (data: string) => string | Promise<string>;
517
+ decrypt: (data: string) => string | Promise<string>;
518
+ }
519
+ ```
520
+
468
521
  # API
469
522
 
470
523
  ## new Keyv([storage-adapter], [options]) or new Keyv([options])
@@ -478,9 +531,7 @@ The Keyv instance is also an `EventEmitter` that will emit an `'error'` event if
478
531
  Type: `KeyvStorageAdapter`<br />
479
532
  Default: `undefined`
480
533
 
481
- The connection string URI.
482
-
483
- Merged into the options object as options.uri.
534
+ The storage adapter instance to be used by Keyv.
484
535
 
485
536
  ## .namespace
486
537
 
@@ -511,24 +562,17 @@ Default TTL. Can be overridden by specififying a TTL on `.set()`.
511
562
 
512
563
  ## options.compression
513
564
 
514
- Type: `@keyv/compress-<compression_package_name>`<br />
565
+ Type: `KeyvCompressionAdapter`<br />
515
566
  Default: `undefined`
516
567
 
517
568
  Compression package to use. See [Compression](#compression) for more details.
518
569
 
519
- ## options.serialize
520
-
521
- Type: `Function`<br />
522
- Default: `JSON.stringify`
523
-
524
- A custom serialization function.
570
+ ## options.serialization
525
571
 
526
- ## options.deserialize
572
+ Type: `KeyvSerializationAdapter | false`<br />
573
+ Default: `KeyvJsonSerializer` (built-in)
527
574
 
528
- Type: `Function`<br />
529
- Default: `JSON.parse`
530
-
531
- A custom deserialization function.
575
+ A serialization object with `stringify` and `parse` methods. Set to `false` to disable serialization and store raw objects. See [Serialization](#serialization) for more details.
532
576
 
533
577
  ## options.store
534
578
 
@@ -561,24 +605,48 @@ Returns a promise which resolves to the retrieved value.
561
605
 
562
606
  Returns a promise which resolves to an array of retrieved values.
563
607
 
564
- ### options.raw - (Will be deprecated in v6)
608
+ ## .getRaw(key)
565
609
 
566
- Type: `Boolean`<br />
567
- Default: `false`
610
+ Returns a promise which resolves to the raw stored data for the key or `undefined` if the key does not exist or is expired.
568
611
 
569
- If set to true the raw DB object Keyv stores internally will be returned instead of just the value.
612
+ ## .getManyRaw(keys)
570
613
 
571
- This contains the TTL timestamp.
614
+ Returns a promise which resolves to an array of raw stored data for the keys or `undefined` if the key does not exist or is expired.
572
615
 
573
- NOTE: This option will be deprecated in v6 and replaced with `.getRaw()` and `.getManyRaw()` methods.
616
+ ## .setRaw(key, value, [ttl])
574
617
 
575
- ## .getRaw(key)
618
+ Sets a raw value in the store without wrapping. This is the write-side counterpart to `.getRaw()`. The caller provides the `DeserializedData` envelope directly (`{ value, expires? }`) instead of having Keyv wrap it. The envelope is still serialized before storing so that all read paths (`get()`, `getRaw()`, `has()`, `getManyRaw()`) work consistently. If `expires` is not set in the value and `ttl` is provided, `expires` will be computed from `ttl`.
576
619
 
577
- Returns a promise which resolves to the raw stored data for the key or `undefined` if the key does not exist or is expired.
620
+ Returns a promise which resolves to `true`.
578
621
 
579
- ## .getManyRaw(keys)
622
+ ```js
623
+ const keyv = new Keyv();
580
624
 
581
- Returns a promise which resolves to an array of raw stored data for the keys or `undefined` if the key does not exist or is expired.
625
+ // Set a raw value directly
626
+ await keyv.setRaw('foo', { value: 'bar', expires: Date.now() + 60000 });
627
+
628
+ // Round-trip: get raw, modify, set raw
629
+ const raw = await keyv.getRaw('foo');
630
+ raw.value = 'updated';
631
+ await keyv.setRaw('foo', raw);
632
+
633
+ // TTL computes expires automatically if not set
634
+ await keyv.setRaw('foo', { value: 'bar' }, 60000);
635
+ ```
636
+
637
+ ## .setManyRaw(entries)
638
+
639
+ Sets many raw values in the store without wrapping. Each entry should have a `key`, a `value` (`DeserializedData` envelope), and an optional `ttl`. Like `setRaw()`, the envelopes are serialized before storing.
640
+
641
+ Returns a promise which resolves to an array of booleans.
642
+
643
+ ```js
644
+ const keyv = new Keyv();
645
+ await keyv.setManyRaw([
646
+ { key: 'foo', value: { value: 'bar' } },
647
+ { key: 'baz', value: { value: 'qux', expires: Date.now() + 60000 } },
648
+ ]);
649
+ ```
582
650
 
583
651
  ## .delete(key)
584
652
 
@@ -588,7 +656,7 @@ Returns a promise which resolves to `true` if the key existed, `false` if not.
588
656
 
589
657
  ## .deleteMany(keys)
590
658
  Deletes multiple entries.
591
- Returns a promise which resolves to an array of booleans indicating if the key existed or not.
659
+ Returns a promise which resolves to `true` if all keys were deleted successfully, `false` otherwise.
592
660
 
593
661
  ## .clear()
594
662
 
@@ -596,6 +664,39 @@ Delete all entries in the current namespace.
596
664
 
597
665
  Returns a promise which is resolved when the entries have been cleared.
598
666
 
667
+ ## .has(key)
668
+
669
+ Check if a key exists in the store.
670
+
671
+ Returns a promise which resolves to `true` if the key exists, `false` if not.
672
+
673
+ ```js
674
+ await keyv.set('foo', 'bar');
675
+ await keyv.has('foo'); // true
676
+ await keyv.has('unknown'); // false
677
+ ```
678
+
679
+ ## .hasMany(keys)
680
+
681
+ Check if multiple keys exist in the store.
682
+
683
+ Returns a promise which resolves to an array of booleans indicating if each key exists.
684
+
685
+ ```js
686
+ await keyv.set('foo', 'bar');
687
+ await keyv.hasMany(['foo', 'unknown']); // [true, false]
688
+ ```
689
+
690
+ ## .disconnect()
691
+
692
+ Disconnect from the storage adapter. Emits a `'disconnect'` event.
693
+
694
+ Returns a promise which is resolved when the connection has been closed.
695
+
696
+ ```js
697
+ await keyv.disconnect();
698
+ ```
699
+
599
700
  ## .iterator()
600
701
 
601
702
  Iterate over all entries of the current namespace.
@@ -660,40 +761,26 @@ keyv.store = new KeyvSqlite('sqlite://path/to/database.sqlite');
660
761
  console.log(keyv.store instanceof KeyvSqlite); // true
661
762
  ```
662
763
 
663
- ## .serialize
664
-
665
- Type: `Function`<br />
666
- Default: `JSON.stringify`
667
-
668
- A custom serialization function used for any value.
669
-
670
- ```js
671
- const keyv = new Keyv();
672
- console.log(keyv.serialize); // JSON.stringify
673
- keyv.serialize = value => value.toString();
674
- console.log(keyv.serialize); // value => value.toString()
675
- ```
676
-
677
- ## .deserialize
764
+ ## .serialization
678
765
 
679
- Type: `Function`<br />
680
- Default: `JSON.parse`
766
+ Type: `KeyvSerializationAdapter | false | undefined`<br />
767
+ Default: `KeyvJsonSerializer` (built-in)
681
768
 
682
- A custom deserialization function used for any value.
769
+ The serialization object used for storing and retrieving values. Set to `false` or `undefined` to disable serialization and use raw object pass-through. See [Serialization](#serialization) for more details.
683
770
 
684
771
  ```js
685
772
  const keyv = new Keyv();
686
- console.log(keyv.deserialize); // JSON.parse
687
- keyv.deserialize = value => parseInt(value);
688
- console.log(keyv.deserialize); // value => parseInt(value)
773
+ console.log(keyv.serialization); // KeyvJsonSerializer (default)
774
+ keyv.serialization = false; // disable serialization
775
+ console.log(keyv.serialization); // undefined
689
776
  ```
690
777
 
691
778
  ## .compression
692
779
 
693
- Type: `CompressionAdapter`<br />
780
+ Type: `KeyvCompressionAdapter`<br />
694
781
  Default: `undefined`
695
782
 
696
- this is the compression package to use. See [Compression](#compression) for more details. If it is undefined it will not compress (default).
783
+ This is the compression package to use. See [Compression](#compression) for more details. If it is undefined it will not compress (default).
697
784
 
698
785
  ```js
699
786
  import KeyvGzip from '@keyv/compress-gzip';
@@ -734,6 +821,20 @@ await keyv.get('foo'); // 'bar'
734
821
  await keyv.clear();
735
822
  ```
736
823
 
824
+ ## .emitErrors
825
+
826
+ Type: `Boolean`<br />
827
+ Default: `true`
828
+
829
+ If set to `true`, Keyv will emit an `'error'` event when an error occurs. Set to `false` to suppress error events.
830
+
831
+ ```js
832
+ const keyv = new Keyv({ emitErrors: false });
833
+ console.log(keyv.emitErrors); // false
834
+ keyv.emitErrors = true;
835
+ console.log(keyv.emitErrors); // true
836
+ ```
837
+
737
838
  ## .throwOnErrors
738
839
 
739
840
  Type: `Boolean`<br />