ioredis 5.7.0 → 5.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -41,6 +41,10 @@ class DataHandler {
41
41
  name: item.command.name,
42
42
  args: item.command.args,
43
43
  };
44
+ if (item.command.name == "ssubscribe" && err.message.includes("MOVED")) {
45
+ this.redis.emit("moved");
46
+ return;
47
+ }
44
48
  this.redis.handleReconnection(err, item);
45
49
  }
46
50
  returnReply(reply) {
@@ -131,6 +131,9 @@ class ClusterSubscriber {
131
131
  });
132
132
  // Ignore the errors since they're handled in the connection pool.
133
133
  this.subscriber.on("error", utils_1.noop);
134
+ this.subscriber.on("moved", () => {
135
+ this.emitter.emit("forceRefresh");
136
+ });
134
137
  // The node we lost connection to may not come back up in a
135
138
  // reasonable amount of time (e.g. a slave that's taken down
136
139
  // for maintainence), we could potentially miss many published
@@ -23,7 +23,7 @@ export default class ClusterSubscriberGroup {
23
23
  *
24
24
  * @param cluster
25
25
  */
26
- constructor(cluster: Cluster);
26
+ constructor(cluster: Cluster, refreshSlotsCacheCallback: () => void);
27
27
  /**
28
28
  * Get the responsible subscriber.
29
29
  *
@@ -23,7 +23,7 @@ class ClusterSubscriberGroup {
23
23
  *
24
24
  * @param cluster
25
25
  */
26
- constructor(cluster) {
26
+ constructor(cluster, refreshSlotsCacheCallback) {
27
27
  this.cluster = cluster;
28
28
  this.shardedSubscribers = new Map();
29
29
  this.clusterSlots = [];
@@ -39,6 +39,9 @@ class ClusterSubscriberGroup {
39
39
  cluster.on("refresh", () => {
40
40
  this._refreshSlots(cluster);
41
41
  });
42
+ cluster.on("forceRefresh", () => {
43
+ refreshSlotsCacheCallback();
44
+ });
42
45
  }
43
46
  /**
44
47
  * Get the responsible subscriber.
@@ -63,7 +63,7 @@ class Cluster extends Commander_1.default {
63
63
  this.startupNodes = startupNodes;
64
64
  this.options = (0, utils_1.defaults)({}, options, ClusterOptions_1.DEFAULT_CLUSTER_OPTIONS, this.options);
65
65
  if (this.options.shardedSubscribers == true)
66
- this.shardedSubscribers = new ClusterSubscriberGroup_1.default(this);
66
+ this.shardedSubscribers = new ClusterSubscriberGroup_1.default(this, this.refreshSlotsCache.bind(this));
67
67
  if (this.options.redisOptions &&
68
68
  this.options.redisOptions.keyPrefix &&
69
69
  !this.options.keyPrefix) {
@@ -36,6 +36,18 @@ export interface CommonRedisOptions extends CommanderOptions {
36
36
  * @link https://redis.io/commands/client-setname
37
37
  */
38
38
  connectionName?: string;
39
+ /**
40
+ * If true, skips setting library info via CLIENT SETINFO.
41
+ * @link https://redis.io/docs/latest/commands/client-setinfo/
42
+ * @default false
43
+ */
44
+ disableClientInfo?: boolean;
45
+ /**
46
+ * Tag to append to the library name in CLIENT SETINFO (ioredis(tag)).
47
+ * @link https://redis.io/docs/latest/commands/client-setinfo/
48
+ * @default undefined
49
+ */
50
+ clientInfoTag?: string;
39
51
  /**
40
52
  * If set, client will send AUTH command with the value of this option as the first argument when connected.
41
53
  * This is supported since Redis 6.
@@ -14,6 +14,8 @@ exports.DEFAULT_REDIS_OPTIONS = {
14
14
  keepAlive: 0,
15
15
  noDelay: true,
16
16
  connectionName: null,
17
+ disableClientInfo: false,
18
+ clientInfoTag: undefined,
17
19
  // Sentinel
18
20
  sentinels: null,
19
21
  name: null,
@@ -199,6 +199,7 @@ function errorHandler(self) {
199
199
  exports.errorHandler = errorHandler;
200
200
  function readyHandler(self) {
201
201
  return function () {
202
+ var _a, _b;
202
203
  self.setStatus("ready");
203
204
  self.retryAttempts = 0;
204
205
  if (self.options.monitor) {
@@ -223,6 +224,25 @@ function readyHandler(self) {
223
224
  debug("set the connection name [%s]", self.options.connectionName);
224
225
  self.client("setname", self.options.connectionName).catch(utils_1.noop);
225
226
  }
227
+ if (!((_a = self.options) === null || _a === void 0 ? void 0 : _a.disableClientInfo)) {
228
+ debug("set the client info");
229
+ let version = null;
230
+ (0, utils_1.getPackageMeta)()
231
+ .then((packageMeta) => {
232
+ version = packageMeta === null || packageMeta === void 0 ? void 0 : packageMeta.version;
233
+ })
234
+ .catch(utils_1.noop)
235
+ .finally(() => {
236
+ self
237
+ .client("SETINFO", "LIB-VER", version)
238
+ .catch(utils_1.noop);
239
+ });
240
+ self
241
+ .client("SETINFO", "LIB-NAME", ((_b = self.options) === null || _b === void 0 ? void 0 : _b.clientInfoTag)
242
+ ? `ioredis(${self.options.clientInfoTag})`
243
+ : "ioredis")
244
+ .catch(utils_1.noop);
245
+ }
226
246
  if (self.options.readOnly) {
227
247
  debug("set the connection to readonly mode");
228
248
  self.readonly().catch(utils_1.noop);
@@ -249,8 +269,10 @@ function readyHandler(self) {
249
269
  }
250
270
  const ssubscribeChannels = condition.subscriber.channels("ssubscribe");
251
271
  if (ssubscribeChannels.length) {
252
- debug("ssubscribe %d channels", ssubscribeChannels.length);
253
- self.ssubscribe(ssubscribeChannels);
272
+ debug("ssubscribe %s", ssubscribeChannels.length);
273
+ for (const channel of ssubscribeChannels) {
274
+ self.ssubscribe(channel);
275
+ }
254
276
  }
255
277
  }
256
278
  }
@@ -2341,6 +2341,22 @@ interface RedisCommander<Context extends ClientContext = {
2341
2341
  callback: Callback<"OK">
2342
2342
  ]): Result<"OK", Context>;
2343
2343
  hmset(...args: [key: RedisKey, ...fieldValues: (string | Buffer | number)[]]): Result<"OK", Context>;
2344
+ /**
2345
+ * Set expiry for hash field using relative time to expire (milliseconds)
2346
+ * - _group_: hash
2347
+ * - _complexity_: O(N) where N is the number of specified fields
2348
+ * - _since_: 7.4.0
2349
+ */
2350
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
2351
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
2352
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, nx: 'NX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
2353
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, nx: 'NX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
2354
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, xx: 'XX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
2355
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, xx: 'XX', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
2356
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, gt: 'GT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
2357
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, gt: 'GT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
2358
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, lt: 'LT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[], callback: Callback<number[]>]): Result<number[], Context>;
2359
+ hpexpire(...args: [key: RedisKey, milliseconds: number | string, lt: 'LT', fieldsToken: 'FIELDS', numfields: number | string, ...fields: (string | Buffer)[]]): Result<number[], Context>;
2344
2360
  /**
2345
2361
  * Get one or multiple random fields from a hash
2346
2362
  * - _group_: hash
@@ -5331,6 +5347,70 @@ interface RedisCommander<Context extends ClientContext = {
5331
5347
  callback: Callback<number>
5332
5348
  ]): Result<number, Context>;
5333
5349
  xdel(...args: [key: RedisKey, ...ids: (string | Buffer | number)[]]): Result<number, Context>;
5350
+ /**
5351
+ * Deletes one or multiple entries from the stream.
5352
+ * - _group_: stream
5353
+ * - _complexity_: O(1) for each single item to delete in the stream, regardless of the stream size.
5354
+ * - _since_: 8.2.0
5355
+ */
5356
+ xdelex(...args: [
5357
+ key: RedisKey,
5358
+ idsToken: "IDS",
5359
+ numids: number | string,
5360
+ ...ids: (string | Buffer | number)[],
5361
+ callback: Callback<unknown>
5362
+ ]): Result<unknown, Context>;
5363
+ xdelex(...args: [
5364
+ key: RedisKey,
5365
+ idsToken: "IDS",
5366
+ numids: number | string,
5367
+ ...ids: (string | Buffer | number)[]
5368
+ ]): Result<unknown, Context>;
5369
+ xdelex(...args: [
5370
+ key: RedisKey,
5371
+ keepref: "KEEPREF",
5372
+ idsToken: "IDS",
5373
+ numids: number | string,
5374
+ ...ids: (string | Buffer | number)[],
5375
+ callback: Callback<unknown>
5376
+ ]): Result<unknown, Context>;
5377
+ xdelex(...args: [
5378
+ key: RedisKey,
5379
+ keepref: "KEEPREF",
5380
+ idsToken: "IDS",
5381
+ numids: number | string,
5382
+ ...ids: (string | Buffer | number)[]
5383
+ ]): Result<unknown, Context>;
5384
+ xdelex(...args: [
5385
+ key: RedisKey,
5386
+ delref: "DELREF",
5387
+ idsToken: "IDS",
5388
+ numids: number | string,
5389
+ ...ids: (string | Buffer | number)[],
5390
+ callback: Callback<unknown>
5391
+ ]): Result<unknown, Context>;
5392
+ xdelex(...args: [
5393
+ key: RedisKey,
5394
+ delref: "DELREF",
5395
+ idsToken: "IDS",
5396
+ numids: number | string,
5397
+ ...ids: (string | Buffer | number)[]
5398
+ ]): Result<unknown, Context>;
5399
+ xdelex(...args: [
5400
+ key: RedisKey,
5401
+ acked: "ACKED",
5402
+ idsToken: "IDS",
5403
+ numids: number | string,
5404
+ ...ids: (string | Buffer | number)[],
5405
+ callback: Callback<unknown>
5406
+ ]): Result<unknown, Context>;
5407
+ xdelex(...args: [
5408
+ key: RedisKey,
5409
+ acked: "ACKED",
5410
+ idsToken: "IDS",
5411
+ numids: number | string,
5412
+ ...ids: (string | Buffer | number)[]
5413
+ ]): Result<unknown, Context>;
5334
5414
  /**
5335
5415
  * Create a consumer group.
5336
5416
  * - _group_: stream
@@ -5804,23 +5884,59 @@ interface RedisCommander<Context extends ClientContext = {
5804
5884
  xsetid(key: RedisKey, lastId: string | Buffer | number, entriesAddedToken: "ENTRIESADDED", entriesAdded: number | string, callback?: Callback<unknown>): Result<unknown, Context>;
5805
5885
  xsetid(key: RedisKey, lastId: string | Buffer | number, entriesAddedToken: "ENTRIESADDED", entriesAdded: number | string, maxDeletedEntryIdToken: "MAXDELETEDID", maxDeletedEntryId: string | Buffer | number, callback?: Callback<unknown>): Result<unknown, Context>;
5806
5886
  /**
5807
- * Trims the stream to (approximately if '~' is passed) a certain size
5887
+ * Deletes messages from the beginning of a stream.
5808
5888
  * - _group_: stream
5809
5889
  * - _complexity_: O(N), with N being the number of evicted entries. Constant times are very small however, since entries are organized in macro nodes containing multiple entries that can be released with a single deallocation.
5810
5890
  * - _since_: 5.0.0
5811
5891
  */
5812
5892
  xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, callback?: Callback<number>): Result<number, Context>;
5893
+ xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5894
+ xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5895
+ xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5813
5896
  xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, callback?: Callback<number>): Result<number, Context>;
5897
+ xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5898
+ xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5899
+ xtrim(key: RedisKey, maxlen: "MAXLEN", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5814
5900
  xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, callback?: Callback<number>): Result<number, Context>;
5901
+ xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5902
+ xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5903
+ xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5815
5904
  xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, callback?: Callback<number>): Result<number, Context>;
