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
JavaScript
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;
}