ioredis 5.3.1 → 5.4.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 +37 -56
- package/built/Redis.d.ts +16 -0
- package/built/Redis.js +19 -0
- package/built/cluster/index.d.ts +1 -0
- package/built/cluster/index.js +6 -4
- package/built/redis/RedisOptions.d.ts +7 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
[](https://github.com/redis/ioredis)
|
|
2
2
|
|
|
3
|
-
[](https://github.com/redis/ioredis/actions/workflows/release.yml?query=branch%3Amain)
|
|
4
4
|
[](https://coveralls.io/github/luin/ioredis?branch=main)
|
|
5
|
-
[](https://gitter.im/luin/ioredis?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
|
6
5
|
[](http://commitizen.github.io/cz-cli/)
|
|
7
6
|
[](https://github.com/semantic-release/semantic-release)
|
|
8
7
|
|
|
8
|
+
[](https://discord.gg/redis)
|
|
9
|
+
[](https://www.twitch.tv/redisinc)
|
|
10
|
+
[](https://www.youtube.com/redisinc)
|
|
11
|
+
[](https://twitter.com/redisinc)
|
|
12
|
+
|
|
9
13
|
A robust, performance-focused and full-featured [Redis](http://redis.io) client for [Node.js](https://nodejs.org).
|
|
10
14
|
|
|
11
|
-
Supports Redis >= 2.6.12
|
|
15
|
+
Supports Redis >= 2.6.12. Completely compatible with Redis 7.x.
|
|
12
16
|
|
|
13
17
|
# Features
|
|
14
18
|
|
|
@@ -20,9 +24,9 @@ used in the world's biggest online commerce company [Alibaba](http://www.alibaba
|
|
|
20
24
|
2. Delightful API 😄. It works with Node callbacks and Native promises.
|
|
21
25
|
3. Transformation of command arguments and replies.
|
|
22
26
|
4. Transparent key prefixing.
|
|
23
|
-
5. Abstraction for Lua scripting, allowing you to [define custom commands](https://github.com/
|
|
24
|
-
6. Supports [binary data](https://github.com/
|
|
25
|
-
7. Supports [TLS](https://github.com/
|
|
27
|
+
5. Abstraction for Lua scripting, allowing you to [define custom commands](https://github.com/redis/ioredis#lua-scripting).
|
|
28
|
+
6. Supports [binary data](https://github.com/redis/ioredis#handle-binary-data).
|
|
29
|
+
7. Supports [TLS](https://github.com/redis/ioredis#tls-options) 🔒.
|
|
26
30
|
8. Supports offline queue and ready checking.
|
|
27
31
|
9. Supports ES6 types, such as `Map` and `Set`.
|
|
28
32
|
10. Supports GEO commands 📍.
|
|
@@ -44,46 +48,12 @@ used in the world's biggest online commerce company [Alibaba](http://www.alibaba
|
|
|
44
48
|
|
|
45
49
|
Refer to [CHANGELOG.md](CHANGELOG.md) for features and bug fixes introduced in v5.
|
|
46
50
|
|
|
47
|
-
🚀 [Upgrading from v4 to v5](https://github.com/
|
|
51
|
+
🚀 [Upgrading from v4 to v5](https://github.com/redis/ioredis/wiki/Upgrading-from-v4-to-v5)
|
|
48
52
|
|
|
49
53
|
# Links
|
|
50
54
|
|
|
51
|
-
- [API Documentation](https://
|
|
55
|
+
- [API Documentation](https://redis.github.io/ioredis/) ([Redis](https://redis.github.io/ioredis/classes/Redis.html), [Cluster](https://redis.github.io/ioredis/classes/Cluster.html))
|
|
52
56
|
- [Changelog](CHANGELOG.md)
|
|
53
|
-
- [Migrating from node_redis](https://github.com/luin/ioredis/wiki/Migrating-from-node_redis)
|
|
54
|
-
|
|
55
|
-
<hr>
|
|
56
|
-
|
|
57
|
-
# Sponsors
|
|
58
|
-
|
|
59
|
-
### Upstash: Serverless Database for Redis
|
|
60
|
-
|
|
61
|
-
<a href="https://upstash.com/?utm_source=ioredis"><img align="right" width="320" src="resources/upstash.png" alt="Upstash"></a>
|
|
62
|
-
|
|
63
|
-
Upstash is a Serverless Database with Redis/REST API and durable storage. It is the perfect database for your applications thanks to its per request pricing and low latency data.
|
|
64
|
-
|
|
65
|
-
[Start for free in 30 seconds!](https://upstash.com/?utm_source=ioredis)
|
|
66
|
-
|
|
67
|
-
<br clear="both"/>
|
|
68
|
-
|
|
69
|
-
### Medis: Redis GUI for macOS
|
|
70
|
-
|
|
71
|
-
<a href="https://getmedis.com/"><img align="right" width="404" src="resources/medis.png" alt="Download on the App Store"></a>
|
|
72
|
-
|
|
73
|
-
Looking for a Redis GUI for macOS, Windows and Linux? Here's [Medis](https://getmedis.com/)!
|
|
74
|
-
|
|
75
|
-
Medis is an open-sourced, beautiful, easy-to-use Redis GUI management application.
|
|
76
|
-
|
|
77
|
-
Medis starts with all the basic features you need:
|
|
78
|
-
|
|
79
|
-
- Keys viewing/editing
|
|
80
|
-
- SSH Tunnel for connecting with remote servers
|
|
81
|
-
- Terminal for executing custom commands
|
|
82
|
-
- And other awesome features...
|
|
83
|
-
|
|
84
|
-
[Medis 1 is open sourced on GitHub](https://github.com/luin/medis)
|
|
85
|
-
|
|
86
|
-
<br clear="both"/>
|
|
87
57
|
|
|
88
58
|
<hr>
|
|
89
59
|
|
|
@@ -156,7 +126,7 @@ See the `examples/` folder for more examples. For example:
|
|
|
156
126
|
- [Streams](examples/stream.js)
|
|
157
127
|
- [Redis Modules](examples/module.js) e.g. RedisJSON
|
|
158
128
|
|
|
159
|
-
All Redis commands are supported. See [the documentation](https://
|
|
129
|
+
All Redis commands are supported. See [the documentation](https://redis.github.io/ioredis/classes/Redis.html) for details.
|
|
160
130
|
|
|
161
131
|
## Connect to Redis
|
|
162
132
|
|
|
@@ -188,7 +158,7 @@ new Redis("redis://:authpassword@127.0.0.1:6380/4");
|
|
|
188
158
|
new Redis("redis://username:authpassword@127.0.0.1:6380/4");
|
|
189
159
|
```
|
|
190
160
|
|
|
191
|
-
See [API Documentation](https://
|
|
161
|
+
See [API Documentation](https://redis.github.io/ioredis/index.html#RedisOptions) for all available options.
|
|
192
162
|
|
|
193
163
|
## Pub/Sub
|
|
194
164
|
|
|
@@ -302,6 +272,16 @@ async function listenForMessage(lastId = "$") {
|
|
|
302
272
|
listenForMessage();
|
|
303
273
|
```
|
|
304
274
|
|
|
275
|
+
## Expiration
|
|
276
|
+
|
|
277
|
+
Redis can set a timeout to expire your key, after the timeout has expired the key will be automatically deleted. (You can find the [official Expire documentation](https://redis.io/commands/expire/) to understand better the different parameters you can use), to set your key to expire in 60 seconds, we will have the following code:
|
|
278
|
+
|
|
279
|
+
```javascript
|
|
280
|
+
redis.set("key", "data", "EX", 60);
|
|
281
|
+
// Equivalent to redis command "SET key data EX 60", because on ioredis set method,
|
|
282
|
+
// all arguments are passed directly to the redis server.
|
|
283
|
+
```
|
|
284
|
+
|
|
305
285
|
## Handle Binary Data
|
|
306
286
|
|
|
307
287
|
Binary data support is out of the box. Pass buffers to send binary data:
|
|
@@ -559,8 +539,8 @@ This feature allows you to specify a string that will automatically be prepended
|
|
|
559
539
|
to all the keys in a command, which makes it easier to manage your key
|
|
560
540
|
namespaces.
|
|
561
541
|
|
|
562
|
-
**Warning** This feature won't apply to commands like [KEYS](http://redis.io/commands/KEYS) and [SCAN](http://redis.io/commands/scan) that take patterns rather than actual keys([#239](https://github.com/
|
|
563
|
-
and this feature also won't apply to the replies of commands even if they are key names ([#325](https://github.com/
|
|
542
|
+
**Warning** This feature won't apply to commands like [KEYS](http://redis.io/commands/KEYS) and [SCAN](http://redis.io/commands/scan) that take patterns rather than actual keys([#239](https://github.com/redis/ioredis/issues/239)),
|
|
543
|
+
and this feature also won't apply to the replies of commands even if they are key names ([#325](https://github.com/redis/ioredis/issues/325)).
|
|
564
544
|
|
|
565
545
|
```javascript
|
|
566
546
|
const fooRedis = new Redis({ keyPrefix: "foo:" });
|
|
@@ -884,6 +864,15 @@ Alternatively, specify the connection through a [`rediss://` URL](https://www.ia
|
|
|
884
864
|
const redis = new Redis("rediss://redis.my-service.com");
|
|
885
865
|
```
|
|
886
866
|
|
|
867
|
+
If you do not want to use a connection string, you can also specify an empty `tls: {}` object:
|
|
868
|
+
|
|
869
|
+
```javascript
|
|
870
|
+
const redis = new Redis({
|
|
871
|
+
host: "redis.my-service.com",
|
|
872
|
+
tls: {},
|
|
873
|
+
});
|
|
874
|
+
```
|
|
875
|
+
|
|
887
876
|
### TLS Profiles
|
|
888
877
|
|
|
889
878
|
> **Warning**
|
|
@@ -1412,19 +1401,11 @@ I'm happy to receive bug reports, fixes, documentation enhancements, and any oth
|
|
|
1412
1401
|
|
|
1413
1402
|
And since I'm not a native English speaker, if you find any grammar mistakes in the documentation, please also let me know. :)
|
|
1414
1403
|
|
|
1415
|
-
# Become a Sponsor
|
|
1416
|
-
|
|
1417
|
-
Open source is hard and time-consuming. If you want to invest in ioredis's future you can become a sponsor and make us spend more time on this library's improvements and new features.
|
|
1418
|
-
|
|
1419
|
-
<a href="https://opencollective.com/ioredis"><img src="https://opencollective.com/ioredis/tiers/sponsor.svg?avatarHeight=36"></a>
|
|
1420
|
-
|
|
1421
|
-
Thank you for using ioredis :-)
|
|
1422
|
-
|
|
1423
1404
|
# Contributors
|
|
1424
1405
|
|
|
1425
1406
|
This project exists thanks to all the people who contribute:
|
|
1426
1407
|
|
|
1427
|
-
<a href="https://github.com/
|
|
1408
|
+
<a href="https://github.com/redis/ioredis/graphs/contributors"><img src="https://opencollective.com/ioredis/contributors.svg?width=890&showBtn=false" /></a>
|
|
1428
1409
|
|
|
1429
1410
|
# License
|
|
1430
1411
|
|
package/built/Redis.d.ts
CHANGED
|
@@ -63,6 +63,7 @@ declare class Redis extends Commander implements DataHandledable {
|
|
|
63
63
|
private connectionEpoch;
|
|
64
64
|
private retryAttempts;
|
|
65
65
|
private manuallyClosing;
|
|
66
|
+
private socketTimeoutTimer;
|
|
66
67
|
private _autoPipelines;
|
|
67
68
|
private _runningAutoPipelines;
|
|
68
69
|
constructor(port: number, host: string, options: RedisOptions);
|
|
@@ -159,6 +160,7 @@ declare class Redis extends Commander implements DataHandledable {
|
|
|
159
160
|
* @ignore
|
|
160
161
|
*/
|
|
161
162
|
sendCommand(command: Command, stream?: WriteableStream): unknown;
|
|
163
|
+
private setSocketTimeout;
|
|
162
164
|
scanStream(options?: ScanStreamOptions): ScanStream;
|
|
163
165
|
scanBufferStream(options?: ScanStreamOptions): ScanStream;
|
|
164
166
|
sscanStream(key: string, options?: ScanStreamOptions): ScanStream;
|
|
@@ -207,6 +209,20 @@ declare class Redis extends Commander implements DataHandledable {
|
|
|
207
209
|
private _readyCheck;
|
|
208
210
|
}
|
|
209
211
|
interface Redis extends EventEmitter {
|
|
212
|
+
on(event: "message", cb: (channel: string, message: string) => void): this;
|
|
213
|
+
once(event: "message", cb: (channel: string, message: string) => void): this;
|
|
214
|
+
on(event: "messageBuffer", cb: (channel: Buffer, message: Buffer) => void): this;
|
|
215
|
+
once(event: "messageBuffer", cb: (channel: Buffer, message: Buffer) => void): this;
|
|
216
|
+
on(event: "pmessage", cb: (pattern: string, channel: string, message: string) => void): this;
|
|
217
|
+
once(event: "pmessage", cb: (pattern: string, channel: string, message: string) => void): this;
|
|
218
|
+
on(event: "pmessageBuffer", cb: (pattern: string, channel: Buffer, message: Buffer) => void): this;
|
|
219
|
+
once(event: "pmessageBuffer", cb: (pattern: string, channel: Buffer, message: Buffer) => void): this;
|
|
220
|
+
on(event: "error", cb: (error: Error) => void): this;
|
|
221
|
+
once(event: "error", cb: (error: Error) => void): this;
|
|
222
|
+
on(event: RedisStatus, cb: () => void): this;
|
|
223
|
+
once(event: RedisStatus, cb: () => void): this;
|
|
224
|
+
on(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
225
|
+
once(event: string | symbol, listener: (...args: any[]) => void): this;
|
|
210
226
|
}
|
|
211
227
|
interface Redis extends Transaction {
|
|
212
228
|
}
|
package/built/Redis.js
CHANGED
|
@@ -401,6 +401,9 @@ class Redis extends Commander_1.default {
|
|
|
401
401
|
if (Command_1.default.checkFlag("WILL_DISCONNECT", command.name)) {
|
|
402
402
|
this.manuallyClosing = true;
|
|
403
403
|
}
|
|
404
|
+
if (this.options.socketTimeout !== undefined && this.socketTimeoutTimer === undefined) {
|
|
405
|
+
this.setSocketTimeout();
|
|
406
|
+
}
|
|
404
407
|
}
|
|
405
408
|
if (command.name === "select" && (0, utils_1.isInt)(command.args[0])) {
|
|
406
409
|
const db = parseInt(command.args[0], 10);
|
|
@@ -412,6 +415,22 @@ class Redis extends Commander_1.default {
|
|
|
412
415
|
}
|
|
413
416
|
return command.promise;
|
|
414
417
|
}
|
|
418
|
+
setSocketTimeout() {
|
|
419
|
+
this.socketTimeoutTimer = setTimeout(() => {
|
|
420
|
+
this.stream.destroy(new Error(`Socket timeout. Expecting data, but didn't receive any in ${this.options.socketTimeout}ms.`));
|
|
421
|
+
this.socketTimeoutTimer = undefined;
|
|
422
|
+
}, this.options.socketTimeout);
|
|
423
|
+
// this handler must run after the "data" handler in "DataHandler"
|
|
424
|
+
// so that `this.commandQueue.length` will be updated
|
|
425
|
+
this.stream.once("data", () => {
|
|
426
|
+
console.log('GOT DATA, CLEARING TIMER');
|
|
427
|
+
clearTimeout(this.socketTimeoutTimer);
|
|
428
|
+
this.socketTimeoutTimer = undefined;
|
|
429
|
+
if (this.commandQueue.length === 0)
|
|
430
|
+
return;
|
|
431
|
+
this.setSocketTimeout();
|
|
432
|
+
});
|
|
433
|
+
}
|
|
415
434
|
scanStream(options) {
|
|
416
435
|
return this.createScanStream("scan", { options });
|
|
417
436
|
}
|
package/built/cluster/index.d.ts
CHANGED
package/built/cluster/index.js
CHANGED
|
@@ -46,6 +46,7 @@ class Cluster extends Commander_1.default {
|
|
|
46
46
|
this.delayQueue = new DelayQueue_1.default();
|
|
47
47
|
this.offlineQueue = new Deque();
|
|
48
48
|
this.isRefreshing = false;
|
|
49
|
+
this._refreshSlotsCacheCallbacks = [];
|
|
49
50
|
this._autoPipelines = new Map();
|
|
50
51
|
this._runningAutoPipelines = new Set();
|
|
51
52
|
this._readyDelayedCallbacks = [];
|
|
@@ -287,19 +288,20 @@ class Cluster extends Commander_1.default {
|
|
|
287
288
|
* @ignore
|
|
288
289
|
*/
|
|
289
290
|
refreshSlotsCache(callback) {
|
|
291
|
+
if (callback) {
|
|
292
|
+
this._refreshSlotsCacheCallbacks.push(callback);
|
|
293
|
+
}
|
|
290
294
|
if (this.isRefreshing) {
|
|
291
|
-
if (callback) {
|
|
292
|
-
process.nextTick(callback);
|
|
293
|
-
}
|
|
294
295
|
return;
|
|
295
296
|
}
|
|
296
297
|
this.isRefreshing = true;
|
|
297
298
|
const _this = this;
|
|
298
299
|
const wrapper = (error) => {
|
|
299
300
|
this.isRefreshing = false;
|
|
300
|
-
|
|
301
|
+
for (const callback of this._refreshSlotsCacheCallbacks) {
|
|
301
302
|
callback(error);
|
|
302
303
|
}
|
|
304
|
+
this._refreshSlotsCacheCallbacks = [];
|
|
303
305
|
};
|
|
304
306
|
const nodes = (0, utils_1.shuffle)(this.connectionPool.getNodes());
|
|
305
307
|
let lastNodeError = null;
|
|
@@ -11,6 +11,13 @@ export interface CommonRedisOptions extends CommanderOptions {
|
|
|
11
11
|
* a "Command timed out" error will be thrown.
|
|
12
12
|
*/
|
|
13
13
|
commandTimeout?: number;
|
|
14
|
+
/**
|
|
15
|
+
* If the socket does not receive data within a set number of milliseconds:
|
|
16
|
+
* 1. the socket is considered "dead" and will be destroyed
|
|
17
|
+
* 2. the client will reject any running commands (altought they might have been processed by the server)
|
|
18
|
+
* 3. the reconnect strategy will kick in (depending on the configuration)
|
|
19
|
+
*/
|
|
20
|
+
socketTimeout?: number;
|
|
14
21
|
/**
|
|
15
22
|
* Enable/disable keep-alive functionality.
|
|
16
23
|
* @link https://nodejs.org/api/net.html#socketsetkeepaliveenable-initialdelay
|