Sign In

keyv

Package Overview
Dependencies
Maintainers
2
Versions
86
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

keyv - npm Package Compare versions

Comparing version
6.0.0-beta.4
to
6.0.0-rc.1
+141
-69
dist/index.d.cts
import { Hookified, IEventEmitter } from "hookified";
//#region src/capabilities.d.ts

@@ -30,7 +29,7 @@ type MethodType = "sync" | "async" | "none";

*
* 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
* Declaring `expires: true` means the adapter is used directly and should ENFORCE expiry —
* ideally via a native mechanism (TTL index, key expiry, lease) so the backend reclaims
* space, and/or a client-side check on read. Keyv core also filters expired reads by default
* (`checkExpired` is on), so an adapter with coarse or lazily-swept native expiry (e.g.
* Memcached, DynamoDB) still reads millisecond-precise. Validate with `@keyv/test-suite`'s
* `storageTtlTests`.

@@ -231,7 +230,13 @@ */

type KeyvSanitizeAdapter = {
/** Whether any sanitization is currently enabled. */readonly enabled: boolean; /** The key sanitization pattern configuration. */
readonly keys: KeyvSanitizePatterns; /** The namespace sanitization pattern configuration. */
readonly namespace: KeyvSanitizePatterns; /** Sanitize a single key. */
cleanKey(key: string): string; /** Sanitize an array of keys. */
cleanKeys(keys: string[]): string[]; /** Sanitize a namespace string. */
/** Whether any sanitization is currently enabled. */
readonly enabled: boolean;
/** The key sanitization pattern configuration. */
readonly keys: KeyvSanitizePatterns;
/** The namespace sanitization pattern configuration. */
readonly namespace: KeyvSanitizePatterns;
/** Sanitize a single key. */
cleanKey(key: string): string;
/** Sanitize an array of keys. */
cleanKeys(keys: string[]): string[];
/** Sanitize a namespace string. */
cleanNamespace(ns: string): string;

@@ -292,5 +297,9 @@ };

type KeyvTelemetryEvent = {
/** The event type (e.g. "hit", "miss", "set", "delete", "error"). */event: string; /** The cache key involved, if applicable. */
key?: string; /** The namespace of the Keyv instance. */
namespace?: string; /** Unix timestamp in milliseconds when the event occurred. */
/** The event type (e.g. "hit", "miss", "set", "delete", "error"). */
event: string;
/** The cache key involved, if applicable. */
key?: string;
/** The namespace of the Keyv instance. */
namespace?: string;
/** Unix timestamp in milliseconds when the event occurred. */
timestamp: number;

@@ -419,5 +428,16 @@ };

/**
* A permissive `any` type used at Keyv's dynamic boundaries — untyped store
* values, parameterized query arguments, and other places where the concrete
* type is intentionally open. Centralizing it keeps the `noExplicitAny`
* suppression in one place instead of scattered across the codebase.
*/
type KeyvAny = any;
/**
* The array counterpart to {@link KeyvAny} (i.e. `any[]`).
*/
type KeyvAnyArray = KeyvAny[];
/**
* A Map or any Map-like object. Used as a flexible input type for stores.
*/
type KeyvMapAny = Map<any, any> | any;
type KeyvMapAny = Map<KeyvAny, KeyvAny> | KeyvAny;
/**

@@ -428,3 +448,5 @@ * The envelope structure used to store values in Keyv.

type KeyvValue<Value> = {
/** The stored value. */value?: Value; /** Absolute expiration timestamp in milliseconds since epoch, or `undefined` for no expiry. */
/** The stored value. */
value?: Value;
/** Absolute expiration timestamp in milliseconds since epoch, or `undefined` for no expiry. */
expires?: number | undefined;

@@ -533,3 +555,3 @@ };

