-first commit
This commit is contained in:
40
node_modules/@redis/client/dist/lib/RESP/decoder.d.ts
generated
vendored
Normal file
40
node_modules/@redis/client/dist/lib/RESP/decoder.d.ts
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/// <reference types="node" />
|
||||
import { ErrorReply } from '../errors';
|
||||
import { TypeMapping } from './types';
|
||||
export declare const RESP_TYPES: {
|
||||
readonly NULL: 95;
|
||||
readonly BOOLEAN: 35;
|
||||
readonly NUMBER: 58;
|
||||
readonly BIG_NUMBER: 40;
|
||||
readonly DOUBLE: 44;
|
||||
readonly SIMPLE_STRING: 43;
|
||||
readonly BLOB_STRING: 36;
|
||||
readonly VERBATIM_STRING: 61;
|
||||
readonly SIMPLE_ERROR: 45;
|
||||
readonly BLOB_ERROR: 33;
|
||||
readonly ARRAY: 42;
|
||||
readonly SET: 126;
|
||||
readonly MAP: 37;
|
||||
readonly PUSH: 62;
|
||||
};
|
||||
export declare const PUSH_TYPE_MAPPING: {
|
||||
36: BufferConstructor;
|
||||
};
|
||||
interface DecoderOptions {
|
||||
onReply(reply: any): unknown;
|
||||
onErrorReply(err: ErrorReply): unknown;
|
||||
onPush(push: Array<any>): unknown;
|
||||
getTypeMapping(): TypeMapping;
|
||||
}
|
||||
export declare class Decoder {
|
||||
#private;
|
||||
onReply: (reply: any) => unknown;
|
||||
onErrorReply: (err: ErrorReply) => unknown;
|
||||
onPush: (push: any[]) => unknown;
|
||||
getTypeMapping: () => TypeMapping;
|
||||
constructor(config: DecoderOptions);
|
||||
reset(): void;
|
||||
write(chunk: any): void;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=decoder.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/decoder.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/decoder.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"decoder.d.ts","sourceRoot":"","sources":["../../../lib/RESP/decoder.ts"],"names":[],"mappings":";AAEA,OAAO,EAA0B,UAAU,EAAE,MAAM,WAAW,CAAC;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAGtC,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;CAeb,CAAC;AAeX,eAAO,MAAM,iBAAiB;;CAE7B,CAAC;AAIF,UAAU,cAAc;IACtB,OAAO,CAAC,KAAK,EAAE,GAAG,GAAG,OAAO,CAAC;IAC7B,YAAY,CAAC,GAAG,EAAE,UAAU,GAAG,OAAO,CAAC;IACvC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC;IAClC,cAAc,IAAI,WAAW,CAAC;CAC/B;AAED,qBAAa,OAAO;;IAClB,OAAO,0BAAC;IACR,YAAY,+BAAC;IACb,MAAM,2BAAC;IACP,cAAc,oBAAC;gBAIH,MAAM,EAAE,cAAc;IAOlC,KAAK;IAKL,KAAK,CAAC,KAAK,KAAA;CAklCZ"}
|
||||
727
node_modules/@redis/client/dist/lib/RESP/decoder.js
generated
vendored
Normal file
727
node_modules/@redis/client/dist/lib/RESP/decoder.js
generated
vendored
Normal file
@@ -0,0 +1,727 @@
|
||||
"use strict";
|
||||
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 = require("./verbatim-string");
|
||||
const errors_1 = require("../errors");
|
||||
// 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));
|
||||
const buffer = Buffer.concat(chunks);
|
||||
return type === Buffer ? buffer : buffer.toString();
|
||||
}
|
||||
#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;
|
||||
const buffer = Buffer.concat(chunks);
|
||||
return type === Buffer ? buffer : buffer.toString();
|
||||
}
|
||||
#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;
|
||||
//# sourceMappingURL=decoder.js.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/decoder.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/decoder.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
3
node_modules/@redis/client/dist/lib/RESP/encoder.d.ts
generated
vendored
Normal file
3
node_modules/@redis/client/dist/lib/RESP/encoder.d.ts
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
import { RedisArgument } from './types';
|
||||
export default function encodeCommand(args: ReadonlyArray<RedisArgument>): ReadonlyArray<RedisArgument>;
|
||||
//# sourceMappingURL=encoder.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/encoder.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/encoder.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"encoder.d.ts","sourceRoot":"","sources":["../../../lib/RESP/encoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAIxC,MAAM,CAAC,OAAO,UAAU,aAAa,CAAC,IAAI,EAAE,aAAa,CAAC,aAAa,CAAC,GAAG,aAAa,CAAC,aAAa,CAAC,CAuBtG"}
|
||||
24
node_modules/@redis/client/dist/lib/RESP/encoder.js
generated
vendored
Normal file
24
node_modules/@redis/client/dist/lib/RESP/encoder.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const CRLF = '\r\n';
|
||||
function encodeCommand(args) {
|
||||
const toWrite = [];
|
||||
let strings = '*' + args.length + CRLF;
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
if (typeof arg === 'string') {
|
||||
strings += '$' + Buffer.byteLength(arg) + CRLF + arg + CRLF;
|
||||
}
|
||||
else if (arg instanceof Buffer) {
|
||||
toWrite.push(strings + '$' + arg.length.toString() + CRLF, arg);
|
||||
strings = CRLF;
|
||||
}
|
||||
else {
|
||||
throw new TypeError(`"arguments[${i}]" must be of type "string | Buffer", got ${typeof arg} instead.`);
|
||||
}
|
||||
}
|
||||
toWrite.push(strings);
|
||||
return toWrite;
|
||||
}
|
||||
exports.default = encodeCommand;
|
||||
//# sourceMappingURL=encoder.js.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/encoder.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/encoder.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"encoder.js","sourceRoot":"","sources":["../../../lib/RESP/encoder.ts"],"names":[],"mappings":";;AAEA,MAAM,IAAI,GAAG,MAAM,CAAC;AAEpB,SAAwB,aAAa,CAAC,IAAkC;IACtE,MAAM,OAAO,GAAyB,EAAE,CAAC;IAEzC,IAAI,OAAO,GAAG,GAAG,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IAEvC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,IAAI,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC;QAC9D,CAAC;aAAM,IAAI,GAAG,YAAY,MAAM,EAAE,CAAC;YACjC,OAAO,CAAC,IAAI,CACV,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,IAAI,EAC5C,GAAG,CACJ,CAAC;YACF,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,SAAS,CAAC,cAAc,CAAC,6CAA6C,OAAO,GAAG,WAAW,CAAC,CAAC;QACzG,CAAC;IACH,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAEtB,OAAO,OAAO,CAAC;AACjB,CAAC;AAvBD,gCAuBC"}
|
||||
127
node_modules/@redis/client/dist/lib/RESP/types.d.ts
generated
vendored
Normal file
127
node_modules/@redis/client/dist/lib/RESP/types.d.ts
generated
vendored
Normal file
@@ -0,0 +1,127 @@
|
||||
/// <reference types="node" />
|
||||
import { CommandParser } from '../client/parser';
|
||||
import { Tail } from '../commands/generic-transformers';
|
||||
import { BlobError, SimpleError } from '../errors';
|
||||
import { RedisScriptConfig, SHA1 } from '../lua-script';
|
||||
import { RESP_TYPES } from './decoder';
|
||||
import { VerbatimString } from './verbatim-string';
|
||||
export type RESP_TYPES = typeof RESP_TYPES;
|
||||
export type RespTypes = RESP_TYPES[keyof RESP_TYPES];
|
||||
export interface RespType<RESP_TYPE extends RespTypes, DEFAULT, TYPES = never, TYPE_MAPPING = DEFAULT | TYPES> {
|
||||
RESP_TYPE: RESP_TYPE;
|
||||
DEFAULT: DEFAULT;
|
||||
TYPES: TYPES;
|
||||
TYPE_MAPPING: MappedType<TYPE_MAPPING>;
|
||||
}
|
||||
export interface NullReply extends RespType<RESP_TYPES['NULL'], null> {
|
||||
}
|
||||
export interface BooleanReply<T extends boolean = boolean> extends RespType<RESP_TYPES['BOOLEAN'], T> {
|
||||
}
|
||||
export interface NumberReply<T extends number = number> extends RespType<RESP_TYPES['NUMBER'], T, `${T}`, number | string> {
|
||||
}
|
||||
export interface BigNumberReply<T extends bigint = bigint> extends RespType<RESP_TYPES['BIG_NUMBER'], T, number | `${T}`, bigint | number | string> {
|
||||
}
|
||||
export interface DoubleReply<T extends number = number> extends RespType<RESP_TYPES['DOUBLE'], T, `${T}`, number | string> {
|
||||
}
|
||||
export interface SimpleStringReply<T extends string = string> extends RespType<RESP_TYPES['SIMPLE_STRING'], T, Buffer, string | Buffer> {
|
||||
}
|
||||
export interface BlobStringReply<T extends string = string> extends RespType<RESP_TYPES['BLOB_STRING'], T, Buffer, string | Buffer> {
|
||||
toString(): string;
|
||||
}
|
||||
export interface VerbatimStringReply<T extends string = string> extends RespType<RESP_TYPES['VERBATIM_STRING'], T, Buffer | VerbatimString, string | Buffer | VerbatimString> {
|
||||
}
|
||||
export interface SimpleErrorReply extends RespType<RESP_TYPES['SIMPLE_ERROR'], SimpleError, Buffer> {
|
||||
}
|
||||
export interface BlobErrorReply extends RespType<RESP_TYPES['BLOB_ERROR'], BlobError, Buffer> {
|
||||
}
|
||||
export interface ArrayReply<T> extends RespType<RESP_TYPES['ARRAY'], Array<T>, never, Array<any>> {
|
||||
}
|
||||
export interface TuplesReply<T extends [...Array<unknown>]> extends RespType<RESP_TYPES['ARRAY'], T, never, Array<any>> {
|
||||
}
|
||||
export interface SetReply<T> extends RespType<RESP_TYPES['SET'], Array<T>, Set<T>, Array<any> | Set<any>> {
|
||||
}
|
||||
export interface MapReply<K, V> extends RespType<RESP_TYPES['MAP'], {
|
||||
[key: string]: V;
|
||||
}, Map<K, V> | Array<K | V>, Map<any, any> | Array<any>> {
|
||||
}
|
||||
type MapKeyValue = [key: BlobStringReply | SimpleStringReply, value: unknown];
|
||||
type MapTuples = Array<MapKeyValue>;
|
||||
type ExtractMapKey<T> = (T extends BlobStringReply<infer S> ? S : T extends SimpleStringReply<infer S> ? S : never);
|
||||
export interface TuplesToMapReply<T extends MapTuples> extends RespType<RESP_TYPES['MAP'], {
|
||||
[P in T[number] as ExtractMapKey<P[0]>]: P[1];
|
||||
}, Map<ExtractMapKey<T[number][0]>, T[number][1]> | FlattenTuples<T>> {
|
||||
}
|
||||
type FlattenTuples<T> = (T extends [] ? [] : T extends [MapKeyValue] ? T[0] : T extends [MapKeyValue, ...infer R] ? [
|
||||
...T[0],
|
||||
...FlattenTuples<R>
|
||||
] : never);
|
||||
export type ReplyUnion = (NullReply | BooleanReply | NumberReply | BigNumberReply | DoubleReply | SimpleStringReply | BlobStringReply | VerbatimStringReply | SimpleErrorReply | BlobErrorReply | ArrayReply<ReplyUnion> | SetReply<ReplyUnion> | MapReply<ReplyUnion, ReplyUnion>);
|
||||
export type MappedType<T> = ((...args: any) => T) | (new (...args: any) => T);
|
||||
type InferTypeMapping<T> = T extends RespType<RespTypes, unknown, unknown, infer FLAG_TYPES> ? FLAG_TYPES : never;
|
||||
export type TypeMapping = {
|
||||
[P in RespTypes]?: MappedType<InferTypeMapping<Extract<ReplyUnion, RespType<P, any, any, any>>>>;
|
||||
};
|
||||
type MapKey<T, TYPE_MAPPING extends TypeMapping> = ReplyWithTypeMapping<T, TYPE_MAPPING & {
|
||||
[RESP_TYPES.SIMPLE_STRING]: StringConstructor;
|
||||
[RESP_TYPES.BLOB_STRING]: StringConstructor;
|
||||
}>;
|
||||
export type UnwrapReply<REPLY extends RespType<any, any, any, any>> = REPLY['DEFAULT' | 'TYPES'];
|
||||
export type ReplyWithTypeMapping<REPLY, TYPE_MAPPING extends TypeMapping> = (REPLY extends RespType<infer RESP_TYPE, infer DEFAULT, infer TYPES, unknown> ? TYPE_MAPPING[RESP_TYPE] extends MappedType<infer T> ? ReplyWithTypeMapping<Extract<DEFAULT | TYPES, T>, TYPE_MAPPING> : ReplyWithTypeMapping<DEFAULT, TYPE_MAPPING> : (REPLY extends Array<infer T> ? Array<ReplyWithTypeMapping<T, TYPE_MAPPING>> : REPLY extends Set<infer T> ? Set<ReplyWithTypeMapping<T, TYPE_MAPPING>> : REPLY extends Map<infer K, infer V> ? Map<MapKey<K, TYPE_MAPPING>, ReplyWithTypeMapping<V, TYPE_MAPPING>> : REPLY extends Date | Buffer | Error ? REPLY : REPLY extends Record<PropertyKey, any> ? {
|
||||
[P in keyof REPLY]: ReplyWithTypeMapping<REPLY[P], TYPE_MAPPING>;
|
||||
} : REPLY));
|
||||
export type TransformReply = (this: void, reply: any, preserve?: any, typeMapping?: TypeMapping) => any;
|
||||
export type RedisArgument = string | Buffer;
|
||||
export type CommandArguments = Array<RedisArgument> & {
|
||||
preserve?: unknown;
|
||||
};
|
||||
export type Command = {
|
||||
CACHEABLE?: boolean;
|
||||
IS_READ_ONLY?: boolean;
|
||||
/**
|
||||
* @internal
|
||||
* TODO: remove once `POLICIES` is implemented
|
||||
*/
|
||||
IS_FORWARD_COMMAND?: boolean;
|
||||
NOT_KEYED_COMMAND?: true;
|
||||
parseCommand(this: void, parser: CommandParser, ...args: Array<any>): void;
|
||||
TRANSFORM_LEGACY_REPLY?: boolean;
|
||||
transformReply: TransformReply | Record<RespVersions, TransformReply>;
|
||||
unstableResp3?: boolean;
|
||||
};
|
||||
export type RedisCommands = Record<string, Command>;
|
||||
export type RedisModules = Record<string, RedisCommands>;
|
||||
export interface RedisFunction extends Command {
|
||||
NUMBER_OF_KEYS?: number;
|
||||
}
|
||||
export type RedisFunctions = Record<string, Record<string, RedisFunction>>;
|
||||
export type RedisScript = RedisScriptConfig & SHA1;
|
||||
export type RedisScripts = Record<string, RedisScript>;
|
||||
export interface CommanderConfig<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions> {
|
||||
modules?: M;
|
||||
functions?: F;
|
||||
scripts?: S;
|
||||
/**
|
||||
* Specifies the Redis Serialization Protocol version to use.
|
||||
* RESP2 is the default (value 2), while RESP3 (value 3) provides
|
||||
* additional data types and features introduced in Redis 6.0.
|
||||
*/
|
||||
RESP?: RESP;
|
||||
/**
|
||||
* When set to true, enables commands that have unstable RESP3 implementations.
|
||||
* When using RESP3 protocol, commands marked as having unstable RESP3 support
|
||||
* will throw an error unless this flag is explicitly set to true.
|
||||
* This primarily affects modules like Redis Search where response formats
|
||||
* in RESP3 mode may change in future versions.
|
||||
*/
|
||||
unstableResp3?: boolean;
|
||||
}
|
||||
type Resp2Array<T> = (T extends [] ? [] : T extends [infer ITEM] ? [Resp2Reply<ITEM>] : T extends [infer ITEM, ...infer REST] ? [
|
||||
Resp2Reply<ITEM>,
|
||||
...Resp2Array<REST>
|
||||
] : T extends Array<infer ITEM> ? Array<Resp2Reply<ITEM>> : never);
|
||||
export type Resp2Reply<RESP3REPLY> = (RESP3REPLY extends RespType<infer RESP_TYPE, infer DEFAULT, infer TYPES, unknown> ? RESP_TYPE extends RESP_TYPES['DOUBLE'] ? BlobStringReply : RESP_TYPE extends RESP_TYPES['ARRAY'] | RESP_TYPES['SET'] ? RespType<RESP_TYPE, Resp2Array<DEFAULT>> : RESP_TYPE extends RESP_TYPES['MAP'] ? RespType<RESP_TYPES['ARRAY'], Resp2Array<Extract<TYPES, Array<any>>>> : RESP3REPLY : RESP3REPLY);
|
||||
export type RespVersions = 2 | 3;
|
||||
export type CommandReply<COMMAND extends Command, RESP extends RespVersions> = (COMMAND['transformReply'] extends (...args: any) => infer T ? T : COMMAND['transformReply'] extends Record<RESP, (...args: any) => infer T> ? T : ReplyUnion);
|
||||
export type CommandSignature<COMMAND extends Command, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = (...args: Tail<Parameters<COMMAND['parseCommand']>>) => Promise<ReplyWithTypeMapping<CommandReply<COMMAND, RESP>, TYPE_MAPPING>>;
|
||||
export {};
|
||||
//# sourceMappingURL=types.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/types.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/types.d.ts.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
31
node_modules/@redis/client/dist/lib/RESP/types.js
generated
vendored
Normal file
31
node_modules/@redis/client/dist/lib/RESP/types.js
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const decoder_1 = require("./decoder");
|
||||
// export type CommandWithPoliciesSignature<
|
||||
// COMMAND extends Command,
|
||||
// RESP extends RespVersions,
|
||||
// TYPE_MAPPING extends TypeMapping,
|
||||
// POLICIES extends CommandPolicies
|
||||
// > = (...args: Parameters<COMMAND['transformArguments']>) => Promise<
|
||||
// ReplyWithPolicy<
|
||||
// ReplyWithTypeMapping<CommandReply<COMMAND, RESP>, TYPE_MAPPING>,
|
||||
// MergePolicies<COMMAND, POLICIES>
|
||||
// >
|
||||
// >;
|
||||
// export type MergePolicies<
|
||||
// COMMAND extends Command,
|
||||
// POLICIES extends CommandPolicies
|
||||
// > = Omit<COMMAND['POLICIES'], keyof POLICIES> & POLICIES;
|
||||
// type ReplyWithPolicy<
|
||||
// REPLY,
|
||||
// POLICIES extends CommandPolicies,
|
||||
// > = (
|
||||
// POLICIES['request'] extends REQUEST_POLICIES['SPECIAL'] ? never :
|
||||
// POLICIES['request'] extends null | undefined ? REPLY :
|
||||
// unknown extends POLICIES['request'] ? REPLY :
|
||||
// POLICIES['response'] extends RESPONSE_POLICIES['SPECIAL'] ? never :
|
||||
// POLICIES['response'] extends RESPONSE_POLICIES['ALL_SUCCEEDED' | 'ONE_SUCCEEDED' | 'LOGICAL_AND'] ? REPLY :
|
||||
// // otherwise, return array of replies
|
||||
// Array<REPLY>
|
||||
// );
|
||||
//# sourceMappingURL=types.js.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/types.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/types.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../lib/RESP/types.ts"],"names":[],"mappings":";;AAIA,uCAAuC;AAsXvC,4CAA4C;AAC5C,6BAA6B;AAC7B,+BAA+B;AAC/B,sCAAsC;AACtC,qCAAqC;AACrC,uEAAuE;AACvE,qBAAqB;AACrB,uEAAuE;AACvE,uCAAuC;AACvC,MAAM;AACN,KAAK;AAEL,6BAA6B;AAC7B,6BAA6B;AAC7B,qCAAqC;AACrC,4DAA4D;AAE5D,wBAAwB;AACxB,WAAW;AACX,sCAAsC;AACtC,QAAQ;AACR,sEAAsE;AACtE,2DAA2D;AAC3D,kDAAkD;AAClD,wEAAwE;AACxE,gHAAgH;AAChH,0CAA0C;AAC1C,iBAAiB;AACjB,KAAK"}
|
||||
5
node_modules/@redis/client/dist/lib/RESP/verbatim-string.d.ts
generated
vendored
Normal file
5
node_modules/@redis/client/dist/lib/RESP/verbatim-string.d.ts
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export declare class VerbatimString extends String {
|
||||
format: string;
|
||||
constructor(format: string, value: string);
|
||||
}
|
||||
//# sourceMappingURL=verbatim-string.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/verbatim-string.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/verbatim-string.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"verbatim-string.d.ts","sourceRoot":"","sources":["../../../lib/RESP/verbatim-string.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,MAAM;IAE/B,MAAM,EAAE,MAAM;gBAAd,MAAM,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM;CAIhB"}
|
||||
12
node_modules/@redis/client/dist/lib/RESP/verbatim-string.js
generated
vendored
Normal file
12
node_modules/@redis/client/dist/lib/RESP/verbatim-string.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.VerbatimString = void 0;
|
||||
class VerbatimString extends String {
|
||||
format;
|
||||
constructor(format, value) {
|
||||
super(value);
|
||||
this.format = format;
|
||||
}
|
||||
}
|
||||
exports.VerbatimString = VerbatimString;
|
||||
//# sourceMappingURL=verbatim-string.js.map
|
||||
1
node_modules/@redis/client/dist/lib/RESP/verbatim-string.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/RESP/verbatim-string.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"verbatim-string.js","sourceRoot":"","sources":["../../../lib/RESP/verbatim-string.ts"],"names":[],"mappings":";;;AAAA,MAAa,cAAe,SAAQ,MAAM;IAE/B;IADT,YACS,MAAc,EACrB,KAAa;QAEb,KAAK,CAAC,KAAK,CAAC,CAAC;QAHN,WAAM,GAAN,MAAM,CAAQ;IAIvB,CAAC;CACF;AAPD,wCAOC"}
|
||||
88
node_modules/@redis/client/dist/lib/authx/credentials-provider.d.ts
generated
vendored
Normal file
88
node_modules/@redis/client/dist/lib/authx/credentials-provider.d.ts
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
import { Disposable } from './disposable';
|
||||
/**
|
||||
* Provides credentials asynchronously.
|
||||
*/
|
||||
export interface AsyncCredentialsProvider {
|
||||
readonly type: 'async-credentials-provider';
|
||||
credentials: () => Promise<BasicAuth>;
|
||||
}
|
||||
/**
|
||||
* Provides credentials asynchronously with support for continuous updates via a subscription model.
|
||||
* This is useful for environments where credentials are frequently rotated or updated or can be revoked.
|
||||
*/
|
||||
export interface StreamingCredentialsProvider {
|
||||
readonly type: 'streaming-credentials-provider';
|
||||
/**
|
||||
* Provides initial credentials and subscribes to subsequent updates. This is used internally by the node-redis client
|
||||
* to handle credential rotation and re-authentication.
|
||||
*
|
||||
* Note: The node-redis client manages the subscription lifecycle automatically. Users only need to implement
|
||||
* onReAuthenticationError if they want to be notified about authentication failures.
|
||||
*
|
||||
* Error handling:
|
||||
* - Errors received via onError indicate a fatal issue with the credentials stream
|
||||
* - The stream is automatically closed(disposed) when onError occurs
|
||||
* - onError typically mean the provider failed to fetch new credentials after retrying
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* const provider = getStreamingProvider();
|
||||
* const [initialCredentials, disposable] = await provider.subscribe({
|
||||
* onNext: (newCredentials) => {
|
||||
* // Handle credential update
|
||||
* },
|
||||
* onError: (error) => {
|
||||
* // Handle fatal stream error
|
||||
* }
|
||||
* });
|
||||
*
|
||||
* @param listener - Callbacks to handle credential updates and errors
|
||||
* @returns A Promise resolving to [initial credentials, cleanup function]
|
||||
*/
|
||||
subscribe: (listener: StreamingCredentialsListener<BasicAuth>) => Promise<[BasicAuth, Disposable]>;
|
||||
/**
|
||||
* Called when authentication fails or credentials cannot be renewed in time.
|
||||
* Implement this to handle authentication errors in your application.
|
||||
*
|
||||
* @param error - Either a CredentialsError (invalid/expired credentials) or
|
||||
* UnableToObtainNewCredentialsError (failed to fetch new credentials on time)
|
||||
*/
|
||||
onReAuthenticationError: (error: ReAuthenticationError) => void;
|
||||
}
|
||||
/**
|
||||
* Type representing basic authentication credentials.
|
||||
*/
|
||||
export type BasicAuth = {
|
||||
username?: string;
|
||||
password?: string;
|
||||
};
|
||||
/**
|
||||
* Callback to handle credential updates and errors.
|
||||
*/
|
||||
export type StreamingCredentialsListener<T> = {
|
||||
onNext: (credentials: T) => void;
|
||||
onError: (e: Error) => void;
|
||||
};
|
||||
/**
|
||||
* Providers that can supply authentication credentials
|
||||
*/
|
||||
export type CredentialsProvider = AsyncCredentialsProvider | StreamingCredentialsProvider;
|
||||
/**
|
||||
* Errors that can occur during re-authentication.
|
||||
*/
|
||||
export type ReAuthenticationError = CredentialsError | UnableToObtainNewCredentialsError;
|
||||
/**
|
||||
* Thrown when re-authentication fails with provided credentials .
|
||||
* e.g. when the credentials are invalid, expired or revoked.
|
||||
*
|
||||
*/
|
||||
export declare class CredentialsError extends Error {
|
||||
constructor(message: string);
|
||||
}
|
||||
/**
|
||||
* Thrown when new credentials cannot be obtained before current ones expire
|
||||
*/
|
||||
export declare class UnableToObtainNewCredentialsError extends Error {
|
||||
constructor(message: string);
|
||||
}
|
||||
//# sourceMappingURL=credentials-provider.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/credentials-provider.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/credentials-provider.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"credentials-provider.d.ts","sourceRoot":"","sources":["../../../lib/authx/credentials-provider.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,4BAA4B,CAAC;IAC5C,WAAW,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,CAAA;CACtC;AAED;;;GAGG;AACH,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,IAAI,EAAE,gCAAgC,CAAC;IAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,SAAS,EAAE,CAAC,QAAQ,EAAE,4BAA4B,CAAC,SAAS,CAAC,KAAK,OAAO,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;IAElG;;;;;;OAMG;IACH,uBAAuB,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAC;CAEjE;AAED;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEhE;;GAEG;AACH,MAAM,MAAM,4BAA4B,CAAC,CAAC,IAAI;IAC5C,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,IAAI,CAAC;IACjC,OAAO,EAAE,CAAC,CAAC,EAAE,KAAK,KAAK,IAAI,CAAC;CAC7B,CAAA;AAGD;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,GAAG,4BAA4B,CAAA;AAEzF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,gBAAgB,GAAG,iCAAiC,CAAA;AAExF;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM;CAK5B;AAED;;GAEG;AACH,qBAAa,iCAAkC,SAAQ,KAAK;gBAC9C,OAAO,EAAE,MAAM;CAI5B"}
|
||||
26
node_modules/@redis/client/dist/lib/authx/credentials-provider.js
generated
vendored
Normal file
26
node_modules/@redis/client/dist/lib/authx/credentials-provider.js
generated
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UnableToObtainNewCredentialsError = exports.CredentialsError = void 0;
|
||||
/**
|
||||
* Thrown when re-authentication fails with provided credentials .
|
||||
* e.g. when the credentials are invalid, expired or revoked.
|
||||
*
|
||||
*/
|
||||
class CredentialsError extends Error {
|
||||
constructor(message) {
|
||||
super(`Re-authentication with latest credentials failed: ${message}`);
|
||||
this.name = 'CredentialsError';
|
||||
}
|
||||
}
|
||||
exports.CredentialsError = CredentialsError;
|
||||
/**
|
||||
* Thrown when new credentials cannot be obtained before current ones expire
|
||||
*/
|
||||
class UnableToObtainNewCredentialsError extends Error {
|
||||
constructor(message) {
|
||||
super(`Unable to obtain new credentials : ${message}`);
|
||||
this.name = 'UnableToObtainNewCredentialsError';
|
||||
}
|
||||
}
|
||||
exports.UnableToObtainNewCredentialsError = UnableToObtainNewCredentialsError;
|
||||
//# sourceMappingURL=credentials-provider.js.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/credentials-provider.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/credentials-provider.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"credentials-provider.js","sourceRoot":"","sources":["../../../lib/authx/credentials-provider.ts"],"names":[],"mappings":";;;AAgFA;;;;GAIG;AACH,MAAa,gBAAiB,SAAQ,KAAK;IACzC,YAAY,OAAe;QACzB,KAAK,CAAC,qDAAqD,OAAO,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;IACjC,CAAC;CAEF;AAND,4CAMC;AAED;;GAEG;AACH,MAAa,iCAAkC,SAAQ,KAAK;IAC1D,YAAY,OAAe;QACzB,KAAK,CAAC,sCAAsC,OAAO,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,IAAI,GAAG,mCAAmC,CAAC;IAClD,CAAC;CACF;AALD,8EAKC"}
|
||||
7
node_modules/@redis/client/dist/lib/authx/disposable.d.ts
generated
vendored
Normal file
7
node_modules/@redis/client/dist/lib/authx/disposable.d.ts
generated
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* Represents a resource that can be disposed.
|
||||
*/
|
||||
export interface Disposable {
|
||||
dispose(): void;
|
||||
}
|
||||
//# sourceMappingURL=disposable.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/disposable.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/disposable.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"disposable.d.ts","sourceRoot":"","sources":["../../../lib/authx/disposable.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,IAAI,IAAI,CAAC;CACjB"}
|
||||
3
node_modules/@redis/client/dist/lib/authx/disposable.js
generated
vendored
Normal file
3
node_modules/@redis/client/dist/lib/authx/disposable.js
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=disposable.js.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/disposable.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/disposable.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"disposable.js","sourceRoot":"","sources":["../../../lib/authx/disposable.ts"],"names":[],"mappings":""}
|
||||
24
node_modules/@redis/client/dist/lib/authx/identity-provider.d.ts
generated
vendored
Normal file
24
node_modules/@redis/client/dist/lib/authx/identity-provider.d.ts
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* An identity provider is responsible for providing a token that can be used to authenticate with a service.
|
||||
*/
|
||||
/**
|
||||
* The response from an identity provider when requesting a token.
|
||||
*
|
||||
* note: "native" refers to the type of the token that the actual identity provider library is using.
|
||||
*
|
||||
* @type T The type of the native idp token.
|
||||
* @property token The token.
|
||||
* @property ttlMs The time-to-live of the token in epoch milliseconds extracted from the native token in local time.
|
||||
*/
|
||||
export type TokenResponse<T> = {
|
||||
token: T;
|
||||
ttlMs: number;
|
||||
};
|
||||
export interface IdentityProvider<T> {
|
||||
/**
|
||||
* Request a token from the identity provider.
|
||||
* @returns A promise that resolves to an object containing the token and the time-to-live in epoch milliseconds.
|
||||
*/
|
||||
requestToken(): Promise<TokenResponse<T>>;
|
||||
}
|
||||
//# sourceMappingURL=identity-provider.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/identity-provider.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/identity-provider.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"identity-provider.d.ts","sourceRoot":"","sources":["../../../lib/authx/identity-provider.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;;;;;GAQG;AACH,MAAM,MAAM,aAAa,CAAC,CAAC,IAAI;IAAE,KAAK,EAAE,CAAC,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC;;;OAGG;IACH,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;CAC3C"}
|
||||
6
node_modules/@redis/client/dist/lib/authx/identity-provider.js
generated
vendored
Normal file
6
node_modules/@redis/client/dist/lib/authx/identity-provider.js
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
"use strict";
|
||||
/**
|
||||
* An identity provider is responsible for providing a token that can be used to authenticate with a service.
|
||||
*/
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
//# sourceMappingURL=identity-provider.js.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/identity-provider.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/identity-provider.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"identity-provider.js","sourceRoot":"","sources":["../../../lib/authx/identity-provider.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|
||||
6
node_modules/@redis/client/dist/lib/authx/index.d.ts
generated
vendored
Normal file
6
node_modules/@redis/client/dist/lib/authx/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
export { TokenManager, TokenManagerConfig, TokenStreamListener, RetryPolicy, IDPError } from './token-manager';
|
||||
export { CredentialsProvider, StreamingCredentialsProvider, UnableToObtainNewCredentialsError, CredentialsError, StreamingCredentialsListener, AsyncCredentialsProvider, ReAuthenticationError, BasicAuth } from './credentials-provider';
|
||||
export { Token } from './token';
|
||||
export { IdentityProvider, TokenResponse } from './identity-provider';
|
||||
export { Disposable } from './disposable';
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/index.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/index.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../lib/authx/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,iCAAiC,EACjC,gBAAgB,EAChB,4BAA4B,EAC5B,wBAAwB,EACxB,qBAAqB,EACrB,SAAS,EACV,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEtE,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA"}
|
||||
12
node_modules/@redis/client/dist/lib/authx/index.js
generated
vendored
Normal file
12
node_modules/@redis/client/dist/lib/authx/index.js
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Token = exports.CredentialsError = exports.UnableToObtainNewCredentialsError = exports.IDPError = exports.TokenManager = void 0;
|
||||
var token_manager_1 = require("./token-manager");
|
||||
Object.defineProperty(exports, "TokenManager", { enumerable: true, get: function () { return token_manager_1.TokenManager; } });
|
||||
Object.defineProperty(exports, "IDPError", { enumerable: true, get: function () { return token_manager_1.IDPError; } });
|
||||
var credentials_provider_1 = require("./credentials-provider");
|
||||
Object.defineProperty(exports, "UnableToObtainNewCredentialsError", { enumerable: true, get: function () { return credentials_provider_1.UnableToObtainNewCredentialsError; } });
|
||||
Object.defineProperty(exports, "CredentialsError", { enumerable: true, get: function () { return credentials_provider_1.CredentialsError; } });
|
||||
var token_1 = require("./token");
|
||||
Object.defineProperty(exports, "Token", { enumerable: true, get: function () { return token_1.Token; } });
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/index.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/index.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../lib/authx/index.ts"],"names":[],"mappings":";;;AAAA,iDAA+G;AAAtG,6GAAA,YAAY,OAAA;AAAwD,yGAAA,QAAQ,OAAA;AACrF,+DASgC;AAN9B,yIAAA,iCAAiC,OAAA;AACjC,wHAAA,gBAAgB,OAAA;AAMlB,iCAAgC;AAAvB,8FAAA,KAAK,OAAA"}
|
||||
164
node_modules/@redis/client/dist/lib/authx/token-manager.d.ts
generated
vendored
Normal file
164
node_modules/@redis/client/dist/lib/authx/token-manager.d.ts
generated
vendored
Normal file
@@ -0,0 +1,164 @@
|
||||
import { IdentityProvider } from './identity-provider';
|
||||
import { Token } from './token';
|
||||
import { Disposable } from './disposable';
|
||||
/**
|
||||
* The configuration for retrying token refreshes.
|
||||
*/
|
||||
export interface RetryPolicy {
|
||||
/**
|
||||
* The maximum number of attempts to retry token refreshes.
|
||||
*/
|
||||
maxAttempts: number;
|
||||
/**
|
||||
* The initial delay in milliseconds before the first retry.
|
||||
*/
|
||||
initialDelayMs: number;
|
||||
/**
|
||||
* The maximum delay in milliseconds between retries.
|
||||
* The calculated delay will be capped at this value.
|
||||
*/
|
||||
maxDelayMs: number;
|
||||
/**
|
||||
* The multiplier for exponential backoff between retries.
|
||||
* @example
|
||||
* A value of 2 will double the delay each time:
|
||||
* - 1st retry: initialDelayMs
|
||||
* - 2nd retry: initialDelayMs * 2
|
||||
* - 3rd retry: initialDelayMs * 4
|
||||
*/
|
||||
backoffMultiplier: number;
|
||||
/**
|
||||
* The percentage of jitter to apply to the delay.
|
||||
* @example
|
||||
* A value of 0.1 will add or subtract up to 10% of the delay.
|
||||
*/
|
||||
jitterPercentage?: number;
|
||||
/**
|
||||
* Function to classify errors from the identity provider as retryable or non-retryable.
|
||||
* Used to determine if a token refresh failure should be retried based on the type of error.
|
||||
*
|
||||
* The default behavior is to retry all types of errors if no function is provided.
|
||||
*
|
||||
* Common use cases:
|
||||
* - Network errors that may be transient (should retry)
|
||||
* - Invalid credentials (should not retry)
|
||||
* - Rate limiting responses (should retry)
|
||||
*
|
||||
* @param error - The error from the identity provider3
|
||||
* @param attempt - Current retry attempt (0-based)
|
||||
* @returns `true` if the error is considered transient and the operation should be retried
|
||||
*
|
||||
* @example
|
||||
* ```typescript
|
||||
* const retryPolicy: RetryPolicy = {
|
||||
* maxAttempts: 3,
|
||||
* initialDelayMs: 1000,
|
||||
* maxDelayMs: 5000,
|
||||
* backoffMultiplier: 2,
|
||||
* isRetryable: (error) => {
|
||||
* // Retry on network errors or rate limiting
|
||||
* return error instanceof NetworkError ||
|
||||
* error instanceof RateLimitError;
|
||||
* }
|
||||
* };
|
||||
* ```
|
||||
*/
|
||||
isRetryable?: (error: unknown, attempt: number) => boolean;
|
||||
}
|
||||
/**
|
||||
* the configuration for the TokenManager.
|
||||
*/
|
||||
export interface TokenManagerConfig {
|
||||
/**
|
||||
* Represents the ratio of a token's lifetime at which a refresh should be triggered.
|
||||
* For example, a value of 0.75 means the token should be refreshed when 75% of its lifetime has elapsed (or when
|
||||
* 25% of its lifetime remains).
|
||||
*/
|
||||
expirationRefreshRatio: number;
|
||||
retry?: RetryPolicy;
|
||||
}
|
||||
/**
|
||||
* IDPError indicates a failure from the identity provider.
|
||||
*
|
||||
* The `isRetryable` flag is determined by the RetryPolicy's error classification function - if an error is
|
||||
* classified as retryable, it will be marked as transient and the token manager will attempt to recover.
|
||||
*/
|
||||
export declare class IDPError extends Error {
|
||||
readonly message: string;
|
||||
readonly isRetryable: boolean;
|
||||
constructor(message: string, isRetryable: boolean);
|
||||
}
|
||||
/**
|
||||
* TokenStreamListener is an interface for objects that listen to token changes.
|
||||
*/
|
||||
export type TokenStreamListener<T> = {
|
||||
/**
|
||||
* Called each time a new token is received.
|
||||
* @param token
|
||||
*/
|
||||
onNext: (token: Token<T>) => void;
|
||||
/**
|
||||
* Called when an error occurs while calling the underlying IdentityProvider. The error can be
|
||||
* transient and the token manager will attempt to obtain a token again if retry policy is configured.
|
||||
*
|
||||
* Only fatal errors will terminate the stream and stop the token manager.
|
||||
*
|
||||
* @param error
|
||||
*/
|
||||
onError: (error: IDPError) => void;
|
||||
};
|
||||
/**
|
||||
* TokenManager is responsible for obtaining/refreshing tokens and notifying listeners about token changes.
|
||||
* It uses an IdentityProvider to request tokens. The token refresh is scheduled based on the token's TTL and
|
||||
* the expirationRefreshRatio configuration.
|
||||
*
|
||||
* The TokenManager should be disposed when it is no longer needed by calling the dispose method on the Disposable
|
||||
* returned by start.
|
||||
*/
|
||||
export declare class TokenManager<T> {
|
||||
private readonly identityProvider;
|
||||
private readonly config;
|
||||
private currentToken;
|
||||
private refreshTimeout;
|
||||
private listener;
|
||||
private retryAttempt;
|
||||
constructor(identityProvider: IdentityProvider<T>, config: TokenManagerConfig);
|
||||
/**
|
||||
* Starts the token manager and returns a Disposable that can be used to stop the token manager.
|
||||
*
|
||||
* @param listener The listener that will receive token updates.
|
||||
* @param initialDelayMs The initial delay in milliseconds before the first token refresh.
|
||||
*/
|
||||
start(listener: TokenStreamListener<T>, initialDelayMs?: number): Disposable;
|
||||
calculateRetryDelay(): number;
|
||||
private shouldRetry;
|
||||
isRunning(): boolean;
|
||||
private refresh;
|
||||
private handleNewToken;
|
||||
/**
|
||||
* Creates a Token object from a native token and sets it as the current token.
|
||||
*
|
||||
* @param nativeToken - The raw token received from the identity provider
|
||||
* @param ttlMs - Time-to-live in milliseconds for the token
|
||||
*
|
||||
* @returns A new Token instance containing the wrapped native token and expiration details
|
||||
*
|
||||
*/
|
||||
wrapAndSetCurrentToken(nativeToken: T, ttlMs: number): Token<T>;
|
||||
private scheduleNextRefresh;
|
||||
/**
|
||||
* Calculates the time in milliseconds when the token should be refreshed
|
||||
* based on the token's TTL and the expirationRefreshRatio configuration.
|
||||
*
|
||||
* @param token The token to calculate the refresh time for.
|
||||
* @param now The current time in milliseconds. Defaults to Date.now().
|
||||
*/
|
||||
calculateRefreshTime(token: Token<T>, now?: number): number;
|
||||
private stop;
|
||||
/**
|
||||
* Returns the current token or null if no token is available.
|
||||
*/
|
||||
getCurrentToken(): Token<T> | null;
|
||||
private notifyError;
|
||||
}
|
||||
//# sourceMappingURL=token-manager.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/token-manager.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/token-manager.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"token-manager.d.ts","sourceRoot":"","sources":["../../../lib/authx/token-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAiB,MAAM,qBAAqB,CAAC;AACtE,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAC;AAChC,OAAO,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAExC;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,cAAc,EAAE,MAAM,CAAC;IAEvB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;;;;;OAOG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAEjC;;;;OAIG;IACH,sBAAsB,EAAE,MAAM,CAAC;IAG/B,KAAK,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,QAAS,SAAQ,KAAK;aACL,OAAO,EAAE,MAAM;aAAkB,WAAW,EAAE,OAAO;gBAArD,OAAO,EAAE,MAAM,EAAkB,WAAW,EAAE,OAAO;CAIlF;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,CAAC,CAAC,IAAI;IACnC;;;OAGG;IACH,MAAM,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAElC;;;;;;;OAOG;IACH,OAAO,EAAE,CAAC,KAAK,EAAE,QAAQ,KAAK,IAAI,CAAC;CAEpC,CAAA;AAED;;;;;;;GAOG;AACH,qBAAa,YAAY,CAAC,CAAC;IAOvB,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPzB,OAAO,CAAC,YAAY,CAAyB;IAC7C,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAuC;IACvD,OAAO,CAAC,YAAY,CAAa;gBAGd,gBAAgB,EAAE,gBAAgB,CAAC,CAAC,CAAC,EACrC,MAAM,EAAE,kBAAkB;IAU7C;;;;;OAKG;IACI,KAAK,CAAC,QAAQ,EAAE,mBAAmB,CAAC,CAAC,CAAC,EAAE,cAAc,GAAE,MAAU,GAAG,UAAU;IAe/E,mBAAmB,IAAI,MAAM;IAoBpC,OAAO,CAAC,WAAW;IAgBZ,SAAS,IAAI,OAAO;YAIb,OAAO;IAsBrB,OAAO,CAAC,cAAc,CAQrB;IAED;;;;;;;;OAQG;IACI,sBAAsB,CAAC,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC;IAWtE,OAAO,CAAC,mBAAmB;IAa3B;;;;;;OAMG;IACI,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM;IAK9E,OAAO,CAAC,IAAI;IAYZ;;OAEG;IACI,eAAe,IAAI,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI;IAIzC,OAAO,CAAC,WAAW;CASpB"}
|
||||
184
node_modules/@redis/client/dist/lib/authx/token-manager.js
generated
vendored
Normal file
184
node_modules/@redis/client/dist/lib/authx/token-manager.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TokenManager = exports.IDPError = void 0;
|
||||
const token_1 = require("./token");
|
||||
/**
|
||||
* IDPError indicates a failure from the identity provider.
|
||||
*
|
||||
* The `isRetryable` flag is determined by the RetryPolicy's error classification function - if an error is
|
||||
* classified as retryable, it will be marked as transient and the token manager will attempt to recover.
|
||||
*/
|
||||
class IDPError extends Error {
|
||||
message;
|
||||
isRetryable;
|
||||
constructor(message, isRetryable) {
|
||||
super(message);
|
||||
this.message = message;
|
||||
this.isRetryable = isRetryable;
|
||||
this.name = 'IDPError';
|
||||
}
|
||||
}
|
||||
exports.IDPError = IDPError;
|
||||
/**
|
||||
* TokenManager is responsible for obtaining/refreshing tokens and notifying listeners about token changes.
|
||||
* It uses an IdentityProvider to request tokens. The token refresh is scheduled based on the token's TTL and
|
||||
* the expirationRefreshRatio configuration.
|
||||
*
|
||||
* The TokenManager should be disposed when it is no longer needed by calling the dispose method on the Disposable
|
||||
* returned by start.
|
||||
*/
|
||||
class TokenManager {
|
||||
identityProvider;
|
||||
config;
|
||||
currentToken = null;
|
||||
refreshTimeout = null;
|
||||
listener = null;
|
||||
retryAttempt = 0;
|
||||
constructor(identityProvider, config) {
|
||||
this.identityProvider = identityProvider;
|
||||
this.config = config;
|
||||
if (this.config.expirationRefreshRatio > 1) {
|
||||
throw new Error('expirationRefreshRatio must be less than or equal to 1');
|
||||
}
|
||||
if (this.config.expirationRefreshRatio < 0) {
|
||||
throw new Error('expirationRefreshRatio must be greater or equal to 0');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Starts the token manager and returns a Disposable that can be used to stop the token manager.
|
||||
*
|
||||
* @param listener The listener that will receive token updates.
|
||||
* @param initialDelayMs The initial delay in milliseconds before the first token refresh.
|
||||
*/
|
||||
start(listener, initialDelayMs = 0) {
|
||||
if (this.listener) {
|
||||
this.stop();
|
||||
}
|
||||
this.listener = listener;
|
||||
this.retryAttempt = 0;
|
||||
this.scheduleNextRefresh(initialDelayMs);
|
||||
return {
|
||||
dispose: () => this.stop()
|
||||
};
|
||||
}
|
||||
calculateRetryDelay() {
|
||||
if (!this.config.retry)
|
||||
return 0;
|
||||
const { initialDelayMs, maxDelayMs, backoffMultiplier, jitterPercentage } = this.config.retry;
|
||||
let delay = initialDelayMs * Math.pow(backoffMultiplier, this.retryAttempt - 1);
|
||||
delay = Math.min(delay, maxDelayMs);
|
||||
if (jitterPercentage) {
|
||||
const jitterRange = delay * (jitterPercentage / 100);
|
||||
const jitterAmount = Math.random() * jitterRange - (jitterRange / 2);
|
||||
delay += jitterAmount;
|
||||
}
|
||||
let result = Math.max(0, Math.floor(delay));
|
||||
return result;
|
||||
}
|
||||
shouldRetry(error) {
|
||||
if (!this.config.retry)
|
||||
return false;
|
||||
const { maxAttempts, isRetryable } = this.config.retry;
|
||||
if (this.retryAttempt >= maxAttempts) {
|
||||
return false;
|
||||
}
|
||||
if (isRetryable) {
|
||||
return isRetryable(error, this.retryAttempt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
isRunning() {
|
||||
return this.listener !== null;
|
||||
}
|
||||
async refresh() {
|
||||
if (!this.listener) {
|
||||
throw new Error('TokenManager is not running, but refresh was called');
|
||||
}
|
||||
try {
|
||||
await this.identityProvider.requestToken().then(this.handleNewToken);
|
||||
this.retryAttempt = 0;
|
||||
}
|
||||
catch (error) {
|
||||
if (this.shouldRetry(error)) {
|
||||
this.retryAttempt++;
|
||||
const retryDelay = this.calculateRetryDelay();
|
||||
this.notifyError(`Token refresh failed (attempt ${this.retryAttempt}), retrying in ${retryDelay}ms: ${error}`, true);
|
||||
this.scheduleNextRefresh(retryDelay);
|
||||
}
|
||||
else {
|
||||
this.notifyError(error, false);
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
handleNewToken = async ({ token: nativeToken, ttlMs }) => {
|
||||
if (!this.listener) {
|
||||
throw new Error('TokenManager is not running, but a new token was received');
|
||||
}
|
||||
const token = this.wrapAndSetCurrentToken(nativeToken, ttlMs);
|
||||
this.listener.onNext(token);
|
||||
this.scheduleNextRefresh(this.calculateRefreshTime(token));
|
||||
};
|
||||
/**
|
||||
* Creates a Token object from a native token and sets it as the current token.
|
||||
*
|
||||
* @param nativeToken - The raw token received from the identity provider
|
||||
* @param ttlMs - Time-to-live in milliseconds for the token
|
||||
*
|
||||
* @returns A new Token instance containing the wrapped native token and expiration details
|
||||
*
|
||||
*/
|
||||
wrapAndSetCurrentToken(nativeToken, ttlMs) {
|
||||
const now = Date.now();
|
||||
const token = new token_1.Token(nativeToken, now + ttlMs, now);
|
||||
this.currentToken = token;
|
||||
return token;
|
||||
}
|
||||
scheduleNextRefresh(delayMs) {
|
||||
if (this.refreshTimeout) {
|
||||
clearTimeout(this.refreshTimeout);
|
||||
this.refreshTimeout = null;
|
||||
}
|
||||
if (delayMs === 0) {
|
||||
this.refresh();
|
||||
}
|
||||
else {
|
||||
this.refreshTimeout = setTimeout(() => this.refresh(), delayMs);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Calculates the time in milliseconds when the token should be refreshed
|
||||
* based on the token's TTL and the expirationRefreshRatio configuration.
|
||||
*
|
||||
* @param token The token to calculate the refresh time for.
|
||||
* @param now The current time in milliseconds. Defaults to Date.now().
|
||||
*/
|
||||
calculateRefreshTime(token, now = Date.now()) {
|
||||
const ttlMs = token.getTtlMs(now);
|
||||
return Math.floor(ttlMs * this.config.expirationRefreshRatio);
|
||||
}
|
||||
stop() {
|
||||
if (this.refreshTimeout) {
|
||||
clearTimeout(this.refreshTimeout);
|
||||
this.refreshTimeout = null;
|
||||
}
|
||||
this.listener = null;
|
||||
this.currentToken = null;
|
||||
this.retryAttempt = 0;
|
||||
}
|
||||
/**
|
||||
* Returns the current token or null if no token is available.
|
||||
*/
|
||||
getCurrentToken() {
|
||||
return this.currentToken;
|
||||
}
|
||||
notifyError(error, isRetryable) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
if (!this.listener) {
|
||||
throw new Error(`TokenManager is not running but received an error: ${errorMessage}`);
|
||||
}
|
||||
this.listener.onError(new IDPError(errorMessage, isRetryable));
|
||||
}
|
||||
}
|
||||
exports.TokenManager = TokenManager;
|
||||
//# sourceMappingURL=token-manager.js.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/token-manager.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/token-manager.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"token-manager.js","sourceRoot":"","sources":["../../../lib/authx/token-manager.ts"],"names":[],"mappings":"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"}
|
||||
15
node_modules/@redis/client/dist/lib/authx/token.d.ts
generated
vendored
Normal file
15
node_modules/@redis/client/dist/lib/authx/token.d.ts
generated
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* A token that can be used to authenticate with a service.
|
||||
*/
|
||||
export declare class Token<T> {
|
||||
readonly value: T;
|
||||
readonly expiresAtMs: number;
|
||||
readonly receivedAtMs: number;
|
||||
constructor(value: T, expiresAtMs: number, receivedAtMs: number);
|
||||
/**
|
||||
* Returns the time-to-live of the token in milliseconds.
|
||||
* @param now The current time in milliseconds since the Unix epoch.
|
||||
*/
|
||||
getTtlMs(now: number): number;
|
||||
}
|
||||
//# sourceMappingURL=token.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/token.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/token.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../lib/authx/token.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,qBAAa,KAAK,CAAC,CAAC;aAEA,KAAK,EAAE,CAAC;aAER,WAAW,EAAE,MAAM;aAEnB,YAAY,EAAE,MAAM;gBAJpB,KAAK,EAAE,CAAC,EAER,WAAW,EAAE,MAAM,EAEnB,YAAY,EAAE,MAAM;IAGtC;;;OAGG;IACH,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;CAM9B"}
|
||||
32
node_modules/@redis/client/dist/lib/authx/token.js
generated
vendored
Normal file
32
node_modules/@redis/client/dist/lib/authx/token.js
generated
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.Token = void 0;
|
||||
/**
|
||||
* A token that can be used to authenticate with a service.
|
||||
*/
|
||||
class Token {
|
||||
value;
|
||||
expiresAtMs;
|
||||
receivedAtMs;
|
||||
constructor(value,
|
||||
//represents the token deadline - the time in milliseconds since the Unix epoch at which the token expires
|
||||
expiresAtMs,
|
||||
//represents the time in milliseconds since the Unix epoch at which the token was received
|
||||
receivedAtMs) {
|
||||
this.value = value;
|
||||
this.expiresAtMs = expiresAtMs;
|
||||
this.receivedAtMs = receivedAtMs;
|
||||
}
|
||||
/**
|
||||
* Returns the time-to-live of the token in milliseconds.
|
||||
* @param now The current time in milliseconds since the Unix epoch.
|
||||
*/
|
||||
getTtlMs(now) {
|
||||
if (this.expiresAtMs < now) {
|
||||
return 0;
|
||||
}
|
||||
return this.expiresAtMs - now;
|
||||
}
|
||||
}
|
||||
exports.Token = Token;
|
||||
//# sourceMappingURL=token.js.map
|
||||
1
node_modules/@redis/client/dist/lib/authx/token.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/authx/token.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"token.js","sourceRoot":"","sources":["../../../lib/authx/token.ts"],"names":[],"mappings":";;;AAAA;;GAEG;AACH,MAAa,KAAK;IAEE;IAEA;IAEA;IALlB,YACkB,KAAQ;IACxB,0GAA0G;IAC1F,WAAmB;IACnC,0FAA0F;IAC1E,YAAoB;QAJpB,UAAK,GAAL,KAAK,CAAG;QAER,gBAAW,GAAX,WAAW,CAAQ;QAEnB,iBAAY,GAAZ,YAAY,CAAQ;IACnC,CAAC;IAEJ;;;OAGG;IACH,QAAQ,CAAC,GAAW;QAClB,IAAI,IAAI,CAAC,WAAW,GAAG,GAAG,EAAE,CAAC;YAC3B,OAAO,CAAC,CAAC;QACX,CAAC;QACD,OAAO,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC;IAChC,CAAC;CACF;AAnBD,sBAmBC"}
|
||||
297
node_modules/@redis/client/dist/lib/client/cache.d.ts
generated
vendored
Normal file
297
node_modules/@redis/client/dist/lib/client/cache.d.ts
generated
vendored
Normal file
@@ -0,0 +1,297 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { EventEmitter } from 'stream';
|
||||
import RedisClient from '.';
|
||||
import { RedisArgument, ReplyUnion, TransformReply, TypeMapping } from '../RESP/types';
|
||||
import { BasicCommandParser } from './parser';
|
||||
/**
|
||||
* A snapshot of cache statistics.
|
||||
*
|
||||
* This class provides an immutable view of the cache's operational statistics at a particular
|
||||
* point in time. It is heavily inspired by the statistics reporting capabilities found in
|
||||
* Ben Manes's Caffeine cache (https://github.com/ben-manes/caffeine).
|
||||
*
|
||||
* Instances of `CacheStats` are typically obtained from a {@link StatsCounter} and can be used
|
||||
* for performance monitoring, debugging, or logging. It includes metrics such as hit rate,
|
||||
* miss rate, load success/failure rates, average load penalty, and eviction counts.
|
||||
*
|
||||
* All statistics are non-negative. Rates and averages are typically in the range `[0.0, 1.0]`,
|
||||
* or `0` if the an operation has not occurred (e.g. hit rate is 0 if there are no requests).
|
||||
*
|
||||
* Cache statistics are incremented according to specific rules:
|
||||
* - When a cache lookup encounters an existing entry, hitCount is incremented.
|
||||
* - When a cache lookup encounters a missing entry, missCount is incremented.
|
||||
* - When a new entry is successfully loaded, loadSuccessCount is incremented and the
|
||||
* loading time is added to totalLoadTime.
|
||||
* - When an entry fails to load, loadFailureCount is incremented and the
|
||||
* loading time is added to totalLoadTime.
|
||||
* - When an entry is evicted due to size constraints or expiration,
|
||||
* evictionCount is incremented.
|
||||
*/
|
||||
export declare class CacheStats {
|
||||
readonly hitCount: number;
|
||||
readonly missCount: number;
|
||||
readonly loadSuccessCount: number;
|
||||
readonly loadFailureCount: number;
|
||||
readonly totalLoadTime: number;
|
||||
readonly evictionCount: number;
|
||||
/**
|
||||
* Creates a new CacheStats instance with the specified statistics.
|
||||
*/
|
||||
private constructor();
|
||||
/**
|
||||
* Creates a new CacheStats instance with the specified statistics.
|
||||
*
|
||||
* @param hitCount - Number of cache hits
|
||||
* @param missCount - Number of cache misses
|
||||
* @param loadSuccessCount - Number of successful cache loads
|
||||
* @param loadFailureCount - Number of failed cache loads
|
||||
* @param totalLoadTime - Total load time in milliseconds
|
||||
* @param evictionCount - Number of cache evictions
|
||||
*/
|
||||
static of(hitCount?: number, missCount?: number, loadSuccessCount?: number, loadFailureCount?: number, totalLoadTime?: number, evictionCount?: number): CacheStats;
|
||||
/**
|
||||
* Returns a statistics instance where no cache events have been recorded.
|
||||
*
|
||||
* @returns An empty statistics instance
|
||||
*/
|
||||
static empty(): CacheStats;
|
||||
/**
|
||||
* An empty stats instance with all counters set to zero.
|
||||
*/
|
||||
private static readonly EMPTY_STATS;
|
||||
/**
|
||||
* Returns the total number of times cache lookup methods have returned
|
||||
* either a cached or uncached value.
|
||||
*
|
||||
* @returns Total number of requests (hits + misses)
|
||||
*/
|
||||
requestCount(): number;
|
||||
/**
|
||||
* Returns the hit rate of the cache.
|
||||
* This is defined as hitCount / requestCount, or 1.0 when requestCount is 0.
|
||||
*
|
||||
* @returns The ratio of cache requests that were hits (between 0.0 and 1.0)
|
||||
*/
|
||||
hitRate(): number;
|
||||
/**
|
||||
* Returns the miss rate of the cache.
|
||||
* This is defined as missCount / requestCount, or 0.0 when requestCount is 0.
|
||||
*
|
||||
* @returns The ratio of cache requests that were misses (between 0.0 and 1.0)
|
||||
*/
|
||||
missRate(): number;
|
||||
/**
|
||||
* Returns the total number of load operations (successful + failed).
|
||||
*
|
||||
* @returns Total number of load operations
|
||||
*/
|
||||
loadCount(): number;
|
||||
/**
|
||||
* Returns the ratio of cache loading attempts that failed.
|
||||
* This is defined as loadFailureCount / loadCount, or 0.0 when loadCount is 0.
|
||||
*
|
||||
* @returns Ratio of load operations that failed (between 0.0 and 1.0)
|
||||
*/
|
||||
loadFailureRate(): number;
|
||||
/**
|
||||
* Returns the average time spent loading new values, in milliseconds.
|
||||
* This is defined as totalLoadTime / loadCount, or 0.0 when loadCount is 0.
|
||||
*
|
||||
* @returns Average load time in milliseconds
|
||||
*/
|
||||
averageLoadPenalty(): number;
|
||||
/**
|
||||
* Returns a new CacheStats representing the difference between this CacheStats
|
||||
* and another. Negative values are rounded up to zero.
|
||||
*
|
||||
* @param other - The statistics to subtract from this instance
|
||||
* @returns The difference between this instance and other
|
||||
*/
|
||||
minus(other: CacheStats): CacheStats;
|
||||
/**
|
||||
* Returns a new CacheStats representing the sum of this CacheStats and another.
|
||||
*
|
||||
* @param other - The statistics to add to this instance
|
||||
* @returns The sum of this instance and other
|
||||
*/
|
||||
plus(other: CacheStats): CacheStats;
|
||||
}
|
||||
/**
|
||||
* An accumulator for cache statistics.
|
||||
*
|
||||
* This interface defines the contract for objects that record cache-related events
|
||||
* such as hits, misses, loads (successes and failures), and evictions. The design
|
||||
* is inspired by the statistics collection mechanisms in Ben Manes's Caffeine cache
|
||||
* (https://github.com/ben-manes/caffeine).
|
||||
*
|
||||
* Implementations of this interface are responsible for aggregating these events.
|
||||
* A snapshot of the current statistics can be obtained by calling the `snapshot()`
|
||||
* method, which returns an immutable {@link CacheStats} object.
|
||||
*
|
||||
* Common implementations include `DefaultStatsCounter` for active statistics collection
|
||||
* and `DisabledStatsCounter` for a no-op version when stats are not needed.
|
||||
*/
|
||||
export interface StatsCounter {
|
||||
/**
|
||||
* Records cache hits. This should be called when a cache request returns a cached value.
|
||||
*
|
||||
* @param count - The number of hits to record
|
||||
*/
|
||||
recordHits(count: number): void;
|
||||
/**
|
||||
* Records cache misses. This should be called when a cache request returns a value that was not
|
||||
* found in the cache.
|
||||
*
|
||||
* @param count - The number of misses to record
|
||||
*/
|
||||
recordMisses(count: number): void;
|
||||
/**
|
||||
* Records the successful load of a new entry. This method should be called when a cache request
|
||||
* causes an entry to be loaded and the loading completes successfully.
|
||||
*
|
||||
* @param loadTime - The number of milliseconds the cache spent computing or retrieving the new value
|
||||
*/
|
||||
recordLoadSuccess(loadTime: number): void;
|
||||
/**
|
||||
* Records the failed load of a new entry. This method should be called when a cache request
|
||||
* causes an entry to be loaded, but an exception is thrown while loading the entry.
|
||||
*
|
||||
* @param loadTime - The number of milliseconds the cache spent computing or retrieving the new value
|
||||
* prior to the failure
|
||||
*/
|
||||
recordLoadFailure(loadTime: number): void;
|
||||
/**
|
||||
* Records the eviction of an entry from the cache. This should only be called when an entry is
|
||||
* evicted due to the cache's eviction strategy, and not as a result of manual invalidations.
|
||||
*
|
||||
* @param count - The number of evictions to record
|
||||
*/
|
||||
recordEvictions(count: number): void;
|
||||
/**
|
||||
* Returns a snapshot of this counter's values. Note that this may be an inconsistent view, as it
|
||||
* may be interleaved with update operations.
|
||||
*
|
||||
* @return A snapshot of this counter's values
|
||||
*/
|
||||
snapshot(): CacheStats;
|
||||
}
|
||||
type CachingClient = RedisClient<any, any, any, any, any>;
|
||||
type CmdFunc = () => Promise<ReplyUnion>;
|
||||
type EvictionPolicy = "LRU" | "FIFO";
|
||||
/**
|
||||
* Configuration options for Client Side Cache
|
||||
*/
|
||||
export interface ClientSideCacheConfig {
|
||||
/**
|
||||
* Time-to-live in milliseconds for cached entries.
|
||||
* Use 0 for no expiration.
|
||||
* @default 0
|
||||
*/
|
||||
ttl?: number;
|
||||
/**
|
||||
* Maximum number of entries to store in the cache.
|
||||
* Use 0 for unlimited entries.
|
||||
* @default 0
|
||||
*/
|
||||
maxEntries?: number;
|
||||
/**
|
||||
* Eviction policy to use when the cache reaches its capacity.
|
||||
* - "LRU" (Least Recently Used): Evicts least recently accessed entries first
|
||||
* - "FIFO" (First In First Out): Evicts oldest entries first
|
||||
* @default "LRU"
|
||||
*/
|
||||
evictPolicy?: EvictionPolicy;
|
||||
/**
|
||||
* Whether to collect statistics about cache operations.
|
||||
* @default true
|
||||
*/
|
||||
recordStats?: boolean;
|
||||
}
|
||||
interface ClientSideCacheEntry {
|
||||
invalidate(): void;
|
||||
validate(): boolean;
|
||||
}
|
||||
declare abstract class ClientSideCacheEntryBase implements ClientSideCacheEntry {
|
||||
#private;
|
||||
constructor(ttl: number);
|
||||
invalidate(): void;
|
||||
validate(): boolean;
|
||||
}
|
||||
declare class ClientSideCacheEntryValue extends ClientSideCacheEntryBase {
|
||||
#private;
|
||||
get value(): any;
|
||||
constructor(ttl: number, value: any);
|
||||
}
|
||||
declare class ClientSideCacheEntryPromise extends ClientSideCacheEntryBase {
|
||||
#private;
|
||||
get promise(): Promise<ReplyUnion>;
|
||||
constructor(ttl: number, sendCommandPromise: Promise<ReplyUnion>);
|
||||
}
|
||||
export declare abstract class ClientSideCacheProvider extends EventEmitter {
|
||||
abstract handleCache(client: CachingClient, parser: BasicCommandParser, fn: CmdFunc, transformReply: TransformReply | undefined, typeMapping: TypeMapping | undefined): Promise<any>;
|
||||
abstract trackingOn(): Array<RedisArgument>;
|
||||
abstract invalidate(key: RedisArgument | null): void;
|
||||
abstract clear(): void;
|
||||
abstract stats(): CacheStats;
|
||||
abstract onError(): void;
|
||||
abstract onClose(): void;
|
||||
}
|
||||
export declare class BasicClientSideCache extends ClientSideCacheProvider {
|
||||
#private;
|
||||
readonly ttl: number;
|
||||
readonly maxEntries: number;
|
||||
readonly lru: boolean;
|
||||
recordEvictions(count: number): void;
|
||||
recordHits(count: number): void;
|
||||
recordMisses(count: number): void;
|
||||
constructor(config?: ClientSideCacheConfig);
|
||||
handleCache(client: CachingClient, parser: BasicCommandParser, fn: CmdFunc, transformReply?: TransformReply, typeMapping?: TypeMapping): Promise<any>;
|
||||
trackingOn(): string[];
|
||||
invalidate(key: RedisArgument | null): void;
|
||||
clear(resetStats?: boolean): void;
|
||||
get(cacheKey: string): ClientSideCacheEntry | undefined;
|
||||
delete(cacheKey: string): void;
|
||||
has(cacheKey: string): boolean;
|
||||
set(cacheKey: string, cacheEntry: ClientSideCacheEntry, keys: Array<RedisArgument>): void;
|
||||
size(): number;
|
||||
createValueEntry(client: CachingClient, value: any): ClientSideCacheEntryValue;
|
||||
createPromiseEntry(client: CachingClient, sendCommandPromise: Promise<ReplyUnion>): ClientSideCacheEntryPromise;
|
||||
stats(): CacheStats;
|
||||
onError(): void;
|
||||
onClose(): void;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
deleteOldest(): void;
|
||||
/**
|
||||
* Get cache entries for debugging
|
||||
* @internal
|
||||
*/
|
||||
entryEntries(): IterableIterator<[string, ClientSideCacheEntry]>;
|
||||
/**
|
||||
* Get key set entries for debugging
|
||||
* @internal
|
||||
*/
|
||||
keySetEntries(): IterableIterator<[string, Set<string>]>;
|
||||
}
|
||||
export declare abstract class PooledClientSideCacheProvider extends BasicClientSideCache {
|
||||
#private;
|
||||
disable(): void;
|
||||
enable(): void;
|
||||
get(cacheKey: string): ClientSideCacheEntry | undefined;
|
||||
has(cacheKey: string): boolean;
|
||||
onPoolClose(): void;
|
||||
}
|
||||
export declare class BasicPooledClientSideCache extends PooledClientSideCacheProvider {
|
||||
onError(): void;
|
||||
onClose(): void;
|
||||
}
|
||||
export declare class PooledNoRedirectClientSideCache extends BasicPooledClientSideCache {
|
||||
createValueEntry(client: CachingClient, value: any): ClientSideCacheEntryValue;
|
||||
createPromiseEntry(client: CachingClient, sendCommandPromise: Promise<ReplyUnion>): ClientSideCacheEntryPromise;
|
||||
onError(): void;
|
||||
onClose(): void;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=cache.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/cache.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/cache.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../../lib/client/cache.ts"],"names":[],"mappings":"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"}
|
||||
614
node_modules/@redis/client/dist/lib/client/cache.js
generated
vendored
Normal file
614
node_modules/@redis/client/dist/lib/client/cache.js
generated
vendored
Normal file
@@ -0,0 +1,614 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PooledNoRedirectClientSideCache = exports.BasicPooledClientSideCache = exports.PooledClientSideCacheProvider = exports.BasicClientSideCache = exports.ClientSideCacheProvider = exports.CacheStats = void 0;
|
||||
const stream_1 = require("stream");
|
||||
/**
|
||||
* A snapshot of cache statistics.
|
||||
*
|
||||
* This class provides an immutable view of the cache's operational statistics at a particular
|
||||
* point in time. It is heavily inspired by the statistics reporting capabilities found in
|
||||
* Ben Manes's Caffeine cache (https://github.com/ben-manes/caffeine).
|
||||
*
|
||||
* Instances of `CacheStats` are typically obtained from a {@link StatsCounter} and can be used
|
||||
* for performance monitoring, debugging, or logging. It includes metrics such as hit rate,
|
||||
* miss rate, load success/failure rates, average load penalty, and eviction counts.
|
||||
*
|
||||
* All statistics are non-negative. Rates and averages are typically in the range `[0.0, 1.0]`,
|
||||
* or `0` if the an operation has not occurred (e.g. hit rate is 0 if there are no requests).
|
||||
*
|
||||
* Cache statistics are incremented according to specific rules:
|
||||
* - When a cache lookup encounters an existing entry, hitCount is incremented.
|
||||
* - When a cache lookup encounters a missing entry, missCount is incremented.
|
||||
* - When a new entry is successfully loaded, loadSuccessCount is incremented and the
|
||||
* loading time is added to totalLoadTime.
|
||||
* - When an entry fails to load, loadFailureCount is incremented and the
|
||||
* loading time is added to totalLoadTime.
|
||||
* - When an entry is evicted due to size constraints or expiration,
|
||||
* evictionCount is incremented.
|
||||
*/
|
||||
class CacheStats {
|
||||
hitCount;
|
||||
missCount;
|
||||
loadSuccessCount;
|
||||
loadFailureCount;
|
||||
totalLoadTime;
|
||||
evictionCount;
|
||||
/**
|
||||
* Creates a new CacheStats instance with the specified statistics.
|
||||
*/
|
||||
constructor(hitCount, missCount, loadSuccessCount, loadFailureCount, totalLoadTime, evictionCount) {
|
||||
this.hitCount = hitCount;
|
||||
this.missCount = missCount;
|
||||
this.loadSuccessCount = loadSuccessCount;
|
||||
this.loadFailureCount = loadFailureCount;
|
||||
this.totalLoadTime = totalLoadTime;
|
||||
this.evictionCount = evictionCount;
|
||||
if (hitCount < 0 ||
|
||||
missCount < 0 ||
|
||||
loadSuccessCount < 0 ||
|
||||
loadFailureCount < 0 ||
|
||||
totalLoadTime < 0 ||
|
||||
evictionCount < 0) {
|
||||
throw new Error('All statistics values must be non-negative');
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Creates a new CacheStats instance with the specified statistics.
|
||||
*
|
||||
* @param hitCount - Number of cache hits
|
||||
* @param missCount - Number of cache misses
|
||||
* @param loadSuccessCount - Number of successful cache loads
|
||||
* @param loadFailureCount - Number of failed cache loads
|
||||
* @param totalLoadTime - Total load time in milliseconds
|
||||
* @param evictionCount - Number of cache evictions
|
||||
*/
|
||||
static of(hitCount = 0, missCount = 0, loadSuccessCount = 0, loadFailureCount = 0, totalLoadTime = 0, evictionCount = 0) {
|
||||
return new CacheStats(hitCount, missCount, loadSuccessCount, loadFailureCount, totalLoadTime, evictionCount);
|
||||
}
|
||||
/**
|
||||
* Returns a statistics instance where no cache events have been recorded.
|
||||
*
|
||||
* @returns An empty statistics instance
|
||||
*/
|
||||
static empty() {
|
||||
return CacheStats.EMPTY_STATS;
|
||||
}
|
||||
/**
|
||||
* An empty stats instance with all counters set to zero.
|
||||
*/
|
||||
static EMPTY_STATS = new CacheStats(0, 0, 0, 0, 0, 0);
|
||||
/**
|
||||
* Returns the total number of times cache lookup methods have returned
|
||||
* either a cached or uncached value.
|
||||
*
|
||||
* @returns Total number of requests (hits + misses)
|
||||
*/
|
||||
requestCount() {
|
||||
return this.hitCount + this.missCount;
|
||||
}
|
||||
/**
|
||||
* Returns the hit rate of the cache.
|
||||
* This is defined as hitCount / requestCount, or 1.0 when requestCount is 0.
|
||||
*
|
||||
* @returns The ratio of cache requests that were hits (between 0.0 and 1.0)
|
||||
*/
|
||||
hitRate() {
|
||||
const requestCount = this.requestCount();
|
||||
return requestCount === 0 ? 1.0 : this.hitCount / requestCount;
|
||||
}
|
||||
/**
|
||||
* Returns the miss rate of the cache.
|
||||
* This is defined as missCount / requestCount, or 0.0 when requestCount is 0.
|
||||
*
|
||||
* @returns The ratio of cache requests that were misses (between 0.0 and 1.0)
|
||||
*/
|
||||
missRate() {
|
||||
const requestCount = this.requestCount();
|
||||
return requestCount === 0 ? 0.0 : this.missCount / requestCount;
|
||||
}
|
||||
/**
|
||||
* Returns the total number of load operations (successful + failed).
|
||||
*
|
||||
* @returns Total number of load operations
|
||||
*/
|
||||
loadCount() {
|
||||
return this.loadSuccessCount + this.loadFailureCount;
|
||||
}
|
||||
/**
|
||||
* Returns the ratio of cache loading attempts that failed.
|
||||
* This is defined as loadFailureCount / loadCount, or 0.0 when loadCount is 0.
|
||||
*
|
||||
* @returns Ratio of load operations that failed (between 0.0 and 1.0)
|
||||
*/
|
||||
loadFailureRate() {
|
||||
const loadCount = this.loadCount();
|
||||
return loadCount === 0 ? 0.0 : this.loadFailureCount / loadCount;
|
||||
}
|
||||
/**
|
||||
* Returns the average time spent loading new values, in milliseconds.
|
||||
* This is defined as totalLoadTime / loadCount, or 0.0 when loadCount is 0.
|
||||
*
|
||||
* @returns Average load time in milliseconds
|
||||
*/
|
||||
averageLoadPenalty() {
|
||||
const loadCount = this.loadCount();
|
||||
return loadCount === 0 ? 0.0 : this.totalLoadTime / loadCount;
|
||||
}
|
||||
/**
|
||||
* Returns a new CacheStats representing the difference between this CacheStats
|
||||
* and another. Negative values are rounded up to zero.
|
||||
*
|
||||
* @param other - The statistics to subtract from this instance
|
||||
* @returns The difference between this instance and other
|
||||
*/
|
||||
minus(other) {
|
||||
return CacheStats.of(Math.max(0, this.hitCount - other.hitCount), Math.max(0, this.missCount - other.missCount), Math.max(0, this.loadSuccessCount - other.loadSuccessCount), Math.max(0, this.loadFailureCount - other.loadFailureCount), Math.max(0, this.totalLoadTime - other.totalLoadTime), Math.max(0, this.evictionCount - other.evictionCount));
|
||||
}
|
||||
/**
|
||||
* Returns a new CacheStats representing the sum of this CacheStats and another.
|
||||
*
|
||||
* @param other - The statistics to add to this instance
|
||||
* @returns The sum of this instance and other
|
||||
*/
|
||||
plus(other) {
|
||||
return CacheStats.of(this.hitCount + other.hitCount, this.missCount + other.missCount, this.loadSuccessCount + other.loadSuccessCount, this.loadFailureCount + other.loadFailureCount, this.totalLoadTime + other.totalLoadTime, this.evictionCount + other.evictionCount);
|
||||
}
|
||||
}
|
||||
exports.CacheStats = CacheStats;
|
||||
/**
|
||||
* A StatsCounter implementation that does nothing and always returns empty stats.
|
||||
*/
|
||||
class DisabledStatsCounter {
|
||||
static INSTANCE = new DisabledStatsCounter();
|
||||
constructor() { }
|
||||
recordHits(count) { }
|
||||
recordMisses(count) { }
|
||||
recordLoadSuccess(loadTime) { }
|
||||
recordLoadFailure(loadTime) { }
|
||||
recordEvictions(count) { }
|
||||
snapshot() { return CacheStats.empty(); }
|
||||
}
|
||||
/**
|
||||
* Returns a StatsCounter that does not record any cache events.
|
||||
*
|
||||
* @return A StatsCounter that does not record metrics
|
||||
*/
|
||||
function disabledStatsCounter() {
|
||||
return DisabledStatsCounter.INSTANCE;
|
||||
}
|
||||
/**
|
||||
* A StatsCounter implementation that maintains cache statistics.
|
||||
*/
|
||||
class DefaultStatsCounter {
|
||||
#hitCount = 0;
|
||||
#missCount = 0;
|
||||
#loadSuccessCount = 0;
|
||||
#loadFailureCount = 0;
|
||||
#totalLoadTime = 0;
|
||||
#evictionCount = 0;
|
||||
/**
|
||||
* Records cache hits.
|
||||
*
|
||||
* @param count - The number of hits to record
|
||||
*/
|
||||
recordHits(count) {
|
||||
this.#hitCount += count;
|
||||
}
|
||||
/**
|
||||
* Records cache misses.
|
||||
*
|
||||
* @param count - The number of misses to record
|
||||
*/
|
||||
recordMisses(count) {
|
||||
this.#missCount += count;
|
||||
}
|
||||
/**
|
||||
* Records the successful load of a new entry.
|
||||
*
|
||||
* @param loadTime - The number of milliseconds spent loading the entry
|
||||
*/
|
||||
recordLoadSuccess(loadTime) {
|
||||
this.#loadSuccessCount++;
|
||||
this.#totalLoadTime += loadTime;
|
||||
}
|
||||
/**
|
||||
* Records the failed load of a new entry.
|
||||
*
|
||||
* @param loadTime - The number of milliseconds spent attempting to load the entry
|
||||
*/
|
||||
recordLoadFailure(loadTime) {
|
||||
this.#loadFailureCount++;
|
||||
this.#totalLoadTime += loadTime;
|
||||
}
|
||||
/**
|
||||
* Records cache evictions.
|
||||
*
|
||||
* @param count - The number of evictions to record
|
||||
*/
|
||||
recordEvictions(count) {
|
||||
this.#evictionCount += count;
|
||||
}
|
||||
/**
|
||||
* Returns a snapshot of the current statistics.
|
||||
*
|
||||
* @returns A snapshot of the current statistics
|
||||
*/
|
||||
snapshot() {
|
||||
return CacheStats.of(this.#hitCount, this.#missCount, this.#loadSuccessCount, this.#loadFailureCount, this.#totalLoadTime, this.#evictionCount);
|
||||
}
|
||||
/**
|
||||
* Creates a new DefaultStatsCounter.
|
||||
*
|
||||
* @returns A new DefaultStatsCounter instance
|
||||
*/
|
||||
static create() {
|
||||
return new DefaultStatsCounter();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Generates a unique cache key from Redis command arguments
|
||||
*
|
||||
* @param redisArgs - Array of Redis command arguments
|
||||
* @returns A unique string key for caching
|
||||
*/
|
||||
function generateCacheKey(redisArgs) {
|
||||
const tmp = new Array(redisArgs.length * 2);
|
||||
for (let i = 0; i < redisArgs.length; i++) {
|
||||
tmp[i] = redisArgs[i].length;
|
||||
tmp[i + redisArgs.length] = redisArgs[i];
|
||||
}
|
||||
return tmp.join('_');
|
||||
}
|
||||
class ClientSideCacheEntryBase {
|
||||
#invalidated = false;
|
||||
#expireTime;
|
||||
constructor(ttl) {
|
||||
if (ttl == 0) {
|
||||
this.#expireTime = 0;
|
||||
}
|
||||
else {
|
||||
this.#expireTime = Date.now() + ttl;
|
||||
}
|
||||
}
|
||||
invalidate() {
|
||||
this.#invalidated = true;
|
||||
}
|
||||
validate() {
|
||||
return !this.#invalidated && (this.#expireTime == 0 || (Date.now() < this.#expireTime));
|
||||
}
|
||||
}
|
||||
class ClientSideCacheEntryValue extends ClientSideCacheEntryBase {
|
||||
#value;
|
||||
get value() {
|
||||
return this.#value;
|
||||
}
|
||||
constructor(ttl, value) {
|
||||
super(ttl);
|
||||
this.#value = value;
|
||||
}
|
||||
}
|
||||
class ClientSideCacheEntryPromise extends ClientSideCacheEntryBase {
|
||||
#sendCommandPromise;
|
||||
get promise() {
|
||||
return this.#sendCommandPromise;
|
||||
}
|
||||
constructor(ttl, sendCommandPromise) {
|
||||
super(ttl);
|
||||
this.#sendCommandPromise = sendCommandPromise;
|
||||
}
|
||||
}
|
||||
class ClientSideCacheProvider extends stream_1.EventEmitter {
|
||||
}
|
||||
exports.ClientSideCacheProvider = ClientSideCacheProvider;
|
||||
class BasicClientSideCache extends ClientSideCacheProvider {
|
||||
#cacheKeyToEntryMap;
|
||||
#keyToCacheKeySetMap;
|
||||
ttl;
|
||||
maxEntries;
|
||||
lru;
|
||||
#statsCounter;
|
||||
recordEvictions(count) {
|
||||
this.#statsCounter.recordEvictions(count);
|
||||
}
|
||||
recordHits(count) {
|
||||
this.#statsCounter.recordHits(count);
|
||||
}
|
||||
recordMisses(count) {
|
||||
this.#statsCounter.recordMisses(count);
|
||||
}
|
||||
constructor(config) {
|
||||
super();
|
||||
this.#cacheKeyToEntryMap = new Map();
|
||||
this.#keyToCacheKeySetMap = new Map();
|
||||
this.ttl = config?.ttl ?? 0;
|
||||
this.maxEntries = config?.maxEntries ?? 0;
|
||||
this.lru = config?.evictPolicy !== "FIFO";
|
||||
const recordStats = config?.recordStats !== false;
|
||||
this.#statsCounter = recordStats ? DefaultStatsCounter.create() : disabledStatsCounter();
|
||||
}
|
||||
/* logic of how caching works:
|
||||
|
||||
1. commands use a CommandParser
|
||||
it enables us to define/retrieve
|
||||
cacheKey - a unique key that corresponds to this command and its arguments
|
||||
redisKeys - an array of redis keys as strings that if the key is modified, will cause redis to invalidate this result when cached
|
||||
2. check if cacheKey is in our cache
|
||||
2b1. if its a value cacheEntry - return it
|
||||
2b2. if it's a promise cache entry - wait on promise and then go to 3c.
|
||||
3. if cacheEntry is not in cache
|
||||
3a. send the command save the promise into a a cacheEntry and then wait on result
|
||||
3b. transform reply (if required) based on transformReply
|
||||
3b. check the cacheEntry is still valid - in cache and hasn't been deleted)
|
||||
3c. if valid - overwrite with value entry
|
||||
4. return previously non cached result
|
||||
*/
|
||||
async handleCache(client, parser, fn, transformReply, typeMapping) {
|
||||
let reply;
|
||||
const cacheKey = generateCacheKey(parser.redisArgs);
|
||||
// "2"
|
||||
let cacheEntry = this.get(cacheKey);
|
||||
if (cacheEntry) {
|
||||
// If instanceof is "too slow", can add a "type" and then use an "as" cast to call proper getters.
|
||||
if (cacheEntry instanceof ClientSideCacheEntryValue) { // "2b1"
|
||||
this.#statsCounter.recordHits(1);
|
||||
return structuredClone(cacheEntry.value);
|
||||
}
|
||||
else if (cacheEntry instanceof ClientSideCacheEntryPromise) { // 2b2
|
||||
// This counts as a miss since the value hasn't been fully loaded yet.
|
||||
this.#statsCounter.recordMisses(1);
|
||||
reply = await cacheEntry.promise;
|
||||
}
|
||||
else {
|
||||
throw new Error("unknown cache entry type");
|
||||
}
|
||||
}
|
||||
else { // 3/3a
|
||||
this.#statsCounter.recordMisses(1);
|
||||
const startTime = performance.now();
|
||||
const promise = fn();
|
||||
cacheEntry = this.createPromiseEntry(client, promise);
|
||||
this.set(cacheKey, cacheEntry, parser.keys);
|
||||
try {
|
||||
reply = await promise;
|
||||
const loadTime = performance.now() - startTime;
|
||||
this.#statsCounter.recordLoadSuccess(loadTime);
|
||||
}
|
||||
catch (err) {
|
||||
const loadTime = performance.now() - startTime;
|
||||
this.#statsCounter.recordLoadFailure(loadTime);
|
||||
if (cacheEntry.validate()) {
|
||||
this.delete(cacheKey);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
// 3b
|
||||
let val;
|
||||
if (transformReply) {
|
||||
val = transformReply(reply, parser.preserve, typeMapping);
|
||||
}
|
||||
else {
|
||||
val = reply;
|
||||
}
|
||||
// 3c
|
||||
if (cacheEntry.validate()) { // revalidating promise entry (dont save value, if promise entry has been invalidated)
|
||||
// 3d
|
||||
cacheEntry = this.createValueEntry(client, val);
|
||||
this.set(cacheKey, cacheEntry, parser.keys);
|
||||
this.emit("cached-key", cacheKey);
|
||||
}
|
||||
else {
|
||||
// cache entry for key got invalidated between execution and saving, so not saving
|
||||
}
|
||||
return structuredClone(val);
|
||||
}
|
||||
trackingOn() {
|
||||
return ['CLIENT', 'TRACKING', 'ON'];
|
||||
}
|
||||
invalidate(key) {
|
||||
if (key === null) {
|
||||
this.clear(false);
|
||||
this.emit("invalidate", key);
|
||||
return;
|
||||
}
|
||||
const keySet = this.#keyToCacheKeySetMap.get(key.toString());
|
||||
if (keySet) {
|
||||
for (const cacheKey of keySet) {
|
||||
const entry = this.#cacheKeyToEntryMap.get(cacheKey);
|
||||
if (entry) {
|
||||
entry.invalidate();
|
||||
}
|
||||
this.#cacheKeyToEntryMap.delete(cacheKey);
|
||||
}
|
||||
this.#keyToCacheKeySetMap.delete(key.toString());
|
||||
}
|
||||
this.emit('invalidate', key);
|
||||
}
|
||||
clear(resetStats = true) {
|
||||
const oldSize = this.#cacheKeyToEntryMap.size;
|
||||
this.#cacheKeyToEntryMap.clear();
|
||||
this.#keyToCacheKeySetMap.clear();
|
||||
if (resetStats) {
|
||||
if (!(this.#statsCounter instanceof DisabledStatsCounter)) {
|
||||
this.#statsCounter = DefaultStatsCounter.create();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// If old entries were evicted due to clear, record them as evictions
|
||||
if (oldSize > 0) {
|
||||
this.#statsCounter.recordEvictions(oldSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
get(cacheKey) {
|
||||
const val = this.#cacheKeyToEntryMap.get(cacheKey);
|
||||
if (val && !val.validate()) {
|
||||
this.delete(cacheKey);
|
||||
this.#statsCounter.recordEvictions(1);
|
||||
this.emit("cache-evict", cacheKey);
|
||||
return undefined;
|
||||
}
|
||||
if (val !== undefined && this.lru) {
|
||||
this.#cacheKeyToEntryMap.delete(cacheKey);
|
||||
this.#cacheKeyToEntryMap.set(cacheKey, val);
|
||||
}
|
||||
return val;
|
||||
}
|
||||
delete(cacheKey) {
|
||||
const entry = this.#cacheKeyToEntryMap.get(cacheKey);
|
||||
if (entry) {
|
||||
entry.invalidate();
|
||||
this.#cacheKeyToEntryMap.delete(cacheKey);
|
||||
}
|
||||
}
|
||||
has(cacheKey) {
|
||||
return this.#cacheKeyToEntryMap.has(cacheKey);
|
||||
}
|
||||
set(cacheKey, cacheEntry, keys) {
|
||||
let count = this.#cacheKeyToEntryMap.size;
|
||||
const oldEntry = this.#cacheKeyToEntryMap.get(cacheKey);
|
||||
if (oldEntry) {
|
||||
count--; // overwriting, so not incrementig
|
||||
oldEntry.invalidate();
|
||||
}
|
||||
if (this.maxEntries > 0 && count >= this.maxEntries) {
|
||||
this.deleteOldest();
|
||||
this.#statsCounter.recordEvictions(1);
|
||||
}
|
||||
this.#cacheKeyToEntryMap.set(cacheKey, cacheEntry);
|
||||
for (const key of keys) {
|
||||
if (!this.#keyToCacheKeySetMap.has(key.toString())) {
|
||||
this.#keyToCacheKeySetMap.set(key.toString(), new Set());
|
||||
}
|
||||
const cacheKeySet = this.#keyToCacheKeySetMap.get(key.toString());
|
||||
cacheKeySet.add(cacheKey);
|
||||
}
|
||||
}
|
||||
size() {
|
||||
return this.#cacheKeyToEntryMap.size;
|
||||
}
|
||||
createValueEntry(client, value) {
|
||||
return new ClientSideCacheEntryValue(this.ttl, value);
|
||||
}
|
||||
createPromiseEntry(client, sendCommandPromise) {
|
||||
return new ClientSideCacheEntryPromise(this.ttl, sendCommandPromise);
|
||||
}
|
||||
stats() {
|
||||
return this.#statsCounter.snapshot();
|
||||
}
|
||||
onError() {
|
||||
this.clear();
|
||||
}
|
||||
onClose() {
|
||||
this.clear();
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
deleteOldest() {
|
||||
const it = this.#cacheKeyToEntryMap[Symbol.iterator]();
|
||||
const n = it.next();
|
||||
if (!n.done) {
|
||||
const key = n.value[0];
|
||||
const entry = this.#cacheKeyToEntryMap.get(key);
|
||||
if (entry) {
|
||||
entry.invalidate();
|
||||
}
|
||||
this.#cacheKeyToEntryMap.delete(key);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Get cache entries for debugging
|
||||
* @internal
|
||||
*/
|
||||
entryEntries() {
|
||||
return this.#cacheKeyToEntryMap.entries();
|
||||
}
|
||||
/**
|
||||
* Get key set entries for debugging
|
||||
* @internal
|
||||
*/
|
||||
keySetEntries() {
|
||||
return this.#keyToCacheKeySetMap.entries();
|
||||
}
|
||||
}
|
||||
exports.BasicClientSideCache = BasicClientSideCache;
|
||||
class PooledClientSideCacheProvider extends BasicClientSideCache {
|
||||
#disabled = false;
|
||||
disable() {
|
||||
this.#disabled = true;
|
||||
}
|
||||
enable() {
|
||||
this.#disabled = false;
|
||||
}
|
||||
get(cacheKey) {
|
||||
if (this.#disabled) {
|
||||
return undefined;
|
||||
}
|
||||
return super.get(cacheKey);
|
||||
}
|
||||
has(cacheKey) {
|
||||
if (this.#disabled) {
|
||||
return false;
|
||||
}
|
||||
return super.has(cacheKey);
|
||||
}
|
||||
onPoolClose() {
|
||||
this.clear();
|
||||
}
|
||||
}
|
||||
exports.PooledClientSideCacheProvider = PooledClientSideCacheProvider;
|
||||
class BasicPooledClientSideCache extends PooledClientSideCacheProvider {
|
||||
onError() {
|
||||
this.clear(false);
|
||||
}
|
||||
onClose() {
|
||||
this.clear(false);
|
||||
}
|
||||
}
|
||||
exports.BasicPooledClientSideCache = BasicPooledClientSideCache;
|
||||
class PooledClientSideCacheEntryValue extends ClientSideCacheEntryValue {
|
||||
#creator;
|
||||
constructor(ttl, creator, value) {
|
||||
super(ttl, value);
|
||||
this.#creator = creator;
|
||||
}
|
||||
validate() {
|
||||
let ret = super.validate();
|
||||
if (this.#creator) {
|
||||
ret = ret && this.#creator.client.isReady && this.#creator.client.socketEpoch == this.#creator.epoch;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
class PooledClientSideCacheEntryPromise extends ClientSideCacheEntryPromise {
|
||||
#creator;
|
||||
constructor(ttl, creator, sendCommandPromise) {
|
||||
super(ttl, sendCommandPromise);
|
||||
this.#creator = creator;
|
||||
}
|
||||
validate() {
|
||||
let ret = super.validate();
|
||||
return ret && this.#creator.client.isReady && this.#creator.client.socketEpoch == this.#creator.epoch;
|
||||
}
|
||||
}
|
||||
class PooledNoRedirectClientSideCache extends BasicPooledClientSideCache {
|
||||
createValueEntry(client, value) {
|
||||
const creator = {
|
||||
epoch: client.socketEpoch,
|
||||
client: client
|
||||
};
|
||||
return new PooledClientSideCacheEntryValue(this.ttl, creator, value);
|
||||
}
|
||||
createPromiseEntry(client, sendCommandPromise) {
|
||||
const creator = {
|
||||
epoch: client.socketEpoch,
|
||||
client: client
|
||||
};
|
||||
return new PooledClientSideCacheEntryPromise(this.ttl, creator, sendCommandPromise);
|
||||
}
|
||||
onError() { }
|
||||
onClose() { }
|
||||
}
|
||||
exports.PooledNoRedirectClientSideCache = PooledNoRedirectClientSideCache;
|
||||
//# sourceMappingURL=cache.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/cache.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/cache.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
70
node_modules/@redis/client/dist/lib/client/commands-queue.d.ts
generated
vendored
Normal file
70
node_modules/@redis/client/dist/lib/client/commands-queue.d.ts
generated
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
/// <reference types="node" />
|
||||
import { Decoder } from '../RESP/decoder';
|
||||
import { TypeMapping, RespVersions, RedisArgument } from '../RESP/types';
|
||||
import { ChannelListeners, PubSubListener, PubSubType, PubSubTypeListeners } from './pub-sub';
|
||||
import { MonitorCallback } from '.';
|
||||
export interface CommandOptions<T = TypeMapping> {
|
||||
chainId?: symbol;
|
||||
asap?: boolean;
|
||||
abortSignal?: AbortSignal;
|
||||
/**
|
||||
* Maps between RESP and JavaScript types
|
||||
*/
|
||||
typeMapping?: T;
|
||||
/**
|
||||
* Timeout for the command in milliseconds
|
||||
*/
|
||||
timeout?: number;
|
||||
}
|
||||
export interface CommandToWrite extends CommandWaitingForReply {
|
||||
args: ReadonlyArray<RedisArgument>;
|
||||
chainId: symbol | undefined;
|
||||
abort: {
|
||||
signal: AbortSignal;
|
||||
listener: () => unknown;
|
||||
} | undefined;
|
||||
timeout: {
|
||||
signal: AbortSignal;
|
||||
listener: () => unknown;
|
||||
originalTimeout: number | undefined;
|
||||
} | undefined;
|
||||
}
|
||||
interface CommandWaitingForReply {
|
||||
resolve(reply?: unknown): void;
|
||||
reject(err: unknown): void;
|
||||
channelsCounter: number | undefined;
|
||||
typeMapping: TypeMapping | undefined;
|
||||
}
|
||||
export type OnShardedChannelMoved = (channel: string, listeners: ChannelListeners) => void;
|
||||
type PushHandler = (pushItems: Array<any>) => boolean;
|
||||
export default class RedisCommandsQueue {
|
||||
#private;
|
||||
readonly decoder: Decoder;
|
||||
setMaintenanceCommandTimeout(ms: number | undefined): void;
|
||||
get isPubSubActive(): boolean;
|
||||
constructor(respVersion: RespVersions, maxLength: number | null | undefined, onShardedChannelMoved: OnShardedChannelMoved);
|
||||
addPushHandler(handler: PushHandler): void;
|
||||
waitForInflightCommandsToComplete(): Promise<void>;
|
||||
addCommand<T>(args: ReadonlyArray<RedisArgument>, options?: CommandOptions): Promise<T>;
|
||||
subscribe<T extends boolean>(type: PubSubType, channels: string | Array<string>, listener: PubSubListener<T>, returnBuffers?: T): Promise<void> | undefined;
|
||||
unsubscribe<T extends boolean>(type: PubSubType, channels?: string | Array<string>, listener?: PubSubListener<T>, returnBuffers?: T): Promise<void> | undefined;
|
||||
removeAllPubSubListeners(): {
|
||||
CHANNELS: PubSubTypeListeners;
|
||||
PATTERNS: PubSubTypeListeners;
|
||||
SHARDED: PubSubTypeListeners;
|
||||
};
|
||||
resubscribe(chainId?: symbol): Promise<void[]> | undefined;
|
||||
extendPubSubChannelListeners(type: PubSubType, channel: string, listeners: ChannelListeners): Promise<void> | undefined;
|
||||
extendPubSubListeners(type: PubSubType, listeners: PubSubTypeListeners): Promise<void> | undefined;
|
||||
getPubSubListeners(type: PubSubType): PubSubTypeListeners;
|
||||
monitor(callback: MonitorCallback, options?: CommandOptions): Promise<void>;
|
||||
resetDecoder(): void;
|
||||
reset<T extends TypeMapping>(chainId: symbol, typeMapping?: T): Promise<unknown>;
|
||||
isWaitingToWrite(): boolean;
|
||||
commandsToWrite(): Generator<readonly RedisArgument[], void, unknown>;
|
||||
flushWaitingForReply(err: Error): void;
|
||||
flushAll(err: Error): void;
|
||||
isEmpty(): boolean;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=commands-queue.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/commands-queue.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/commands-queue.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"commands-queue.d.ts","sourceRoot":"","sources":["../../../lib/client/commands-queue.ts"],"names":[],"mappings":"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"}
|
||||
411
node_modules/@redis/client/dist/lib/client/commands-queue.js
generated
vendored
Normal file
411
node_modules/@redis/client/dist/lib/client/commands-queue.js
generated
vendored
Normal file
@@ -0,0 +1,411 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const linked_list_1 = require("./linked-list");
|
||||
const encoder_1 = __importDefault(require("../RESP/encoder"));
|
||||
const decoder_1 = require("../RESP/decoder");
|
||||
const pub_sub_1 = require("./pub-sub");
|
||||
const errors_1 = require("../errors");
|
||||
const enterprise_maintenance_manager_1 = require("./enterprise-maintenance-manager");
|
||||
const PONG = Buffer.from('pong'), RESET = Buffer.from('RESET');
|
||||
const RESP2_PUSH_TYPE_MAPPING = {
|
||||
...decoder_1.PUSH_TYPE_MAPPING,
|
||||
[decoder_1.RESP_TYPES.SIMPLE_STRING]: Buffer
|
||||
};
|
||||
class RedisCommandsQueue {
|
||||
#respVersion;
|
||||
#maxLength;
|
||||
#toWrite = new linked_list_1.DoublyLinkedList();
|
||||
#waitingForReply = new linked_list_1.EmptyAwareSinglyLinkedList();
|
||||
#onShardedChannelMoved;
|
||||
#chainInExecution;
|
||||
decoder;
|
||||
#pubSub = new pub_sub_1.PubSub();
|
||||
#pushHandlers = [this.#onPush.bind(this)];
|
||||
#maintenanceCommandTimeout;
|
||||
setMaintenanceCommandTimeout(ms) {
|
||||
// Prevent possible api misuse
|
||||
if (this.#maintenanceCommandTimeout === ms) {
|
||||
(0, enterprise_maintenance_manager_1.dbgMaintenance)(`Queue already set maintenanceCommandTimeout to ${ms}, skipping`);
|
||||
return;
|
||||
}
|
||||
;
|
||||
(0, enterprise_maintenance_manager_1.dbgMaintenance)(`Setting maintenance command timeout to ${ms}`);
|
||||
this.#maintenanceCommandTimeout = ms;
|
||||
if (this.#maintenanceCommandTimeout === undefined) {
|
||||
(0, enterprise_maintenance_manager_1.dbgMaintenance)(`Queue will keep maintenanceCommandTimeout for exisitng commands, just to be on the safe side. New commands will receive normal timeouts`);
|
||||
return;
|
||||
}
|
||||
let counter = 0;
|
||||
const total = this.#toWrite.length;
|
||||
// Overwrite timeouts of all eligible toWrite commands
|
||||
for (const node of this.#toWrite.nodes()) {
|
||||
const command = node.value;
|
||||
// Remove timeout listener if it exists
|
||||
RedisCommandsQueue.#removeTimeoutListener(command);
|
||||
counter++;
|
||||
const newTimeout = this.#maintenanceCommandTimeout;
|
||||
// Overwrite the command's timeout
|
||||
const signal = AbortSignal.timeout(newTimeout);
|
||||
command.timeout = {
|
||||
signal,
|
||||
listener: () => {
|
||||
this.#toWrite.remove(node);
|
||||
command.reject(new errors_1.CommandTimeoutDuringMaintenanceError(newTimeout));
|
||||
},
|
||||
originalTimeout: command.timeout?.originalTimeout
|
||||
};
|
||||
signal.addEventListener('abort', command.timeout.listener, { once: true });
|
||||
}
|
||||
;
|
||||
(0, enterprise_maintenance_manager_1.dbgMaintenance)(`Total of ${counter} of ${total} timeouts reset to ${ms}`);
|
||||
}
|
||||
get isPubSubActive() {
|
||||
return this.#pubSub.isActive;
|
||||
}
|
||||
constructor(respVersion, maxLength, onShardedChannelMoved) {
|
||||
this.#respVersion = respVersion;
|
||||
this.#maxLength = maxLength;
|
||||
this.#onShardedChannelMoved = onShardedChannelMoved;
|
||||
this.decoder = this.#initiateDecoder();
|
||||
}
|
||||
#onReply(reply) {
|
||||
this.#waitingForReply.shift().resolve(reply);
|
||||
}
|
||||
#onErrorReply(err) {
|
||||
this.#waitingForReply.shift().reject(err);
|
||||
}
|
||||
#onPush(push) {
|
||||
// TODO: type
|
||||
if (this.#pubSub.handleMessageReply(push))
|
||||
return true;
|
||||
const isShardedUnsubscribe = pub_sub_1.PubSub.isShardedUnsubscribe(push);
|
||||
if (isShardedUnsubscribe && !this.#waitingForReply.length) {
|
||||
const channel = push[1].toString();
|
||||
this.#onShardedChannelMoved(channel, this.#pubSub.removeShardedListeners(channel));
|
||||
return true;
|
||||
}
|
||||
else if (isShardedUnsubscribe || pub_sub_1.PubSub.isStatusReply(push)) {
|
||||
const head = this.#waitingForReply.head.value;
|
||||
if ((Number.isNaN(head.channelsCounter) && push[2] === 0) ||
|
||||
--head.channelsCounter === 0) {
|
||||
this.#waitingForReply.shift().resolve();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#getTypeMapping() {
|
||||
return this.#waitingForReply.head.value.typeMapping ?? {};
|
||||
}
|
||||
#initiateDecoder() {
|
||||
return new decoder_1.Decoder({
|
||||
onReply: reply => this.#onReply(reply),
|
||||
onErrorReply: err => this.#onErrorReply(err),
|
||||
//TODO: we can shave off a few cycles by not adding onPush handler at all if CSC is not used
|
||||
onPush: push => {
|
||||
for (const pushHandler of this.#pushHandlers) {
|
||||
if (pushHandler(push))
|
||||
return;
|
||||
}
|
||||
},
|
||||
getTypeMapping: () => this.#getTypeMapping()
|
||||
});
|
||||
}
|
||||
addPushHandler(handler) {
|
||||
this.#pushHandlers.push(handler);
|
||||
}
|
||||
async waitForInflightCommandsToComplete() {
|
||||
// In-flight commands already completed
|
||||
if (this.#waitingForReply.length === 0) {
|
||||
return;
|
||||
}
|
||||
;
|
||||
// Otherwise wait for in-flight commands to fire `empty` event
|
||||
return new Promise(resolve => {
|
||||
this.#waitingForReply.events.on('empty', resolve);
|
||||
});
|
||||
}
|
||||
addCommand(args, options) {
|
||||
if (this.#maxLength && this.#toWrite.length + this.#waitingForReply.length >= this.#maxLength) {
|
||||
return Promise.reject(new Error('The queue is full'));
|
||||
}
|
||||
else if (options?.abortSignal?.aborted) {
|
||||
return Promise.reject(new errors_1.AbortError());
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
let node;
|
||||
const value = {
|
||||
args,
|
||||
chainId: options?.chainId,
|
||||
abort: undefined,
|
||||
timeout: undefined,
|
||||
resolve,
|
||||
reject,
|
||||
channelsCounter: undefined,
|
||||
typeMapping: options?.typeMapping
|
||||
};
|
||||
// If #maintenanceCommandTimeout was explicitly set, we should
|
||||
// use it instead of the timeout provided by the command
|
||||
const timeout = this.#maintenanceCommandTimeout ?? options?.timeout;
|
||||
const wasInMaintenance = this.#maintenanceCommandTimeout !== undefined;
|
||||
if (timeout) {
|
||||
const signal = AbortSignal.timeout(timeout);
|
||||
value.timeout = {
|
||||
signal,
|
||||
listener: () => {
|
||||
this.#toWrite.remove(node);
|
||||
value.reject(wasInMaintenance ? new errors_1.CommandTimeoutDuringMaintenanceError(timeout) : new errors_1.TimeoutError());
|
||||
},
|
||||
originalTimeout: options?.timeout
|
||||
};
|
||||
signal.addEventListener('abort', value.timeout.listener, { once: true });
|
||||
}
|
||||
const signal = options?.abortSignal;
|
||||
if (signal) {
|
||||
value.abort = {
|
||||
signal,
|
||||
listener: () => {
|
||||
this.#toWrite.remove(node);
|
||||
value.reject(new errors_1.AbortError());
|
||||
}
|
||||
};
|
||||
signal.addEventListener('abort', value.abort.listener, { once: true });
|
||||
}
|
||||
node = this.#toWrite.add(value, options?.asap);
|
||||
});
|
||||
}
|
||||
#addPubSubCommand(command, asap = false, chainId) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.#toWrite.add({
|
||||
args: command.args,
|
||||
chainId,
|
||||
abort: undefined,
|
||||
timeout: undefined,
|
||||
resolve() {
|
||||
command.resolve();
|
||||
resolve();
|
||||
},
|
||||
reject(err) {
|
||||
command.reject?.();
|
||||
reject(err);
|
||||
},
|
||||
channelsCounter: command.channelsCounter,
|
||||
typeMapping: decoder_1.PUSH_TYPE_MAPPING
|
||||
}, asap);
|
||||
});
|
||||
}
|
||||
#setupPubSubHandler() {
|
||||
// RESP3 uses `onPush` to handle PubSub, so no need to modify `onReply`
|
||||
if (this.#respVersion !== 2)
|
||||
return;
|
||||
this.decoder.onReply = (reply => {
|
||||
if (Array.isArray(reply)) {
|
||||
if (this.#onPush(reply))
|
||||
return;
|
||||
if (PONG.equals(reply[0])) {
|
||||
const { resolve, typeMapping } = this.#waitingForReply.shift(), buffer = (reply[1].length === 0 ? reply[0] : reply[1]);
|
||||
resolve(typeMapping?.[decoder_1.RESP_TYPES.SIMPLE_STRING] === Buffer ? buffer : buffer.toString());
|
||||
return;
|
||||
}
|
||||
}
|
||||
return this.#onReply(reply);
|
||||
});
|
||||
this.decoder.getTypeMapping = () => RESP2_PUSH_TYPE_MAPPING;
|
||||
}
|
||||
subscribe(type, channels, listener, returnBuffers) {
|
||||
const command = this.#pubSub.subscribe(type, channels, listener, returnBuffers);
|
||||
if (!command)
|
||||
return;
|
||||
this.#setupPubSubHandler();
|
||||
return this.#addPubSubCommand(command);
|
||||
}
|
||||
#resetDecoderCallbacks() {
|
||||
this.decoder.onReply = (reply => this.#onReply(reply));
|
||||
this.decoder.getTypeMapping = () => this.#getTypeMapping();
|
||||
}
|
||||
unsubscribe(type, channels, listener, returnBuffers) {
|
||||
const command = this.#pubSub.unsubscribe(type, channels, listener, returnBuffers);
|
||||
if (!command)
|
||||
return;
|
||||
if (command && this.#respVersion === 2) {
|
||||
// RESP2 modifies `onReply` to handle PubSub (see #setupPubSubHandler)
|
||||
const { resolve } = command;
|
||||
command.resolve = () => {
|
||||
if (!this.#pubSub.isActive) {
|
||||
this.#resetDecoderCallbacks();
|
||||
}
|
||||
resolve();
|
||||
};
|
||||
}
|
||||
return this.#addPubSubCommand(command);
|
||||
}
|
||||
removeAllPubSubListeners() {
|
||||
return this.#pubSub.removeAllListeners();
|
||||
}
|
||||
resubscribe(chainId) {
|
||||
const commands = this.#pubSub.resubscribe();
|
||||
if (!commands.length)
|
||||
return;
|
||||
this.#setupPubSubHandler();
|
||||
return Promise.all(commands.map(command => this.#addPubSubCommand(command, true, chainId)));
|
||||
}
|
||||
extendPubSubChannelListeners(type, channel, listeners) {
|
||||
const command = this.#pubSub.extendChannelListeners(type, channel, listeners);
|
||||
if (!command)
|
||||
return;
|
||||
this.#setupPubSubHandler();
|
||||
return this.#addPubSubCommand(command);
|
||||
}
|
||||
extendPubSubListeners(type, listeners) {
|
||||
const command = this.#pubSub.extendTypeListeners(type, listeners);
|
||||
if (!command)
|
||||
return;
|
||||
this.#setupPubSubHandler();
|
||||
return this.#addPubSubCommand(command);
|
||||
}
|
||||
getPubSubListeners(type) {
|
||||
return this.#pubSub.listeners[type];
|
||||
}
|
||||
monitor(callback, options) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const typeMapping = options?.typeMapping ?? {};
|
||||
this.#toWrite.add({
|
||||
args: ['MONITOR'],
|
||||
chainId: options?.chainId,
|
||||
abort: undefined,
|
||||
timeout: undefined,
|
||||
// using `resolve` instead of using `.then`/`await` to make sure it'll be called before processing the next reply
|
||||
resolve: () => {
|
||||
// after running `MONITOR` only `MONITOR` and `RESET` replies are expected
|
||||
// any other command should cause an error
|
||||
// if `RESET` already overrides `onReply`, set monitor as it's fallback
|
||||
if (this.#resetFallbackOnReply) {
|
||||
this.#resetFallbackOnReply = callback;
|
||||
}
|
||||
else {
|
||||
this.decoder.onReply = callback;
|
||||
}
|
||||
this.decoder.getTypeMapping = () => typeMapping;
|
||||
resolve();
|
||||
},
|
||||
reject,
|
||||
channelsCounter: undefined,
|
||||
typeMapping
|
||||
}, options?.asap);
|
||||
});
|
||||
}
|
||||
resetDecoder() {
|
||||
this.#resetDecoderCallbacks();
|
||||
this.decoder.reset();
|
||||
}
|
||||
#resetFallbackOnReply;
|
||||
async reset(chainId, typeMapping) {
|
||||
return new Promise((resolve, reject) => {
|
||||
// overriding onReply to handle `RESET` while in `MONITOR` or PubSub mode
|
||||
this.#resetFallbackOnReply = this.decoder.onReply;
|
||||
this.decoder.onReply = (reply => {
|
||||
if ((typeof reply === 'string' && reply === 'RESET') ||
|
||||
(reply instanceof Buffer && RESET.equals(reply))) {
|
||||
this.#resetDecoderCallbacks();
|
||||
this.#resetFallbackOnReply = undefined;
|
||||
this.#pubSub.reset();
|
||||
this.#waitingForReply.shift().resolve(reply);
|
||||
return;
|
||||
}
|
||||
this.#resetFallbackOnReply(reply);
|
||||
});
|
||||
this.#toWrite.push({
|
||||
args: ['RESET'],
|
||||
chainId,
|
||||
abort: undefined,
|
||||
timeout: undefined,
|
||||
resolve,
|
||||
reject,
|
||||
channelsCounter: undefined,
|
||||
typeMapping
|
||||
});
|
||||
});
|
||||
}
|
||||
isWaitingToWrite() {
|
||||
return this.#toWrite.length > 0;
|
||||
}
|
||||
*commandsToWrite() {
|
||||
let toSend = this.#toWrite.shift();
|
||||
while (toSend) {
|
||||
let encoded;
|
||||
try {
|
||||
encoded = (0, encoder_1.default)(toSend.args);
|
||||
}
|
||||
catch (err) {
|
||||
toSend.reject(err);
|
||||
toSend = this.#toWrite.shift();
|
||||
continue;
|
||||
}
|
||||
// TODO reuse `toSend` or create new object?
|
||||
toSend.args = undefined;
|
||||
if (toSend.abort) {
|
||||
RedisCommandsQueue.#removeAbortListener(toSend);
|
||||
toSend.abort = undefined;
|
||||
}
|
||||
if (toSend.timeout) {
|
||||
RedisCommandsQueue.#removeTimeoutListener(toSend);
|
||||
toSend.timeout = undefined;
|
||||
}
|
||||
this.#chainInExecution = toSend.chainId;
|
||||
toSend.chainId = undefined;
|
||||
this.#waitingForReply.push(toSend);
|
||||
yield encoded;
|
||||
toSend = this.#toWrite.shift();
|
||||
}
|
||||
}
|
||||
#flushWaitingForReply(err) {
|
||||
for (const node of this.#waitingForReply) {
|
||||
node.reject(err);
|
||||
}
|
||||
this.#waitingForReply.reset();
|
||||
}
|
||||
static #removeAbortListener(command) {
|
||||
command.abort.signal.removeEventListener('abort', command.abort.listener);
|
||||
}
|
||||
static #removeTimeoutListener(command) {
|
||||
command.timeout?.signal.removeEventListener('abort', command.timeout.listener);
|
||||
}
|
||||
static #flushToWrite(toBeSent, err) {
|
||||
if (toBeSent.abort) {
|
||||
RedisCommandsQueue.#removeAbortListener(toBeSent);
|
||||
}
|
||||
if (toBeSent.timeout) {
|
||||
RedisCommandsQueue.#removeTimeoutListener(toBeSent);
|
||||
}
|
||||
toBeSent.reject(err);
|
||||
}
|
||||
flushWaitingForReply(err) {
|
||||
this.resetDecoder();
|
||||
this.#pubSub.reset();
|
||||
this.#flushWaitingForReply(err);
|
||||
if (!this.#chainInExecution)
|
||||
return;
|
||||
while (this.#toWrite.head?.value.chainId === this.#chainInExecution) {
|
||||
RedisCommandsQueue.#flushToWrite(this.#toWrite.shift(), err);
|
||||
}
|
||||
this.#chainInExecution = undefined;
|
||||
}
|
||||
flushAll(err) {
|
||||
this.resetDecoder();
|
||||
this.#pubSub.reset();
|
||||
this.#flushWaitingForReply(err);
|
||||
for (const node of this.#toWrite) {
|
||||
RedisCommandsQueue.#flushToWrite(node, err);
|
||||
}
|
||||
this.#toWrite.reset();
|
||||
}
|
||||
isEmpty() {
|
||||
return (this.#toWrite.length === 0 &&
|
||||
this.#waitingForReply.length === 0);
|
||||
}
|
||||
}
|
||||
exports.default = RedisCommandsQueue;
|
||||
//# sourceMappingURL=commands-queue.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/commands-queue.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/commands-queue.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
43
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.d.ts
generated
vendored
Normal file
43
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.d.ts
generated
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
import { RedisClientOptions } from ".";
|
||||
import RedisCommandsQueue from "./commands-queue";
|
||||
import { RedisArgument } from "../..";
|
||||
import RedisSocket from "./socket";
|
||||
export declare const MAINTENANCE_EVENTS: {
|
||||
readonly PAUSE_WRITING: "pause-writing";
|
||||
readonly RESUME_WRITING: "resume-writing";
|
||||
readonly TIMEOUTS_UPDATE: "timeouts-update";
|
||||
};
|
||||
export type DiagnosticsEvent = {
|
||||
type: string;
|
||||
timestamp: number;
|
||||
data?: Object;
|
||||
};
|
||||
export declare const dbgMaintenance: (...args: any[]) => void;
|
||||
export declare const emitDiagnostics: (event: DiagnosticsEvent) => void;
|
||||
export interface MaintenanceUpdate {
|
||||
relaxedCommandTimeout?: number;
|
||||
relaxedSocketTimeout?: number;
|
||||
}
|
||||
interface Client {
|
||||
_ejectSocket: () => RedisSocket;
|
||||
_insertSocket: (socket: RedisSocket) => void;
|
||||
_pause: () => void;
|
||||
_unpause: () => void;
|
||||
_maintenanceUpdate: (update: MaintenanceUpdate) => void;
|
||||
duplicate: () => Client;
|
||||
connect: () => Promise<Client>;
|
||||
destroy: () => void;
|
||||
on: (event: string, callback: (value: unknown) => void) => void;
|
||||
}
|
||||
export default class EnterpriseMaintenanceManager {
|
||||
#private;
|
||||
static setupDefaultMaintOptions(options: RedisClientOptions): void;
|
||||
static getHandshakeCommand(options: RedisClientOptions): Promise<{
|
||||
cmd: Array<RedisArgument>;
|
||||
errorHandler: (error: Error) => void;
|
||||
} | undefined>;
|
||||
constructor(commandsQueue: RedisCommandsQueue, client: Client, options: RedisClientOptions);
|
||||
}
|
||||
export type MovingEndpointType = "auto" | "internal-ip" | "internal-fqdn" | "external-ip" | "external-fqdn" | "none";
|
||||
export {};
|
||||
//# sourceMappingURL=enterprise-maintenance-manager.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"enterprise-maintenance-manager.d.ts","sourceRoot":"","sources":["../../../lib/client/enterprise-maintenance-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,GAAG,CAAC;AACvC,OAAO,kBAAkB,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAKtC,OAAO,WAAsC,MAAM,UAAU,CAAC;AAG9D,eAAO,MAAM,kBAAkB;;;;CAIrB,CAAC;AAUX,MAAM,MAAM,gBAAgB,GAAG;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,cAAc,YAAa,GAAG,EAAE,SAG5C,CAAC;AAEF,eAAO,MAAM,eAAe,UAAW,gBAAgB,SAKtD,CAAC;AAEF,MAAM,WAAW,iBAAiB;IAChC,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;CAC/B;AAED,UAAU,MAAM;IACd,YAAY,EAAE,MAAM,WAAW,CAAC;IAChC,aAAa,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;IAC7C,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,kBAAkB,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACxD,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,EAAE,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,KAAK,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,OAAO,4BAA4B;;IAM/C,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE,kBAAkB;WAgB9C,mBAAmB,CAC9B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CACN;QAAE,GAAG,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;QAAC,YAAY,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAA;KAAE,GACnE,SAAS,CACZ;gBA8BC,aAAa,EAAE,kBAAkB,EACjC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,kBAAkB;CAuL9B;AAED,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,aAAa,GACb,eAAe,GACf,aAAa,GACb,eAAe,GACf,MAAM,CAAC"}
|
||||
280
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.js
generated
vendored
Normal file
280
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.js
generated
vendored
Normal file
@@ -0,0 +1,280 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.emitDiagnostics = exports.dbgMaintenance = exports.MAINTENANCE_EVENTS = void 0;
|
||||
const net_1 = require("net");
|
||||
const promises_1 = require("dns/promises");
|
||||
const node_assert_1 = __importDefault(require("node:assert"));
|
||||
const promises_2 = require("node:timers/promises");
|
||||
const node_diagnostics_channel_1 = __importDefault(require("node:diagnostics_channel"));
|
||||
exports.MAINTENANCE_EVENTS = {
|
||||
PAUSE_WRITING: "pause-writing",
|
||||
RESUME_WRITING: "resume-writing",
|
||||
TIMEOUTS_UPDATE: "timeouts-update",
|
||||
};
|
||||
const PN = {
|
||||
MOVING: "MOVING",
|
||||
MIGRATING: "MIGRATING",
|
||||
MIGRATED: "MIGRATED",
|
||||
FAILING_OVER: "FAILING_OVER",
|
||||
FAILED_OVER: "FAILED_OVER",
|
||||
};
|
||||
const dbgMaintenance = (...args) => {
|
||||
if (!process.env.REDIS_DEBUG_MAINTENANCE)
|
||||
return;
|
||||
return console.log("[MNT]", ...args);
|
||||
};
|
||||
exports.dbgMaintenance = dbgMaintenance;
|
||||
const emitDiagnostics = (event) => {
|
||||
if (!process.env.REDIS_EMIT_DIAGNOSTICS)
|
||||
return;
|
||||
const channel = node_diagnostics_channel_1.default.channel("redis.maintenance");
|
||||
channel.publish(event);
|
||||
};
|
||||
exports.emitDiagnostics = emitDiagnostics;
|
||||
class EnterpriseMaintenanceManager {
|
||||
#commandsQueue;
|
||||
#options;
|
||||
#isMaintenance = 0;
|
||||
#client;
|
||||
static setupDefaultMaintOptions(options) {
|
||||
if (options.maintNotifications === undefined) {
|
||||
options.maintNotifications =
|
||||
options?.RESP === 3 ? "auto" : "disabled";
|
||||
}
|
||||
if (options.maintEndpointType === undefined) {
|
||||
options.maintEndpointType = "auto";
|
||||
}
|
||||
if (options.maintRelaxedSocketTimeout === undefined) {
|
||||
options.maintRelaxedSocketTimeout = 10000;
|
||||
}
|
||||
if (options.maintRelaxedCommandTimeout === undefined) {
|
||||
options.maintRelaxedCommandTimeout = 10000;
|
||||
}
|
||||
}
|
||||
static async getHandshakeCommand(options) {
|
||||
if (options.maintNotifications === "disabled")
|
||||
return;
|
||||
const host = options.url
|
||||
? new URL(options.url).hostname
|
||||
: options.socket?.host;
|
||||
if (!host)
|
||||
return;
|
||||
const tls = options.socket?.tls ?? false;
|
||||
const movingEndpointType = await determineEndpoint(tls, host, options);
|
||||
return {
|
||||
cmd: [
|
||||
"CLIENT",
|
||||
"MAINT_NOTIFICATIONS",
|
||||
"ON",
|
||||
"moving-endpoint-type",
|
||||
movingEndpointType,
|
||||
],
|
||||
errorHandler: (error) => {
|
||||
(0, exports.dbgMaintenance)("handshake failed:", error);
|
||||
if (options.maintNotifications === "enabled") {
|
||||
throw error;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
constructor(commandsQueue, client, options) {
|
||||
this.#commandsQueue = commandsQueue;
|
||||
this.#options = options;
|
||||
this.#client = client;
|
||||
this.#commandsQueue.addPushHandler(this.#onPush);
|
||||
}
|
||||
#onPush = (push) => {
|
||||
(0, exports.dbgMaintenance)("ONPUSH:", push.map(String));
|
||||
if (!Array.isArray(push) || !["MOVING", "MIGRATING", "MIGRATED", "FAILING_OVER", "FAILED_OVER"].includes(String(push[0]))) {
|
||||
return false;
|
||||
}
|
||||
const type = String(push[0]);
|
||||
(0, exports.emitDiagnostics)({
|
||||
type,
|
||||
timestamp: Date.now(),
|
||||
data: {
|
||||
push: push.map(String),
|
||||
},
|
||||
});
|
||||
switch (type) {
|
||||
case PN.MOVING: {
|
||||
// [ 'MOVING', '17', '15', '54.78.247.156:12075' ]
|
||||
// ^seq ^after ^new ip
|
||||
const afterSeconds = push[2];
|
||||
const url = push[3] ? String(push[3]) : null;
|
||||
(0, exports.dbgMaintenance)("Received MOVING:", afterSeconds, url);
|
||||
this.#onMoving(afterSeconds, url);
|
||||
return true;
|
||||
}
|
||||
case PN.MIGRATING:
|
||||
case PN.FAILING_OVER: {
|
||||
(0, exports.dbgMaintenance)("Received MIGRATING|FAILING_OVER");
|
||||
this.#onMigrating();
|
||||
return true;
|
||||
}
|
||||
case PN.MIGRATED:
|
||||
case PN.FAILED_OVER: {
|
||||
(0, exports.dbgMaintenance)("Received MIGRATED|FAILED_OVER");
|
||||
this.#onMigrated();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
// Queue:
|
||||
// toWrite [ C D E ]
|
||||
// waitingForReply [ A B ] - aka In-flight commands
|
||||
//
|
||||
// time: ---1-2---3-4-5-6---------------------------
|
||||
//
|
||||
// 1. [EVENT] MOVING PN received
|
||||
// 2. [ACTION] Pause writing ( we need to wait for new socket to connect and for all in-flight commands to complete )
|
||||
// 3. [EVENT] New socket connected
|
||||
// 4. [EVENT] In-flight commands completed
|
||||
// 5. [ACTION] Destroy old socket
|
||||
// 6. [ACTION] Resume writing -> we are going to write to the new socket from now on
|
||||
#onMoving = async (afterSeconds, url) => {
|
||||
// 1 [EVENT] MOVING PN received
|
||||
this.#onMigrating();
|
||||
let host;
|
||||
let port;
|
||||
// The special value `none` indicates that the `MOVING` message doesn’t need
|
||||
// to contain an endpoint. Instead it contains the value `null` then. In
|
||||
// such a corner case, the client is expected to schedule a graceful
|
||||
// reconnect to its currently configured endpoint after half of the grace
|
||||
// period that was communicated by the server is over.
|
||||
if (url === null) {
|
||||
(0, node_assert_1.default)(this.#options.maintEndpointType === "none");
|
||||
(0, node_assert_1.default)(this.#options.socket !== undefined);
|
||||
(0, node_assert_1.default)("host" in this.#options.socket);
|
||||
(0, node_assert_1.default)(typeof this.#options.socket.host === "string");
|
||||
host = this.#options.socket.host;
|
||||
(0, node_assert_1.default)(typeof this.#options.socket.port === "number");
|
||||
port = this.#options.socket.port;
|
||||
const waitTime = (afterSeconds * 1000) / 2;
|
||||
(0, exports.dbgMaintenance)(`Wait for ${waitTime}ms`);
|
||||
await (0, promises_2.setTimeout)(waitTime);
|
||||
}
|
||||
else {
|
||||
const split = url.split(":");
|
||||
host = split[0];
|
||||
port = Number(split[1]);
|
||||
}
|
||||
// 2 [ACTION] Pause writing
|
||||
(0, exports.dbgMaintenance)("Pausing writing of new commands to old socket");
|
||||
this.#client._pause();
|
||||
(0, exports.dbgMaintenance)("Creating new tmp client");
|
||||
let start = performance.now();
|
||||
// If the URL is provided, it takes precedense
|
||||
// the options object could just be mutated
|
||||
if (this.#options.url) {
|
||||
const u = new URL(this.#options.url);
|
||||
u.hostname = host;
|
||||
u.port = String(port);
|
||||
this.#options.url = u.toString();
|
||||
}
|
||||
else {
|
||||
this.#options.socket = {
|
||||
...this.#options.socket,
|
||||
host,
|
||||
port
|
||||
};
|
||||
}
|
||||
const tmpClient = this.#client.duplicate();
|
||||
tmpClient.on('error', (error) => {
|
||||
//We dont know how to handle tmp client errors
|
||||
(0, exports.dbgMaintenance)(`[ERR]`, error);
|
||||
});
|
||||
(0, exports.dbgMaintenance)(`Tmp client created in ${(performance.now() - start).toFixed(2)}ms`);
|
||||
(0, exports.dbgMaintenance)(`Set timeout for tmp client to ${this.#options.maintRelaxedSocketTimeout}`);
|
||||
tmpClient._maintenanceUpdate({
|
||||
relaxedCommandTimeout: this.#options.maintRelaxedCommandTimeout,
|
||||
relaxedSocketTimeout: this.#options.maintRelaxedSocketTimeout,
|
||||
});
|
||||
(0, exports.dbgMaintenance)(`Connecting tmp client: ${host}:${port}`);
|
||||
start = performance.now();
|
||||
await tmpClient.connect();
|
||||
(0, exports.dbgMaintenance)(`Connected to tmp client in ${(performance.now() - start).toFixed(2)}ms`);
|
||||
// 3 [EVENT] New socket connected
|
||||
(0, exports.dbgMaintenance)(`Wait for all in-flight commands to complete`);
|
||||
await this.#commandsQueue.waitForInflightCommandsToComplete();
|
||||
(0, exports.dbgMaintenance)(`In-flight commands completed`);
|
||||
// 4 [EVENT] In-flight commands completed
|
||||
(0, exports.dbgMaintenance)("Swap client sockets...");
|
||||
const oldSocket = this.#client._ejectSocket();
|
||||
const newSocket = tmpClient._ejectSocket();
|
||||
this.#client._insertSocket(newSocket);
|
||||
tmpClient._insertSocket(oldSocket);
|
||||
tmpClient.destroy();
|
||||
(0, exports.dbgMaintenance)("Swap client sockets done.");
|
||||
// 5 + 6
|
||||
(0, exports.dbgMaintenance)("Resume writing");
|
||||
this.#client._unpause();
|
||||
this.#onMigrated();
|
||||
};
|
||||
#onMigrating = () => {
|
||||
this.#isMaintenance++;
|
||||
if (this.#isMaintenance > 1) {
|
||||
(0, exports.dbgMaintenance)(`Timeout relaxation already done`);
|
||||
return;
|
||||
}
|
||||
const update = {
|
||||
relaxedCommandTimeout: this.#options.maintRelaxedCommandTimeout,
|
||||
relaxedSocketTimeout: this.#options.maintRelaxedSocketTimeout,
|
||||
};
|
||||
this.#client._maintenanceUpdate(update);
|
||||
};
|
||||
#onMigrated = () => {
|
||||
//ensure that #isMaintenance doesnt go under 0
|
||||
this.#isMaintenance = Math.max(this.#isMaintenance - 1, 0);
|
||||
if (this.#isMaintenance > 0) {
|
||||
(0, exports.dbgMaintenance)(`Not ready to unrelax timeouts yet`);
|
||||
return;
|
||||
}
|
||||
const update = {
|
||||
relaxedCommandTimeout: undefined,
|
||||
relaxedSocketTimeout: undefined
|
||||
};
|
||||
this.#client._maintenanceUpdate(update);
|
||||
};
|
||||
}
|
||||
exports.default = EnterpriseMaintenanceManager;
|
||||
function isPrivateIP(ip) {
|
||||
const version = (0, net_1.isIP)(ip);
|
||||
if (version === 4) {
|
||||
const octets = ip.split(".").map(Number);
|
||||
return (octets[0] === 10 ||
|
||||
(octets[0] === 172 && octets[1] >= 16 && octets[1] <= 31) ||
|
||||
(octets[0] === 192 && octets[1] === 168));
|
||||
}
|
||||
if (version === 6) {
|
||||
return (ip.startsWith("fc") || // Unique local
|
||||
ip.startsWith("fd") || // Unique local
|
||||
ip === "::1" || // Loopback
|
||||
ip.startsWith("fe80") // Link-local unicast
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
async function determineEndpoint(tlsEnabled, host, options) {
|
||||
(0, node_assert_1.default)(options.maintEndpointType !== undefined);
|
||||
if (options.maintEndpointType !== "auto") {
|
||||
(0, exports.dbgMaintenance)(`Determine endpoint type: ${options.maintEndpointType}`);
|
||||
return options.maintEndpointType;
|
||||
}
|
||||
const ip = (0, net_1.isIP)(host) ? host : (await (0, promises_1.lookup)(host, { family: 0 })).address;
|
||||
const isPrivate = isPrivateIP(ip);
|
||||
let result;
|
||||
if (tlsEnabled) {
|
||||
result = isPrivate ? "internal-fqdn" : "external-fqdn";
|
||||
}
|
||||
else {
|
||||
result = isPrivate ? "internal-ip" : "external-ip";
|
||||
}
|
||||
(0, exports.dbgMaintenance)(`Determine endpoint type: ${result}`);
|
||||
return result;
|
||||
}
|
||||
//# sourceMappingURL=enterprise-maintenance-manager.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/enterprise-maintenance-manager.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
367
node_modules/@redis/client/dist/lib/client/index.d.ts
generated
vendored
Normal file
367
node_modules/@redis/client/dist/lib/client/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,367 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import COMMANDS from '../commands';
|
||||
import RedisSocket, { RedisSocketOptions } from './socket';
|
||||
import { CredentialsProvider } from '../authx';
|
||||
import { CommandOptions } from './commands-queue';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import { PubSubType, PubSubListener, PubSubTypeListeners, ChannelListeners } from './pub-sub';
|
||||
import { Command, CommandSignature, TypeMapping, CommanderConfig, RedisFunctions, RedisModules, RedisScript, RedisScripts, ReplyUnion, RespVersions, RedisArgument, ReplyWithTypeMapping, SimpleStringReply, TransformReply } from '../RESP/types';
|
||||
import { RedisClientMultiCommandType } from './multi-command';
|
||||
import { MULTI_MODE, MultiMode, RedisMultiQueuedCommand } from '../multi-command';
|
||||
import { ScanOptions, ScanCommonOptions } from '../commands/SCAN';
|
||||
import { RedisLegacyClientType } from './legacy-mode';
|
||||
import { RedisPoolOptions } from './pool';
|
||||
import { RedisVariadicArgument } from '../commands/generic-transformers';
|
||||
import { ClientSideCacheConfig, ClientSideCacheProvider } from './cache';
|
||||
import { CommandParser } from './parser';
|
||||
import { MaintenanceUpdate, MovingEndpointType } from './enterprise-maintenance-manager';
|
||||
export interface RedisClientOptions<M extends RedisModules = RedisModules, F extends RedisFunctions = RedisFunctions, S extends RedisScripts = RedisScripts, RESP extends RespVersions = RespVersions, TYPE_MAPPING extends TypeMapping = TypeMapping, SocketOptions extends RedisSocketOptions = RedisSocketOptions> extends CommanderConfig<M, F, S, RESP> {
|
||||
/**
|
||||
* `redis[s]://[[username][:password]@][host][:port][/db-number]`
|
||||
* See [`redis`](https://www.iana.org/assignments/uri-schemes/prov/redis) and [`rediss`](https://www.iana.org/assignments/uri-schemes/prov/rediss) IANA registration for more details
|
||||
*/
|
||||
url?: string;
|
||||
/**
|
||||
* Socket connection properties
|
||||
*/
|
||||
socket?: SocketOptions;
|
||||
/**
|
||||
* ACL username ([see ACL guide](https://redis.io/topics/acl))
|
||||
*/
|
||||
username?: string;
|
||||
/**
|
||||
* ACL password or the old "--requirepass" password
|
||||
*/
|
||||
password?: string;
|
||||
/**
|
||||
* Provides credentials for authentication. Can be set directly or will be created internally
|
||||
* if username/password are provided instead. If both are supplied, this credentialsProvider
|
||||
* takes precedence over username/password.
|
||||
*/
|
||||
credentialsProvider?: CredentialsProvider;
|
||||
/**
|
||||
* Client name ([see `CLIENT SETNAME`](https://redis.io/commands/client-setname))
|
||||
*/
|
||||
name?: string;
|
||||
/**
|
||||
* Redis database number (see [`SELECT`](https://redis.io/commands/select) command)
|
||||
*/
|
||||
database?: number;
|
||||
/**
|
||||
* Maximum length of the client's internal command queue
|
||||
*/
|
||||
commandsQueueMaxLength?: number;
|
||||
/**
|
||||
* When `true`, commands are rejected when the client is reconnecting.
|
||||
* When `false`, commands are queued for execution after reconnection.
|
||||
*/
|
||||
disableOfflineQueue?: boolean;
|
||||
/**
|
||||
* Connect in [`READONLY`](https://redis.io/commands/readonly) mode
|
||||
*/
|
||||
readonly?: boolean;
|
||||
/**
|
||||
* Send `PING` command at interval (in ms).
|
||||
* Useful with Redis deployments that do not honor TCP Keep-Alive.
|
||||
*/
|
||||
pingInterval?: number;
|
||||
/**
|
||||
* Default command options to be applied to all commands executed through this client.
|
||||
*
|
||||
* These options can be overridden on a per-command basis when calling specific commands.
|
||||
*
|
||||
* @property {symbol} [chainId] - Identifier for chaining commands together
|
||||
* @property {boolean} [asap] - When true, the command is executed as soon as possible
|
||||
* @property {AbortSignal} [abortSignal] - AbortSignal to cancel the command
|
||||
* @property {TypeMapping} [typeMapping] - Custom type mappings between RESP and JavaScript types
|
||||
*
|
||||
* @example Setting default command options
|
||||
* ```
|
||||
* const client = createClient({
|
||||
* commandOptions: {
|
||||
* asap: true,
|
||||
* typeMapping: {
|
||||
* // Custom type mapping configuration
|
||||
* }
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
commandOptions?: CommandOptions<TYPE_MAPPING>;
|
||||
/**
|
||||
* Client Side Caching configuration.
|
||||
*
|
||||
* Enables Redis Servers and Clients to work together to cache results from commands
|
||||
* sent to a server. The server will notify the client when cached results are no longer valid.
|
||||
*
|
||||
* Note: Client Side Caching is only supported with RESP3.
|
||||
*
|
||||
* @example Anonymous cache configuration
|
||||
* ```
|
||||
* const client = createClient({
|
||||
* RESP: 3,
|
||||
* clientSideCache: {
|
||||
* ttl: 0,
|
||||
* maxEntries: 0,
|
||||
* evictPolicy: "LRU"
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example Using a controllable cache
|
||||
* ```
|
||||
* const cache = new BasicClientSideCache({
|
||||
* ttl: 0,
|
||||
* maxEntries: 0,
|
||||
* evictPolicy: "LRU"
|
||||
* });
|
||||
* const client = createClient({
|
||||
* RESP: 3,
|
||||
* clientSideCache: cache
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
clientSideCache?: ClientSideCacheProvider | ClientSideCacheConfig;
|
||||
/**
|
||||
* If set to true, disables sending client identifier (user-agent like message) to the redis server
|
||||
*/
|
||||
disableClientInfo?: boolean;
|
||||
/**
|
||||
* Tag to append to library name that is sent to the Redis server
|
||||
*/
|
||||
clientInfoTag?: string;
|
||||
/**
|
||||
* When set to true, client tracking is turned on and the client emits `invalidate` events when it receives invalidation messages from the redis server.
|
||||
* Mutually exclusive with `clientSideCache` option.
|
||||
*/
|
||||
emitInvalidate?: boolean;
|
||||
/**
|
||||
* Controls how the client handles Redis Enterprise maintenance push notifications.
|
||||
*
|
||||
* - `disabled`: The feature is not used by the client.
|
||||
* - `enabled`: The client attempts to enable the feature on the server. If the server responds with an error, the connection is interrupted.
|
||||
* - `auto`: The client attempts to enable the feature on the server. If the server returns an error, the client disables the feature and continues.
|
||||
*
|
||||
* The default is `auto`.
|
||||
*/
|
||||
maintNotifications?: 'disabled' | 'enabled' | 'auto';
|
||||
/**
|
||||
* Controls how the client requests the endpoint to reconnect to during a MOVING notification in Redis Enterprise maintenance.
|
||||
*
|
||||
* - `auto`: If the connection is opened to a name or IP address that is from/resolves to a reserved private IP range, request an internal endpoint (e.g., internal-ip), otherwise an external one. If TLS is enabled, then request a FQDN.
|
||||
* - `internal-ip`: Enforce requesting the internal IP.
|
||||
* - `internal-fqdn`: Enforce requesting the internal FQDN.
|
||||
* - `external-ip`: Enforce requesting the external IP address.
|
||||
* - `external-fqdn`: Enforce requesting the external FQDN.
|
||||
* - `none`: Used to request a null endpoint, which tells the client to reconnect based on its current config
|
||||
|
||||
* The default is `auto`.
|
||||
*/
|
||||
maintEndpointType?: MovingEndpointType;
|
||||
/**
|
||||
* Specifies a more relaxed timeout (in milliseconds) for commands during a maintenance window.
|
||||
* This helps minimize command timeouts during maintenance. Timeouts during maintenance period result
|
||||
* in a `CommandTimeoutDuringMaintenance` error.
|
||||
*
|
||||
* The default is 10000
|
||||
*/
|
||||
maintRelaxedCommandTimeout?: number;
|
||||
/**
|
||||
* Specifies a more relaxed timeout (in milliseconds) for the socket during a maintenance window.
|
||||
* This helps minimize socket timeouts during maintenance. Timeouts during maintenance period result
|
||||
* in a `SocketTimeoutDuringMaintenance` error.
|
||||
*
|
||||
* The default is 10000
|
||||
*/
|
||||
maintRelaxedSocketTimeout?: number;
|
||||
}
|
||||
export type WithCommands<RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof typeof COMMANDS]: CommandSignature<(typeof COMMANDS)[P], RESP, TYPE_MAPPING>;
|
||||
};
|
||||
export type WithModules<M extends RedisModules, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof M]: {
|
||||
[C in keyof M[P]]: CommandSignature<M[P][C], RESP, TYPE_MAPPING>;
|
||||
};
|
||||
};
|
||||
export type WithFunctions<F extends RedisFunctions, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[L in keyof F]: {
|
||||
[C in keyof F[L]]: CommandSignature<F[L][C], RESP, TYPE_MAPPING>;
|
||||
};
|
||||
};
|
||||
export type WithScripts<S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof S]: CommandSignature<S[P], RESP, TYPE_MAPPING>;
|
||||
};
|
||||
export type RedisClientExtensions<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}> = (WithCommands<RESP, TYPE_MAPPING> & WithModules<M, RESP, TYPE_MAPPING> & WithFunctions<F, RESP, TYPE_MAPPING> & WithScripts<S, RESP, TYPE_MAPPING>);
|
||||
export type RedisClientType<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}> = (RedisClient<M, F, S, RESP, TYPE_MAPPING> & RedisClientExtensions<M, F, S, RESP, TYPE_MAPPING>);
|
||||
interface ScanIteratorOptions {
|
||||
cursor?: RedisArgument;
|
||||
}
|
||||
export type MonitorCallback<TYPE_MAPPING extends TypeMapping = TypeMapping> = (reply: ReplyWithTypeMapping<SimpleStringReply, TYPE_MAPPING>) => unknown;
|
||||
export default class RedisClient<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> extends EventEmitter {
|
||||
#private;
|
||||
static factory<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2>(config?: CommanderConfig<M, F, S, RESP>): <TYPE_MAPPING extends TypeMapping = {}>(options?: Omit<RedisClientOptions<M, F, S, RESP, TYPE_MAPPING, RedisSocketOptions>, keyof CommanderConfig<M, F, S, RESP>> | undefined) => RedisClientType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
static create<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}>(this: void, options?: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>): RedisClientType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
static parseOptions<O extends RedisClientOptions>(options: O): O;
|
||||
static parseURL(url: string): RedisClientOptions & {
|
||||
socket: Exclude<RedisClientOptions['socket'], undefined> & {
|
||||
tls: boolean;
|
||||
};
|
||||
};
|
||||
private _self;
|
||||
private _commandOptions?;
|
||||
get clientSideCache(): ClientSideCacheProvider | undefined;
|
||||
get options(): RedisClientOptions<M, F, S, RESP>;
|
||||
get isOpen(): boolean;
|
||||
get isReady(): boolean;
|
||||
get isPubSubActive(): boolean;
|
||||
get socketEpoch(): number;
|
||||
get isWatching(): boolean;
|
||||
/**
|
||||
* Indicates whether the client's WATCH command has been invalidated by a topology change.
|
||||
* When this returns true, any transaction using WATCH will fail with a WatchError.
|
||||
* @returns true if the watched keys have been modified, false otherwise
|
||||
*/
|
||||
get isDirtyWatch(): boolean;
|
||||
/**
|
||||
* Marks the client's WATCH command as invalidated due to a topology change.
|
||||
* This will cause any subsequent EXEC in a transaction to fail with a WatchError.
|
||||
* @param msg - The error message explaining why the WATCH is dirty
|
||||
*/
|
||||
setDirtyWatch(msg: string): void;
|
||||
constructor(options?: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>);
|
||||
/**
|
||||
* @param credentials
|
||||
*/
|
||||
private reAuthenticate;
|
||||
withCommandOptions<OPTIONS extends CommandOptions<TYPE_MAPPING>, TYPE_MAPPING extends TypeMapping>(options: OPTIONS): RedisClientType<M, F, S, RESP, TYPE_MAPPING extends TypeMapping ? TYPE_MAPPING : {}>;
|
||||
private _commandOptionsProxy;
|
||||
/**
|
||||
* Override the `typeMapping` command option
|
||||
*/
|
||||
withTypeMapping<TYPE_MAPPING extends TypeMapping>(typeMapping: TYPE_MAPPING): RedisClientType<M, F, S, RESP, TYPE_MAPPING extends TypeMapping ? TYPE_MAPPING : {}>;
|
||||
/**
|
||||
* Override the `abortSignal` command option
|
||||
*/
|
||||
withAbortSignal(abortSignal: AbortSignal): RedisClientType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
/**
|
||||
* Override the `asap` command option to `true`
|
||||
*/
|
||||
asap(): RedisClientType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
/**
|
||||
* Create the "legacy" (v3/callback) interface
|
||||
*/
|
||||
legacy(): RedisLegacyClientType;
|
||||
/**
|
||||
* Create {@link RedisClientPool `RedisClientPool`} using this client as a prototype
|
||||
*/
|
||||
createPool(options?: Partial<RedisPoolOptions>): import("./pool").RedisClientPoolType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
duplicate<_M extends RedisModules = M, _F extends RedisFunctions = F, _S extends RedisScripts = S, _RESP extends RespVersions = RESP, _TYPE_MAPPING extends TypeMapping = TYPE_MAPPING>(overrides?: Partial<RedisClientOptions<_M, _F, _S, _RESP, _TYPE_MAPPING>>): RedisClientType<_M, _F, _S, _RESP, _TYPE_MAPPING>;
|
||||
connect(): Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_ejectSocket(): RedisSocket;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_insertSocket(socket: RedisSocket): void;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_maintenanceUpdate(update: MaintenanceUpdate): void;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_pause(): void;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_unpause(): void;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_executeCommand(command: Command, parser: CommandParser, commandOptions: CommandOptions<TYPE_MAPPING> | undefined, transformReply: TransformReply | undefined): Promise<any>;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_executeScript(script: RedisScript, parser: CommandParser, options: CommandOptions | undefined, transformReply: TransformReply | undefined): Promise<any>;
|
||||
sendCommand<T = ReplyUnion>(args: ReadonlyArray<RedisArgument>, options?: CommandOptions): Promise<T>;
|
||||
SELECT(db: number): Promise<void>;
|
||||
select: (db: number) => Promise<void>;
|
||||
SUBSCRIBE<T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
subscribe: <T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T | undefined) => Promise<void>;
|
||||
UNSUBSCRIBE<T extends boolean = false>(channels?: string | Array<string>, listener?: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
unsubscribe: <T extends boolean = false>(channels?: string | Array<string>, listener?: PubSubListener<T> | undefined, bufferMode?: T | undefined) => Promise<void>;
|
||||
PSUBSCRIBE<T extends boolean = false>(patterns: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
pSubscribe: <T extends boolean = false>(patterns: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T | undefined) => Promise<void>;
|
||||
PUNSUBSCRIBE<T extends boolean = false>(patterns?: string | Array<string>, listener?: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
pUnsubscribe: <T extends boolean = false>(patterns?: string | Array<string>, listener?: PubSubListener<T> | undefined, bufferMode?: T | undefined) => Promise<void>;
|
||||
SSUBSCRIBE<T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
sSubscribe: <T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T | undefined) => Promise<void>;
|
||||
SUNSUBSCRIBE<T extends boolean = false>(channels?: string | Array<string>, listener?: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
sUnsubscribe: <T extends boolean = false>(channels?: string | Array<string>, listener?: PubSubListener<T> | undefined, bufferMode?: T | undefined) => Promise<void>;
|
||||
WATCH(key: RedisVariadicArgument): Promise<TYPE_MAPPING[43] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<"OK", T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> : "OK">;
|
||||
watch: (key: RedisVariadicArgument) => Promise<TYPE_MAPPING[43] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<"OK", T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> : "OK">;
|
||||
UNWATCH(): Promise<TYPE_MAPPING[43] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<"OK", T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> : "OK">;
|
||||
unwatch: () => Promise<TYPE_MAPPING[43] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<"OK", T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> : "OK">;
|
||||
getPubSubListeners(type: PubSubType): PubSubTypeListeners;
|
||||
extendPubSubChannelListeners(type: PubSubType, channel: string, listeners: ChannelListeners): Promise<void>;
|
||||
extendPubSubListeners(type: PubSubType, listeners: PubSubTypeListeners): Promise<void>;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_executePipeline(commands: Array<RedisMultiQueuedCommand>, selectedDB?: number): Promise<unknown[]>;
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_executeMulti(commands: Array<RedisMultiQueuedCommand>, selectedDB?: number): Promise<unknown[]>;
|
||||
MULTI<isTyped extends MultiMode = MULTI_MODE['TYPED']>(): RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
|
||||
multi: <isTyped extends MultiMode = "typed">() => RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
|
||||
scanIterator(this: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, options?: ScanOptions & ScanIteratorOptions): AsyncGenerator<TYPE_MAPPING[42] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<import("../RESP/types").BlobStringReply<string>[], T>, TYPE_MAPPING> : (TYPE_MAPPING[36] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<string, T>, TYPE_MAPPING> : string)[], void, unknown>;
|
||||
hScanIterator(this: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, key: RedisArgument, options?: ScanCommonOptions & ScanIteratorOptions): AsyncGenerator<{
|
||||
field: TYPE_MAPPING[36] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<string, T>, TYPE_MAPPING> : string;
|
||||
value: TYPE_MAPPING[36] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<string, T>, TYPE_MAPPING> : string;
|
||||
}[], void, unknown>;
|
||||
hScanValuesIterator(this: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, key: RedisArgument, options?: ScanCommonOptions & ScanIteratorOptions): AsyncGenerator<(TYPE_MAPPING[36] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<string, T>, TYPE_MAPPING> : string)[], void, unknown>;
|
||||
hScanNoValuesIterator(this: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, key: RedisArgument, options?: ScanCommonOptions & ScanIteratorOptions): AsyncGenerator<(TYPE_MAPPING[36] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<string, T>, TYPE_MAPPING> : string)[], void, unknown>;
|
||||
sScanIterator(this: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, key: RedisArgument, options?: ScanCommonOptions & ScanIteratorOptions): AsyncGenerator<(TYPE_MAPPING[36] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<string, T>, TYPE_MAPPING> : string)[], void, unknown>;
|
||||
zScanIterator(this: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, key: RedisArgument, options?: ScanCommonOptions & ScanIteratorOptions): AsyncGenerator<{
|
||||
value: TYPE_MAPPING[36] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<Buffer, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<string, T>, TYPE_MAPPING> : string;
|
||||
score: TYPE_MAPPING[44] extends import("../RESP/types").MappedType<infer T> ? ReplyWithTypeMapping<Extract<number, T>, TYPE_MAPPING> | ReplyWithTypeMapping<Extract<`${number}`, T>, TYPE_MAPPING> : number;
|
||||
}[], void, unknown>;
|
||||
MONITOR(callback: MonitorCallback<TYPE_MAPPING>): Promise<void>;
|
||||
monitor: (callback: MonitorCallback<TYPE_MAPPING>) => Promise<void>;
|
||||
/**
|
||||
* Reset the client to its default state (i.e. stop PubSub, stop monitoring, select default DB, etc.)
|
||||
*/
|
||||
reset(): Promise<void>;
|
||||
/**
|
||||
* If the client has state, reset it.
|
||||
* An internal function to be used by wrapper class such as `RedisClientPool`.
|
||||
* @internal
|
||||
*/
|
||||
resetIfDirty(): Promise<void> | undefined;
|
||||
/**
|
||||
* @deprecated use .close instead
|
||||
*/
|
||||
QUIT(): Promise<string>;
|
||||
quit: () => Promise<string>;
|
||||
/**
|
||||
* @deprecated use .destroy instead
|
||||
*/
|
||||
disconnect(): Promise<void>;
|
||||
/**
|
||||
* Close the client. Wait for pending commands.
|
||||
*/
|
||||
close(): Promise<void>;
|
||||
/**
|
||||
* Destroy the client. Rejects all commands immediately.
|
||||
*/
|
||||
destroy(): void;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/index.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/index.d.ts.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
953
node_modules/@redis/client/dist/lib/client/index.js
generated
vendored
Normal file
953
node_modules/@redis/client/dist/lib/client/index.js
generated
vendored
Normal file
@@ -0,0 +1,953 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const commands_1 = __importDefault(require("../commands"));
|
||||
const socket_1 = __importDefault(require("./socket"));
|
||||
const authx_1 = require("../authx");
|
||||
const commands_queue_1 = __importDefault(require("./commands-queue"));
|
||||
const node_events_1 = require("node:events");
|
||||
const commander_1 = require("../commander");
|
||||
const errors_1 = require("../errors");
|
||||
const node_url_1 = require("node:url");
|
||||
const pub_sub_1 = require("./pub-sub");
|
||||
const multi_command_1 = __importDefault(require("./multi-command"));
|
||||
const HELLO_1 = __importDefault(require("../commands/HELLO"));
|
||||
const legacy_mode_1 = require("./legacy-mode");
|
||||
const pool_1 = require("./pool");
|
||||
const generic_transformers_1 = require("../commands/generic-transformers");
|
||||
const cache_1 = require("./cache");
|
||||
const parser_1 = require("./parser");
|
||||
const single_entry_cache_1 = __importDefault(require("../single-entry-cache"));
|
||||
const package_json_1 = require("../../package.json");
|
||||
const enterprise_maintenance_manager_1 = __importDefault(require("./enterprise-maintenance-manager"));
|
||||
;
|
||||
class RedisClient extends node_events_1.EventEmitter {
|
||||
static #createCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
return this._self._executeCommand(command, parser, this._commandOptions, transformReply);
|
||||
};
|
||||
}
|
||||
static #createModuleCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
return this._self._executeCommand(command, parser, this._self._commandOptions, transformReply);
|
||||
};
|
||||
}
|
||||
static #createFunctionCommand(name, fn, resp) {
|
||||
const prefix = (0, commander_1.functionArgumentsPrefix)(name, fn);
|
||||
const transformReply = (0, commander_1.getTransformReply)(fn, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.push(...prefix);
|
||||
fn.parseCommand(parser, ...args);
|
||||
return this._self._executeCommand(fn, parser, this._self._commandOptions, transformReply);
|
||||
};
|
||||
}
|
||||
static #createScriptCommand(script, resp) {
|
||||
const prefix = (0, commander_1.scriptArgumentsPrefix)(script);
|
||||
const transformReply = (0, commander_1.getTransformReply)(script, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.push(...prefix);
|
||||
script.parseCommand(parser, ...args);
|
||||
return this._executeScript(script, parser, this._commandOptions, transformReply);
|
||||
};
|
||||
}
|
||||
static #SingleEntryCache = new single_entry_cache_1.default();
|
||||
static factory(config) {
|
||||
let Client = _a.#SingleEntryCache.get(config);
|
||||
if (!Client) {
|
||||
Client = (0, commander_1.attachConfig)({
|
||||
BaseClass: _a,
|
||||
commands: commands_1.default,
|
||||
createCommand: _a.#createCommand,
|
||||
createModuleCommand: _a.#createModuleCommand,
|
||||
createFunctionCommand: _a.#createFunctionCommand,
|
||||
createScriptCommand: _a.#createScriptCommand,
|
||||
config
|
||||
});
|
||||
Client.prototype.Multi = multi_command_1.default.extend(config);
|
||||
_a.#SingleEntryCache.set(config, Client);
|
||||
}
|
||||
return (options) => {
|
||||
// returning a "proxy" to prevent the namespaces._self to leak between "proxies"
|
||||
return Object.create(new Client(options));
|
||||
};
|
||||
}
|
||||
static create(options) {
|
||||
return _a.factory(options)(options);
|
||||
}
|
||||
static parseOptions(options) {
|
||||
if (options?.url) {
|
||||
const parsed = _a.parseURL(options.url);
|
||||
if (options.socket) {
|
||||
if (options.socket.tls !== undefined && options.socket.tls !== parsed.socket.tls) {
|
||||
throw new TypeError(`tls socket option is set to ${options.socket.tls} which is mismatch with protocol or the URL ${options.url} passed`);
|
||||
}
|
||||
parsed.socket = Object.assign(options.socket, parsed.socket);
|
||||
}
|
||||
Object.assign(options, parsed);
|
||||
}
|
||||
return options;
|
||||
}
|
||||
static parseURL(url) {
|
||||
// https://www.iana.org/assignments/uri-schemes/prov/redis
|
||||
const { hostname, port, protocol, username, password, pathname } = new node_url_1.URL(url), parsed = {
|
||||
socket: {
|
||||
host: hostname,
|
||||
tls: false
|
||||
}
|
||||
};
|
||||
if (protocol !== 'redis:' && protocol !== 'rediss:') {
|
||||
throw new TypeError('Invalid protocol');
|
||||
}
|
||||
parsed.socket.tls = protocol === 'rediss:';
|
||||
if (port) {
|
||||
parsed.socket.port = Number(port);
|
||||
}
|
||||
if (username) {
|
||||
parsed.username = decodeURIComponent(username);
|
||||
}
|
||||
if (password) {
|
||||
parsed.password = decodeURIComponent(password);
|
||||
}
|
||||
if (username || password) {
|
||||
parsed.credentialsProvider = {
|
||||
type: 'async-credentials-provider',
|
||||
credentials: async () => ({
|
||||
username: username ? decodeURIComponent(username) : undefined,
|
||||
password: password ? decodeURIComponent(password) : undefined
|
||||
})
|
||||
};
|
||||
}
|
||||
if (pathname.length > 1) {
|
||||
const database = Number(pathname.substring(1));
|
||||
if (isNaN(database)) {
|
||||
throw new TypeError('Invalid pathname');
|
||||
}
|
||||
parsed.database = database;
|
||||
}
|
||||
return parsed;
|
||||
}
|
||||
#options;
|
||||
#socket;
|
||||
#queue;
|
||||
#selectedDB = 0;
|
||||
#monitorCallback;
|
||||
_self = this;
|
||||
_commandOptions;
|
||||
// flag used to annotate that the client
|
||||
// was in a watch transaction when
|
||||
// a topology change occured
|
||||
#dirtyWatch;
|
||||
#watchEpoch;
|
||||
#clientSideCache;
|
||||
#credentialsSubscription = null;
|
||||
// Flag used to pause writing to the socket during maintenance windows.
|
||||
// When true, prevents new commands from being written while waiting for:
|
||||
// 1. New socket to be ready after maintenance redirect
|
||||
// 2. In-flight commands on the old socket to complete
|
||||
#paused = false;
|
||||
get clientSideCache() {
|
||||
return this._self.#clientSideCache;
|
||||
}
|
||||
get options() {
|
||||
return this._self.#options;
|
||||
}
|
||||
get isOpen() {
|
||||
return this._self.#socket.isOpen;
|
||||
}
|
||||
get isReady() {
|
||||
return this._self.#socket.isReady;
|
||||
}
|
||||
get isPubSubActive() {
|
||||
return this._self.#queue.isPubSubActive;
|
||||
}
|
||||
get socketEpoch() {
|
||||
return this._self.#socket.socketEpoch;
|
||||
}
|
||||
get isWatching() {
|
||||
return this._self.#watchEpoch !== undefined;
|
||||
}
|
||||
/**
|
||||
* Indicates whether the client's WATCH command has been invalidated by a topology change.
|
||||
* When this returns true, any transaction using WATCH will fail with a WatchError.
|
||||
* @returns true if the watched keys have been modified, false otherwise
|
||||
*/
|
||||
get isDirtyWatch() {
|
||||
return this._self.#dirtyWatch !== undefined;
|
||||
}
|
||||
/**
|
||||
* Marks the client's WATCH command as invalidated due to a topology change.
|
||||
* This will cause any subsequent EXEC in a transaction to fail with a WatchError.
|
||||
* @param msg - The error message explaining why the WATCH is dirty
|
||||
*/
|
||||
setDirtyWatch(msg) {
|
||||
this._self.#dirtyWatch = msg;
|
||||
}
|
||||
constructor(options) {
|
||||
super();
|
||||
this.#validateOptions(options);
|
||||
this.#options = this.#initiateOptions(options);
|
||||
this.#queue = this.#initiateQueue();
|
||||
this.#socket = this.#initiateSocket();
|
||||
if (this.#options.maintNotifications !== 'disabled') {
|
||||
new enterprise_maintenance_manager_1.default(this.#queue, this, this.#options);
|
||||
}
|
||||
;
|
||||
if (this.#options.clientSideCache) {
|
||||
if (this.#options.clientSideCache instanceof cache_1.ClientSideCacheProvider) {
|
||||
this.#clientSideCache = this.#options.clientSideCache;
|
||||
}
|
||||
else {
|
||||
const cscConfig = this.#options.clientSideCache;
|
||||
this.#clientSideCache = new cache_1.BasicClientSideCache(cscConfig);
|
||||
}
|
||||
this.#queue.addPushHandler((push) => {
|
||||
if (push[0].toString() !== 'invalidate')
|
||||
return false;
|
||||
if (push[1] !== null) {
|
||||
for (const key of push[1]) {
|
||||
this.#clientSideCache?.invalidate(key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.#clientSideCache?.invalidate(null);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
else if (options?.emitInvalidate) {
|
||||
this.#queue.addPushHandler((push) => {
|
||||
if (push[0].toString() !== 'invalidate')
|
||||
return false;
|
||||
if (push[1] !== null) {
|
||||
for (const key of push[1]) {
|
||||
this.emit('invalidate', key);
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.emit('invalidate', null);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
}
|
||||
#validateOptions(options) {
|
||||
if (options?.clientSideCache && options?.RESP !== 3) {
|
||||
throw new Error('Client Side Caching is only supported with RESP3');
|
||||
}
|
||||
if (options?.emitInvalidate && options?.RESP !== 3) {
|
||||
throw new Error('emitInvalidate is only supported with RESP3');
|
||||
}
|
||||
if (options?.clientSideCache && options?.emitInvalidate) {
|
||||
throw new Error('emitInvalidate is not supported (or necessary) when clientSideCache is enabled');
|
||||
}
|
||||
if (options?.maintNotifications && options?.maintNotifications !== 'disabled' && options?.RESP !== 3) {
|
||||
throw new Error('Graceful Maintenance is only supported with RESP3');
|
||||
}
|
||||
}
|
||||
#initiateOptions(options = {}) {
|
||||
// Convert username/password to credentialsProvider if no credentialsProvider is already in place
|
||||
if (!options.credentialsProvider && (options.username || options.password)) {
|
||||
options.credentialsProvider = {
|
||||
type: 'async-credentials-provider',
|
||||
credentials: async () => ({
|
||||
username: options.username,
|
||||
password: options.password
|
||||
})
|
||||
};
|
||||
}
|
||||
if (options.database) {
|
||||
this._self.#selectedDB = options.database;
|
||||
}
|
||||
if (options.commandOptions) {
|
||||
this._commandOptions = options.commandOptions;
|
||||
}
|
||||
if (options.maintNotifications !== 'disabled') {
|
||||
enterprise_maintenance_manager_1.default.setupDefaultMaintOptions(options);
|
||||
}
|
||||
if (options.url) {
|
||||
const parsedOptions = _a.parseOptions(options);
|
||||
if (parsedOptions?.database) {
|
||||
this._self.#selectedDB = parsedOptions.database;
|
||||
}
|
||||
return parsedOptions;
|
||||
}
|
||||
return options;
|
||||
}
|
||||
#initiateQueue() {
|
||||
return new commands_queue_1.default(this.#options.RESP ?? 2, this.#options.commandsQueueMaxLength, (channel, listeners) => this.emit('sharded-channel-moved', channel, listeners));
|
||||
}
|
||||
/**
|
||||
* @param credentials
|
||||
*/
|
||||
reAuthenticate = async (credentials) => {
|
||||
// Re-authentication is not supported on RESP2 with PubSub active
|
||||
if (!(this.isPubSubActive && !this.#options.RESP)) {
|
||||
await this.sendCommand((0, generic_transformers_1.parseArgs)(commands_1.default.AUTH, {
|
||||
username: credentials.username,
|
||||
password: credentials.password ?? ''
|
||||
}));
|
||||
}
|
||||
};
|
||||
#subscribeForStreamingCredentials(cp) {
|
||||
return cp.subscribe({
|
||||
onNext: credentials => {
|
||||
this.reAuthenticate(credentials).catch(error => {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
cp.onReAuthenticationError(new authx_1.CredentialsError(errorMessage));
|
||||
});
|
||||
},
|
||||
onError: (e) => {
|
||||
const errorMessage = `Error from streaming credentials provider: ${e.message}`;
|
||||
cp.onReAuthenticationError(new authx_1.UnableToObtainNewCredentialsError(errorMessage));
|
||||
}
|
||||
});
|
||||
}
|
||||
async #handshake(chainId, asap) {
|
||||
const promises = [];
|
||||
const commandsWithErrorHandlers = await this.#getHandshakeCommands();
|
||||
if (asap)
|
||||
commandsWithErrorHandlers.reverse();
|
||||
for (const { cmd, errorHandler } of commandsWithErrorHandlers) {
|
||||
promises.push(this.#queue
|
||||
.addCommand(cmd, {
|
||||
chainId,
|
||||
asap
|
||||
})
|
||||
.catch(errorHandler));
|
||||
}
|
||||
return promises;
|
||||
}
|
||||
async #getHandshakeCommands() {
|
||||
const commands = [];
|
||||
const cp = this.#options.credentialsProvider;
|
||||
if (this.#options.RESP) {
|
||||
const hello = {};
|
||||
if (cp && cp.type === 'async-credentials-provider') {
|
||||
const credentials = await cp.credentials();
|
||||
if (credentials.password) {
|
||||
hello.AUTH = {
|
||||
username: credentials.username ?? 'default',
|
||||
password: credentials.password
|
||||
};
|
||||
}
|
||||
}
|
||||
if (cp && cp.type === 'streaming-credentials-provider') {
|
||||
const [credentials, disposable] = await this.#subscribeForStreamingCredentials(cp);
|
||||
this.#credentialsSubscription = disposable;
|
||||
if (credentials.password) {
|
||||
hello.AUTH = {
|
||||
username: credentials.username ?? 'default',
|
||||
password: credentials.password
|
||||
};
|
||||
}
|
||||
}
|
||||
if (this.#options.name) {
|
||||
hello.SETNAME = this.#options.name;
|
||||
}
|
||||
commands.push({ cmd: (0, generic_transformers_1.parseArgs)(HELLO_1.default, this.#options.RESP, hello) });
|
||||
}
|
||||
else {
|
||||
if (cp && cp.type === 'async-credentials-provider') {
|
||||
const credentials = await cp.credentials();
|
||||
if (credentials.username || credentials.password) {
|
||||
commands.push({
|
||||
cmd: (0, generic_transformers_1.parseArgs)(commands_1.default.AUTH, {
|
||||
username: credentials.username,
|
||||
password: credentials.password ?? ''
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
if (cp && cp.type === 'streaming-credentials-provider') {
|
||||
const [credentials, disposable] = await this.#subscribeForStreamingCredentials(cp);
|
||||
this.#credentialsSubscription = disposable;
|
||||
if (credentials.username || credentials.password) {
|
||||
commands.push({
|
||||
cmd: (0, generic_transformers_1.parseArgs)(commands_1.default.AUTH, {
|
||||
username: credentials.username,
|
||||
password: credentials.password ?? ''
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.#options.name) {
|
||||
commands.push({
|
||||
cmd: (0, generic_transformers_1.parseArgs)(commands_1.default.CLIENT_SETNAME, this.#options.name)
|
||||
});
|
||||
}
|
||||
}
|
||||
if (this.#selectedDB !== 0) {
|
||||
commands.push({ cmd: ['SELECT', this.#selectedDB.toString()] });
|
||||
}
|
||||
if (this.#options.readonly) {
|
||||
commands.push({ cmd: (0, generic_transformers_1.parseArgs)(commands_1.default.READONLY) });
|
||||
}
|
||||
if (!this.#options.disableClientInfo) {
|
||||
commands.push({
|
||||
cmd: ['CLIENT', 'SETINFO', 'LIB-VER', package_json_1.version],
|
||||
errorHandler: () => {
|
||||
// Client libraries are expected to pipeline this command
|
||||
// after authentication on all connections and ignore failures
|
||||
// since they could be connected to an older version that doesn't support them.
|
||||
}
|
||||
});
|
||||
commands.push({
|
||||
cmd: [
|
||||
'CLIENT',
|
||||
'SETINFO',
|
||||
'LIB-NAME',
|
||||
this.#options.clientInfoTag
|
||||
? `node-redis(${this.#options.clientInfoTag})`
|
||||
: 'node-redis'
|
||||
],
|
||||
errorHandler: () => {
|
||||
// Client libraries are expected to pipeline this command
|
||||
// after authentication on all connections and ignore failures
|
||||
// since they could be connected to an older version that doesn't support them.
|
||||
}
|
||||
});
|
||||
}
|
||||
if (this.#clientSideCache) {
|
||||
commands.push({ cmd: this.#clientSideCache.trackingOn() });
|
||||
}
|
||||
if (this.#options?.emitInvalidate) {
|
||||
commands.push({ cmd: ['CLIENT', 'TRACKING', 'ON'] });
|
||||
}
|
||||
const maintenanceHandshakeCmd = await enterprise_maintenance_manager_1.default.getHandshakeCommand(this.#options);
|
||||
if (maintenanceHandshakeCmd) {
|
||||
commands.push(maintenanceHandshakeCmd);
|
||||
}
|
||||
;
|
||||
return commands;
|
||||
}
|
||||
#attachListeners(socket) {
|
||||
socket.on('data', chunk => {
|
||||
try {
|
||||
this.#queue.decoder.write(chunk);
|
||||
}
|
||||
catch (err) {
|
||||
this.#queue.resetDecoder();
|
||||
this.emit('error', err);
|
||||
}
|
||||
})
|
||||
.on('error', err => {
|
||||
this.emit('error', err);
|
||||
this.#clientSideCache?.onError();
|
||||
if (this.#socket.isOpen && !this.#options.disableOfflineQueue) {
|
||||
this.#queue.flushWaitingForReply(err);
|
||||
}
|
||||
else {
|
||||
this.#queue.flushAll(err);
|
||||
}
|
||||
})
|
||||
.on('connect', () => this.emit('connect'))
|
||||
.on('ready', () => {
|
||||
this.emit('ready');
|
||||
this.#setPingTimer();
|
||||
this.#maybeScheduleWrite();
|
||||
})
|
||||
.on('reconnecting', () => this.emit('reconnecting'))
|
||||
.on('drain', () => this.#maybeScheduleWrite())
|
||||
.on('end', () => this.emit('end'));
|
||||
}
|
||||
#initiateSocket() {
|
||||
const socketInitiator = async () => {
|
||||
const promises = [], chainId = Symbol('Socket Initiator');
|
||||
const resubscribePromise = this.#queue.resubscribe(chainId);
|
||||
resubscribePromise?.catch(error => {
|
||||
if (error.message && error.message.startsWith('MOVED')) {
|
||||
this.emit('__MOVED', this._self.#queue.removeAllPubSubListeners());
|
||||
}
|
||||
});
|
||||
if (resubscribePromise) {
|
||||
promises.push(resubscribePromise);
|
||||
}
|
||||
if (this.#monitorCallback) {
|
||||
promises.push(this.#queue.monitor(this.#monitorCallback, {
|
||||
typeMapping: this._commandOptions?.typeMapping,
|
||||
chainId,
|
||||
asap: true
|
||||
}));
|
||||
}
|
||||
promises.push(...(await this.#handshake(chainId, true)));
|
||||
if (promises.length) {
|
||||
this.#write();
|
||||
return Promise.all(promises);
|
||||
}
|
||||
};
|
||||
const socket = new socket_1.default(socketInitiator, this.#options.socket);
|
||||
this.#attachListeners(socket);
|
||||
return socket;
|
||||
}
|
||||
#pingTimer;
|
||||
#setPingTimer() {
|
||||
if (!this.#options.pingInterval || !this.#socket.isReady)
|
||||
return;
|
||||
clearTimeout(this.#pingTimer);
|
||||
this.#pingTimer = setTimeout(() => {
|
||||
if (!this.#socket.isReady)
|
||||
return;
|
||||
this.sendCommand(['PING'])
|
||||
.then(reply => this.emit('ping-interval', reply))
|
||||
.catch(err => this.emit('error', err))
|
||||
.finally(() => this.#setPingTimer());
|
||||
}, this.#options.pingInterval);
|
||||
}
|
||||
withCommandOptions(options) {
|
||||
const proxy = Object.create(this._self);
|
||||
proxy._commandOptions = options;
|
||||
return proxy;
|
||||
}
|
||||
_commandOptionsProxy(key, value) {
|
||||
const proxy = Object.create(this._self);
|
||||
proxy._commandOptions = Object.create(this._commandOptions ?? null);
|
||||
proxy._commandOptions[key] = value;
|
||||
return proxy;
|
||||
}
|
||||
/**
|
||||
* Override the `typeMapping` command option
|
||||
*/
|
||||
withTypeMapping(typeMapping) {
|
||||
return this._commandOptionsProxy('typeMapping', typeMapping);
|
||||
}
|
||||
/**
|
||||
* Override the `abortSignal` command option
|
||||
*/
|
||||
withAbortSignal(abortSignal) {
|
||||
return this._commandOptionsProxy('abortSignal', abortSignal);
|
||||
}
|
||||
/**
|
||||
* Override the `asap` command option to `true`
|
||||
*/
|
||||
asap() {
|
||||
return this._commandOptionsProxy('asap', true);
|
||||
}
|
||||
/**
|
||||
* Create the "legacy" (v3/callback) interface
|
||||
*/
|
||||
legacy() {
|
||||
return new legacy_mode_1.RedisLegacyClient(this);
|
||||
}
|
||||
/**
|
||||
* Create {@link RedisClientPool `RedisClientPool`} using this client as a prototype
|
||||
*/
|
||||
createPool(options) {
|
||||
return pool_1.RedisClientPool.create(this._self.#options, options);
|
||||
}
|
||||
duplicate(overrides) {
|
||||
return new (Object.getPrototypeOf(this).constructor)({
|
||||
...this._self.#options,
|
||||
commandOptions: this._commandOptions,
|
||||
...overrides
|
||||
});
|
||||
}
|
||||
async connect() {
|
||||
await this._self.#socket.connect();
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_ejectSocket() {
|
||||
const socket = this._self.#socket;
|
||||
// @ts-ignore
|
||||
this._self.#socket = null;
|
||||
socket.removeAllListeners();
|
||||
return socket;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_insertSocket(socket) {
|
||||
if (this._self.#socket) {
|
||||
this._self._ejectSocket().destroy();
|
||||
}
|
||||
this._self.#socket = socket;
|
||||
this._self.#attachListeners(this._self.#socket);
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_maintenanceUpdate(update) {
|
||||
this._self.#socket.setMaintenanceTimeout(update.relaxedSocketTimeout);
|
||||
this._self.#queue.setMaintenanceCommandTimeout(update.relaxedCommandTimeout);
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_pause() {
|
||||
this._self.#paused = true;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
_unpause() {
|
||||
this._self.#paused = false;
|
||||
this._self.#maybeScheduleWrite();
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async _executeCommand(command, parser, commandOptions, transformReply) {
|
||||
const csc = this._self.#clientSideCache;
|
||||
const defaultTypeMapping = this._self.#options.commandOptions === commandOptions;
|
||||
const fn = () => { return this.sendCommand(parser.redisArgs, commandOptions); };
|
||||
if (csc && command.CACHEABLE && defaultTypeMapping) {
|
||||
return await csc.handleCache(this._self, parser, fn, transformReply, commandOptions?.typeMapping);
|
||||
}
|
||||
else {
|
||||
const reply = await fn();
|
||||
if (transformReply) {
|
||||
return transformReply(reply, parser.preserve, commandOptions?.typeMapping);
|
||||
}
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async _executeScript(script, parser, options, transformReply) {
|
||||
const args = parser.redisArgs;
|
||||
let reply;
|
||||
try {
|
||||
reply = await this.sendCommand(args, options);
|
||||
}
|
||||
catch (err) {
|
||||
if (!err?.message?.startsWith?.('NOSCRIPT'))
|
||||
throw err;
|
||||
args[0] = 'EVAL';
|
||||
args[1] = script.SCRIPT;
|
||||
reply = await this.sendCommand(args, options);
|
||||
}
|
||||
return transformReply ?
|
||||
transformReply(reply, parser.preserve, options?.typeMapping) :
|
||||
reply;
|
||||
}
|
||||
sendCommand(args, options) {
|
||||
if (!this._self.#socket.isOpen) {
|
||||
return Promise.reject(new errors_1.ClientClosedError());
|
||||
}
|
||||
else if (!this._self.#socket.isReady && this._self.#options.disableOfflineQueue) {
|
||||
return Promise.reject(new errors_1.ClientOfflineError());
|
||||
}
|
||||
// Merge global options with provided options
|
||||
const opts = {
|
||||
...this._self._commandOptions,
|
||||
...options
|
||||
};
|
||||
const promise = this._self.#queue.addCommand(args, opts);
|
||||
this._self.#scheduleWrite();
|
||||
return promise;
|
||||
}
|
||||
async SELECT(db) {
|
||||
await this.sendCommand(['SELECT', db.toString()]);
|
||||
this._self.#selectedDB = db;
|
||||
}
|
||||
select = this.SELECT;
|
||||
#pubSubCommand(promise) {
|
||||
if (promise === undefined)
|
||||
return Promise.resolve();
|
||||
this.#scheduleWrite();
|
||||
return promise;
|
||||
}
|
||||
SUBSCRIBE(channels, listener, bufferMode) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.subscribe(pub_sub_1.PUBSUB_TYPE.CHANNELS, channels, listener, bufferMode));
|
||||
}
|
||||
subscribe = this.SUBSCRIBE;
|
||||
UNSUBSCRIBE(channels, listener, bufferMode) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.unsubscribe(pub_sub_1.PUBSUB_TYPE.CHANNELS, channels, listener, bufferMode));
|
||||
}
|
||||
unsubscribe = this.UNSUBSCRIBE;
|
||||
PSUBSCRIBE(patterns, listener, bufferMode) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.subscribe(pub_sub_1.PUBSUB_TYPE.PATTERNS, patterns, listener, bufferMode));
|
||||
}
|
||||
pSubscribe = this.PSUBSCRIBE;
|
||||
PUNSUBSCRIBE(patterns, listener, bufferMode) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.unsubscribe(pub_sub_1.PUBSUB_TYPE.PATTERNS, patterns, listener, bufferMode));
|
||||
}
|
||||
pUnsubscribe = this.PUNSUBSCRIBE;
|
||||
SSUBSCRIBE(channels, listener, bufferMode) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.subscribe(pub_sub_1.PUBSUB_TYPE.SHARDED, channels, listener, bufferMode));
|
||||
}
|
||||
sSubscribe = this.SSUBSCRIBE;
|
||||
SUNSUBSCRIBE(channels, listener, bufferMode) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.unsubscribe(pub_sub_1.PUBSUB_TYPE.SHARDED, channels, listener, bufferMode));
|
||||
}
|
||||
sUnsubscribe = this.SUNSUBSCRIBE;
|
||||
async WATCH(key) {
|
||||
const reply = await this._self.sendCommand((0, generic_transformers_1.pushVariadicArguments)(['WATCH'], key));
|
||||
this._self.#watchEpoch ??= this._self.socketEpoch;
|
||||
return reply;
|
||||
}
|
||||
watch = this.WATCH;
|
||||
async UNWATCH() {
|
||||
const reply = await this._self.sendCommand(['UNWATCH']);
|
||||
this._self.#watchEpoch = undefined;
|
||||
return reply;
|
||||
}
|
||||
unwatch = this.UNWATCH;
|
||||
getPubSubListeners(type) {
|
||||
return this._self.#queue.getPubSubListeners(type);
|
||||
}
|
||||
extendPubSubChannelListeners(type, channel, listeners) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.extendPubSubChannelListeners(type, channel, listeners));
|
||||
}
|
||||
extendPubSubListeners(type, listeners) {
|
||||
return this._self.#pubSubCommand(this._self.#queue.extendPubSubListeners(type, listeners));
|
||||
}
|
||||
#write() {
|
||||
if (this.#paused) {
|
||||
return;
|
||||
}
|
||||
this.#socket.write(this.#queue.commandsToWrite());
|
||||
}
|
||||
#scheduledWrite;
|
||||
#scheduleWrite() {
|
||||
if (!this.#socket.isReady || this.#scheduledWrite)
|
||||
return;
|
||||
this.#scheduledWrite = setImmediate(() => {
|
||||
this.#write();
|
||||
this.#scheduledWrite = undefined;
|
||||
});
|
||||
}
|
||||
#maybeScheduleWrite() {
|
||||
if (!this.#queue.isWaitingToWrite())
|
||||
return;
|
||||
this.#scheduleWrite();
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async _executePipeline(commands, selectedDB) {
|
||||
if (!this._self.#socket.isOpen) {
|
||||
return Promise.reject(new errors_1.ClientClosedError());
|
||||
}
|
||||
const chainId = Symbol('Pipeline Chain'), promise = Promise.all(commands.map(({ args }) => this._self.#queue.addCommand(args, {
|
||||
chainId,
|
||||
typeMapping: this._commandOptions?.typeMapping
|
||||
})));
|
||||
this._self.#scheduleWrite();
|
||||
const result = await promise;
|
||||
if (selectedDB !== undefined) {
|
||||
this._self.#selectedDB = selectedDB;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
async _executeMulti(commands, selectedDB) {
|
||||
const dirtyWatch = this._self.#dirtyWatch;
|
||||
this._self.#dirtyWatch = undefined;
|
||||
const watchEpoch = this._self.#watchEpoch;
|
||||
this._self.#watchEpoch = undefined;
|
||||
if (!this._self.#socket.isOpen) {
|
||||
throw new errors_1.ClientClosedError();
|
||||
}
|
||||
if (dirtyWatch) {
|
||||
throw new errors_1.WatchError(dirtyWatch);
|
||||
}
|
||||
if (watchEpoch && watchEpoch !== this._self.socketEpoch) {
|
||||
throw new errors_1.WatchError('Client reconnected after WATCH');
|
||||
}
|
||||
const typeMapping = this._commandOptions?.typeMapping;
|
||||
const chainId = Symbol('MULTI Chain');
|
||||
const promises = [
|
||||
this._self.#queue.addCommand(['MULTI'], { chainId }),
|
||||
];
|
||||
for (const { args } of commands) {
|
||||
promises.push(this._self.#queue.addCommand(args, {
|
||||
chainId,
|
||||
typeMapping
|
||||
}));
|
||||
}
|
||||
promises.push(this._self.#queue.addCommand(['EXEC'], { chainId }));
|
||||
this._self.#scheduleWrite();
|
||||
const results = await Promise.all(promises), execResult = results[results.length - 1];
|
||||
if (execResult === null) {
|
||||
throw new errors_1.WatchError();
|
||||
}
|
||||
if (selectedDB !== undefined) {
|
||||
this._self.#selectedDB = selectedDB;
|
||||
}
|
||||
return execResult;
|
||||
}
|
||||
MULTI() {
|
||||
return new this.Multi(this._executeMulti.bind(this), this._executePipeline.bind(this), this._commandOptions?.typeMapping);
|
||||
}
|
||||
multi = this.MULTI;
|
||||
async *scanIterator(options) {
|
||||
let cursor = options?.cursor ?? '0';
|
||||
do {
|
||||
const reply = await this.scan(cursor, options);
|
||||
cursor = reply.cursor;
|
||||
yield reply.keys;
|
||||
} while (cursor !== '0');
|
||||
}
|
||||
async *hScanIterator(key, options) {
|
||||
let cursor = options?.cursor ?? '0';
|
||||
do {
|
||||
const reply = await this.hScan(key, cursor, options);
|
||||
cursor = reply.cursor;
|
||||
yield reply.entries;
|
||||
} while (cursor !== '0');
|
||||
}
|
||||
async *hScanValuesIterator(key, options) {
|
||||
let cursor = options?.cursor ?? '0';
|
||||
do {
|
||||
const reply = await this.hScanNoValues(key, cursor, options);
|
||||
cursor = reply.cursor;
|
||||
yield reply.fields;
|
||||
} while (cursor !== '0');
|
||||
}
|
||||
async *hScanNoValuesIterator(key, options) {
|
||||
let cursor = options?.cursor ?? '0';
|
||||
do {
|
||||
const reply = await this.hScanNoValues(key, cursor, options);
|
||||
cursor = reply.cursor;
|
||||
yield reply.fields;
|
||||
} while (cursor !== '0');
|
||||
}
|
||||
async *sScanIterator(key, options) {
|
||||
let cursor = options?.cursor ?? '0';
|
||||
do {
|
||||
const reply = await this.sScan(key, cursor, options);
|
||||
cursor = reply.cursor;
|
||||
yield reply.members;
|
||||
} while (cursor !== '0');
|
||||
}
|
||||
async *zScanIterator(key, options) {
|
||||
let cursor = options?.cursor ?? '0';
|
||||
do {
|
||||
const reply = await this.zScan(key, cursor, options);
|
||||
cursor = reply.cursor;
|
||||
yield reply.members;
|
||||
} while (cursor !== '0');
|
||||
}
|
||||
async MONITOR(callback) {
|
||||
const promise = this._self.#queue.monitor(callback, {
|
||||
typeMapping: this._commandOptions?.typeMapping
|
||||
});
|
||||
this._self.#scheduleWrite();
|
||||
await promise;
|
||||
this._self.#monitorCallback = callback;
|
||||
}
|
||||
monitor = this.MONITOR;
|
||||
/**
|
||||
* Reset the client to its default state (i.e. stop PubSub, stop monitoring, select default DB, etc.)
|
||||
*/
|
||||
async reset() {
|
||||
const chainId = Symbol('Reset Chain'), promises = [this._self.#queue.reset(chainId)], selectedDB = this._self.#options?.database ?? 0;
|
||||
this._self.#credentialsSubscription?.dispose();
|
||||
this._self.#credentialsSubscription = null;
|
||||
promises.push(...(await this._self.#handshake(chainId, false)));
|
||||
this._self.#scheduleWrite();
|
||||
await Promise.all(promises);
|
||||
this._self.#selectedDB = selectedDB;
|
||||
this._self.#monitorCallback = undefined;
|
||||
this._self.#dirtyWatch = undefined;
|
||||
this._self.#watchEpoch = undefined;
|
||||
}
|
||||
/**
|
||||
* If the client has state, reset it.
|
||||
* An internal function to be used by wrapper class such as `RedisClientPool`.
|
||||
* @internal
|
||||
*/
|
||||
resetIfDirty() {
|
||||
let shouldReset = false;
|
||||
if (this._self.#selectedDB !== (this._self.#options?.database ?? 0)) {
|
||||
console.warn('Returning a client with a different selected DB');
|
||||
shouldReset = true;
|
||||
}
|
||||
if (this._self.#monitorCallback) {
|
||||
console.warn('Returning a client with active MONITOR');
|
||||
shouldReset = true;
|
||||
}
|
||||
if (this._self.#queue.isPubSubActive) {
|
||||
console.warn('Returning a client with active PubSub');
|
||||
shouldReset = true;
|
||||
}
|
||||
if (this._self.#dirtyWatch || this._self.#watchEpoch) {
|
||||
console.warn('Returning a client with active WATCH');
|
||||
shouldReset = true;
|
||||
}
|
||||
if (shouldReset) {
|
||||
return this.reset();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @deprecated use .close instead
|
||||
*/
|
||||
QUIT() {
|
||||
this._self.#credentialsSubscription?.dispose();
|
||||
this._self.#credentialsSubscription = null;
|
||||
return this._self.#socket.quit(async () => {
|
||||
clearTimeout(this._self.#pingTimer);
|
||||
const quitPromise = this._self.#queue.addCommand(['QUIT']);
|
||||
this._self.#scheduleWrite();
|
||||
return quitPromise;
|
||||
});
|
||||
}
|
||||
quit = this.QUIT;
|
||||
/**
|
||||
* @deprecated use .destroy instead
|
||||
*/
|
||||
disconnect() {
|
||||
return Promise.resolve(this.destroy());
|
||||
}
|
||||
/**
|
||||
* Close the client. Wait for pending commands.
|
||||
*/
|
||||
close() {
|
||||
return new Promise(resolve => {
|
||||
clearTimeout(this._self.#pingTimer);
|
||||
this._self.#socket.close();
|
||||
this._self.#clientSideCache?.onClose();
|
||||
if (this._self.#queue.isEmpty()) {
|
||||
this._self.#socket.destroySocket();
|
||||
return resolve();
|
||||
}
|
||||
const maybeClose = () => {
|
||||
if (!this._self.#queue.isEmpty())
|
||||
return;
|
||||
this._self.#socket.off('data', maybeClose);
|
||||
this._self.#socket.destroySocket();
|
||||
resolve();
|
||||
};
|
||||
this._self.#socket.on('data', maybeClose);
|
||||
this._self.#credentialsSubscription?.dispose();
|
||||
this._self.#credentialsSubscription = null;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Destroy the client. Rejects all commands immediately.
|
||||
*/
|
||||
destroy() {
|
||||
clearTimeout(this._self.#pingTimer);
|
||||
this._self.#queue.flushAll(new errors_1.DisconnectsClientError());
|
||||
this._self.#socket.destroy();
|
||||
this._self.#clientSideCache?.onClose();
|
||||
this._self.#credentialsSubscription?.dispose();
|
||||
this._self.#credentialsSubscription = null;
|
||||
}
|
||||
ref() {
|
||||
this._self.#socket.ref();
|
||||
}
|
||||
unref() {
|
||||
this._self.#socket.unref();
|
||||
}
|
||||
}
|
||||
_a = RedisClient;
|
||||
exports.default = RedisClient;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/index.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
37
node_modules/@redis/client/dist/lib/client/legacy-mode.d.ts
generated
vendored
Normal file
37
node_modules/@redis/client/dist/lib/client/legacy-mode.d.ts
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/// <reference types="node" />
|
||||
import { RedisModules, RedisFunctions, RedisScripts, RespVersions, Command, CommandArguments, ReplyUnion } from '../RESP/types';
|
||||
import { RedisClientType } from '.';
|
||||
import { ErrorReply } from '../errors';
|
||||
import COMMANDS from '../commands';
|
||||
type LegacyArgument = string | Buffer | number | Date;
|
||||
type LegacyArguments = Array<LegacyArgument | LegacyArguments>;
|
||||
type LegacyCallback = (err: ErrorReply | null, reply?: ReplyUnion) => unknown;
|
||||
type LegacyCommandArguments = LegacyArguments | [
|
||||
...args: LegacyArguments,
|
||||
callback: LegacyCallback
|
||||
];
|
||||
type WithCommands = {
|
||||
[P in keyof typeof COMMANDS]: (...args: LegacyCommandArguments) => void;
|
||||
};
|
||||
export type RedisLegacyClientType = RedisLegacyClient & WithCommands;
|
||||
export declare class RedisLegacyClient {
|
||||
#private;
|
||||
static pushArguments(redisArgs: CommandArguments, args: LegacyArguments): void;
|
||||
static getTransformReply(command: Command, resp: RespVersions): import("../RESP/types").TransformReply | undefined;
|
||||
constructor(client: RedisClientType<RedisModules, RedisFunctions, RedisScripts>);
|
||||
sendCommand(...args: LegacyCommandArguments): void;
|
||||
multi(): RedisLegacyMultiType;
|
||||
}
|
||||
type MultiWithCommands = {
|
||||
[P in keyof typeof COMMANDS]: (...args: LegacyCommandArguments) => RedisLegacyMultiType;
|
||||
};
|
||||
export type RedisLegacyMultiType = LegacyMultiCommand & MultiWithCommands;
|
||||
declare class LegacyMultiCommand {
|
||||
#private;
|
||||
static factory(resp: RespVersions): (client: RedisClientType<RedisModules, RedisFunctions, RedisScripts>) => RedisLegacyMultiType;
|
||||
constructor(client: RedisClientType<RedisModules, RedisFunctions, RedisScripts>);
|
||||
sendCommand(...args: LegacyArguments): this;
|
||||
exec(cb?: (err: ErrorReply | null, replies?: Array<unknown>) => unknown): void;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=legacy-mode.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/legacy-mode.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/legacy-mode.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"legacy-mode.d.ts","sourceRoot":"","sources":["../../../lib/client/legacy-mode.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAChI,OAAO,EAAE,eAAe,EAAE,MAAM,GAAG,CAAC;AAEpC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,OAAO,QAAQ,MAAM,aAAa,CAAC;AAGnC,KAAK,cAAc,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;AAEtD,KAAK,eAAe,GAAG,KAAK,CAAC,cAAc,GAAG,eAAe,CAAC,CAAC;AAE/D,KAAK,cAAc,GAAG,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,EAAE,KAAK,CAAC,EAAE,UAAU,KAAK,OAAO,CAAA;AAE7E,KAAK,sBAAsB,GAAG,eAAe,GAAG;IAC9C,GAAG,IAAI,EAAE,eAAe;IACxB,QAAQ,EAAE,cAAc;CACzB,CAAC;AAEF,KAAK,YAAY,GAAG;KACjB,CAAC,IAAI,MAAM,OAAO,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,sBAAsB,KAAK,IAAI;CACxE,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,iBAAiB,GAAG,YAAY,CAAC;AAErE,qBAAa,iBAAiB;;IAY5B,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,eAAe;IAevE,MAAM,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY;gBA4B3D,MAAM,EAAE,eAAe,CAAC,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;IAiBrE,WAAW,CAAC,GAAG,IAAI,EAAE,sBAAsB;IAe3C,KAAK;CAGN;AAED,KAAK,iBAAiB,GAAG;KACtB,CAAC,IAAI,MAAM,OAAO,QAAQ,GAAG,CAAC,GAAG,IAAI,EAAE,sBAAsB,KAAK,oBAAoB;CACxF,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,kBAAkB,GAAG,iBAAiB,CAAC;AAE1E,cAAM,kBAAkB;;IAWtB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,YAAY,YAYf,gBAAgB,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;gBAQjE,MAAM,EAAE,eAAe,CAAC,YAAY,EAAE,cAAc,EAAE,YAAY,CAAC;IAI/E,WAAW,CAAC,GAAG,IAAI,EAAE,eAAe;IAOpC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,OAAO;CAYxE"}
|
||||
119
node_modules/@redis/client/dist/lib/client/legacy-mode.js
generated
vendored
Normal file
119
node_modules/@redis/client/dist/lib/client/legacy-mode.js
generated
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RedisLegacyClient = void 0;
|
||||
const commander_1 = require("../commander");
|
||||
const commands_1 = __importDefault(require("../commands"));
|
||||
const multi_command_1 = __importDefault(require("../multi-command"));
|
||||
class RedisLegacyClient {
|
||||
static #transformArguments(redisArgs, args) {
|
||||
let callback;
|
||||
if (typeof args[args.length - 1] === 'function') {
|
||||
callback = args.pop();
|
||||
}
|
||||
RedisLegacyClient.pushArguments(redisArgs, args);
|
||||
return callback;
|
||||
}
|
||||
static pushArguments(redisArgs, args) {
|
||||
for (let i = 0; i < args.length; ++i) {
|
||||
const arg = args[i];
|
||||
if (Array.isArray(arg)) {
|
||||
RedisLegacyClient.pushArguments(redisArgs, arg);
|
||||
}
|
||||
else {
|
||||
redisArgs.push(typeof arg === 'number' || arg instanceof Date ?
|
||||
arg.toString() :
|
||||
arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
static getTransformReply(command, resp) {
|
||||
return command.TRANSFORM_LEGACY_REPLY ?
|
||||
(0, commander_1.getTransformReply)(command, resp) :
|
||||
undefined;
|
||||
}
|
||||
static #createCommand(name, command, resp) {
|
||||
const transformReply = RedisLegacyClient.getTransformReply(command, resp);
|
||||
return function (...args) {
|
||||
const redisArgs = [name], callback = RedisLegacyClient.#transformArguments(redisArgs, args), promise = this.#client.sendCommand(redisArgs);
|
||||
if (!callback) {
|
||||
promise.catch(err => this.#client.emit('error', err));
|
||||
return;
|
||||
}
|
||||
promise
|
||||
.then(reply => callback(null, transformReply ? transformReply(reply) : reply))
|
||||
.catch(err => callback(err));
|
||||
};
|
||||
}
|
||||
#client;
|
||||
#Multi;
|
||||
constructor(client) {
|
||||
this.#client = client;
|
||||
const RESP = client.options?.RESP ?? 2;
|
||||
for (const [name, command] of Object.entries(commands_1.default)) {
|
||||
// TODO: as any?
|
||||
this[name] = RedisLegacyClient.#createCommand(name, command, RESP);
|
||||
}
|
||||
this.#Multi = LegacyMultiCommand.factory(RESP);
|
||||
}
|
||||
sendCommand(...args) {
|
||||
const redisArgs = [], callback = RedisLegacyClient.#transformArguments(redisArgs, args), promise = this.#client.sendCommand(redisArgs);
|
||||
if (!callback) {
|
||||
promise.catch(err => this.#client.emit('error', err));
|
||||
return;
|
||||
}
|
||||
promise
|
||||
.then(reply => callback(null, reply))
|
||||
.catch(err => callback(err));
|
||||
}
|
||||
multi() {
|
||||
return this.#Multi(this.#client);
|
||||
}
|
||||
}
|
||||
exports.RedisLegacyClient = RedisLegacyClient;
|
||||
class LegacyMultiCommand {
|
||||
static #createCommand(name, command, resp) {
|
||||
const transformReply = RedisLegacyClient.getTransformReply(command, resp);
|
||||
return function (...args) {
|
||||
const redisArgs = [name];
|
||||
RedisLegacyClient.pushArguments(redisArgs, args);
|
||||
this.#multi.addCommand(redisArgs, transformReply);
|
||||
return this;
|
||||
};
|
||||
}
|
||||
static factory(resp) {
|
||||
const Multi = class extends LegacyMultiCommand {
|
||||
};
|
||||
for (const [name, command] of Object.entries(commands_1.default)) {
|
||||
// TODO: as any?
|
||||
Multi.prototype[name] = LegacyMultiCommand.#createCommand(name, command, resp);
|
||||
}
|
||||
return (client) => {
|
||||
return new Multi(client);
|
||||
};
|
||||
}
|
||||
#multi = new multi_command_1.default();
|
||||
#client;
|
||||
constructor(client) {
|
||||
this.#client = client;
|
||||
}
|
||||
sendCommand(...args) {
|
||||
const redisArgs = [];
|
||||
RedisLegacyClient.pushArguments(redisArgs, args);
|
||||
this.#multi.addCommand(redisArgs);
|
||||
return this;
|
||||
}
|
||||
exec(cb) {
|
||||
const promise = this.#client._executeMulti(this.#multi.queue);
|
||||
if (!cb) {
|
||||
promise.catch(err => this.#client.emit('error', err));
|
||||
return;
|
||||
}
|
||||
promise
|
||||
.then(results => cb(null, this.#multi.transformReplies(results)))
|
||||
.catch(err => cb?.(err));
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=legacy-mode.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/legacy-mode.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/legacy-mode.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"legacy-mode.js","sourceRoot":"","sources":["../../../lib/client/legacy-mode.ts"],"names":[],"mappings":";;;;;;AAEA,4CAAiD;AAEjD,2DAAmC;AACnC,qEAAiD;AAmBjD,MAAa,iBAAiB;IAC5B,MAAM,CAAC,mBAAmB,CAAC,SAA2B,EAAE,IAA4B;QAClF,IAAI,QAAoC,CAAC;QACzC,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;YAChD,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAoB,CAAC;QAC1C,CAAC;QAED,iBAAiB,CAAC,aAAa,CAAC,SAAS,EAAE,IAAuB,CAAC,CAAC;QAEpE,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,MAAM,CAAC,aAAa,CAAC,SAA2B,EAAE,IAAqB;QACrE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,EAAE,CAAC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;YACpB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvB,iBAAiB,CAAC,aAAa,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;YAClD,CAAC;iBAAM,CAAC;gBACN,SAAS,CAAC,IAAI,CACZ,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,YAAY,IAAI,CAAC,CAAC;oBAC9C,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAChB,GAAG,CACN,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,CAAC,iBAAiB,CAAC,OAAgB,EAAE,IAAkB;QAC3D,OAAO,OAAO,CAAC,sBAAsB,CAAC,CAAC;YACrC,IAAA,6BAAiB,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC;YAClC,SAAS,CAAC;IACd,CAAC;IAED,MAAM,CAAC,cAAc,CAAC,IAAY,EAAE,OAAgB,EAAE,IAAkB;QACtE,MAAM,cAAc,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1E,OAAO,UAAmC,GAAG,IAA4B;YACvE,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,EACtB,QAAQ,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,EACjE,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;YAEhD,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;gBACtD,OAAO;YACT,CAAC;YAED,OAAO;iBACJ,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;iBAC7E,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC;IACJ,CAAC;IAED,OAAO,CAA8D;IACrE,MAAM,CAAmD;IAEzD,YACE,MAAmE;QAEnE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;QAEtB,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,IAAI,IAAI,CAAC,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAQ,CAAC,EAAE,CAAC;YACvD,gBAAgB;YACf,IAAY,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,cAAc,CACpD,IAAI,EACJ,OAAO,EACP,IAAI,CACL,CAAC;QACJ,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,kBAAkB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;IAED,WAAW,CAAC,GAAG,IAA4B;QACzC,MAAM,SAAS,GAAqB,EAAE,EACpC,QAAQ,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,SAAS,EAAE,IAAI,CAAC,EACjE,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QAEhD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,OAAO;aACJ,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;aACpC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACnC,CAAC;CACF;AA1FD,8CA0FC;AAQD,MAAM,kBAAkB;IACtB,MAAM,CAAC,cAAc,CAAC,IAAY,EAAE,OAAgB,EAAE,IAAkB;QACtE,MAAM,cAAc,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC1E,OAAO,UAAoC,GAAG,IAAqB;YACjE,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,CAAC;YACzB,iBAAiB,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YACjD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;IACJ,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,IAAkB;QAC/B,MAAM,KAAK,GAAG,KAAM,SAAQ,kBAAkB;SAAG,CAAC;QAElD,KAAK,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,kBAAQ,CAAC,EAAE,CAAC;YACvD,gBAAgB;YACf,KAAa,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,kBAAkB,CAAC,cAAc,CAChE,IAAI,EACJ,OAAO,EACP,IAAI,CACL,CAAC;QACJ,CAAC;QAED,OAAO,CAAC,MAAmE,EAAE,EAAE;YAC7E,OAAO,IAAI,KAAK,CAAC,MAAM,CAAoC,CAAC;QAC9D,CAAC,CAAC;IACJ,CAAC;IAEQ,MAAM,GAAG,IAAI,uBAAiB,EAAE,CAAC;IACjC,OAAO,CAA8D;IAE9E,YAAY,MAAmE;QAC7E,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,WAAW,CAAC,GAAG,IAAqB;QAClC,MAAM,SAAS,GAAqB,EAAE,CAAC;QACvC,iBAAiB,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,CAAC,EAAkE;QACrE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAE9D,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;YACtD,OAAO;QACT,CAAC;QAED,OAAO;aACJ,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;aAChE,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7B,CAAC;CACF"}
|
||||
68
node_modules/@redis/client/dist/lib/client/linked-list.d.ts
generated
vendored
Normal file
68
node_modules/@redis/client/dist/lib/client/linked-list.d.ts
generated
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
/// <reference types="node" />
|
||||
import EventEmitter from "events";
|
||||
export interface DoublyLinkedNode<T> {
|
||||
value: T;
|
||||
previous: DoublyLinkedNode<T> | undefined;
|
||||
next: DoublyLinkedNode<T> | undefined;
|
||||
}
|
||||
export declare class DoublyLinkedList<T> {
|
||||
#private;
|
||||
get length(): number;
|
||||
get head(): DoublyLinkedNode<T> | undefined;
|
||||
get tail(): DoublyLinkedNode<T> | undefined;
|
||||
push(value: T): {
|
||||
previous: DoublyLinkedNode<T> | undefined;
|
||||
next: undefined;
|
||||
value: T;
|
||||
};
|
||||
unshift(value: T): {
|
||||
previous: undefined;
|
||||
next: undefined;
|
||||
value: T;
|
||||
} | {
|
||||
previous: undefined;
|
||||
next: DoublyLinkedNode<T>;
|
||||
value: T;
|
||||
};
|
||||
add(value: T, prepend?: boolean): {
|
||||
previous: DoublyLinkedNode<T> | undefined;
|
||||
next: undefined;
|
||||
value: T;
|
||||
} | {
|
||||
previous: undefined;
|
||||
next: DoublyLinkedNode<T>;
|
||||
value: T;
|
||||
};
|
||||
shift(): T | undefined;
|
||||
remove(node: DoublyLinkedNode<T>): void;
|
||||
reset(): void;
|
||||
[Symbol.iterator](): Generator<T, void, unknown>;
|
||||
nodes(): Generator<DoublyLinkedNode<T>, void, unknown>;
|
||||
}
|
||||
export interface SinglyLinkedNode<T> {
|
||||
value: T;
|
||||
next: SinglyLinkedNode<T> | undefined;
|
||||
removed: boolean;
|
||||
}
|
||||
export declare class SinglyLinkedList<T> {
|
||||
#private;
|
||||
get length(): number;
|
||||
get head(): SinglyLinkedNode<T> | undefined;
|
||||
get tail(): SinglyLinkedNode<T> | undefined;
|
||||
push(value: T): {
|
||||
value: T;
|
||||
next: undefined;
|
||||
removed: boolean;
|
||||
};
|
||||
remove(node: SinglyLinkedNode<T>, parent: SinglyLinkedNode<T> | undefined): void;
|
||||
shift(): T | undefined;
|
||||
reset(): void;
|
||||
[Symbol.iterator](): Generator<T, void, unknown>;
|
||||
}
|
||||
export declare class EmptyAwareSinglyLinkedList<T> extends SinglyLinkedList<T> {
|
||||
readonly events: EventEmitter;
|
||||
reset(): void;
|
||||
shift(): T | undefined;
|
||||
remove(node: SinglyLinkedNode<T>, parent: SinglyLinkedNode<T> | undefined): void;
|
||||
}
|
||||
//# sourceMappingURL=linked-list.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/linked-list.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/linked-list.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"linked-list.d.ts","sourceRoot":"","sources":["../../../lib/client/linked-list.ts"],"names":[],"mappings":";AAAA,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IAC1C,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;CACvC;AAED,qBAAa,gBAAgB,CAAC,CAAC;;IAG7B,IAAI,MAAM,WAET;IAID,IAAI,IAAI,oCAEP;IAID,IAAI,IAAI,oCAEP;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;;;;;IAkBb,OAAO,CAAC,KAAK,EAAE,CAAC;;;;;;;;;IAkBhB,GAAG,CAAC,KAAK,EAAE,CAAC,EAAE,OAAO,UAAQ;;;;;;;;;IAM7B,KAAK;IAeL,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAqBhC,KAAK;IAKJ,CAAC,MAAM,CAAC,QAAQ,CAAC;IAQjB,KAAK;CAQP;AAED,MAAM,WAAW,gBAAgB,CAAC,CAAC;IACjC,KAAK,EAAE,CAAC,CAAC;IACT,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC;IACtC,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,qBAAa,gBAAgB,CAAC,CAAC;;IAG7B,IAAI,MAAM,WAET;IAID,IAAI,IAAI,oCAEP;IAID,IAAI,IAAI,oCAEP;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;;;;;IAgBb,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS;IAsBzE,KAAK;IAcL,KAAK;IAKJ,CAAC,MAAM,CAAC,QAAQ,CAAC;CAOnB;AAED,qBAAa,0BAA0B,CAAC,CAAC,CAAE,SAAQ,gBAAgB,CAAC,CAAC,CAAC;IACpE,QAAQ,CAAC,MAAM,eAAsB;IACrC,KAAK;IAOL,KAAK,IAAI,CAAC,GAAG,SAAS;IAQtB,MAAM,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS;CAQ1E"}
|
||||
212
node_modules/@redis/client/dist/lib/client/linked-list.js
generated
vendored
Normal file
212
node_modules/@redis/client/dist/lib/client/linked-list.js
generated
vendored
Normal file
@@ -0,0 +1,212 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.EmptyAwareSinglyLinkedList = exports.SinglyLinkedList = exports.DoublyLinkedList = void 0;
|
||||
const events_1 = __importDefault(require("events"));
|
||||
class DoublyLinkedList {
|
||||
#length = 0;
|
||||
get length() {
|
||||
return this.#length;
|
||||
}
|
||||
#head;
|
||||
get head() {
|
||||
return this.#head;
|
||||
}
|
||||
#tail;
|
||||
get tail() {
|
||||
return this.#tail;
|
||||
}
|
||||
push(value) {
|
||||
++this.#length;
|
||||
if (this.#tail === undefined) {
|
||||
return this.#head = this.#tail = {
|
||||
previous: this.#head,
|
||||
next: undefined,
|
||||
value
|
||||
};
|
||||
}
|
||||
return this.#tail = this.#tail.next = {
|
||||
previous: this.#tail,
|
||||
next: undefined,
|
||||
value
|
||||
};
|
||||
}
|
||||
unshift(value) {
|
||||
++this.#length;
|
||||
if (this.#head === undefined) {
|
||||
return this.#head = this.#tail = {
|
||||
previous: undefined,
|
||||
next: undefined,
|
||||
value
|
||||
};
|
||||
}
|
||||
return this.#head = this.#head.previous = {
|
||||
previous: undefined,
|
||||
next: this.#head,
|
||||
value
|
||||
};
|
||||
}
|
||||
add(value, prepend = false) {
|
||||
return prepend ?
|
||||
this.unshift(value) :
|
||||
this.push(value);
|
||||
}
|
||||
shift() {
|
||||
if (this.#head === undefined)
|
||||
return undefined;
|
||||
--this.#length;
|
||||
const node = this.#head;
|
||||
if (node.next) {
|
||||
node.next.previous = undefined;
|
||||
this.#head = node.next;
|
||||
node.next = undefined;
|
||||
}
|
||||
else {
|
||||
this.#head = this.#tail = undefined;
|
||||
}
|
||||
return node.value;
|
||||
}
|
||||
remove(node) {
|
||||
if (this.#length === 0)
|
||||
return;
|
||||
--this.#length;
|
||||
if (this.#tail === node) {
|
||||
this.#tail = node.previous;
|
||||
}
|
||||
if (this.#head === node) {
|
||||
this.#head = node.next;
|
||||
}
|
||||
else {
|
||||
if (node.previous) {
|
||||
node.previous.next = node.next;
|
||||
}
|
||||
if (node.next) {
|
||||
node.next.previous = node.previous;
|
||||
}
|
||||
}
|
||||
node.previous = undefined;
|
||||
node.next = undefined;
|
||||
}
|
||||
reset() {
|
||||
this.#length = 0;
|
||||
this.#head = this.#tail = undefined;
|
||||
}
|
||||
*[Symbol.iterator]() {
|
||||
let node = this.#head;
|
||||
while (node !== undefined) {
|
||||
yield node.value;
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
*nodes() {
|
||||
let node = this.#head;
|
||||
while (node) {
|
||||
const next = node.next;
|
||||
yield node;
|
||||
node = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.DoublyLinkedList = DoublyLinkedList;
|
||||
class SinglyLinkedList {
|
||||
#length = 0;
|
||||
get length() {
|
||||
return this.#length;
|
||||
}
|
||||
#head;
|
||||
get head() {
|
||||
return this.#head;
|
||||
}
|
||||
#tail;
|
||||
get tail() {
|
||||
return this.#tail;
|
||||
}
|
||||
push(value) {
|
||||
++this.#length;
|
||||
const node = {
|
||||
value,
|
||||
next: undefined,
|
||||
removed: false
|
||||
};
|
||||
if (this.#head === undefined) {
|
||||
return this.#head = this.#tail = node;
|
||||
}
|
||||
return this.#tail.next = this.#tail = node;
|
||||
}
|
||||
remove(node, parent) {
|
||||
if (node.removed) {
|
||||
throw new Error("node already removed");
|
||||
}
|
||||
--this.#length;
|
||||
if (this.#head === node) {
|
||||
if (this.#tail === node) {
|
||||
this.#head = this.#tail = undefined;
|
||||
}
|
||||
else {
|
||||
this.#head = node.next;
|
||||
}
|
||||
}
|
||||
else if (this.#tail === node) {
|
||||
this.#tail = parent;
|
||||
parent.next = undefined;
|
||||
}
|
||||
else {
|
||||
parent.next = node.next;
|
||||
}
|
||||
node.removed = true;
|
||||
}
|
||||
shift() {
|
||||
if (this.#head === undefined)
|
||||
return undefined;
|
||||
const node = this.#head;
|
||||
if (--this.#length === 0) {
|
||||
this.#head = this.#tail = undefined;
|
||||
}
|
||||
else {
|
||||
this.#head = node.next;
|
||||
}
|
||||
node.removed = true;
|
||||
return node.value;
|
||||
}
|
||||
reset() {
|
||||
this.#length = 0;
|
||||
this.#head = this.#tail = undefined;
|
||||
}
|
||||
*[Symbol.iterator]() {
|
||||
let node = this.#head;
|
||||
while (node !== undefined) {
|
||||
yield node.value;
|
||||
node = node.next;
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.SinglyLinkedList = SinglyLinkedList;
|
||||
class EmptyAwareSinglyLinkedList extends SinglyLinkedList {
|
||||
events = new events_1.default();
|
||||
reset() {
|
||||
const old = this.length;
|
||||
super.reset();
|
||||
if (old !== this.length && this.length === 0) {
|
||||
this.events.emit('empty');
|
||||
}
|
||||
}
|
||||
shift() {
|
||||
const old = this.length;
|
||||
const ret = super.shift();
|
||||
if (old !== this.length && this.length === 0) {
|
||||
this.events.emit('empty');
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
remove(node, parent) {
|
||||
const old = this.length;
|
||||
super.remove(node, parent);
|
||||
if (old !== this.length && this.length === 0) {
|
||||
this.events.emit('empty');
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.EmptyAwareSinglyLinkedList = EmptyAwareSinglyLinkedList;
|
||||
//# sourceMappingURL=linked-list.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/linked-list.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/linked-list.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
45
node_modules/@redis/client/dist/lib/client/multi-command.d.ts
generated
vendored
Normal file
45
node_modules/@redis/client/dist/lib/client/multi-command.d.ts
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
import COMMANDS from '../commands';
|
||||
import { MULTI_MODE, MULTI_REPLY, MultiMode, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command';
|
||||
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, TypeMapping } from '../RESP/types';
|
||||
import { Tail } from '../commands/generic-transformers';
|
||||
type CommandSignature<REPLIES extends Array<unknown>, C extends Command, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = (...args: Tail<Parameters<C['parseCommand']>>) => InternalRedisClientMultiCommandType<[
|
||||
...REPLIES,
|
||||
ReplyWithTypeMapping<CommandReply<C, RESP>, TYPE_MAPPING>
|
||||
], M, F, S, RESP, TYPE_MAPPING>;
|
||||
type WithCommands<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof typeof COMMANDS]: CommandSignature<REPLIES, (typeof COMMANDS)[P], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
type WithModules<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof M]: {
|
||||
[C in keyof M[P]]: CommandSignature<REPLIES, M[P][C], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
};
|
||||
type WithFunctions<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[L in keyof F]: {
|
||||
[C in keyof F[L]]: CommandSignature<REPLIES, F[L][C], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
};
|
||||
type WithScripts<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof S]: CommandSignature<REPLIES, S[P], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
type InternalRedisClientMultiCommandType<REPLIES extends Array<any>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = (RedisClientMultiCommand<REPLIES> & WithCommands<REPLIES, M, F, S, RESP, TYPE_MAPPING> & WithModules<REPLIES, M, F, S, RESP, TYPE_MAPPING> & WithFunctions<REPLIES, M, F, S, RESP, TYPE_MAPPING> & WithScripts<REPLIES, M, F, S, RESP, TYPE_MAPPING>);
|
||||
type TypedOrAny<Flag extends MultiMode, T> = [
|
||||
Flag
|
||||
] extends [MULTI_MODE['TYPED']] ? T : any;
|
||||
export type RedisClientMultiCommandType<isTyped extends MultiMode, REPLIES extends Array<any>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = TypedOrAny<isTyped, InternalRedisClientMultiCommandType<REPLIES, M, F, S, RESP, TYPE_MAPPING>>;
|
||||
type ExecuteMulti = (commands: Array<RedisMultiQueuedCommand>, selectedDB?: number) => Promise<Array<unknown>>;
|
||||
export default class RedisClientMultiCommand<REPLIES = []> {
|
||||
#private;
|
||||
static extend<M extends RedisModules = Record<string, never>, F extends RedisFunctions = Record<string, never>, S extends RedisScripts = Record<string, never>, RESP extends RespVersions = 2>(config?: CommanderConfig<M, F, S, RESP>): any;
|
||||
constructor(executeMulti: ExecuteMulti, executePipeline: ExecuteMulti, typeMapping?: TypeMapping);
|
||||
SELECT(db: number, transformReply?: TransformReply): this;
|
||||
select: (db: number, transformReply?: TransformReply) => this;
|
||||
addCommand(args: CommandArguments, transformReply?: TransformReply): this;
|
||||
exec<T extends MultiReply = MULTI_REPLY['GENERIC']>(execAsPipeline?: boolean): Promise<MultiReplyType<T, REPLIES>>;
|
||||
EXEC: <T extends MultiReply = "generic">(execAsPipeline?: boolean) => Promise<MultiReplyType<T, REPLIES>>;
|
||||
execTyped(execAsPipeline?: boolean): Promise<REPLIES>;
|
||||
execAsPipeline<T extends MultiReply = MULTI_REPLY['GENERIC']>(): Promise<MultiReplyType<T, REPLIES>>;
|
||||
execAsPipelineTyped(): Promise<REPLIES>;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=multi-command.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/multi-command.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/multi-command.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"multi-command.d.ts","sourceRoot":"","sources":["../../../lib/client/multi-command.ts"],"names":[],"mappings":"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"}
|
||||
106
node_modules/@redis/client/dist/lib/client/multi-command.js
generated
vendored
Normal file
106
node_modules/@redis/client/dist/lib/client/multi-command.js
generated
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const commands_1 = __importDefault(require("../commands"));
|
||||
const multi_command_1 = __importDefault(require("../multi-command"));
|
||||
const commander_1 = require("../commander");
|
||||
const parser_1 = require("./parser");
|
||||
class RedisClientMultiCommand {
|
||||
static #createCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
const redisArgs = parser.redisArgs;
|
||||
redisArgs.preserve = parser.preserve;
|
||||
return this.addCommand(redisArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static #createModuleCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
const redisArgs = parser.redisArgs;
|
||||
redisArgs.preserve = parser.preserve;
|
||||
return this._self.addCommand(redisArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static #createFunctionCommand(name, fn, resp) {
|
||||
const prefix = (0, commander_1.functionArgumentsPrefix)(name, fn);
|
||||
const transformReply = (0, commander_1.getTransformReply)(fn, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.push(...prefix);
|
||||
fn.parseCommand(parser, ...args);
|
||||
const redisArgs = parser.redisArgs;
|
||||
redisArgs.preserve = parser.preserve;
|
||||
return this._self.addCommand(redisArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static #createScriptCommand(script, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(script, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
script.parseCommand(parser, ...args);
|
||||
const redisArgs = parser.redisArgs;
|
||||
redisArgs.preserve = parser.preserve;
|
||||
return this.#addScript(script, redisArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static extend(config) {
|
||||
return (0, commander_1.attachConfig)({
|
||||
BaseClass: RedisClientMultiCommand,
|
||||
commands: commands_1.default,
|
||||
createCommand: RedisClientMultiCommand.#createCommand,
|
||||
createModuleCommand: RedisClientMultiCommand.#createModuleCommand,
|
||||
createFunctionCommand: RedisClientMultiCommand.#createFunctionCommand,
|
||||
createScriptCommand: RedisClientMultiCommand.#createScriptCommand,
|
||||
config
|
||||
});
|
||||
}
|
||||
#multi;
|
||||
#executeMulti;
|
||||
#executePipeline;
|
||||
#selectedDB;
|
||||
constructor(executeMulti, executePipeline, typeMapping) {
|
||||
this.#multi = new multi_command_1.default(typeMapping);
|
||||
this.#executeMulti = executeMulti;
|
||||
this.#executePipeline = executePipeline;
|
||||
}
|
||||
SELECT(db, transformReply) {
|
||||
this.#selectedDB = db;
|
||||
this.#multi.addCommand(['SELECT', db.toString()], transformReply);
|
||||
return this;
|
||||
}
|
||||
select = this.SELECT;
|
||||
addCommand(args, transformReply) {
|
||||
this.#multi.addCommand(args, transformReply);
|
||||
return this;
|
||||
}
|
||||
#addScript(script, args, transformReply) {
|
||||
this.#multi.addScript(script, args, transformReply);
|
||||
return this;
|
||||
}
|
||||
async exec(execAsPipeline = false) {
|
||||
if (execAsPipeline)
|
||||
return this.execAsPipeline();
|
||||
return this.#multi.transformReplies(await this.#executeMulti(this.#multi.queue, this.#selectedDB));
|
||||
}
|
||||
EXEC = this.exec;
|
||||
execTyped(execAsPipeline = false) {
|
||||
return this.exec(execAsPipeline);
|
||||
}
|
||||
async execAsPipeline() {
|
||||
if (this.#multi.queue.length === 0)
|
||||
return [];
|
||||
return this.#multi.transformReplies(await this.#executePipeline(this.#multi.queue, this.#selectedDB));
|
||||
}
|
||||
execAsPipelineTyped() {
|
||||
return this.execAsPipeline();
|
||||
}
|
||||
}
|
||||
exports.default = RedisClientMultiCommand;
|
||||
//# sourceMappingURL=multi-command.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/multi-command.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/multi-command.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"multi-command.js","sourceRoot":"","sources":["../../../lib/client/multi-command.ts"],"names":[],"mappings":"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"}
|
||||
31
node_modules/@redis/client/dist/lib/client/parser.d.ts
generated
vendored
Normal file
31
node_modules/@redis/client/dist/lib/client/parser.d.ts
generated
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
import { RedisArgument } from '../RESP/types';
|
||||
import { RedisVariadicArgument } from '../commands/generic-transformers';
|
||||
export interface CommandParser {
|
||||
redisArgs: ReadonlyArray<RedisArgument>;
|
||||
keys: ReadonlyArray<RedisArgument>;
|
||||
firstKey: RedisArgument | undefined;
|
||||
preserve: unknown;
|
||||
push: (...arg: Array<RedisArgument>) => unknown;
|
||||
pushVariadic: (vals: RedisVariadicArgument) => unknown;
|
||||
pushVariadicWithLength: (vals: RedisVariadicArgument) => unknown;
|
||||
pushVariadicNumber: (vals: number | Array<number>) => unknown;
|
||||
pushKey: (key: RedisArgument) => unknown;
|
||||
pushKeys: (keys: RedisVariadicArgument) => unknown;
|
||||
pushKeysLength: (keys: RedisVariadicArgument) => unknown;
|
||||
}
|
||||
export declare class BasicCommandParser implements CommandParser {
|
||||
#private;
|
||||
preserve: unknown;
|
||||
get redisArgs(): RedisArgument[];
|
||||
get keys(): RedisArgument[];
|
||||
get firstKey(): RedisArgument;
|
||||
get cacheKey(): string;
|
||||
push(...arg: Array<RedisArgument>): void;
|
||||
pushVariadic(vals: RedisVariadicArgument): void;
|
||||
pushVariadicWithLength(vals: RedisVariadicArgument): void;
|
||||
pushVariadicNumber(vals: number | number[]): void;
|
||||
pushKey(key: RedisArgument): void;
|
||||
pushKeysLength(keys: RedisVariadicArgument): void;
|
||||
pushKeys(keys: RedisVariadicArgument): void;
|
||||
}
|
||||
//# sourceMappingURL=parser.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/parser.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/parser.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../../lib/client/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAEzE,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACxC,IAAI,EAAE,aAAa,CAAC,aAAa,CAAC,CAAC;IACnC,QAAQ,EAAE,aAAa,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,OAAO,CAAC;IAElB,IAAI,EAAE,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,aAAa,CAAC,KAAK,OAAO,CAAC;IAChD,YAAY,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC;IACvD,sBAAsB,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC;IACjE,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,OAAO,CAAC;IAC9D,OAAO,EAAE,CAAC,GAAG,EAAE,aAAa,KAAK,OAAO,CAAC;IACzC,QAAQ,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC;IACnD,cAAc,EAAE,CAAC,IAAI,EAAE,qBAAqB,KAAK,OAAO,CAAC;CAC1D;AAED,qBAAa,kBAAmB,YAAW,aAAa;;IAGtD,QAAQ,EAAE,OAAO,CAAC;IAElB,IAAI,SAAS,oBAEZ;IAED,IAAI,IAAI,oBAEP;IAED,IAAI,QAAQ,kBAEX;IAED,IAAI,QAAQ,WASX;IAED,IAAI,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,aAAa,CAAC;IAIjC,YAAY,CAAC,IAAI,EAAE,qBAAqB;IAUxC,sBAAsB,CAAC,IAAI,EAAE,qBAAqB;IASlD,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE;IAU1C,OAAO,CAAC,GAAG,EAAE,aAAa;IAK1B,cAAc,CAAC,IAAI,EAAE,qBAAqB;IAS1C,QAAQ,CAAC,IAAI,EAAE,qBAAqB;CASrC"}
|
||||
83
node_modules/@redis/client/dist/lib/client/parser.js
generated
vendored
Normal file
83
node_modules/@redis/client/dist/lib/client/parser.js
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.BasicCommandParser = void 0;
|
||||
class BasicCommandParser {
|
||||
#redisArgs = [];
|
||||
#keys = [];
|
||||
preserve;
|
||||
get redisArgs() {
|
||||
return this.#redisArgs;
|
||||
}
|
||||
get keys() {
|
||||
return this.#keys;
|
||||
}
|
||||
get firstKey() {
|
||||
return this.#keys[0];
|
||||
}
|
||||
get cacheKey() {
|
||||
const tmp = new Array(this.#redisArgs.length * 2);
|
||||
for (let i = 0; i < this.#redisArgs.length; i++) {
|
||||
tmp[i] = this.#redisArgs[i].length;
|
||||
tmp[i + this.#redisArgs.length] = this.#redisArgs[i];
|
||||
}
|
||||
return tmp.join('_');
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.BasicCommandParser = BasicCommandParser;
|
||||
//# sourceMappingURL=parser.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/parser.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/parser.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../../lib/client/parser.ts"],"names":[],"mappings":"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"}
|
||||
138
node_modules/@redis/client/dist/lib/client/pool.d.ts
generated
vendored
Normal file
138
node_modules/@redis/client/dist/lib/client/pool.d.ts
generated
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { RedisArgument, RedisFunctions, RedisModules, RedisScripts, RespVersions, TypeMapping } from '../RESP/types';
|
||||
import { RedisClientType, RedisClientOptions, RedisClientExtensions } from '.';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import { CommandOptions } from './commands-queue';
|
||||
import { RedisClientMultiCommandType } from './multi-command';
|
||||
import { ClientSideCacheConfig, PooledClientSideCacheProvider } from './cache';
|
||||
import { MULTI_MODE, MultiMode } from '../multi-command';
|
||||
export interface RedisPoolOptions {
|
||||
/**
|
||||
* The minimum number of clients to keep in the pool (>= 1).
|
||||
*/
|
||||
minimum: number;
|
||||
/**
|
||||
* The maximum number of clients to keep in the pool (>= {@link RedisPoolOptions.minimum} >= 1).
|
||||
*/
|
||||
maximum: number;
|
||||
/**
|
||||
* The maximum time a task can wait for a client to become available (>= 0).
|
||||
*/
|
||||
acquireTimeout: number;
|
||||
/**
|
||||
* The delay in milliseconds before a cleanup operation is performed on idle clients.
|
||||
*
|
||||
* After this delay, the pool will check if there are too many idle clients and destroy
|
||||
* excess ones to maintain optimal pool size.
|
||||
*/
|
||||
cleanupDelay: number;
|
||||
/**
|
||||
* Client Side Caching configuration for the pool.
|
||||
*
|
||||
* Enables Redis Servers and Clients to work together to cache results from commands
|
||||
* sent to a server. The server will notify the client when cached results are no longer valid.
|
||||
* In pooled mode, the cache is shared across all clients in the pool.
|
||||
*
|
||||
* Note: Client Side Caching is only supported with RESP3.
|
||||
*
|
||||
* @example Anonymous cache configuration
|
||||
* ```
|
||||
* const client = createClientPool({RESP: 3}, {
|
||||
* clientSideCache: {
|
||||
* ttl: 0,
|
||||
* maxEntries: 0,
|
||||
* evictPolicy: "LRU"
|
||||
* },
|
||||
* minimum: 5
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example Using a controllable cache
|
||||
* ```
|
||||
* const cache = new BasicPooledClientSideCache({
|
||||
* ttl: 0,
|
||||
* maxEntries: 0,
|
||||
* evictPolicy: "LRU"
|
||||
* });
|
||||
* const client = createClientPool({RESP: 3}, {
|
||||
* clientSideCache: cache,
|
||||
* minimum: 5
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
clientSideCache?: PooledClientSideCacheProvider | ClientSideCacheConfig;
|
||||
/**
|
||||
* Enable experimental support for RESP3 module commands.
|
||||
*
|
||||
* When enabled, allows the use of module commands that have been adapted
|
||||
* for the RESP3 protocol. This is an unstable feature and may change in
|
||||
* future versions.
|
||||
*
|
||||
* @default false
|
||||
*/
|
||||
unstableResp3Modules?: boolean;
|
||||
}
|
||||
export type PoolTask<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping, T = unknown> = (client: RedisClientType<M, F, S, RESP, TYPE_MAPPING>) => T;
|
||||
export type RedisClientPoolType<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}> = (RedisClientPool<M, F, S, RESP, TYPE_MAPPING> & RedisClientExtensions<M, F, S, RESP, TYPE_MAPPING>);
|
||||
export declare class RedisClientPool<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}> extends EventEmitter {
|
||||
#private;
|
||||
static create<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping = {}>(clientOptions?: Omit<RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>, "clientSideCache">, options?: Partial<RedisPoolOptions>): RedisClientPoolType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
/**
|
||||
* The number of idle clients.
|
||||
*/
|
||||
get idleClients(): number;
|
||||
/**
|
||||
* The number of clients in use.
|
||||
*/
|
||||
get clientsInUse(): number;
|
||||
/**
|
||||
* The total number of clients in the pool (including connecting, idle, and in use).
|
||||
*/
|
||||
get totalClients(): number;
|
||||
/**
|
||||
* The number of tasks waiting for a client to become available.
|
||||
*/
|
||||
get tasksQueueLength(): number;
|
||||
/**
|
||||
* Whether the pool is open (either connecting or connected).
|
||||
*/
|
||||
get isOpen(): boolean;
|
||||
/**
|
||||
* Whether the pool is closing (*not* closed).
|
||||
*/
|
||||
get isClosing(): boolean;
|
||||
get clientSideCache(): PooledClientSideCacheProvider | undefined;
|
||||
/**
|
||||
* You are probably looking for {@link RedisClient.createPool `RedisClient.createPool`},
|
||||
* {@link RedisClientPool.fromClient `RedisClientPool.fromClient`},
|
||||
* or {@link RedisClientPool.fromOptions `RedisClientPool.fromOptions`}...
|
||||
*/
|
||||
constructor(clientOptions?: RedisClientOptions<M, F, S, RESP, TYPE_MAPPING>, options?: Partial<RedisPoolOptions>);
|
||||
private _self;
|
||||
private _commandOptions?;
|
||||
withCommandOptions<OPTIONS extends CommandOptions<TYPE_MAPPING>, TYPE_MAPPING extends TypeMapping>(options: OPTIONS): RedisClientPoolType<M, F, S, RESP, TYPE_MAPPING extends TypeMapping ? TYPE_MAPPING : {}>;
|
||||
/**
|
||||
* Override the `typeMapping` command option
|
||||
*/
|
||||
withTypeMapping<TYPE_MAPPING extends TypeMapping>(typeMapping: TYPE_MAPPING): RedisClientPoolType<M, F, S, RESP, TYPE_MAPPING extends TypeMapping ? TYPE_MAPPING : {}>;
|
||||
/**
|
||||
* Override the `abortSignal` command option
|
||||
*/
|
||||
withAbortSignal(abortSignal: AbortSignal): RedisClientPoolType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
/**
|
||||
* Override the `asap` command option to `true`
|
||||
* TODO: remove?
|
||||
*/
|
||||
asap(): RedisClientPoolType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
connect(): Promise<RedisClientPoolType<M, F, S, RESP, TYPE_MAPPING> | undefined>;
|
||||
execute<T>(fn: PoolTask<M, F, S, RESP, TYPE_MAPPING, T>): Promise<Awaited<T>>;
|
||||
cleanupTimeout?: NodeJS.Timeout;
|
||||
sendCommand(args: Array<RedisArgument>, options?: CommandOptions): Promise<import("../RESP/types").ReplyUnion>;
|
||||
MULTI<isTyped extends MultiMode = MULTI_MODE['TYPED']>(): RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
|
||||
multi: <isTyped extends MultiMode = "typed">() => RedisClientMultiCommandType<isTyped, [], M, F, S, RESP, TYPE_MAPPING>;
|
||||
close(): Promise<void>;
|
||||
destroy(): void;
|
||||
}
|
||||
//# sourceMappingURL=pool.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/pool.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/pool.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pool.d.ts","sourceRoot":"","sources":["../../../lib/client/pool.ts"],"names":[],"mappings":"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"}
|
||||
327
node_modules/@redis/client/dist/lib/client/pool.js
generated
vendored
Normal file
327
node_modules/@redis/client/dist/lib/client/pool.js
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.RedisClientPool = void 0;
|
||||
const commands_1 = __importDefault(require("../commands"));
|
||||
const _1 = __importDefault(require("."));
|
||||
const node_events_1 = require("node:events");
|
||||
const linked_list_1 = require("./linked-list");
|
||||
const errors_1 = require("../errors");
|
||||
const commander_1 = require("../commander");
|
||||
const multi_command_1 = __importDefault(require("./multi-command"));
|
||||
const cache_1 = require("./cache");
|
||||
const parser_1 = require("./parser");
|
||||
const single_entry_cache_1 = __importDefault(require("../single-entry-cache"));
|
||||
class RedisClientPool extends node_events_1.EventEmitter {
|
||||
static #createCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
return this.execute(client => client._executeCommand(command, parser, this._commandOptions, transformReply));
|
||||
};
|
||||
}
|
||||
static #createModuleCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
return this._self.execute(client => client._executeCommand(command, parser, this._self._commandOptions, transformReply));
|
||||
};
|
||||
}
|
||||
static #createFunctionCommand(name, fn, resp) {
|
||||
const prefix = (0, commander_1.functionArgumentsPrefix)(name, fn);
|
||||
const transformReply = (0, commander_1.getTransformReply)(fn, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.push(...prefix);
|
||||
fn.parseCommand(parser, ...args);
|
||||
return this._self.execute(client => client._executeCommand(fn, parser, this._self._commandOptions, transformReply));
|
||||
};
|
||||
}
|
||||
static #createScriptCommand(script, resp) {
|
||||
const prefix = (0, commander_1.scriptArgumentsPrefix)(script);
|
||||
const transformReply = (0, commander_1.getTransformReply)(script, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.pushVariadic(prefix);
|
||||
script.parseCommand(parser, ...args);
|
||||
return this.execute(client => client._executeScript(script, parser, this._commandOptions, transformReply));
|
||||
};
|
||||
}
|
||||
static #SingleEntryCache = new single_entry_cache_1.default();
|
||||
static create(clientOptions, options) {
|
||||
let Pool = RedisClientPool.#SingleEntryCache.get(clientOptions);
|
||||
if (!Pool) {
|
||||
Pool = (0, commander_1.attachConfig)({
|
||||
BaseClass: RedisClientPool,
|
||||
commands: commands_1.default,
|
||||
createCommand: RedisClientPool.#createCommand,
|
||||
createModuleCommand: RedisClientPool.#createModuleCommand,
|
||||
createFunctionCommand: RedisClientPool.#createFunctionCommand,
|
||||
createScriptCommand: RedisClientPool.#createScriptCommand,
|
||||
config: clientOptions
|
||||
});
|
||||
Pool.prototype.Multi = multi_command_1.default.extend(clientOptions);
|
||||
RedisClientPool.#SingleEntryCache.set(clientOptions, Pool);
|
||||
}
|
||||
// returning a "proxy" to prevent the namespaces._self to leak between "proxies"
|
||||
return Object.create(new Pool(clientOptions, options));
|
||||
}
|
||||
// TODO: defaults
|
||||
static #DEFAULTS = {
|
||||
minimum: 1,
|
||||
maximum: 100,
|
||||
acquireTimeout: 3000,
|
||||
cleanupDelay: 3000
|
||||
};
|
||||
#clientFactory;
|
||||
#options;
|
||||
#idleClients = new linked_list_1.SinglyLinkedList();
|
||||
/**
|
||||
* The number of idle clients.
|
||||
*/
|
||||
get idleClients() {
|
||||
return this._self.#idleClients.length;
|
||||
}
|
||||
#clientsInUse = new linked_list_1.DoublyLinkedList();
|
||||
/**
|
||||
* The number of clients in use.
|
||||
*/
|
||||
get clientsInUse() {
|
||||
return this._self.#clientsInUse.length;
|
||||
}
|
||||
/**
|
||||
* The total number of clients in the pool (including connecting, idle, and in use).
|
||||
*/
|
||||
get totalClients() {
|
||||
return this._self.#idleClients.length + this._self.#clientsInUse.length;
|
||||
}
|
||||
#tasksQueue = new linked_list_1.SinglyLinkedList();
|
||||
/**
|
||||
* The number of tasks waiting for a client to become available.
|
||||
*/
|
||||
get tasksQueueLength() {
|
||||
return this._self.#tasksQueue.length;
|
||||
}
|
||||
#isOpen = false;
|
||||
/**
|
||||
* Whether the pool is open (either connecting or connected).
|
||||
*/
|
||||
get isOpen() {
|
||||
return this._self.#isOpen;
|
||||
}
|
||||
#isClosing = false;
|
||||
/**
|
||||
* Whether the pool is closing (*not* closed).
|
||||
*/
|
||||
get isClosing() {
|
||||
return this._self.#isClosing;
|
||||
}
|
||||
#clientSideCache;
|
||||
get clientSideCache() {
|
||||
return this._self.#clientSideCache;
|
||||
}
|
||||
/**
|
||||
* You are probably looking for {@link RedisClient.createPool `RedisClient.createPool`},
|
||||
* {@link RedisClientPool.fromClient `RedisClientPool.fromClient`},
|
||||
* or {@link RedisClientPool.fromOptions `RedisClientPool.fromOptions`}...
|
||||
*/
|
||||
constructor(clientOptions, options) {
|
||||
super();
|
||||
this.#options = {
|
||||
...RedisClientPool.#DEFAULTS,
|
||||
...options
|
||||
};
|
||||
if (options?.clientSideCache) {
|
||||
if (clientOptions === undefined) {
|
||||
clientOptions = {};
|
||||
}
|
||||
if (options.clientSideCache instanceof cache_1.PooledClientSideCacheProvider) {
|
||||
this.#clientSideCache = clientOptions.clientSideCache = options.clientSideCache;
|
||||
}
|
||||
else {
|
||||
const cscConfig = options.clientSideCache;
|
||||
this.#clientSideCache = clientOptions.clientSideCache = new cache_1.BasicPooledClientSideCache(cscConfig);
|
||||
// this.#clientSideCache = clientOptions.clientSideCache = new PooledNoRedirectClientSideCache(cscConfig);
|
||||
}
|
||||
}
|
||||
this.#clientFactory = _1.default.factory(clientOptions).bind(undefined, clientOptions);
|
||||
}
|
||||
_self = this;
|
||||
_commandOptions;
|
||||
withCommandOptions(options) {
|
||||
const proxy = Object.create(this._self);
|
||||
proxy._commandOptions = options;
|
||||
return proxy;
|
||||
}
|
||||
#commandOptionsProxy(key, value) {
|
||||
const proxy = Object.create(this._self);
|
||||
proxy._commandOptions = Object.create(this._commandOptions ?? null);
|
||||
proxy._commandOptions[key] = value;
|
||||
return proxy;
|
||||
}
|
||||
/**
|
||||
* Override the `typeMapping` command option
|
||||
*/
|
||||
withTypeMapping(typeMapping) {
|
||||
return this._self.#commandOptionsProxy('typeMapping', typeMapping);
|
||||
}
|
||||
/**
|
||||
* Override the `abortSignal` command option
|
||||
*/
|
||||
withAbortSignal(abortSignal) {
|
||||
return this._self.#commandOptionsProxy('abortSignal', abortSignal);
|
||||
}
|
||||
/**
|
||||
* Override the `asap` command option to `true`
|
||||
* TODO: remove?
|
||||
*/
|
||||
asap() {
|
||||
return this._self.#commandOptionsProxy('asap', true);
|
||||
}
|
||||
async connect() {
|
||||
if (this._self.#isOpen)
|
||||
return; // TODO: throw error?
|
||||
this._self.#isOpen = true;
|
||||
const promises = [];
|
||||
while (promises.length < this._self.#options.minimum) {
|
||||
promises.push(this._self.#create());
|
||||
}
|
||||
try {
|
||||
await Promise.all(promises);
|
||||
}
|
||||
catch (err) {
|
||||
this.destroy();
|
||||
throw err;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
async #create() {
|
||||
const node = this._self.#clientsInUse.push(this._self.#clientFactory()
|
||||
.on('error', (err) => this.emit('error', err)));
|
||||
try {
|
||||
const client = node.value;
|
||||
await client.connect();
|
||||
}
|
||||
catch (err) {
|
||||
this._self.#clientsInUse.remove(node);
|
||||
throw err;
|
||||
}
|
||||
this._self.#returnClient(node);
|
||||
}
|
||||
execute(fn) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const client = this._self.#idleClients.shift(), { tail } = this._self.#tasksQueue;
|
||||
if (!client) {
|
||||
let timeout;
|
||||
if (this._self.#options.acquireTimeout > 0) {
|
||||
timeout = setTimeout(() => {
|
||||
this._self.#tasksQueue.remove(task, tail);
|
||||
reject(new errors_1.TimeoutError('Timeout waiting for a client')); // TODO: message
|
||||
}, this._self.#options.acquireTimeout);
|
||||
}
|
||||
const task = this._self.#tasksQueue.push({
|
||||
timeout,
|
||||
// @ts-ignore
|
||||
resolve,
|
||||
reject,
|
||||
fn
|
||||
});
|
||||
if (this.totalClients < this._self.#options.maximum) {
|
||||
this._self.#create();
|
||||
}
|
||||
return;
|
||||
}
|
||||
const node = this._self.#clientsInUse.push(client);
|
||||
// @ts-ignore
|
||||
this._self.#executeTask(node, resolve, reject, fn);
|
||||
});
|
||||
}
|
||||
#executeTask(node, resolve, reject, fn) {
|
||||
const result = fn(node.value);
|
||||
if (result instanceof Promise) {
|
||||
result
|
||||
.then(resolve, reject)
|
||||
.finally(() => this.#returnClient(node));
|
||||
}
|
||||
else {
|
||||
resolve(result);
|
||||
this.#returnClient(node);
|
||||
}
|
||||
}
|
||||
#returnClient(node) {
|
||||
const task = this.#tasksQueue.shift();
|
||||
if (task) {
|
||||
clearTimeout(task.timeout);
|
||||
this.#executeTask(node, task.resolve, task.reject, task.fn);
|
||||
return;
|
||||
}
|
||||
this.#clientsInUse.remove(node);
|
||||
this.#idleClients.push(node.value);
|
||||
this.#scheduleCleanup();
|
||||
}
|
||||
cleanupTimeout;
|
||||
#scheduleCleanup() {
|
||||
if (this.totalClients <= this.#options.minimum)
|
||||
return;
|
||||
clearTimeout(this.cleanupTimeout);
|
||||
this.cleanupTimeout = setTimeout(() => this.#cleanup(), this.#options.cleanupDelay);
|
||||
}
|
||||
#cleanup() {
|
||||
const toDestroy = Math.min(this.#idleClients.length, this.totalClients - this.#options.minimum);
|
||||
for (let i = 0; i < toDestroy; i++) {
|
||||
// TODO: shift vs pop
|
||||
const client = this.#idleClients.shift();
|
||||
client.destroy();
|
||||
}
|
||||
}
|
||||
sendCommand(args, options) {
|
||||
return this.execute(client => client.sendCommand(args, options));
|
||||
}
|
||||
MULTI() {
|
||||
return new this.Multi((commands, selectedDB) => this.execute(client => client._executeMulti(commands, selectedDB)), commands => this.execute(client => client._executePipeline(commands)), this._commandOptions?.typeMapping);
|
||||
}
|
||||
multi = this.MULTI;
|
||||
async close() {
|
||||
if (this._self.#isClosing)
|
||||
return; // TODO: throw err?
|
||||
if (!this._self.#isOpen)
|
||||
return; // TODO: throw err?
|
||||
this._self.#isClosing = true;
|
||||
try {
|
||||
const promises = [];
|
||||
for (const client of this._self.#idleClients) {
|
||||
promises.push(client.close());
|
||||
}
|
||||
for (const client of this._self.#clientsInUse) {
|
||||
promises.push(client.close());
|
||||
}
|
||||
await Promise.all(promises);
|
||||
this.#clientSideCache?.onPoolClose();
|
||||
this._self.#idleClients.reset();
|
||||
this._self.#clientsInUse.reset();
|
||||
}
|
||||
catch (err) {
|
||||
}
|
||||
finally {
|
||||
this._self.#isClosing = false;
|
||||
}
|
||||
}
|
||||
destroy() {
|
||||
for (const client of this._self.#idleClients) {
|
||||
client.destroy();
|
||||
}
|
||||
this._self.#idleClients.reset();
|
||||
for (const client of this._self.#clientsInUse) {
|
||||
client.destroy();
|
||||
}
|
||||
this._self.#clientSideCache?.onPoolClose();
|
||||
this._self.#clientsInUse.reset();
|
||||
this._self.#isOpen = false;
|
||||
}
|
||||
}
|
||||
exports.RedisClientPool = RedisClientPool;
|
||||
//# sourceMappingURL=pool.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/pool.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/pool.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
62
node_modules/@redis/client/dist/lib/client/pub-sub.d.ts
generated
vendored
Normal file
62
node_modules/@redis/client/dist/lib/client/pub-sub.d.ts
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/// <reference types="node" />
|
||||
import { RedisArgument } from '../RESP/types';
|
||||
import { CommandToWrite } from './commands-queue';
|
||||
export declare const PUBSUB_TYPE: {
|
||||
readonly CHANNELS: "CHANNELS";
|
||||
readonly PATTERNS: "PATTERNS";
|
||||
readonly SHARDED: "SHARDED";
|
||||
};
|
||||
export type PUBSUB_TYPE = typeof PUBSUB_TYPE;
|
||||
export type PubSubType = PUBSUB_TYPE[keyof PUBSUB_TYPE];
|
||||
export type PubSubListener<RETURN_BUFFERS extends boolean = false> = <T extends RETURN_BUFFERS extends true ? Buffer : string>(message: T, channel: T) => unknown;
|
||||
export interface ChannelListeners {
|
||||
unsubscribing: boolean;
|
||||
buffers: Set<PubSubListener<true>>;
|
||||
strings: Set<PubSubListener<false>>;
|
||||
}
|
||||
export type PubSubTypeListeners = Map<string, ChannelListeners>;
|
||||
export type PubSubListeners = Record<PubSubType, PubSubTypeListeners>;
|
||||
export type PubSubCommand = (Required<Pick<CommandToWrite, 'args' | 'channelsCounter' | 'resolve'>> & {
|
||||
reject: undefined | (() => unknown);
|
||||
});
|
||||
export declare class PubSub {
|
||||
#private;
|
||||
static isStatusReply(reply: Array<Buffer>): boolean;
|
||||
static isShardedUnsubscribe(reply: Array<Buffer>): boolean;
|
||||
get isActive(): boolean;
|
||||
readonly listeners: PubSubListeners;
|
||||
subscribe<T extends boolean>(type: PubSubType, channels: string | Array<string>, listener: PubSubListener<T>, returnBuffers?: T): {
|
||||
args: RedisArgument[];
|
||||
channelsCounter: number;
|
||||
resolve: () => void;
|
||||
reject: () => void;
|
||||
} | undefined;
|
||||
extendChannelListeners(type: PubSubType, channel: string, listeners: ChannelListeners): {
|
||||
args: (string | Buffer)[];
|
||||
channelsCounter: number;
|
||||
resolve: () => number;
|
||||
reject: () => void;
|
||||
} | undefined;
|
||||
extendTypeListeners(type: PubSubType, listeners: PubSubTypeListeners): {
|
||||
args: RedisArgument[];
|
||||
channelsCounter: number;
|
||||
resolve: () => number;
|
||||
reject: () => void;
|
||||
} | undefined;
|
||||
unsubscribe<T extends boolean>(type: PubSubType, channels?: string | Array<string>, listener?: PubSubListener<T>, returnBuffers?: T): {
|
||||
args: RedisArgument[];
|
||||
channelsCounter: number;
|
||||
resolve: () => void;
|
||||
reject: undefined;
|
||||
} | undefined;
|
||||
reset(): void;
|
||||
resubscribe(): PubSubCommand[];
|
||||
handleMessageReply(reply: Array<Buffer>): boolean;
|
||||
removeShardedListeners(channel: string): ChannelListeners;
|
||||
removeAllListeners(): {
|
||||
CHANNELS: PubSubTypeListeners;
|
||||
PATTERNS: PubSubTypeListeners;
|
||||
SHARDED: PubSubTypeListeners;
|
||||
};
|
||||
}
|
||||
//# sourceMappingURL=pub-sub.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/pub-sub.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/pub-sub.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"pub-sub.d.ts","sourceRoot":"","sources":["../../../lib/client/pub-sub.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,eAAO,MAAM,WAAW;;;;CAId,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,OAAO,WAAW,CAAC;AAE7C,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC,MAAM,WAAW,CAAC,CAAC;AAoBxD,MAAM,MAAM,cAAc,CACxB,cAAc,SAAS,OAAO,GAAG,KAAK,IACpC,CAAC,CAAC,SAAS,cAAc,SAAS,IAAI,GAAG,MAAM,GAAG,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,KAAK,OAAO,CAAC;AAEjG,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,OAAO,EAAE,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;IACnC,OAAO,EAAE,GAAG,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;CACrC;AAED,MAAM,MAAM,mBAAmB,GAAG,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;AAEhE,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,UAAU,EAAE,mBAAmB,CAAC,CAAC;AAEtE,MAAM,MAAM,aAAa,GAAG,CAC1B,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,iBAAiB,GAAG,SAAS,CAAC,CAAC,GAAG;IACvE,MAAM,EAAE,SAAS,GAAG,CAAC,MAAM,OAAO,CAAC,CAAC;CACrC,CACF,CAAC;AAEF,qBAAa,MAAM;;IACjB,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO;IAUnD,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO;IAmB1D,IAAI,QAAQ,YAEX;IAED,QAAQ,CAAC,SAAS,EAAE,eAAe,CAIjC;IAEF,SAAS,CAAC,CAAC,SAAS,OAAO,EACzB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,EAChC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,EAC3B,aAAa,CAAC,EAAE,CAAC;;;;;;IAkDnB,sBAAsB,CACpB,IAAI,EAAE,UAAU,EAChB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,gBAAgB;;;;;;IA0C7B,mBAAmB,CAAC,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,mBAAmB;;;;;;IAuBpE,WAAW,CAAC,CAAC,SAAS,OAAO,EAC3B,IAAI,EAAE,UAAU,EAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,EACjC,QAAQ,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,EAC5B,aAAa,CAAC,EAAE,CAAC;;;;;;IAsGnB,KAAK;IAKL,WAAW;IA+CX,kBAAkB,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,GAAG,OAAO;IA4BjD,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB;IAOzD,kBAAkB;;;;;CA2CnB"}
|
||||
320
node_modules/@redis/client/dist/lib/client/pub-sub.js
generated
vendored
Normal file
320
node_modules/@redis/client/dist/lib/client/pub-sub.js
generated
vendored
Normal file
@@ -0,0 +1,320 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.PubSub = exports.PUBSUB_TYPE = void 0;
|
||||
exports.PUBSUB_TYPE = {
|
||||
CHANNELS: 'CHANNELS',
|
||||
PATTERNS: 'PATTERNS',
|
||||
SHARDED: 'SHARDED'
|
||||
};
|
||||
const COMMANDS = {
|
||||
[exports.PUBSUB_TYPE.CHANNELS]: {
|
||||
subscribe: Buffer.from('subscribe'),
|
||||
unsubscribe: Buffer.from('unsubscribe'),
|
||||
message: Buffer.from('message')
|
||||
},
|
||||
[exports.PUBSUB_TYPE.PATTERNS]: {
|
||||
subscribe: Buffer.from('psubscribe'),
|
||||
unsubscribe: Buffer.from('punsubscribe'),
|
||||
message: Buffer.from('pmessage')
|
||||
},
|
||||
[exports.PUBSUB_TYPE.SHARDED]: {
|
||||
subscribe: Buffer.from('ssubscribe'),
|
||||
unsubscribe: Buffer.from('sunsubscribe'),
|
||||
message: Buffer.from('smessage')
|
||||
}
|
||||
};
|
||||
class PubSub {
|
||||
static isStatusReply(reply) {
|
||||
return (COMMANDS[exports.PUBSUB_TYPE.CHANNELS].subscribe.equals(reply[0]) ||
|
||||
COMMANDS[exports.PUBSUB_TYPE.CHANNELS].unsubscribe.equals(reply[0]) ||
|
||||
COMMANDS[exports.PUBSUB_TYPE.PATTERNS].subscribe.equals(reply[0]) ||
|
||||
COMMANDS[exports.PUBSUB_TYPE.PATTERNS].unsubscribe.equals(reply[0]) ||
|
||||
COMMANDS[exports.PUBSUB_TYPE.SHARDED].subscribe.equals(reply[0]));
|
||||
}
|
||||
static isShardedUnsubscribe(reply) {
|
||||
return COMMANDS[exports.PUBSUB_TYPE.SHARDED].unsubscribe.equals(reply[0]);
|
||||
}
|
||||
static #channelsArray(channels) {
|
||||
return (Array.isArray(channels) ? channels : [channels]);
|
||||
}
|
||||
static #listenersSet(listeners, returnBuffers) {
|
||||
return (returnBuffers ? listeners.buffers : listeners.strings);
|
||||
}
|
||||
#subscribing = 0;
|
||||
#isActive = false;
|
||||
get isActive() {
|
||||
return this.#isActive;
|
||||
}
|
||||
listeners = {
|
||||
[exports.PUBSUB_TYPE.CHANNELS]: new Map(),
|
||||
[exports.PUBSUB_TYPE.PATTERNS]: new Map(),
|
||||
[exports.PUBSUB_TYPE.SHARDED]: new Map()
|
||||
};
|
||||
subscribe(type, channels, listener, returnBuffers) {
|
||||
const args = [COMMANDS[type].subscribe], channelsArray = PubSub.#channelsArray(channels);
|
||||
for (const channel of channelsArray) {
|
||||
let channelListeners = this.listeners[type].get(channel);
|
||||
if (!channelListeners || channelListeners.unsubscribing) {
|
||||
args.push(channel);
|
||||
}
|
||||
}
|
||||
if (args.length === 1) {
|
||||
// all channels are already subscribed, add listeners without issuing a command
|
||||
for (const channel of channelsArray) {
|
||||
PubSub.#listenersSet(this.listeners[type].get(channel), returnBuffers).add(listener);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this.#isActive = true;
|
||||
this.#subscribing++;
|
||||
return {
|
||||
args,
|
||||
channelsCounter: args.length - 1,
|
||||
resolve: () => {
|
||||
this.#subscribing--;
|
||||
for (const channel of channelsArray) {
|
||||
let listeners = this.listeners[type].get(channel);
|
||||
if (!listeners) {
|
||||
listeners = {
|
||||
unsubscribing: false,
|
||||
buffers: new Set(),
|
||||
strings: new Set()
|
||||
};
|
||||
this.listeners[type].set(channel, listeners);
|
||||
}
|
||||
PubSub.#listenersSet(listeners, returnBuffers).add(listener);
|
||||
}
|
||||
},
|
||||
reject: () => {
|
||||
this.#subscribing--;
|
||||
this.#updateIsActive();
|
||||
}
|
||||
};
|
||||
}
|
||||
extendChannelListeners(type, channel, listeners) {
|
||||
if (!this.#extendChannelListeners(type, channel, listeners))
|
||||
return;
|
||||
this.#isActive = true;
|
||||
this.#subscribing++;
|
||||
return {
|
||||
args: [
|
||||
COMMANDS[type].subscribe,
|
||||
channel
|
||||
],
|
||||
channelsCounter: 1,
|
||||
resolve: () => this.#subscribing--,
|
||||
reject: () => {
|
||||
this.#subscribing--;
|
||||
this.#updateIsActive();
|
||||
}
|
||||
};
|
||||
}
|
||||
#extendChannelListeners(type, channel, listeners) {
|
||||
const existingListeners = this.listeners[type].get(channel);
|
||||
if (!existingListeners) {
|
||||
this.listeners[type].set(channel, listeners);
|
||||
return true;
|
||||
}
|
||||
for (const listener of listeners.buffers) {
|
||||
existingListeners.buffers.add(listener);
|
||||
}
|
||||
for (const listener of listeners.strings) {
|
||||
existingListeners.strings.add(listener);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
extendTypeListeners(type, listeners) {
|
||||
const args = [COMMANDS[type].subscribe];
|
||||
for (const [channel, channelListeners] of listeners) {
|
||||
if (this.#extendChannelListeners(type, channel, channelListeners)) {
|
||||
args.push(channel);
|
||||
}
|
||||
}
|
||||
if (args.length === 1)
|
||||
return;
|
||||
this.#isActive = true;
|
||||
this.#subscribing++;
|
||||
return {
|
||||
args,
|
||||
channelsCounter: args.length - 1,
|
||||
resolve: () => this.#subscribing--,
|
||||
reject: () => {
|
||||
this.#subscribing--;
|
||||
this.#updateIsActive();
|
||||
}
|
||||
};
|
||||
}
|
||||
unsubscribe(type, channels, listener, returnBuffers) {
|
||||
const listeners = this.listeners[type];
|
||||
if (!channels) {
|
||||
return this.#unsubscribeCommand([COMMANDS[type].unsubscribe],
|
||||
// cannot use `this.#subscribed` because there might be some `SUBSCRIBE` commands in the queue
|
||||
// cannot use `this.#subscribed + this.#subscribing` because some `SUBSCRIBE` commands might fail
|
||||
NaN, () => listeners.clear());
|
||||
}
|
||||
const channelsArray = PubSub.#channelsArray(channels);
|
||||
if (!listener) {
|
||||
return this.#unsubscribeCommand([COMMANDS[type].unsubscribe, ...channelsArray], channelsArray.length, () => {
|
||||
for (const channel of channelsArray) {
|
||||
listeners.delete(channel);
|
||||
}
|
||||
});
|
||||
}
|
||||
const args = [COMMANDS[type].unsubscribe];
|
||||
for (const channel of channelsArray) {
|
||||
const sets = listeners.get(channel);
|
||||
if (sets) {
|
||||
let current, other;
|
||||
if (returnBuffers) {
|
||||
current = sets.buffers;
|
||||
other = sets.strings;
|
||||
}
|
||||
else {
|
||||
current = sets.strings;
|
||||
other = sets.buffers;
|
||||
}
|
||||
const currentSize = current.has(listener) ? current.size - 1 : current.size;
|
||||
if (currentSize !== 0 || other.size !== 0)
|
||||
continue;
|
||||
sets.unsubscribing = true;
|
||||
}
|
||||
args.push(channel);
|
||||
}
|
||||
if (args.length === 1) {
|
||||
// all channels has other listeners,
|
||||
// delete the listeners without issuing a command
|
||||
for (const channel of channelsArray) {
|
||||
PubSub.#listenersSet(listeners.get(channel), returnBuffers).delete(listener);
|
||||
}
|
||||
return;
|
||||
}
|
||||
return this.#unsubscribeCommand(args, args.length - 1, () => {
|
||||
for (const channel of channelsArray) {
|
||||
const sets = listeners.get(channel);
|
||||
if (!sets)
|
||||
continue;
|
||||
(returnBuffers ? sets.buffers : sets.strings).delete(listener);
|
||||
if (sets.buffers.size === 0 && sets.strings.size === 0) {
|
||||
listeners.delete(channel);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
#unsubscribeCommand(args, channelsCounter, removeListeners) {
|
||||
return {
|
||||
args,
|
||||
channelsCounter,
|
||||
resolve: () => {
|
||||
removeListeners();
|
||||
this.#updateIsActive();
|
||||
},
|
||||
reject: undefined
|
||||
};
|
||||
}
|
||||
#updateIsActive() {
|
||||
this.#isActive = (this.listeners[exports.PUBSUB_TYPE.CHANNELS].size !== 0 ||
|
||||
this.listeners[exports.PUBSUB_TYPE.PATTERNS].size !== 0 ||
|
||||
this.listeners[exports.PUBSUB_TYPE.SHARDED].size !== 0 ||
|
||||
this.#subscribing !== 0);
|
||||
}
|
||||
reset() {
|
||||
this.#isActive = false;
|
||||
this.#subscribing = 0;
|
||||
}
|
||||
resubscribe() {
|
||||
const commands = [];
|
||||
for (const [type, listeners] of Object.entries(this.listeners)) {
|
||||
if (!listeners.size)
|
||||
continue;
|
||||
this.#isActive = true;
|
||||
if (type === exports.PUBSUB_TYPE.SHARDED) {
|
||||
this.#shardedResubscribe(commands, listeners);
|
||||
}
|
||||
else {
|
||||
this.#normalResubscribe(commands, type, listeners);
|
||||
}
|
||||
}
|
||||
return commands;
|
||||
}
|
||||
#normalResubscribe(commands, type, listeners) {
|
||||
this.#subscribing++;
|
||||
const callback = () => this.#subscribing--;
|
||||
commands.push({
|
||||
args: [
|
||||
COMMANDS[type].subscribe,
|
||||
...listeners.keys()
|
||||
],
|
||||
channelsCounter: listeners.size,
|
||||
resolve: callback,
|
||||
reject: callback
|
||||
});
|
||||
}
|
||||
#shardedResubscribe(commands, listeners) {
|
||||
const callback = () => this.#subscribing--;
|
||||
for (const channel of listeners.keys()) {
|
||||
this.#subscribing++;
|
||||
commands.push({
|
||||
args: [
|
||||
COMMANDS[exports.PUBSUB_TYPE.SHARDED].subscribe,
|
||||
channel
|
||||
],
|
||||
channelsCounter: 1,
|
||||
resolve: callback,
|
||||
reject: callback
|
||||
});
|
||||
}
|
||||
}
|
||||
handleMessageReply(reply) {
|
||||
if (COMMANDS[exports.PUBSUB_TYPE.CHANNELS].message.equals(reply[0])) {
|
||||
this.#emitPubSubMessage(exports.PUBSUB_TYPE.CHANNELS, reply[2], reply[1]);
|
||||
return true;
|
||||
}
|
||||
else if (COMMANDS[exports.PUBSUB_TYPE.PATTERNS].message.equals(reply[0])) {
|
||||
this.#emitPubSubMessage(exports.PUBSUB_TYPE.PATTERNS, reply[3], reply[2], reply[1]);
|
||||
return true;
|
||||
}
|
||||
else if (COMMANDS[exports.PUBSUB_TYPE.SHARDED].message.equals(reply[0])) {
|
||||
this.#emitPubSubMessage(exports.PUBSUB_TYPE.SHARDED, reply[2], reply[1]);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
removeShardedListeners(channel) {
|
||||
const listeners = this.listeners[exports.PUBSUB_TYPE.SHARDED].get(channel);
|
||||
this.listeners[exports.PUBSUB_TYPE.SHARDED].delete(channel);
|
||||
this.#updateIsActive();
|
||||
return listeners;
|
||||
}
|
||||
removeAllListeners() {
|
||||
const result = {
|
||||
[exports.PUBSUB_TYPE.CHANNELS]: this.listeners[exports.PUBSUB_TYPE.CHANNELS],
|
||||
[exports.PUBSUB_TYPE.PATTERNS]: this.listeners[exports.PUBSUB_TYPE.PATTERNS],
|
||||
[exports.PUBSUB_TYPE.SHARDED]: this.listeners[exports.PUBSUB_TYPE.SHARDED]
|
||||
};
|
||||
this.#updateIsActive();
|
||||
this.listeners[exports.PUBSUB_TYPE.CHANNELS] = new Map();
|
||||
this.listeners[exports.PUBSUB_TYPE.PATTERNS] = new Map();
|
||||
this.listeners[exports.PUBSUB_TYPE.SHARDED] = new Map();
|
||||
return result;
|
||||
}
|
||||
#emitPubSubMessage(type, message, channel, pattern) {
|
||||
const keyString = (pattern ?? channel).toString(), listeners = this.listeners[type].get(keyString);
|
||||
if (!listeners)
|
||||
return;
|
||||
for (const listener of listeners.buffers) {
|
||||
listener(message, channel);
|
||||
}
|
||||
if (!listeners.strings.size)
|
||||
return;
|
||||
const channelString = pattern ? channel.toString() : keyString, messageString = channelString === '__redis__:invalidate' ?
|
||||
// https://github.com/redis/redis/pull/7469
|
||||
// https://github.com/redis/redis/issues/7463
|
||||
(message === null ? null : message.map(x => x.toString())) :
|
||||
message.toString();
|
||||
for (const listener of listeners.strings) {
|
||||
listener(messageString, channelString);
|
||||
}
|
||||
}
|
||||
}
|
||||
exports.PubSub = PubSub;
|
||||
//# sourceMappingURL=pub-sub.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/pub-sub.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/pub-sub.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
59
node_modules/@redis/client/dist/lib/client/socket.d.ts
generated
vendored
Normal file
59
node_modules/@redis/client/dist/lib/client/socket.d.ts
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { EventEmitter } from 'node:events';
|
||||
import net from 'node:net';
|
||||
import tls from 'node:tls';
|
||||
import { RedisArgument } from '../RESP/types';
|
||||
type NetOptions = {
|
||||
tls?: false;
|
||||
};
|
||||
type ReconnectStrategyFunction = (retries: number, cause: Error) => false | Error | number;
|
||||
type RedisSocketOptionsCommon = {
|
||||
/**
|
||||
* Connection timeout (in milliseconds)
|
||||
*/
|
||||
connectTimeout?: number;
|
||||
/**
|
||||
* When the socket closes unexpectedly (without calling `.close()`/`.destroy()`), the client uses `reconnectStrategy` to decide what to do. The following values are supported:
|
||||
* 1. `false` -> do not reconnect, close the client and flush the command queue.
|
||||
* 2. `number` -> wait for `X` milliseconds before reconnecting.
|
||||
* 3. `(retries: number, cause: Error) => false | number | Error` -> `number` is the same as configuring a `number` directly, `Error` is the same as `false`, but with a custom error.
|
||||
*/
|
||||
reconnectStrategy?: false | number | ReconnectStrategyFunction;
|
||||
/**
|
||||
* The timeout (in milliseconds) after which the socket will be closed. `undefined` means no timeout.
|
||||
*/
|
||||
socketTimeout?: number;
|
||||
};
|
||||
type RedisTcpOptions = RedisSocketOptionsCommon & NetOptions & Omit<net.TcpNetConnectOpts, 'timeout' | 'onread' | 'readable' | 'writable' | 'port'> & {
|
||||
port?: number;
|
||||
};
|
||||
type RedisTlsOptions = RedisSocketOptionsCommon & tls.ConnectionOptions & {
|
||||
tls: true;
|
||||
};
|
||||
type RedisIpcOptions = RedisSocketOptionsCommon & Omit<net.IpcNetConnectOpts, 'timeout' | 'onread' | 'readable' | 'writable'> & {
|
||||
tls: false;
|
||||
};
|
||||
export type RedisTcpSocketOptions = RedisTcpOptions | RedisTlsOptions;
|
||||
export type RedisSocketOptions = RedisTcpSocketOptions | RedisIpcOptions;
|
||||
export type RedisSocketInitiator = () => void | Promise<unknown>;
|
||||
export default class RedisSocket extends EventEmitter {
|
||||
#private;
|
||||
get isOpen(): boolean;
|
||||
get isReady(): boolean;
|
||||
get socketEpoch(): number;
|
||||
constructor(initiator: RedisSocketInitiator, options?: RedisSocketOptions);
|
||||
connect(): Promise<void>;
|
||||
setMaintenanceTimeout(ms?: number): void;
|
||||
write(iterable: Iterable<ReadonlyArray<RedisArgument>>): void;
|
||||
quit<T>(fn: () => Promise<T>): Promise<T>;
|
||||
close(): void;
|
||||
destroy(): void;
|
||||
destroySocket(): void;
|
||||
ref(): void;
|
||||
unref(): void;
|
||||
defaultReconnectStrategy(retries: number, cause: unknown): number | false;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=socket.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/client/socket.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/socket.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"socket.d.ts","sourceRoot":"","sources":["../../../lib/client/socket.ts"],"names":[],"mappings":";;;AAAA,OAAO,EAAE,YAAY,EAAQ,MAAM,aAAa,CAAC;AACjD,OAAO,GAAG,MAAM,UAAU,CAAC;AAC3B,OAAO,GAAG,MAAM,UAAU,CAAC;AAG3B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,KAAK,UAAU,GAAG;IAChB,GAAG,CAAC,EAAE,KAAK,CAAC;CACb,CAAC;AAEF,KAAK,yBAAyB,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;AAE3F,KAAK,wBAAwB,GAAG;IAC9B;;OAEG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,iBAAiB,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,yBAAyB,CAAC;IAC/D;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAA;AAED,KAAK,eAAe,GAAG,wBAAwB,GAAG,UAAU,GAAG,IAAI,CACjE,GAAG,CAAC,iBAAiB,EACrB,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CACxD,GAAG;IACF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,eAAe,GAAG,wBAAwB,GAAG,GAAG,CAAC,iBAAiB,GAAG;IACxE,GAAG,EAAE,IAAI,CAAC;CACX,CAAA;AAED,KAAK,eAAe,GAAG,wBAAwB,GAAG,IAAI,CACpD,GAAG,CAAC,iBAAiB,EACrB,SAAS,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,CAC/C,GAAG;IACF,GAAG,EAAE,KAAK,CAAC;CACZ,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,eAAe,CAAC;AAEtE,MAAM,MAAM,kBAAkB,GAAG,qBAAqB,GAAG,eAAe,CAAC;AAEzE,MAAM,MAAM,oBAAoB,GAAG,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;AAEjE,MAAM,CAAC,OAAO,OAAO,WAAY,SAAQ,YAAY;;IAanD,IAAI,MAAM,YAET;IAID,IAAI,OAAO,YAEV;IAMD,IAAI,WAAW,WAEd;gBAEW,SAAS,EAAE,oBAAoB,EAAE,OAAO,CAAC,EAAE,kBAAkB;IAqHnE,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAuC9B,qBAAqB,CAAC,EAAE,CAAC,EAAE,MAAM;IAuEjC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;IAchD,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAW/C,KAAK;IAQL,OAAO;IASP,aAAa;IAWb,GAAG;IAKH,KAAK;IAKL,wBAAwB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO;CAazD"}
|
||||
303
node_modules/@redis/client/dist/lib/client/socket.js
generated
vendored
Normal file
303
node_modules/@redis/client/dist/lib/client/socket.js
generated
vendored
Normal file
@@ -0,0 +1,303 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const node_events_1 = require("node:events");
|
||||
const node_net_1 = __importDefault(require("node:net"));
|
||||
const node_tls_1 = __importDefault(require("node:tls"));
|
||||
const errors_1 = require("../errors");
|
||||
const promises_1 = require("node:timers/promises");
|
||||
const enterprise_maintenance_manager_1 = require("./enterprise-maintenance-manager");
|
||||
class RedisSocket extends node_events_1.EventEmitter {
|
||||
#initiator;
|
||||
#connectTimeout;
|
||||
#reconnectStrategy;
|
||||
#socketFactory;
|
||||
#socketTimeout;
|
||||
#maintenanceTimeout;
|
||||
#socket;
|
||||
#isOpen = false;
|
||||
get isOpen() {
|
||||
return this.#isOpen;
|
||||
}
|
||||
#isReady = false;
|
||||
get isReady() {
|
||||
return this.#isReady;
|
||||
}
|
||||
#isSocketUnrefed = false;
|
||||
#socketEpoch = 0;
|
||||
get socketEpoch() {
|
||||
return this.#socketEpoch;
|
||||
}
|
||||
constructor(initiator, options) {
|
||||
super();
|
||||
this.#initiator = initiator;
|
||||
this.#connectTimeout = options?.connectTimeout ?? 5000;
|
||||
this.#reconnectStrategy = this.#createReconnectStrategy(options);
|
||||
this.#socketFactory = this.#createSocketFactory(options);
|
||||
this.#socketTimeout = options?.socketTimeout;
|
||||
}
|
||||
#createReconnectStrategy(options) {
|
||||
const strategy = options?.reconnectStrategy;
|
||||
if (strategy === false || typeof strategy === 'number') {
|
||||
return () => strategy;
|
||||
}
|
||||
if (strategy) {
|
||||
return (retries, cause) => {
|
||||
try {
|
||||
const retryIn = strategy(retries, cause);
|
||||
if (retryIn !== false && !(retryIn instanceof Error) && typeof retryIn !== 'number') {
|
||||
throw new TypeError(`Reconnect strategy should return \`false | Error | number\`, got ${retryIn} instead`);
|
||||
}
|
||||
return retryIn;
|
||||
}
|
||||
catch (err) {
|
||||
this.emit('error', err);
|
||||
return this.defaultReconnectStrategy(retries, err);
|
||||
}
|
||||
};
|
||||
}
|
||||
return this.defaultReconnectStrategy;
|
||||
}
|
||||
#createSocketFactory(options) {
|
||||
// TLS
|
||||
if (options?.tls === true) {
|
||||
const withDefaults = {
|
||||
...options,
|
||||
port: options?.port ?? 6379,
|
||||
// https://nodejs.org/api/tls.html#tlsconnectoptions-callback "Any socket.connect() option not already listed"
|
||||
// @types/node is... incorrect...
|
||||
// @ts-expect-error
|
||||
noDelay: options?.noDelay ?? true,
|
||||
// https://nodejs.org/api/tls.html#tlsconnectoptions-callback "Any socket.connect() option not already listed"
|
||||
// @types/node is... incorrect...
|
||||
// @ts-expect-error
|
||||
keepAlive: options?.keepAlive ?? true,
|
||||
// https://nodejs.org/api/tls.html#tlsconnectoptions-callback "Any socket.connect() option not already listed"
|
||||
// @types/node is... incorrect...
|
||||
// @ts-expect-error
|
||||
keepAliveInitialDelay: options?.keepAliveInitialDelay ?? 5000,
|
||||
timeout: undefined,
|
||||
onread: undefined,
|
||||
readable: true,
|
||||
writable: true
|
||||
};
|
||||
return {
|
||||
create() {
|
||||
return node_tls_1.default.connect(withDefaults);
|
||||
},
|
||||
event: 'secureConnect'
|
||||
};
|
||||
}
|
||||
// IPC
|
||||
if (options && 'path' in options) {
|
||||
const withDefaults = {
|
||||
...options,
|
||||
timeout: undefined,
|
||||
onread: undefined,
|
||||
readable: true,
|
||||
writable: true
|
||||
};
|
||||
return {
|
||||
create() {
|
||||
return node_net_1.default.createConnection(withDefaults);
|
||||
},
|
||||
event: 'connect'
|
||||
};
|
||||
}
|
||||
// TCP
|
||||
const withDefaults = {
|
||||
...options,
|
||||
port: options?.port ?? 6379,
|
||||
noDelay: options?.noDelay ?? true,
|
||||
keepAlive: options?.keepAlive ?? true,
|
||||
keepAliveInitialDelay: options?.keepAliveInitialDelay ?? 5000,
|
||||
timeout: undefined,
|
||||
onread: undefined,
|
||||
readable: true,
|
||||
writable: true
|
||||
};
|
||||
return {
|
||||
create() {
|
||||
return node_net_1.default.createConnection(withDefaults);
|
||||
},
|
||||
event: 'connect'
|
||||
};
|
||||
}
|
||||
#shouldReconnect(retries, cause) {
|
||||
const retryIn = this.#reconnectStrategy(retries, cause);
|
||||
if (retryIn === false) {
|
||||
this.#isOpen = false;
|
||||
this.emit('error', cause);
|
||||
return cause;
|
||||
}
|
||||
else if (retryIn instanceof Error) {
|
||||
this.#isOpen = false;
|
||||
this.emit('error', cause);
|
||||
return new errors_1.ReconnectStrategyError(retryIn, cause);
|
||||
}
|
||||
return retryIn;
|
||||
}
|
||||
async connect() {
|
||||
if (this.#isOpen) {
|
||||
throw new Error('Socket already opened');
|
||||
}
|
||||
this.#isOpen = true;
|
||||
return this.#connect();
|
||||
}
|
||||
async #connect() {
|
||||
let retries = 0;
|
||||
do {
|
||||
try {
|
||||
this.#socket = await this.#createSocket();
|
||||
this.emit('connect');
|
||||
try {
|
||||
await this.#initiator();
|
||||
}
|
||||
catch (err) {
|
||||
this.#socket.destroy();
|
||||
this.#socket = undefined;
|
||||
throw err;
|
||||
}
|
||||
this.#isReady = true;
|
||||
this.#socketEpoch++;
|
||||
this.emit('ready');
|
||||
}
|
||||
catch (err) {
|
||||
const retryIn = this.#shouldReconnect(retries++, err);
|
||||
if (typeof retryIn !== 'number') {
|
||||
throw retryIn;
|
||||
}
|
||||
this.emit('error', err);
|
||||
await (0, promises_1.setTimeout)(retryIn);
|
||||
this.emit('reconnecting');
|
||||
}
|
||||
} while (this.#isOpen && !this.#isReady);
|
||||
}
|
||||
setMaintenanceTimeout(ms) {
|
||||
(0, enterprise_maintenance_manager_1.dbgMaintenance)(`Set socket timeout to ${ms}`);
|
||||
if (this.#maintenanceTimeout === ms) {
|
||||
(0, enterprise_maintenance_manager_1.dbgMaintenance)(`Socket already set maintenanceCommandTimeout to ${ms}, skipping`);
|
||||
return;
|
||||
}
|
||||
;
|
||||
this.#maintenanceTimeout = ms;
|
||||
if (ms !== undefined) {
|
||||
this.#socket?.setTimeout(ms);
|
||||
}
|
||||
else {
|
||||
this.#socket?.setTimeout(this.#socketTimeout ?? 0);
|
||||
}
|
||||
}
|
||||
async #createSocket() {
|
||||
const socket = this.#socketFactory.create();
|
||||
let onTimeout;
|
||||
if (this.#connectTimeout !== undefined) {
|
||||
onTimeout = () => socket.destroy(new errors_1.ConnectionTimeoutError());
|
||||
socket.once('timeout', onTimeout);
|
||||
socket.setTimeout(this.#connectTimeout);
|
||||
}
|
||||
if (this.#isSocketUnrefed) {
|
||||
socket.unref();
|
||||
}
|
||||
await (0, node_events_1.once)(socket, this.#socketFactory.event);
|
||||
if (onTimeout) {
|
||||
socket.removeListener('timeout', onTimeout);
|
||||
}
|
||||
if (this.#socketTimeout) {
|
||||
socket.once('timeout', () => {
|
||||
const error = this.#maintenanceTimeout
|
||||
? new errors_1.SocketTimeoutDuringMaintenanceError(this.#maintenanceTimeout)
|
||||
: new errors_1.SocketTimeoutError(this.#socketTimeout);
|
||||
socket.destroy(error);
|
||||
});
|
||||
socket.setTimeout(this.#socketTimeout);
|
||||
}
|
||||
socket
|
||||
.once('error', err => this.#onSocketError(err))
|
||||
.once('close', hadError => {
|
||||
if (hadError || !this.#isOpen || this.#socket !== socket)
|
||||
return;
|
||||
this.#onSocketError(new errors_1.SocketClosedUnexpectedlyError());
|
||||
})
|
||||
.on('drain', () => this.emit('drain'))
|
||||
.on('data', data => this.emit('data', data));
|
||||
return socket;
|
||||
}
|
||||
#onSocketError(err) {
|
||||
const wasReady = this.#isReady;
|
||||
this.#isReady = false;
|
||||
this.emit('error', err);
|
||||
if (!wasReady || !this.#isOpen || typeof this.#shouldReconnect(0, err) !== 'number')
|
||||
return;
|
||||
this.emit('reconnecting');
|
||||
this.#connect().catch(() => {
|
||||
// the error was already emitted, silently ignore it
|
||||
});
|
||||
}
|
||||
write(iterable) {
|
||||
if (!this.#socket)
|
||||
return;
|
||||
this.#socket.cork();
|
||||
for (const args of iterable) {
|
||||
for (const toWrite of args) {
|
||||
this.#socket.write(toWrite);
|
||||
}
|
||||
if (this.#socket.writableNeedDrain)
|
||||
break;
|
||||
}
|
||||
this.#socket.uncork();
|
||||
}
|
||||
async quit(fn) {
|
||||
if (!this.#isOpen) {
|
||||
throw new errors_1.ClientClosedError();
|
||||
}
|
||||
this.#isOpen = false;
|
||||
const reply = await fn();
|
||||
this.destroySocket();
|
||||
return reply;
|
||||
}
|
||||
close() {
|
||||
if (!this.#isOpen) {
|
||||
throw new errors_1.ClientClosedError();
|
||||
}
|
||||
this.#isOpen = false;
|
||||
}
|
||||
destroy() {
|
||||
if (!this.#isOpen) {
|
||||
throw new errors_1.ClientClosedError();
|
||||
}
|
||||
this.#isOpen = false;
|
||||
this.destroySocket();
|
||||
}
|
||||
destroySocket() {
|
||||
this.#isReady = false;
|
||||
if (this.#socket) {
|
||||
this.#socket.destroy();
|
||||
this.#socket = undefined;
|
||||
}
|
||||
this.emit('end');
|
||||
}
|
||||
ref() {
|
||||
this.#isSocketUnrefed = false;
|
||||
this.#socket?.ref();
|
||||
}
|
||||
unref() {
|
||||
this.#isSocketUnrefed = true;
|
||||
this.#socket?.unref();
|
||||
}
|
||||
defaultReconnectStrategy(retries, cause) {
|
||||
// By default, do not reconnect on socket timeout.
|
||||
if (cause instanceof errors_1.SocketTimeoutError) {
|
||||
return false;
|
||||
}
|
||||
// Generate a random jitter between 0 – 200 ms:
|
||||
const jitter = Math.floor(Math.random() * 200);
|
||||
// Delay is an exponential back off, (times^2) * 50 ms, with a maximum value of 2000 ms:
|
||||
const delay = Math.min(Math.pow(2, retries) * 50, 2000);
|
||||
return delay + jitter;
|
||||
}
|
||||
}
|
||||
exports.default = RedisSocket;
|
||||
//# sourceMappingURL=socket.js.map
|
||||
1
node_modules/@redis/client/dist/lib/client/socket.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/client/socket.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
72
node_modules/@redis/client/dist/lib/cluster/cluster-slots.d.ts
generated
vendored
Normal file
72
node_modules/@redis/client/dist/lib/cluster/cluster-slots.d.ts
generated
vendored
Normal file
@@ -0,0 +1,72 @@
|
||||
/// <reference types="node" />
|
||||
/// <reference types="node" />
|
||||
import { RedisClusterOptions } from '.';
|
||||
import { RedisClientType } from '../client';
|
||||
import { EventEmitter } from 'node:stream';
|
||||
import { ChannelListeners } from '../client/pub-sub';
|
||||
import { RedisArgument, RedisFunctions, RedisModules, RedisScripts, RespVersions, TypeMapping } from '../RESP/types';
|
||||
import { PooledClientSideCacheProvider } from '../client/cache';
|
||||
interface NodeAddress {
|
||||
host: string;
|
||||
port: number;
|
||||
}
|
||||
export type NodeAddressMap = {
|
||||
[address: string]: NodeAddress;
|
||||
} | ((address: string) => NodeAddress | undefined);
|
||||
export interface Node<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> {
|
||||
address: string;
|
||||
client?: RedisClientType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
connectPromise?: Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
}
|
||||
export interface ShardNode<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> extends Node<M, F, S, RESP, TYPE_MAPPING>, NodeAddress {
|
||||
id: string;
|
||||
readonly: boolean;
|
||||
}
|
||||
export interface MasterNode<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> extends ShardNode<M, F, S, RESP, TYPE_MAPPING> {
|
||||
pubSub?: {
|
||||
connectPromise?: Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
client: RedisClientType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
}
|
||||
export interface Shard<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> {
|
||||
master: MasterNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
replicas?: Array<ShardNode<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
nodesIterator?: IterableIterator<ShardNode<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
}
|
||||
type PubSubNode<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = (Omit<Node<M, F, S, RESP, TYPE_MAPPING>, 'client'> & Required<Pick<Node<M, F, S, RESP, TYPE_MAPPING>, 'client'>>);
|
||||
export type OnShardedChannelMovedError = (err: unknown, channel: string, listeners?: ChannelListeners) => void;
|
||||
export default class RedisClusterSlots<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> {
|
||||
#private;
|
||||
slots: Shard<M, F, S, RESP, TYPE_MAPPING>[];
|
||||
masters: MasterNode<M, F, S, RESP, TYPE_MAPPING>[];
|
||||
replicas: ShardNode<M, F, S, RESP, TYPE_MAPPING>[];
|
||||
readonly nodeByAddress: Map<string, ShardNode<M, F, S, RESP, TYPE_MAPPING> | MasterNode<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
pubSubNode?: PubSubNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
clientSideCache?: PooledClientSideCacheProvider;
|
||||
get isOpen(): boolean;
|
||||
constructor(options: RedisClusterOptions<M, F, S, RESP, TYPE_MAPPING>, emit: EventEmitter['emit']);
|
||||
connect(): Promise<void>;
|
||||
nodeClient(node: ShardNode<M, F, S, RESP, TYPE_MAPPING>): RedisClientType<M, F, S, RESP, TYPE_MAPPING> | Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
rediscover(startWith: RedisClientType<M, F, S, RESP>): Promise<void>;
|
||||
/**
|
||||
* @deprecated Use `close` instead.
|
||||
*/
|
||||
quit(): Promise<void>;
|
||||
/**
|
||||
* @deprecated Use `destroy` instead.
|
||||
*/
|
||||
disconnect(): Promise<void>;
|
||||
close(): Promise<void>;
|
||||
destroy(): void;
|
||||
getClient(firstKey: RedisArgument | undefined, isReadonly: boolean | undefined): RedisClientType<M, F, S, RESP, TYPE_MAPPING> | Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
_randomNodeIterator?: IterableIterator<ShardNode<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
getRandomNode(): ShardNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
getSlotRandomNode(slotNumber: number): ShardNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
getMasterByAddress(address: string): RedisClientType<M, F, S, RESP, TYPE_MAPPING> | Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>> | undefined;
|
||||
getPubSubClient(): RedisClientType<M, F, S, RESP, TYPE_MAPPING> | Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
executeUnsubscribeCommand(unsubscribe: (client: RedisClientType<M, F, S, RESP>) => Promise<void>): Promise<void>;
|
||||
getShardedPubSubClient(channel: string): RedisClientType<M, F, S, RESP, TYPE_MAPPING> | Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
executeShardedUnsubscribeCommand(channel: string, unsubscribe: (client: RedisClientType<M, F, S, RESP, TYPE_MAPPING>) => Promise<void>): Promise<void>;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=cluster-slots.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/cluster/cluster-slots.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/cluster/cluster-slots.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"cluster-slots.d.ts","sourceRoot":"","sources":["../../../lib/cluster/cluster-slots.ts"],"names":[],"mappings":";;AAAA,OAAO,EAA6B,mBAAmB,EAAE,MAAM,GAAG,CAAC;AAEnE,OAAoB,EAAsB,eAAe,EAAE,MAAM,WAAW,CAAC;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAqD,MAAM,mBAAmB,CAAC;AACxG,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAGrH,OAAO,EAA8B,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AAE5F,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,CAAC;CAChC,GAAG,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,WAAW,GAAG,SAAS,CAAC,CAAC;AAEnD,MAAM,WAAW,IAAI,CACnB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY,EACzB,YAAY,SAAS,WAAW;IAEhC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;CACxE;AAED,MAAM,WAAW,SAAS,CACxB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY,EACzB,YAAY,SAAS,WAAW,CAChC,SAAQ,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,WAAW;IACtD,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,UAAU,CACzB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY,EACzB,YAAY,SAAS,WAAW,CAChC,SAAQ,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC;IAC9C,MAAM,CAAC,EAAE;QACP,cAAc,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;QACvE,MAAM,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;KACtD,CAAC;CACH;AAED,MAAM,WAAW,KAAK,CACpB,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY,EACzB,YAAY,SAAS,WAAW;IAEhC,MAAM,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IACzD,aAAa,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;CAC1E;AAUD,KAAK,UAAU,CACb,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY,EACzB,YAAY,SAAS,WAAW,IAC9B,CACA,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,QAAQ,CAAC,GACjD,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,EAAE,QAAQ,CAAC,CAAC,CAC5D,CAAC;AAOJ,MAAM,MAAM,0BAA0B,GAAG,CACvC,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,gBAAgB,KACzB,IAAI,CAAC;AAEV,MAAM,CAAC,OAAO,OAAO,iBAAiB,CACpC,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY,EACzB,YAAY,SAAS,WAAW;;IAOhC,KAAK,uCAA2E;IAChF,OAAO,4CAAwD;IAC/D,QAAQ,2CAAuD;IAC/D,QAAQ,CAAC,aAAa,gGAAuG;IAC7H,UAAU,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC;IACrD,eAAe,CAAC,EAAE,6BAA6B,CAAC;IAIhD,IAAI,MAAM,YAET;gBASC,OAAO,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,EACzD,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC;IAiBtB,OAAO;IAiOb,UAAU,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC;IAUjD,UAAU,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAc1E;;OAEG;IACH,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB;;OAEG;IACH,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAI3B,KAAK;IAIL,OAAO;IAuDP,SAAS,CACP,QAAQ,EAAE,aAAa,GAAG,SAAS,EACnC,UAAU,EAAE,OAAO,GAAG,SAAS;IA2CjC,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC;IAE/E,aAAa;IAsBb,iBAAiB,CAAC,UAAU,EAAE,MAAM;IAUpC,kBAAkB,CAAC,OAAO,EAAE,MAAM;IAOlC,eAAe;IAqCT,yBAAyB,CAC7B,WAAW,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,GACrE,OAAO,CAAC,IAAI,CAAC;IAUhB,sBAAsB,CAAC,OAAO,EAAE,MAAM;IAsChC,gCAAgC,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,YAAY,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC;CAgBvF"}
|
||||
462
node_modules/@redis/client/dist/lib/cluster/cluster-slots.js
generated
vendored
Normal file
462
node_modules/@redis/client/dist/lib/cluster/cluster-slots.js
generated
vendored
Normal file
@@ -0,0 +1,462 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
var _a;
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const errors_1 = require("../errors");
|
||||
const client_1 = __importDefault(require("../client"));
|
||||
const pub_sub_1 = require("../client/pub-sub");
|
||||
const cluster_key_slot_1 = __importDefault(require("cluster-key-slot"));
|
||||
const cache_1 = require("../client/cache");
|
||||
class RedisClusterSlots {
|
||||
static #SLOTS = 16384;
|
||||
#options;
|
||||
#clientFactory;
|
||||
#emit;
|
||||
slots = new Array(_a.#SLOTS);
|
||||
masters = new Array();
|
||||
replicas = new Array();
|
||||
nodeByAddress = new Map();
|
||||
pubSubNode;
|
||||
clientSideCache;
|
||||
#isOpen = false;
|
||||
get isOpen() {
|
||||
return this.#isOpen;
|
||||
}
|
||||
#validateOptions(options) {
|
||||
if (options?.clientSideCache && options?.RESP !== 3) {
|
||||
throw new Error('Client Side Caching is only supported with RESP3');
|
||||
}
|
||||
}
|
||||
constructor(options, emit) {
|
||||
this.#validateOptions(options);
|
||||
this.#options = options;
|
||||
if (options?.clientSideCache) {
|
||||
if (options.clientSideCache instanceof cache_1.PooledClientSideCacheProvider) {
|
||||
this.clientSideCache = options.clientSideCache;
|
||||
}
|
||||
else {
|
||||
this.clientSideCache = new cache_1.BasicPooledClientSideCache(options.clientSideCache);
|
||||
}
|
||||
}
|
||||
this.#clientFactory = client_1.default.factory(this.#options);
|
||||
this.#emit = emit;
|
||||
}
|
||||
async connect() {
|
||||
if (this.#isOpen) {
|
||||
throw new Error('Cluster already open');
|
||||
}
|
||||
this.#isOpen = true;
|
||||
try {
|
||||
await this.#discoverWithRootNodes();
|
||||
this.#emit('connect');
|
||||
}
|
||||
catch (err) {
|
||||
this.#isOpen = false;
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
async #discoverWithRootNodes() {
|
||||
let start = Math.floor(Math.random() * this.#options.rootNodes.length);
|
||||
for (let i = start; i < this.#options.rootNodes.length; i++) {
|
||||
if (!this.#isOpen)
|
||||
throw new Error('Cluster closed');
|
||||
if (await this.#discover(this.#options.rootNodes[i]))
|
||||
return;
|
||||
}
|
||||
for (let i = 0; i < start; i++) {
|
||||
if (!this.#isOpen)
|
||||
throw new Error('Cluster closed');
|
||||
if (await this.#discover(this.#options.rootNodes[i]))
|
||||
return;
|
||||
}
|
||||
throw new errors_1.RootNodesUnavailableError();
|
||||
}
|
||||
#resetSlots() {
|
||||
this.slots = new Array(_a.#SLOTS);
|
||||
this.masters = [];
|
||||
this.replicas = [];
|
||||
this._randomNodeIterator = undefined;
|
||||
}
|
||||
async #discover(rootNode) {
|
||||
this.clientSideCache?.clear();
|
||||
this.clientSideCache?.disable();
|
||||
try {
|
||||
const addressesInUse = new Set(), promises = [], eagerConnect = this.#options.minimizeConnections !== true;
|
||||
const shards = await this.#getShards(rootNode);
|
||||
this.#resetSlots(); // Reset slots AFTER shards have been fetched to prevent a race condition
|
||||
for (const { from, to, master, replicas } of shards) {
|
||||
const shard = {
|
||||
master: this.#initiateSlotNode(master, false, eagerConnect, addressesInUse, promises)
|
||||
};
|
||||
if (this.#options.useReplicas) {
|
||||
shard.replicas = replicas.map(replica => this.#initiateSlotNode(replica, true, eagerConnect, addressesInUse, promises));
|
||||
}
|
||||
for (let i = from; i <= to; i++) {
|
||||
this.slots[i] = shard;
|
||||
}
|
||||
}
|
||||
if (this.pubSubNode && !addressesInUse.has(this.pubSubNode.address)) {
|
||||
const channelsListeners = this.pubSubNode.client.getPubSubListeners(pub_sub_1.PUBSUB_TYPE.CHANNELS), patternsListeners = this.pubSubNode.client.getPubSubListeners(pub_sub_1.PUBSUB_TYPE.PATTERNS);
|
||||
this.pubSubNode.client.destroy();
|
||||
if (channelsListeners.size || patternsListeners.size) {
|
||||
promises.push(this.#initiatePubSubClient({
|
||||
[pub_sub_1.PUBSUB_TYPE.CHANNELS]: channelsListeners,
|
||||
[pub_sub_1.PUBSUB_TYPE.PATTERNS]: patternsListeners
|
||||
}));
|
||||
}
|
||||
}
|
||||
//Keep only the nodes that are still in use
|
||||
for (const [address, node] of this.nodeByAddress.entries()) {
|
||||
if (addressesInUse.has(address))
|
||||
continue;
|
||||
if (node.client) {
|
||||
node.client.destroy();
|
||||
}
|
||||
const { pubSub } = node;
|
||||
if (pubSub) {
|
||||
pubSub.client.destroy();
|
||||
}
|
||||
this.nodeByAddress.delete(address);
|
||||
}
|
||||
await Promise.all(promises);
|
||||
this.clientSideCache?.enable();
|
||||
return true;
|
||||
}
|
||||
catch (err) {
|
||||
this.#emit('error', err);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async #getShards(rootNode) {
|
||||
const options = this.#clientOptionsDefaults(rootNode);
|
||||
options.socket ??= {};
|
||||
options.socket.reconnectStrategy = false;
|
||||
options.RESP = this.#options.RESP;
|
||||
options.commandOptions = undefined;
|
||||
// TODO: find a way to avoid type casting
|
||||
const client = await this.#clientFactory(options)
|
||||
.on('error', err => this.#emit('error', err))
|
||||
.connect();
|
||||
try {
|
||||
// switch to `CLUSTER SHARDS` when Redis 7.0 will be the minimum supported version
|
||||
return await client.clusterSlots();
|
||||
}
|
||||
finally {
|
||||
client.destroy();
|
||||
}
|
||||
}
|
||||
#getNodeAddress(address) {
|
||||
switch (typeof this.#options.nodeAddressMap) {
|
||||
case 'object':
|
||||
return this.#options.nodeAddressMap[address];
|
||||
case 'function':
|
||||
return this.#options.nodeAddressMap(address);
|
||||
}
|
||||
}
|
||||
#clientOptionsDefaults(options) {
|
||||
if (!this.#options.defaults)
|
||||
return options;
|
||||
let socket;
|
||||
if (this.#options.defaults.socket) {
|
||||
socket = {
|
||||
...this.#options.defaults.socket,
|
||||
...options?.socket
|
||||
};
|
||||
}
|
||||
else {
|
||||
socket = options?.socket;
|
||||
}
|
||||
return {
|
||||
...this.#options.defaults,
|
||||
...options,
|
||||
socket: socket
|
||||
};
|
||||
}
|
||||
#initiateSlotNode(shard, readonly, eagerConnent, addressesInUse, promises) {
|
||||
const address = `${shard.host}:${shard.port}`;
|
||||
let node = this.nodeByAddress.get(address);
|
||||
if (!node) {
|
||||
node = {
|
||||
...shard,
|
||||
address,
|
||||
readonly,
|
||||
client: undefined,
|
||||
connectPromise: undefined
|
||||
};
|
||||
if (eagerConnent) {
|
||||
promises.push(this.#createNodeClient(node));
|
||||
}
|
||||
this.nodeByAddress.set(address, node);
|
||||
}
|
||||
if (!addressesInUse.has(address)) {
|
||||
addressesInUse.add(address);
|
||||
(readonly ? this.replicas : this.masters).push(node);
|
||||
}
|
||||
return node;
|
||||
}
|
||||
#createClient(node, readonly = node.readonly) {
|
||||
const socket = this.#getNodeAddress(node.address) ??
|
||||
{ host: node.host, port: node.port, };
|
||||
const clientInfo = Object.freeze({
|
||||
host: socket.host,
|
||||
port: socket.port,
|
||||
});
|
||||
const emit = this.#emit;
|
||||
const client = this.#clientFactory(this.#clientOptionsDefaults({
|
||||
clientSideCache: this.clientSideCache,
|
||||
RESP: this.#options.RESP,
|
||||
socket,
|
||||
readonly,
|
||||
}))
|
||||
.on('error', error => emit('node-error', error, clientInfo))
|
||||
.on('reconnecting', () => emit('node-reconnecting', clientInfo))
|
||||
.once('ready', () => emit('node-ready', clientInfo))
|
||||
.once('connect', () => emit('node-connect', clientInfo))
|
||||
.once('end', () => emit('node-disconnect', clientInfo))
|
||||
.on('__MOVED', async (allPubSubListeners) => {
|
||||
await this.rediscover(client);
|
||||
this.#emit('__resubscribeAllPubSubListeners', allPubSubListeners);
|
||||
});
|
||||
return client;
|
||||
}
|
||||
#createNodeClient(node, readonly) {
|
||||
const client = node.client = this.#createClient(node, readonly);
|
||||
return node.connectPromise = client.connect()
|
||||
.finally(() => node.connectPromise = undefined);
|
||||
}
|
||||
nodeClient(node) {
|
||||
return (node.connectPromise ?? // if the node is connecting
|
||||
node.client ?? // if the node is connected
|
||||
this.#createNodeClient(node) // if the not is disconnected
|
||||
);
|
||||
}
|
||||
#runningRediscoverPromise;
|
||||
async rediscover(startWith) {
|
||||
this.#runningRediscoverPromise ??= this.#rediscover(startWith)
|
||||
.finally(() => {
|
||||
this.#runningRediscoverPromise = undefined;
|
||||
});
|
||||
return this.#runningRediscoverPromise;
|
||||
}
|
||||
async #rediscover(startWith) {
|
||||
if (await this.#discover(startWith.options))
|
||||
return;
|
||||
return this.#discoverWithRootNodes();
|
||||
}
|
||||
/**
|
||||
* @deprecated Use `close` instead.
|
||||
*/
|
||||
quit() {
|
||||
return this.#destroy(client => client.quit());
|
||||
}
|
||||
/**
|
||||
* @deprecated Use `destroy` instead.
|
||||
*/
|
||||
disconnect() {
|
||||
return this.#destroy(client => client.disconnect());
|
||||
}
|
||||
close() {
|
||||
return this.#destroy(client => client.close());
|
||||
}
|
||||
destroy() {
|
||||
this.#isOpen = false;
|
||||
for (const client of this.#clients()) {
|
||||
client.destroy();
|
||||
}
|
||||
if (this.pubSubNode) {
|
||||
this.pubSubNode.client.destroy();
|
||||
this.pubSubNode = undefined;
|
||||
}
|
||||
this.#resetSlots();
|
||||
this.nodeByAddress.clear();
|
||||
this.#emit('disconnect');
|
||||
}
|
||||
*#clients() {
|
||||
for (const master of this.masters) {
|
||||
if (master.client) {
|
||||
yield master.client;
|
||||
}
|
||||
if (master.pubSub) {
|
||||
yield master.pubSub.client;
|
||||
}
|
||||
}
|
||||
for (const replica of this.replicas) {
|
||||
if (replica.client) {
|
||||
yield replica.client;
|
||||
}
|
||||
}
|
||||
}
|
||||
async #destroy(fn) {
|
||||
this.#isOpen = false;
|
||||
const promises = [];
|
||||
for (const client of this.#clients()) {
|
||||
promises.push(fn(client));
|
||||
}
|
||||
if (this.pubSubNode) {
|
||||
promises.push(fn(this.pubSubNode.client));
|
||||
this.pubSubNode = undefined;
|
||||
}
|
||||
this.#resetSlots();
|
||||
this.nodeByAddress.clear();
|
||||
await Promise.allSettled(promises);
|
||||
this.#emit('disconnect');
|
||||
}
|
||||
getClient(firstKey, isReadonly) {
|
||||
if (!firstKey) {
|
||||
return this.nodeClient(this.getRandomNode());
|
||||
}
|
||||
const slotNumber = (0, cluster_key_slot_1.default)(firstKey);
|
||||
if (!isReadonly) {
|
||||
return this.nodeClient(this.slots[slotNumber].master);
|
||||
}
|
||||
return this.nodeClient(this.getSlotRandomNode(slotNumber));
|
||||
}
|
||||
*#iterateAllNodes() {
|
||||
if (this.masters.length + this.replicas.length === 0)
|
||||
return;
|
||||
let i = Math.floor(Math.random() * (this.masters.length + this.replicas.length));
|
||||
if (i < this.masters.length) {
|
||||
do {
|
||||
yield this.masters[i];
|
||||
} while (++i < this.masters.length);
|
||||
for (const replica of this.replicas) {
|
||||
yield replica;
|
||||
}
|
||||
}
|
||||
else {
|
||||
i -= this.masters.length;
|
||||
do {
|
||||
yield this.replicas[i];
|
||||
} while (++i < this.replicas.length);
|
||||
}
|
||||
while (true) {
|
||||
for (const master of this.masters) {
|
||||
yield master;
|
||||
}
|
||||
for (const replica of this.replicas) {
|
||||
yield replica;
|
||||
}
|
||||
}
|
||||
}
|
||||
_randomNodeIterator;
|
||||
getRandomNode() {
|
||||
this._randomNodeIterator ??= this.#iterateAllNodes();
|
||||
return this._randomNodeIterator.next().value;
|
||||
}
|
||||
*#slotNodesIterator(slot) {
|
||||
let i = Math.floor(Math.random() * (1 + slot.replicas.length));
|
||||
if (i < slot.replicas.length) {
|
||||
do {
|
||||
yield slot.replicas[i];
|
||||
} while (++i < slot.replicas.length);
|
||||
}
|
||||
while (true) {
|
||||
yield slot.master;
|
||||
for (const replica of slot.replicas) {
|
||||
yield replica;
|
||||
}
|
||||
}
|
||||
}
|
||||
getSlotRandomNode(slotNumber) {
|
||||
const slot = this.slots[slotNumber];
|
||||
if (!slot.replicas?.length) {
|
||||
return slot.master;
|
||||
}
|
||||
slot.nodesIterator ??= this.#slotNodesIterator(slot);
|
||||
return slot.nodesIterator.next().value;
|
||||
}
|
||||
getMasterByAddress(address) {
|
||||
const master = this.nodeByAddress.get(address);
|
||||
if (!master)
|
||||
return;
|
||||
return this.nodeClient(master);
|
||||
}
|
||||
getPubSubClient() {
|
||||
if (!this.pubSubNode)
|
||||
return this.#initiatePubSubClient();
|
||||
return this.pubSubNode.connectPromise ?? this.pubSubNode.client;
|
||||
}
|
||||
async #initiatePubSubClient(toResubscribe) {
|
||||
const index = Math.floor(Math.random() * (this.masters.length + this.replicas.length)), node = index < this.masters.length ?
|
||||
this.masters[index] :
|
||||
this.replicas[index - this.masters.length], client = this.#createClient(node, false);
|
||||
this.pubSubNode = {
|
||||
address: node.address,
|
||||
client,
|
||||
connectPromise: client.connect()
|
||||
.then(async (client) => {
|
||||
if (toResubscribe) {
|
||||
await Promise.all([
|
||||
client.extendPubSubListeners(pub_sub_1.PUBSUB_TYPE.CHANNELS, toResubscribe[pub_sub_1.PUBSUB_TYPE.CHANNELS]),
|
||||
client.extendPubSubListeners(pub_sub_1.PUBSUB_TYPE.PATTERNS, toResubscribe[pub_sub_1.PUBSUB_TYPE.PATTERNS])
|
||||
]);
|
||||
}
|
||||
this.pubSubNode.connectPromise = undefined;
|
||||
return client;
|
||||
})
|
||||
.catch(err => {
|
||||
this.pubSubNode = undefined;
|
||||
throw err;
|
||||
})
|
||||
};
|
||||
return this.pubSubNode.connectPromise;
|
||||
}
|
||||
async executeUnsubscribeCommand(unsubscribe) {
|
||||
const client = await this.getPubSubClient();
|
||||
await unsubscribe(client);
|
||||
if (!client.isPubSubActive) {
|
||||
client.destroy();
|
||||
this.pubSubNode = undefined;
|
||||
}
|
||||
}
|
||||
getShardedPubSubClient(channel) {
|
||||
const { master } = this.slots[(0, cluster_key_slot_1.default)(channel)];
|
||||
if (!master.pubSub)
|
||||
return this.#initiateShardedPubSubClient(master);
|
||||
return master.pubSub.connectPromise ?? master.pubSub.client;
|
||||
}
|
||||
async #initiateShardedPubSubClient(master) {
|
||||
const client = this.#createClient(master, false)
|
||||
.on('server-sunsubscribe', async (channel, listeners) => {
|
||||
try {
|
||||
await this.rediscover(client);
|
||||
const redirectTo = await this.getShardedPubSubClient(channel);
|
||||
await redirectTo.extendPubSubChannelListeners(pub_sub_1.PUBSUB_TYPE.SHARDED, channel, listeners);
|
||||
}
|
||||
catch (err) {
|
||||
this.#emit('sharded-shannel-moved-error', err, channel, listeners);
|
||||
}
|
||||
});
|
||||
master.pubSub = {
|
||||
client,
|
||||
connectPromise: client.connect()
|
||||
.then(client => {
|
||||
master.pubSub.connectPromise = undefined;
|
||||
return client;
|
||||
})
|
||||
.catch(err => {
|
||||
master.pubSub = undefined;
|
||||
throw err;
|
||||
})
|
||||
};
|
||||
return master.pubSub.connectPromise;
|
||||
}
|
||||
async executeShardedUnsubscribeCommand(channel, unsubscribe) {
|
||||
const { master } = this.slots[(0, cluster_key_slot_1.default)(channel)];
|
||||
if (!master.pubSub)
|
||||
return;
|
||||
const client = master.pubSub.connectPromise ?
|
||||
await master.pubSub.connectPromise :
|
||||
master.pubSub.client;
|
||||
await unsubscribe(client);
|
||||
if (!client.isPubSubActive) {
|
||||
client.destroy();
|
||||
master.pubSub = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
_a = RedisClusterSlots;
|
||||
exports.default = RedisClusterSlots;
|
||||
//# sourceMappingURL=cluster-slots.js.map
|
||||
1
node_modules/@redis/client/dist/lib/cluster/cluster-slots.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/cluster/cluster-slots.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
178
node_modules/@redis/client/dist/lib/cluster/index.d.ts
generated
vendored
Normal file
178
node_modules/@redis/client/dist/lib/cluster/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/// <reference types="node" />
|
||||
import { RedisClientOptions, RedisClientType } from '../client';
|
||||
import { CommandOptions } from '../client/commands-queue';
|
||||
import { CommandArguments, CommanderConfig, TypeMapping, RedisArgument, RedisFunctions, RedisModules, RedisScripts, ReplyUnion, RespVersions } from '../RESP/types';
|
||||
import { EventEmitter } from 'node:events';
|
||||
import RedisClusterSlots, { NodeAddressMap, ShardNode } from './cluster-slots';
|
||||
import { RedisClusterMultiCommandType } from './multi-command';
|
||||
import { PubSubListener, PubSubListeners } from '../client/pub-sub';
|
||||
import { RedisTcpSocketOptions } from '../client/socket';
|
||||
import { ClientSideCacheConfig, PooledClientSideCacheProvider } from '../client/cache';
|
||||
import { WithCommands, WithFunctions, WithModules, WithScripts } from '../client';
|
||||
interface ClusterCommander<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> extends CommanderConfig<M, F, S, RESP> {
|
||||
commandOptions?: ClusterCommandOptions<TYPE_MAPPING>;
|
||||
}
|
||||
export type RedisClusterClientOptions = Omit<RedisClientOptions<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping, RedisTcpSocketOptions>, keyof ClusterCommander<RedisModules, RedisFunctions, RedisScripts, RespVersions, TypeMapping>>;
|
||||
export interface RedisClusterOptions<M extends RedisModules = RedisModules, F extends RedisFunctions = RedisFunctions, S extends RedisScripts = RedisScripts, RESP extends RespVersions = RespVersions, TYPE_MAPPING extends TypeMapping = TypeMapping> extends ClusterCommander<M, F, S, RESP, TYPE_MAPPING> {
|
||||
/**
|
||||
* Should contain details for some of the cluster nodes that the client will use to discover
|
||||
* the "cluster topology". We recommend including details for at least 3 nodes here.
|
||||
*/
|
||||
rootNodes: Array<RedisClusterClientOptions>;
|
||||
/**
|
||||
* Default values used for every client in the cluster. Use this to specify global values,
|
||||
* for example: ACL credentials, timeouts, TLS configuration etc.
|
||||
*/
|
||||
defaults?: Partial<RedisClusterClientOptions>;
|
||||
/**
|
||||
* When `true`, `.connect()` will only discover the cluster topology, without actually connecting to all the nodes.
|
||||
* Useful for short-term or PubSub-only connections.
|
||||
*/
|
||||
minimizeConnections?: boolean;
|
||||
/**
|
||||
* When `true`, distribute load by executing readonly commands (such as `GET`, `GEOSEARCH`, etc.) across all cluster nodes. When `false`, only use master nodes.
|
||||
*/
|
||||
useReplicas?: boolean;
|
||||
/**
|
||||
* The maximum number of times a command will be redirected due to `MOVED` or `ASK` errors.
|
||||
*/
|
||||
maxCommandRedirections?: number;
|
||||
/**
|
||||
* Mapping between the addresses in the cluster (see `CLUSTER SHARDS`) and the addresses the client should connect to
|
||||
* Useful when the cluster is running on another network
|
||||
*/
|
||||
nodeAddressMap?: NodeAddressMap;
|
||||
/**
|
||||
* Client Side Caching configuration for the pool.
|
||||
*
|
||||
* Enables Redis Servers and Clients to work together to cache results from commands
|
||||
* sent to a server. The server will notify the client when cached results are no longer valid.
|
||||
* In pooled mode, the cache is shared across all clients in the pool.
|
||||
*
|
||||
* Note: Client Side Caching is only supported with RESP3.
|
||||
*
|
||||
* @example Anonymous cache configuration
|
||||
* ```
|
||||
* const client = createCluster({
|
||||
* clientSideCache: {
|
||||
* ttl: 0,
|
||||
* maxEntries: 0,
|
||||
* evictPolicy: "LRU"
|
||||
* },
|
||||
* minimum: 5
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example Using a controllable cache
|
||||
* ```
|
||||
* const cache = new BasicPooledClientSideCache({
|
||||
* ttl: 0,
|
||||
* maxEntries: 0,
|
||||
* evictPolicy: "LRU"
|
||||
* });
|
||||
* const client = createCluster({
|
||||
* clientSideCache: cache,
|
||||
* minimum: 5
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
clientSideCache?: PooledClientSideCacheProvider | ClientSideCacheConfig;
|
||||
}
|
||||
export type RedisClusterType<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}> = (RedisCluster<M, F, S, RESP, TYPE_MAPPING> & WithCommands<RESP, TYPE_MAPPING> & WithModules<M, RESP, TYPE_MAPPING> & WithFunctions<F, RESP, TYPE_MAPPING> & WithScripts<S, RESP, TYPE_MAPPING>);
|
||||
export interface ClusterCommandOptions<TYPE_MAPPING extends TypeMapping = TypeMapping> extends CommandOptions<TYPE_MAPPING> {
|
||||
}
|
||||
export default class RedisCluster<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> extends EventEmitter {
|
||||
#private;
|
||||
static factory<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}>(config?: ClusterCommander<M, F, S, RESP, TYPE_MAPPING>): (options?: Omit<RedisClusterOptions, keyof Exclude<typeof config, undefined>>) => RedisClusterType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
static create<M extends RedisModules = {}, F extends RedisFunctions = {}, S extends RedisScripts = {}, RESP extends RespVersions = 2, TYPE_MAPPING extends TypeMapping = {}>(options?: RedisClusterOptions<M, F, S, RESP, TYPE_MAPPING>): RedisClusterType<M, F, S, RESP, TYPE_MAPPING>;
|
||||
readonly _options: RedisClusterOptions<M, F, S, RESP, TYPE_MAPPING>;
|
||||
readonly _slots: RedisClusterSlots<M, F, S, RESP, TYPE_MAPPING>;
|
||||
private _self;
|
||||
private _commandOptions?;
|
||||
/**
|
||||
* An array of the cluster slots, each slot contain its `master` and `replicas`.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific node (master or replica).
|
||||
*/
|
||||
get slots(): import("./cluster-slots").Shard<M, F, S, RESP, TYPE_MAPPING>[];
|
||||
get clientSideCache(): PooledClientSideCacheProvider | undefined;
|
||||
/**
|
||||
* An array of the cluster masters.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific master node.
|
||||
*/
|
||||
get masters(): import("./cluster-slots").MasterNode<M, F, S, RESP, TYPE_MAPPING>[];
|
||||
/**
|
||||
* An array of the cluster replicas.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific replica node.
|
||||
*/
|
||||
get replicas(): ShardNode<M, F, S, RESP, TYPE_MAPPING>[];
|
||||
/**
|
||||
* A map form a node address (`<host>:<port>`) to its shard, each shard contain its `master` and `replicas`.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific node (master or replica).
|
||||
*/
|
||||
get nodeByAddress(): Map<string, import("./cluster-slots").MasterNode<M, F, S, RESP, TYPE_MAPPING> | ShardNode<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
/**
|
||||
* The current pub/sub node.
|
||||
*/
|
||||
get pubSubNode(): (Omit<import("./cluster-slots").Node<M, F, S, RESP, TYPE_MAPPING>, "client"> & Required<Pick<import("./cluster-slots").Node<M, F, S, RESP, TYPE_MAPPING>, "client">>) | undefined;
|
||||
get isOpen(): boolean;
|
||||
constructor(options: RedisClusterOptions<M, F, S, RESP, TYPE_MAPPING>);
|
||||
duplicate<_M extends RedisModules = M, _F extends RedisFunctions = F, _S extends RedisScripts = S, _RESP extends RespVersions = RESP, _TYPE_MAPPING extends TypeMapping = TYPE_MAPPING>(overrides?: Partial<RedisClusterOptions<_M, _F, _S, _RESP, _TYPE_MAPPING>>): RedisClusterType<_M, _F, _S, _RESP, _TYPE_MAPPING>;
|
||||
connect(): Promise<RedisClusterType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
withCommandOptions<OPTIONS extends ClusterCommandOptions<TYPE_MAPPING>, TYPE_MAPPING extends TypeMapping>(options: OPTIONS): RedisClusterType<M, F, S, RESP, TYPE_MAPPING extends TypeMapping ? TYPE_MAPPING : {}>;
|
||||
private _commandOptionsProxy;
|
||||
/**
|
||||
* Override the `typeMapping` command option
|
||||
*/
|
||||
withTypeMapping<TYPE_MAPPING extends TypeMapping>(typeMapping: TYPE_MAPPING): RedisClusterType<M, F, S, RESP, TYPE_MAPPING extends TypeMapping ? TYPE_MAPPING : {}>;
|
||||
_handleAsk<T>(fn: (client: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, opts?: ClusterCommandOptions) => Promise<T>): (client: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, options?: ClusterCommandOptions) => Promise<T>;
|
||||
_execute<T>(firstKey: RedisArgument | undefined, isReadonly: boolean | undefined, options: ClusterCommandOptions | undefined, fn: (client: RedisClientType<M, F, S, RESP, TYPE_MAPPING>, opts?: ClusterCommandOptions) => Promise<T>): Promise<T>;
|
||||
sendCommand<T = ReplyUnion>(firstKey: RedisArgument | undefined, isReadonly: boolean | undefined, args: CommandArguments, options?: ClusterCommandOptions): Promise<T>;
|
||||
MULTI(routing?: RedisArgument): RedisClusterMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
|
||||
multi: (routing?: RedisArgument) => RedisClusterMultiCommandType<[], M, F, S, RESP, TYPE_MAPPING>;
|
||||
SUBSCRIBE<T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
subscribe: <T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T | undefined) => Promise<void>;
|
||||
UNSUBSCRIBE<T extends boolean = false>(channels?: string | Array<string>, listener?: PubSubListener<boolean>, bufferMode?: T): Promise<void>;
|
||||
unsubscribe: <T extends boolean = false>(channels?: string | Array<string>, listener?: PubSubListener<boolean>, bufferMode?: T | undefined) => Promise<void>;
|
||||
PSUBSCRIBE<T extends boolean = false>(patterns: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
pSubscribe: <T extends boolean = false>(patterns: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T | undefined) => Promise<void>;
|
||||
PUNSUBSCRIBE<T extends boolean = false>(patterns?: string | Array<string>, listener?: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
pUnsubscribe: <T extends boolean = false>(patterns?: string | Array<string>, listener?: PubSubListener<T> | undefined, bufferMode?: T | undefined) => Promise<void>;
|
||||
SSUBSCRIBE<T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
sSubscribe: <T extends boolean = false>(channels: string | Array<string>, listener: PubSubListener<T>, bufferMode?: T | undefined) => Promise<void>;
|
||||
SUNSUBSCRIBE<T extends boolean = false>(channels: string | Array<string>, listener?: PubSubListener<T>, bufferMode?: T): Promise<void>;
|
||||
resubscribeAllPubSubListeners(allListeners: PubSubListeners): void;
|
||||
sUnsubscribe: <T extends boolean = false>(channels: string | Array<string>, listener?: PubSubListener<T> | undefined, bufferMode?: T | undefined) => Promise<void>;
|
||||
/**
|
||||
* @deprecated Use `close` instead.
|
||||
*/
|
||||
quit(): Promise<void>;
|
||||
/**
|
||||
* @deprecated Use `destroy` instead.
|
||||
*/
|
||||
disconnect(): Promise<void>;
|
||||
close(): Promise<void>;
|
||||
destroy(): void;
|
||||
nodeClient(node: ShardNode<M, F, S, RESP, TYPE_MAPPING>): RedisClientType<M, F, S, RESP, TYPE_MAPPING> | Promise<RedisClientType<M, F, S, RESP, TYPE_MAPPING>>;
|
||||
/**
|
||||
* Returns a random node from the cluster.
|
||||
* Userful for running "forward" commands (like PUBLISH) on a random node.
|
||||
*/
|
||||
getRandomNode(): ShardNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
/**
|
||||
* Get a random node from a slot.
|
||||
* Useful for running readonly commands on a slot.
|
||||
*/
|
||||
getSlotRandomNode(slot: number): ShardNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
/**
|
||||
* @deprecated use `.masters` instead
|
||||
* TODO
|
||||
*/
|
||||
getMasters(): import("./cluster-slots").MasterNode<M, F, S, RESP, TYPE_MAPPING>[];
|
||||
/**
|
||||
* @deprecated use `.slots[<SLOT>]` instead
|
||||
* TODO
|
||||
*/
|
||||
getSlotMaster(slot: number): import("./cluster-slots").MasterNode<M, F, S, RESP, TYPE_MAPPING>;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=index.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/cluster/index.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/cluster/index.d.ts.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
357
node_modules/@redis/client/dist/lib/cluster/index.js
generated
vendored
Normal file
357
node_modules/@redis/client/dist/lib/cluster/index.js
generated
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const commands_1 = __importDefault(require("../commands"));
|
||||
const node_events_1 = require("node:events");
|
||||
const commander_1 = require("../commander");
|
||||
const cluster_slots_1 = __importDefault(require("./cluster-slots"));
|
||||
const multi_command_1 = __importDefault(require("./multi-command"));
|
||||
const errors_1 = require("../errors");
|
||||
const parser_1 = require("../client/parser");
|
||||
const ASKING_1 = require("../commands/ASKING");
|
||||
const single_entry_cache_1 = __importDefault(require("../single-entry-cache"));
|
||||
class RedisCluster extends node_events_1.EventEmitter {
|
||||
static #createCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
return this._self._execute(parser.firstKey, command.IS_READ_ONLY, this._commandOptions, (client, opts) => client._executeCommand(command, parser, opts, transformReply));
|
||||
};
|
||||
}
|
||||
static #createModuleCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
return this._self._execute(parser.firstKey, command.IS_READ_ONLY, this._self._commandOptions, (client, opts) => client._executeCommand(command, parser, opts, transformReply));
|
||||
};
|
||||
}
|
||||
static #createFunctionCommand(name, fn, resp) {
|
||||
const prefix = (0, commander_1.functionArgumentsPrefix)(name, fn);
|
||||
const transformReply = (0, commander_1.getTransformReply)(fn, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.push(...prefix);
|
||||
fn.parseCommand(parser, ...args);
|
||||
return this._self._execute(parser.firstKey, fn.IS_READ_ONLY, this._self._commandOptions, (client, opts) => client._executeCommand(fn, parser, opts, transformReply));
|
||||
};
|
||||
}
|
||||
static #createScriptCommand(script, resp) {
|
||||
const prefix = (0, commander_1.scriptArgumentsPrefix)(script);
|
||||
const transformReply = (0, commander_1.getTransformReply)(script, resp);
|
||||
return async function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.push(...prefix);
|
||||
script.parseCommand(parser, ...args);
|
||||
return this._self._execute(parser.firstKey, script.IS_READ_ONLY, this._commandOptions, (client, opts) => client._executeScript(script, parser, opts, transformReply));
|
||||
};
|
||||
}
|
||||
static #SingleEntryCache = new single_entry_cache_1.default();
|
||||
static factory(config) {
|
||||
let Cluster = RedisCluster.#SingleEntryCache.get(config);
|
||||
if (!Cluster) {
|
||||
Cluster = (0, commander_1.attachConfig)({
|
||||
BaseClass: RedisCluster,
|
||||
commands: commands_1.default,
|
||||
createCommand: RedisCluster.#createCommand,
|
||||
createModuleCommand: RedisCluster.#createModuleCommand,
|
||||
createFunctionCommand: RedisCluster.#createFunctionCommand,
|
||||
createScriptCommand: RedisCluster.#createScriptCommand,
|
||||
config
|
||||
});
|
||||
Cluster.prototype.Multi = multi_command_1.default.extend(config);
|
||||
RedisCluster.#SingleEntryCache.set(config, Cluster);
|
||||
}
|
||||
return (options) => {
|
||||
// returning a "proxy" to prevent the namespaces._self to leak between "proxies"
|
||||
return Object.create(new Cluster(options));
|
||||
};
|
||||
}
|
||||
static create(options) {
|
||||
return RedisCluster.factory(options)(options);
|
||||
}
|
||||
_options;
|
||||
_slots;
|
||||
_self = this;
|
||||
_commandOptions;
|
||||
/**
|
||||
* An array of the cluster slots, each slot contain its `master` and `replicas`.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific node (master or replica).
|
||||
*/
|
||||
get slots() {
|
||||
return this._self._slots.slots;
|
||||
}
|
||||
get clientSideCache() {
|
||||
return this._self._slots.clientSideCache;
|
||||
}
|
||||
/**
|
||||
* An array of the cluster masters.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific master node.
|
||||
*/
|
||||
get masters() {
|
||||
return this._self._slots.masters;
|
||||
}
|
||||
/**
|
||||
* An array of the cluster replicas.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific replica node.
|
||||
*/
|
||||
get replicas() {
|
||||
return this._self._slots.replicas;
|
||||
}
|
||||
/**
|
||||
* A map form a node address (`<host>:<port>`) to its shard, each shard contain its `master` and `replicas`.
|
||||
* Use with {@link RedisCluster.prototype.nodeClient} to get the client for a specific node (master or replica).
|
||||
*/
|
||||
get nodeByAddress() {
|
||||
return this._self._slots.nodeByAddress;
|
||||
}
|
||||
/**
|
||||
* The current pub/sub node.
|
||||
*/
|
||||
get pubSubNode() {
|
||||
return this._self._slots.pubSubNode;
|
||||
}
|
||||
get isOpen() {
|
||||
return this._self._slots.isOpen;
|
||||
}
|
||||
constructor(options) {
|
||||
super();
|
||||
this._options = options;
|
||||
this._slots = new cluster_slots_1.default(options, this.emit.bind(this));
|
||||
this.on('__resubscribeAllPubSubListeners', this.resubscribeAllPubSubListeners.bind(this));
|
||||
if (options?.commandOptions) {
|
||||
this._commandOptions = options.commandOptions;
|
||||
}
|
||||
}
|
||||
duplicate(overrides) {
|
||||
return new (Object.getPrototypeOf(this).constructor)({
|
||||
...this._self._options,
|
||||
commandOptions: this._commandOptions,
|
||||
...overrides
|
||||
});
|
||||
}
|
||||
async connect() {
|
||||
await this._self._slots.connect();
|
||||
return this;
|
||||
}
|
||||
withCommandOptions(options) {
|
||||
const proxy = Object.create(this);
|
||||
proxy._commandOptions = options;
|
||||
return proxy;
|
||||
}
|
||||
_commandOptionsProxy(key, value) {
|
||||
const proxy = Object.create(this);
|
||||
proxy._commandOptions = Object.create(this._commandOptions ?? null);
|
||||
proxy._commandOptions[key] = value;
|
||||
return proxy;
|
||||
}
|
||||
/**
|
||||
* Override the `typeMapping` command option
|
||||
*/
|
||||
withTypeMapping(typeMapping) {
|
||||
return this._commandOptionsProxy('typeMapping', typeMapping);
|
||||
}
|
||||
// /**
|
||||
// * Override the `policies` command option
|
||||
// * TODO
|
||||
// */
|
||||
// withPolicies<POLICIES extends CommandPolicies> (policies: POLICIES) {
|
||||
// return this._commandOptionsProxy('policies', policies);
|
||||
// }
|
||||
_handleAsk(fn) {
|
||||
return async (client, options) => {
|
||||
const chainId = Symbol("asking chain");
|
||||
const opts = options ? { ...options } : {};
|
||||
opts.chainId = chainId;
|
||||
const ret = await Promise.all([
|
||||
client.sendCommand([ASKING_1.ASKING_CMD], { chainId: chainId }),
|
||||
fn(client, opts)
|
||||
]);
|
||||
return ret[1];
|
||||
};
|
||||
}
|
||||
async _execute(firstKey, isReadonly, options, fn) {
|
||||
const maxCommandRedirections = this._options.maxCommandRedirections ?? 16;
|
||||
let client = await this._slots.getClient(firstKey, isReadonly);
|
||||
let i = 0;
|
||||
let myFn = fn;
|
||||
while (true) {
|
||||
try {
|
||||
return await myFn(client, options);
|
||||
}
|
||||
catch (err) {
|
||||
myFn = fn;
|
||||
// TODO: error class
|
||||
if (++i > maxCommandRedirections || !(err instanceof Error)) {
|
||||
throw err;
|
||||
}
|
||||
if (err.message.startsWith('ASK')) {
|
||||
const address = err.message.substring(err.message.lastIndexOf(' ') + 1);
|
||||
let redirectTo = await this._slots.getMasterByAddress(address);
|
||||
if (!redirectTo) {
|
||||
await this._slots.rediscover(client);
|
||||
redirectTo = await this._slots.getMasterByAddress(address);
|
||||
}
|
||||
if (!redirectTo) {
|
||||
throw new Error(`Cannot find node ${address}`);
|
||||
}
|
||||
client = redirectTo;
|
||||
myFn = this._handleAsk(fn);
|
||||
continue;
|
||||
}
|
||||
if (err.message.startsWith('MOVED')) {
|
||||
await this._slots.rediscover(client);
|
||||
client = await this._slots.getClient(firstKey, isReadonly);
|
||||
continue;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
async sendCommand(firstKey, isReadonly, args, options) {
|
||||
// Merge global options with local options
|
||||
const opts = {
|
||||
...this._self._commandOptions,
|
||||
...options
|
||||
};
|
||||
return this._self._execute(firstKey, isReadonly, opts, (client, opts) => client.sendCommand(args, opts));
|
||||
}
|
||||
MULTI(routing) {
|
||||
return new this.Multi(async (firstKey, isReadonly, commands) => {
|
||||
const client = await this._self._slots.getClient(firstKey, isReadonly);
|
||||
return client._executeMulti(commands);
|
||||
}, async (firstKey, isReadonly, commands) => {
|
||||
const client = await this._self._slots.getClient(firstKey, isReadonly);
|
||||
return client._executePipeline(commands);
|
||||
}, routing, this._commandOptions?.typeMapping);
|
||||
}
|
||||
multi = this.MULTI;
|
||||
async SUBSCRIBE(channels, listener, bufferMode) {
|
||||
return (await this._self._slots.getPubSubClient())
|
||||
.SUBSCRIBE(channels, listener, bufferMode);
|
||||
}
|
||||
subscribe = this.SUBSCRIBE;
|
||||
async UNSUBSCRIBE(channels, listener, bufferMode) {
|
||||
return this._self._slots.executeUnsubscribeCommand(client => client.UNSUBSCRIBE(channels, listener, bufferMode));
|
||||
}
|
||||
unsubscribe = this.UNSUBSCRIBE;
|
||||
async PSUBSCRIBE(patterns, listener, bufferMode) {
|
||||
return (await this._self._slots.getPubSubClient())
|
||||
.PSUBSCRIBE(patterns, listener, bufferMode);
|
||||
}
|
||||
pSubscribe = this.PSUBSCRIBE;
|
||||
async PUNSUBSCRIBE(patterns, listener, bufferMode) {
|
||||
return this._self._slots.executeUnsubscribeCommand(client => client.PUNSUBSCRIBE(patterns, listener, bufferMode));
|
||||
}
|
||||
pUnsubscribe = this.PUNSUBSCRIBE;
|
||||
async SSUBSCRIBE(channels, listener, bufferMode) {
|
||||
const maxCommandRedirections = this._self._options.maxCommandRedirections ?? 16, firstChannel = Array.isArray(channels) ? channels[0] : channels;
|
||||
let client = await this._self._slots.getShardedPubSubClient(firstChannel);
|
||||
for (let i = 0;; i++) {
|
||||
try {
|
||||
return await client.SSUBSCRIBE(channels, listener, bufferMode);
|
||||
}
|
||||
catch (err) {
|
||||
if (++i > maxCommandRedirections || !(err instanceof errors_1.ErrorReply)) {
|
||||
throw err;
|
||||
}
|
||||
if (err.message.startsWith('MOVED')) {
|
||||
await this._self._slots.rediscover(client);
|
||||
client = await this._self._slots.getShardedPubSubClient(firstChannel);
|
||||
continue;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
sSubscribe = this.SSUBSCRIBE;
|
||||
SUNSUBSCRIBE(channels, listener, bufferMode) {
|
||||
return this._self._slots.executeShardedUnsubscribeCommand(Array.isArray(channels) ? channels[0] : channels, client => client.SUNSUBSCRIBE(channels, listener, bufferMode));
|
||||
}
|
||||
resubscribeAllPubSubListeners(allListeners) {
|
||||
for (const [channel, listeners] of allListeners.CHANNELS) {
|
||||
listeners.buffers.forEach(bufListener => {
|
||||
this.subscribe(channel, bufListener, true);
|
||||
});
|
||||
listeners.strings.forEach(strListener => {
|
||||
this.subscribe(channel, strListener);
|
||||
});
|
||||
}
|
||||
;
|
||||
for (const [channel, listeners] of allListeners.PATTERNS) {
|
||||
listeners.buffers.forEach(bufListener => {
|
||||
this.pSubscribe(channel, bufListener, true);
|
||||
});
|
||||
listeners.strings.forEach(strListener => {
|
||||
this.pSubscribe(channel, strListener);
|
||||
});
|
||||
}
|
||||
;
|
||||
for (const [channel, listeners] of allListeners.SHARDED) {
|
||||
listeners.buffers.forEach(bufListener => {
|
||||
this.sSubscribe(channel, bufListener, true);
|
||||
});
|
||||
listeners.strings.forEach(strListener => {
|
||||
this.sSubscribe(channel, strListener);
|
||||
});
|
||||
}
|
||||
;
|
||||
}
|
||||
sUnsubscribe = this.SUNSUBSCRIBE;
|
||||
/**
|
||||
* @deprecated Use `close` instead.
|
||||
*/
|
||||
quit() {
|
||||
return this._self._slots.quit();
|
||||
}
|
||||
/**
|
||||
* @deprecated Use `destroy` instead.
|
||||
*/
|
||||
disconnect() {
|
||||
return this._self._slots.disconnect();
|
||||
}
|
||||
close() {
|
||||
this._self._slots.clientSideCache?.onPoolClose();
|
||||
return this._self._slots.close();
|
||||
}
|
||||
destroy() {
|
||||
this._self._slots.clientSideCache?.onPoolClose();
|
||||
return this._self._slots.destroy();
|
||||
}
|
||||
nodeClient(node) {
|
||||
return this._self._slots.nodeClient(node);
|
||||
}
|
||||
/**
|
||||
* Returns a random node from the cluster.
|
||||
* Userful for running "forward" commands (like PUBLISH) on a random node.
|
||||
*/
|
||||
getRandomNode() {
|
||||
return this._self._slots.getRandomNode();
|
||||
}
|
||||
/**
|
||||
* Get a random node from a slot.
|
||||
* Useful for running readonly commands on a slot.
|
||||
*/
|
||||
getSlotRandomNode(slot) {
|
||||
return this._self._slots.getSlotRandomNode(slot);
|
||||
}
|
||||
/**
|
||||
* @deprecated use `.masters` instead
|
||||
* TODO
|
||||
*/
|
||||
getMasters() {
|
||||
return this.masters;
|
||||
}
|
||||
/**
|
||||
* @deprecated use `.slots[<SLOT>]` instead
|
||||
* TODO
|
||||
*/
|
||||
getSlotMaster(slot) {
|
||||
return this.slots[slot].master;
|
||||
}
|
||||
}
|
||||
exports.default = RedisCluster;
|
||||
//# sourceMappingURL=index.js.map
|
||||
1
node_modules/@redis/client/dist/lib/cluster/index.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/cluster/index.js.map
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
39
node_modules/@redis/client/dist/lib/cluster/multi-command.d.ts
generated
vendored
Normal file
39
node_modules/@redis/client/dist/lib/cluster/multi-command.d.ts
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
import COMMANDS from '../commands';
|
||||
import { MULTI_REPLY, MultiReply, MultiReplyType, RedisMultiQueuedCommand } from '../multi-command';
|
||||
import { ReplyWithTypeMapping, CommandReply, Command, CommandArguments, CommanderConfig, RedisFunctions, RedisModules, RedisScripts, RespVersions, TransformReply, TypeMapping, RedisArgument } from '../RESP/types';
|
||||
import { Tail } from '../commands/generic-transformers';
|
||||
type CommandSignature<REPLIES extends Array<unknown>, C extends Command, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = (...args: Tail<Parameters<C['parseCommand']>>) => RedisClusterMultiCommandType<[
|
||||
...REPLIES,
|
||||
ReplyWithTypeMapping<CommandReply<C, RESP>, TYPE_MAPPING>
|
||||
], M, F, S, RESP, TYPE_MAPPING>;
|
||||
type WithCommands<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof typeof COMMANDS]: CommandSignature<REPLIES, (typeof COMMANDS)[P], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
type WithModules<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof M]: {
|
||||
[C in keyof M[P]]: CommandSignature<REPLIES, M[P][C], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
};
|
||||
type WithFunctions<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[L in keyof F]: {
|
||||
[C in keyof F[L]]: CommandSignature<REPLIES, F[L][C], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
};
|
||||
type WithScripts<REPLIES extends Array<unknown>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = {
|
||||
[P in keyof S]: CommandSignature<REPLIES, S[P], M, F, S, RESP, TYPE_MAPPING>;
|
||||
};
|
||||
export type RedisClusterMultiCommandType<REPLIES extends Array<any>, M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions, TYPE_MAPPING extends TypeMapping> = (RedisClusterMultiCommand<REPLIES> & WithCommands<REPLIES, M, F, S, RESP, TYPE_MAPPING> & WithModules<REPLIES, M, F, S, RESP, TYPE_MAPPING> & WithFunctions<REPLIES, M, F, S, RESP, TYPE_MAPPING> & WithScripts<REPLIES, M, F, S, RESP, TYPE_MAPPING>);
|
||||
export type ClusterMultiExecute = (firstKey: RedisArgument | undefined, isReadonly: boolean | undefined, commands: Array<RedisMultiQueuedCommand>) => Promise<Array<unknown>>;
|
||||
export default class RedisClusterMultiCommand<REPLIES = []> {
|
||||
#private;
|
||||
static extend<M extends RedisModules = Record<string, never>, F extends RedisFunctions = Record<string, never>, S extends RedisScripts = Record<string, never>, RESP extends RespVersions = 2>(config?: CommanderConfig<M, F, S, RESP>): any;
|
||||
constructor(executeMulti: ClusterMultiExecute, executePipeline: ClusterMultiExecute, routing: RedisArgument | undefined, typeMapping?: TypeMapping);
|
||||
addCommand(firstKey: RedisArgument | undefined, isReadonly: boolean | undefined, args: CommandArguments, transformReply?: TransformReply): this;
|
||||
exec<T extends MultiReply = MULTI_REPLY['GENERIC']>(execAsPipeline?: boolean): Promise<MultiReplyType<T, REPLIES>>;
|
||||
EXEC: <T extends MultiReply = "generic">(execAsPipeline?: boolean) => Promise<MultiReplyType<T, REPLIES>>;
|
||||
execTyped(execAsPipeline?: boolean): Promise<REPLIES>;
|
||||
execAsPipeline<T extends MultiReply = MULTI_REPLY['GENERIC']>(): Promise<MultiReplyType<T, REPLIES>>;
|
||||
execAsPipelineTyped(): Promise<REPLIES>;
|
||||
}
|
||||
export {};
|
||||
//# sourceMappingURL=multi-command.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/cluster/multi-command.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/cluster/multi-command.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"multi-command.d.ts","sourceRoot":"","sources":["../../../lib/cluster/multi-command.ts"],"names":[],"mappings":"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"}
|
||||
112
node_modules/@redis/client/dist/lib/cluster/multi-command.js
generated
vendored
Normal file
112
node_modules/@redis/client/dist/lib/cluster/multi-command.js
generated
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const commands_1 = __importDefault(require("../commands"));
|
||||
const multi_command_1 = __importDefault(require("../multi-command"));
|
||||
const commander_1 = require("../commander");
|
||||
const parser_1 = require("../client/parser");
|
||||
class RedisClusterMultiCommand {
|
||||
static #createCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
const redisArgs = parser.redisArgs;
|
||||
redisArgs.preserve = parser.preserve;
|
||||
const firstKey = parser.firstKey;
|
||||
return this.addCommand(firstKey, command.IS_READ_ONLY, redisArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static #createModuleCommand(command, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(command, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
command.parseCommand(parser, ...args);
|
||||
const redisArgs = parser.redisArgs;
|
||||
redisArgs.preserve = parser.preserve;
|
||||
const firstKey = parser.firstKey;
|
||||
return this._self.addCommand(firstKey, command.IS_READ_ONLY, redisArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static #createFunctionCommand(name, fn, resp) {
|
||||
const prefix = (0, commander_1.functionArgumentsPrefix)(name, fn);
|
||||
const transformReply = (0, commander_1.getTransformReply)(fn, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
parser.push(...prefix);
|
||||
fn.parseCommand(parser, ...args);
|
||||
const redisArgs = parser.redisArgs;
|
||||
redisArgs.preserve = parser.preserve;
|
||||
const firstKey = parser.firstKey;
|
||||
return this._self.addCommand(firstKey, fn.IS_READ_ONLY, redisArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static #createScriptCommand(script, resp) {
|
||||
const transformReply = (0, commander_1.getTransformReply)(script, resp);
|
||||
return function (...args) {
|
||||
const parser = new parser_1.BasicCommandParser();
|
||||
script.parseCommand(parser, ...args);
|
||||
const scriptArgs = parser.redisArgs;
|
||||
scriptArgs.preserve = parser.preserve;
|
||||
const firstKey = parser.firstKey;
|
||||
return this.#addScript(firstKey, script.IS_READ_ONLY, script, scriptArgs, transformReply);
|
||||
};
|
||||
}
|
||||
static extend(config) {
|
||||
return (0, commander_1.attachConfig)({
|
||||
BaseClass: RedisClusterMultiCommand,
|
||||
commands: commands_1.default,
|
||||
createCommand: RedisClusterMultiCommand.#createCommand,
|
||||
createModuleCommand: RedisClusterMultiCommand.#createModuleCommand,
|
||||
createFunctionCommand: RedisClusterMultiCommand.#createFunctionCommand,
|
||||
createScriptCommand: RedisClusterMultiCommand.#createScriptCommand,
|
||||
config
|
||||
});
|
||||
}
|
||||
#multi;
|
||||
#executeMulti;
|
||||
#executePipeline;
|
||||
#firstKey;
|
||||
#isReadonly = true;
|
||||
constructor(executeMulti, executePipeline, routing, typeMapping) {
|
||||
this.#multi = new multi_command_1.default(typeMapping);
|
||||
this.#executeMulti = executeMulti;
|
||||
this.#executePipeline = executePipeline;
|
||||
this.#firstKey = routing;
|
||||
}
|
||||
#setState(firstKey, isReadonly) {
|
||||
this.#firstKey ??= firstKey;
|
||||
this.#isReadonly &&= isReadonly;
|
||||
}
|
||||
addCommand(firstKey, isReadonly, args, transformReply) {
|
||||
this.#setState(firstKey, isReadonly);
|
||||
this.#multi.addCommand(args, transformReply);
|
||||
return this;
|
||||
}
|
||||
#addScript(firstKey, isReadonly, script, args, transformReply) {
|
||||
this.#setState(firstKey, isReadonly);
|
||||
this.#multi.addScript(script, args, transformReply);
|
||||
return this;
|
||||
}
|
||||
async exec(execAsPipeline = false) {
|
||||
if (execAsPipeline)
|
||||
return this.execAsPipeline();
|
||||
return this.#multi.transformReplies(await this.#executeMulti(this.#firstKey, this.#isReadonly, this.#multi.queue));
|
||||
}
|
||||
EXEC = this.exec;
|
||||
execTyped(execAsPipeline = false) {
|
||||
return this.exec(execAsPipeline);
|
||||
}
|
||||
async execAsPipeline() {
|
||||
if (this.#multi.queue.length === 0)
|
||||
return [];
|
||||
return this.#multi.transformReplies(await this.#executePipeline(this.#firstKey, this.#isReadonly, this.#multi.queue));
|
||||
}
|
||||
execAsPipelineTyped() {
|
||||
return this.execAsPipeline();
|
||||
}
|
||||
}
|
||||
exports.default = RedisClusterMultiCommand;
|
||||
//# sourceMappingURL=multi-command.js.map
|
||||
1
node_modules/@redis/client/dist/lib/cluster/multi-command.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/cluster/multi-command.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"multi-command.js","sourceRoot":"","sources":["../../../lib/cluster/multi-command.ts"],"names":[],"mappings":"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"}
|
||||
17
node_modules/@redis/client/dist/lib/commander.d.ts
generated
vendored
Normal file
17
node_modules/@redis/client/dist/lib/commander.d.ts
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
/// <reference types="node" />
|
||||
import { Command, CommanderConfig, RedisArgument, RedisCommands, RedisFunction, RedisFunctions, RedisModules, RedisScript, RedisScripts, RespVersions, TransformReply } from './RESP/types';
|
||||
interface AttachConfigOptions<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions> {
|
||||
BaseClass: new (...args: any) => any;
|
||||
commands: RedisCommands;
|
||||
createCommand(command: Command, resp: RespVersions): (...args: any) => any;
|
||||
createModuleCommand(command: Command, resp: RespVersions): (...args: any) => any;
|
||||
createFunctionCommand(name: string, fn: RedisFunction, resp: RespVersions): (...args: any) => any;
|
||||
createScriptCommand(script: RedisScript, resp: RespVersions): (...args: any) => any;
|
||||
config?: CommanderConfig<M, F, S, RESP>;
|
||||
}
|
||||
export declare function attachConfig<M extends RedisModules, F extends RedisFunctions, S extends RedisScripts, RESP extends RespVersions>({ BaseClass, commands, createCommand, createModuleCommand, createFunctionCommand, createScriptCommand, config }: AttachConfigOptions<M, F, S, RESP>): any;
|
||||
export declare function getTransformReply(command: Command, resp: RespVersions): TransformReply | undefined;
|
||||
export declare function functionArgumentsPrefix(name: string, fn: RedisFunction): RedisArgument[];
|
||||
export declare function scriptArgumentsPrefix(script: RedisScript): (string | Buffer)[];
|
||||
export {};
|
||||
//# sourceMappingURL=commander.d.ts.map
|
||||
1
node_modules/@redis/client/dist/lib/commander.d.ts.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/commander.d.ts.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"commander.d.ts","sourceRoot":"","sources":["../../lib/commander.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE5L,UAAU,mBAAmB,CAC3B,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY;IAEzB,SAAS,EAAE,KAAK,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IACrC,QAAQ,EAAE,aAAa,CAAC;IACxB,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IAC3E,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IACjF,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IAClG,mBAAmB,CAAC,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,YAAY,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;IACpF,MAAM,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;CACzC;AAOD,wBAAgB,YAAY,CAC1B,CAAC,SAAS,YAAY,EACtB,CAAC,SAAS,cAAc,EACxB,CAAC,SAAS,YAAY,EACtB,IAAI,SAAS,YAAY,EACzB,EACA,SAAS,EACT,QAAQ,EACR,aAAa,EACb,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,MAAM,EACP,EAAE,mBAAmB,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,OA6CpC;AAaD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,YAAY,GAAG,cAAc,GAAG,SAAS,CAQlG;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,mBAWtE;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,WAAW,uBAWxD"}
|
||||
91
node_modules/@redis/client/dist/lib/commander.js
generated
vendored
Normal file
91
node_modules/@redis/client/dist/lib/commander.js
generated
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.scriptArgumentsPrefix = exports.functionArgumentsPrefix = exports.getTransformReply = exports.attachConfig = void 0;
|
||||
/* FIXME: better error message / link */
|
||||
function throwResp3SearchModuleUnstableError() {
|
||||
throw new Error('Some RESP3 results for Redis Query Engine responses may change. Refer to the readme for guidance');
|
||||
}
|
||||
function attachConfig({ BaseClass, commands, createCommand, createModuleCommand, createFunctionCommand, createScriptCommand, config }) {
|
||||
const RESP = config?.RESP ?? 2, Class = class extends BaseClass {
|
||||
};
|
||||
for (const [name, command] of Object.entries(commands)) {
|
||||
if (config?.RESP == 3 && command.unstableResp3 && !config.unstableResp3) {
|
||||
Class.prototype[name] = throwResp3SearchModuleUnstableError;
|
||||
}
|
||||
else {
|
||||
Class.prototype[name] = createCommand(command, RESP);
|
||||
}
|
||||
}
|
||||
if (config?.modules) {
|
||||
for (const [moduleName, module] of Object.entries(config.modules)) {
|
||||
const fns = Object.create(null);
|
||||
for (const [name, command] of Object.entries(module)) {
|
||||
if (config.RESP == 3 && command.unstableResp3 && !config.unstableResp3) {
|
||||
fns[name] = throwResp3SearchModuleUnstableError;
|
||||
}
|
||||
else {
|
||||
fns[name] = createModuleCommand(command, RESP);
|
||||
}
|
||||
}
|
||||
attachNamespace(Class.prototype, moduleName, fns);
|
||||
}
|
||||
}
|
||||
if (config?.functions) {
|
||||
for (const [library, commands] of Object.entries(config.functions)) {
|
||||
const fns = Object.create(null);
|
||||
for (const [name, command] of Object.entries(commands)) {
|
||||
fns[name] = createFunctionCommand(name, command, RESP);
|
||||
}
|
||||
attachNamespace(Class.prototype, library, fns);
|
||||
}
|
||||
}
|
||||
if (config?.scripts) {
|
||||
for (const [name, script] of Object.entries(config.scripts)) {
|
||||
Class.prototype[name] = createScriptCommand(script, RESP);
|
||||
}
|
||||
}
|
||||
return Class;
|
||||
}
|
||||
exports.attachConfig = attachConfig;
|
||||
function attachNamespace(prototype, name, fns) {
|
||||
Object.defineProperty(prototype, name, {
|
||||
get() {
|
||||
const value = Object.create(fns);
|
||||
value._self = this;
|
||||
Object.defineProperty(this, name, { value });
|
||||
return value;
|
||||
}
|
||||
});
|
||||
}
|
||||
function getTransformReply(command, resp) {
|
||||
switch (typeof command.transformReply) {
|
||||
case 'function':
|
||||
return command.transformReply;
|
||||
case 'object':
|
||||
return command.transformReply[resp];
|
||||
}
|
||||
}
|
||||
exports.getTransformReply = getTransformReply;
|
||||
function functionArgumentsPrefix(name, fn) {
|
||||
const prefix = [
|
||||
fn.IS_READ_ONLY ? 'FCALL_RO' : 'FCALL',
|
||||
name
|
||||
];
|
||||
if (fn.NUMBER_OF_KEYS !== undefined) {
|
||||
prefix.push(fn.NUMBER_OF_KEYS.toString());
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
exports.functionArgumentsPrefix = functionArgumentsPrefix;
|
||||
function scriptArgumentsPrefix(script) {
|
||||
const prefix = [
|
||||
script.IS_READ_ONLY ? 'EVALSHA_RO' : 'EVALSHA',
|
||||
script.SHA1
|
||||
];
|
||||
if (script.NUMBER_OF_KEYS !== undefined) {
|
||||
prefix.push(script.NUMBER_OF_KEYS.toString());
|
||||
}
|
||||
return prefix;
|
||||
}
|
||||
exports.scriptArgumentsPrefix = scriptArgumentsPrefix;
|
||||
//# sourceMappingURL=commander.js.map
|
||||
1
node_modules/@redis/client/dist/lib/commander.js.map
generated
vendored
Normal file
1
node_modules/@redis/client/dist/lib/commander.js.map
generated
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"commander.js","sourceRoot":"","sources":["../../lib/commander.ts"],"names":[],"mappings":"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"}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user