keyv 6.0.0-beta.3 → 6.0.0-beta.4
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/LICENSE +0 -10
- package/README.md +203 -136
- package/dist/index.cjs +162 -82
- package/dist/index.d.cts +158 -61
- package/dist/index.d.mts +158 -61
- package/dist/index.mjs +162 -83
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -173,6 +173,26 @@ function detectKeyvStorage(obj) {
|
|
|
173
173
|
};
|
|
174
174
|
}
|
|
175
175
|
/**
|
|
176
|
+
* Build the capability descriptor for a v6 storage adapter: the structurally detected
|
|
177
|
+
* methods plus `expires: true`, declaring that the adapter accepts an absolute `expires`
|
|
178
|
+
* timestamp on `set`/`setMany`. First-party adapters expose this from their `capabilities`
|
|
179
|
+
* getter so Keyv uses them directly instead of bridging.
|
|
180
|
+
* @param adapter - The storage adapter to describe (typically `this`).
|
|
181
|
+
* @returns A {@link KeyvStorageCapability} with `expires` set to `true`.
|
|
182
|
+
* @example
|
|
183
|
+
* ```typescript
|
|
184
|
+
* public get capabilities(): KeyvStorageCapability {
|
|
185
|
+
* return keyvStorageCapability(this);
|
|
186
|
+
* }
|
|
187
|
+
* ```
|
|
188
|
+
*/
|
|
189
|
+
function keyvStorageCapability(adapter) {
|
|
190
|
+
return {
|
|
191
|
+
...detectKeyvStorage(adapter),
|
|
192
|
+
expires: true
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
176
196
|
* Detect whether an object implements the Keyv compression adapter interface
|
|
177
197
|
* @param obj - The object to check
|
|
178
198
|
* @returns A {@link KeyvCompressionCapability} where `compatible` is `true` when both `compress` and `decompress` methods are present
|
|
@@ -475,6 +495,12 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
475
495
|
_keySeparator = ":";
|
|
476
496
|
_capabilities;
|
|
477
497
|
/**
|
|
498
|
+
* Whether the wrapped store manages its own namespace (exposes a `namespace` property).
|
|
499
|
+
* When true the bridge propagates its namespace to the store and does not prefix keys,
|
|
500
|
+
* so the store's native, namespace-scoped operations (notably `clear()`) are used directly.
|
|
501
|
+
*/
|
|
502
|
+
_storeHandlesNamespace;
|
|
503
|
+
/**
|
|
478
504
|
* Creates a new KeyvBridgeAdapter instance.
|
|
479
505
|
* @param store - The underlying promise-based store to bridge
|
|
480
506
|
* @param options - Configuration options for the adapter
|
|
@@ -482,9 +508,11 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
482
508
|
constructor(store, options) {
|
|
483
509
|
super({ throwOnHookError: false });
|
|
484
510
|
this._store = store;
|
|
511
|
+
this._capabilities = detectKeyvStorage(store);
|
|
512
|
+
this._storeHandlesNamespace = this._capabilities.store === "keyvStorage" && "namespace" in store;
|
|
485
513
|
if (options?.keySeparator) this._keySeparator = options.keySeparator;
|
|
486
514
|
if (options?.namespace) this._namespace = options.namespace;
|
|
487
|
-
this.
|
|
515
|
+
if (this._storeHandlesNamespace) this._store.namespace = this._namespace;
|
|
488
516
|
if (typeof store.on === "function") store.on("error", (error) => this.emit("error", error));
|
|
489
517
|
}
|
|
490
518
|
/**
|
|
@@ -500,10 +528,15 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
500
528
|
this._store = store;
|
|
501
529
|
}
|
|
502
530
|
/**
|
|
503
|
-
* Gets the
|
|
531
|
+
* Gets the capabilities of the underlying store, with `expires: true` to declare that
|
|
532
|
+
* the bridge accepts an absolute `expires` timestamp (which it converts to a ttl for the
|
|
533
|
+
* wrapped legacy store).
|
|
504
534
|
*/
|
|
505
535
|
get capabilities() {
|
|
506
|
-
return
|
|
536
|
+
return {
|
|
537
|
+
...this._capabilities,
|
|
538
|
+
expires: true
|
|
539
|
+
};
|
|
507
540
|
}
|
|
508
541
|
/**
|
|
509
542
|
* Gets the current key separator used between namespace and key.
|
|
@@ -524,10 +557,12 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
524
557
|
return this._namespace;
|
|
525
558
|
}
|
|
526
559
|
/**
|
|
527
|
-
* Sets the namespace.
|
|
560
|
+
* Sets the namespace. When the wrapped store manages its own namespace, the value is
|
|
561
|
+
* propagated to it so its native scoped operations stay in sync.
|
|
528
562
|
*/
|
|
529
563
|
set namespace(namespace) {
|
|
530
564
|
this._namespace = namespace;
|
|
565
|
+
if (this._storeHandlesNamespace) this._store.namespace = namespace;
|
|
531
566
|
}
|
|
532
567
|
/**
|
|
533
568
|
* Creates a prefixed key by combining the namespace and key with the separator.
|
|
@@ -536,6 +571,7 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
536
571
|
* @returns The prefixed key if namespace is provided, otherwise the original key
|
|
537
572
|
*/
|
|
538
573
|
getKeyPrefix(key, namespace) {
|
|
574
|
+
if (this._storeHandlesNamespace) return key;
|
|
539
575
|
if (namespace) return `${namespace}${this._keySeparator}${key}`;
|
|
540
576
|
return key;
|
|
541
577
|
}
|
|
@@ -601,35 +637,49 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
601
637
|
return values;
|
|
602
638
|
}
|
|
603
639
|
/**
|
|
604
|
-
* Stores a value in the store with an optional
|
|
640
|
+
* Stores a value in the store with an optional absolute expiry.
|
|
641
|
+
* The wrapped store's `set(key, value, ttl?)` expects a relative duration, so the absolute
|
|
642
|
+
* `expires` is converted to a remaining ttl (`undefined` when already expired or absent).
|
|
643
|
+
* The value is passed through unchanged — the bridge does not wrap it in an envelope — so
|
|
644
|
+
* expiry is enforced by the wrapped legacy store's own ttl handling. (The read-side
|
|
645
|
+
* {@link isDataExpired} check only fires when a caller stores a raw `{ value, expires }`
|
|
646
|
+
* object directly; when Keyv core drives the bridge the value arrives already encoded.)
|
|
605
647
|
* @param key - The key to store the value under
|
|
606
648
|
* @param value - The value to store
|
|
607
|
-
* @param
|
|
649
|
+
* @param expires - Optional absolute expiry as Unix ms since epoch
|
|
608
650
|
* @returns Always returns true indicating success
|
|
609
651
|
*/
|
|
610
|
-
async set(key, value,
|
|
652
|
+
async set(key, value, expires) {
|
|
611
653
|
const keyPrefix = this.getKeyPrefix(key, this._namespace);
|
|
612
|
-
|
|
654
|
+
if (typeof expires === "number" && expires <= Date.now()) {
|
|
655
|
+
await this._store.delete(keyPrefix);
|
|
656
|
+
return true;
|
|
657
|
+
}
|
|
658
|
+
const result = await this._store.set(keyPrefix, value, ttlFromExpires(expires));
|
|
613
659
|
if (typeof result === "boolean") return result;
|
|
614
660
|
return true;
|
|
615
661
|
}
|
|
616
662
|
/**
|
|
617
663
|
* Stores multiple entries in the store at once.
|
|
618
664
|
* Delegates to the store's native setMany if available, otherwise loops over set.
|
|
619
|
-
* @param entries - Array of entries containing key, value, and optional
|
|
665
|
+
* @param entries - Array of entries containing key, value, and optional absolute `expires`
|
|
620
666
|
*/
|
|
621
667
|
async setMany(entries) {
|
|
622
668
|
if (this._capabilities.methods.setMany.exists) {
|
|
623
|
-
const
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
669
|
+
const now = Date.now();
|
|
670
|
+
const isExpired = (entry) => typeof entry.expires === "number" && entry.expires <= now;
|
|
671
|
+
const live = entries.filter((entry) => !isExpired(entry));
|
|
672
|
+
if (live.length > 0) await this._store.setMany?.(live.map((entry) => ({
|
|
673
|
+
key: this.getKeyPrefix(entry.key, this._namespace),
|
|
674
|
+
value: entry.value,
|
|
675
|
+
ttl: ttlFromExpires(entry.expires)
|
|
676
|
+
})));
|
|
677
|
+
for (const entry of entries) if (isExpired(entry)) await this._store.delete(this.getKeyPrefix(entry.key, this._namespace));
|
|
628
678
|
return entries.map(() => true);
|
|
629
679
|
}
|
|
630
680
|
const results = [];
|
|
631
681
|
for (const entry of entries) {
|
|
632
|
-
await this.set(entry.key, entry.value, entry.
|
|
682
|
+
await this.set(entry.key, entry.value, entry.expires);
|
|
633
683
|
results.push(true);
|
|
634
684
|
}
|
|
635
685
|
return results;
|
|
@@ -703,6 +753,10 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
703
753
|
* entire store is cleared.
|
|
704
754
|
*/
|
|
705
755
|
async clear() {
|
|
756
|
+
if (this._namespace && this._storeHandlesNamespace) {
|
|
757
|
+
await this._store.clear();
|
|
758
|
+
return;
|
|
759
|
+
}
|
|
706
760
|
if (!this._namespace || !this._capabilities.methods.iterator.exists) {
|
|
707
761
|
await this._store.clear();
|
|
708
762
|
return;
|
|
@@ -724,7 +778,7 @@ var KeyvBridgeAdapter = class extends Hookified {
|
|
|
724
778
|
async *iterator() {
|
|
725
779
|
if (!this._capabilities.methods.iterator.exists) return;
|
|
726
780
|
const namespace = this._namespace;
|
|
727
|
-
const prefix = namespace ? `${namespace}${this._keySeparator}` : void 0;
|
|
781
|
+
const prefix = namespace && !this._storeHandlesNamespace ? `${namespace}${this._keySeparator}` : void 0;
|
|
728
782
|
/* v8 ignore next -- @preserve */
|
|
729
783
|
for await (const entry of this._store.iterator?.(this._namespace) ?? []) {
|
|
730
784
|
const [key, data] = Array.isArray(entry) ? entry : [entry];
|
|
@@ -1164,6 +1218,29 @@ var KeyvStats = class {
|
|
|
1164
1218
|
//#endregion
|
|
1165
1219
|
//#region src/keyv.ts
|
|
1166
1220
|
var Keyv = class Keyv extends Hookified {
|
|
1221
|
+
/**
|
|
1222
|
+
* Keyv Constructor
|
|
1223
|
+
* @param {KeyvStorageAdapter | KeyvOptions} store
|
|
1224
|
+
* @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options
|
|
1225
|
+
*/
|
|
1226
|
+
constructor(store, options) {
|
|
1227
|
+
const mergedOptions = Keyv.resolveOptions(store, options);
|
|
1228
|
+
super({
|
|
1229
|
+
throwOnHookError: false,
|
|
1230
|
+
throwOnEmptyListeners: true,
|
|
1231
|
+
throwOnEmitError: mergedOptions.throwOnErrors ?? false
|
|
1232
|
+
});
|
|
1233
|
+
this.deprecatedHooks = buildDeprecatedHooks();
|
|
1234
|
+
this._compression = mergedOptions.compression;
|
|
1235
|
+
this._encryption = mergedOptions.encryption;
|
|
1236
|
+
this.initSerialization(mergedOptions);
|
|
1237
|
+
this.initSanitize(mergedOptions);
|
|
1238
|
+
this.initNamespace(mergedOptions.namespace);
|
|
1239
|
+
this.initStats(mergedOptions);
|
|
1240
|
+
if (mergedOptions.store) this.setStore(mergedOptions.store);
|
|
1241
|
+
this.setTtl(mergedOptions.ttl);
|
|
1242
|
+
this._checkExpired = mergedOptions.checkExpired ?? false;
|
|
1243
|
+
}
|
|
1167
1244
|
/**
|
|
1168
1245
|
* Stats manager for tracking cache operation metrics (hits, misses, sets, deletes, errors).
|
|
1169
1246
|
* @default this is disabled.
|
|
@@ -1203,29 +1280,6 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1203
1280
|
*/
|
|
1204
1281
|
_checkExpired = false;
|
|
1205
1282
|
/**
|
|
1206
|
-
* Keyv Constructor
|
|
1207
|
-
* @param {KeyvStorageAdapter | KeyvOptions} store
|
|
1208
|
-
* @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options
|
|
1209
|
-
*/
|
|
1210
|
-
constructor(store, options) {
|
|
1211
|
-
const mergedOptions = Keyv.resolveOptions(store, options);
|
|
1212
|
-
super({
|
|
1213
|
-
throwOnHookError: false,
|
|
1214
|
-
throwOnEmptyListeners: true,
|
|
1215
|
-
throwOnEmitError: mergedOptions.throwOnErrors ?? false
|
|
1216
|
-
});
|
|
1217
|
-
this.deprecatedHooks = buildDeprecatedHooks();
|
|
1218
|
-
this._compression = mergedOptions.compression;
|
|
1219
|
-
this._encryption = mergedOptions.encryption;
|
|
1220
|
-
this.initSerialization(mergedOptions);
|
|
1221
|
-
this.initSanitize(mergedOptions);
|
|
1222
|
-
this.initNamespace(mergedOptions.namespace);
|
|
1223
|
-
this.initStats(mergedOptions);
|
|
1224
|
-
if (mergedOptions.store) this.setStore(mergedOptions.store);
|
|
1225
|
-
this.setTtl(mergedOptions.ttl);
|
|
1226
|
-
this._checkExpired = mergedOptions.checkExpired ?? false;
|
|
1227
|
-
}
|
|
1228
|
-
/**
|
|
1229
1283
|
* Get the current storage adapter.
|
|
1230
1284
|
* @returns {KeyvStorageAdapter} The current storage adapter.
|
|
1231
1285
|
*/
|
|
@@ -1353,13 +1407,6 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1353
1407
|
return this._stats;
|
|
1354
1408
|
}
|
|
1355
1409
|
/**
|
|
1356
|
-
* When true, Keyv checks expiry at its layer on get/getMany/has/hasMany.
|
|
1357
|
-
* When false (default), trusts the storage adapter.
|
|
1358
|
-
*/
|
|
1359
|
-
get checkExpired() {
|
|
1360
|
-
return this._checkExpired;
|
|
1361
|
-
}
|
|
1362
|
-
/**
|
|
1363
1410
|
* Set the stats. When setting a new instance it will unsubscribe the old listeners
|
|
1364
1411
|
* and subscribe the new instance.
|
|
1365
1412
|
* @param {KeyvStats} stats The stats instance to set.
|
|
@@ -1370,19 +1417,32 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1370
1417
|
this._stats.subscribe(this);
|
|
1371
1418
|
}
|
|
1372
1419
|
/**
|
|
1373
|
-
*
|
|
1374
|
-
*
|
|
1375
|
-
*
|
|
1376
|
-
|
|
1377
|
-
|
|
1420
|
+
* Get whether Keyv checks expiry at its own layer on get/getMany/has/hasMany.
|
|
1421
|
+
* When false (default), it trusts the storage adapter to handle expiry.
|
|
1422
|
+
* @returns {boolean} `true` if Keyv checks expiry at its layer.
|
|
1423
|
+
*/
|
|
1424
|
+
get checkExpired() {
|
|
1425
|
+
return this._checkExpired;
|
|
1426
|
+
}
|
|
1427
|
+
/**
|
|
1428
|
+
* Resolves a store to a fully-compliant KeyvStorageAdapter:
|
|
1429
|
+
* 1. If the store declares the v6 `capabilities.expires` contract, use it directly (this takes
|
|
1430
|
+
* precedence over structural detection, so a full adapter whose async methods aren't written
|
|
1431
|
+
* with the `async` keyword is not mis-bridged).
|
|
1432
|
+
* 2. If the store implements the full async storage interface (but doesn't declare `expires`),
|
|
1433
|
+
* treat it as a legacy relative-`ttl` adapter and wrap it in KeyvBridgeAdapter.
|
|
1434
|
+
* 3. If the store is map-like (synchronous get/set/delete/has), wrap it in KeyvMemoryAdapter.
|
|
1435
|
+
* 4. If the store has async get/set/delete/clear, wrap it in KeyvBridgeAdapter.
|
|
1436
|
+
* 5. Otherwise, emit an error and fall back to a default in-memory KeyvMemoryAdapter.
|
|
1378
1437
|
*
|
|
1379
1438
|
* NOTE: this is used for internal but provided public for custom adapter testing
|
|
1380
1439
|
* @param {unknown} store The store to resolve.
|
|
1381
1440
|
* @returns {KeyvStorageAdapter} A fully-compliant storage adapter.
|
|
1382
1441
|
*/
|
|
1383
1442
|
resolveStore(store) {
|
|
1443
|
+
if (store?.capabilities?.expires === true) return store;
|
|
1384
1444
|
const cap = detectKeyvStorage(store);
|
|
1385
|
-
if (cap.store === "keyvStorage") return store;
|
|
1445
|
+
if (cap.store === "keyvStorage") return new KeyvBridgeAdapter(store);
|
|
1386
1446
|
if (cap.store === "mapLike") return new KeyvMemoryAdapter(store);
|
|
1387
1447
|
if (cap.store === "asyncMap") return new KeyvBridgeAdapter(store);
|
|
1388
1448
|
this.emit("error", /* @__PURE__ */ new Error("Could not use the provided storage adapter, falling back to KeyvMemoryAdapter with Map"));
|
|
@@ -1440,13 +1500,27 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1440
1500
|
return data.value;
|
|
1441
1501
|
}
|
|
1442
1502
|
/**
|
|
1443
|
-
*
|
|
1444
|
-
*
|
|
1503
|
+
* Reads many keys from the store, preferring its native `getMany` and falling back to parallel
|
|
1504
|
+
* single `get`s when an adapter does not implement it. A directly-used v6 adapter is not
|
|
1505
|
+
* structurally required to provide `getMany` (the bridge and memory adapters always do), so
|
|
1506
|
+
* this keeps `getMany`/`getManyRaw` working regardless of the resolved adapter.
|
|
1507
|
+
* @param keys - the keys to read
|
|
1508
|
+
* @returns the raw store results in the same order as `keys`
|
|
1509
|
+
*/
|
|
1510
|
+
async storeGetMany(keys) {
|
|
1511
|
+
if (typeof this._store.getMany === "function") return this._store.getMany(keys);
|
|
1512
|
+
return Promise.all(keys.map(async (key) => this._store.get(key)));
|
|
1513
|
+
}
|
|
1514
|
+
/**
|
|
1515
|
+
* Get many values for an array of keys.
|
|
1516
|
+
* @param {string[]} keys the keys to get
|
|
1517
|
+
* @returns {Promise<Array<Value | undefined>>} an array of values in the same order as the
|
|
1518
|
+
* keys, with `undefined` for keys that do not exist or are expired.
|
|
1445
1519
|
*/
|
|
1446
1520
|
async getMany(keys) {
|
|
1447
1521
|
keys = this._sanitize.enabled ? this._sanitize.cleanKeys(keys) : keys;
|
|
1448
1522
|
await this.hookWithDeprecated("before:getMany", { keys });
|
|
1449
|
-
const rawData = await this.
|
|
1523
|
+
const rawData = await this.storeGetMany(keys);
|
|
1450
1524
|
let deserialized;
|
|
1451
1525
|
if (this._checkExpired) deserialized = await this.decodeWithExpire(keys, rawData);
|
|
1452
1526
|
else deserialized = await Promise.all(rawData.map(async (row) => {
|
|
@@ -1505,7 +1579,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1505
1579
|
});
|
|
1506
1580
|
return result;
|
|
1507
1581
|
}
|
|
1508
|
-
const rawData = await this.
|
|
1582
|
+
const rawData = await this.storeGetMany(keys);
|
|
1509
1583
|
let result;
|
|
1510
1584
|
if (this._checkExpired) result = await this.decodeWithExpire(keys, rawData);
|
|
1511
1585
|
else result = await Promise.all(rawData.map(async (row) => {
|
|
@@ -1522,10 +1596,10 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1522
1596
|
}
|
|
1523
1597
|
/**
|
|
1524
1598
|
* Set an item to the store
|
|
1525
|
-
* @param {string
|
|
1599
|
+
* @param {string} key the key to use
|
|
1526
1600
|
* @param {Value} value the value of the key
|
|
1527
|
-
* @param {number} [ttl] time to live in milliseconds
|
|
1528
|
-
* @returns {boolean} if it
|
|
1601
|
+
* @param {number} [ttl] time to live in milliseconds. Overrides the instance-level `ttl`.
|
|
1602
|
+
* @returns {Promise<boolean>} `true` if it was set successfully, `false` on failure.
|
|
1529
1603
|
*/
|
|
1530
1604
|
async set(key, value, ttl) {
|
|
1531
1605
|
key = this._sanitize.enabled ? this._sanitize.cleanKey(key) : key;
|
|
@@ -1551,7 +1625,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1551
1625
|
let encodedValue = formattedValue;
|
|
1552
1626
|
try {
|
|
1553
1627
|
encodedValue = await this.encode(formattedValue);
|
|
1554
|
-
result = await this._store.set(data.key, encodedValue,
|
|
1628
|
+
result = await this._store.set(data.key, encodedValue, expires);
|
|
1555
1629
|
} catch (error) {
|
|
1556
1630
|
result = false;
|
|
1557
1631
|
this.emit("error", error);
|
|
@@ -1568,7 +1642,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1568
1642
|
/**
|
|
1569
1643
|
* Set many items to the store
|
|
1570
1644
|
* @param {Array<KeyvEntry<Value>>} entries the entries to set
|
|
1571
|
-
* @returns {boolean[]}
|
|
1645
|
+
* @returns {Promise<boolean[]>} an array of booleans, one per entry: `true` if set successfully, `false` on failure.
|
|
1572
1646
|
*/
|
|
1573
1647
|
async setMany(entries) {
|
|
1574
1648
|
entries = entries.map((e) => ({
|
|
@@ -1597,7 +1671,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1597
1671
|
return {
|
|
1598
1672
|
key,
|
|
1599
1673
|
value: await this.encode(formattedValue),
|
|
1600
|
-
|
|
1674
|
+
expires
|
|
1601
1675
|
};
|
|
1602
1676
|
}));
|
|
1603
1677
|
const storeResult = await this._store.setMany(serializedEntries);
|
|
@@ -1622,7 +1696,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1622
1696
|
* The store-level TTL is derived automatically from `value.expires`.
|
|
1623
1697
|
* @param {string} key the key to set
|
|
1624
1698
|
* @param {KeyvValue<Value>} value the raw value envelope to store
|
|
1625
|
-
* @returns {boolean} if it
|
|
1699
|
+
* @returns {Promise<boolean>} `true` if it was set successfully, `false` on failure.
|
|
1626
1700
|
*/
|
|
1627
1701
|
async setRaw(key, value) {
|
|
1628
1702
|
key = this._sanitize.enabled ? this._sanitize.cleanKey(key) : key;
|
|
@@ -1632,11 +1706,12 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1632
1706
|
value
|
|
1633
1707
|
};
|
|
1634
1708
|
await this.hookWithDeprecated("before:setRaw", data);
|
|
1635
|
-
const
|
|
1709
|
+
const expires = data.value.expires;
|
|
1710
|
+
const ttl = ttlFromExpires(expires);
|
|
1636
1711
|
let result = true;
|
|
1637
1712
|
try {
|
|
1638
1713
|
const encodedValue = await this.encode(data.value);
|
|
1639
|
-
const storeResult = await this._store.set(data.key, encodedValue,
|
|
1714
|
+
const storeResult = await this._store.set(data.key, encodedValue, expires);
|
|
1640
1715
|
if (typeof storeResult === "boolean") result = storeResult;
|
|
1641
1716
|
} catch (error) {
|
|
1642
1717
|
result = false;
|
|
@@ -1656,7 +1731,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1656
1731
|
* Each entry's value should be a KeyvValue object with { value, expires? }. If you need TTL-based expiration,
|
|
1657
1732
|
* set `expires` on each value directly. The store-level TTL is derived automatically from `value.expires`.
|
|
1658
1733
|
* @param {KeyvEntry<KeyvValue<Value>>[]} entries the raw entries to set
|
|
1659
|
-
* @returns {boolean[]}
|
|
1734
|
+
* @returns {Promise<boolean[]>} an array of booleans, one per entry: `true` if set successfully, `false` on failure.
|
|
1660
1735
|
*/
|
|
1661
1736
|
async setManyRaw(entries) {
|
|
1662
1737
|
entries = entries.map((e) => ({
|
|
@@ -1668,11 +1743,10 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1668
1743
|
await this.hookWithDeprecated("before:setManyRaw", { entries });
|
|
1669
1744
|
try {
|
|
1670
1745
|
const rawEntries = await Promise.all(entries.map(async ({ key, value }) => {
|
|
1671
|
-
const ttl = ttlFromExpires(value.expires);
|
|
1672
1746
|
return {
|
|
1673
1747
|
key,
|
|
1674
1748
|
value: await this.encode(value),
|
|
1675
|
-
|
|
1749
|
+
expires: value.expires
|
|
1676
1750
|
};
|
|
1677
1751
|
}));
|
|
1678
1752
|
const storeResult = await this._store.setMany(rawEntries);
|
|
@@ -1712,7 +1786,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1712
1786
|
/**
|
|
1713
1787
|
* Delete many items from the store
|
|
1714
1788
|
* @param {string[]} keys the keys to be deleted
|
|
1715
|
-
* @returns {boolean[]} array of booleans indicating success for each key
|
|
1789
|
+
* @returns {Promise<boolean[]>} an array of booleans indicating success for each key.
|
|
1716
1790
|
*/
|
|
1717
1791
|
async deleteMany(keys) {
|
|
1718
1792
|
/* v8 ignore next -- @preserve */
|
|
@@ -1765,7 +1839,7 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1765
1839
|
/**
|
|
1766
1840
|
* Check if many keys exist
|
|
1767
1841
|
* @param {string[]} keys the keys to check
|
|
1768
|
-
* @returns {boolean[]}
|
|
1842
|
+
* @returns {Promise<boolean[]>} an array of booleans in the same order as the keys, `true` if the key exists.
|
|
1769
1843
|
*/
|
|
1770
1844
|
async hasMany(keys) {
|
|
1771
1845
|
keys = this._sanitize.enabled ? this._sanitize.cleanKeys(keys) : keys;
|
|
@@ -1788,8 +1862,9 @@ var Keyv = class Keyv extends Hookified {
|
|
|
1788
1862
|
return results;
|
|
1789
1863
|
}
|
|
1790
1864
|
/**
|
|
1791
|
-
* Clear the store
|
|
1792
|
-
*
|
|
1865
|
+
* Clear the store. If a namespace is set only entries in that namespace are removed.
|
|
1866
|
+
* Emits a `clear` event.
|
|
1867
|
+
* @returns {Promise<void>} resolves once the entries have been cleared.
|
|
1793
1868
|
*/
|
|
1794
1869
|
async clear() {
|
|
1795
1870
|
this.emit("clear");
|
|
@@ -2005,10 +2080,14 @@ var KeyvMemoryAdapter = class extends Hookified {
|
|
|
2005
2080
|
if (options?.namespace) this._namespace = options?.namespace;
|
|
2006
2081
|
}
|
|
2007
2082
|
/**
|
|
2008
|
-
* Gets the
|
|
2083
|
+
* Gets the capabilities of the underlying store, with `expires: true` to declare that
|
|
2084
|
+
* this adapter accepts an absolute `expires` timestamp (the v6 storage contract).
|
|
2009
2085
|
*/
|
|
2010
2086
|
get capabilities() {
|
|
2011
|
-
return
|
|
2087
|
+
return {
|
|
2088
|
+
...this._capabilities,
|
|
2089
|
+
expires: true
|
|
2090
|
+
};
|
|
2012
2091
|
}
|
|
2013
2092
|
/**
|
|
2014
2093
|
* Gets the underlying store instance.
|
|
@@ -2085,24 +2164,24 @@ var KeyvMemoryAdapter = class extends Hookified {
|
|
|
2085
2164
|
return entry.value;
|
|
2086
2165
|
}
|
|
2087
2166
|
/**
|
|
2088
|
-
* Stores a value in the store with an optional
|
|
2167
|
+
* Stores a value in the store with an optional absolute expiry.
|
|
2089
2168
|
* @param key - The key to store the value under
|
|
2090
2169
|
* @param value - The value to store
|
|
2091
|
-
* @param
|
|
2170
|
+
* @param expires - Optional absolute expiry as Unix ms since epoch
|
|
2092
2171
|
* @returns Always returns true indicating success
|
|
2093
2172
|
*/
|
|
2094
|
-
async set(key, value,
|
|
2173
|
+
async set(key, value, expires) {
|
|
2095
2174
|
const keyPrefix = this.getKeyPrefix(key, this._namespace);
|
|
2096
2175
|
const entry = {
|
|
2097
2176
|
value,
|
|
2098
|
-
expires:
|
|
2177
|
+
expires: typeof expires === "number" ? expires : void 0
|
|
2099
2178
|
};
|
|
2100
|
-
this._store.set(keyPrefix, entry,
|
|
2179
|
+
this._store.set(keyPrefix, entry, ttlFromExpires(expires));
|
|
2101
2180
|
return true;
|
|
2102
2181
|
}
|
|
2103
2182
|
/**
|
|
2104
2183
|
* Stores multiple entries in the store at once.
|
|
2105
|
-
* @param entries - Array of entries containing key, value, and optional
|
|
2184
|
+
* @param entries - Array of entries containing key, value, and optional absolute `expires`
|
|
2106
2185
|
*/
|
|
2107
2186
|
async setMany(entries) {
|
|
2108
2187
|
const results = [];
|
|
@@ -2110,9 +2189,9 @@ var KeyvMemoryAdapter = class extends Hookified {
|
|
|
2110
2189
|
const keyPrefix = this.getKeyPrefix(entry.key, this._namespace);
|
|
2111
2190
|
const memEntry = {
|
|
2112
2191
|
value: entry.value,
|
|
2113
|
-
expires: entry.
|
|
2192
|
+
expires: typeof entry.expires === "number" ? entry.expires : void 0
|
|
2114
2193
|
};
|
|
2115
|
-
this._store.set(keyPrefix, memEntry, entry.
|
|
2194
|
+
this._store.set(keyPrefix, memEntry, ttlFromExpires(entry.expires));
|
|
2116
2195
|
results.push(true);
|
|
2117
2196
|
}
|
|
2118
2197
|
return results;
|
|
@@ -2265,4 +2344,4 @@ function createKeyv(store, options) {
|
|
|
2265
2344
|
});
|
|
2266
2345
|
}
|
|
2267
2346
|
//#endregion
|
|
2268
|
-
export { Keyv, Keyv as default, KeyvBridgeAdapter, KeyvEvents, KeyvHooks, KeyvJsonSerializer, KeyvMemoryAdapter, KeyvSanitize, KeyvStats, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer };
|
|
2347
|
+
export { Keyv, Keyv as default, KeyvBridgeAdapter, KeyvEvents, KeyvHooks, KeyvJsonSerializer, KeyvMemoryAdapter, KeyvSanitize, KeyvStats, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer, keyvStorageCapability };
|