*/
type KeyvEntry<Value = any> = {
type KeyvEntry<Value = KeyvAny> = {
/**

@@ -554,5 +576,8 @@ * Key to set.

*/
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. */
type KeyvStorageEntry<Value = KeyvAny> = {
/** 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;

@@ -578,3 +603,3 @@ };

*/
store?: KeyvStorageAdapter | Map<any, any> | any;
store?: KeyvStorageAdapter | Map<KeyvAny, KeyvAny> | KeyvAny;
/**

@@ -589,3 +614,3 @@ * Default TTL in milliseconds. Can be overridden by specifying a TTL on `.set()`.

*/
compression?: KeyvCompressionAdapter | any;
compression?: KeyvCompressionAdapter | KeyvAny;
/**

@@ -617,5 +642,9 @@ * Enable or disable statistics (default is false)

/**
* When true, Keyv checks expiry on get/getMany/has/hasMany at its layer.
* When false (default), trusts the storage adapter to handle expiry.
* @default false
* When true (default), Keyv checks expiry on get/getMany/has/hasMany at its own layer,
* filtering (and deleting) expired entries using the absolute `expires` stored in the
* serialized envelope. This keeps reads millisecond-precise even on adapters whose native
* expiry is coarse or lazily swept (e.g. Memcached's second-granular exptime, DynamoDB's
* background TTL sweep that can lag for hours). Set to false to trust the storage adapter
* to handle expiry on its own (skips the extra decode + expiry check on reads).
* @default true
*/

@@ -631,3 +660,5 @@ checkExpired?: boolean;

type KeyvSerializationAdapter = {
/** Converts a value to a string representation. */stringify: (object: unknown) => string | Promise<string>; /** Parses a string back into its original value. */
/** Converts a value to a string representation. */
stringify: (object: unknown) => string | Promise<string>;
/** Parses a string back into its original value. */
parse: <T>(data: string) => T | Promise<T>;

@@ -640,3 +671,5 @@ };

type KeyvCompressionAdapter = {
/** Compresses a string value. */compress(value: string): Promise<string>; /** Decompresses a string value back to its original form. */
/** Compresses a string value. */
compress(value: string): Promise<string>;
/** Decompresses a string value back to its original form. */
decompress(value: string): Promise<string>;

@@ -649,3 +682,5 @@ };

type KeyvEncryptionAdapter = {
/** Encrypts a string value. */encrypt: (data: string) => string | Promise<string>; /** Decrypts a string value back to its original form. */
/** Encrypts a string value. */
encrypt: (data: string) => string | Promise<string>;
/** Decrypts a string value back to its original form. */
decrypt: (data: string) => string | Promise<string>;

@@ -659,3 +694,4 @@ };

type KeyvStorageAdapter = {
/** Optional namespace for key isolation. */namespace?: string | undefined;
/** Optional namespace for key isolation. */
namespace?: string | undefined;
/**

@@ -667,7 +703,10 @@ * The adapter's capabilities. v6 adapters set `capabilities.expires = true` (e.g. via

*
* 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}.
* Declaring `expires: true` means the adapter should enforce expiry on read so `get`/`getMany`/
* `has` do not return a key past its deadline (ideally backed by a native mechanism that also
* reclaims space). Keyv core additionally filters expired reads by default (`checkExpired` is
* on), as a safety net for backends with coarse or lazily-swept native expiry. See
* {@link KeyvStorageCapability.expires}.
*/
capabilities?: KeyvStorageCapability; /** Retrieves a value by key. */
capabilities?: KeyvStorageCapability;
/** Retrieves a value by key. */
get<Value>(key: string): Promise<KeyvStorageGetResult<Value>>;

@@ -679,11 +718,20 @@ /**

*/
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). */
clear(): Promise<void>; /** Checks if a key exists in the store. */
has(key: string): Promise<boolean>; /** Checks if multiple keys exist in the store. */
hasMany(keys: string[]): Promise<boolean[]>; /** Retrieves multiple values by keys. */
getMany<Value>(keys: string[]): Promise<Array<KeyvStorageGetResult<Value | undefined>>>; /** Disconnects from the store and releases resources. */
disconnect?(): Promise<void>; /** Deletes multiple keys from the store. */
deleteMany(key: string[]): Promise<boolean[]>; /** Returns an async iterator over all key-value pairs. */
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). */
clear(): Promise<void>;
/** Checks if a key exists in the store. */
has(key: string): Promise<boolean>;
/** Checks if multiple keys exist in the store. */
hasMany(keys: string[]): Promise<boolean[]>;
/** Retrieves multiple values by keys. */
getMany<Value>(keys: string[]): Promise<Array<KeyvStorageGetResult<Value | undefined>>>;
/** Disconnects from the store and releases resources. */
disconnect?(): Promise<void>;
/** Deletes multiple keys from the store. */
deleteMany(key: string[]): Promise<boolean[]>;
/** Returns an async iterator over all key-value pairs. */
iterator?<Value>(): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;

@@ -722,16 +770,30 @@ } & IEventEmitter;

type KeyvBridgeStore = {
/** 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 */
set(key: string, value: any, ttl?: number): Promise<any>; /** Deletes a key from the store */
delete(key: string): Promise<boolean>; /** Clears all entries from the store */
clear(): Promise<void>; /** Checks if a key exists in the store */
has?(key: string): Promise<boolean>; /** Checks if multiple keys exist in the store */
hasMany?(keys: string[]): Promise<boolean[]>; /** Retrieves multiple values by keys */
getMany?(keys: string[]): Promise<any[]>; /** Sets multiple entries at once */
setMany?(entries: any[]): Promise<any>; /** Deletes multiple keys at once */
deleteMany?(keys: string[]): Promise<boolean | boolean[]>; /** Iterates over all entries, optionally filtered by namespace */
iterator?(namespace?: string): AsyncGenerator<any>; /** Disconnects from the store */
disconnect?(): Promise<void>; /** Subscribe to events (e.g. error events from v5 adapters) */
on?(event: string, listener: (...args: any[]) => void): any;
/** Store configuration/options (e.g. dialect, url) */
opts?: KeyvAny;
/** Namespace the store scopes its keys under, when it manages its own namespacing. */
namespace?: string;
/** Retrieves a value by key */
get(key: string): Promise<KeyvAny>;
/** Sets a value with a key and optional TTL */
set(key: string, value: KeyvAny, ttl?: number): Promise<KeyvAny>;
/** Deletes a key from the store */
delete(key: string): Promise<boolean>;
/** Clears all entries from the store */
clear(): Promise<void>;
/** Checks if a key exists in the store */
has?(key: string): Promise<boolean>;
/** Checks if multiple keys exist in the store */
hasMany?(keys: string[]): Promise<boolean[]>;
/** Retrieves multiple values by keys */
getMany?(keys: string[]): Promise<KeyvAnyArray>;
/** Sets multiple entries at once */
setMany?(entries: KeyvAnyArray): Promise<KeyvAny>;
/** Deletes multiple keys at once */
deleteMany?(keys: string[]): Promise<boolean | boolean[]>;
/** Iterates over all entries, optionally filtered by namespace */
iterator?(namespace?: string): AsyncGenerator<KeyvAny>;
/** Disconnects from the store */
disconnect?(): Promise<void>;
/** Subscribe to events (e.g. error events from v5 adapters) */
on?(event: string, listener: (...args: KeyvAnyArray) => void): KeyvAny;
};

@@ -742,3 +804,5 @@ /**

type KeyPrefixData = {
/** The namespace extracted from the key, if present */namespace?: string; /** The key without the namespace prefix */
/** The namespace extracted from the key, if present */
namespace?: string;
/** The key without the namespace prefix */
key: string;

@@ -851,3 +915,3 @@ };