5905
+ xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5906
+ xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5907
+ xtrim(key: RedisKey, maxlen: "MAXLEN", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5816
5908
  xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, callback?: Callback<number>): Result<number, Context>;
5909
+ xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5910
+ xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5911
+ xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5817
5912
  xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, callback?: Callback<number>): Result<number, Context>;
5913
+ xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5914
+ xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5915
+ xtrim(key: RedisKey, maxlen: "MAXLEN", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5818
5916
  xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, callback?: Callback<number>): Result<number, Context>;
5917
+ xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5918
+ xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5919
+ xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5819
5920
  xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, callback?: Callback<number>): Result<number, Context>;
5921
+ xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5922
+ xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5923
+ xtrim(key: RedisKey, minid: "MINID", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5820
5924
  xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, callback?: Callback<number>): Result<number, Context>;
5925
+ xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5926
+ xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5927
+ xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5821
5928
  xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, callback?: Callback<number>): Result<number, Context>;
5929
+ xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5930
+ xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5931
+ xtrim(key: RedisKey, minid: "MINID", equal: "=", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5822
5932
  xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, callback?: Callback<number>): Result<number, Context>;
5933
+ xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5934
+ xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5935
+ xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5823
5936
  xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, callback?: Callback<number>): Result<number, Context>;
