UNPKG

@valkey/valkey-glide

Version:

General Language Independent Driver for the Enterprise (GLIDE) for Valkey

1,065 lines (1,064 loc) 267 kB
/** * 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)[]>;