*/
set(key: string, value: any, expires?: number): Promise<boolean>;
set(key: string, value: KeyvAny, expires?: number): Promise<boolean>;
/**

@@ -906,3 +970,3 @@ * Stores multiple entries in the store at once.

//#region src/keyv.d.ts
declare class Keyv<GenericValue = any> extends Hookified {
declare class Keyv<GenericValue = KeyvAny> extends Hookified {
/**

@@ -955,2 +1019,4 @@ * Keyv Constructor

* When true, Keyv checks expiry at its layer on get/getMany/has/hasMany.
* Defaults to true so reads stay millisecond-precise even on adapters whose
* native expiry is coarse or lazily swept (e.g. Memcached, DynamoDB).
*/

@@ -1056,3 +1122,4 @@ private _checkExpired;

* 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.
* When true (default), expired entries are filtered (and deleted) by Keyv regardless of
* the adapter. Set to false to trust the storage adapter to handle expiry on its own.
* @returns {boolean} `true` if Keyv checks expiry at its layer.

@@ -1076,3 +1143,3 @@ */

*/
resolveStore(store: any): KeyvStorageAdapter;
resolveStore(store: KeyvAny): KeyvStorageAdapter;
/**

@@ -1210,3 +1277,3 @@ * Sets the storage adapter by resolving it via {@link resolveStore}, then wires up

*/
iterator(): AsyncGenerator<[string, any], void>;
iterator(): AsyncGenerator<[string, KeyvAny], void>;
/**

@@ -1289,6 +1356,11 @@ * Encodes a value for storage. Pipeline: serialize → compress → encrypt.

type KeyvMapType = {
/** Retrieves a value by key */get: (key: string) => any; /** Sets a value with a key. Additional parameters (like TTL) vary by implementation. */
set: (key: string, value: any, ...args: any[]) => any; /** Deletes a key from the store */
delete: (key: string) => boolean; /** Clears all entries from the store */
clear: () => void; /** Checks if a key exists in the store */
/** Retrieves a value by key */
get: (key: string) => KeyvAny;
/** Sets a value with a key. Additional parameters (like TTL) vary by implementation. */
set: (key: string, value: KeyvAny, ...args: KeyvAnyArray) => KeyvAny;
/** Deletes a key from the store */
delete: (key: string) => boolean;
/** Clears all entries from the store */
clear: () => void;
/** Checks if a key exists in the store */
has: (key: string) => boolean;

@@ -1370,4 +1442,4 @@ };

} | {
namespace?: undefined;
key: string;
namespace?: undefined;
};

