@keyv/redis
Version:
Redis storage adapter for Keyv
344 lines (341 loc) • 15.6 kB
TypeScript
import { RedisClientOptions, RedisClusterOptions, RedisSentinelOptions, RedisClientType, RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, RedisClusterType, RedisSentinelType } from '@redis/client';
export { RedisClientOptions, RedisClientType, RedisClusterOptions, RedisClusterType, RedisSentinelType, createClient, createCluster, createSentinel } from '@redis/client';
import { Hookified } from 'hookified';
import { KeyvStoreAdapter, KeyvEntry, Keyv } from 'keyv';
export { Keyv } from 'keyv';
type KeyvRedisOptions = {
/**
* Namespace for the current instance.
*/
namespace?: string;
/**
* Separator to use between namespace and key.
*/
keyPrefixSeparator?: string;
/**
* Number of keys to delete in a single batch.
*/
clearBatchSize?: number;
/**
* Enable Unlink instead of using Del for clearing keys. This is more performant but may not be supported by all Redis versions.
*/
useUnlink?: boolean;
/**
* Whether to allow clearing all keys when no namespace is set.
* If set to true and no namespace is set, iterate() will return all keys.
* Defaults to `false`.
*/
noNamespaceAffectsAll?: boolean;
/**
* This is used to throw an error if the client is not connected when trying to connect. By default, this is
* set to true so that it throws an error when trying to connect to the Redis server fails.
*/
throwOnConnectError?: boolean;
/**
* This is used to throw an error if at any point there is a failure. Use this if you want to
* ensure that all operations are successful and you want to handle errors. By default, this is
* set to false so that it does not throw an error on every operation and instead emits an error event
* and returns no-op responses.
* @default false
*/
throwOnErrors?: boolean;
/**
* Timeout in milliseconds for the connection. Default is undefined, which uses the default timeout of the Redis client.
* If set, it will throw an error if the connection does not succeed within the specified time.
* @default undefined
*/
connectionTimeout?: number;
};
type KeyvRedisPropertyOptions = KeyvRedisOptions & {
/**
* Dialect used by the adapter. This is legacy so Keyv knows what is iteratable.
*/
dialect: "redis";
/**
* URL used to connect to the Redis server. This is legacy so Keyv knows what is iteratable.
*/
url: string;
};
type KeyvRedisEntry<T> = {
/**
* Key to set.
*/
key: string;
/**
* Value to set.
*/
value: T;
/**
* Time to live in milliseconds.
*/
ttl?: number;
};
declare enum RedisErrorMessages {
/**
* Error message when the Redis client is not connected and throwOnConnectError is set to true.
*/
RedisClientNotConnectedThrown = "Redis client is not connected or has failed to connect. This is thrown because throwOnConnectError is set to true."
}
declare const defaultReconnectStrategy: (attempts: number) => number | Error;
type RedisConnectionClientType = RedisClientType | RedisClientType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisClientType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
type RedisConnectionClusterType = RedisClusterType | RedisClusterType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisClusterType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
type RedisConnectionSentinelType = RedisSentinelType | RedisSentinelType<RedisModules, RedisFunctions, RedisScripts, RespVersions> | RedisSentinelType<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>;
type RedisClientConnectionType = RedisConnectionClientType | RedisConnectionClusterType | RedisConnectionSentinelType;
declare class KeyvRedis<T> extends Hookified implements KeyvStoreAdapter {
private _client;
private _namespace;
private _keyPrefixSeparator;
private _clearBatchSize;
private _useUnlink;
private _noNamespaceAffectsAll;
private _throwOnConnectError;
private _throwOnErrors;
private _connectionTimeout;
/**
* KeyvRedis constructor.
* @param {string | RedisClientOptions | RedisClientType} [connect] How to connect to the Redis server. If string pass in the url, if object pass in the options, if RedisClient pass in the client.
* @param {KeyvRedisOptions} [options] Options for the adapter such as namespace, keyPrefixSeparator, and clearBatchSize.
*/
constructor(connect?: string | RedisClientOptions | RedisClusterOptions | RedisSentinelOptions | RedisClientConnectionType, options?: KeyvRedisOptions);
/**
* Get the Redis client.
*/
get client(): RedisClientConnectionType;
/**
* Set the Redis client.
*/
set client(value: RedisClientConnectionType);
/**
* Get the options for the adapter.
*/
get opts(): KeyvRedisPropertyOptions;
/**
* Set the options for the adapter.
*/
set opts(options: KeyvRedisOptions);
/**
* Get the namespace for the adapter. If undefined, it will not use a namespace including keyPrefixing.
* @default undefined
*/
get namespace(): string | undefined;
/**
* Set the namespace for the adapter. If undefined, it will not use a namespace including keyPrefixing.
*/
set namespace(value: string | undefined);
/**
* Get the separator between the namespace and key.
* @default '::'
*/
get keyPrefixSeparator(): string;
/**
* Set the separator between the namespace and key.
*/
set keyPrefixSeparator(value: string);
/**
* Get the number of keys to delete in a single batch.
* @default 1000
*/
get clearBatchSize(): number;
/**
* Set the number of keys to delete in a single batch.
*/
set clearBatchSize(value: number);
/**
* Get if Unlink is used instead of Del for clearing keys. This is more performant but may not be supported by all Redis versions.
* @default true
*/
get useUnlink(): boolean;
/**
* Set if Unlink is used instead of Del for clearing keys. This is more performant but may not be supported by all Redis versions.
*/
set useUnlink(value: boolean);
/**
* Get if no namespace affects all keys.
* Whether to allow clearing all keys when no namespace is set.
* If set to true and no namespace is set, iterate() will return all keys.
* @default false
*/
get noNamespaceAffectsAll(): boolean;
/**
* Set if not namespace affects all keys.
*/
set noNamespaceAffectsAll(value: boolean);
/**
* Get if throwOnConnectError is set to true.
* This is used to throw an error if the client is not connected when trying to connect. By default, this is
* set to true so that it throws an error when trying to connect to the Redis server fails.
* @default true
*/
get throwOnConnectError(): boolean;
/**
* Set if throwOnConnectError is set to true.
* This is used to throw an error if the client is not connected when trying to connect. By default, this is
* set to true so that it throws an error when trying to connect to the Redis server fails.
*/
set throwOnConnectError(value: boolean);
/**
* Get if throwOnErrors is set to true.
* This is used to throw an error if at any point there is a failure. Use this if you want to
* ensure that all operations are successful and you want to handle errors. By default, this is
* set to false so that it does not throw an error on every operation and instead emits an error event
* and returns no-op responses.
* @default false
*/
get throwOnErrors(): boolean;
/**
* Set if throwOnErrors is set to true.
* This is used to throw an error if at any point there is a failure. Use this if you want to
* ensure that all operations are successful and you want to handle errors. By default, this is
* set to false so that it does not throw an error on every operation and instead emits an error event
* and returns no-op responses.
*/
set throwOnErrors(value: boolean);
/**
* Get the connection timeout in milliseconds such as 5000 (5 seconds). Default is undefined. If undefined, it will use the default.
* @default undefined
*/
get connectionTimeout(): number | undefined;
/**
* Set the connection timeout in milliseconds such as 5000 (5 seconds). Default is undefined. If undefined, it will use the default.
* @default undefined
*/
set connectionTimeout(value: number | undefined);
/**
* Get the Redis URL used to connect to the server. This is used to get a connected client.
*/
getClient(): Promise<RedisClientConnectionType>;
/**
* Set a key value pair in the store. TTL is in milliseconds.
* @param {string} key - the key to set
* @param {string} value - the value to set
* @param {number} [ttl] - the time to live in milliseconds
*/
set(key: string, value: string, ttl?: number): Promise<void>;
/**
* Will set many key value pairs in the store. TTL is in milliseconds. This will be done as a single transaction.
* @param {KeyvEntry[]} entries - the key value pairs to set with optional ttl
*/
setMany(entries: KeyvEntry[]): Promise<void>;
/**
* Check if a key exists in the store.
* @param {string} key - the key to check
* @returns {Promise<boolean>} - true if the key exists, false if not
*/
has(key: string): Promise<boolean>;
/**
* Check if many keys exist in the store. This will be done as a single transaction.
* @param {Array<string>} keys - the keys to check
* @returns {Promise<Array<boolean>>} - array of booleans for each key if it exists
*/
hasMany(keys: string[]): Promise<boolean[]>;
/**
* Get a value from the store. If the key does not exist, it will return undefined.
* @param {string} key - the key to get
* @returns {Promise<string | undefined>} - the value or undefined if the key does not exist
*/
get<U = T>(key: string): Promise<U | undefined>;
/**
* Get many values from the store. If a key does not exist, it will return undefined.
* @param {Array<string>} keys - the keys to get
* @returns {Promise<Array<string | undefined>>} - array of values or undefined if the key does not exist
*/
getMany<U = T>(keys: string[]): Promise<Array<U | undefined>>;
/**
* Delete a key from the store.
* @param {string} key - the key to delete
* @returns {Promise<boolean>} - true if the key was deleted, false if not
*/
delete(key: string): Promise<boolean>;
/**
* Delete many keys from the store. This will be done as a single transaction.
* @param {Array<string>} keys - the keys to delete
* @returns {Promise<boolean>} - true if any key was deleted, false if not
*/
deleteMany(keys: string[]): Promise<boolean>;
/**
* Disconnect from the Redis server.
* @returns {Promise<void>}
* @param {boolean} [force] - it will send a quit command if false, otherwise it will send a disconnect command to forcefully disconnect.
* @see {@link https://github.com/redis/node-redis/tree/master/packages/redis#disconnecting}
*/
disconnect(force?: boolean): Promise<void>;
/**
* Helper function to create a key with a namespace.
* @param {string} key - the key to prefix
* @param {string} namespace - the namespace to prefix the key with
* @returns {string} - the key with the namespace such as 'namespace::key'
*/
createKeyPrefix(key: string, namespace?: string): string;
/**
* Helper function to get a key without the namespace.
* @param {string} key - the key to remove the namespace from
* @param {string} namespace - the namespace to remove from the key
* @returns {string} - the key without the namespace such as 'key'
*/
getKeyWithoutPrefix(key: string, namespace?: string): string;
/**
* Is the client a cluster.
* @returns {boolean} - true if the client is a cluster, false if not
*/
isCluster(): boolean;
/**
* Is the client a sentinel.
* @returns {boolean} - true if the client is a sentinel, false if not
*/
isSentinel(): boolean;
/**
* Get the master nodes in the cluster. If not a cluster, it will return the single client.
*
* @returns {Promise<RedisClientType[]>} - array of master nodes
*/
getMasterNodes(): Promise<RedisClientType[]>;
/**
* Get an async iterator for the keys and values in the store. If a namespace is provided, it will only iterate over keys with that namespace.
* @param {string} [namespace] - the namespace to iterate over
* @returns {AsyncGenerator<[string, T | undefined], void, unknown>} - async iterator with key value pairs
*/
iterator<U = T>(namespace?: string): AsyncGenerator<[string, U | undefined], void, unknown>;
/**
* Clear all keys in the store.
* IMPORTANT: this can cause performance issues if there are a large number of keys in the store and worse with clusters. Use with caution as not recommended for production.
* If a namespace is not set it will clear all keys with no prefix.
* If a namespace is set it will clear all keys with that namespace.
* @returns {Promise<void>}
*/
clear(): Promise<void>;
/**
* Get many keys. If the instance is a cluster, it will do multiple MGET calls
* by separating the keys by slot to solve the CROSS-SLOT restriction.
*/
private mget;
/**
* Clear all keys in the store with a specific namespace. If the instance is a cluster, it will clear all keys
* by separating the keys by slot to solve the CROSS-SLOT restriction.
*/
private clearWithClusterSupport;
/**
* Returns the master node client for a given slot or the instance's client if it's not a cluster.
*/
private getSlotMaster;
/**
* Group keys by their slot.
*
* @param {string[]} keys - the keys to group
* @returns {Map<number, string[]>} - map of slot to keys
*/
private getSlotMap;
private isClientCluster;
private isClientSentinel;
private setOptions;
private initClient;
private createTimeoutPromise;
}
/**
* Will create a Keyv instance with the Redis adapter. This will also set the namespace and useKeyPrefix to false.
* @param connect - How to connect to the Redis server. If string pass in the url, if object pass in the options, if RedisClient pass in the client. If nothing is passed in, it will default to 'redis://localhost:6379'.
* @param {KeyvRedisOptions} options - Options for the adapter such as namespace, keyPrefixSeparator, and clearBatchSize.
* @returns {Keyv} - Keyv instance with the Redis adapter
*/
declare function createKeyv(connect?: string | RedisClientOptions | RedisClientType, options?: KeyvRedisOptions): Keyv;
declare function createKeyvNonBlocking(connect?: string | RedisClientOptions | RedisClientType, options?: KeyvRedisOptions): Keyv;
export { type KeyvRedisEntry, type KeyvRedisOptions, type KeyvRedisPropertyOptions, type RedisClientConnectionType, type RedisConnectionClientType, type RedisConnectionClusterType, type RedisConnectionSentinelType, RedisErrorMessages, createKeyv, createKeyvNonBlocking, KeyvRedis as default, defaultReconnectStrategy };