@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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +333 -0
  3. package/dist/src/adapters/bullmq.adapter.d.ts +157 -0
  4. package/dist/src/adapters/bullmq.adapter.d.ts.map +1 -0
  5. package/dist/src/adapters/bullmq.adapter.js +252 -0
  6. package/dist/src/adapters/bullmq.adapter.js.map +1 -0
  7. package/dist/src/adapters/index.d.ts +12 -0
  8. package/dist/src/adapters/index.d.ts.map +1 -0
  9. package/dist/src/adapters/index.js +29 -0
  10. package/dist/src/adapters/index.js.map +1 -0
  11. package/dist/src/bullmq-execution-strategy.d.ts +59 -0
  12. package/dist/src/bullmq-execution-strategy.d.ts.map +1 -0
  13. package/dist/src/bullmq-execution-strategy.js +60 -0
  14. package/dist/src/bullmq-execution-strategy.js.map +1 -0
  15. package/dist/src/bullmq-runtime.service.d.ts +237 -0
  16. package/dist/src/bullmq-runtime.service.d.ts.map +1 -0
  17. package/dist/src/bullmq-runtime.service.js +441 -0
  18. package/dist/src/bullmq-runtime.service.js.map +1 -0
  19. package/dist/src/bullmq-schedule.service.d.ts +121 -0
  20. package/dist/src/bullmq-schedule.service.d.ts.map +1 -0
  21. package/dist/src/bullmq-schedule.service.js +232 -0
  22. package/dist/src/bullmq-schedule.service.js.map +1 -0
  23. package/dist/src/connection.d.ts +83 -0
  24. package/dist/src/connection.d.ts.map +1 -0
  25. package/dist/src/connection.js +72 -0
  26. package/dist/src/connection.js.map +1 -0
  27. package/dist/src/index.d.ts +29 -0
  28. package/dist/src/index.d.ts.map +1 -0
  29. package/dist/src/index.js +46 -0
  30. package/dist/src/index.js.map +1 -0
  31. package/dist/src/module-options.d.ts +68 -0
  32. package/dist/src/module-options.d.ts.map +1 -0
  33. package/dist/src/module-options.js +13 -0
  34. package/dist/src/module-options.js.map +1 -0
  35. package/package.json +71 -0
  36. package/src/adapters/bullmq.adapter.ts +346 -0
  37. package/src/adapters/index.ts +11 -0
  38. package/src/bullmq-execution-strategy.ts +81 -0
  39. package/src/bullmq-runtime.service.ts +540 -0
  40. package/src/bullmq-schedule.service.ts +271 -0
  41. package/src/connection.ts +97 -0
  42. package/src/index.ts +28 -0
  43. 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"}