@@ -1388,3 +1460,3 @@ /**

*/
set(key: string, value: any, expires?: number): Promise<boolean>;
set(key: string, value: KeyvAny, expires?: number): Promise<boolean>;
/**

@@ -1475,2 +1547,2 @@ * Stores multiple entries in the store at once.

//#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 KeyvStorageEntry, type KeyvStorageGetResult, type KeyvStorageMethod, type KeyvStorageMethods, type KeyvStoreAdapter, type KeyvTelemetryEvent, type KeyvValue, type MethodType, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer, keyvStorageCapability };
export { type DeserializedData, Keyv, Keyv as default, type KeyvAny, type KeyvAnyArray, 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 };
import { Hookified, IEventEmitter } from "hookified";
//#region src/capabilities.d.ts

@@ -30,7 +29,7 @@ type MethodType = "sync" | "async" | "none";

*
* 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
* Declaring `expires: true` means the adapter is used directly and should ENFORCE expiry —
* ideally via a native mechanism (TTL index, key expiry, lease) so the backend reclaims
* space, and/or a client-side check on read. Keyv core also filters expired reads by default
* (`checkExpired` is on), so an adapter with coarse or lazily-swept native expiry (e.g.
* Memcached, DynamoDB) still reads millisecond-precise. Validate with `@keyv/test-suite`'s
* `storageTtlTests`.

@@ -231,7 +230,13 @@ */

type KeyvSanitizeAdapter = {
/** Whether any sanitization is currently enabled. */readonly enabled: boolean; /** The key sanitization pattern configuration. */
readonly keys: KeyvSanitizePatterns; /** The namespace sanitization pattern configuration. */
readonly namespace: KeyvSanitizePatterns; /** Sanitize a single key. */
cleanKey(key: string): string; /** Sanitize an array of keys. */
cleanKeys(keys: string[]): string[]; /** Sanitize a namespace string. */
/** Whether any sanitization is currently enabled. */
readonly enabled: boolean;
/** The key sanitization pattern configuration. */
readonly keys: KeyvSanitizePatterns;
/** The namespace sanitization pattern configuration. */
readonly namespace: KeyvSanitizePatterns;
/** Sanitize a single key. */
cleanKey(key: string): string;
/** Sanitize an array of keys. */
cleanKeys(keys: string[]): string[];
/** Sanitize a namespace string. */
cleanNamespace(ns: string): string;

@@ -292,5 +297,9 @@ };

type KeyvTelemetryEvent = {
/** The event type (e.g. "hit", "miss", "set", "delete", "error"). */event: string; /** The cache key involved, if applicable. */
key?: string; /** The namespace of the Keyv instance. */
namespace?: string; /** Unix timestamp in milliseconds when the event occurred. */
/** The event type (e.g. "hit", "miss", "set", "delete", "error"). */
event: string;
/** The cache key involved, if applicable. */
key?: string;
/** The namespace of the Keyv instance. */
namespace?: string;
/** Unix timestamp in milliseconds when the event occurred. */
timestamp: number;

@@ -419,5 +428,16 @@ };

/**
* A permissive `any` type used at Keyv's dynamic boundaries — untyped store
* values, parameterized query arguments, and other places where the concrete
* type is intentionally open. Centralizing it keeps the `noExplicitAny`
* suppression in one place instead of scattered across the codebase.
*/
type KeyvAny = any;
/**
* The array counterpart to {@link KeyvAny} (i.e. `any[]`).
*/
type KeyvAnyArray = KeyvAny[];
/**
* A Map or any Map-like object. Used as a flexible input type for stores.
*/
type KeyvMapAny = Map<any, any> | any;
type KeyvMapAny = Map<KeyvAny, KeyvAny> | KeyvAny;
/**

@@ -428,3 +448,5 @@ * The envelope structure used to store values in Keyv.

type KeyvValue<Value> = {
/** The stored value. */value?: Value; /** Absolute expiration timestamp in milliseconds since epoch, or `undefined` for no expiry. */
/** The stored value. */
value?: Value;
/** Absolute expiration timestamp in milliseconds since epoch, or `undefined` for no expiry. */
expires?: number | undefined;

@@ -533,3 +555,3 @@ };

