bullmq 6.0.8 → 6.0.10
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 +2 -1
- package/dist/cjs/classes/ioredis-client.js +0 -20
- package/dist/cjs/classes/redis-connection.js +79 -6
- package/dist/cjs/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/cjs/version.js +1 -1
- package/dist/esm/classes/ioredis-client.d.ts +18 -2
- package/dist/esm/classes/ioredis-client.js +0 -20
- package/dist/esm/classes/job.d.ts +1 -1
- package/dist/esm/classes/queue-events.d.ts +8 -8
- package/dist/esm/classes/redis-connection.js +79 -6
- package/dist/esm/interfaces/redis-options.d.ts +38 -4
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/version.d.ts +1 -1
- package/dist/esm/version.js +1 -1
- package/package.json +6 -7
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<br/>
|
|
5
5
|
<br/>
|
|
6
6
|
<p>
|
|
7
|
-
The fastest, most reliable, Redis-based distributed queue for Node.js, Python, Elixir, Rust, PHP, and more. <br/>
|
|
7
|
+
The fastest, most reliable, Redis-based distributed queue for Node.js, Python, Elixir, .NET, Rust, PHP, and more. <br/>
|
|
8
8
|
Carefully written for rock solid stability and atomicity.
|
|
9
9
|
</p>
|
|
10
10
|
Read the <a href="https://docs.bullmq.io">documentation</a>
|
|
@@ -46,6 +46,7 @@ BullMQ is available natively in multiple languages:
|
|
|
46
46
|
- **Python** — [`python/`](./python) directory (`pip install bullmq`)
|
|
47
47
|
- **Rust** — [`rust/`](./rust) directory (`cargo add bullmq-official --rename bullmq`)
|
|
48
48
|
- **Elixir** — [`elixir/`](./elixir) directory (`{:bullmq, "~> x.x"}`)
|
|
49
|
+
- **.Net** — [`dotnet/`](./dotnet) directory (`dotnet add package BullMQ`)
|
|
49
50
|
- **PHP** — [`php/`](./php) directory
|
|
50
51
|
|
|
51
52
|
For other platforms, check out the [BullMQ Proxy](https://github.com/taskforcesh/bullmq-proxy).
|
|
@@ -8,26 +8,6 @@ exports.isIRedisClient = isIRedisClient;
|
|
|
8
8
|
* event-listener identity for the BullMQ-facing client.
|
|
9
9
|
*/
|
|
10
10
|
const proxyCache = new WeakMap();
|
|
11
|
-
/**
|
|
12
|
-
* Wraps an ioredis `Redis` / `Cluster` instance with a `Proxy` so it conforms
|
|
13
|
-
* to {@link IRedisClient}.
|
|
14
|
-
*
|
|
15
|
-
* For backwards compatibility BullMQ continues to accept a raw `IORedis`
|
|
16
|
-
* instance through tehe `connection` option, even though internally it relies
|
|
17
|
-
* on the `IRedisClient` adapter interface. The returned proxy:
|
|
18
|
-
*
|
|
19
|
-
* - exposes `runCommand` (Lua script dispatch by name)
|
|
20
|
-
* - exposes structured-options variants of `hset`, `set`, `zrange`,
|
|
21
|
-
* `zrevrange`, `xadd`, `xread`, `xtrim`, `scan` (backward-compatible:
|
|
22
|
-
* they still accept native ioredis varargs if called that way)
|
|
23
|
-
* - returns augmented {@link IRedisTransaction}s from `pipeline()` / `multi()`
|
|
24
|
-
* - wraps the result of `duplicate()` in a new proxy
|
|
25
|
-
*
|
|
26
|
-
* The underlying ioredis instance is **not** mutated. Properties and methods
|
|
27
|
-
* not in the override table are forwarded to the raw client via the proxy
|
|
28
|
-
* traps, with `this === target` so EventEmitter / Commander internals work
|
|
29
|
-
* normally.
|
|
30
|
-
*/
|
|
31
11
|
function createIORedisClient(client) {
|
|
32
12
|
// If the caller already passed a proxy produced by this function, return
|
|
33
13
|
// it as-is. Wrapping a proxy in a second proxy would defeat the WeakMap
|
|
@@ -3,11 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.RedisConnection = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const events_1 = require("events");
|
|
6
|
-
const ioredis_1 = require("ioredis");
|
|
7
6
|
const utils_1 = require("../utils");
|
|
8
7
|
const version_1 = require("../version");
|
|
9
8
|
const scripts = require("../scripts");
|
|
10
9
|
const ioredis_client_1 = require("./ioredis-client");
|
|
10
|
+
const node_redis_client_1 = require("./node-redis-client");
|
|
11
|
+
const bun_redis_client_1 = require("./bun-redis-client");
|
|
11
12
|
const connection_closed_error_1 = require("./errors/connection-closed-error");
|
|
12
13
|
const overrideMessage = [
|
|
13
14
|
'BullMQ: WARNING! Your redis options maxRetriesPerRequest must be null',
|
|
@@ -27,6 +28,75 @@ const clusterClosingRefCount = Symbol('bullmqClusterClosingRefCount');
|
|
|
27
28
|
// the worker. 30s is comfortably above the default ioredis slotsRefreshTimeout
|
|
28
29
|
// while bounded enough that wedged workers recover within one or two ticks.
|
|
29
30
|
const DEFAULT_CLUSTER_RECONNECT_TIMEOUT_MS = 30000;
|
|
31
|
+
/**
|
|
32
|
+
* Lazily loads the optional `ioredis` driver. Users on another Redis driver
|
|
33
|
+
* (node-redis, Bun built-in, …) or on the PostgreSQL backend never hit this
|
|
34
|
+
* path, so they never need `ioredis` installed.
|
|
35
|
+
*
|
|
36
|
+
* Only reached when no {@link RedisConnection.clientFactory} is set and the
|
|
37
|
+
* caller did not pass an already-constructed client instance. In native ESM
|
|
38
|
+
* environments where `require` is unavailable, callers should provide a client
|
|
39
|
+
* instance or a `clientFactory` instead.
|
|
40
|
+
*/
|
|
41
|
+
function loadIORedis() {
|
|
42
|
+
var _a;
|
|
43
|
+
try {
|
|
44
|
+
if (typeof require === 'function') {
|
|
45
|
+
const mod = require('ioredis');
|
|
46
|
+
// ioredis exports the constructor both as the module itself (CJS) and
|
|
47
|
+
// under `default` (ESM interop); normalise to the constructor.
|
|
48
|
+
return (_a = mod.default) !== null && _a !== void 0 ? _a : mod;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
catch (_b) {
|
|
52
|
+
// Fall through to the friendly error below.
|
|
53
|
+
}
|
|
54
|
+
throw new Error("BullMQ could not load the optional 'ioredis' package. " +
|
|
55
|
+
'Install it with `npm install ioredis`, or provide a different Redis ' +
|
|
56
|
+
'client instance (e.g. node-redis) via the connection option. In a ' +
|
|
57
|
+
'native ESM environment, pass an already-constructed client instance ' +
|
|
58
|
+
'instead of connection options.');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Wraps a raw client instance passed through the `connection` option in the
|
|
62
|
+
* matching {@link IRedisClient} adapter, auto-detecting the underlying driver.
|
|
63
|
+
*
|
|
64
|
+
* This lets consumers pass a native node-redis or Bun client directly (without
|
|
65
|
+
* manually calling `createNodeRedisClient` / `createBunRedisClient` or setting a
|
|
66
|
+
* global {@link RedisConnection.clientFactory}), so those users never need
|
|
67
|
+
* `ioredis` installed. ioredis instances keep their existing code path, so the
|
|
68
|
+
* behaviour is fully backwards compatible.
|
|
69
|
+
*
|
|
70
|
+
* Detection is purely structural (no driver package is imported), keying off
|
|
71
|
+
* markers that are unique to each client:
|
|
72
|
+
* - ioredis exposes `defineCommand` (used to register Lua scripts);
|
|
73
|
+
* node-redis and Bun do not.
|
|
74
|
+
* - node-redis (`@redis/client`) exposes `sendCommand` plus `isOpen`/`isReady`.
|
|
75
|
+
* - Bun's built-in `RedisClient` exposes `send` plus a `connected` flag.
|
|
76
|
+
*/
|
|
77
|
+
function wrapRedisInstance(instance) {
|
|
78
|
+
// Already an adapted IRedisClient (ioredis proxy, node-redis, Bun, or a
|
|
79
|
+
// custom implementation) — use as-is.
|
|
80
|
+
if ((0, ioredis_client_1.isIRedisClient)(instance)) {
|
|
81
|
+
return instance;
|
|
82
|
+
}
|
|
83
|
+
const hasDefineCommand = typeof instance.defineCommand === 'function';
|
|
84
|
+
// node-redis (@redis/client): `sendCommand` + `isOpen`/`isReady`, and no
|
|
85
|
+
// ioredis-style `defineCommand`.
|
|
86
|
+
if (!hasDefineCommand &&
|
|
87
|
+
typeof instance.sendCommand === 'function' &&
|
|
88
|
+
('isOpen' in instance || 'isReady' in instance)) {
|
|
89
|
+
return (0, node_redis_client_1.createNodeRedisClient)(instance);
|
|
90
|
+
}
|
|
91
|
+
// Bun's built-in RedisClient: `send` + `connected`, and no `defineCommand`.
|
|
92
|
+
if (!hasDefineCommand &&
|
|
93
|
+
typeof instance.send === 'function' &&
|
|
94
|
+
'connected' in instance) {
|
|
95
|
+
return (0, bun_redis_client_1.createBunRedisClient)(instance);
|
|
96
|
+
}
|
|
97
|
+
// Default: treat as an ioredis instance (backwards compatible).
|
|
98
|
+
return (0, ioredis_client_1.createIORedisClient)(instance);
|
|
99
|
+
}
|
|
30
100
|
class RedisConnection extends events_1.EventEmitter {
|
|
31
101
|
constructor(opts, extraOptions) {
|
|
32
102
|
super();
|
|
@@ -51,10 +121,10 @@ class RedisConnection extends events_1.EventEmitter {
|
|
|
51
121
|
}
|
|
52
122
|
}
|
|
53
123
|
else {
|
|
54
|
-
// Wrap raw
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
124
|
+
// Wrap raw client instances in the matching IRedisClient adapter,
|
|
125
|
+
// auto-detecting the driver (ioredis / node-redis / Bun) so callers can
|
|
126
|
+
// pass a native client directly without setting a clientFactory.
|
|
127
|
+
this._client = wrapRedisInstance(opts);
|
|
58
128
|
// Test if the redis instance is using keyPrefix
|
|
59
129
|
// and if so, throw an error.
|
|
60
130
|
if (this._client.options.keyPrefix) {
|
|
@@ -187,7 +257,10 @@ class RedisConnection extends events_1.EventEmitter {
|
|
|
187
257
|
}
|
|
188
258
|
else {
|
|
189
259
|
const _a = this.opts, { url } = _a, rest = tslib_1.__rest(_a, ["url"]);
|
|
190
|
-
const
|
|
260
|
+
const IORedisCtor = loadIORedis();
|
|
261
|
+
const ioredisClient = url
|
|
262
|
+
? new IORedisCtor(url, rest)
|
|
263
|
+
: new IORedisCtor(rest);
|
|
191
264
|
this._client = (0, ioredis_client_1.createIORedisClient)(ioredisClient);
|
|
192
265
|
}
|
|
193
266
|
}
|