5937
+ xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, keepref: "KEEPREF", callback?: Callback<number>): Result<number, Context>;
5938
+ xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, delref: "DELREF", callback?: Callback<number>): Result<number, Context>;
5939
+ xtrim(key: RedisKey, minid: "MINID", approximately: "~", threshold: string | Buffer | number, countToken: "LIMIT", count: number | string, acked: "ACKED", callback?: Callback<number>): Result<number, Context>;
5824
5940
  /**
5825
5941
  * Add one or more members to a sorted set, or update its score if it already exists
5826
5942
  * - _group_: sorted-set
@@ -112,4 +112,13 @@ export declare function shuffle<T>(array: T[]): T[];
112
112
  */
113
113
  export declare const CONNECTION_CLOSED_ERROR_MSG = "Connection is closed.";
114
114
  export declare function zipMap<K, V>(keys: K[], values: V[]): Map<K, V>;
115
+ /**
116
+ * Retrieves cached package metadata from package.json.
117
+ *
118
+ * @internal
119
+ * @returns {Promise<{version: string} | null>} Package metadata or null if unavailable
120
+ */
121
+ export declare function getPackageMeta(): Promise<{
122
+ version: string;
123
+ }>;
115
124
  export { Debug, defaults, noop };
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.noop = exports.defaults = exports.Debug = exports.zipMap = exports.CONNECTION_CLOSED_ERROR_MSG = exports.shuffle = exports.sample = exports.resolveTLSProfile = exports.parseURL = exports.optimizeErrorStack = exports.toArg = exports.convertMapToArray = exports.convertObjectToArray = exports.timeout = exports.packObject = exports.isInt = exports.wrapMultiResult = exports.convertBufferToString = void 0;
3
+ exports.noop = exports.defaults = exports.Debug = exports.getPackageMeta = exports.zipMap = exports.CONNECTION_CLOSED_ERROR_MSG = exports.shuffle = exports.sample = exports.resolveTLSProfile = exports.parseURL = exports.optimizeErrorStack = exports.toArg = exports.convertMapToArray = exports.convertObjectToArray = exports.timeout = exports.packObject = exports.isInt = exports.wrapMultiResult = exports.convertBufferToString = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
4
6
  const url_1 = require("url");