*/
type KeyvEntry<Value = any> = {
type KeyvEntry<Value = KeyvAny> = {
/**

@@ -554,5 +576,8 @@ * Key to set.

*/
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. */
type KeyvStorageEntry<Value = KeyvAny> = {
/** 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;

@@ -578,3 +603,3 @@ };

*/
store?: KeyvStorageAdapter | Map<any, any> | any;
store?: KeyvStorageAdapter | Map<KeyvAny, KeyvAny> | KeyvAny;
/**

@@ -589,3 +614,3 @@ * Default TTL in milliseconds. Can be overridden by specifying a TTL on `.set()`.

*/
compression?: KeyvCompressionAdapter | any;
compression?: KeyvCompressionAdapter | KeyvAny;
/**

@@ -617,5 +642,9 @@ * Enable or disable statistics (default is false)

/**
* When true, Keyv checks expiry on get/getMany/has/hasMany at its layer.
* When false (default), trusts the storage adapter to handle expiry.
* @default false
* When true (default), Keyv checks expiry on get/getMany/has/hasMany at its own layer,
* filtering (and deleting) expired entries using the absolute `expires` stored in the
* serialized envelope. This keeps reads millisecond-precise even on adapters whose native
* expiry is coarse or lazily swept (e.g. Memcached's second-granular exptime, DynamoDB's
* background TTL sweep that can lag for hours). Set to false to trust the storage adapter
* to handle expiry on its own (skips the extra decode + expiry check on reads).
* @default true
*/

@@ -631,3 +660,5 @@ checkExpired?: boolean;

type KeyvSerializationAdapter = {
/** Converts a value to a string representation. */stringify: (object: unknown) => string | Promise<string>; /** Parses a string back into its original value. */
/** Converts a value to a string representation. */
stringify: (object: unknown) => string | Promise<string>;
/** Parses a string back into its original value. */
parse: <T>(data: string) => T | Promise<T>;

@@ -640,3 +671,5 @@ };

type KeyvCompressionAdapter = {
/** Compresses a string value. */compress(value: string): Promise<string>; /** Decompresses a string value back to its original form. */
/** Compresses a string value. */
compress(value: string): Promise<string>;
/** Decompresses a string value back to its original form. */
decompress(value: string): Promise<string>;

@@ -649,3 +682,5 @@ };

type KeyvEncryptionAdapter = {
/** Encrypts a string value. */encrypt: (data: string) => string | Promise<string>; /** Decrypts a string value back to its original form. */
/** Encrypts a string value. */
encrypt: (data: string) => string | Promise<string>;
/** Decrypts a string value back to its original form. */
decrypt: (data: string) => string | Promise<string>;

@@ -659,3 +694,4 @@ };

type KeyvStorageAdapter = {
/** Optional namespace for key isolation. */namespace?: string | undefined;
/** Optional namespace for key isolation. */
namespace?: string | undefined;
/**

@@ -667,7 +703,10 @@ * The adapter's capabilities. v6 adapters set `capabilities.expires = true` (e.g. via

*
* 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}.
* Declaring `expires: true` means the adapter should enforce expiry on read so `get`/`getMany`/
* `has` do not return a key past its deadline (ideally backed by a native mechanism that also
* reclaims space). Keyv core additionally filters expired reads by default (`checkExpired` is
* on), as a safety net for backends with coarse or lazily-swept native expiry. See
* {@link KeyvStorageCapability.expires}.
*/
capabilities?: KeyvStorageCapability; /** Retrieves a value by key. */
capabilities?: KeyvStorageCapability;
/** Retrieves a value by key. */
get<Value>(key: string): Promise<KeyvStorageGetResult<Value>>;

@@ -679,11 +718,20 @@ /**

*/
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). */
clear(): Promise<void>; /** Checks if a key exists in the store. */
has(key: string): Promise<boolean>; /** Checks if multiple keys exist in the store. */
hasMany(keys: string[]): Promise<boolean[]>; /** Retrieves multiple values by keys. */
getMany<Value>(keys: string[]): Promise<Array<KeyvStorageGetResult<Value | undefined>>>; /** Disconnects from the store and releases resources. */
disconnect?(): Promise<void>; /** Deletes multiple keys from the store. */
deleteMany(key: string[]): Promise<boolean[]>; /** Returns an async iterator over all key-value pairs. */
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). */
clear(): Promise<void>;
/** Checks if a key exists in the store. */
has(key: string): Promise<boolean>;
/** Checks if multiple keys exist in the store. */
hasMany(keys: string[]): Promise<boolean[]>;
/** Retrieves multiple values by keys. */
getMany<Value>(keys: string[]): Promise<Array<KeyvStorageGetResult<Value | undefined>>>;
/** Disconnects from the store and releases resources. */
disconnect?(): Promise<void>;
/** Deletes multiple keys from the store. */
deleteMany(key: string[]): Promise<boolean[]>;
/** Returns an async iterator over all key-value pairs. */
iterator?<Value>(): AsyncGenerator<Array<string | Awaited<Value> | undefined>, void>;

@@ -722,16 +770,30 @@ } & IEventEmitter;

type KeyvBridgeStore = {
/** 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 */
set(key: string, value: any, ttl?: number): Promise<any>; /** Deletes a key from the store */
delete(key: string): Promise<boolean>; /** Clears all entries from the store */
clear(): Promise<void>; /** Checks if a key exists in the store */
has?(key: string): Promise<boolean>; /** Checks if multiple keys exist in the store */
hasMany?(keys: string[]): Promise<boolean[]>; /** Retrieves multiple values by keys */
getMany?(keys: string[]): Promise<any[]>; /** Sets multiple entries at once */
setMany?(entries: any[]): Promise<any>; /** Deletes multiple keys at once */
deleteMany?(keys: string[]): Promise<boolean | boolean[]>; /** Iterates over all entries, optionally filtered by namespace */
iterator?(namespace?: string): AsyncGenerator<any>; /** Disconnects from the store */
disconnect?(): Promise<void>; /** Subscribe to events (e.g. error events from v5 adapters) */
on?(event: string, listener: (...args: any[]) => void): any;
/** Store configuration/options (e.g. dialect, url) */
opts?: KeyvAny;
/** Namespace the store scopes its keys under, when it manages its own namespacing. */
namespace?: string;
/** Retrieves a value by key */
get(key: string): Promise<KeyvAny>;
/** Sets a value with a key and optional TTL */
set(key: string, value: KeyvAny, ttl?: number): Promise<KeyvAny>;
/** Deletes a key from the store */
delete(key: string): Promise<boolean>;
/** Clears all entries from the store */
clear(): Promise<void>;
/** Checks if a key exists in the store */
has?(key: string): Promise<boolean>;
/** Checks if multiple keys exist in the store */
hasMany?(keys: string[]): Promise<boolean[]>;
/** Retrieves multiple values by keys */
getMany?(keys: string[]): Promise<KeyvAnyArray>;
/** Sets multiple entries at once */
setMany?(entries: KeyvAnyArray): Promise<KeyvAny>;
/** Deletes multiple keys at once */
deleteMany?(keys: string[]): Promise<boolean | boolean[]>;
/** Iterates over all entries, optionally filtered by namespace */
iterator?(namespace?: string): AsyncGenerator<KeyvAny>;
/** Disconnects from the store */
disconnect?(): Promise<void>;
/** Subscribe to events (e.g. error events from v5 adapters) */
on?(event: string, listener: (...args: KeyvAnyArray) => void): KeyvAny;
};

@@ -742,3 +804,5 @@ /**

type KeyPrefixData = {
/** The namespace extracted from the key, if present */namespace?: string; /** The key without the namespace prefix */
/** The namespace extracted from the key, if present */
namespace?: string;
/** The key without the namespace prefix */
key: string;

@@ -851,3 +915,3 @@ };

