UNPKG

cache-center

Version:

A powerful and flexible Node.js caching library that provides a simple interface for managing cached data with support for products, categories, and users.

1,276 lines (1,218 loc) 778 kB
import require$$0 from 'node:crypto'; import require$$0$1 from 'node:events'; import require$$1 from 'node:net'; import require$$2 from 'node:tls'; import require$$4 from 'node:timers/promises'; import require$$7 from 'node:url'; var dist$1 = {}; var dist = {}; var decoder = {}; var verbatimString = {}; var hasRequiredVerbatimString; function requireVerbatimString () { if (hasRequiredVerbatimString) return verbatimString; hasRequiredVerbatimString = 1; Object.defineProperty(verbatimString, "__esModule", { value: true }); verbatimString.VerbatimString = void 0; class VerbatimString extends String { format; constructor(format, value) { super(value); this.format = format; } } verbatimString.VerbatimString = VerbatimString; return verbatimString; } var errors = {}; var hasRequiredErrors; function requireErrors () { if (hasRequiredErrors) return errors; hasRequiredErrors = 1; Object.defineProperty(errors, "__esModule", { value: true }); errors.MultiErrorReply = errors.TimeoutError = errors.BlobError = errors.SimpleError = errors.ErrorReply = errors.ReconnectStrategyError = errors.RootNodesUnavailableError = errors.SocketClosedUnexpectedlyError = errors.DisconnectsClientError = errors.ClientOfflineError = errors.ClientClosedError = errors.ConnectionTimeoutError = errors.WatchError = errors.AbortError = void 0; class AbortError extends Error { constructor() { super('The command was aborted'); } } errors.AbortError = AbortError; class WatchError extends Error { constructor(message = 'One (or more) of the watched keys has been changed') { super(message); } } errors.WatchError = WatchError; class ConnectionTimeoutError extends Error { constructor() { super('Connection timeout'); } } errors.ConnectionTimeoutError = ConnectionTimeoutError; class ClientClosedError extends Error { constructor() { super('The client is closed'); } } errors.ClientClosedError = ClientClosedError; class ClientOfflineError extends Error { constructor() { super('The client is offline'); } } errors.ClientOfflineError = ClientOfflineError; class DisconnectsClientError extends Error { constructor() { super('Disconnects client'); } } errors.DisconnectsClientError = DisconnectsClientError; class SocketClosedUnexpectedlyError extends Error { constructor() { super('Socket closed unexpectedly'); } } errors.SocketClosedUnexpectedlyError = SocketClosedUnexpectedlyError; class RootNodesUnavailableError extends Error { constructor() { super('All the root nodes are unavailable'); } } errors.RootNodesUnavailableError = RootNodesUnavailableError; class ReconnectStrategyError extends Error { originalError; socketError; constructor(originalError, socketError) { super(originalError.message); this.originalError = originalError; this.socketError = socketError; } } errors.ReconnectStrategyError = ReconnectStrategyError; class ErrorReply extends Error { constructor(message) { super(message); this.stack = undefined; } } errors.ErrorReply = ErrorReply; class SimpleError extends ErrorReply { } errors.SimpleError = SimpleError; class BlobError extends ErrorReply { } errors.BlobError = BlobError; class TimeoutError extends Error { } errors.TimeoutError = TimeoutError; class MultiErrorReply extends ErrorReply { replies; errorIndexes; constructor(replies, errorIndexes) { super(`${errorIndexes.length} commands failed, see .replies and .errorIndexes for more information`); this.replies = replies; this.errorIndexes = errorIndexes; } *errors() { for (const index of this.errorIndexes) { yield this.replies[index]; } } } errors.MultiErrorReply = MultiErrorReply; return errors; } var hasRequiredDecoder; function requireDecoder () { if (hasRequiredDecoder) return decoder; hasRequiredDecoder = 1; (function (exports) { var _a; Object.defineProperty(exports, "__esModule", { value: true }); exports.Decoder = exports.PUSH_TYPE_MAPPING = exports.RESP_TYPES = void 0; // @ts-nocheck const verbatim_string_1 = requireVerbatimString(); const errors_1 = requireErrors(); // https://github.com/redis/redis-specifications/blob/master/protocol/RESP3.md exports.RESP_TYPES = { NULL: 95, // _ BOOLEAN: 35, // # NUMBER: 58, // : BIG_NUMBER: 40, // ( DOUBLE: 44, // , SIMPLE_STRING: 43, // + BLOB_STRING: 36, // $ VERBATIM_STRING: 61, // = SIMPLE_ERROR: 45, // - BLOB_ERROR: 33, // ! ARRAY: 42, // * SET: 126, // ~ MAP: 37, // % PUSH: 62 // > }; const ASCII = { '\r': 13, 't': 116, '+': 43, '-': 45, '0': 48, '.': 46, 'i': 105, 'n': 110, 'E': 69, 'e': 101 }; exports.PUSH_TYPE_MAPPING = { [exports.RESP_TYPES.BLOB_STRING]: Buffer }; class Decoder { onReply; onErrorReply; onPush; getTypeMapping; #cursor = 0; #next; constructor(config) { this.onReply = config.onReply; this.onErrorReply = config.onErrorReply; this.onPush = config.onPush; this.getTypeMapping = config.getTypeMapping; } reset() { this.#cursor = 0; this.#next = undefined; } write(chunk) { if (this.#cursor >= chunk.length) { this.#cursor -= chunk.length; return; } if (this.#next) { if (this.#next(chunk) || this.#cursor >= chunk.length) { this.#cursor -= chunk.length; return; } } do { const type = chunk[this.#cursor]; if (++this.#cursor === chunk.length) { this.#next = this.#continueDecodeTypeValue.bind(this, type); break; } if (this.#decodeTypeValue(type, chunk)) { break; } } while (this.#cursor < chunk.length); this.#cursor -= chunk.length; } #continueDecodeTypeValue(type, chunk) { this.#next = undefined; return this.#decodeTypeValue(type, chunk); } #decodeTypeValue(type, chunk) { switch (type) { case exports.RESP_TYPES.NULL: this.onReply(this.#decodeNull()); return false; case exports.RESP_TYPES.BOOLEAN: return this.#handleDecodedValue(this.onReply, this.#decodeBoolean(chunk)); case exports.RESP_TYPES.NUMBER: return this.#handleDecodedValue(this.onReply, this.#decodeNumber(this.getTypeMapping()[exports.RESP_TYPES.NUMBER], chunk)); case exports.RESP_TYPES.BIG_NUMBER: return this.#handleDecodedValue(this.onReply, this.#decodeBigNumber(this.getTypeMapping()[exports.RESP_TYPES.BIG_NUMBER], chunk)); case exports.RESP_TYPES.DOUBLE: return this.#handleDecodedValue(this.onReply, this.#decodeDouble(this.getTypeMapping()[exports.RESP_TYPES.DOUBLE], chunk)); case exports.RESP_TYPES.SIMPLE_STRING: return this.#handleDecodedValue(this.onReply, this.#decodeSimpleString(this.getTypeMapping()[exports.RESP_TYPES.SIMPLE_STRING], chunk)); case exports.RESP_TYPES.BLOB_STRING: return this.#handleDecodedValue(this.onReply, this.#decodeBlobString(this.getTypeMapping()[exports.RESP_TYPES.BLOB_STRING], chunk)); case exports.RESP_TYPES.VERBATIM_STRING: return this.#handleDecodedValue(this.onReply, this.#decodeVerbatimString(this.getTypeMapping()[exports.RESP_TYPES.VERBATIM_STRING], chunk)); case exports.RESP_TYPES.SIMPLE_ERROR: return this.#handleDecodedValue(this.onErrorReply, this.#decodeSimpleError(chunk)); case exports.RESP_TYPES.BLOB_ERROR: return this.#handleDecodedValue(this.onErrorReply, this.#decodeBlobError(chunk)); case exports.RESP_TYPES.ARRAY: return this.#handleDecodedValue(this.onReply, this.#decodeArray(this.getTypeMapping(), chunk)); case exports.RESP_TYPES.SET: return this.#handleDecodedValue(this.onReply, this.#decodeSet(this.getTypeMapping(), chunk)); case exports.RESP_TYPES.MAP: return this.#handleDecodedValue(this.onReply, this.#decodeMap(this.getTypeMapping(), chunk)); case exports.RESP_TYPES.PUSH: return this.#handleDecodedValue(this.onPush, this.#decodeArray(exports.PUSH_TYPE_MAPPING, chunk)); default: throw new Error(`Unknown RESP type ${type} "${String.fromCharCode(type)}"`); } } #handleDecodedValue(cb, value) { if (typeof value === 'function') { this.#next = this.#continueDecodeValue.bind(this, cb, value); return true; } cb(value); return false; } #continueDecodeValue(cb, next, chunk) { this.#next = undefined; return this.#handleDecodedValue(cb, next(chunk)); } #decodeNull() { this.#cursor += 2; // skip \r\n return null; } #decodeBoolean(chunk) { const boolean = chunk[this.#cursor] === ASCII.t; this.#cursor += 3; // skip {t | f}\r\n return boolean; } #decodeNumber(type, chunk) { if (type === String) { return this.#decodeSimpleString(String, chunk); } switch (chunk[this.#cursor]) { case ASCII['+']: return this.#maybeDecodeNumberValue(false, chunk); case ASCII['-']: return this.#maybeDecodeNumberValue(true, chunk); default: return this.#decodeNumberValue(false, this.#decodeUnsingedNumber.bind(this, 0), chunk); } } #maybeDecodeNumberValue(isNegative, chunk) { const cb = this.#decodeUnsingedNumber.bind(this, 0); return ++this.#cursor === chunk.length ? this.#decodeNumberValue.bind(this, isNegative, cb) : this.#decodeNumberValue(isNegative, cb, chunk); } #decodeNumberValue(isNegative, numberCb, chunk) { const number = numberCb(chunk); return typeof number === 'function' ? this.#decodeNumberValue.bind(this, isNegative, number) : isNegative ? -number : number; } #decodeUnsingedNumber(number, chunk) { let cursor = this.#cursor; do { const byte = chunk[cursor]; if (byte === ASCII['\r']) { this.#cursor = cursor + 2; // skip \r\n return number; } number = number * 10 + byte - ASCII['0']; } while (++cursor < chunk.length); this.#cursor = cursor; return this.#decodeUnsingedNumber.bind(this, number); } #decodeBigNumber(type, chunk) { if (type === String) { return this.#decodeSimpleString(String, chunk); } switch (chunk[this.#cursor]) { case ASCII['+']: return this.#maybeDecodeBigNumberValue(false, chunk); case ASCII['-']: return this.#maybeDecodeBigNumberValue(true, chunk); default: return this.#decodeBigNumberValue(false, this.#decodeUnsingedBigNumber.bind(this, 0n), chunk); } } #maybeDecodeBigNumberValue(isNegative, chunk) { const cb = this.#decodeUnsingedBigNumber.bind(this, 0n); return ++this.#cursor === chunk.length ? this.#decodeBigNumberValue.bind(this, isNegative, cb) : this.#decodeBigNumberValue(isNegative, cb, chunk); } #decodeBigNumberValue(isNegative, bigNumberCb, chunk) { const bigNumber = bigNumberCb(chunk); return typeof bigNumber === 'function' ? this.#decodeBigNumberValue.bind(this, isNegative, bigNumber) : isNegative ? -bigNumber : bigNumber; } #decodeUnsingedBigNumber(bigNumber, chunk) { let cursor = this.#cursor; do { const byte = chunk[cursor]; if (byte === ASCII['\r']) { this.#cursor = cursor + 2; // skip \r\n return bigNumber; } bigNumber = bigNumber * 10n + BigInt(byte - ASCII['0']); } while (++cursor < chunk.length); this.#cursor = cursor; return this.#decodeUnsingedBigNumber.bind(this, bigNumber); } #decodeDouble(type, chunk) { if (type === String) { return this.#decodeSimpleString(String, chunk); } switch (chunk[this.#cursor]) { case ASCII.n: this.#cursor += 5; // skip nan\r\n return NaN; case ASCII['+']: return this.#maybeDecodeDoubleInteger(false, chunk); case ASCII['-']: return this.#maybeDecodeDoubleInteger(true, chunk); default: return this.#decodeDoubleInteger(false, 0, chunk); } } #maybeDecodeDoubleInteger(isNegative, chunk) { return ++this.#cursor === chunk.length ? this.#decodeDoubleInteger.bind(this, isNegative, 0) : this.#decodeDoubleInteger(isNegative, 0, chunk); } #decodeDoubleInteger(isNegative, integer, chunk) { if (chunk[this.#cursor] === ASCII.i) { this.#cursor += 5; // skip inf\r\n return isNegative ? -Infinity : Infinity; } return this.#continueDecodeDoubleInteger(isNegative, integer, chunk); } #continueDecodeDoubleInteger(isNegative, integer, chunk) { let cursor = this.#cursor; do { const byte = chunk[cursor]; switch (byte) { case ASCII['.']: this.#cursor = cursor + 1; // skip . return this.#cursor < chunk.length ? this.#decodeDoubleDecimal(isNegative, 0, integer, chunk) : this.#decodeDoubleDecimal.bind(this, isNegative, 0, integer); case ASCII.E: case ASCII.e: this.#cursor = cursor + 1; // skip E/e const i = isNegative ? -integer : integer; return this.#cursor < chunk.length ? this.#decodeDoubleExponent(i, chunk) : this.#decodeDoubleExponent.bind(this, i); case ASCII['\r']: this.#cursor = cursor + 2; // skip \r\n return isNegative ? -integer : integer; default: integer = integer * 10 + byte - ASCII['0']; } } while (++cursor < chunk.length); this.#cursor = cursor; return this.#continueDecodeDoubleInteger.bind(this, isNegative, integer); } // Precalculated multipliers for decimal points to improve performance // "... about 15 to 17 decimal places ..." // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number#:~:text=about%2015%20to%2017%20decimal%20places static #DOUBLE_DECIMAL_MULTIPLIERS = [ 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7, 1e-8, 1e-9, 1e-10, 1e-11, 1e-12, 1e-13, 1e-14, 1e-15, 1e-16, 1e-17 ]; #decodeDoubleDecimal(isNegative, decimalIndex, double, chunk) { let cursor = this.#cursor; do { const byte = chunk[cursor]; switch (byte) { case ASCII.E: case ASCII.e: this.#cursor = cursor + 1; // skip E/e const d = isNegative ? -double : double; return this.#cursor === chunk.length ? this.#decodeDoubleExponent.bind(this, d) : this.#decodeDoubleExponent(d, chunk); case ASCII['\r']: this.#cursor = cursor + 2; // skip \r\n return isNegative ? -double : double; } if (decimalIndex < _a.#DOUBLE_DECIMAL_MULTIPLIERS.length) { double += (byte - ASCII['0']) * _a.#DOUBLE_DECIMAL_MULTIPLIERS[decimalIndex++]; } } while (++cursor < chunk.length); this.#cursor = cursor; return this.#decodeDoubleDecimal.bind(this, isNegative, decimalIndex, double); } #decodeDoubleExponent(double, chunk) { switch (chunk[this.#cursor]) { case ASCII['+']: return ++this.#cursor === chunk.length ? this.#continueDecodeDoubleExponent.bind(this, false, double, 0) : this.#continueDecodeDoubleExponent(false, double, 0, chunk); case ASCII['-']: return ++this.#cursor === chunk.length ? this.#continueDecodeDoubleExponent.bind(this, true, double, 0) : this.#continueDecodeDoubleExponent(true, double, 0, chunk); } return this.#continueDecodeDoubleExponent(false, double, 0, chunk); } #continueDecodeDoubleExponent(isNegative, double, exponent, chunk) { let cursor = this.#cursor; do { const byte = chunk[cursor]; if (byte === ASCII['\r']) { this.#cursor = cursor + 2; // skip \r\n return double * 10 ** (isNegative ? -exponent : exponent); } exponent = exponent * 10 + byte - ASCII['0']; } while (++cursor < chunk.length); this.#cursor = cursor; return this.#continueDecodeDoubleExponent.bind(this, isNegative, double, exponent); } #findCRLF(chunk, cursor) { while (chunk[cursor] !== ASCII['\r']) { if (++cursor === chunk.length) { this.#cursor = chunk.length; return -1; } } this.#cursor = cursor + 2; // skip \r\n return cursor; } #decodeSimpleString(type, chunk) { const start = this.#cursor, crlfIndex = this.#findCRLF(chunk, start); if (crlfIndex === -1) { return this.#continueDecodeSimpleString.bind(this, [chunk.subarray(start)], type); } const slice = chunk.subarray(start, crlfIndex); return type === Buffer ? slice : slice.toString(); } #continueDecodeSimpleString(chunks, type, chunk) { const start = this.#cursor, crlfIndex = this.#findCRLF(chunk, start); if (crlfIndex === -1) { chunks.push(chunk.subarray(start)); return this.#continueDecodeSimpleString.bind(this, chunks, type); } chunks.push(chunk.subarray(start, crlfIndex)); return type === Buffer ? Buffer.concat(chunks) : chunks.join(''); } #decodeBlobString(type, chunk) { // RESP 2 bulk string null // https://github.com/redis/redis-specifications/blob/master/protocol/RESP2.md#resp-bulk-strings if (chunk[this.#cursor] === ASCII['-']) { this.#cursor += 4; // skip -1\r\n return null; } const length = this.#decodeUnsingedNumber(0, chunk); if (typeof length === 'function') { return this.#continueDecodeBlobStringLength.bind(this, length, type); } else if (this.#cursor >= chunk.length) { return this.#decodeBlobStringWithLength.bind(this, length, type); } return this.#decodeBlobStringWithLength(length, type, chunk); } #continueDecodeBlobStringLength(lengthCb, type, chunk) { const length = lengthCb(chunk); if (typeof length === 'function') { return this.#continueDecodeBlobStringLength.bind(this, length, type); } else if (this.#cursor >= chunk.length) { return this.#decodeBlobStringWithLength.bind(this, length, type); } return this.#decodeBlobStringWithLength(length, type, chunk); } #decodeStringWithLength(length, skip, type, chunk) { const end = this.#cursor + length; if (end >= chunk.length) { const slice = chunk.subarray(this.#cursor); this.#cursor = chunk.length; return this.#continueDecodeStringWithLength.bind(this, length - slice.length, [slice], skip, type); } const slice = chunk.subarray(this.#cursor, end); this.#cursor = end + skip; return type === Buffer ? slice : slice.toString(); } #continueDecodeStringWithLength(length, chunks, skip, type, chunk) { const end = this.#cursor + length; if (end >= chunk.length) { const slice = chunk.subarray(this.#cursor); chunks.push(slice); this.#cursor = chunk.length; return this.#continueDecodeStringWithLength.bind(this, length - slice.length, chunks, skip, type); } chunks.push(chunk.subarray(this.#cursor, end)); this.#cursor = end + skip; return type === Buffer ? Buffer.concat(chunks) : chunks.join(''); } #decodeBlobStringWithLength(length, type, chunk) { return this.#decodeStringWithLength(length, 2, type, chunk); } #decodeVerbatimString(type, chunk) { return this.#continueDecodeVerbatimStringLength(this.#decodeUnsingedNumber.bind(this, 0), type, chunk); } #continueDecodeVerbatimStringLength(lengthCb, type, chunk) { const length = lengthCb(chunk); return typeof length === 'function' ? this.#continueDecodeVerbatimStringLength.bind(this, length, type) : this.#decodeVerbatimStringWithLength(length, type, chunk); } #decodeVerbatimStringWithLength(length, type, chunk) { const stringLength = length - 4; // skip <format>: if (type === verbatim_string_1.VerbatimString) { return this.#decodeVerbatimStringFormat(stringLength, chunk); } this.#cursor += 4; // skip <format>: return this.#cursor >= chunk.length ? this.#decodeBlobStringWithLength.bind(this, stringLength, type) : this.#decodeBlobStringWithLength(stringLength, type, chunk); } #decodeVerbatimStringFormat(stringLength, chunk) { const formatCb = this.#decodeStringWithLength.bind(this, 3, 1, String); return this.#cursor >= chunk.length ? this.#continueDecodeVerbatimStringFormat.bind(this, stringLength, formatCb) : this.#continueDecodeVerbatimStringFormat(stringLength, formatCb, chunk); } #continueDecodeVerbatimStringFormat(stringLength, formatCb, chunk) { const format = formatCb(chunk); return typeof format === 'function' ? this.#continueDecodeVerbatimStringFormat.bind(this, stringLength, format) : this.#decodeVerbatimStringWithFormat(stringLength, format, chunk); } #decodeVerbatimStringWithFormat(stringLength, format, chunk) { return this.#continueDecodeVerbatimStringWithFormat(format, this.#decodeBlobStringWithLength.bind(this, stringLength, String), chunk); } #continueDecodeVerbatimStringWithFormat(format, stringCb, chunk) { const string = stringCb(chunk); return typeof string === 'function' ? this.#continueDecodeVerbatimStringWithFormat.bind(this, format, string) : new verbatim_string_1.VerbatimString(format, string); } #decodeSimpleError(chunk) { const string = this.#decodeSimpleString(String, chunk); return typeof string === 'function' ? this.#continueDecodeSimpleError.bind(this, string) : new errors_1.SimpleError(string); } #continueDecodeSimpleError(stringCb, chunk) { const string = stringCb(chunk); return typeof string === 'function' ? this.#continueDecodeSimpleError.bind(this, string) : new errors_1.SimpleError(string); } #decodeBlobError(chunk) { const string = this.#decodeBlobString(String, chunk); return typeof string === 'function' ? this.#continueDecodeBlobError.bind(this, string) : new errors_1.BlobError(string); } #continueDecodeBlobError(stringCb, chunk) { const string = stringCb(chunk); return typeof string === 'function' ? this.#continueDecodeBlobError.bind(this, string) : new errors_1.BlobError(string); } #decodeNestedType(typeMapping, chunk) { const type = chunk[this.#cursor]; return ++this.#cursor === chunk.length ? this.#decodeNestedTypeValue.bind(this, type, typeMapping) : this.#decodeNestedTypeValue(type, typeMapping, chunk); } #decodeNestedTypeValue(type, typeMapping, chunk) { switch (type) { case exports.RESP_TYPES.NULL: return this.#decodeNull(); case exports.RESP_TYPES.BOOLEAN: return this.#decodeBoolean(chunk); case exports.RESP_TYPES.NUMBER: return this.#decodeNumber(typeMapping[exports.RESP_TYPES.NUMBER], chunk); case exports.RESP_TYPES.BIG_NUMBER: return this.#decodeBigNumber(typeMapping[exports.RESP_TYPES.BIG_NUMBER], chunk); case exports.RESP_TYPES.DOUBLE: return this.#decodeDouble(typeMapping[exports.RESP_TYPES.DOUBLE], chunk); case exports.RESP_TYPES.SIMPLE_STRING: return this.#decodeSimpleString(typeMapping[exports.RESP_TYPES.SIMPLE_STRING], chunk); case exports.RESP_TYPES.BLOB_STRING: return this.#decodeBlobString(typeMapping[exports.RESP_TYPES.BLOB_STRING], chunk); case exports.RESP_TYPES.VERBATIM_STRING: return this.#decodeVerbatimString(typeMapping[exports.RESP_TYPES.VERBATIM_STRING], chunk); case exports.RESP_TYPES.SIMPLE_ERROR: return this.#decodeSimpleError(chunk); case exports.RESP_TYPES.BLOB_ERROR: return this.#decodeBlobError(chunk); case exports.RESP_TYPES.ARRAY: return this.#decodeArray(typeMapping, chunk); case exports.RESP_TYPES.SET: return this.#decodeSet(typeMapping, chunk); case exports.RESP_TYPES.MAP: return this.#decodeMap(typeMapping, chunk); default: throw new Error(`Unknown RESP type ${type} "${String.fromCharCode(type)}"`); } } #decodeArray(typeMapping, chunk) { // RESP 2 null // https://github.com/redis/redis-specifications/blob/master/protocol/RESP2.md#resp-arrays if (chunk[this.#cursor] === ASCII['-']) { this.#cursor += 4; // skip -1\r\n return null; } return this.#decodeArrayWithLength(this.#decodeUnsingedNumber(0, chunk), typeMapping, chunk); } #decodeArrayWithLength(length, typeMapping, chunk) { return typeof length === 'function' ? this.#continueDecodeArrayLength.bind(this, length, typeMapping) : this.#decodeArrayItems(new Array(length), 0, typeMapping, chunk); } #continueDecodeArrayLength(lengthCb, typeMapping, chunk) { return this.#decodeArrayWithLength(lengthCb(chunk), typeMapping, chunk); } #decodeArrayItems(array, filled, typeMapping, chunk) { for (let i = filled; i < array.length; i++) { if (this.#cursor >= chunk.length) { return this.#decodeArrayItems.bind(this, array, i, typeMapping); } const item = this.#decodeNestedType(typeMapping, chunk); if (typeof item === 'function') { return this.#continueDecodeArrayItems.bind(this, array, i, item, typeMapping); } array[i] = item; } return array; } #continueDecodeArrayItems(array, filled, itemCb, typeMapping, chunk) { const item = itemCb(chunk); if (typeof item === 'function') { return this.#continueDecodeArrayItems.bind(this, array, filled, item, typeMapping); } array[filled++] = item; return this.#decodeArrayItems(array, filled, typeMapping, chunk); } #decodeSet(typeMapping, chunk) { const length = this.#decodeUnsingedNumber(0, chunk); if (typeof length === 'function') { return this.#continueDecodeSetLength.bind(this, length, typeMapping); } return this.#decodeSetItems(length, typeMapping, chunk); } #continueDecodeSetLength(lengthCb, typeMapping, chunk) { const length = lengthCb(chunk); return typeof length === 'function' ? this.#continueDecodeSetLength.bind(this, length, typeMapping) : this.#decodeSetItems(length, typeMapping, chunk); } #decodeSetItems(length, typeMapping, chunk) { return typeMapping[exports.RESP_TYPES.SET] === Set ? this.#decodeSetAsSet(new Set(), length, typeMapping, chunk) : this.#decodeArrayItems(new Array(length), 0, typeMapping, chunk); } #decodeSetAsSet(set, remaining, typeMapping, chunk) { // using `remaining` instead of `length` & `set.size` to make it work even if the set contains duplicates while (remaining > 0) { if (this.#cursor >= chunk.length) { return this.#decodeSetAsSet.bind(this, set, remaining, typeMapping); } const item = this.#decodeNestedType(typeMapping, chunk); if (typeof item === 'function') { return this.#continueDecodeSetAsSet.bind(this, set, remaining, item, typeMapping); } set.add(item); --remaining; } return set; } #continueDecodeSetAsSet(set, remaining, itemCb, typeMapping, chunk) { const item = itemCb(chunk); if (typeof item === 'function') { return this.#continueDecodeSetAsSet.bind(this, set, remaining, item, typeMapping); } set.add(item); return this.#decodeSetAsSet(set, remaining - 1, typeMapping, chunk); } #decodeMap(typeMapping, chunk) { const length = this.#decodeUnsingedNumber(0, chunk); if (typeof length === 'function') { return this.#continueDecodeMapLength.bind(this, length, typeMapping); } return this.#decodeMapItems(length, typeMapping, chunk); } #continueDecodeMapLength(lengthCb, typeMapping, chunk) { const length = lengthCb(chunk); return typeof length === 'function' ? this.#continueDecodeMapLength.bind(this, length, typeMapping) : this.#decodeMapItems(length, typeMapping, chunk); } #decodeMapItems(length, typeMapping, chunk) { switch (typeMapping[exports.RESP_TYPES.MAP]) { case Map: return this.#decodeMapAsMap(new Map(), length, typeMapping, chunk); case Array: return this.#decodeArrayItems(new Array(length * 2), 0, typeMapping, chunk); default: return this.#decodeMapAsObject(Object.create(null), length, typeMapping, chunk); } } #decodeMapAsMap(map, remaining, typeMapping, chunk) { // using `remaining` instead of `length` & `map.size` to make it work even if the map contains duplicate keys while (remaining > 0) { if (this.#cursor >= chunk.length) { return this.#decodeMapAsMap.bind(this, map, remaining, typeMapping); } const key = this.#decodeMapKey(typeMapping, chunk); if (typeof key === 'function') { return this.#continueDecodeMapKey.bind(this, map, remaining, key, typeMapping); } if (this.#cursor >= chunk.length) { return this.#continueDecodeMapValue.bind(this, map, remaining, key, this.#decodeNestedType.bind(this, typeMapping), typeMapping); } const value = this.#decodeNestedType(typeMapping, chunk); if (typeof value === 'function') { return this.#continueDecodeMapValue.bind(this, map, remaining, key, value, typeMapping); } map.set(key, value); --remaining; } return map; } #decodeMapKey(typeMapping, chunk) { const type = chunk[this.#cursor]; return ++this.#cursor === chunk.length ? this.#decodeMapKeyValue.bind(this, type, typeMapping) : this.#decodeMapKeyValue(type, typeMapping, chunk); } #decodeMapKeyValue(type, typeMapping, chunk) { switch (type) { // decode simple string map key as string (and not as buffer) case exports.RESP_TYPES.SIMPLE_STRING: return this.#decodeSimpleString(String, chunk); // decode blob string map key as string (and not as buffer) case exports.RESP_TYPES.BLOB_STRING: return this.#decodeBlobString(String, chunk); default: return this.#decodeNestedTypeValue(type, typeMapping, chunk); } } #continueDecodeMapKey(map, remaining, keyCb, typeMapping, chunk) { const key = keyCb(chunk); if (typeof key === 'function') { return this.#continueDecodeMapKey.bind(this, map, remaining, key, typeMapping); } if (this.#cursor >= chunk.length) { return this.#continueDecodeMapValue.bind(this, map, remaining, key, this.#decodeNestedType.bind(this, typeMapping), typeMapping); } const value = this.#decodeNestedType(typeMapping, chunk); if (typeof value === 'function') { return this.#continueDecodeMapValue.bind(this, map, remaining, key, value, typeMapping); } map.set(key, value); return this.#decodeMapAsMap(map, remaining - 1, typeMapping, chunk); } #continueDecodeMapValue(map, remaining, key, valueCb, typeMapping, chunk) { const value = valueCb(chunk); if (typeof value === 'function') { return this.#continueDecodeMapValue.bind(this, map, remaining, key, value, typeMapping); } map.set(key, value); return this.#decodeMapAsMap(map, remaining - 1, typeMapping, chunk); } #decodeMapAsObject(object, remaining, typeMapping, chunk) { while (remaining > 0) { if (this.#cursor >= chunk.length) { return this.#decodeMapAsObject.bind(this, object, remaining, typeMapping); } const key = this.#decodeMapKey(typeMapping, chunk); if (typeof key === 'function') { return this.#continueDecodeMapAsObjectKey.bind(this, object, remaining, key, typeMapping); } if (this.#cursor >= chunk.length) { return this.#continueDecodeMapAsObjectValue.bind(this, object, remaining, key, this.#decodeNestedType.bind(this, typeMapping), typeMapping); } const value = this.#decodeNestedType(typeMapping, chunk); if (typeof value === 'function') { return this.#continueDecodeMapAsObjectValue.bind(this, object, remaining, key, value, typeMapping); } object[key] = value; --remaining; } return object; } #continueDecodeMapAsObjectKey(object, remaining, keyCb, typeMapping, chunk) { const key = keyCb(chunk); if (typeof key === 'function') { return this.#continueDecodeMapAsObjectKey.bind(this, object, remaining, key, typeMapping); } if (this.#cursor >= chunk.length) { return this.#continueDecodeMapAsObjectValue.bind(this, object, remaining, key, this.#decodeNestedType.bind(this, typeMapping), typeMapping); } const value = this.#decodeNestedType(typeMapping, chunk); if (typeof value === 'function') { return this.#continueDecodeMapAsObjectValue.bind(this, object, remaining, key, value, typeMapping); } object[key] = value; return this.#decodeMapAsObject(object, remaining - 1, typeMapping, chunk); } #continueDecodeMapAsObjectValue(object, remaining, key, valueCb, typeMapping, chunk) { const value = valueCb(chunk); if (typeof value === 'function') { return this.#continueDecodeMapAsObjectValue.bind(this, object, remaining, key, value, typeMapping); } object[key] = value; return this.#decodeMapAsObject(object, remaining - 1, typeMapping, chunk); } } exports.Decoder = Decoder; _a = Decoder; } (decoder)); return decoder; } var luaScript = {}; var hasRequiredLuaScript; function requireLuaScript () { if (hasRequiredLuaScript) return luaScript; hasRequiredLuaScript = 1; Object.defineProperty(luaScript, "__esModule", { value: true }); luaScript.scriptSha1 = luaScript.defineScript = void 0; const node_crypto_1 = require$$0; function defineScript(script) { return { ...script, SHA1: scriptSha1(script.SCRIPT) }; } luaScript.defineScript = defineScript; function scriptSha1(script) { return (0, node_crypto_1.createHash)('sha1').update(script).digest('hex'); } luaScript.scriptSha1 = scriptSha1; return luaScript; } var client = {}; var commands$5 = {}; var ACL_CAT = {}; var hasRequiredACL_CAT; function requireACL_CAT () { if (hasRequiredACL_CAT) return ACL_CAT; hasRequiredACL_CAT = 1; Object.defineProperty(ACL_CAT, "__esModule", { value: true }); ACL_CAT.default = { NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, parseCommand(parser, categoryName) { parser.push('ACL', 'CAT'); if (categoryName) { parser.push(categoryName); } }, transformReply: undefined }; return ACL_CAT; } var ACL_DELUSER = {}; var hasRequiredACL_DELUSER; function requireACL_DELUSER () { if (hasRequiredACL_DELUSER) return ACL_DELUSER; hasRequiredACL_DELUSER = 1; Object.defineProperty(ACL_DELUSER, "__esModule", { value: true }); ACL_DELUSER.default = { NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, parseCommand(parser, username) { parser.push('ACL', 'DELUSER'); parser.pushVariadic(username); }, transformReply: undefined }; return ACL_DELUSER; } var ACL_DRYRUN = {}; var hasRequiredACL_DRYRUN; function requireACL_DRYRUN () { if (hasRequiredACL_DRYRUN) return ACL_DRYRUN; hasRequiredACL_DRYRUN = 1; Object.defineProperty(ACL_DRYRUN, "__esModule", { value: true }); ACL_DRYRUN.default = { NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, parseCommand(parser, username, command) { parser.push('ACL', 'DRYRUN', username, ...command); }, transformReply: undefined }; return ACL_DRYRUN; } var ACL_GENPASS = {}; var hasRequiredACL_GENPASS; function requireACL_GENPASS () { if (hasRequiredACL_GENPASS) return ACL_GENPASS; hasRequiredACL_GENPASS = 1; Object.defineProperty(ACL_GENPASS, "__esModule", { value: true }); ACL_GENPASS.default = { NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, parseCommand(parser, bits) { parser.push('ACL', 'GENPASS'); if (bits) { parser.push(bits.toString()); } }, transformReply: undefined }; return ACL_GENPASS; } var ACL_GETUSER = {}; var hasRequiredACL_GETUSER; function requireACL_GETUSER () { if (hasRequiredACL_GETUSER) return ACL_GETUSER; hasRequiredACL_GETUSER = 1; Object.defineProperty(ACL_GETUSER, "__esModule", { value: true }); ACL_GETUSER.default = { NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, parseCommand(parser, username) { parser.push('ACL', 'GETUSER', username); }, transformReply: { 2: (reply) => ({ flags: reply[1], passwords: reply[3], commands: reply[5], keys: reply[7], channels: reply[9], selectors: reply[11]?.map(selector => { const inferred = selector; return { commands: inferred[1], keys: inferred[3], channels: inferred[5] }; }) }), 3: undefined } }; return ACL_GETUSER; } var ACL_LIST = {}; var hasRequiredACL_LIST; function requireACL_LIST () { if (hasRequiredACL_LIST) return ACL_LIST; hasRequiredACL_LIST = 1; Object.defineProperty(ACL_LIST, "__esModule", { value: true }); ACL_LIST.default = { NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, parseCommand(parser) { parser.push('ACL', 'LIST'); }, transformReply: undefined }; return ACL_LIST; } var ACL_LOAD = {}; var hasRequiredACL_LOAD; function requireACL_LOAD () { if (hasRequiredACL_LOAD) return ACL_LOAD; hasRequiredACL_LOAD = 1; Object.defineProperty(ACL_LOAD, "__esModule", { value: true }); ACL_LOAD.default = { NOT_KEYED_COMMAND: true, IS_READ_ONLY: true, parseCommand(parser) { parser.push('ACL', 'LOAD'); }, transformReply: undefined }; return ACL_LOAD; } var ACL_LOG_RESET = {}; var ACL_LOG = {}; var genericTransformers = {}; var parser = {}; var hasRequiredParser; function requireParser () { if (hasRequiredParser) return parser; hasRequiredParser = 1; Object.defineProperty(parser, "__esModule", { value: true }); parser.BasicCommandParser = void 0; class BasicCommandParser { #redisArgs = []; #keys = []; preserve; get redisArgs() { return this.#redisArgs; } get keys() { return this.#keys; } get firstKey() { return this.#keys[0]; } push(...arg) { this.#redisArgs.push(...arg); } ; pushVariadic(vals) { if (Array.isArray(vals)) { for (const val of vals) { this.push(val); } } else { this.push(vals); } } pushVariadicWithLength(vals) { if (Array.isArray(vals)) { this.#redisArgs.push(vals.length.toString()); } else { this.#redisArgs.push('1'); } this.pushVariadic(vals); } pushVariadicNumber(vals) { if (Array.isArray(vals)) { for (const val of vals) { this.push(val.toString()); } } else { this.push(vals.toString()); } } pushKey(key) { this.#keys.push(key); this.#redisArgs.push(key); } pushKeysLength(keys) { if (Array.isArray(keys)) { this.#redisArgs.push(keys.length.toString()); } else { this.#redisArgs.push('1'); } this.pushKeys(keys); } pushKeys(keys) { if (Array.isArray(keys)) { this.#keys.push(...keys); this.#redisArgs.push(...keys); } else { this.#keys.push(keys); this.#redisArgs.push(keys); } } } parser.BasicCommandParser = BasicCommandParser; return parser; } var hasRequiredGenericTransformers; function requireGenericTransformers () { if (hasRequiredGenericTransformers) return genericTransformers; hasRequiredGenericTransformers = 1; (function (exports) { Object.defineProperty(exports, "__esModule", { value: true }); exports.transformStreamsMessagesReplyResp3 = exports.transformStreamsMessagesReplyResp2 = exports.transformStreamMessagesReply = exports.transformStreamMessageNullReply = exports.transformStreamMessageReply = exports.parseArgs = exports.parseZKeysArguments = exports.transformRangeReply = exports.parseSlotRangesArguments = exports.transformFunctionListItemReply = exports.RedisFunctionFlags = exports.transformCommandReply = exports.CommandCategories = exports.CommandFlags = exports.parseOptionalVariadicArgument = exports.pushVariadicArgument = exports.pushVariadicNumberArguments = exports.pushVariadicArguments = exports.pushEvalArguments = exports.evalFirstKeyIndex = exports.transformPXAT = exports.transformEXAT = exports.transformSortedSetReply = exports.transformTuplesReply = exports.createTransformTuplesReplyFunc = exports.transformTuplesToMap = exports.transformNullableDoubleReply = exports.createTransformNullableDoubleReplyResp2Func = exports.transformDoubleArrayReply = exports.createTransformDoubleReplyResp2Func = exports.transformDoubleReply = exports.transformStringDoubleArgument = exports.transformDoubleArgument = exports.transformBooleanArrayReply = exports.transformBooleanReply = exports.isArrayReply = exports.isNullReply = void 0; const parser_1 = requireParser(); const decoder_1 = requireDecoder(); function isNullReply(reply) { return reply === null; } exports.isNullReply = isNullReply; function isArrayReply(reply) { return Array.isArray(reply); } exports.isArrayReply = isArrayReply; exports.transformBooleanReply = { 2: (reply) => reply === 1, 3: undefined }; exports.transformBooleanArrayReply = { 2: (reply) => { return reply.map(exports.transformBooleanReply[2]); }, 3: undefined }; function transformDoubleArgument(num) { switch (num) { case Infinity: return '+inf'; case -Infinity: return '-inf'; default: return num.toString(); } } exports.transformDoubleArgument = transformDoubleArgument; function transformStringDoubleArgument(num) { if (typeof num !== 'number') return num; return transformDoubleArgument(num); } exports.transformStringDoubleArgument = transformStringDoubleArgument; exports.transformDoubleReply = { 2: (reply, preserve, typeMapping) => { const double = typeMapping ? typeMapping[decoder_1.RESP_TYPES.DOUBLE] : undefined; switch (double) { case String: { return reply; } default: { let ret; switch (reply.toString()) { case 'inf': case '+inf': ret = Infinity; case '-inf': ret = -Infinity; case 'nan': ret = NaN; default: ret = Number(reply); } return ret; } } }, 3: undefined }; function createTransformDoubleReplyResp2Func(preserve, typeMapping) { return (reply) => { return exports.transformDoubleReply[2](reply, preserve, typeMapping); }; } exports.createTransformDoubleReplyResp2Func = createTransformDoubleReplyResp2Func; exports.transformDoubleArrayReply = { 2: (reply, preserve, typeMapping) => { return reply.map(createTransformDoubleReplyResp2Func(preserve, typeMapping)); }, 3: undefined }; function createTransformNullableDoubleReplyResp2Func(preserve, typeMapping) { return (reply) => { return exports.transformNullableDoubleReply[2](reply, preserve, typeMapping); }; } exports.createTransformNullableDoubleReplyResp2Func = createTransformNullableDoubleReplyResp2Func; exports.transformNullableDoubleReply = { 2: (reply, preserve, typeMapping) => { if (reply === null) return null; return exports.transformDoubleReply[2](reply, preserve, typeMapping); }, 3: undefined }; function transformTuplesToMap(reply, func) { const message = Object.create(null); for (let i = 0; i < reply.length; i += 2) { message[reply[i].toString()] = func(reply[i + 1]); } return message; } exports.transformTuplesToMap = transformTuplesToMap; function createTransformTuplesReplyFunc(preserve, typeMapping) { return (reply) => { return transformTuplesReply(reply, preserve, typeMapping); }; } exports.createTransformTuplesReplyFunc = createTransformTuplesReplyFunc; function transformTuplesReply(reply, preserve, typeMapping) { const mapType = typeMapping ? typeMapping[decoder_1.RESP_TYPES.MAP] : undefined; const inferred = reply; switch (mapType) { case Array: { return reply; }