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 +170 -69
- package/dist/index.cjs +266 -147
- package/dist/index.d.cts +71 -68
- package/dist/index.d.ts +71 -68
- package/dist/index.js +263 -148
- package/package.json +1 -4
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
|
-
- [
|
|
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
|
-
- [.
|
|
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
|
-
#
|
|
301
|
+
# Serialization
|
|
292
302
|
|
|
293
|
-
Keyv uses
|
|
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
|
-
|
|
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({
|
|
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
|
|
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
|
-
|
|
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/
|
|
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
|
|
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
|
|
452
|
-
|
|
453
|
-
|
|
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
|
|
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:
|
|
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.
|
|
520
|
-
|
|
521
|
-
Type: `Function`<br />
|
|
522
|
-
Default: `JSON.stringify`
|
|
523
|
-
|
|
524
|
-
A custom serialization function.
|
|
570
|
+
## options.serialization
|
|
525
571
|
|
|
526
|
-
|
|
572
|
+
Type: `KeyvSerializationAdapter | false`<br />
|
|
573
|
+
Default: `KeyvJsonSerializer` (built-in)
|
|
527
574
|
|
|
528
|
-
|
|
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
|
-
|
|
608
|
+
## .getRaw(key)
|
|
565
609
|
|
|
566
|
-
|
|
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
|
-
|
|
612
|
+
## .getManyRaw(keys)
|
|
570
613
|
|
|
571
|
-
|
|
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
|
-
|
|
616
|
+
## .setRaw(key, value, [ttl])
|
|
574
617
|
|
|
575
|
-
|
|
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
|
|
620
|
+
Returns a promise which resolves to `true`.
|
|
578
621
|
|
|
579
|
-
|
|
622
|
+
```js
|
|
623
|
+
const keyv = new Keyv();
|
|
580
624
|
|
|
581
|
-
|
|
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
|
|
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
|
-
## .
|
|
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: `
|
|
680
|
-
Default: `
|
|
766
|
+
Type: `KeyvSerializationAdapter | false | undefined`<br />
|
|
767
|
+
Default: `KeyvJsonSerializer` (built-in)
|
|
681
768
|
|
|
682
|
-
|
|
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.
|
|
687
|
-
keyv.
|
|
688
|
-
console.log(keyv.
|
|
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: `
|
|
780
|
+
Type: `KeyvCompressionAdapter`<br />
|
|
694
781
|
Default: `undefined`
|
|
695
782
|
|
|
696
|
-
|
|
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 />
|