@valkey/valkey-glide
Version:
General Language Independent Driver for the Enterprise (GLIDE) for Valkey
1,065 lines (1,064 loc) • 267 kB
TypeScript
/**
* Copyright Valkey GLIDE Project Contributors - SPDX Identifier: Apache-2.0
*/
import { Script } from "glide-rs";
import * as net from "net";
import { Buffer, Writer } from "protobufjs";
import { AggregationType, BaseScanOptions, BitFieldGet, // eslint-disable-line @typescript-eslint/no-unused-vars
BitFieldSubCommands, // eslint-disable-line @typescript-eslint/no-unused-vars
BitOffsetOptions, BitwiseOperation, Boundary, // eslint-disable-line @typescript-eslint/no-unused-vars
ExpireOptions, GeoAddOptions, // eslint-disable-line @typescript-eslint/no-unused-vars
GeoSearchResultOptions, GeoSearchShape, GeoSearchStoreResultOptions, GeoUnit, GeospatialData, HScanOptions, InsertPosition, KeyWeight, LPosOptions, ListDirection, // eslint-disable-line @typescript-eslint/no-unused-vars
RangeByIndex, RangeByLex, RangeByScore, RestoreOptions, ScoreFilter, SearchOrigin, SetOptions, SortOptions, StreamAddOptions, StreamClaimOptions, StreamGroupOptions, StreamPendingOptions, StreamReadGroupOptions, StreamReadOptions, StreamTrimOptions, TimeUnit, ZAddOptions, ZScanOptions } from "./Commands";
import { ConnectionError, ValkeyError } from "./Errors";
import { GlideClientConfiguration } from "./GlideClient";
import { GlideClusterClientConfiguration, RouteOption, Routes } from "./GlideClusterClient";
import { command_request, connection_request, response } from "./ProtobufMessage";
type PromiseFunction = (value?: any) => void;
type ErrorFunction = (error: ValkeyError) => void;
export type ReturnTypeRecord = {
[key: string]: GlideReturnType;
};
export type ReturnTypeMap = Map<string, GlideReturnType>;
export interface ReturnTypeAttribute {
value: GlideReturnType;
attributes: ReturnTypeRecord;
}
export declare enum ProtocolVersion {
/** Use RESP2 to communicate with the server nodes. */
RESP2 = 1,
/** Use RESP3 to communicate with the server nodes. */
RESP3 = 0
}
export type GlideReturnType = "OK" | string | number | null | boolean | bigint | Buffer | Set<GlideReturnType> | ReturnTypeRecord | ReturnTypeMap | ReturnTypeAttribute | GlideReturnType[];
/**
* Union type that can store either a valid UTF-8 string or array of bytes.
*/
export type GlideString = string | Buffer;
/**
* Enum representing the different types of decoders.
*/
export declare enum Decoder {
/**
* Decodes the response into a buffer array.
*/
Bytes = 0,
/**
* Decodes the response into a string.
*/
String = 1
}
/** An extension to command option types with {@link Decoder}. */
export interface DecoderOption {
/**
* {@link Decoder} type which defines how to handle the response.
* If not set, the {@link BaseClientConfiguration.defaultDecoder|default decoder} will be used.
*/
decoder?: Decoder;
}
/** A replacement for `Record<GlideString, T>` - array of key-value pairs. */
export type GlideRecord<T> = {
/** The value name. */
key: GlideString;
/** The value itself. */
value: T;
}[];
/**
* Data type which represents sorted sets data, including elements and their respective scores.
* Similar to `Record<GlideString, number>` - see {@link GlideRecord}.
*/
export type SortedSetDataType = {
/** The sorted set element name. */
element: GlideString;
/** The element score. */
score: number;
}[];
/**
* Data type which represents how data are returned from hashes or insterted there.
* Similar to `Record<GlideString, GlideString>` - see {@link GlideRecord}.
*/
export type HashDataType = {
/** The hash element name. */
field: GlideString;
/** The hash element value. */
value: GlideString;
}[];
/**
* Data type which reflects now stream entries are returned.
* The keys of the record are stream entry IDs, which are mapped to key-value pairs of the data.
*/
export type StreamEntryDataType = Record<string, [GlideString, GlideString][]>;
/**
* Union type that can store either a number or positive/negative infinity.
*/
export type Score = number | "+inf" | "-inf";
/**
* Data type which represents sorted sets data for input parameter of ZADD command,
* including element and its respective score.
*/
export type ElementAndScore = {
/** The sorted set element name. */
element: GlideString;
/** The element score. */
score: Score;
};
/**
* @internal
* This function converts an input from GlideRecord or Record types to GlideRecord.
*
* @param keysAndValues - key names and their values.
* @returns GlideRecord array containing keys and their values.
*/
export declare function convertGlideRecord(keysAndValues: GlideRecord<GlideString> | Record<string, GlideString>): GlideRecord<GlideString>;
/**
* @internal
* Recursively downcast `GlideRecord` to `Record`. Use if `data` keys are always strings.
*/
export declare function convertGlideRecordToRecord<T>(data: GlideRecord<T>): Record<string, T>;
/**
* @internal
* Check whether an object is a `GlideRecord` (see {@link GlideRecord}).
*/
export declare function isGlideRecord(obj?: unknown): boolean;
/** Represents the return type of {@link xinfoStream} command. */
export type ReturnTypeXinfoStream = Record<string, StreamEntries | Record<string, StreamEntries | Record<string, StreamEntries>[]>[]>;
/**
* Represents an array of Stream Entires in the response of {@link xinfoStream} command.
* See {@link ReturnTypeXinfoStream}.
*/
export type StreamEntries = GlideString | number | (GlideString | number | GlideString[])[][];
/**
* @internal
* Reverse of {@link convertGlideRecordToRecord}.
*/
export declare function convertRecordToGlideRecord<T>(data: Record<string, T>): GlideRecord<T>;
/** Represents the credentials for connecting to a server. */
export interface ServerCredentials {
/**
* The username that will be used for authenticating connections to the Valkey servers.
* If not supplied, "default" will be used.
*/
username?: string;
/**
* The password that will be used for authenticating connections to the Valkey servers.
*/
password: string;
}
/** Represents the client's read from strategy. */
export type ReadFrom =
/** Always get from primary, in order to get the freshest data.*/
"primary"
/** Spread the requests between all replicas in a round robin manner.
If no replica is available, route the requests to the primary.*/
| "preferReplica"
/** Spread the requests between replicas in the same client's Aviliablity zone in a round robin manner.
If no replica is available, route the requests to the primary.*/
| "AZAffinity"
/** Spread the read requests among all nodes within the client's Availability Zone (AZ) in a round robin manner,
prioritizing local replicas, then the local primary, and falling back to any replica or the primary if needed.*/
| "AZAffinityReplicasAndPrimary";
/**
* Configuration settings for creating a client. Shared settings for standalone and cluster clients.
*
* @remarks
* The `BaseClientConfiguration` interface defines the foundational configuration options used when creating a client to connect to a Valkey server or cluster. It includes connection details, authentication, communication protocols, and various settings that influence the client's behavior and interaction with the server.
*
* ### Connection Details
*
* - **Addresses**: Use the `addresses` property to specify the hostnames and ports of the server(s) to connect to.
* - **Cluster Mode**: In cluster mode, the client will discover other nodes based on the provided addresses.
* - **Standalone Mode**: In standalone mode, only the provided nodes will be used.
*
* ### Security Settings
*
* - **TLS**: Enable secure communication using `useTLS`.
* - **Authentication**: Provide `credentials` to authenticate with the server.
*
* ### Communication Settings
*
* - **Request Timeout**: Set `requestTimeout` to specify how long the client should wait for a request to complete.
* - **Protocol Version**: Choose the serialization protocol using `protocol`.
*
* ### Client Identification
*
* - **Client Name**: Set `clientName` to identify the client connection.
*
* ### Read Strategy
*
* - Use `readFrom` to specify the client's read strategy (e.g., primary, preferReplica, AZAffinity, AZAffinityReplicasAndPrimary).
*
* ### Availability Zone
*
* - Use `clientAz` to specify the client's availability zone, which can influence read operations when using `readFrom: 'AZAffinity'or `readFrom: 'AZAffinityReplicasAndPrimary'`.
*
* ### Decoder Settings
*
* - **Default Decoder**: Set `defaultDecoder` to specify how responses are decoded by default.
*
* ### Concurrency Control
*
* - **Inflight Requests Limit**: Control the number of concurrent requests using `inflightRequestsLimit`.
*
* @example
* ```typescript
* const config: BaseClientConfiguration = {
* addresses: [
* { host: 'redis-node-1.example.com', port: 6379 },
* { host: 'redis-node-2.example.com' }, // Defaults to port 6379
* ],
* useTLS: true,
* credentials: {
* username: 'myUser',
* password: 'myPassword',
* },
* requestTimeout: 5000, // 5 seconds
* protocol: ProtocolVersion.RESP3,
* clientName: 'myValkeyClient',
* readFrom: ReadFrom.AZAffinity,
* clientAz: 'us-east-1a',
* defaultDecoder: Decoder.String,
* inflightRequestsLimit: 1000,
* };
* ```
*/
export interface BaseClientConfiguration {
/**
* DNS Addresses and ports of known nodes in the cluster.
* If the server is in cluster mode the list can be partial, as the client will attempt to map out the cluster and find all nodes.
* If the server is in standalone mode, only nodes whose addresses were provided will be used by the client.
*
* @example
* ```typescript
* configuration.addresses =
* [
* { address: sample-address-0001.use1.cache.amazonaws.com, port:6378 },
* { address: sample-address-0002.use2.cache.amazonaws.com }
* { address: sample-address-0003.use2.cache.amazonaws.com, port:6380 }
* ]
* ```
*/
addresses: {
host: string;
/**
* If port isn't supplied, 6379 will be used
*/
port?: number;
}[];
/**
* True if communication with the cluster should use Transport Level Security.
* Should match the TLS configuration of the server/cluster,
* otherwise the connection attempt will fail.
*/
useTLS?: boolean;
/**
* Credentials for authentication process.
* If none are set, the client will not authenticate itself with the server.
*/
credentials?: ServerCredentials;
/**
* The duration in milliseconds that the client should wait for a request to complete.
* This duration encompasses sending the request, awaiting for a response from the server, and any required reconnections or retries.
* If the specified timeout is exceeded for a pending request, it will result in a timeout error.
* If not explicitly set, a default value of 250 milliseconds will be used.
* Value must be an integer.
*/
requestTimeout?: number;
/**
* The client's read from strategy.
* If not set, `Primary` will be used.
*/
readFrom?: ReadFrom;
/**
* Serialization protocol to be used.
* If not set, `RESP3` will be used.
*/
protocol?: ProtocolVersion;
/**
* Client name to be used for the client. Will be used with CLIENT SETNAME command during connection establishment.
*/
clientName?: string;
/**
* Default decoder when decoder is not set per command.
* If not set, 'Decoder.String' will be used.
*/
defaultDecoder?: Decoder;
/**
* The maximum number of concurrent requests allowed to be in-flight (sent but not yet completed).
* This limit is used to control the memory usage and prevent the client from overwhelming the
* server or getting stuck in case of a queue backlog. If not set, a default value of 1000 will be
* used.
*/
inflightRequestsLimit?: number;
/**
* Availability Zone of the client.
* If ReadFrom strategy is AZAffinity or AZAffinityReplicasAndPrimary, this setting ensures that readonly commands are directed to nodes within the specified AZ if they exist.
*
* @example
* ```typescript
* // Example configuration for setting client availability zone and read strategy
* configuration.clientAz = 'us-east-1a'; // Sets the client's availability zone
* configuration.readFrom = 'AZAffinity'; // Directs read operations to nodes within the same AZ
* Or
* configuration.readFrom = 'AZAffinityReplicasAndPrimary'; // Directs read operations to any node (primary or replica) within the same AZ
* ```
*/
clientAz?: string;
}
/**
* Represents advanced configuration settings for a client, including connection-related options.
*
* @remarks
* The `AdvancedBaseClientConfiguration` interface defines advanced configuration settings for managing the client's connection behavior.
*
* ### Connection Timeout
*
* - **Connection Timeout**: The `connectionTimeout` property specifies the duration (in milliseconds) the client should wait for a connection to be established.
*
* @example
* ```typescript
* const config: AdvancedBaseClientConfiguration = {
* connectionTimeout: 5000, // 5 seconds
* };
* ```
*/
export interface AdvancedBaseClientConfiguration {
/**
* The duration in milliseconds to wait for a TCP/TLS connection to complete.
* This applies both during initial client creation and any reconnections that may occur during request processing.
* **Note**: A high connection timeout may lead to prolonged blocking of the entire command pipeline.
* If not explicitly set, a default value of 250 milliseconds will be used.
*/
connectionTimeout?: number;
}
/**
* Enum of Valkey data types
* `STRING`
* `LIST`
* `SET`
* `ZSET`
* `HASH`
* `STREAM`
*/
export declare enum ObjectType {
STRING = "String",
LIST = "List",
SET = "Set",
ZSET = "ZSet",
HASH = "Hash",
STREAM = "Stream"
}
export interface PubSubMsg {
message: GlideString;
channel: GlideString;
pattern?: GlideString | null;
}
/**
* @internal
* A type to combine RouterOption and DecoderOption to be used for creating write promises for the command.
* See - {@link DecoderOption} and {@link RouteOption}
*/
export type WritePromiseOptions = RouteOption & DecoderOption;
export declare class BaseClient {
private socket;
protected readonly promiseCallbackFunctions: [PromiseFunction, ErrorFunction, Decoder | undefined][] | [PromiseFunction, ErrorFunction][];
private readonly availableCallbackSlots;
private requestWriter;
private writeInProgress;
private remainingReadData;
private readonly requestTimeout;
protected isClosed: boolean;
protected defaultDecoder: Decoder;
private readonly pubsubFutures;
private pendingPushNotification;
private readonly inflightRequestsLimit;
private config;
protected configurePubsub(options: GlideClusterClientConfiguration | GlideClientConfiguration, configuration: connection_request.IConnectionRequest): void;
private handleReadData;
protected toProtobufRoute(route: Routes | undefined): command_request.Routes | undefined;
processResponse(message: response.Response): void;
processPush(response: response.Response): void;
/**
* @internal
*/
protected constructor(socket: net.Socket, options?: BaseClientConfiguration);
protected getCallbackIndex(): number;
private writeBufferedRequestsToSocket;
protected ensureClientIsOpen(): void;
/**
* @internal
*/
protected createWritePromise<T>(command: command_request.Command | command_request.Command[], options?: WritePromiseOptions): Promise<T>;
protected createUpdateConnectionPasswordPromise(command: command_request.UpdateConnectionPassword): Promise<GlideString>;
protected createScriptInvocationPromise<T = GlideString>(command: command_request.ScriptInvocation, options?: {
keys?: GlideString[];
args?: GlideString[];
} & DecoderOption): Promise<T>;
protected writeOrBufferCommandRequest(callbackIdx: number, command: command_request.Command | command_request.Command[], route?: command_request.Routes): void;
protected writeOrBufferRequest<TRequest>(message: TRequest, encodeDelimited: (message: TRequest, writer: Writer) => void): void;
/**
* @internal
*/
protected processResultWithSetCommands(result: GlideReturnType[] | null, setCommandsIndexes: number[]): GlideReturnType[] | null;
cancelPubSubFuturesWithExceptionSafe(exception: ConnectionError): void;
isPubsubConfigured(config: GlideClientConfiguration | GlideClusterClientConfiguration): boolean;
getPubsubCallbackAndContext(config: GlideClientConfiguration | GlideClusterClientConfiguration): [((msg: PubSubMsg, context: any) => void) | null | undefined, any];
getPubSubMessage(): Promise<PubSubMsg>;
tryGetPubSubMessage(decoder?: Decoder): PubSubMsg | null;
notificationToPubSubMessageSafe(pushNotification: response.Response, decoder?: Decoder): PubSubMsg | null;
completePubSubFuturesSafe(): void;
/** Get the value associated with the given key, or null if no such value exists.
*
* @see {@link https://valkey.io/commands/get/|valkey.io} for details.
*
* @param key - The key to retrieve from the database.
* @param options - (Optional) See {@link DecoderOption}.
* @returns If `key` exists, returns the value of `key`. Otherwise, return null.
*
* @example
* ```typescript
* // Example usage of get method to retrieve the value of a key
* const result = await client.get("key");
* console.log(result); // Output: 'value'
* // Example usage of get method to retrieve the value of a key with Bytes decoder
* const result = await client.get("key", Decoder.Bytes);
* console.log(result); // Output: {"data": [118, 97, 108, 117, 101], "type": "Buffer"}
* ```
*/
get(key: GlideString, options?: DecoderOption): Promise<GlideString | null>;
/**
* Get the value of `key` and optionally set its expiration. `GETEX` is similar to {@link get}.
*
* @see {@link https://valkey.io/commands/getex/|valkey.op} for more details.
* @remarks Since Valkey version 6.2.0.
*
* @param key - The key to retrieve from the database.
* @param options - (Optional) Additional Parameters:
* - (Optional) `expiry`: expiriation to the given key:
* `"persist"` will retain the time to live associated with the key. Equivalent to `PERSIST` in the VALKEY API.
* Otherwise, a {@link TimeUnit} and duration of the expire time should be specified.
* - (Optional) `decoder`: see {@link DecoderOption}.
* @returns If `key` exists, returns the value of `key` as a `string`. Otherwise, return `null`.
*
* @example
* ```typescript
* const result = await client.getex("key", {expiry: { type: TimeUnit.Seconds, count: 5 }});
* console.log(result); // Output: 'value'
* ```
*/
getex(key: GlideString, options?: {
expiry: "persist" | {
type: TimeUnit;
duration: number;
};
} & DecoderOption): Promise<GlideString | null>;
/**
* Gets a string value associated with the given `key`and deletes the key.
*
* @see {@link https://valkey.io/commands/getdel/|valkey.io} for details.
*
* @param key - The key to retrieve from the database.
* @param options - (Optional) See {@link DecoderOption}.
* @returns If `key` exists, returns the `value` of `key`. Otherwise, return `null`.
*
* @example
* ```typescript
* const result = client.getdel("key");
* console.log(result); // Output: 'value'
*
* const value = client.getdel("key"); // value is null
* ```
*/
getdel(key: GlideString, options?: DecoderOption): Promise<GlideString | null>;
/**
* Returns the substring of the string value stored at `key`, determined by the byte offsets
* `start` and `end` (both are inclusive). Negative offsets can be used in order to provide
* an offset starting from the end of the string. So `-1` means the last character, `-2` the
* penultimate and so forth. If `key` does not exist, an empty string is returned. If `start`
* or `end` are out of range, returns the substring within the valid range of the string.
*
* @see {@link https://valkey.io/commands/getrange/|valkey.io} for details.
*
* @param key - The key of the string.
* @param start - The starting byte offset.
* @param end - The ending byte offset.
* @param options - (Optional) See {@link DecoderOption}.
* @returns A substring extracted from the value stored at `key`.
*
* @example
* ```typescript
* await client.set("mykey", "This is a string")
* let result = await client.getrange("mykey", 0, 3)
* console.log(result); // Output: "This"
* result = await client.getrange("mykey", -3, -1)
* console.log(result); // Output: "ing" - extracted last 3 characters of a string
* result = await client.getrange("mykey", 0, 100)
* console.log(result); // Output: "This is a string"
* result = await client.getrange("mykey", 5, 6)
* console.log(result); // Output: ""
* ```
*/
getrange(key: GlideString, start: number, end: number, options?: DecoderOption): Promise<GlideString | null>;
/** Set the given key with the given value. Return value is dependent on the passed options.
*
* @see {@link https://valkey.io/commands/set/|valkey.io} for details.
*
* @param key - The key to store.
* @param value - The value to store with the given key.
* @param options - (Optional) See {@link SetOptions} and {@link DecoderOption}.
* @returns - If the value is successfully set, return OK.
* If `conditional` in `options` is not set, the value will be set regardless of prior value existence.
* If value isn't set because of `onlyIfExists` or `onlyIfDoesNotExist` or `onlyIfEqual` conditions, return `null`.
* If `returnOldValue` is set, return the old value as a string.
*
* @example
* ```typescript
* // Example usage of set method to set a key-value pair
* const result = await client.set("my_key", "my_value");
* console.log(result); // Output: 'OK'
*
* // Example usage of set method with conditional options and expiration
* const result2 = await client.set("key", "new_value", {conditionalSet: "onlyIfExists", expiry: { type: TimeUnit.Seconds, count: 5 }});
* console.log(result2); // Output: 'OK' - Set "new_value" to "key" only if "key" already exists, and set the key expiration to 5 seconds.
*
* // Example usage of set method with conditional options and returning old value
* const result3 = await client.set("key", "value", {conditionalSet: "onlyIfDoesNotExist", returnOldValue: true});
* console.log(result3); // Output: 'new_value' - Returns the old value of "key".
*
* // Example usage of get method to retrieve the value of a key
* const result4 = await client.get("key");
* console.log(result4); // Output: 'new_value' - Value wasn't modified back to being "value" because of "NX" flag.
*
* // Example usage of set method with conditional option IFEQ
* await client.set("key", "value we will compare to");
* const result5 = await client.set("key", "new_value", {conditionalSet: "onlyIfEqual", comparisonValue: "value we will compare to"});
* console.log(result5); // Output: 'OK' - Set "new_value" to "key" only if comparisonValue is equal to the current value of "key".
* const result6 = await client.set("key", "another_new_value", {conditionalSet: "onlyIfEqual", comparisonValue: "value we will compare to"});
* console.log(result6); // Output: `null` - Value wasn't set because the comparisonValue is not equal to the current value of "key". Value of "key" remains "new_value".
* ```
*/
set(key: GlideString, value: GlideString, options?: SetOptions & DecoderOption): Promise<"OK" | GlideString | null>;
/**
* Removes the specified keys. A key is ignored if it does not exist.
*
* @see {@link https://valkey.io/commands/del/|valkey.io} for details.
*
* @remarks In cluster mode, if keys in `keys` map to different hash slots,
* the command will be split across these slots and executed separately for each.
* This means the command is atomic only at the slot level. If one or more slot-specific
* requests fail, the entire call will return the first encountered error, even
* though some requests may have succeeded while others did not.
* If this behavior impacts your application logic, consider splitting the
* request into sub-requests per slot to ensure atomicity.
*
* @param keys - The keys we wanted to remove.
* @returns The number of keys that were removed.
*
* @example
* ```typescript
* // Example usage of del method to delete an existing key
* await client.set("my_key", "my_value");
* const result = await client.del(["my_key"]);
* console.log(result); // Output: 1
* ```
*
* @example
* ```typescript
* // Example usage of del method for a non-existing key
* const result = await client.del(["non_existing_key"]);
* console.log(result); // Output: 0
* ```
*/
del(keys: GlideString[]): Promise<number>;
/**
* Serialize the value stored at `key` in a Valkey-specific format and return it to the user.
*
* @see {@link https://valkey.io/commands/dump/|valkey.io} for details.
*
* @param key - The `key` to serialize.
* @returns The serialized value of the data stored at `key`. If `key` does not exist, `null` will be returned.
*
* @example
* ```typescript
* let result = await client.dump("myKey");
* console.log(result); // Output: the serialized value of "myKey"
* ```
*
* @example
* ```typescript
* result = await client.dump("nonExistingKey");
* console.log(result); // Output: `null`
* ```
*/
dump(key: GlideString): Promise<Buffer | null>;
/**
* Create a `key` associated with a `value` that is obtained by deserializing the provided
* serialized `value` (obtained via {@link dump}).
*
* @see {@link https://valkey.io/commands/restore/|valkey.io} for details.
* @remarks `options.idletime` and `options.frequency` modifiers cannot be set at the same time.
*
* @param key - The `key` to create.
* @param ttl - The expiry time (in milliseconds). If `0`, the `key` will persist.
* @param value - The serialized value to deserialize and assign to `key`.
* @param options - (Optional) Restore options {@link RestoreOptions}.
* @returns Return "OK" if the `key` was successfully restored with a `value`.
*
* @example
* ```typescript
* const result = await client.restore("myKey", 0, value);
* console.log(result); // Output: "OK"
* ```
*
* @example
* ```typescript
* const result = await client.restore("myKey", 1000, value, {replace: true, absttl: true});
* console.log(result); // Output: "OK"
* ```
*
* @example
* ```typescript
* const result = await client.restore("myKey", 0, value, {replace: true, idletime: 10});
* console.log(result); // Output: "OK"
* ```
*
* @example
* ```typescript
* const result = await client.restore("myKey", 0, value, {replace: true, frequency: 10});
* console.log(result); // Output: "OK"
* ```
*/
restore(key: GlideString, ttl: number, value: Buffer, options?: RestoreOptions): Promise<"OK">;
/** Retrieve the values of multiple keys.
*
* @see {@link https://valkey.io/commands/mget/|valkey.io} for details.
*
* @remarks In cluster mode, if keys in `keys` map to different hash slots,
* the command will be split across these slots and executed separately for each.
* This means the command is atomic only at the slot level. If one or more slot-specific
* requests fail, the entire call will return the first encountered error, even
* though some requests may have succeeded while others did not.
* If this behavior impacts your application logic, consider splitting the
* request into sub-requests per slot to ensure atomicity.
*
* @param keys - A list of keys to retrieve values for.
* @param options - (Optional) See {@link DecoderOption}.
* @returns A list of values corresponding to the provided keys. If a key is not found,
* its corresponding value in the list will be null.
*
* @example
* ```typescript
* // Example usage of mget method to retrieve values of multiple keys
* await client.set("key1", "value1");
* await client.set("key2", "value2");
* const result = await client.mget(["key1", "key2"]);
* console.log(result); // Output: ['value1', 'value2']
* ```
*/
mget(keys: GlideString[], options?: DecoderOption): Promise<(GlideString | null)[]>;
/** Set multiple keys to multiple values in a single operation.
*
* @see {@link https://valkey.io/commands/mset/|valkey.io} for details.
*
* @remarks In cluster mode, if keys in `keyValueMap` map to different hash slots,
* the command will be split across these slots and executed separately for each.
* This means the command is atomic only at the slot level. If one or more slot-specific
* requests fail, the entire call will return the first encountered error, even
* though some requests may have succeeded while others did not.
* If this behavior impacts your application logic, consider splitting the
* request into sub-requests per slot to ensure atomicity.
*
* @param keysAndValues - A list of key-value pairs to set.
*
* @returns A simple "OK" response.
*
* @example
* ```typescript
* // Example usage of mset method to set values for multiple keys
* const result = await client.mset({"key1": "value1", "key2": "value2"});
* console.log(result); // Output: 'OK'
* ```
*
* @example
* ```typescript
* // Example usage of mset method to set values for multiple keys (GlideRecords allow binary data in the key)
* const result = await client.mset([{key: "key1", value: "value1"}, {key: "key2", value: "value2"}]);
* console.log(result); // Output: 'OK'
* ```
*/
mset(keysAndValues: Record<string, GlideString> | GlideRecord<GlideString>): Promise<"OK">;
/**
* Sets multiple keys to values if the key does not exist. The operation is atomic, and if one or
* more keys already exist, the entire operation fails.
*
* @see {@link https://valkey.io/commands/msetnx/|valkey.io} for more details.
* @remarks When in cluster mode, all keys in `keyValueMap` must map to the same hash slot.
*
* @param keysAndValues - A list of key-value pairs to set.
* @returns `true` if all keys were set. `false` if no key was set.
*
* @example
* ```typescript
* const result1 = await client.msetnx({"key1": "value1", "key2": "value2"});
* console.log(result1); // Output: `true`
*
* const result2 = await client.msetnx({"key2": "value4", "key3": "value5"});
* console.log(result2); // Output: `false`
* ```
*/
msetnx(keysAndValues: Record<string, GlideString> | GlideRecord<GlideString>): Promise<boolean>;
/** Increments the number stored at `key` by one. If `key` does not exist, it is set to 0 before performing the operation.
*
* @see {@link https://valkey.io/commands/incr/|valkey.io} for details.
*
* @param key - The key to increment its value.
* @returns the value of `key` after the increment.
*
* @example
* ```typescript
* // Example usage of incr method to increment the value of a key
* await client.set("my_counter", "10");
* const result = await client.incr("my_counter");
* console.log(result); // Output: 11
* ```
*/
incr(key: GlideString): Promise<number>;
/** Increments the number stored at `key` by `amount`. If `key` does not exist, it is set to 0 before performing the operation.
*
* @see {@link https://valkey.io/commands/incrby/|valkey.io} for details.
*
* @param key - The key to increment its value.
* @param amount - The amount to increment.
* @returns the value of `key` after the increment.
*
* @example
* ```typescript
* // Example usage of incrBy method to increment the value of a key by a specified amount
* await client.set("my_counter", "10");
* const result = await client.incrBy("my_counter", 5);
* console.log(result); // Output: 15
* ```
*/
incrBy(key: GlideString, amount: number): Promise<number>;
/** Increment the string representing a floating point number stored at `key` by `amount`.
* By using a negative increment value, the result is that the value stored at `key` is decremented.
* If `key` does not exist, it is set to 0 before performing the operation.
*
* @see {@link https://valkey.io/commands/incrbyfloat/|valkey.io} for details.
*
* @param key - The key to increment its value.
* @param amount - The amount to increment.
* @returns the value of `key` after the increment.
*
* @example
* ```typescript
* // Example usage of incrByFloat method to increment the value of a floating point key by a specified amount
* await client.set("my_float_counter", "10.5");
* const result = await client.incrByFloat("my_float_counter", 2.5);
* console.log(result); // Output: 13.0
* ```
*/
incrByFloat(key: GlideString, amount: number): Promise<number>;
/** Decrements the number stored at `key` by one. If `key` does not exist, it is set to 0 before performing the operation.
*
* @see {@link https://valkey.io/commands/decr/|valkey.io} for details.
*
* @param key - The key to decrement its value.
* @returns the value of `key` after the decrement.
*
* @example
* ```typescript
* // Example usage of decr method to decrement the value of a key by 1
* await client.set("my_counter", "10");
* const result = await client.decr("my_counter");
* console.log(result); // Output: 9
* ```
*/
decr(key: GlideString): Promise<number>;
/** Decrements the number stored at `key` by `amount`. If `key` does not exist, it is set to 0 before performing the operation.
*
* @see {@link https://valkey.io/commands/decrby/|valkey.io} for details.
*
* @param key - The key to decrement its value.
* @param amount - The amount to decrement.
* @returns the value of `key` after the decrement.
*
* @example
* ```typescript
* // Example usage of decrby method to decrement the value of a key by a specified amount
* await client.set("my_counter", "10");
* const result = await client.decrby("my_counter", 5);
* console.log(result); // Output: 5
* ```
*/
decrBy(key: GlideString, amount: number): Promise<number>;
/**
* Perform a bitwise operation between multiple keys (containing string values) and store the result in the
* `destination`.
*
* @see {@link https://valkey.io/commands/bitop/|valkey.io} for more details.
* @remarks When in cluster mode, `destination` and all `keys` must map to the same hash slot.
*
* @param operation - The bitwise operation to perform.
* @param destination - The key that will store the resulting string.
* @param keys - The list of keys to perform the bitwise operation on.
* @returns The size of the string stored in `destination`.
*
* @example
* ```typescript
* await client.set("key1", "A"); // "A" has binary value 01000001
* await client.set("key2", "B"); // "B" has binary value 01000010
* const result1 = await client.bitop(BitwiseOperation.AND, "destination", ["key1", "key2"]);
* console.log(result1); // Output: 1 - The size of the resulting string stored in "destination" is 1.
*
* const result2 = await client.get("destination");
* console.log(result2); // Output: "@" - "@" has binary value 01000000
* ```
*/
bitop(operation: BitwiseOperation, destination: GlideString, keys: GlideString[]): Promise<number>;
/**
* Returns the bit value at `offset` in the string value stored at `key`. `offset` must be greater than or equal
* to zero.
*
* @see {@link https://valkey.io/commands/getbit/|valkey.io} for more details.
*
* @param key - The key of the string.
* @param offset - The index of the bit to return.
* @returns The bit at the given `offset` of the string. Returns `0` if the key is empty or if the `offset` exceeds
* the length of the string.
*
* @example
* ```typescript
* const result = await client.getbit("key", 1);
* console.log(result); // Output: 1 - The second bit of the string stored at "key" is set to 1.
* ```
*/
getbit(key: GlideString, offset: number): Promise<number>;
/**
* Sets or clears the bit at `offset` in the string value stored at `key`. The `offset` is a zero-based index, with
* `0` being the first element of the list, `1` being the next element, and so on. The `offset` must be less than
* `2^32` and greater than or equal to `0`. If a key is non-existent then the bit at `offset` is set to `value` and
* the preceding bits are set to `0`.
*
* @see {@link https://valkey.io/commands/setbit/|valkey.io} for more details.
*
* @param key - The key of the string.
* @param offset - The index of the bit to be set.
* @param value - The bit value to set at `offset`. The value must be `0` or `1`.
* @returns The bit value that was previously stored at `offset`.
*
* @example
* ```typescript
* const result = await client.setbit("key", 1, 1);
* console.log(result); // Output: 0 - The second bit value was 0 before setting to 1.
* ```
*/
setbit(key: GlideString, offset: number, value: number): Promise<number>;
/**
* Returns the position of the first bit matching the given `bit` value. The optional starting offset
* `start` is a zero-based index, with `0` being the first byte of the list, `1` being the next byte and so on.
* The offset can also be a negative number indicating an offset starting at the end of the list, with `-1` being
* the last byte of the list, `-2` being the penultimate, and so on.
*
* @see {@link https://valkey.io/commands/bitpos/|valkey.io} for details.
*
* @param key - The key of the string.
* @param bit - The bit value to match. Must be `0` or `1`.
* @param options - (Optional) The {@link BitOffsetOptions}.
*
* @returns The position of the first occurrence of `bit` in the binary value of the string held at `key`.
* If `start` was provided, the search begins at the offset indicated by `start`.
*
* @example
* ```typescript
* await client.set("key1", "A1"); // "A1" has binary value 01000001 00110001
* const result1 = await client.bitpos("key1", 1);
* console.log(result1); // Output: 1 - The first occurrence of bit value 1 in the string stored at "key1" is at the second position.
*
* const result2 = await client.bitpos("key1", 1, { start: -1 });
* console.log(result2); // Output: 10 - The first occurrence of bit value 1, starting at the last byte in the string stored at "key1", is at the eleventh position.
*
* await client.set("key1", "A12"); // "A12" has binary value 01000001 00110001 00110010
* const result3 = await client.bitpos("key1", 1, { start: 1, end: -1 });
* console.log(result3); // Output: 10 - The first occurrence of bit value 1 in the second byte to the last byte of the string stored at "key1" is at the eleventh position.
*
* const result4 = await client.bitpos("key1", 1, { start: 2, end: 9, indexType: BitmapIndexType.BIT });
* console.log(result4); // Output: 7 - The first occurrence of bit value 1 in the third to tenth bits of the string stored at "key1" is at the eighth position.
* ```
*/
bitpos(key: GlideString, bit: number, options?: BitOffsetOptions): Promise<number>;
/**
* Reads or modifies the array of bits representing the string that is held at `key` based on the specified
* `subcommands`.
*
* @see {@link https://valkey.io/commands/bitfield/|valkey.io} for more details.
*
* @param key - The key of the string.
* @param subcommands - The subcommands to be performed on the binary value of the string at `key`, which could be
* any of the following:
*
* - {@link BitFieldGet}
* - {@link BitFieldSet}
* - {@link BitFieldIncrBy}
* - {@link BitFieldOverflow}
*
* @returns An array of results from the executed subcommands:
*
* - {@link BitFieldGet} returns the value in {@link BitOffset} or {@link BitOffsetMultiplier}.
* - {@link BitFieldSet} returns the old value in {@link BitOffset} or {@link BitOffsetMultiplier}.
* - {@link BitFieldIncrBy} returns the new value in {@link BitOffset} or {@link BitOffsetMultiplier}.
* - {@link BitFieldOverflow} determines the behavior of the {@link BitFieldSet} and {@link BitFieldIncrBy}
* subcommands when an overflow or underflow occurs. {@link BitFieldOverflow} does not return a value and
* does not contribute a value to the array response.
*
* @example
* ```typescript
* await client.set("key", "A"); // "A" has binary value 01000001
* const result = await client.bitfield("key", [new BitFieldSet(new UnsignedEncoding(2), new BitOffset(1), 3), new BitFieldGet(new UnsignedEncoding(2), new BitOffset(1))]);
* console.log(result); // Output: [2, 3] - The old value at offset 1 with an unsigned encoding of 2 was 2. The new value at offset 1 with an unsigned encoding of 2 is 3.
* ```
*/
bitfield(key: GlideString, subcommands: BitFieldSubCommands[]): Promise<(number | null)[]>;
/**
* Reads the array of bits representing the string that is held at `key` based on the specified `subcommands`.
*
* @see {@link https://valkey.io/commands/bitfield_ro/|valkey.io} for more details.
* @remarks Since Valkey version 6.0.0.
*
* @param key - The key of the string.
* @param subcommands - The {@link BitFieldGet} subcommands to be performed.
* @returns An array of results from the {@link BitFieldGet} subcommands.
*
* @example
* ```typescript
* await client.set("key", "A"); // "A" has binary value 01000001
* const result = await client.bitfieldReadOnly("key", [new BitFieldGet(new UnsignedEncoding(2), new BitOffset(1))]);
* console.log(result); // Output: [2] - The value at offset 1 with an unsigned encoding of 2 is 2.
* ```
*/
bitfieldReadOnly(key: GlideString, subcommands: BitFieldGet[]): Promise<number[]>;
/** Retrieve the value associated with `field` in the hash stored at `key`.
*
* @see {@link https://valkey.io/commands/hget/|valkey.io} for details.
*
* @param key - The key of the hash.
* @param field - The field in the hash stored at `key` to retrieve from the database.
* @param options - (Optional) See {@link DecoderOption}.
* @returns the value associated with `field`, or null when `field` is not present in the hash or `key` does not exist.
*
* @example
* ```typescript
* // Example usage of the hget method on an-existing field
* await client.hset("my_hash", {"field": "value"});
* const result = await client.hget("my_hash", "field");
* console.log(result); // Output: "value"
* ```
*
* @example
* ```typescript
* // Example usage of the hget method on a non-existing field
* const result = await client.hget("my_hash", "nonexistent_field");
* console.log(result); // Output: null
* ```
*/
hget(key: GlideString, field: GlideString, options?: DecoderOption): Promise<GlideString | null>;
/** Sets the specified fields to their respective values in the hash stored at `key`.
*
* @see {@link https://valkey.io/commands/hset/|valkey.io} for details.
*
* @param key - The key of the hash.
* @param fieldsAndValues - A list of field names and their values.
* @returns The number of fields that were added.
*
* @example
* ```typescript
* // Example usage of the hset method using HashDataType as input type
* const result = await client.hset("my_hash", [{"field": "field1", "value": "value1"}, {"field": "field2", "value": "value2"}]);
* console.log(result); // Output: 2 - Indicates that 2 fields were successfully set in the hash "my_hash".
*
* // Example usage of the hset method using Record<string, GlideString> as input
* const result = await client.hset("my_hash", {"field1": "value", "field2": "value2"});
* console.log(result); // Output: 2 - Indicates that 2 fields were successfully set in the hash "my_hash".
* ```
*/
hset(key: GlideString, fieldsAndValues: HashDataType | Record<string, GlideString>): Promise<number>;
/**
* Returns all field names in the hash stored at `key`.
*
* @see {@link https://valkey.io/commands/hkeys/|valkey.io} for details.
*
* @param key - The key of the hash.
* @param options - (Optional) See {@link DecoderOption}.
* @returns A list of field names for the hash, or an empty list when the key does not exist.
*
* @example
* ```typescript
* // Example usage of the hkeys method:
* await client.hset("my_hash", {"field1": "value1", "field2": "value2", "field3": "value3"});
* const result = await client.hkeys("my_hash");
* console.log(result); // Output: ["field1", "field2", "field3"] - Returns all the field names stored in the hash "my_hash".
* ```
*/
hkeys(key: GlideString, options?: DecoderOption): Promise<GlideString[]>;
/** Sets `field` in the hash stored at `key` to `value`, only if `field` does not yet exist.
* If `key` does not exist, a new key holding a hash is created.
* If `field` already exists, this operation has no effect.
*
* @see {@link https://valkey.io/commands/hsetnx/|valkey.io} for more details.
*
* @param key - The key of the hash.
* @param field - The field to set the value for.
* @param value - The value to set.
* @returns `true` if the field was set, `false` if the field already existed and was not set.
*
* @example
* ```typescript
* // Example usage of the hsetnx method
* const result = await client.hsetnx("my_hash", "field", "value");
* console.log(result); // Output: true - Indicates that the field "field" was set successfully in the hash "my_hash".
* ```
*
* @example
* ```typescript
* // Example usage of the hsetnx method on a field that already exists
* const result = await client.hsetnx("my_hash", "field", "new_value");
* console.log(result); // Output: false - Indicates that the field "field" already existed in the hash "my_hash" and was not set again.
* ```
*/
hsetnx(key: GlideString, field: GlideString, value: GlideString): Promise<boolean>;
/** Removes the specified fields from the hash stored at `key`.
* Specified fields that do not exist within this hash are ignored.
*
* @see {@link https://valkey.io/commands/hdel/|valkey.io} for details.
*
* @param key - The key of the hash.
* @param fields - The fields to remove from the hash stored at `key`.
* @returns the number of fields that were removed from the hash, not including specified but non existing fields.
* If `key` does not exist, it is treated as an empty hash and it returns 0.
*
* @example
* ```typescript
* // Example usage of the hdel method
* const result = await client.hdel("my_hash", ["field1", "field2"]);
* console.log(result); // Output: 2 - Indicates that two fields were successfully removed from the hash.
* ```
*/
hdel(key: GlideString, fields: GlideString[]): Promise<number>;
/** Returns the values associated with the specified fields in the hash stored at `key`.
*
* @see {@link https://valkey.io/commands/hmget/|valkey.io} for details.
*
* @param key - The key of the hash.
* @param fields - The fields in the hash stored at `key` to retrieve from the database.
* @param options - (Optional) See {@link DecoderOption}.
* @returns a list of values associated with the given fields, in the same order as they are requested.
* For every field that does not exist in the hash, a null value is returned.
* If `key` does not exist, it is treated as an empty hash and it returns a list of null values.
*
* @example
* ```typescript
* // Example usage of the hmget method
* const result = await client.hmget("my_hash", ["field1", "field2"]);
* console.log(result); // Output: ["value1", "value2"] - A list of values associated with the specified fields.
* ```
*/
hmget(key: GlideString, fields: GlideString[], options?: DecoderOption): Promise<(GlideString | null)[]>;