ioredis 5.4.1 → 5.5.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.
package/README.md CHANGED
@@ -14,6 +14,8 @@ A robust, performance-focused and full-featured [Redis](http://redis.io) client
14
14
 
15
15
  Supports Redis >= 2.6.12. Completely compatible with Redis 7.x.
16
16
 
17
+ ioredis is a stable project and maintenance is done on a best-effort basis for relevant issues (contributions to ioredis will still be evaluated, reviewed, and merged when they benefit the project). For new projects, node-redis is the recommended client library. [node-redis](https://github.com/redis/node-redis) is the open-source (MIT license) Redis JavaScript client library redesigned from the ground up and actively maintained. [node-redis](https://github.com/redis/node-redis) supports new (hash-field expiration) and future commands and the capabilities available in Redis Stack and Redis 8 (search, JSON, time-series, probabilistic data structures).
18
+
17
19
  # Features
18
20
 
19
21
  ioredis is a robust, full-featured Redis client that is
@@ -722,12 +724,18 @@ the key names are not utf8 strings.
722
724
  There are also `hscanStream`, `zscanStream` and `sscanStream` to iterate through elements in a hash, zset and set. The interface of each is
723
725
  similar to `scanStream` except the first argument is the key name:
724
726
 
727
+ ```javascript
728
+ const stream = redis.zscanStream("myhash", {
729
+ match: "age:??",
730
+ });
731
+ ```
732
+ The `hscanStream` also accepts the `noValues` option to specify whether Redis should return only the keys in the hash table without their corresponding values.
725
733
  ```javascript
726
734
  const stream = redis.hscanStream("myhash", {
727
735
  match: "age:??",
736
+ noValues: true,
728
737
  });
729
738
  ```
730
-
731
739
  You can learn more from the [Redis documentation](http://redis.io/commands/scan).
732
740
 
733
741
  **Useful Tips**
@@ -1130,7 +1138,31 @@ const cluster = new Redis.Cluster(
1130
1138
  );
1131
1139
  ```
1132
1140
 
1141
+ Or you can specify this parameter through function:
1142
+ ```javascript
1143
+ const cluster = new Redis.Cluster(
1144
+ [
1145
+ {
1146
+ host: "203.0.113.73",
1147
+ port: 30001,
1148
+ },
1149
+ ],
1150
+ {
1151
+ natMap: (key) => {
1152
+ if(key.indexOf('30001')) {
1153
+ return { host: "203.0.113.73", port: 30001 };
1154
+ }
1155
+
1156
+ return null;
1157
+ },
1158
+ }
1159
+ );
1160
+ ```
1161
+
1133
1162
  This option is also useful when the cluster is running inside a Docker container.
1163
+ Also it works for Clusters in cloud infrastructure where cluster nodes connected through dedicated subnet.
1164
+
1165
+ Specifying through may be useful if you don't know concrete internal host and know only node port.
1134
1166
 
1135
1167
  ### Transaction and Pipeline in Cluster Mode
1136
1168
 
@@ -21,9 +21,12 @@ class DataHandler {
21
21
  this.returnReply(reply);
22
22
  },
23
23
  });
24
- redis.stream.on("data", (data) => {
24
+ // prependListener ensures the parser receives and processes data before socket timeout checks are performed
25
+ redis.stream.prependListener("data", (data) => {
25
26
  parser.execute(data);
26
27
  });
28
+ // prependListener() doesn't enable flowing mode automatically - we need to resume the stream manually
29
+ redis.stream.resume();
27
30
  }
28
31
  returnFatalError(err) {
29
32
  err.message += ". Please report this.";
@@ -7,6 +7,7 @@ interface Options extends ReadableOptions {
7
7
  command: string;
8
8
  redis: any;
9
9
  count?: string | number;
10
+ noValues?: boolean;
10
11
  }
11
12
  /**
12
13
  * Convenient class to convert the process of scanning keys to a readable stream.
@@ -29,6 +29,9 @@ class ScanStream extends stream_1.Readable {
29
29
  if (this.opt.count) {
30
30
  args.push("COUNT", String(this.opt.count));
31
31
  }
32
+ if (this.opt.noValues) {
33
+ args.push("NOVALUES");
34
+ }
32
35
  this.opt.redis[this.opt.command](args, (err, res) => {
33
36
  if (err) {
34
37
  this.emit("error", err);
@@ -5,12 +5,16 @@ import { CommanderOptions } from "../utils/Commander";
5
5
  import { NodeRole } from "./util";
6
6
  export declare type DNSResolveSrvFunction = (hostname: string, callback: (err: NodeJS.ErrnoException | null | undefined, records?: SrvRecord[]) => void) => void;
7
7
  export declare type DNSLookupFunction = (hostname: string, callback: (err: NodeJS.ErrnoException | null | undefined, address: string, family?: number) => void) => void;
8
- export interface NatMap {
8
+ export declare type NatMapFunction = (key: string) => {
9
+ host: string;
10
+ port: number;
11
+ } | null;
12
+ export declare type NatMap = {
9
13
  [key: string]: {
10
14
  host: string;
11
15
  port: number;
12
16
  };
13
- }
17
+ } | NatMapFunction;
14
18
  /**
15
19
  * Options for Cluster constructor
16
20
  */
@@ -628,15 +628,19 @@ class Cluster extends Commander_1.default {
628
628
  }
629
629
  }
630
630
  natMapper(nodeKey) {
631
- if (this.options.natMap && typeof this.options.natMap === "object") {
632
- const key = typeof nodeKey === "string"
633
- ? nodeKey
634
- : `${nodeKey.host}:${nodeKey.port}`;
635
- const mapped = this.options.natMap[key];
636
- if (mapped) {
637
- debug("NAT mapping %s -> %O", key, mapped);
638
- return Object.assign({}, mapped);
639
- }
631
+ const key = typeof nodeKey === "string"
632
+ ? nodeKey
633
+ : `${nodeKey.host}:${nodeKey.port}`;
634
+ let mapped = null;
635
+ if (this.options.natMap && typeof this.options.natMap === "function") {
636
+ mapped = this.options.natMap(key);
637
+ }
638
+ else if (this.options.natMap && typeof this.options.natMap === "object") {
639
+ mapped = this.options.natMap[key];
640
+ }
641
+ if (mapped) {
642
+ debug("NAT mapping %s -> %O", key, mapped);
643
+ return Object.assign({}, mapped);
640
644
  }
641
645
  return typeof nodeKey === "string"
642
646
  ? (0, util_1.nodeKeyToRedisOptions)(nodeKey)
@@ -162,7 +162,15 @@ class SentinelConnector extends AbstractConnector_1.default {
162
162
  sentinelNatResolve(item) {
163
163
  if (!item || !this.options.natMap)
164
164
  return item;
165
- return this.options.natMap[`${item.host}:${item.port}`] || item;
165
+ const key = `${item.host}:${item.port}`;
166
+ let result = item;
167
+ if (typeof this.options.natMap === "function") {
168
+ result = this.options.natMap(key) || item;
169
+ }
170
+ else if (typeof this.options.natMap === "object") {
171
+ result = this.options.natMap[key] || item;
172
+ }
173
+ return result;
166
174
  }
167
175
  connectToSentinel(endpoint, options) {
168
176
  const redis = new Redis_1.default({
package/built/types.d.ts CHANGED
@@ -29,4 +29,5 @@ export interface ScanStreamOptions {
29
29
  match?: string;
30
30
  type?: string;
31
31
  count?: number;
32
+ noValues?: boolean;
32
33
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ioredis",
3
- "version": "5.4.1",
3
+ "version": "5.5.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",