keyv 5.5.3 → 5.5.5
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 +107 -7
- package/dist/index.cjs +19 -2
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +4 -4
- package/dist/index.js +19 -2
- package/package.json +20 -14
package/README.md
CHANGED
|
@@ -34,6 +34,7 @@ There are a few existing modules similar to Keyv, however Keyv is different beca
|
|
|
34
34
|
- [Custom Serializers](#custom-serializers)
|
|
35
35
|
- [Official Storage Adapters](#official-storage-adapters)
|
|
36
36
|
- [Third-party Storage Adapters](#third-party-storage-adapters)
|
|
37
|
+
- [Using BigMap to Scale](#using-bigmap-to-scale)
|
|
37
38
|
- [Compression](#compression)
|
|
38
39
|
- [API](#api)
|
|
39
40
|
- [new Keyv([storage-adapter], [options]) or new Keyv([options])](#new-keyvstorage-adapter-options-or-new-keyvoptions)
|
|
@@ -208,8 +209,12 @@ Keyv supports hooks for `get`, `set`, and `delete` methods. Hooks are useful for
|
|
|
208
209
|
```
|
|
209
210
|
PRE_GET
|
|
210
211
|
POST_GET
|
|
212
|
+
PRE_GET_RAW
|
|
213
|
+
POST_GET_RAW
|
|
211
214
|
PRE_GET_MANY
|
|
212
215
|
POST_GET_MANY
|
|
216
|
+
PRE_GET_MANY_RAW
|
|
217
|
+
POST_GET_MANY_RAW
|
|
213
218
|
PRE_SET
|
|
214
219
|
POST_SET
|
|
215
220
|
PRE_DELETE
|
|
@@ -222,6 +227,37 @@ You can access this by importing `KeyvHooks` from the main Keyv package.
|
|
|
222
227
|
import Keyv, { KeyvHooks } from 'keyv';
|
|
223
228
|
```
|
|
224
229
|
|
|
230
|
+
## Get Hooks
|
|
231
|
+
|
|
232
|
+
The `POST_GET` and `POST_GET_RAW` hooks fire on both cache hits and misses. When a cache miss occurs (key doesn't exist or is expired), the hooks receive `undefined` as the value.
|
|
233
|
+
|
|
234
|
+
```js
|
|
235
|
+
// POST_GET hook - fires on both hits and misses
|
|
236
|
+
const keyv = new Keyv();
|
|
237
|
+
keyv.hooks.addHandler(KeyvHooks.POST_GET, (data) => {
|
|
238
|
+
if (data.value === undefined) {
|
|
239
|
+
console.log(`Cache miss for key: ${data.key}`);
|
|
240
|
+
} else {
|
|
241
|
+
console.log(`Cache hit for key: ${data.key}`, data.value);
|
|
242
|
+
}
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
await keyv.get('existing-key'); // Logs cache hit with value
|
|
246
|
+
await keyv.get('missing-key'); // Logs cache miss with undefined
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```js
|
|
250
|
+
// POST_GET_RAW hook - same behavior as POST_GET
|
|
251
|
+
const keyv = new Keyv();
|
|
252
|
+
keyv.hooks.addHandler(KeyvHooks.POST_GET_RAW, (data) => {
|
|
253
|
+
console.log(`Key: ${data.key}, Value:`, data.value);
|
|
254
|
+
});
|
|
255
|
+
|
|
256
|
+
await keyv.getRaw('foo'); // Logs with value or undefined
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
## Set Hooks
|
|
260
|
+
|
|
225
261
|
```js
|
|
226
262
|
//PRE_SET hook
|
|
227
263
|
const keyv = new Keyv();
|
|
@@ -245,6 +281,8 @@ keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data) => {
|
|
|
245
281
|
|
|
246
282
|
Now this key will have prefix- added to it before it is set.
|
|
247
283
|
|
|
284
|
+
## Delete Hooks
|
|
285
|
+
|
|
248
286
|
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.
|
|
249
287
|
|
|
250
288
|
|
|
@@ -313,16 +351,78 @@ const keyv = new Keyv({ store: lru });
|
|
|
313
351
|
|
|
314
352
|
The following are third-party storage adapters compatible with Keyv:
|
|
315
353
|
|
|
316
|
-
- [
|
|
354
|
+
- [@resolid/keyv-sqlite](https://github.com/huijiewei/keyv-sqlite) - A new SQLite storage adapter for Keyv
|
|
355
|
+
- [keyv-arango](https://github.com/TimMikeladze/keyv-arango) - ArangoDB storage adapter for Keyv
|
|
356
|
+
- [keyv-azuretable](https://github.com/howlowck/keyv-azuretable) - Azure Table Storage/API adapter for Keyv
|
|
357
|
+
- [keyv-browser](https://github.com/zaaack/keyv-browser) - Browser storage adapter for Keyv, including localStorage and indexedDB.
|
|
358
|
+
- [keyv-cloudflare](https://npm.im/keyv-cloudflare) - Storage adapter for Cloudflare Workers KV
|
|
359
|
+
- [keyv-dynamodb](https://www.npmjs.com/package/keyv-dynamodb) - DynamoDB storage adapter for Keyv
|
|
317
360
|
- [keyv-file](https://github.com/zaaack/keyv-file) - File system storage adapter for Keyv
|
|
318
|
-
- [keyv-lru](https://www.npmjs.com/package/keyv-lru) - LRU storage adapter for Keyv
|
|
319
|
-
- [keyv-null](https://www.npmjs.com/package/keyv-null) - Null storage adapter for Keyv
|
|
320
361
|
- [keyv-firestore ](https://github.com/goto-bus-stop/keyv-firestore) – Firebase Cloud Firestore adapter for Keyv
|
|
321
|
-
- [keyv-
|
|
322
|
-
- [keyv-azuretable](https://github.com/howlowck/keyv-azuretable) - Azure Table Storage/API adapter for Keyv
|
|
323
|
-
- [keyv-arango](https://github.com/TimMikeladze/keyv-arango) - ArangoDB storage adapter for Keyv
|
|
362
|
+
- [keyv-lru](https://www.npmjs.com/package/keyv-lru) - LRU storage adapter for Keyv
|
|
324
363
|
- [keyv-momento](https://github.com/momentohq/node-keyv-adaptor/) - Momento storage adapter for Keyv
|
|
325
|
-
- [
|
|
364
|
+
- [keyv-mssql](https://github.com/pmorgan3/keyv-mssql) - Microsoft Sql Server adapter for Keyv
|
|
365
|
+
- [keyv-null](https://www.npmjs.com/package/keyv-null) - Null storage adapter for Keyv
|
|
366
|
+
- [keyv-upstash](https://github.com/mahdavipanah/keyv-upstash) - Upstash Redis adapter for Keyv
|
|
367
|
+
- [quick-lru](https://github.com/sindresorhus/quick-lru) - Simple "Least Recently Used" (LRU) cache
|
|
368
|
+
|
|
369
|
+
# Using BigMap to Scale
|
|
370
|
+
|
|
371
|
+
## Understanding JavaScript Map Limitations
|
|
372
|
+
|
|
373
|
+
JavaScript's built-in `Map` object has a practical limit of approximately **16.7 million entries** (2^24). When you try to store more entries than this limit, you'll encounter performance degradation or runtime errors. This limitation is due to how JavaScript engines internally manage Map objects.
|
|
374
|
+
|
|
375
|
+
For applications that need to cache millions of entries in memory, this becomes a significant constraint. Common scenarios include:
|
|
376
|
+
- High-traffic caching layers
|
|
377
|
+
- Session stores for large-scale applications
|
|
378
|
+
- In-memory data processing of large datasets
|
|
379
|
+
- Real-time analytics with millions of data points
|
|
380
|
+
|
|
381
|
+
## Why BigMap?
|
|
382
|
+
|
|
383
|
+
`@keyv/bigmap` solves this limitation by using a **distributed hash approach** with multiple internal Map instances. Instead of storing all entries in a single Map, BigMap distributes entries across multiple Maps using a hash function. This allows you to scale beyond the 16.7 million entry limit while maintaining the familiar Map API.
|
|
384
|
+
|
|
385
|
+
### Key Benefits:
|
|
386
|
+
- **Scales beyond Map limits**: Store 20+ million entries without issues
|
|
387
|
+
- **Map-compatible API**: Drop-in replacement for standard Map
|
|
388
|
+
- **Performance**: Uses efficient DJB2 hashing for fast key distribution
|
|
389
|
+
- **Type-safe**: Built with TypeScript and supports generics
|
|
390
|
+
- **Customizable**: Configure store size and hash functions
|
|
391
|
+
|
|
392
|
+
## Using BigMap with Keyv
|
|
393
|
+
|
|
394
|
+
BigMap can be used directly with Keyv as a storage adapter, providing scalable in-memory storage with full TTL support.
|
|
395
|
+
|
|
396
|
+
### Installation
|
|
397
|
+
|
|
398
|
+
```bash
|
|
399
|
+
npm install --save keyv @keyv/bigmap
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
### Basic Usage
|
|
403
|
+
|
|
404
|
+
The simplest way to use BigMap with Keyv is through the `createKeyv` helper function:
|
|
405
|
+
|
|
406
|
+
```js
|
|
407
|
+
import { createKeyv } from '@keyv/bigmap';
|
|
408
|
+
|
|
409
|
+
const keyv = createKeyv();
|
|
410
|
+
|
|
411
|
+
// Set values with TTL (time in milliseconds)
|
|
412
|
+
await keyv.set('user:1', { name: 'Alice', email: 'alice@example.com' }, 60000); // Expires in 60 seconds
|
|
413
|
+
|
|
414
|
+
// Get values
|
|
415
|
+
const user = await keyv.get('user:1');
|
|
416
|
+
console.log(user); // { name: 'Alice', email: 'alice@example.com' }
|
|
417
|
+
|
|
418
|
+
// Delete values
|
|
419
|
+
await keyv.delete('user:1');
|
|
420
|
+
|
|
421
|
+
// Clear all values
|
|
422
|
+
await keyv.clear();
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
For more details about BigMap, see the [@keyv/bigmap documentation](https://github.com/jaredwray/keyv/tree/main/packages/bigmap).
|
|
326
426
|
|
|
327
427
|
# Compression
|
|
328
428
|
|
package/dist/index.cjs
CHANGED
|
@@ -394,14 +394,14 @@ var Keyv = class extends event_manager_default {
|
|
|
394
394
|
}
|
|
395
395
|
/**
|
|
396
396
|
* Get the current TTL.
|
|
397
|
-
* @returns {number} The current TTL.
|
|
397
|
+
* @returns {number} The current TTL in milliseconds.
|
|
398
398
|
*/
|
|
399
399
|
get ttl() {
|
|
400
400
|
return this._ttl;
|
|
401
401
|
}
|
|
402
402
|
/**
|
|
403
403
|
* Set the current TTL.
|
|
404
|
-
* @param {number} ttl The TTL to set.
|
|
404
|
+
* @param {number} ttl The TTL to set in milliseconds.
|
|
405
405
|
*/
|
|
406
406
|
set ttl(ttl) {
|
|
407
407
|
this.opts.ttl = ttl;
|
|
@@ -540,11 +540,19 @@ var Keyv = class extends event_manager_default {
|
|
|
540
540
|
}
|
|
541
541
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
542
542
|
if (deserializedData === void 0 || deserializedData === null) {
|
|
543
|
+
this.hooks.trigger("postGet" /* POST_GET */, {
|
|
544
|
+
key: keyPrefixed,
|
|
545
|
+
value: void 0
|
|
546
|
+
});
|
|
543
547
|
this.stats.miss();
|
|
544
548
|
return void 0;
|
|
545
549
|
}
|
|
546
550
|
if (isDataExpired(deserializedData)) {
|
|
547
551
|
await this.delete(key);
|
|
552
|
+
this.hooks.trigger("postGet" /* POST_GET */, {
|
|
553
|
+
key: keyPrefixed,
|
|
554
|
+
value: void 0
|
|
555
|
+
});
|
|
548
556
|
this.stats.miss();
|
|
549
557
|
return void 0;
|
|
550
558
|
}
|
|
@@ -624,12 +632,20 @@ var Keyv = class extends event_manager_default {
|
|
|
624
632
|
this.hooks.trigger("preGetRaw" /* PRE_GET_RAW */, { key: keyPrefixed });
|
|
625
633
|
const rawData = await store.get(keyPrefixed);
|
|
626
634
|
if (rawData === void 0 || rawData === null) {
|
|
635
|
+
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, {
|
|
636
|
+
key: keyPrefixed,
|
|
637
|
+
value: void 0
|
|
638
|
+
});
|
|
627
639
|
this.stats.miss();
|
|
628
640
|
return void 0;
|
|
629
641
|
}
|
|
630
642
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
631
643
|
if (deserializedData !== void 0 && deserializedData.expires !== void 0 && deserializedData.expires !== null && // biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
632
644
|
deserializedData.expires < Date.now()) {
|
|
645
|
+
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, {
|
|
646
|
+
key: keyPrefixed,
|
|
647
|
+
value: void 0
|
|
648
|
+
});
|
|
633
649
|
this.stats.miss();
|
|
634
650
|
await this.delete(key);
|
|
635
651
|
return void 0;
|
|
@@ -968,3 +984,4 @@ var index_default = Keyv;
|
|
|
968
984
|
Keyv,
|
|
969
985
|
KeyvHooks
|
|
970
986
|
});
|
|
987
|
+
/* v8 ignore next -- @preserve */
|
package/dist/index.d.cts
CHANGED
|
@@ -89,7 +89,7 @@ type IEventEmitter = {
|
|
|
89
89
|
};
|
|
90
90
|
type KeyvStoreAdapter = {
|
|
91
91
|
opts: any;
|
|
92
|
-
namespace?: string;
|
|
92
|
+
namespace?: string | undefined;
|
|
93
93
|
get<Value>(key: string): Promise<StoredData<Value> | undefined>;
|
|
94
94
|
set(key: string, value: any, ttl?: number): any;
|
|
95
95
|
setMany?(values: Array<{
|
|
@@ -133,7 +133,7 @@ type KeyvOptions = {
|
|
|
133
133
|
*/
|
|
134
134
|
store?: KeyvStoreAdapter | Map<any, any> | any;
|
|
135
135
|
/**
|
|
136
|
-
* Default TTL. Can be overridden by specifying a TTL on `.set()`.
|
|
136
|
+
* Default TTL in milliseconds. Can be overridden by specifying a TTL on `.set()`.
|
|
137
137
|
* @default undefined
|
|
138
138
|
*/
|
|
139
139
|
ttl?: number;
|
|
@@ -226,12 +226,12 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
226
226
|
set namespace(namespace: string | undefined);
|
|
227
227
|
/**
|
|
228
228
|
* Get the current TTL.
|
|
229
|
-
* @returns {number} The current TTL.
|
|
229
|
+
* @returns {number} The current TTL in milliseconds.
|
|
230
230
|
*/
|
|
231
231
|
get ttl(): number | undefined;
|
|
232
232
|
/**
|
|
233
233
|
* Set the current TTL.
|
|
234
|
-
* @param {number} ttl The TTL to set.
|
|
234
|
+
* @param {number} ttl The TTL to set in milliseconds.
|
|
235
235
|
*/
|
|
236
236
|
set ttl(ttl: number | undefined);
|
|
237
237
|
/**
|
package/dist/index.d.ts
CHANGED
|
@@ -89,7 +89,7 @@ type IEventEmitter = {
|
|
|
89
89
|
};
|
|
90
90
|
type KeyvStoreAdapter = {
|
|
91
91
|
opts: any;
|
|
92
|
-
namespace?: string;
|
|
92
|
+
namespace?: string | undefined;
|
|
93
93
|
get<Value>(key: string): Promise<StoredData<Value> | undefined>;
|
|
94
94
|
set(key: string, value: any, ttl?: number): any;
|
|
95
95
|
setMany?(values: Array<{
|
|
@@ -133,7 +133,7 @@ type KeyvOptions = {
|
|
|
133
133
|
*/
|
|
134
134
|
store?: KeyvStoreAdapter | Map<any, any> | any;
|
|
135
135
|
/**
|
|
136
|
-
* Default TTL. Can be overridden by specifying a TTL on `.set()`.
|
|
136
|
+
* Default TTL in milliseconds. Can be overridden by specifying a TTL on `.set()`.
|
|
137
137
|
* @default undefined
|
|
138
138
|
*/
|
|
139
139
|
ttl?: number;
|
|
@@ -226,12 +226,12 @@ declare class Keyv<GenericValue = any> extends EventManager {
|
|
|
226
226
|
set namespace(namespace: string | undefined);
|
|
227
227
|
/**
|
|
228
228
|
* Get the current TTL.
|
|
229
|
-
* @returns {number} The current TTL.
|
|
229
|
+
* @returns {number} The current TTL in milliseconds.
|
|
230
230
|
*/
|
|
231
231
|
get ttl(): number | undefined;
|
|
232
232
|
/**
|
|
233
233
|
* Set the current TTL.
|
|
234
|
-
* @param {number} ttl The TTL to set.
|
|
234
|
+
* @param {number} ttl The TTL to set in milliseconds.
|
|
235
235
|
*/
|
|
236
236
|
set ttl(ttl: number | undefined);
|
|
237
237
|
/**
|
package/dist/index.js
CHANGED
|
@@ -368,14 +368,14 @@ var Keyv = class extends event_manager_default {
|
|
|
368
368
|
}
|
|
369
369
|
/**
|
|
370
370
|
* Get the current TTL.
|
|
371
|
-
* @returns {number} The current TTL.
|
|
371
|
+
* @returns {number} The current TTL in milliseconds.
|
|
372
372
|
*/
|
|
373
373
|
get ttl() {
|
|
374
374
|
return this._ttl;
|
|
375
375
|
}
|
|
376
376
|
/**
|
|
377
377
|
* Set the current TTL.
|
|
378
|
-
* @param {number} ttl The TTL to set.
|
|
378
|
+
* @param {number} ttl The TTL to set in milliseconds.
|
|
379
379
|
*/
|
|
380
380
|
set ttl(ttl) {
|
|
381
381
|
this.opts.ttl = ttl;
|
|
@@ -514,11 +514,19 @@ var Keyv = class extends event_manager_default {
|
|
|
514
514
|
}
|
|
515
515
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
516
516
|
if (deserializedData === void 0 || deserializedData === null) {
|
|
517
|
+
this.hooks.trigger("postGet" /* POST_GET */, {
|
|
518
|
+
key: keyPrefixed,
|
|
519
|
+
value: void 0
|
|
520
|
+
});
|
|
517
521
|
this.stats.miss();
|
|
518
522
|
return void 0;
|
|
519
523
|
}
|
|
520
524
|
if (isDataExpired(deserializedData)) {
|
|
521
525
|
await this.delete(key);
|
|
526
|
+
this.hooks.trigger("postGet" /* POST_GET */, {
|
|
527
|
+
key: keyPrefixed,
|
|
528
|
+
value: void 0
|
|
529
|
+
});
|
|
522
530
|
this.stats.miss();
|
|
523
531
|
return void 0;
|
|
524
532
|
}
|
|
@@ -598,12 +606,20 @@ var Keyv = class extends event_manager_default {
|
|
|
598
606
|
this.hooks.trigger("preGetRaw" /* PRE_GET_RAW */, { key: keyPrefixed });
|
|
599
607
|
const rawData = await store.get(keyPrefixed);
|
|
600
608
|
if (rawData === void 0 || rawData === null) {
|
|
609
|
+
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, {
|
|
610
|
+
key: keyPrefixed,
|
|
611
|
+
value: void 0
|
|
612
|
+
});
|
|
601
613
|
this.stats.miss();
|
|
602
614
|
return void 0;
|
|
603
615
|
}
|
|
604
616
|
const deserializedData = typeof rawData === "string" || this.opts.compression ? await this.deserializeData(rawData) : rawData;
|
|
605
617
|
if (deserializedData !== void 0 && deserializedData.expires !== void 0 && deserializedData.expires !== null && // biome-ignore lint/style/noNonNullAssertion: need to fix
|
|
606
618
|
deserializedData.expires < Date.now()) {
|
|
619
|
+
this.hooks.trigger("postGetRaw" /* POST_GET_RAW */, {
|
|
620
|
+
key: keyPrefixed,
|
|
621
|
+
value: void 0
|
|
622
|
+
});
|
|
607
623
|
this.stats.miss();
|
|
608
624
|
await this.delete(key);
|
|
609
625
|
return void 0;
|
|
@@ -942,3 +958,4 @@ export {
|
|
|
942
958
|
KeyvHooks,
|
|
943
959
|
index_default as default
|
|
944
960
|
};
|
|
961
|
+
/* v8 ignore next -- @preserve */
|
package/package.json
CHANGED
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keyv",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.5",
|
|
4
4
|
"description": "Simple key-value storage with support for multiple backends",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "dist/index.
|
|
6
|
+
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
8
8
|
"types": "dist/index.d.ts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
-
"require":
|
|
12
|
-
|
|
11
|
+
"require": {
|
|
12
|
+
"types": "./dist/index.d.cts",
|
|
13
|
+
"default": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"import": {
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
|
+
}
|
|
13
19
|
}
|
|
14
20
|
},
|
|
15
21
|
"repository": {
|
|
@@ -47,20 +53,20 @@
|
|
|
47
53
|
"@keyv/serialize": "^1.1.1"
|
|
48
54
|
},
|
|
49
55
|
"devDependencies": {
|
|
50
|
-
"@biomejs/biome": "^2.
|
|
51
|
-
"@faker-js/faker": "^10.
|
|
52
|
-
"@vitest/coverage-v8": "^
|
|
53
|
-
"rimraf": "^6.
|
|
56
|
+
"@biomejs/biome": "^2.3.8",
|
|
57
|
+
"@faker-js/faker": "^10.1.0",
|
|
58
|
+
"@vitest/coverage-v8": "^4.0.14",
|
|
59
|
+
"rimraf": "^6.1.2",
|
|
54
60
|
"timekeeper": "^2.3.1",
|
|
55
61
|
"tsd": "^0.33.0",
|
|
56
|
-
"vitest": "^
|
|
57
|
-
"@keyv/mongo": "^3.0.
|
|
58
|
-
"@keyv/compress-gzip": "^2.0.3",
|
|
59
|
-
"@keyv/compress-lz4": "^1.0.1",
|
|
62
|
+
"vitest": "^4.0.14",
|
|
63
|
+
"@keyv/mongo": "^3.0.5",
|
|
60
64
|
"@keyv/memcache": "^2.0.2",
|
|
61
|
-
"@keyv/sqlite": "^4.0.5",
|
|
62
65
|
"@keyv/compress-brotli": "^2.0.5",
|
|
63
|
-
"@keyv/
|
|
66
|
+
"@keyv/sqlite": "^4.0.6",
|
|
67
|
+
"@keyv/compress-lz4": "^1.0.1",
|
|
68
|
+
"@keyv/compress-gzip": "^2.0.3",
|
|
69
|
+
"@keyv/test-suite": "^2.1.2"
|
|
64
70
|
},
|
|
65
71
|
"tsd": {
|
|
66
72
|
"directory": "test"
|