*/
set(key: string, value: any, expires?: number): Promise<boolean>;
set(key: string, value: KeyvAny, expires?: number): Promise<boolean>;
/**

@@ -906,3 +970,3 @@ * Stores multiple entries in the store at once.

//#region src/keyv.d.ts
declare class Keyv<GenericValue = any> extends Hookified {
declare class Keyv<GenericValue = KeyvAny> extends Hookified {
/**

@@ -955,2 +1019,4 @@ * Keyv Constructor

* When true, Keyv checks expiry at its layer on get/getMany/has/hasMany.
* Defaults to true so reads stay millisecond-precise even on adapters whose
* native expiry is coarse or lazily swept (e.g. Memcached, DynamoDB).
*/

@@ -1056,3 +1122,4 @@ private _checkExpired;

* 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.
* When true (default), expired entries are filtered (and deleted) by Keyv regardless of
* the adapter. Set to false to trust the storage adapter to handle expiry on its own.
* @returns {boolean} `true` if Keyv checks expiry at its layer.

@@ -1076,3 +1143,3 @@ */

*/
resolveStore(store: any): KeyvStorageAdapter;
resolveStore(store: KeyvAny): KeyvStorageAdapter;
/**

@@ -1210,3 +1277,3 @@ * Sets the storage adapter by resolving it via {@link resolveStore}, then wires up

*/
iterator(): AsyncGenerator<[string, any], void>;
iterator(): AsyncGenerator<[string, KeyvAny], void>;
/**

@@ -1289,6 +1356,11 @@ * Encodes a value for storage. Pipeline: serialize → compress → encrypt.

type KeyvMapType = {
/** Retrieves a value by key */get: (key: string) => any; /** Sets a value with a key. Additional parameters (like TTL) vary by implementation. */
set: (key: string, value: any, ...args: any[]) => any; /** Deletes a key from the store */
delete: (key: string) => boolean; /** Clears all entries from the store */
clear: () => void; /** Checks if a key exists in the store */
/** Retrieves a value by key */
get: (key: string) => KeyvAny;
/** Sets a value with a key. Additional parameters (like TTL) vary by implementation. */
set: (key: string, value: KeyvAny, ...args: KeyvAnyArray) => KeyvAny;
/** Deletes a key from the store */
delete: (key: string) => boolean;
/** Clears all entries from the store */
clear: () => void;
/** Checks if a key exists in the store */
has: (key: string) => boolean;

@@ -1370,4 +1442,4 @@ };

} | {
namespace?: undefined;
key: string;
namespace?: undefined;
};