5
7
  const lodash_1 = require("./lodash");
6
8
  Object.defineProperty(exports, "defaults", { enumerable: true, get: function () { return lodash_1.defaults; } });
@@ -295,3 +297,36 @@ function zipMap(keys, values) {
295
297
  return map;
296
298
  }
297
299
  exports.zipMap = zipMap;
300
+ /**
301
+ * Memoized package metadata to avoid repeated file system reads.
302
+ *
303
+ * @internal
304
+ */
305
+ let cachedPackageMeta = null;
306
+ /**
307
+ * Retrieves cached package metadata from package.json.
308
+ *
309
+ * @internal
310
+ * @returns {Promise<{version: string} | null>} Package metadata or null if unavailable
311
+ */
312
+ async function getPackageMeta() {
313
+ if (cachedPackageMeta) {
314
+ return cachedPackageMeta;
315
+ }
316
+ try {
317
+ const filePath = (0, path_1.resolve)(__dirname, "..", "..", "package.json");
318
+ const data = await fs_1.promises.readFile(filePath, "utf8");
319
+ const parsed = JSON.parse(data);
320
+ cachedPackageMeta = {
321
+ version: parsed.version,
322
+ };
323
+ return cachedPackageMeta;
324
+ }
325
+ catch (err) {
326
+ cachedPackageMeta = {
327
+ version: "error-fetching-version",
328
+ };
329
+ return cachedPackageMeta;
330
+ }
331
+ }
332
+ exports.getPackageMeta = getPackageMeta;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ioredis",
3
- "version": "5.7.0",
3
+ "version": "5.8.0",
4
4
  "description": "A robust, performance-focused and full-featured Redis client for Node.js.",
