+158
-61
@@ -24,2 +24,16 @@ import { Hookified, IEventEmitter } from "hookified"; | ||
| methods: KeyvStorageMethods; | ||
| /** | ||
| * Whether the adapter implements the v6 storage contract — it accepts an absolute | ||
| * `expires` timestamp (ms since epoch) on `set`/`setMany`. Adapters that omit this | ||
| * (legacy relative-`ttl` adapters) are wrapped by `KeyvBridgeAdapter`, which converts | ||
| * the absolute `expires` back to a relative ttl before delegating. | ||
| * | ||
| * Declaring `expires: true` is a two-way contract: the adapter is then used directly and | ||
| * must ENFORCE expiry on read. Keyv core does not filter expired entries by default | ||
| * (`checkExpired` is off), so the adapter is the expiry authority — `get`/`getMany`/`has` | ||
| * must return nothing for a key past its deadline, via a native mechanism (TTL index, key | ||
| * expiry, lease) and/or a client-side check. Validate with `@keyv/test-suite`'s | ||
| * `storageTtlTests`. | ||
| */ | ||
| expires?: boolean; | ||
| }; | ||
@@ -88,2 +102,17 @@ declare const keyvCompressionMethodNames: readonly ["compress", "decompress"]; | ||
| /** | ||
| * Build the capability descriptor for a v6 storage adapter: the structurally detected | ||
| * methods plus `expires: true`, declaring that the adapter accepts an absolute `expires` | ||
| * timestamp on `set`/`setMany`. First-party adapters expose this from their `capabilities` | ||
| * getter so Keyv uses them directly instead of bridging. | ||
| * @param adapter - The storage adapter to describe (typically `this`). | ||
| * @returns A {@link KeyvStorageCapability} with `expires` set to `true`. | ||
| * @example | ||
| * ```typescript | ||
| * public get capabilities(): KeyvStorageCapability { | ||
| * return keyvStorageCapability(this); | ||
| * } | ||
| * ``` | ||
| */ | ||
| declare function keyvStorageCapability(adapter: object): KeyvStorageCapability; | ||
| /** | ||
| * Detect whether an object implements the Keyv compression adapter interface | ||
@@ -498,3 +527,4 @@ * @param obj - The object to check | ||
| /** | ||
| * Represents a key-value entry with an optional TTL, used for batch operations like `setMany`. | ||
| * Represents a key-value entry with an optional TTL, used for the public | ||
| * batch API `Keyv.setMany`. | ||
| */ | ||
@@ -516,2 +546,13 @@ type KeyvEntry<Value = any> = { | ||
| /** | ||
| * Represents a key-value entry at the storage-adapter boundary, carrying an | ||
| * absolute `expires` timestamp instead of a relative `ttl`. Keyv core computes | ||
| * `expires` once and passes these to a storage adapter's `setMany`, so adapters | ||
| * never derive expiry themselves. | ||
| */ | ||
| type KeyvStorageEntry<Value = any> = { | ||
| /** Key to set. */key: string; /** Value to set (already encoded by Keyv core). */ | ||
| value: Value; /** Absolute expiry as Unix ms since epoch, or `undefined` for no expiry. */ | ||
| expires?: number; | ||
| }; | ||
| /** | ||
| * Configuration options for the Keyv constructor. | ||
@@ -609,7 +650,22 @@ */ | ||
| type KeyvStorageAdapter = { | ||
| /** Optional namespace for key isolation. */namespace?: string | undefined; /** Detected capabilities of the underlying store. */ | ||
| /** Optional namespace for key isolation. */namespace?: string | undefined; | ||
| /** | ||
| * The adapter's capabilities. v6 adapters set `capabilities.expires = true` (e.g. via | ||
| * `keyvStorageCapability(this)`) to declare they accept an absolute `expires` timestamp | ||
| * on `set`/`setMany`. Full storage adapters that omit it are treated as legacy relative-`ttl` | ||
| * adapters and wrapped by `KeyvBridgeAdapter`, which converts `expires` back to a ttl. | ||
| * | ||
| * Declaring `expires: true` also obliges the adapter to enforce expiry on read: Keyv core | ||
| * does not filter expired entries by default, so `get`/`getMany`/`has` must not return a key | ||
| * past its deadline. See {@link KeyvStorageCapability.expires}. | ||
| */ | ||
| capabilities?: KeyvStorageCapability; /** Retrieves a value by key. */ | ||
| get<Value>(key: string): Promise<KeyvStorageGetResult<Value>>; /** Stores a value with a key and optional TTL in milliseconds. */ | ||
| set(key: string, value: unknown, ttl?: number): Promise<boolean>; /** Stores multiple entries at once. */ | ||
| setMany<Value>(values: KeyvEntry<Value>[]): Promise<boolean[] | undefined>; /** Deletes a key from the store. */ | ||
| get<Value>(key: string): Promise<KeyvStorageGetResult<Value>>; | ||
| /** | ||
| * Stores a value with a key and optional absolute expiry. | ||
| * @param expires Absolute expiry as Unix ms since epoch; `undefined` means no expiry. | ||
| * A value `<= Date.now()` is already expired and the adapter may delete/skip it. | ||
| */ | ||
| set(key: string, value: unknown, expires?: number): Promise<boolean>; /** Stores multiple entries at once, each with an absolute `expires` timestamp. */ | ||
| setMany<Value>(values: KeyvStorageEntry<Value>[]): Promise<boolean[] | undefined>; /** Deletes a key from the store. */ | ||
| delete(key: string): Promise<boolean>; /** Clears all entries from the store (respects namespace if set). */ | ||
@@ -655,3 +711,4 @@ clear(): Promise<void>; /** Checks if a key exists in the store. */ | ||
| type KeyvBridgeStore = { | ||
| /** Store configuration/options (e.g. dialect, url) */opts?: any; /** Retrieves a value by key */ | ||
| /** Store configuration/options (e.g. dialect, url) */opts?: any; /** Namespace the store scopes its keys under, when it manages its own namespacing. */ | ||
| namespace?: string; /** Retrieves a value by key */ | ||
| get(key: string): Promise<any>; /** Sets a value with a key and optional TTL */ | ||
@@ -700,2 +757,8 @@ set(key: string, value: any, ttl?: number): Promise<any>; /** Deletes a key from the store */ | ||
| /** | ||
| * Whether the wrapped store manages its own namespace (exposes a `namespace` property). | ||
| * When true the bridge propagates its namespace to the store and does not prefix keys, | ||
| * so the store's native, namespace-scoped operations (notably `clear()`) are used directly. | ||
| */ | ||
| private readonly _storeHandlesNamespace; | ||
| /** | ||
| * Creates a new KeyvBridgeAdapter instance. | ||
@@ -715,3 +778,5 @@ * @param store - The underlying promise-based store to bridge | ||
| /** | ||
| * Gets the detected capabilities of the underlying store. | ||
| * Gets the capabilities of the underlying store, with `expires: true` to declare that | ||
| * the bridge accepts an absolute `expires` timestamp (which it converts to a ttl for the | ||
| * wrapped legacy store). | ||
| */ | ||
@@ -732,3 +797,4 @@ get capabilities(): KeyvStorageCapability; | ||
| /** | ||
| * Sets the namespace. | ||
| * Sets the namespace. When the wrapped store manages its own namespace, the value is | ||
| * propagated to it so its native scoped operations stay in sync. | ||
| */ | ||
@@ -764,15 +830,21 @@ set namespace(namespace: string | undefined); | ||
| /** | ||
| * Stores a value in the store with an optional TTL. | ||
| * Stores a value in the store with an optional absolute expiry. | ||
| * The wrapped store's `set(key, value, ttl?)` expects a relative duration, so the absolute | ||
| * `expires` is converted to a remaining ttl (`undefined` when already expired or absent). | ||
| * The value is passed through unchanged — the bridge does not wrap it in an envelope — so | ||
| * expiry is enforced by the wrapped legacy store's own ttl handling. (The read-side | ||
| * {@link isDataExpired} check only fires when a caller stores a raw `{ value, expires }` | ||
| * object directly; when Keyv core drives the bridge the value arrives already encoded.) | ||
| * @param key - The key to store the value under | ||
| * @param value - The value to store | ||
| * @param ttl - Optional time-to-live in milliseconds | ||
| * @param expires - Optional absolute expiry as Unix ms since epoch | ||
| * @returns Always returns true indicating success | ||
| */ | ||
| set(key: string, value: any, ttl?: number): Promise<boolean>; | ||
| set(key: string, value: any, expires?: number): Promise<boolean>; | ||
| /** | ||
| * Stores multiple entries in the store at once. | ||
| * Delegates to the store's native setMany if available, otherwise loops over set. | ||
| * @param entries - Array of entries containing key, value, and optional TTL | ||
| * @param entries - Array of entries containing key, value, and optional absolute `expires` | ||
| */ | ||
| setMany<Value>(entries: KeyvEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| setMany<Value>(entries: KeyvStorageEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| /** | ||
@@ -827,2 +899,13 @@ * Checks if a key exists in the store and is not expired. | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvStorageAdapter | KeyvOptions | Map<any, any> | any} store to be provided or just the options | ||
| * @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options | ||
| */ | ||
| constructor(store?: KeyvStorageAdapter | KeyvOptions | KeyvMapAny, options?: Omit<KeyvOptions, "store">); | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvOptions} options to be provided | ||
| */ | ||
| constructor(options?: KeyvOptions); | ||
| /** | ||
| * Stats manager for tracking cache operation metrics (hits, misses, sets, deletes, errors). | ||
@@ -866,13 +949,2 @@ * @default this is disabled. | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvStorageAdapter | KeyvOptions | Map<any, any> | any} store to be provided or just the options | ||
| * @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options | ||
| */ | ||
| constructor(store?: KeyvStorageAdapter | KeyvOptions | KeyvMapAny, options?: Omit<KeyvOptions, "store">); | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvOptions} options to be provided | ||
| */ | ||
| constructor(options?: KeyvOptions); | ||
| /** | ||
| * Get the current storage adapter. | ||
@@ -968,7 +1040,2 @@ * @returns {KeyvStorageAdapter} The current storage adapter. | ||
| /** | ||
| * When true, Keyv checks expiry at its layer on get/getMany/has/hasMany. | ||
| * When false (default), trusts the storage adapter. | ||
| */ | ||
| get checkExpired(): boolean; | ||
| /** | ||
| * Set the stats. When setting a new instance it will unsubscribe the old listeners | ||
@@ -980,7 +1047,17 @@ * and subscribe the new instance. | ||
| /** | ||
| * Resolves a store to a fully-compliant KeyvStorageAdapter using a 3-tier detection chain: | ||
| * 1. If the store already implements the full KeyvStorageAdapter interface, use it directly. | ||
| * 2. If the store is map-like (synchronous get/set/delete/has), wrap it in KeyvMemoryAdapter. | ||
| * 3. If the store has async get/set/delete/clear, wrap it in KeyvBridgeAdapter. | ||
| * 4. Otherwise, emit an error and fall back to a default in-memory KeyvMemoryAdapter. | ||
| * Get whether Keyv checks expiry at its own layer on get/getMany/has/hasMany. | ||
| * When false (default), it trusts the storage adapter to handle expiry. | ||
| * @returns {boolean} `true` if Keyv checks expiry at its layer. | ||
| */ | ||
| get checkExpired(): boolean; | ||
| /** | ||
| * Resolves a store to a fully-compliant KeyvStorageAdapter: | ||
| * 1. If the store declares the v6 `capabilities.expires` contract, use it directly (this takes | ||
| * precedence over structural detection, so a full adapter whose async methods aren't written | ||
| * with the `async` keyword is not mis-bridged). | ||
| * 2. If the store implements the full async storage interface (but doesn't declare `expires`), | ||
| * treat it as a legacy relative-`ttl` adapter and wrap it in KeyvBridgeAdapter. | ||
| * 3. If the store is map-like (synchronous get/set/delete/has), wrap it in KeyvMemoryAdapter. | ||
| * 4. If the store has async get/set/delete/clear, wrap it in KeyvBridgeAdapter. | ||
| * 5. Otherwise, emit an error and fall back to a default in-memory KeyvMemoryAdapter. | ||
| * | ||
@@ -1004,4 +1081,8 @@ * NOTE: this is used for internal but provided public for custom adapter testing | ||
| /** | ||
| * Get the Value of a Key | ||
| * Get the value of a key. If an array of keys is passed in it will return an array of values | ||
| * delegating to {@link getMany}. | ||
| * @param {string | string[]} key passing in a single key or multiple as an array | ||
| * @returns {Promise<Value | undefined | Array<Value | undefined>>} the value of the key, or | ||
| * `undefined` if the key does not exist or is expired. When an array of keys is passed in it | ||
| * returns an array of values in the same order (with `undefined` for missing keys). | ||
| */ | ||
@@ -1011,5 +1092,16 @@ get<Value = GenericValue>(key: string): Promise<Value | undefined>; | ||
| /** | ||
| * Get many values of keys | ||
| * @param {string[]} keys passing in a single key or multiple as an array | ||
| * Reads many keys from the store, preferring its native `getMany` and falling back to parallel | ||
| * single `get`s when an adapter does not implement it. A directly-used v6 adapter is not | ||
| * structurally required to provide `getMany` (the bridge and memory adapters always do), so | ||
| * this keeps `getMany`/`getManyRaw` working regardless of the resolved adapter. | ||
| * @param keys - the keys to read | ||
| * @returns the raw store results in the same order as `keys` | ||
| */ | ||
| private storeGetMany; | ||
| /** | ||
| * Get many values for an array of keys. | ||
| * @param {string[]} keys the keys to get | ||
| * @returns {Promise<Array<Value | undefined>>} an array of values in the same order as the | ||
| * keys, with `undefined` for keys that do not exist or are expired. | ||
| */ | ||
| getMany<Value = GenericValue>(keys: string[]): Promise<Array<Value | undefined>>; | ||
@@ -1031,6 +1123,6 @@ /** | ||
| * Set an item to the store | ||
| * @param {string | Array<KeyvEntry<Value>>} key the key to use. If you pass in an array of KeyvEntry it will set many items | ||
| * @param {string} key the key to use | ||
| * @param {Value} value the value of the key | ||
| * @param {number} [ttl] time to live in milliseconds | ||
| * @returns {boolean} if it sets then it will return a true. On failure will return false. | ||
| * @param {number} [ttl] time to live in milliseconds. Overrides the instance-level `ttl`. | ||
| * @returns {Promise<boolean>} `true` if it was set successfully, `false` on failure. | ||
| */ | ||
@@ -1041,3 +1133,3 @@ set<Value = GenericValue>(key: string, value: Value, ttl?: number): Promise<boolean>; | ||
| * @param {Array<KeyvEntry<Value>>} entries the entries to set | ||
| * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false. | ||
| * @returns {Promise<boolean[]>} an array of booleans, one per entry: `true` if set successfully, `false` on failure. | ||
| */ | ||
@@ -1052,3 +1144,3 @@ setMany<Value = GenericValue>(entries: KeyvEntry<Value>[]): Promise<boolean[]>; | ||
| * @param {KeyvValue<Value>} value the raw value envelope to store | ||
| * @returns {boolean} if it sets then it will return a true. On failure will return false. | ||
| * @returns {Promise<boolean>} `true` if it was set successfully, `false` on failure. | ||
| */ | ||
@@ -1061,15 +1153,16 @@ setRaw<Value = GenericValue>(key: string, value: KeyvValue<Value>): Promise<boolean>; | ||
| * @param {KeyvEntry<KeyvValue<Value>>[]} entries the raw entries to set | ||
| * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false. | ||
| * @returns {Promise<boolean[]>} an array of booleans, one per entry: `true` if set successfully, `false` on failure. | ||
| */ | ||
| setManyRaw<Value = GenericValue>(entries: KeyvEntry<KeyvValue<Value>>[]): Promise<boolean[]>; | ||
| /** | ||
| * Delete an Entry | ||
| * Delete an entry. If an array of keys is passed in it will delete many entries | ||
| * delegating to {@link deleteMany}. | ||
| * @param {string} key the key to be deleted | ||
| * @returns {boolean} will return true if item is deleted. false if there is an error | ||
| * @returns {Promise<boolean>} `true` if the item was deleted, `false` if there was an error. | ||
| */ | ||
| delete(key: string): Promise<boolean>; | ||
| /** | ||
| * Delete multiple Entries | ||
| * Delete multiple entries | ||
| * @param {string[]} keys the keys to be deleted | ||
| * @returns {boolean[]} will return array of booleans for each key | ||
| * @returns {Promise<boolean[]>} an array of booleans indicating success for each key. | ||
| */ | ||
@@ -1080,9 +1173,11 @@ delete(keys: string[]): Promise<boolean[]>; | ||
| * @param {string[]} keys the keys to be deleted | ||
| * @returns {boolean[]} array of booleans indicating success for each key | ||
| * @returns {Promise<boolean[]>} an array of booleans indicating success for each key. | ||
| */ | ||
| deleteMany(keys: string[]): Promise<boolean[]>; | ||
| /** | ||
| * Has a key. | ||
| * @param {string} key the key to check | ||
| * @returns {boolean} will return true if the key exists | ||
| * Check if a key exists. If an array of keys is passed in it will check many keys | ||
| * delegating to {@link hasMany}. | ||
| * @param {string | string[]} key the key (or keys) to check | ||
| * @returns {Promise<boolean | boolean[]>} `true` if the key exists, `false` if not. When an | ||
| * array of keys is passed in it returns an array of booleans in the same order. | ||
| */ | ||
@@ -1094,8 +1189,9 @@ has(key: string[]): Promise<boolean[]>; | ||
| * @param {string[]} keys the keys to check | ||
| * @returns {boolean[]} will return an array of booleans if the keys exist | ||
| * @returns {Promise<boolean[]>} an array of booleans in the same order as the keys, `true` if the key exists. | ||
| */ | ||
| hasMany(keys: string[]): Promise<boolean[]>; | ||
| /** | ||
| * Clear the store | ||
| * @returns {void} | ||
| * Clear the store. If a namespace is set only entries in that namespace are removed. | ||
| * Emits a `clear` event. | ||
| * @returns {Promise<void>} resolves once the entries have been cleared. | ||
| */ | ||
@@ -1227,3 +1323,4 @@ clear(): Promise<void>; | ||
| /** | ||
| * Gets the detected capabilities of the underlying store. | ||
| * Gets the capabilities of the underlying store, with `expires: true` to declare that | ||
| * this adapter accepts an absolute `expires` timestamp (the v6 storage contract). | ||
| */ | ||
@@ -1282,14 +1379,14 @@ get capabilities(): KeyvStorageCapability; | ||
| /** | ||
| * Stores a value in the store with an optional TTL. | ||
| * Stores a value in the store with an optional absolute expiry. | ||
| * @param key - The key to store the value under | ||
| * @param value - The value to store | ||
| * @param ttl - Optional time-to-live in milliseconds | ||
| * @param expires - Optional absolute expiry as Unix ms since epoch | ||
| * @returns Always returns true indicating success | ||
| */ | ||
| set(key: string, value: any, ttl?: number): Promise<boolean>; | ||
| set(key: string, value: any, expires?: number): Promise<boolean>; | ||
| /** | ||
| * Stores multiple entries in the store at once. | ||
| * @param entries - Array of entries containing key, value, and optional TTL | ||
| * @param entries - Array of entries containing key, value, and optional absolute `expires` | ||
| */ | ||
| setMany<Value>(entries: KeyvEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| setMany<Value>(entries: KeyvStorageEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| /** | ||
@@ -1375,2 +1472,2 @@ * Deletes a value from the store by key. | ||
| //#endregion | ||
| export { type DeserializedData, Keyv, Keyv as default, KeyvBridgeAdapter, type KeyvBridgeAdapterOptions, type KeyvBridgeStore, type KeyvCapability, type KeyvCompression, type KeyvCompressionAdapter, type KeyvCompressionCapability, type KeyvCompressionMethods, type KeyvEncryptionAdapter, type KeyvEncryptionCapability, type KeyvEncryptionMethods, type KeyvEntry, KeyvEvents, KeyvHooks, KeyvJsonSerializer, type KeyvMapAny, type KeyvMapType, KeyvMemoryAdapter, type KeyvMemoryAdapterOptions, type KeyvMethods, type KeyvOptions, type KeyvProperties, KeyvSanitize, type KeyvSanitizeAdapter, type KeyvSanitizeOptions, type KeyvSanitizePatterns, type KeyvSerializationAdapter, type KeyvSerializationCapability, type KeyvSerializationMethods, KeyvStats, type KeyvStatsOptions, type KeyvStorageAdapter, type KeyvStorageCapability, type KeyvStorageGetResult, type KeyvStorageMethod, type KeyvStorageMethods, type KeyvStoreAdapter, type KeyvTelemetryEvent, type KeyvValue, type MethodType, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer }; | ||
| export { type DeserializedData, Keyv, Keyv as default, KeyvBridgeAdapter, type KeyvBridgeAdapterOptions, type KeyvBridgeStore, type KeyvCapability, type KeyvCompression, type KeyvCompressionAdapter, type KeyvCompressionCapability, type KeyvCompressionMethods, type KeyvEncryptionAdapter, type KeyvEncryptionCapability, type KeyvEncryptionMethods, type KeyvEntry, KeyvEvents, KeyvHooks, KeyvJsonSerializer, type KeyvMapAny, type KeyvMapType, KeyvMemoryAdapter, type KeyvMemoryAdapterOptions, type KeyvMethods, type KeyvOptions, type KeyvProperties, KeyvSanitize, type KeyvSanitizeAdapter, type KeyvSanitizeOptions, type KeyvSanitizePatterns, type KeyvSerializationAdapter, type KeyvSerializationCapability, type KeyvSerializationMethods, KeyvStats, type KeyvStatsOptions, type KeyvStorageAdapter, type KeyvStorageCapability, type KeyvStorageEntry, type KeyvStorageGetResult, type KeyvStorageMethod, type KeyvStorageMethods, type KeyvStoreAdapter, type KeyvTelemetryEvent, type KeyvValue, type MethodType, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer, keyvStorageCapability }; |
+158
-61
@@ -24,2 +24,16 @@ import { Hookified, IEventEmitter } from "hookified"; | ||
| methods: KeyvStorageMethods; | ||
| /** | ||
| * Whether the adapter implements the v6 storage contract — it accepts an absolute | ||
| * `expires` timestamp (ms since epoch) on `set`/`setMany`. Adapters that omit this | ||
| * (legacy relative-`ttl` adapters) are wrapped by `KeyvBridgeAdapter`, which converts | ||
| * the absolute `expires` back to a relative ttl before delegating. | ||
| * | ||
| * Declaring `expires: true` is a two-way contract: the adapter is then used directly and | ||
| * must ENFORCE expiry on read. Keyv core does not filter expired entries by default | ||
| * (`checkExpired` is off), so the adapter is the expiry authority — `get`/`getMany`/`has` | ||
| * must return nothing for a key past its deadline, via a native mechanism (TTL index, key | ||
| * expiry, lease) and/or a client-side check. Validate with `@keyv/test-suite`'s | ||
| * `storageTtlTests`. | ||
| */ | ||
| expires?: boolean; | ||
| }; | ||
@@ -88,2 +102,17 @@ declare const keyvCompressionMethodNames: readonly ["compress", "decompress"]; | ||
| /** | ||
| * Build the capability descriptor for a v6 storage adapter: the structurally detected | ||
| * methods plus `expires: true`, declaring that the adapter accepts an absolute `expires` | ||
| * timestamp on `set`/`setMany`. First-party adapters expose this from their `capabilities` | ||
| * getter so Keyv uses them directly instead of bridging. | ||
| * @param adapter - The storage adapter to describe (typically `this`). | ||
| * @returns A {@link KeyvStorageCapability} with `expires` set to `true`. | ||
| * @example | ||
| * ```typescript | ||
| * public get capabilities(): KeyvStorageCapability { | ||
| * return keyvStorageCapability(this); | ||
| * } | ||
| * ``` | ||
| */ | ||
| declare function keyvStorageCapability(adapter: object): KeyvStorageCapability; | ||
| /** | ||
| * Detect whether an object implements the Keyv compression adapter interface | ||
@@ -498,3 +527,4 @@ * @param obj - The object to check | ||
| /** | ||
| * Represents a key-value entry with an optional TTL, used for batch operations like `setMany`. | ||
| * Represents a key-value entry with an optional TTL, used for the public | ||
| * batch API `Keyv.setMany`. | ||
| */ | ||
@@ -516,2 +546,13 @@ type KeyvEntry<Value = any> = { | ||
| /** | ||
| * Represents a key-value entry at the storage-adapter boundary, carrying an | ||
| * absolute `expires` timestamp instead of a relative `ttl`. Keyv core computes | ||
| * `expires` once and passes these to a storage adapter's `setMany`, so adapters | ||
| * never derive expiry themselves. | ||
| */ | ||
| type KeyvStorageEntry<Value = any> = { | ||
| /** Key to set. */key: string; /** Value to set (already encoded by Keyv core). */ | ||
| value: Value; /** Absolute expiry as Unix ms since epoch, or `undefined` for no expiry. */ | ||
| expires?: number; | ||
| }; | ||
| /** | ||
| * Configuration options for the Keyv constructor. | ||
@@ -609,7 +650,22 @@ */ | ||
| type KeyvStorageAdapter = { | ||
| /** Optional namespace for key isolation. */namespace?: string | undefined; /** Detected capabilities of the underlying store. */ | ||
| /** Optional namespace for key isolation. */namespace?: string | undefined; | ||
| /** | ||
| * The adapter's capabilities. v6 adapters set `capabilities.expires = true` (e.g. via | ||
| * `keyvStorageCapability(this)`) to declare they accept an absolute `expires` timestamp | ||
| * on `set`/`setMany`. Full storage adapters that omit it are treated as legacy relative-`ttl` | ||
| * adapters and wrapped by `KeyvBridgeAdapter`, which converts `expires` back to a ttl. | ||
| * | ||
| * Declaring `expires: true` also obliges the adapter to enforce expiry on read: Keyv core | ||
| * does not filter expired entries by default, so `get`/`getMany`/`has` must not return a key | ||
| * past its deadline. See {@link KeyvStorageCapability.expires}. | ||
| */ | ||
| capabilities?: KeyvStorageCapability; /** Retrieves a value by key. */ | ||
| get<Value>(key: string): Promise<KeyvStorageGetResult<Value>>; /** Stores a value with a key and optional TTL in milliseconds. */ | ||
| set(key: string, value: unknown, ttl?: number): Promise<boolean>; /** Stores multiple entries at once. */ | ||
| setMany<Value>(values: KeyvEntry<Value>[]): Promise<boolean[] | undefined>; /** Deletes a key from the store. */ | ||
| get<Value>(key: string): Promise<KeyvStorageGetResult<Value>>; | ||
| /** | ||
| * Stores a value with a key and optional absolute expiry. | ||
| * @param expires Absolute expiry as Unix ms since epoch; `undefined` means no expiry. | ||
| * A value `<= Date.now()` is already expired and the adapter may delete/skip it. | ||
| */ | ||
| set(key: string, value: unknown, expires?: number): Promise<boolean>; /** Stores multiple entries at once, each with an absolute `expires` timestamp. */ | ||
| setMany<Value>(values: KeyvStorageEntry<Value>[]): Promise<boolean[] | undefined>; /** Deletes a key from the store. */ | ||
| delete(key: string): Promise<boolean>; /** Clears all entries from the store (respects namespace if set). */ | ||
@@ -655,3 +711,4 @@ clear(): Promise<void>; /** Checks if a key exists in the store. */ | ||
| type KeyvBridgeStore = { | ||
| /** Store configuration/options (e.g. dialect, url) */opts?: any; /** Retrieves a value by key */ | ||
| /** Store configuration/options (e.g. dialect, url) */opts?: any; /** Namespace the store scopes its keys under, when it manages its own namespacing. */ | ||
| namespace?: string; /** Retrieves a value by key */ | ||
| get(key: string): Promise<any>; /** Sets a value with a key and optional TTL */ | ||
@@ -700,2 +757,8 @@ set(key: string, value: any, ttl?: number): Promise<any>; /** Deletes a key from the store */ | ||
| /** | ||
| * Whether the wrapped store manages its own namespace (exposes a `namespace` property). | ||
| * When true the bridge propagates its namespace to the store and does not prefix keys, | ||
| * so the store's native, namespace-scoped operations (notably `clear()`) are used directly. | ||
| */ | ||
| private readonly _storeHandlesNamespace; | ||
| /** | ||
| * Creates a new KeyvBridgeAdapter instance. | ||
@@ -715,3 +778,5 @@ * @param store - The underlying promise-based store to bridge | ||
| /** | ||
| * Gets the detected capabilities of the underlying store. | ||
| * Gets the capabilities of the underlying store, with `expires: true` to declare that | ||
| * the bridge accepts an absolute `expires` timestamp (which it converts to a ttl for the | ||
| * wrapped legacy store). | ||
| */ | ||
@@ -732,3 +797,4 @@ get capabilities(): KeyvStorageCapability; | ||
| /** | ||
| * Sets the namespace. | ||
| * Sets the namespace. When the wrapped store manages its own namespace, the value is | ||
| * propagated to it so its native scoped operations stay in sync. | ||
| */ | ||
@@ -764,15 +830,21 @@ set namespace(namespace: string | undefined); | ||
| /** | ||
| * Stores a value in the store with an optional TTL. | ||
| * Stores a value in the store with an optional absolute expiry. | ||
| * The wrapped store's `set(key, value, ttl?)` expects a relative duration, so the absolute | ||
| * `expires` is converted to a remaining ttl (`undefined` when already expired or absent). | ||
| * The value is passed through unchanged — the bridge does not wrap it in an envelope — so | ||
| * expiry is enforced by the wrapped legacy store's own ttl handling. (The read-side | ||
| * {@link isDataExpired} check only fires when a caller stores a raw `{ value, expires }` | ||
| * object directly; when Keyv core drives the bridge the value arrives already encoded.) | ||
| * @param key - The key to store the value under | ||
| * @param value - The value to store | ||
| * @param ttl - Optional time-to-live in milliseconds | ||
| * @param expires - Optional absolute expiry as Unix ms since epoch | ||
| * @returns Always returns true indicating success | ||
| */ | ||
| set(key: string, value: any, ttl?: number): Promise<boolean>; | ||
| set(key: string, value: any, expires?: number): Promise<boolean>; | ||
| /** | ||
| * Stores multiple entries in the store at once. | ||
| * Delegates to the store's native setMany if available, otherwise loops over set. | ||
| * @param entries - Array of entries containing key, value, and optional TTL | ||
| * @param entries - Array of entries containing key, value, and optional absolute `expires` | ||
| */ | ||
| setMany<Value>(entries: KeyvEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| setMany<Value>(entries: KeyvStorageEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| /** | ||
@@ -827,2 +899,13 @@ * Checks if a key exists in the store and is not expired. | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvStorageAdapter | KeyvOptions | Map<any, any> | any} store to be provided or just the options | ||
| * @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options | ||
| */ | ||
| constructor(store?: KeyvStorageAdapter | KeyvOptions | KeyvMapAny, options?: Omit<KeyvOptions, "store">); | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvOptions} options to be provided | ||
| */ | ||
| constructor(options?: KeyvOptions); | ||
| /** | ||
| * Stats manager for tracking cache operation metrics (hits, misses, sets, deletes, errors). | ||
@@ -866,13 +949,2 @@ * @default this is disabled. | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvStorageAdapter | KeyvOptions | Map<any, any> | any} store to be provided or just the options | ||
| * @param {Omit<KeyvOptions, 'store'>} [options] if you provide the store you can then provide the Keyv Options | ||
| */ | ||
| constructor(store?: KeyvStorageAdapter | KeyvOptions | KeyvMapAny, options?: Omit<KeyvOptions, "store">); | ||
| /** | ||
| * Keyv Constructor | ||
| * @param {KeyvOptions} options to be provided | ||
| */ | ||
| constructor(options?: KeyvOptions); | ||
| /** | ||
| * Get the current storage adapter. | ||
@@ -968,7 +1040,2 @@ * @returns {KeyvStorageAdapter} The current storage adapter. | ||
| /** | ||
| * When true, Keyv checks expiry at its layer on get/getMany/has/hasMany. | ||
| * When false (default), trusts the storage adapter. | ||
| */ | ||
| get checkExpired(): boolean; | ||
| /** | ||
| * Set the stats. When setting a new instance it will unsubscribe the old listeners | ||
@@ -980,7 +1047,17 @@ * and subscribe the new instance. | ||
| /** | ||
| * Resolves a store to a fully-compliant KeyvStorageAdapter using a 3-tier detection chain: | ||
| * 1. If the store already implements the full KeyvStorageAdapter interface, use it directly. | ||
| * 2. If the store is map-like (synchronous get/set/delete/has), wrap it in KeyvMemoryAdapter. | ||
| * 3. If the store has async get/set/delete/clear, wrap it in KeyvBridgeAdapter. | ||
| * 4. Otherwise, emit an error and fall back to a default in-memory KeyvMemoryAdapter. | ||
| * Get whether Keyv checks expiry at its own layer on get/getMany/has/hasMany. | ||
| * When false (default), it trusts the storage adapter to handle expiry. | ||
| * @returns {boolean} `true` if Keyv checks expiry at its layer. | ||
| */ | ||
| get checkExpired(): boolean; | ||
| /** | ||
| * Resolves a store to a fully-compliant KeyvStorageAdapter: | ||
| * 1. If the store declares the v6 `capabilities.expires` contract, use it directly (this takes | ||
| * precedence over structural detection, so a full adapter whose async methods aren't written | ||
| * with the `async` keyword is not mis-bridged). | ||
| * 2. If the store implements the full async storage interface (but doesn't declare `expires`), | ||
| * treat it as a legacy relative-`ttl` adapter and wrap it in KeyvBridgeAdapter. | ||
| * 3. If the store is map-like (synchronous get/set/delete/has), wrap it in KeyvMemoryAdapter. | ||
| * 4. If the store has async get/set/delete/clear, wrap it in KeyvBridgeAdapter. | ||
| * 5. Otherwise, emit an error and fall back to a default in-memory KeyvMemoryAdapter. | ||
| * | ||
@@ -1004,4 +1081,8 @@ * NOTE: this is used for internal but provided public for custom adapter testing | ||
| /** | ||
| * Get the Value of a Key | ||
| * Get the value of a key. If an array of keys is passed in it will return an array of values | ||
| * delegating to {@link getMany}. | ||
| * @param {string | string[]} key passing in a single key or multiple as an array | ||
| * @returns {Promise<Value | undefined | Array<Value | undefined>>} the value of the key, or | ||
| * `undefined` if the key does not exist or is expired. When an array of keys is passed in it | ||
| * returns an array of values in the same order (with `undefined` for missing keys). | ||
| */ | ||
@@ -1011,5 +1092,16 @@ get<Value = GenericValue>(key: string): Promise<Value | undefined>; | ||
| /** | ||
| * Get many values of keys | ||
| * @param {string[]} keys passing in a single key or multiple as an array | ||
| * Reads many keys from the store, preferring its native `getMany` and falling back to parallel | ||
| * single `get`s when an adapter does not implement it. A directly-used v6 adapter is not | ||
| * structurally required to provide `getMany` (the bridge and memory adapters always do), so | ||
| * this keeps `getMany`/`getManyRaw` working regardless of the resolved adapter. | ||
| * @param keys - the keys to read | ||
| * @returns the raw store results in the same order as `keys` | ||
| */ | ||
| private storeGetMany; | ||
| /** | ||
| * Get many values for an array of keys. | ||
| * @param {string[]} keys the keys to get | ||
| * @returns {Promise<Array<Value | undefined>>} an array of values in the same order as the | ||
| * keys, with `undefined` for keys that do not exist or are expired. | ||
| */ | ||
| getMany<Value = GenericValue>(keys: string[]): Promise<Array<Value | undefined>>; | ||
@@ -1031,6 +1123,6 @@ /** | ||
| * Set an item to the store | ||
| * @param {string | Array<KeyvEntry<Value>>} key the key to use. If you pass in an array of KeyvEntry it will set many items | ||
| * @param {string} key the key to use | ||
| * @param {Value} value the value of the key | ||
| * @param {number} [ttl] time to live in milliseconds | ||
| * @returns {boolean} if it sets then it will return a true. On failure will return false. | ||
| * @param {number} [ttl] time to live in milliseconds. Overrides the instance-level `ttl`. | ||
| * @returns {Promise<boolean>} `true` if it was set successfully, `false` on failure. | ||
| */ | ||
@@ -1041,3 +1133,3 @@ set<Value = GenericValue>(key: string, value: Value, ttl?: number): Promise<boolean>; | ||
| * @param {Array<KeyvEntry<Value>>} entries the entries to set | ||
| * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false. | ||
| * @returns {Promise<boolean[]>} an array of booleans, one per entry: `true` if set successfully, `false` on failure. | ||
| */ | ||
@@ -1052,3 +1144,3 @@ setMany<Value = GenericValue>(entries: KeyvEntry<Value>[]): Promise<boolean[]>; | ||
| * @param {KeyvValue<Value>} value the raw value envelope to store | ||
| * @returns {boolean} if it sets then it will return a true. On failure will return false. | ||
| * @returns {Promise<boolean>} `true` if it was set successfully, `false` on failure. | ||
| */ | ||
@@ -1061,15 +1153,16 @@ setRaw<Value = GenericValue>(key: string, value: KeyvValue<Value>): Promise<boolean>; | ||
| * @param {KeyvEntry<KeyvValue<Value>>[]} entries the raw entries to set | ||
| * @returns {boolean[]} will return an array of booleans if it sets then it will return a true. On failure will return false. | ||
| * @returns {Promise<boolean[]>} an array of booleans, one per entry: `true` if set successfully, `false` on failure. | ||
| */ | ||
| setManyRaw<Value = GenericValue>(entries: KeyvEntry<KeyvValue<Value>>[]): Promise<boolean[]>; | ||
| /** | ||
| * Delete an Entry | ||
| * Delete an entry. If an array of keys is passed in it will delete many entries | ||
| * delegating to {@link deleteMany}. | ||
| * @param {string} key the key to be deleted | ||
| * @returns {boolean} will return true if item is deleted. false if there is an error | ||
| * @returns {Promise<boolean>} `true` if the item was deleted, `false` if there was an error. | ||
| */ | ||
| delete(key: string): Promise<boolean>; | ||
| /** | ||
| * Delete multiple Entries | ||
| * Delete multiple entries | ||
| * @param {string[]} keys the keys to be deleted | ||
| * @returns {boolean[]} will return array of booleans for each key | ||
| * @returns {Promise<boolean[]>} an array of booleans indicating success for each key. | ||
| */ | ||
@@ -1080,9 +1173,11 @@ delete(keys: string[]): Promise<boolean[]>; | ||
| * @param {string[]} keys the keys to be deleted | ||
| * @returns {boolean[]} array of booleans indicating success for each key | ||
| * @returns {Promise<boolean[]>} an array of booleans indicating success for each key. | ||
| */ | ||
| deleteMany(keys: string[]): Promise<boolean[]>; | ||
| /** | ||
| * Has a key. | ||
| * @param {string} key the key to check | ||
| * @returns {boolean} will return true if the key exists | ||
| * Check if a key exists. If an array of keys is passed in it will check many keys | ||
| * delegating to {@link hasMany}. | ||
| * @param {string | string[]} key the key (or keys) to check | ||
| * @returns {Promise<boolean | boolean[]>} `true` if the key exists, `false` if not. When an | ||
| * array of keys is passed in it returns an array of booleans in the same order. | ||
| */ | ||
@@ -1094,8 +1189,9 @@ has(key: string[]): Promise<boolean[]>; | ||
| * @param {string[]} keys the keys to check | ||
| * @returns {boolean[]} will return an array of booleans if the keys exist | ||
| * @returns {Promise<boolean[]>} an array of booleans in the same order as the keys, `true` if the key exists. | ||
| */ | ||
| hasMany(keys: string[]): Promise<boolean[]>; | ||
| /** | ||
| * Clear the store | ||
| * @returns {void} | ||
| * Clear the store. If a namespace is set only entries in that namespace are removed. | ||
| * Emits a `clear` event. | ||
| * @returns {Promise<void>} resolves once the entries have been cleared. | ||
| */ | ||
@@ -1227,3 +1323,4 @@ clear(): Promise<void>; | ||
| /** | ||
| * Gets the detected capabilities of the underlying store. | ||
| * Gets the capabilities of the underlying store, with `expires: true` to declare that | ||
| * this adapter accepts an absolute `expires` timestamp (the v6 storage contract). | ||
| */ | ||
@@ -1282,14 +1379,14 @@ get capabilities(): KeyvStorageCapability; | ||
| /** | ||
| * Stores a value in the store with an optional TTL. | ||
| * Stores a value in the store with an optional absolute expiry. | ||
| * @param key - The key to store the value under | ||
| * @param value - The value to store | ||
| * @param ttl - Optional time-to-live in milliseconds | ||
| * @param expires - Optional absolute expiry as Unix ms since epoch | ||
| * @returns Always returns true indicating success | ||
| */ | ||
| set(key: string, value: any, ttl?: number): Promise<boolean>; | ||
| set(key: string, value: any, expires?: number): Promise<boolean>; | ||
| /** | ||
| * Stores multiple entries in the store at once. | ||
| * @param entries - Array of entries containing key, value, and optional TTL | ||
| * @param entries - Array of entries containing key, value, and optional absolute `expires` | ||
| */ | ||
| setMany<Value>(entries: KeyvEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| setMany<Value>(entries: KeyvStorageEntry<Value>[]): Promise<boolean[] | undefined>; | ||
| /** | ||
@@ -1375,2 +1472,2 @@ * Deletes a value from the store by key. | ||
| //#endregion | ||
| export { type DeserializedData, Keyv, Keyv as default, KeyvBridgeAdapter, type KeyvBridgeAdapterOptions, type KeyvBridgeStore, type KeyvCapability, type KeyvCompression, type KeyvCompressionAdapter, type KeyvCompressionCapability, type KeyvCompressionMethods, type KeyvEncryptionAdapter, type KeyvEncryptionCapability, type KeyvEncryptionMethods, type KeyvEntry, KeyvEvents, KeyvHooks, KeyvJsonSerializer, type KeyvMapAny, type KeyvMapType, KeyvMemoryAdapter, type KeyvMemoryAdapterOptions, type KeyvMethods, type KeyvOptions, type KeyvProperties, KeyvSanitize, type KeyvSanitizeAdapter, type KeyvSanitizeOptions, type KeyvSanitizePatterns, type KeyvSerializationAdapter, type KeyvSerializationCapability, type KeyvSerializationMethods, KeyvStats, type KeyvStatsOptions, type KeyvStorageAdapter, type KeyvStorageCapability, type KeyvStorageGetResult, type KeyvStorageMethod, type KeyvStorageMethods, type KeyvStoreAdapter, type KeyvTelemetryEvent, type KeyvValue, type MethodType, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer }; | ||
| export { type DeserializedData, Keyv, Keyv as default, KeyvBridgeAdapter, type KeyvBridgeAdapterOptions, type KeyvBridgeStore, type KeyvCapability, type KeyvCompression, type KeyvCompressionAdapter, type KeyvCompressionCapability, type KeyvCompressionMethods, type KeyvEncryptionAdapter, type KeyvEncryptionCapability, type KeyvEncryptionMethods, type KeyvEntry, KeyvEvents, KeyvHooks, KeyvJsonSerializer, type KeyvMapAny, type KeyvMapType, KeyvMemoryAdapter, type KeyvMemoryAdapterOptions, type KeyvMethods, type KeyvOptions, type KeyvProperties, KeyvSanitize, type KeyvSanitizeAdapter, type KeyvSanitizeOptions, type KeyvSanitizePatterns, type KeyvSerializationAdapter, type KeyvSerializationCapability, type KeyvSerializationMethods, KeyvStats, type KeyvStatsOptions, type KeyvStorageAdapter, type KeyvStorageCapability, type KeyvStorageEntry, type KeyvStorageGetResult, type KeyvStorageMethod, type KeyvStorageMethods, type KeyvStoreAdapter, type KeyvTelemetryEvent, type KeyvValue, type MethodType, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer, keyvStorageCapability }; |
+0
-10
@@ -6,12 +6,2 @@ MIT License | ||
| Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| of this software and associated documentation files (the "Software"), to deal | ||
| in the Software without restriction, including without limitation the rights | ||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| copies of the Software, and to permit persons to whom the Software is | ||
| furnished to do so, subject to the following conditions: | ||
| The above copyright notice and this permission notice shall be included in all | ||
| copies or substantial portions of the Software. | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
@@ -18,0 +8,0 @@ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
+1
-1
| { | ||
| "name": "keyv", | ||
| "version": "6.0.0-beta.3", | ||
| "version": "6.0.0-beta.4", | ||
| "description": "Simple key-value storage with support for multiple backends", | ||
@@ -5,0 +5,0 @@ "type": "module", |
+203
-136
@@ -8,6 +8,7 @@ <h1 align="center"><img width="250" src="https://jaredwray.com/images/keyv.svg" alt="keyv"></h1> | ||
| [](https://github.com/jaredwray/keyv/actions/workflows/browser-compat.yaml) | ||
| [](https://codecov.io/gh/jaredwray/keyv) | ||
| [](https://www.jsdelivr.com/package/npm/keyv) | ||
| [](https://codecov.io/gh/jaredwray/keyv) | ||
| [](https://www.npmjs.com/package/keyv) | ||
| [](https://www.npmjs.com/package/keyv) | ||
| Keyv provides a consistent interface for key-value storage across multiple backends via storage adapters. It supports TTL based expiry, making it suitable as a cache or a persistent key-value store. | ||
@@ -49,6 +50,6 @@ | ||
| - [.serialization](#serialization-1) | ||
| - [.compression](#compression) | ||
| - [.useKeyPrefix](#usekeyprefix) | ||
| - [.emitErrors](#emiterrors) | ||
| - [.compression](#compression-1) | ||
| - [.encryption](#encryption-1) | ||
| - [.throwOnErrors](#throwonerrors) | ||
| - [.checkExpired](#checkexpired) | ||
| - [.stats](#stats) | ||
@@ -59,4 +60,4 @@ - [.sanitize](#sanitize) | ||
| - [.setMany(entries)](#setmanyentries) | ||
| - [.get(key, [options])](#getkey-options) | ||
| - [.getMany(keys, [options])](#getmanykeys-options) | ||
| - [.get(key)](#getkey) | ||
| - [.getMany(keys)](#getmanykeys) | ||
| - [.getRaw(key)](#getrawkey) | ||
@@ -198,8 +199,7 @@ - [.getManyRaw(keys)](#getmanyrawkeys) | ||
| Keyv is a custom `EventEmitter` and will emit an `'error'` event if there is an error. | ||
| If there is no listener for the `'error'` event, an uncaught exception will be thrown. | ||
| To disable the `'error'` event, pass `emitErrors: false` in the constructor options. | ||
| Keyv is an `EventEmitter` (built on [hookified](https://github.com/jaredwray/hookified)) and will emit an `'error'` event if there is an error. By default an error is only thrown if there are no listeners attached to the `'error'` event. To always throw on errors regardless of listeners, enable the [`throwOnErrors`](#throwonerrors) option. | ||
| ```js | ||
| const keyv = new Keyv({ emitErrors: false }); | ||
| const keyv = new Keyv(); | ||
| keyv.on('error', err => console.log('Connection Error', err)); | ||
| ``` | ||
@@ -222,27 +222,32 @@ | ||
| Keyv supports hooks for `get`, `set`, and `delete` methods. Hooks are useful for logging, debugging, and other custom functionality. Here is a list of all the hooks: | ||
| Keyv supports hooks for all of its operations. Hooks are useful for logging, debugging, and other custom functionality. Each operation fires a `BEFORE_*` hook before it runs and an `AFTER_*` hook after it completes. Here is the list of all the hooks: | ||
| ``` | ||
| PRE_GET | ||
| POST_GET | ||
| PRE_GET_RAW | ||
| POST_GET_RAW | ||
| PRE_GET_MANY | ||
| POST_GET_MANY | ||
| PRE_GET_MANY_RAW | ||
| POST_GET_MANY_RAW | ||
| PRE_SET | ||
| POST_SET | ||
| PRE_SET_RAW | ||
| POST_SET_RAW | ||
| PRE_SET_MANY_RAW | ||
| POST_SET_MANY_RAW | ||
| PRE_DELETE | ||
| POST_DELETE | ||
| BEFORE_GET / AFTER_GET | ||
| BEFORE_GET_MANY / AFTER_GET_MANY | ||
| BEFORE_GET_RAW / AFTER_GET_RAW | ||
| BEFORE_GET_MANY_RAW / AFTER_GET_MANY_RAW | ||
| BEFORE_SET / AFTER_SET | ||
| BEFORE_SET_RAW / AFTER_SET_RAW | ||
| BEFORE_SET_MANY / AFTER_SET_MANY | ||
| BEFORE_SET_MANY_RAW / AFTER_SET_MANY_RAW | ||
| BEFORE_DELETE / AFTER_DELETE | ||
| BEFORE_DELETE_MANY / AFTER_DELETE_MANY | ||
| BEFORE_HAS / AFTER_HAS | ||
| BEFORE_HAS_MANY / AFTER_HAS_MANY | ||
| BEFORE_CLEAR / AFTER_CLEAR | ||
| BEFORE_DISCONNECT / AFTER_DISCONNECT | ||
| ``` | ||
| You can access this by importing `KeyvHooks` from the main Keyv package. | ||
| > The older `PRE_*` / `POST_*` hook names (e.g. `PRE_GET`, `POST_SET`) are deprecated aliases that still fire for backward compatibility. Prefer the `BEFORE_*` / `AFTER_*` names going forward. | ||
| You can access these by importing `KeyvHooks` from the main Keyv package and registering a handler with `onHook()`: | ||
| ```js | ||
| import Keyv, { KeyvHooks } from 'keyv'; | ||
| const keyv = new Keyv(); | ||
| keyv.onHook(KeyvHooks.BEFORE_SET, (data) => { | ||
| console.log(`Setting key ${data.key} to ${data.value}`); | ||
| }); | ||
| ``` | ||
@@ -252,8 +257,8 @@ | ||
| 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. | ||
| The `AFTER_GET` and `AFTER_GET_RAW` hooks fire on both cache hits and misses. When a cache miss occurs (key doesn't exist or is expired), the hook receives `undefined` as the value. | ||
| ```js | ||
| // POST_GET hook - fires on both hits and misses | ||
| // AFTER_GET hook - fires on both hits and misses | ||
| const keyv = new Keyv(); | ||
| keyv.hooks.addHandler(KeyvHooks.POST_GET, (data) => { | ||
| keyv.onHook(KeyvHooks.AFTER_GET, (data) => { | ||
| if (data.value === undefined) { | ||
@@ -271,5 +276,5 @@ console.log(`Cache miss for key: ${data.key}`); | ||
| ```js | ||
| // POST_GET_RAW hook - same behavior as POST_GET | ||
| // AFTER_GET_RAW hook - same behavior as AFTER_GET | ||
| const keyv = new Keyv(); | ||
| keyv.hooks.addHandler(KeyvHooks.POST_GET_RAW, (data) => { | ||
| keyv.onHook(KeyvHooks.AFTER_GET_RAW, (data) => { | ||
| console.log(`Key: ${data.key}, Value:`, data.value); | ||
@@ -284,16 +289,16 @@ }); | ||
| ```js | ||
| //PRE_SET hook | ||
| // BEFORE_SET hook | ||
| const keyv = new Keyv(); | ||
| keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data) => console.log(`Setting key ${data.key} to ${data.value}`)); | ||
| keyv.onHook(KeyvHooks.BEFORE_SET, (data) => console.log(`Setting key ${data.key} to ${data.value}`)); | ||
| //POST_SET hook | ||
| // AFTER_SET hook | ||
| const keyv = new Keyv(); | ||
| keyv.hooks.addHandler(KeyvHooks.POST_SET, ({key, value}) => console.log(`Set key ${key} to ${value}`)); | ||
| keyv.onHook(KeyvHooks.AFTER_SET, ({ key, value }) => console.log(`Set key ${key} to ${value}`)); | ||
| ``` | ||
| In these examples you can also manipulate the value before it is set. For example, you could add a prefix to all keys. | ||
| In the `BEFORE_SET` hook you can also manipulate the value before it is set. For example, you could add a prefix to all keys. | ||
| ```js | ||
| const keyv = new Keyv(); | ||
| keyv.hooks.addHandler(KeyvHooks.PRE_SET, (data) => { | ||
| keyv.onHook(KeyvHooks.BEFORE_SET, (data) => { | ||
| console.log(`Manipulating key ${data.key} and ${data.value}`); | ||
@@ -305,7 +310,7 @@ data.key = `prefix-${data.key}`; | ||
| Now this key will have prefix- added to it before it is set. | ||
| Now this key will have `prefix-` added to it before it is set. | ||
| ## Delete Hooks | ||
| 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. | ||
| In the `BEFORE_DELETE` and `AFTER_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. | ||
@@ -364,9 +369,9 @@ | ||
| When serialization and/or compression are configured, Keyv applies them in this order: | ||
| When serialization, compression, and/or encryption are configured, Keyv applies them in this order: | ||
| **On set:** serialize (optional) → compress (optional) → store | ||
| **On set:** serialize → compress (optional) → encrypt (optional) → store | ||
| **On get:** store → decompress (optional) → parse (optional) → value | ||
| **On get:** store → decrypt (optional) → decompress (optional) → parse → value | ||
| If compression is configured without a serializer, Keyv will use `JSON.stringify`/`JSON.parse` as a minimum fallback since compression adapters require string input. | ||
| Compression and encryption operate on the serialized string, so they only run when a serializer is configured. The built-in `KeyvJsonSerializer` is enabled by default, so this works out of the box. If you disable serialization with `serialization: false`, values are passed through to the store as-is and compression/encryption are skipped. | ||
@@ -420,2 +425,30 @@ # Official Storage Adapters | ||
| ## Storage Adapter Contract (v6) | ||
| > The public API above is unchanged — `keyv.set(key, value, ttl)` still takes a relative TTL in milliseconds. The change below only affects authors of custom **storage adapters**. | ||
| As of v6, Keyv passes an **absolute `expires`** timestamp (Unix ms since epoch) to a storage adapter's write methods instead of a relative TTL. Keyv computes `expires` once, so adapters never need to derive or parse it: | ||
| ```ts | ||
| import { keyvStorageCapability } from 'keyv'; | ||
| type KeyvStorageEntry<Value> = { key: string; value: Value; expires?: number }; | ||
| class MyAdapter { | ||
| // Declare support for the absolute-`expires` contract: | ||
| get capabilities() { | ||
| return keyvStorageCapability(this); // -> { ...detected, expires: true } | ||
| } | ||
| // `expires` is absolute Unix ms; `undefined` means no expiry; `<= Date.now()` means already expired. | ||
| async set(key: string, value: unknown, expires?: number): Promise<boolean> { /* ... */ } | ||
| async setMany<Value>(entries: KeyvStorageEntry<Value>[]): Promise<boolean[] | undefined> { /* ... */ } | ||
| // ...get, delete, clear, has, getMany, deleteMany, hasMany, etc. | ||
| } | ||
| ``` | ||
| A v6 adapter declares `capabilities.expires === true` (the `keyvStorageCapability(this)` helper sets it for you). Keyv then passes the absolute `expires` to it directly — this takes precedence over structural detection, so an adapter whose methods aren't written with `async` is still used directly rather than bridged. Any **legacy** storage adapter that does *not* declare `capabilities.expires` is treated as a relative-TTL adapter and transparently wrapped by [`KeyvBridgeAdapter`](#third-party-storage-adapters), which converts the absolute `expires` back to a relative TTL before delegating (and deletes outright when the deadline has already elapsed) — so existing third-party adapters keep working unchanged. Stores that expose absolute-expiry primitives (e.g. Redis `PXAT`) use `expires` directly. Map-like stores wrapped via `new Keyv({ store: new Map() })` are unaffected. | ||
| > **Adapters are the expiry authority.** Declaring `capabilities.expires === true` is a two-way contract: because Keyv core does not filter expired reads by default (`checkExpired` is off), a v6 adapter must enforce expiry itself — `get`/`getMany`/`has` must not return a key past its deadline, whether via a native mechanism (key expiry, TTL index, lease) or a client-side check. Run `@keyv/test-suite`'s `storageTtlTests` against your adapter to verify it. | ||
| # Using BigMap to Scale | ||
@@ -531,3 +564,3 @@ | ||
| Keyv provides a `KeyvEncryptionAdapter` interface for encryption support. This interface is available for custom implementations but is not yet wired into the core pipeline. | ||
| Keyv supports pluggable encryption of stored values via the `KeyvEncryptionAdapter` interface. Pass an adapter with `encrypt` and `decrypt` methods using the `encryption` option (or set the [`.encryption`](#encryption-1) property). Encryption runs on the serialized (and optionally compressed) value, so it requires a serializer — the built-in `KeyvJsonSerializer` is enabled by default. | ||
@@ -541,5 +574,18 @@ ```typescript | ||
| ```js | ||
| import Keyv from 'keyv'; | ||
| const encryption = { | ||
| encrypt: async (data) => Buffer.from(data).toString('base64'), | ||
| decrypt: async (data) => Buffer.from(data, 'base64').toString('utf8'), | ||
| }; | ||
| const keyv = new Keyv({ encryption }); | ||
| await keyv.set('foo', 'bar'); // value is encrypted at rest | ||
| await keyv.get('foo'); // 'bar' | ||
| ``` | ||
| # Capability Detection | ||
| Keyv exports helper functions to check whether an object implements the expected interface for a Keyv instance, storage adapter, compression adapter, serialization adapter, or encryption adapter. Each function returns an object with boolean flags for every capability, plus a top-level boolean indicating whether the object fully satisfies the interface. | ||
| Keyv exports helper functions to check whether an object implements the expected interface for a Keyv instance, storage adapter, compression adapter, serialization adapter, or encryption adapter. Each function returns an object with a top-level `compatible` boolean (whether the object fully satisfies the interface) plus a `methods` record describing every method it looked for. | ||
@@ -553,9 +599,10 @@ ```ts | ||
| detectKeyvEncryption, | ||
| detectCapabilities, | ||
| } from 'keyv'; | ||
| ``` | ||
| Every entry in the `methods` record has the shape `{ exists: boolean, methodType: "sync" | "async" | "none" }`. | ||
| ## detectKeyv(obj) | ||
| Returns a `KeyvCapability` with a boolean for each Keyv method/property. The `keyv` flag is `true` only when **all** capabilities are present. | ||
| Returns a `KeyvCapability`: `{ compatible, methods, properties }`. `compatible` is `true` only when **all** Keyv methods and properties are present. | ||
@@ -565,10 +612,12 @@ ```ts | ||
| detectKeyv(new Keyv()); | ||
| // { keyv: true, get: true, set: true, delete: true, clear: true, has: true, | ||
| // getMany: true, setMany: true, deleteMany: true, hasMany: true, | ||
| // disconnect: true, getRaw: true, getManyRaw: true, setRaw: true, | ||
| // setManyRaw: true, hooks: true, stats: true, iterator: true } | ||
| const result = detectKeyv(new Keyv()); | ||
| result.compatible; // true — all capabilities present | ||
| result.methods.get.exists; // true | ||
| result.methods.get.methodType; // "async" | ||
| result.properties.hooks; // true | ||
| result.properties.stats; // true | ||
| detectKeyv(new Map()); | ||
| // { keyv: false, get: true, set: true, ... } | ||
| const partial = detectKeyv(new Map()); | ||
| partial.compatible; // false — missing getMany, setMany, hooks, stats, etc. | ||
| partial.methods.get.exists; // true | ||
| ``` | ||
@@ -578,7 +627,8 @@ | ||
| Returns a `KeyvStorageCapability`. The `keyvStorage` flag is `true` when the object has `get`, `set`, `delete`, `clear`, `has`, `setMany`, `deleteMany`, and `hasMany`. | ||
| Returns a `KeyvStorageCapability`: `{ compatible, store, methods }`. `compatible` is `true` when the object is a usable storage adapter, and `store` reports the detected kind: | ||
| The result also includes: | ||
| - **`mapLike`** — `true` when the object has synchronous `get`, `set`, `delete`, `has`, `entries`, and `keys` methods (i.e. it behaves like a `Map`) | ||
| - **`methodTypes`** — a record mapping each method name to `"sync"`, `"async"`, or `"none"` (not present) | ||
| - **`"keyvStorage"`** — implements the full async storage adapter interface (`get`, `set`, `delete`, `clear`, `has`, `setMany`, `deleteMany`, `hasMany`, all async) | ||
| - **`"mapLike"`** — has synchronous `get`, `set`, `delete`, and `has` (i.e. it behaves like a `Map`) | ||
| - **`"asyncMap"`** — has at least async `get`, `set`, `delete`, and `clear` | ||
| - **`"none"`** — not a usable store | ||
@@ -589,6 +639,6 @@ ```ts | ||
| // Map-like object | ||
| const result = detectKeyvStorage(new Map()); | ||
| result.mapLike; // true | ||
| result.methodTypes.get; // "sync" | ||
| result.methodTypes.set; // "sync" | ||
| const map = detectKeyvStorage(new Map()); | ||
| map.compatible; // true | ||
| map.store; // "mapLike" | ||
| map.methods.get.methodType; // "sync" | ||
@@ -602,5 +652,5 @@ // Async storage adapter | ||
| const adapterResult = detectKeyvStorage(adapter); | ||
| adapterResult.keyvStorage; // true | ||
| adapterResult.mapLike; // false | ||
| adapterResult.methodTypes.get; // "async" | ||
| adapterResult.compatible; // true | ||
| adapterResult.store; // "keyvStorage" | ||
| adapterResult.methods.get.methodType; // "async" | ||
| ``` | ||
@@ -610,3 +660,3 @@ | ||
| Returns a `KeyvCompressionCapability`. The `keyvCompression` flag is `true` when both `compress` and `decompress` methods are present. | ||
| Returns a `KeyvCompressionCapability`: `{ compatible, methods }`. `compatible` is `true` when both `compress` and `decompress` methods are present. | ||
@@ -616,4 +666,6 @@ ```ts | ||
| detectKeyvCompression({ compress: (d) => d, decompress: (d) => d }); | ||
| // { keyvCompression: true, compress: true, decompress: true } | ||
| const result = detectKeyvCompression({ compress: (d) => d, decompress: (d) => d }); | ||
| result.compatible; // true | ||
| result.methods.compress.exists; // true | ||
| result.methods.decompress.exists; // true | ||
| ``` | ||
@@ -623,3 +675,3 @@ | ||
| Returns a `KeyvSerializationCapability`. The `keyvSerialization` flag is `true` when both `stringify` and `parse` methods are present. | ||
| Returns a `KeyvSerializationCapability`: `{ compatible, methods }`. `compatible` is `true` when both `stringify` and `parse` methods are present. | ||
@@ -629,4 +681,6 @@ ```ts | ||
| detectKeyvSerialization(JSON); | ||
| // { keyvSerialization: true, stringify: true, parse: true } | ||
| const result = detectKeyvSerialization(JSON); | ||
| result.compatible; // true | ||
| result.methods.stringify.exists; // true | ||
| result.methods.parse.exists; // true | ||
| ``` | ||
@@ -636,3 +690,3 @@ | ||
| Returns a `KeyvEncryptionCapability`. The `keyvEncryption` flag is `true` when both `encrypt` and `decrypt` methods are present. | ||
| Returns a `KeyvEncryptionCapability`: `{ compatible, methods }`. `compatible` is `true` when both `encrypt` and `decrypt` methods are present. | ||
@@ -642,22 +696,8 @@ ```ts | ||
| detectKeyvEncryption({ encrypt: (d) => d, decrypt: (d) => d }); | ||
| // { keyvEncryption: true, encrypt: true, decrypt: true } | ||
| const result = detectKeyvEncryption({ encrypt: (d) => d, decrypt: (d) => d }); | ||
| result.compatible; // true | ||
| result.methods.encrypt.exists; // true | ||
| result.methods.decrypt.exists; // true | ||
| ``` | ||
| ## detectCapabilities(obj, spec) | ||
| A generic helper for building your own capability checks. Accepts a `CapabilitySpec` describing which methods and properties to look for, which are required, and the name of the composite boolean key. | ||
| ```ts | ||
| import { detectCapabilities } from 'keyv'; | ||
| const result = detectCapabilities(myObject, { | ||
| methods: ['read', 'write'], | ||
| properties: ['name'], | ||
| requiredKeys: ['read', 'write', 'name'], | ||
| compositeKey: 'isValid', | ||
| }); | ||
| // { isValid: true/false, read: true/false, write: true/false, name: true/false } | ||
| ``` | ||
| # API | ||
@@ -726,2 +766,37 @@ | ||
| ## options.stats | ||
| Type: `Boolean`<br /> | ||
| Default: `false` | ||
| Enable statistics tracking (hits, misses, sets, deletes, errors). See [.stats](#stats) for details. | ||
| ## options.throwOnErrors | ||
| Type: `Boolean`<br /> | ||
| Default: `false` | ||
| Throw on all errors instead of only when there are no `'error'` listeners. See [.throwOnErrors](#throwonerrors) for details. | ||
| ## options.sanitize | ||
| Type: `KeyvSanitizeOptions`<br /> | ||
| Default: `undefined` | ||
| Enable sanitization of keys and namespaces by stripping dangerous patterns. See [.sanitize](#sanitize) for details. | ||
| ## options.encryption | ||
| Type: `KeyvEncryptionAdapter`<br /> | ||
| Default: `undefined` | ||
| Encryption adapter used to encrypt and decrypt stored values. See [Encryption](#encryption) for details. | ||
| ## options.checkExpired | ||
| Type: `Boolean`<br /> | ||
| Default: `false` | ||
| When `true`, Keyv checks expiry at its own layer on `get`/`getMany`/`has`/`hasMany` instead of trusting the storage adapter. See [.checkExpired](#checkexpired) for details. | ||
| # Keyv Instance | ||
@@ -743,9 +818,9 @@ | ||
| ## .get(key, [options]) | ||
| ## .get(key) | ||
| Returns a promise which resolves to the retrieved value. | ||
| Returns a promise which resolves to the retrieved value, or `undefined` if the key does not exist or is expired. If an array of keys is passed it delegates to `.getMany()` and resolves to an array of values. | ||
| ## .getMany(keys, [options]) | ||
| ## .getMany(keys) | ||
| Returns a promise which resolves to an array of retrieved values. | ||
| Returns a promise which resolves to an array of retrieved values, with `undefined` for keys that do not exist or are expired. | ||
@@ -861,3 +936,3 @@ ## .getRaw(key) | ||
| - **Storage adapters**: delegates to the adapter's `iterator()` method (e.g., Redis SCAN, SQL cursor) | ||
| - **Unsupported stores**: emits an `error` event if the store does not support iteration | ||
| - **Unsupported stores**: yields nothing if the store does not support iteration | ||
@@ -945,44 +1020,29 @@ # API - Properties | ||
| ## .useKeyPrefix | ||
| ## .encryption | ||
| Type: `Boolean`<br /> | ||
| Default: `true` | ||
| Type: `KeyvEncryptionAdapter`<br /> | ||
| Default: `undefined` | ||
| If set to `true` Keyv will prefix all keys with the namespace. This is useful if you want to avoid collisions with other data in your storage. | ||
| The encryption adapter used to encrypt and decrypt stored values. If `undefined` (default) values are not encrypted. See [Encryption](#encryption) for more details. | ||
| ```js | ||
| const keyv = new Keyv({ useKeyPrefix: false }); | ||
| console.log(keyv.useKeyPrefix); // false | ||
| keyv.useKeyPrefix = true; | ||
| console.log(keyv.useKeyPrefix); // true | ||
| const keyv = new Keyv(); | ||
| console.log(keyv.encryption); // undefined | ||
| keyv.encryption = { | ||
| encrypt: async (data) => Buffer.from(data).toString('base64'), | ||
| decrypt: async (data) => Buffer.from(data, 'base64').toString('utf8'), | ||
| }; | ||
| console.log(keyv.encryption); // the encryption adapter | ||
| ``` | ||
| With many of the storage adapters you will also need to set the `namespace` option to `undefined` to have it work correctly. This is because in `v5` we started the transition to having the storage adapter handle the namespacing and `Keyv` will no longer handle it internally via KeyPrefixing. Here is an example of doing ith with `KeyvSqlite`: | ||
| ## .checkExpired | ||
| ```js | ||
| import Keyv from 'keyv'; | ||
| import KeyvSqlite from '@keyv/sqlite'; | ||
| const store = new KeyvSqlite('sqlite://path/to/database.sqlite'); | ||
| const keyv = new Keyv({ store }); | ||
| keyv.useKeyPrefix = false; // disable key prefixing | ||
| store.namespace = undefined; // disable namespacing in the storage adapter | ||
| await keyv.set('foo', 'bar'); // true | ||
| await keyv.get('foo'); // 'bar' | ||
| await keyv.clear(); | ||
| ``` | ||
| ## .emitErrors | ||
| Type: `Boolean`<br /> | ||
| Default: `true` | ||
| Default: `false` | ||
| If set to `true`, Keyv will emit an `'error'` event when an error occurs. Set to `false` to suppress error events. | ||
| A read-only property (configured via the `checkExpired` constructor option). When `true`, Keyv checks expiry at its own layer on `get`, `getMany`, `has`, and `hasMany`, deleting any expired entries it encounters. When `false` (default) it trusts the storage adapter to handle expiry. | ||
| ```js | ||
| const keyv = new Keyv({ emitErrors: false }); | ||
| console.log(keyv.emitErrors); // false | ||
| keyv.emitErrors = true; | ||
| console.log(keyv.emitErrors); // true | ||
| const keyv = new Keyv({ checkExpired: true }); | ||
| console.log(keyv.checkExpired); // true | ||
| ``` | ||
@@ -1090,7 +1150,9 @@ | ||
| ## .sanitize | ||
| Type: `boolean | KeyvSanitizeOptions`<br /> | ||
| Default: `false` | ||
| Type: `KeyvSanitize` (configured via the `sanitize` option: `KeyvSanitizeOptions`)<br /> | ||
| Default: disabled | ||
| Detects and strips dangerous patterns from keys and namespaces to protect against SQL injection, MongoDB operator injection, path traversal, and control character attacks. Harmless characters like quotes, slashes, and dollar signs pass through unchanged — only dangerous *patterns* are stripped. | ||
| The `.sanitize` property is a `KeyvSanitize` adapter. It is configured through the `sanitize` constructor option (`true`, or a `KeyvSanitizeOptions` object) and disabled by default. | ||
| It detects and strips dangerous patterns from keys and namespaces to protect against SQL injection, MongoDB operator injection, path traversal, and control character attacks. Harmless characters like quotes, slashes, and dollar signs pass through unchanged — only dangerous *patterns* are stripped. | ||
| Results are cached in an LRU cache (10,000 entries) for fast repeated lookups. | ||
@@ -1149,7 +1211,12 @@ | ||
| Change at runtime: | ||
| Change at runtime by updating the options on the existing adapter, or by replacing it: | ||
| ```js | ||
| keyv.sanitize = false; // disable | ||
| keyv.sanitize = true; // enable all | ||
| keyv.sanitize = { keys: { sql: true, mongo: false } }; // granular | ||
| import { KeyvSanitize } from 'keyv'; | ||
| // Update options on the existing adapter | ||
| keyv.sanitize.updateOptions({ keys: true, namespace: true }); // enable all | ||
| keyv.sanitize.updateOptions({ keys: { sql: true, mongo: false } }); // granular | ||
| // Or replace the adapter entirely | ||
| keyv.sanitize = new KeyvSanitize({ keys: true, namespace: true }); | ||
| ``` | ||
@@ -1156,0 +1223,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Mixed license
LicensePackage contains multiple licenses.
Non-permissive License
LicenseA license not known to be considered permissive was found.
Unidentified License
LicenseSomething that seems like a license was found, but its contents could not be matched with a known license.
320183
9.06%4715
3.51%1211
5.86%3
Infinity%80
-20%