@nest-batch/bullmq 0.2.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/LICENSE +21 -0
- package/README.md +333 -0
- package/dist/src/adapters/bullmq.adapter.d.ts +157 -0
- package/dist/src/adapters/bullmq.adapter.d.ts.map +1 -0
- package/dist/src/adapters/bullmq.adapter.js +252 -0
- package/dist/src/adapters/bullmq.adapter.js.map +1 -0
- package/dist/src/adapters/index.d.ts +12 -0
- package/dist/src/adapters/index.d.ts.map +1 -0
- package/dist/src/adapters/index.js +29 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/bullmq-execution-strategy.d.ts +59 -0
- package/dist/src/bullmq-execution-strategy.d.ts.map +1 -0
- package/dist/src/bullmq-execution-strategy.js +60 -0
- package/dist/src/bullmq-execution-strategy.js.map +1 -0
- package/dist/src/bullmq-runtime.service.d.ts +237 -0
- package/dist/src/bullmq-runtime.service.d.ts.map +1 -0
- package/dist/src/bullmq-runtime.service.js +441 -0
- package/dist/src/bullmq-runtime.service.js.map +1 -0
- package/dist/src/bullmq-schedule.service.d.ts +121 -0
- package/dist/src/bullmq-schedule.service.d.ts.map +1 -0
- package/dist/src/bullmq-schedule.service.js +232 -0
- package/dist/src/bullmq-schedule.service.js.map +1 -0
- package/dist/src/connection.d.ts +83 -0
- package/dist/src/connection.d.ts.map +1 -0
- package/dist/src/connection.js +72 -0
- package/dist/src/connection.js.map +1 -0
- package/dist/src/index.d.ts +29 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +46 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/module-options.d.ts +68 -0
- package/dist/src/module-options.d.ts.map +1 -0
- package/dist/src/module-options.js +13 -0
- package/dist/src/module-options.js.map +1 -0
- package/package.json +71 -0
- package/src/adapters/bullmq.adapter.ts +346 -0
- package/src/adapters/index.ts +11 -0
- package/src/bullmq-execution-strategy.ts +81 -0
- package/src/bullmq-runtime.service.ts +540 -0
- package/src/bullmq-schedule.service.ts +271 -0
- package/src/connection.ts +97 -0
- package/src/index.ts +28 -0
- package/src/module-options.ts +74 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 easdkr
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
# `@nest-batch/bullmq`
|
|
2
|
+
|
|
3
|
+
BullMQ transport adapter for [`@nest-batch/core`](../core). Provides a
|
|
4
|
+
NestJS dynamic module that overrides the core `EXECUTION_STRATEGY` token
|
|
5
|
+
with a BullMQ-backed `IExecutionStrategy`, so a host app can switch the
|
|
6
|
+
`JobLauncher`'s execution target from in-process to a Redis-backed
|
|
7
|
+
queue with a single line of DI wiring.
|
|
8
|
+
|
|
9
|
+
> **BullMQ is the transport runtime, not the batch engine.** This
|
|
10
|
+
> package owns the Redis client lifecycle, the worker / queue /
|
|
11
|
+
> queue-events plumbing, and the technical retry / backoff / rate
|
|
12
|
+
> limit / worker distribution policies. The batch engine itself
|
|
13
|
+
> (Job/Step/Chunk/Tasklet semantics, checkpoint, restart, skip,
|
|
14
|
+
> chunk transaction, business retry) lives in
|
|
15
|
+
> [`@nest-batch/core`](../core). BullMQ is the courier; the
|
|
16
|
+
> `JobExecutor` is the worker.
|
|
17
|
+
|
|
18
|
+
The package is a **sibling**, not a replacement. The dependency
|
|
19
|
+
direction is strict and one-way:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
@nest-batch/bullmq ──▶ @nest-batch/core
|
|
23
|
+
│
|
|
24
|
+
└──────────────▶ bullmq, ioredis (peer)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
`@nest-batch/core` does **not** know that this package exists, and
|
|
28
|
+
must never import `bullmq` (or any queue runtime) into its own
|
|
29
|
+
`src/`. The boundary is enforced by
|
|
30
|
+
[`packages/core/tests/core/boundary/no-forbidden-imports.test.ts`](../core/tests/core/boundary/no-forbidden-imports.test.ts),
|
|
31
|
+
which scans the core source tree and fails the build if any
|
|
32
|
+
forbidden package — `bullmq`, `mikro-orm`, `typeorm`, `drizzle-orm`,
|
|
33
|
+
`cron` — appears as an import.
|
|
34
|
+
|
|
35
|
+
Consequence: adding `bullmq` to this package's `dependencies` is the
|
|
36
|
+
only way for the host to get a BullMQ transport. The core module
|
|
37
|
+
stays dependency-light.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Install
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pnpm add @nest-batch/bullmq
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Peer dependencies the host must already provide:
|
|
48
|
+
|
|
49
|
+
| Package | Range |
|
|
50
|
+
| ------------------ | ------------- |
|
|
51
|
+
| `@nest-batch/core` | `workspace:*` |
|
|
52
|
+
| `@nestjs/common` | `^11.0.0` |
|
|
53
|
+
| `@nestjs/core` | `^11.0.0` |
|
|
54
|
+
| `bullmq` | `^5.0.0` |
|
|
55
|
+
|
|
56
|
+
`bullmq` is hard-pinned to 5.x. BullMQ 5 is the first version with
|
|
57
|
+
the unified producer / worker connection options this package
|
|
58
|
+
encodes. Versions before 5.x are not supported.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Local Redis setup
|
|
63
|
+
|
|
64
|
+
The repo ships a `docker-compose.yml` at the workspace root with a
|
|
65
|
+
`redis` service alongside the existing `postgres`. Bring it up with:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
docker compose up -d redis
|
|
69
|
+
# wait ~3s for the healthcheck, then:
|
|
70
|
+
docker compose exec -T redis redis-cli ping
|
|
71
|
+
# → PONG
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
The compose service is configured for the BullMQ transport
|
|
75
|
+
semantics:
|
|
76
|
+
|
|
77
|
+
| Setting | Value | Why |
|
|
78
|
+
| ------------- | ------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
79
|
+
| `image` | `redis:7-alpine` | BullMQ 5 requires Redis ≥ 6.2. |
|
|
80
|
+
| `command` | `--appendonly yes` | AOF persistence is on so a container restart does not silently drop in-flight queue state. |
|
|
81
|
+
| `command` | `--maxmemory-policy noeviction` | BullMQ writes to Lua keys / streams; we never want Redis to evict them under memory pressure. |
|
|
82
|
+
| `healthcheck` | `redis-cli ping` every 5s | Surfaces a Redis-down condition to `docker compose ps` within the healthcheck window. |
|
|
83
|
+
| `port` | `6379:6379` | The BullMQ client default. Override in `BullMqConnectionOptions` if you remap. |
|
|
84
|
+
|
|
85
|
+
If you want Redis + Postgres in one go, the full local dev stack is:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
docker compose up -d
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Key prefix
|
|
92
|
+
|
|
93
|
+
By default every key the package writes is prefixed with
|
|
94
|
+
`nest-batch:` (BullMQ appends its own `bull:` after the prefix, so
|
|
95
|
+
the full key looks like `nest-batch:bull:<queue-name>:<job-id>`).
|
|
96
|
+
This makes it safe to share a single Redis instance with other
|
|
97
|
+
applications. Change it via `BullMqConnectionOptions.keyPrefix` if
|
|
98
|
+
you need a different namespace.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Connection policy (worker vs producer)
|
|
103
|
+
|
|
104
|
+
BullMQ is opinionated about Redis client behavior. The two roles
|
|
105
|
+
**must** use different options — otherwise a Redis outage will look
|
|
106
|
+
like a successful enqueue, or a stalled worker will look like a
|
|
107
|
+
connection error. The package applies this split transparently
|
|
108
|
+
based on the role it is building.
|
|
109
|
+
|
|
110
|
+
### Workers (consumer side)
|
|
111
|
+
|
|
112
|
+
The package sets these on every `Worker` / `QueueEvents` client:
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
{
|
|
116
|
+
host, port, password, username, db, tls, keyPrefix,
|
|
117
|
+
maxRetriesPerRequest: null, // mandatory
|
|
118
|
+
enableReadyCheck: false, // mandatory
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
- `maxRetriesPerRequest: null` — BullMQ's internal blocking commands
|
|
123
|
+
(`BLPOP`, `BRPOPLPUSH`, `XREADGROUP`) must not retry per request.
|
|
124
|
+
A stalled worker should surface as a stalled job, not a
|
|
125
|
+
connection error.
|
|
126
|
+
- `enableReadyCheck: false` — paired with the above so the client
|
|
127
|
+
does not give up on a Redis that is briefly not-READY (e.g. while
|
|
128
|
+
loading AOF on restart).
|
|
129
|
+
|
|
130
|
+
### Producers (enqueue side)
|
|
131
|
+
|
|
132
|
+
The package sets these on the `Queue` (producer) client:
|
|
133
|
+
|
|
134
|
+
```ts
|
|
135
|
+
{
|
|
136
|
+
host, port, password, username, db, tls, keyPrefix,
|
|
137
|
+
enableOfflineQueue: false, // mandatory
|
|
138
|
+
maxRetriesPerRequest: 1,
|
|
139
|
+
}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
- `enableOfflineQueue: false` — a Redis-down condition must
|
|
143
|
+
**raise an error synchronously on the enqueue call**, not buffer
|
|
144
|
+
the command and return success. `JobLauncher.launch` propagates
|
|
145
|
+
the error to the caller so the `JobExecution` is marked `FAILED`
|
|
146
|
+
and the HTTP/RPC/cron trigger sees a real failure.
|
|
147
|
+
- `maxRetriesPerRequest: 1` — keep the first `add` fast. BullMQ
|
|
148
|
+
warns against `maxRetriesPerRequest: null` on the producer
|
|
149
|
+
(producers do not use blocking commands), so we use `1` and let
|
|
150
|
+
ioredis handle reconnects.
|
|
151
|
+
|
|
152
|
+
You should not need to override either of these. The defaults are
|
|
153
|
+
the contract the test suite relies on.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Wiring
|
|
158
|
+
|
|
159
|
+
```ts
|
|
160
|
+
import { Module } from '@nestjs/common';
|
|
161
|
+
import { NestBatchModule } from '@nest-batch/core';
|
|
162
|
+
import { BullmqBatchModule } from '@nest-batch/bullmq';
|
|
163
|
+
|
|
164
|
+
@Module({
|
|
165
|
+
imports: [
|
|
166
|
+
NestBatchModule.forRoot({
|
|
167
|
+
// repository, transactionManager, ...
|
|
168
|
+
}),
|
|
169
|
+
BullmqBatchModule.forRoot({
|
|
170
|
+
connection: {
|
|
171
|
+
host: process.env.REDIS_HOST ?? '127.0.0.1',
|
|
172
|
+
port: Number(process.env.REDIS_PORT ?? 6379),
|
|
173
|
+
keyPrefix: 'nest-batch:',
|
|
174
|
+
// password, username, db, tls also accepted
|
|
175
|
+
},
|
|
176
|
+
autoStartWorker: true, // starts a Worker on bootstrap
|
|
177
|
+
}),
|
|
178
|
+
],
|
|
179
|
+
})
|
|
180
|
+
export class AppModule {}
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
`BullmqBatchModule.forRoot({ connection })` is the only required
|
|
184
|
+
field. The connection options are the shared host / port / auth /
|
|
185
|
+
prefix / tls record. The package derives the per-role client
|
|
186
|
+
options internally.
|
|
187
|
+
|
|
188
|
+
`autoStartWorker` defaults to `false`. Set it to `true` to start a
|
|
189
|
+
BullMQ `Worker` on `OnApplicationBootstrap`. A launcher-only
|
|
190
|
+
deployment (e.g. an API service that only enqueues) should leave it
|
|
191
|
+
`false` so the deployment does not accidentally consume Redis.
|
|
192
|
+
|
|
193
|
+
Async configuration (e.g. when the connection comes from a config
|
|
194
|
+
service):
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
BullmqBatchModule.forRootAsync({
|
|
198
|
+
imports: [ConfigModule],
|
|
199
|
+
inject: [ConfigService],
|
|
200
|
+
useFactory: (cfg: ConfigService) => ({
|
|
201
|
+
connection: {
|
|
202
|
+
host: cfg.get<string>('redis.host'),
|
|
203
|
+
port: cfg.get<number>('redis.port'),
|
|
204
|
+
password: cfg.get<string>('redis.password'),
|
|
205
|
+
},
|
|
206
|
+
}),
|
|
207
|
+
});
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`BullmqBatchModule` is registered as `global: true` (matching
|
|
211
|
+
`NestBatchModule`) so consumers do not need to re-import it in
|
|
212
|
+
every sub-module.
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Step / partition granularity
|
|
217
|
+
|
|
218
|
+
The adapter enqueues **one BullMQ job per step** (or, in a future
|
|
219
|
+
enhancement, one job per partition for chunked steps). It does not
|
|
220
|
+
enqueue one job per row, per chunk, or per item. The contract is
|
|
221
|
+
enforced by the `BullmqRuntimeService.launch()` method, which
|
|
222
|
+
takes the step's `id` from the `JobDefinition` and uses it as the
|
|
223
|
+
BullMQ `name` discriminator. The chunk loop runs _inside_ the
|
|
224
|
+
single BullMQ job, in the worker.
|
|
225
|
+
|
|
226
|
+
Why this matters:
|
|
227
|
+
|
|
228
|
+
- A BullMQ job's per-job overhead (queue entry, stream event,
|
|
229
|
+
retry bookkeeping) is several milliseconds. With 25 input rows
|
|
230
|
+
the per-row model creates 25 entries; with the step model it
|
|
231
|
+
creates 1.
|
|
232
|
+
- The unit of retry is the step. A failed item retries the whole
|
|
233
|
+
step (which is the right granularity for batch work, since
|
|
234
|
+
business retry is Batch Core's job — see below).
|
|
235
|
+
- The unit of BullMQ technical retry is the step too. A Redis
|
|
236
|
+
hiccup retries the step; a transient database error retries the
|
|
237
|
+
step; a business validation failure does not consume a BullMQ
|
|
238
|
+
attempt.
|
|
239
|
+
|
|
240
|
+
Future enhancement: chunked steps with explicit partition
|
|
241
|
+
configuration will enqueue one job per partition (e.g. one job per
|
|
242
|
+
range of 1000 input rows). The worker payload already carries a
|
|
243
|
+
`partitionIndex` field for that case.
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## Business retry vs technical retry
|
|
248
|
+
|
|
249
|
+
The split is deliberate and tested:
|
|
250
|
+
|
|
251
|
+
- **Business retry** lives in Batch Core. Skip policies
|
|
252
|
+
(`LimitSkipPolicy`, `ClassifySkipPolicy`) and business retry
|
|
253
|
+
policies (`ExponentialBackoffRetryPolicy`,
|
|
254
|
+
`FixedDelayRetryPolicy`) are pure functions over the chunk loop
|
|
255
|
+
in `ChunkStepExecutor`. They do not consume BullMQ attempts.
|
|
256
|
+
- **Technical retry** lives in BullMQ. Connection errors, Redis
|
|
257
|
+
hiccups, and worker crashes are retried by BullMQ's
|
|
258
|
+
`attempts` / `backoff` policy on the job. Default is
|
|
259
|
+
`attempts: 3`, `backoff: { type: 'exponential', delay: 100, jitter: 0.5 }`.
|
|
260
|
+
|
|
261
|
+
A business-invalid row is skipped by the skip policy and never
|
|
262
|
+
causes a BullMQ retry. A Redis-down condition triggers a BullMQ
|
|
263
|
+
retry on the step job, but does not change the DB state. The two
|
|
264
|
+
paths are observably separate.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Lifecycle and graceful shutdown
|
|
269
|
+
|
|
270
|
+
The package implements `OnApplicationBootstrap` to spin up the
|
|
271
|
+
`Queue` / `Worker` / `QueueEvents` clients and
|
|
272
|
+
`OnApplicationShutdown` to close them in the documented order:
|
|
273
|
+
|
|
274
|
+
1. **Worker first.** In-flight jobs get a chance to finish or be
|
|
275
|
+
returned to the queue.
|
|
276
|
+
2. **QueueEvents next.** No new events can arrive once the worker
|
|
277
|
+
is closed.
|
|
278
|
+
3. **Queue last.** The producer is closed after the events stream
|
|
279
|
+
so any pending `add()` calls had a chance to land.
|
|
280
|
+
|
|
281
|
+
The close path is idempotent. A second call (e.g. from a test
|
|
282
|
+
harness plus a Nest shutdown) short-circuits to the first close's
|
|
283
|
+
promise rather than racing.
|
|
284
|
+
|
|
285
|
+
`QueueEvents` `completed` / `failed` / `stalled` events are bridged
|
|
286
|
+
to a `BatchObserver` (defaulting to `NoopBatchObserver`). Observer
|
|
287
|
+
errors are logged and contained so a slow / failing observer
|
|
288
|
+
cannot poison the BullMQ event stream.
|
|
289
|
+
|
|
290
|
+
---
|
|
291
|
+
|
|
292
|
+
## What is NOT in this package
|
|
293
|
+
|
|
294
|
+
- A persistence adapter. Use `@nest-batch/mikro-orm` or
|
|
295
|
+
`@nest-batch/typeorm` to wire a `JobRepository`. The transport
|
|
296
|
+
reads and writes the same `JobExecution` rows.
|
|
297
|
+
- A batch engine. Step / chunk / tasklet semantics, skip, restart,
|
|
298
|
+
checkpoint, and business retry live in
|
|
299
|
+
[`@nest-batch/core`](../core). BullMQ is the courier.
|
|
300
|
+
- A scheduler. Cron-style scheduling lives in
|
|
301
|
+
`@nest-batch/core`'s `@BatchScheduled` decorator, which stamps
|
|
302
|
+
metadata read by the `BatchScheduleRegistry`. A future package
|
|
303
|
+
(or a follow-up release of this one) will translate that metadata
|
|
304
|
+
into BullMQ `QueueScheduler` jobs.
|
|
305
|
+
- An admin UI, metrics backend, tracing backend, or webhook system.
|
|
306
|
+
Hook a `BatchObserver` to ship events where you need them.
|
|
307
|
+
- Alternative queue transports (Sidekiq, RabbitMQ, SQS, ...).
|
|
308
|
+
`@nest-batch/core`'s `IExecutionStrategy` polymorphism makes
|
|
309
|
+
these possible, but they are not in scope for this release.
|
|
310
|
+
|
|
311
|
+
---
|
|
312
|
+
|
|
313
|
+
## Scripts
|
|
314
|
+
|
|
315
|
+
```bash
|
|
316
|
+
pnpm --filter @nest-batch/bullmq build # SWC transpile + tsc declarations
|
|
317
|
+
pnpm --filter @nest-batch/bullmq test # vitest run (requires Redis via docker compose)
|
|
318
|
+
pnpm --filter @nest-batch/bullmq test:watch # vitest watch
|
|
319
|
+
pnpm --filter @nest-batch/bullmq typecheck # tsc --noEmit
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
The integration tests expect a Redis instance at
|
|
323
|
+
`127.0.0.1:6379`. The repo's `docker compose up -d redis` is the
|
|
324
|
+
recommended way to bring it up.
|
|
325
|
+
|
|
326
|
+
The boundary test in core
|
|
327
|
+
(`packages/core/tests/core/boundary/no-forbidden-imports.test.ts`)
|
|
328
|
+
is the canary for "BullMQ did not leak into core". Run it locally
|
|
329
|
+
with:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
pnpm --filter @nest-batch/core test -- tests/core/boundary/no-forbidden-imports.test.ts
|
|
333
|
+
```
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { type DynamicModule } from '@nestjs/common';
|
|
2
|
+
import { type BatchAdapter } from '@nest-batch/core';
|
|
3
|
+
import { type BullMqModuleOptions } from '../module-options';
|
|
4
|
+
/**
|
|
5
|
+
* Empty Nest module class that owns the BullMQ transport's
|
|
6
|
+
* provider graph.
|
|
7
|
+
*
|
|
8
|
+
* Mirrors `InProcessModule` in `@nest-batch/core/src/adapters/
|
|
9
|
+
* in-process.adapter.ts`: the class has no body on purpose. It is
|
|
10
|
+
* purely a `DynamicModule` carrier — Nest's module system requires
|
|
11
|
+
* *some* class to identify the module, and the empty class is the
|
|
12
|
+
* minimum possible surface (no decorators, no lifecycle hooks, no
|
|
13
|
+
* metadata). All real behaviour lives on the providers.
|
|
14
|
+
*/
|
|
15
|
+
export declare class BullmqModule {
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* `BullmqAdapter` — the transport adapter for `@nest-batch/bullmq`
|
|
19
|
+
* used by the new factory-pattern
|
|
20
|
+
* `NestBatchModule.forRoot({ adapters: { transport, ... } })` API.
|
|
21
|
+
*
|
|
22
|
+
* Overrides the default `EXECUTION_STRATEGY` token with a BullMQ-
|
|
23
|
+
* backed `IExecutionStrategy` (`BullMqExecutionStrategy`) and wires
|
|
24
|
+
* the runtime services that own the BullMQ client lifecycle
|
|
25
|
+
* (`BullmqRuntimeService` for step enqueue + worker, plus
|
|
26
|
+
* `BullmqScheduleService` for `@BatchScheduled` cron entries).
|
|
27
|
+
*
|
|
28
|
+
* Two static methods:
|
|
29
|
+
*
|
|
30
|
+
* - `forRoot(options)` — synchronous configuration. The
|
|
31
|
+
* connection options are resolved up-front and frozen under
|
|
32
|
+
* the `BULLMQ_MODULE_OPTIONS` token. Use this when the Redis
|
|
33
|
+
* host is known at module composition time.
|
|
34
|
+
*
|
|
35
|
+
* - `forRootAsync({ imports, inject, useFactory })` — async
|
|
36
|
+
* configuration. The factory is registered as a sentinel
|
|
37
|
+
* provider; the `BULLMQ_MODULE_OPTIONS` provider depends on
|
|
38
|
+
* it. Use this when the connection comes from a config
|
|
39
|
+
* service or another async source.
|
|
40
|
+
*
|
|
41
|
+
* The two methods share the same provider list via the
|
|
42
|
+
* `buildStaticProviders` helper — the only difference is whether
|
|
43
|
+
* `BULLMQ_MODULE_OPTIONS` is a value provider (sync) or a factory
|
|
44
|
+
* provider that resolves the user's `useFactory` result (async).
|
|
45
|
+
*
|
|
46
|
+
* `globalProviders` is intentionally omitted. The recommended path
|
|
47
|
+
* is to expose host-visible providers via the module's own
|
|
48
|
+
* `exports` (see `ADAPTER_EXPORTS` above) — the `BatchAdapter`
|
|
49
|
+
* interface's `globalProviders` field is for runtime classes the
|
|
50
|
+
* adapter's own module needs but that core itself would also
|
|
51
|
+
* re-export. `JobLauncher` (registered by `NestBatchModule`, not
|
|
52
|
+
* by this adapter) injects the strategy by the `EXECUTION_STRATEGY`
|
|
53
|
+
* token, which is already in `exports`, so the resolution chain
|
|
54
|
+
* works without core having to know which adapter is active.
|
|
55
|
+
*
|
|
56
|
+
* @example
|
|
57
|
+
* ```ts
|
|
58
|
+
* // Synchronous wiring (connection known at module-build time)
|
|
59
|
+
* import { Module } from '@nestjs/common';
|
|
60
|
+
* import { NestBatchModule, InProcessAdapter } from '@nest-batch/core';
|
|
61
|
+
* import { MikroOrmAdapter } from '@nest-batch/mikro-orm';
|
|
62
|
+
* import { BullmqAdapter } from '@nest-batch/bullmq';
|
|
63
|
+
*
|
|
64
|
+
* @Module({
|
|
65
|
+
* imports: [
|
|
66
|
+
* NestBatchModule.forRoot({
|
|
67
|
+
* adapters: {
|
|
68
|
+
* persistence: MikroOrmAdapter,
|
|
69
|
+
* transport: BullmqAdapter.forRoot({
|
|
70
|
+
* connection: {
|
|
71
|
+
* host: process.env.REDIS_HOST,
|
|
72
|
+
* port: Number(process.env.REDIS_PORT),
|
|
73
|
+
* keyPrefix: 'nest-batch:',
|
|
74
|
+
* },
|
|
75
|
+
* autoStartWorker: true,
|
|
76
|
+
* }),
|
|
77
|
+
* },
|
|
78
|
+
* }),
|
|
79
|
+
* ],
|
|
80
|
+
* })
|
|
81
|
+
* class AppModule {}
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @example
|
|
85
|
+
* ```ts
|
|
86
|
+
* // Async wiring (connection sourced from ConfigService)
|
|
87
|
+
* BullmqAdapter.forRootAsync({
|
|
88
|
+
* imports: [ConfigModule],
|
|
89
|
+
* inject: [ConfigService],
|
|
90
|
+
* useFactory: (cfg: ConfigService) => ({
|
|
91
|
+
* connection: {
|
|
92
|
+
* host: cfg.get<string>('redis.host'),
|
|
93
|
+
* port: cfg.get<number>('redis.port'),
|
|
94
|
+
* password: cfg.get<string>('redis.password'),
|
|
95
|
+
* },
|
|
96
|
+
* }),
|
|
97
|
+
* });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
export declare class BullmqAdapter {
|
|
101
|
+
/**
|
|
102
|
+
* Synchronous configuration.
|
|
103
|
+
*
|
|
104
|
+
* Resolves the connection options up-front (`resolveBullMqConnection`
|
|
105
|
+
* fills in defaults + freezes the bag) and emits a
|
|
106
|
+
* `BatchAdapter` whose `module` is a `global: true`
|
|
107
|
+
* `DynamicModule` registering the strategy class, the runtime
|
|
108
|
+
* services, the `EXECUTION_STRATEGY` binding, and the resolved
|
|
109
|
+
* options as a value provider under `BULLMQ_MODULE_OPTIONS`.
|
|
110
|
+
*
|
|
111
|
+
* No options object is required: the module accepts an empty
|
|
112
|
+
* `{}` and applies all defaults (host `127.0.0.1`, port `6379`,
|
|
113
|
+
* keyPrefix `nest-batch:`, no auth, no TLS, `autoStartWorker:
|
|
114
|
+
* false`).
|
|
115
|
+
*
|
|
116
|
+
* @param options - Connection + worker config. All fields optional.
|
|
117
|
+
* @returns A `BatchAdapter` with `name: 'bullmq'` and the
|
|
118
|
+
* `BullmqModule` dynamic module.
|
|
119
|
+
*/
|
|
120
|
+
static forRoot(options?: BullMqModuleOptions): BatchAdapter;
|
|
121
|
+
/**
|
|
122
|
+
* Async configuration — useful when the Redis connection comes
|
|
123
|
+
* from a config service or another async provider.
|
|
124
|
+
*
|
|
125
|
+
* The shape mirrors `NestBatchModule.forRootAsync`:
|
|
126
|
+
* - `imports` is forwarded to the resulting
|
|
127
|
+
* `DynamicModule.imports` (so `ConfigModule` is available
|
|
128
|
+
* when the factory runs).
|
|
129
|
+
* - `inject` lists the providers the factory needs in its
|
|
130
|
+
* argument list.
|
|
131
|
+
* - `useFactory` resolves the options bag at module-build
|
|
132
|
+
* time. The factory's return value is treated as
|
|
133
|
+
* `BullMqModuleOptions` and is fed through
|
|
134
|
+
* `resolveBullMqConnection` by the `BULLMQ_MODULE_OPTIONS`
|
|
135
|
+
* factory provider (defaults applied, bag frozen).
|
|
136
|
+
*
|
|
137
|
+
* Implementation note: the factory is registered under the
|
|
138
|
+
* package-private `OPTIONS_FACTORY` sentinel token; the
|
|
139
|
+
* `BULLMQ_MODULE_OPTIONS` provider depends on it. This is the
|
|
140
|
+
* same chain the legacy `BullmqBatchModule.forRootAsync` used
|
|
141
|
+
* — the dynamic module is built off the static provider list,
|
|
142
|
+
* with the static `BULLMQ_MODULE_OPTIONS` value provider
|
|
143
|
+
* replaced by the async factory pair.
|
|
144
|
+
*
|
|
145
|
+
* @param asyncOptions - `{ imports, inject, useFactory }` bag.
|
|
146
|
+
* `useFactory` is required; `imports` and `inject` are
|
|
147
|
+
* optional and default to `[]`.
|
|
148
|
+
* @returns A `BatchAdapter` with `name: 'bullmq'` and the
|
|
149
|
+
* `BullmqModule` dynamic module (with `imports` wired).
|
|
150
|
+
*/
|
|
151
|
+
static forRootAsync(asyncOptions: {
|
|
152
|
+
imports?: DynamicModule['imports'];
|
|
153
|
+
inject?: readonly unknown[];
|
|
154
|
+
useFactory: (...args: unknown[]) => Promise<BullMqModuleOptions> | BullMqModuleOptions;
|
|
155
|
+
}): BatchAdapter;
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=bullmq.adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bullmq.adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/bullmq.adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AAC3E,OAAO,EAAsB,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAMzE,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,mBAAmB,CAAC;AAE3B;;;;;;;;;;GAUG;AACH,qBACa,YAAY;CAAG;AAsD5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkFG;AACH,qBAAa,aAAa;IACxB;;;;;;;;;;;;;;;;;;OAkBG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,GAAE,mBAAwB,GAAG,YAAY;IAa/D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE;QAChC,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,CAAC,EAAE,SAAS,OAAO,EAAE,CAAC;QAC5B,UAAU,EAAE,CACV,GAAG,IAAI,EAAE,OAAO,EAAE,KACf,OAAO,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;KACzD,GAAG,YAAY;CAoDjB"}
|