5
5
  "main": "./built/index.js",
6
6
  "types": "./built/index.d.ts",
@@ -8,10 +8,12 @@
8
8
  "built/"
9
9
  ],
10
10
  "scripts": {
11
+ "cluster:setup": "docker compose -f test/cluster/docker-compose.cluster.yml up -d --wait",
12
+ "cluster:teardown": "docker compose -f test/cluster/docker-compose.cluster.yml down --volumes --remove-orphans",
11
13
  "test:tsd": "npm run build && tsd",
12
14
  "test:js": "TS_NODE_TRANSPILE_ONLY=true NODE_ENV=test mocha \"test/helpers/*.ts\" \"test/unit/**/*.ts\" \"test/functional/**/*.ts\"",
13
15
  "test:cov": "nyc npm run test:js",
14
- "test:js:cluster": "TS_NODE_TRANSPILE_ONLY=true NODE_ENV=test mocha \"test/cluster/**/*.ts\"",
16
+ "test:cluster": "TS_NODE_TRANSPILE_ONLY=true NODE_ENV=test mocha \"test/cluster/**/*.ts\"",
15
17
  "test": "npm run test:js && npm run test:tsd",
16
18
  "lint": "eslint --ext .js,.ts ./lib",
17
19
  "docs": "npx typedoc --logLevel Error --excludeExternals --excludeProtected --excludePrivate --readme none lib/index.ts",
@@ -41,7 +43,7 @@
41
43
  "url": "https://opencollective.com/ioredis"
42
44
  },
43
45
  "dependencies": {
44
- "@ioredis/commands": "^1.3.0",
46
+ "@ioredis/commands": "1.4.0",
45
47
  "cluster-key-slot": "^1.1.0",
46
48
  "debug": "^4.3.4",
47
49
  "denque": "^2.1.0",