@@ -1388,3 +1460,3 @@ /**

*/
set(key: string, value: any, expires?: number): Promise<boolean>;
set(key: string, value: KeyvAny, expires?: number): Promise<boolean>;
/**

@@ -1475,2 +1547,2 @@ * Stores multiple entries in the store at once.

//#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 KeyvStorageEntry, type KeyvStorageGetResult, type KeyvStorageMethod, type KeyvStorageMethods, type KeyvStoreAdapter, type KeyvTelemetryEvent, type KeyvValue, type MethodType, createKeyv, detectKeyv, detectKeyvCompression, detectKeyvEncryption, detectKeyvSerialization, detectKeyvStorage, jsonSerializer, keyvStorageCapability };
export { type DeserializedData, Keyv, Keyv as default, type KeyvAny, type KeyvAnyArray, 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 };
{
"name": "keyv",
"version": "6.0.0-beta.4",
"version": "6.0.0-rc.1",
"description": "Simple key-value storage with support for multiple backends",

@@ -53,11 +53,11 @@ "type": "module",

"dependencies": {
"hookified": "^3.0.0"
"hookified": "^3.0.2"
},
"devDependencies": {
"@biomejs/biome": "^2.4.16",
"@faker-js/faker": "^10.4.0",
"@vitest/coverage-v8": "^4.1.8",
"happy-dom": "^20.10.2",
"@biomejs/biome": "^2.5.6",
"@faker-js/faker": "^10.5.0",
"@vitest/coverage-v8": "^4.1.10",
"happy-dom": "^20.11.1",
"keyv-anyredis": "^3.3.0",
"keyv-file": "^5.3.3",
"keyv-file": "^5.3.5",
"lru.min": "^1.1.4",

@@ -68,3 +68,3 @@ "quick-lru": "^7.0.0",

"tsd": "^0.33.0",
"vitest": "^4.1.8"
"vitest": "^4.1.10"
},

@@ -75,3 +75,3 @@ "tsd": {

"engines": {
"node": ">= 22.18.0"
"node": ">= 22.19.0"
},

@@ -78,0 +78,0 @@ "files": [

@@ -40,2 +40,3 @@ <h1 align="center"><img width="250" src="https://jaredwray.com/images/keyv.svg" alt="keyv"></h1>

- [Third-party Storage Adapters](#third-party-storage-adapters)
- [Built-in Adapters: Memory and Bridge](#built-in-adapters-memory-and-bridge)
- [Using BigMap to Scale](#using-bigmap-to-scale)

@@ -440,6 +441,58 @@ - [Compression](#compression)

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.
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`](#built-in-adapters-memory-and-bridge), 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.
> **Adapters should enforce expiry — and Keyv double-checks by default.** Declaring `capabilities.expires === true` means a v6 adapter should enforce expiry itself — ideally via a native mechanism (key expiry, TTL index, lease) so the backend reclaims space, and/or a client-side check on read. On top of that, Keyv core filters expired reads at its own layer by default ([`checkExpired`](#checkexpired) is `true`), using the absolute `expires` in the serialized envelope, so `get`/`getMany`/`has` never surface a key past its deadline even on backends whose native expiry is coarse or lazily swept (e.g. Memcached, DynamoDB). Run `@keyv/test-suite`'s `storageTtlTests` against your adapter to verify its own expiry behaviour.
# Built-in Adapters: Memory and Bridge
Keyv ships with two storage adapters built directly into the core package. You rarely instantiate them yourself — Keyv selects and wires up the right one automatically when you create an instance — but knowing how they work explains how the default in-memory store behaves and how legacy or async stores are adapted to the v6 contract. Both are exported from `keyv`:
## KeyvMemoryAdapter
`KeyvMemoryAdapter` is the **default store**. When you create a Keyv instance without a store (`new Keyv()`), it uses `new KeyvMemoryAdapter(new Map())` under the hood. It wraps any synchronous, `Map`-like object — the built-in `Map`, [`quick-lru`](https://github.com/sindresorhus/quick-lru), [`lru.min`](https://github.com/wellwelwel/lru.min), or anything exposing `get`, `set`, `delete`, `clear`, and `has`.
It adds the pieces a raw `Map` does not have:
- **Namespace prefixing** — keys are prefixed with the `namespace` and `keySeparator` (default `:`), so one underlying store can host multiple namespaces. A namespaced `clear()` removes only the current namespace's keys **when the underlying store exposes a `keys()` method** (a standard `Map` does); a minimal store without `keys()` falls back to wiping the **entire** store, so take care sharing one such store across namespaces.
- **TTL expiry** — the adapter keeps a copy of each entry's expiry in its own `{ value, expires }` wrapper *alongside* the stored value, so it can evict expired entries lazily on `get`, `getMany`, `has`, and `iterator()` without decoding the value. This wrapper is **separate from** the `{ value, expires }` envelope Keyv core builds and runs through serialization/compression/encryption — with the default serializer that encoded payload still contains `expires`, so custom serializer/encryption adapters must still handle the `expires` field; only the adapter's outer copy lives outside the payload. When the underlying store accepts a TTL argument (e.g. QuickLRU), the adapter also passes a derived relative duration so the store can evict on its own.
- **Batch and iteration** — `getMany`, `setMany`, `hasMany`, `deleteMany`, and an async `iterator()` (when the store supports `entries()`).
- **v6 contract** — declares `capabilities.expires === true`, so Keyv hands it the absolute `expires` timestamp directly and trusts it to enforce expiry.
```js
import Keyv, { KeyvMemoryAdapter } from 'keyv';
// Wrap any Map-like store. Put the namespace on the Keyv options, not the adapter: Keyv
// propagates its own namespace to the store, overwriting any namespace set on the adapter.
const keyv = new Keyv({ store: new KeyvMemoryAdapter(new Map()), namespace: 'cache' });
// Or wrap an LRU to bound memory usage
import QuickLRU from 'quick-lru';
const cache = new Keyv({ store: new KeyvMemoryAdapter(new QuickLRU({ maxSize: 1000 })) });
```
## KeyvBridgeAdapter
`KeyvBridgeAdapter` wraps any **promise-based / async store** and adapts it to the v6 storage contract. Keyv applies it automatically when you pass:
- a **legacy storage adapter** — a full async adapter that does *not* declare `capabilities.expires` (i.e. pre-v6 third-party adapters), or
- an **async `Map`-like store** with async `get`, `set`, `delete`, and `clear`. For such a store to actually expire data, its `set(key, value, ttl)` must honor the relative millisecond `ttl` the bridge passes as the third argument — a plain Promise-wrapped `Map` that ignores it won't evict on its own. Keyv's `checkExpired` (on by default) still filters expired entries on read, but they linger in the store until read; for native eviction, prefer a full v6 adapter or a store that honors the `ttl`.
This is why existing third-party adapters keep working unchanged on v6. The bridge:
- **Converts expiry** — Keyv passes an absolute `expires` timestamp; the bridge converts it back to the relative TTL the wrapped store expects. A write whose deadline has already elapsed is deleted instead of stored, so a past `expires` becomes an absent key — matching how the native adapters treat an already-expired write.
- **Delegates when it can** — if the wrapped store implements `getMany`, `setMany`, `has`, `hasMany`, `deleteMany`, `iterator`, or `disconnect`, the bridge calls them directly; otherwise it falls back to looping over the single-key primitives.
- **Handles namespacing both ways** — if the wrapped store manages its own namespace (a full adapter exposing a `namespace` property), the bridge propagates its namespace to the store and does *not* prefix keys, avoiding double-namespacing, so the store's native scoped `clear()` and `iterator()` are used. Otherwise the bridge prefixes keys itself, letting one shared store host multiple namespaces.
- **Forwards errors** — re-emits `error` events from the wrapped store so connection failures surface on the Keyv instance.
```js
import Keyv, { KeyvBridgeAdapter } from 'keyv';
// Usually automatic — just pass the store:
const keyv = new Keyv({ store: myAsyncStore });
// ...which is equivalent to wrapping it explicitly. Put the namespace on the Keyv options —
// Keyv overwrites any namespace set on the adapter directly:
const explicit = new Keyv({ store: new KeyvBridgeAdapter(myAsyncStore), namespace: 'cache' });
```
# Using BigMap to Scale

@@ -775,5 +828,5 @@

Type: `Boolean`<br />
Default: `false`
Default: `true`
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.
When `true` (default), Keyv checks expiry at its own layer on `get`/`getMany`/`has`/`hasMany` in addition to the storage adapter. Set to `false` to trust the storage adapter alone. See [.checkExpired](#checkexpired) for details.

@@ -1016,9 +1069,16 @@ # Keyv Instance

Type: `Boolean`<br />
Default: `false`
Default: `true`
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.
A read-only property (configured via the `checkExpired` constructor option). When `true` (the default), Keyv checks expiry at its own layer on `get`, `getMany`, `has`, and `hasMany`, deleting any expired entries it encounters. It does this using the absolute `expires` stored in the serialized envelope, so reads stay **millisecond-precise regardless of the adapter**.
This defaults to `true` because some backends can return entries that are already logically expired: Memcached's `exptime` is **second-granular** (a value can linger up to ~1s past a sub-second deadline), and DynamoDB's native TTL is a **background sweep that can lag by hours** before it deletes expired items. Trusting the backend alone would surface those stale reads; the Keyv-layer check closes that gap.
Set it to `false` to trust the storage adapter to handle expiry on its own. That skips the extra decode + expiry check on every read (and lets `has`/`hasMany` use the adapter's native existence check), at the cost of backend-granularity expiry.
```js
const keyv = new Keyv({ checkExpired: true });
console.log(keyv.checkExpired); // true
const keyv = new Keyv();
console.log(keyv.checkExpired); // true (default)
const trusting = new Keyv({ checkExpired: false });
console.log(trusting.checkExpired); // false
```

@@ -1025,0 +1085,0 @@

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display