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 +33 -1
- package/built/DataHandler.js +4 -1
- package/built/ScanStream.d.ts +1 -0
- package/built/ScanStream.js +3 -0
- package/built/cluster/ClusterOptions.d.ts +6 -2
- package/built/cluster/index.js +13 -9
- package/built/connectors/SentinelConnector/index.js +9 -1
- package/built/types.d.ts +1 -0
- package/package.json +1 -1
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
|
|
package/built/DataHandler.js
CHANGED
|
@@ -21,9 +21,12 @@ class DataHandler {
|
|
|
21
21
|
this.returnReply(reply);
|
|
22
22
|
},
|
|
23
23
|
});
|
|
24
|
-
|
|
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.";
|
package/built/ScanStream.d.ts
CHANGED
package/built/ScanStream.js
CHANGED
|
@@ -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
|
|
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
|
*/
|
package/built/cluster/index.js
CHANGED
|
@@ -628,15 +628,19 @@ class Cluster extends Commander_1.default {
|
|
|
628
628
|
}
|
|
629
629
|
}
|
|
630
630
|
natMapper(nodeKey) {
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
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
|
-
|
|
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