@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
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get BullmqAdapter () {
|
|
13
|
+
return BullmqAdapter;
|
|
14
|
+
},
|
|
15
|
+
get BullmqModule () {
|
|
16
|
+
return BullmqModule;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _common = require("@nestjs/common");
|
|
20
|
+
const _core = require("@nest-batch/core");
|
|
21
|
+
const _bullmqexecutionstrategy = require("../bullmq-execution-strategy");
|
|
22
|
+
const _bullmqruntimeservice = require("../bullmq-runtime.service");
|
|
23
|
+
const _bullmqscheduleservice = require("../bullmq-schedule.service");
|
|
24
|
+
const _connection = require("../connection");
|
|
25
|
+
const _moduleoptions = require("../module-options");
|
|
26
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
27
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
28
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
29
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
30
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
31
|
+
}
|
|
32
|
+
let BullmqModule = class BullmqModule {
|
|
33
|
+
};
|
|
34
|
+
BullmqModule = _ts_decorate([
|
|
35
|
+
(0, _common.Module)({})
|
|
36
|
+
], BullmqModule);
|
|
37
|
+
/**
|
|
38
|
+
* Sentinel token for the async-options factory chain.
|
|
39
|
+
*
|
|
40
|
+
* `forRootAsync` registers a `useFactory` provider under this token
|
|
41
|
+
* that runs the user's factory, then a second provider
|
|
42
|
+
* (`BULLMQ_MODULE_OPTIONS`) that depends on it and freezes the
|
|
43
|
+
* resolved options. A duplicate `provide` for
|
|
44
|
+
* `BULLMQ_MODULE_OPTIONS` would crash Nest's container, so the
|
|
45
|
+
* chain uses this private symbol as the intermediate step.
|
|
46
|
+
*
|
|
47
|
+
* Mirrors the `Symbol.for('@nest-batch/bullmq/OPTIONS_FACTORY')`
|
|
48
|
+
* used by the legacy `BullmqBatchModule.forRootAsync()` — the
|
|
49
|
+
* `Symbol.for` key is process-scoped and stable across module
|
|
50
|
+
* versions, so any host still wiring up the legacy class is not
|
|
51
|
+
* affected.
|
|
52
|
+
*/ const OPTIONS_FACTORY = Symbol.for('@nest-batch/bullmq/OPTIONS_FACTORY');
|
|
53
|
+
/**
|
|
54
|
+
* The list of exports the BullMQ adapter's `DynamicModule` exposes
|
|
55
|
+
* to the host application.
|
|
56
|
+
*
|
|
57
|
+
* Centralised so the sync and async paths stay in lockstep — any
|
|
58
|
+
* future addition (e.g. a `BullmqScheduler` controller) only needs
|
|
59
|
+
* to be added here.
|
|
60
|
+
*
|
|
61
|
+
* The set mirrors the legacy `BullmqBatchModule.forRoot()` exports
|
|
62
|
+
* (the `forRootAsync()` legacy path was missing
|
|
63
|
+
* `BullmqRuntimeService` from `exports` — that omission is fixed
|
|
64
|
+
* here, both paths now export the same five entries).
|
|
65
|
+
*
|
|
66
|
+
* - `EXECUTION_STRATEGY` — the DI token, so host code (e.g. a
|
|
67
|
+
* `/healthz` endpoint) can resolve the strategy class via
|
|
68
|
+
* `moduleRef.get(EXECUTION_STRATEGY)`.
|
|
69
|
+
* - `BULLMQ_MODULE_OPTIONS` — the resolved connection / worker
|
|
70
|
+
* config bag, for inspection and (future) for per-role client
|
|
71
|
+
* builders.
|
|
72
|
+
* - `BullMqExecutionStrategy` — the concrete class, for type-
|
|
73
|
+
* strict consumers that prefer class injection.
|
|
74
|
+
* - `BullmqRuntimeService` — the runtime that owns the
|
|
75
|
+
* `Queue` / `Worker` / `QueueEvents` lifecycle.
|
|
76
|
+
* - `BullmqScheduleService` — the runtime that owns the
|
|
77
|
+
* `@BatchScheduled` cron-to-BullMQ translation.
|
|
78
|
+
*/ const ADAPTER_EXPORTS = [
|
|
79
|
+
_core.EXECUTION_STRATEGY,
|
|
80
|
+
_moduleoptions.BULLMQ_MODULE_OPTIONS,
|
|
81
|
+
_bullmqexecutionstrategy.BullMqExecutionStrategy,
|
|
82
|
+
_bullmqruntimeservice.BullmqRuntimeService,
|
|
83
|
+
_bullmqscheduleservice.BullmqScheduleService
|
|
84
|
+
];
|
|
85
|
+
let BullmqAdapter = class BullmqAdapter {
|
|
86
|
+
/**
|
|
87
|
+
* Synchronous configuration.
|
|
88
|
+
*
|
|
89
|
+
* Resolves the connection options up-front (`resolveBullMqConnection`
|
|
90
|
+
* fills in defaults + freezes the bag) and emits a
|
|
91
|
+
* `BatchAdapter` whose `module` is a `global: true`
|
|
92
|
+
* `DynamicModule` registering the strategy class, the runtime
|
|
93
|
+
* services, the `EXECUTION_STRATEGY` binding, and the resolved
|
|
94
|
+
* options as a value provider under `BULLMQ_MODULE_OPTIONS`.
|
|
95
|
+
*
|
|
96
|
+
* No options object is required: the module accepts an empty
|
|
97
|
+
* `{}` and applies all defaults (host `127.0.0.1`, port `6379`,
|
|
98
|
+
* keyPrefix `nest-batch:`, no auth, no TLS, `autoStartWorker:
|
|
99
|
+
* false`).
|
|
100
|
+
*
|
|
101
|
+
* @param options - Connection + worker config. All fields optional.
|
|
102
|
+
* @returns A `BatchAdapter` with `name: 'bullmq'` and the
|
|
103
|
+
* `BullmqModule` dynamic module.
|
|
104
|
+
*/ static forRoot(options = {}) {
|
|
105
|
+
const resolved = Object.freeze({
|
|
106
|
+
connection: (0, _connection.resolveBullMqConnection)(options.connection),
|
|
107
|
+
autoStartWorker: options.autoStartWorker ?? false
|
|
108
|
+
});
|
|
109
|
+
return {
|
|
110
|
+
name: 'bullmq',
|
|
111
|
+
module: buildBullmqDynamicModule({
|
|
112
|
+
providers: buildStaticProviders(resolved)
|
|
113
|
+
})
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Async configuration — useful when the Redis connection comes
|
|
118
|
+
* from a config service or another async provider.
|
|
119
|
+
*
|
|
120
|
+
* The shape mirrors `NestBatchModule.forRootAsync`:
|
|
121
|
+
* - `imports` is forwarded to the resulting
|
|
122
|
+
* `DynamicModule.imports` (so `ConfigModule` is available
|
|
123
|
+
* when the factory runs).
|
|
124
|
+
* - `inject` lists the providers the factory needs in its
|
|
125
|
+
* argument list.
|
|
126
|
+
* - `useFactory` resolves the options bag at module-build
|
|
127
|
+
* time. The factory's return value is treated as
|
|
128
|
+
* `BullMqModuleOptions` and is fed through
|
|
129
|
+
* `resolveBullMqConnection` by the `BULLMQ_MODULE_OPTIONS`
|
|
130
|
+
* factory provider (defaults applied, bag frozen).
|
|
131
|
+
*
|
|
132
|
+
* Implementation note: the factory is registered under the
|
|
133
|
+
* package-private `OPTIONS_FACTORY` sentinel token; the
|
|
134
|
+
* `BULLMQ_MODULE_OPTIONS` provider depends on it. This is the
|
|
135
|
+
* same chain the legacy `BullmqBatchModule.forRootAsync` used
|
|
136
|
+
* — the dynamic module is built off the static provider list,
|
|
137
|
+
* with the static `BULLMQ_MODULE_OPTIONS` value provider
|
|
138
|
+
* replaced by the async factory pair.
|
|
139
|
+
*
|
|
140
|
+
* @param asyncOptions - `{ imports, inject, useFactory }` bag.
|
|
141
|
+
* `useFactory` is required; `imports` and `inject` are
|
|
142
|
+
* optional and default to `[]`.
|
|
143
|
+
* @returns A `BatchAdapter` with `name: 'bullmq'` and the
|
|
144
|
+
* `BullmqModule` dynamic module (with `imports` wired).
|
|
145
|
+
*/ static forRootAsync(asyncOptions) {
|
|
146
|
+
const factoryProvider = {
|
|
147
|
+
provide: OPTIONS_FACTORY,
|
|
148
|
+
useFactory: asyncOptions.useFactory,
|
|
149
|
+
inject: [
|
|
150
|
+
...asyncOptions.inject ?? []
|
|
151
|
+
]
|
|
152
|
+
};
|
|
153
|
+
const mergedOptionsProvider = {
|
|
154
|
+
provide: _moduleoptions.BULLMQ_MODULE_OPTIONS,
|
|
155
|
+
useFactory: (fromFactory)=>{
|
|
156
|
+
return Object.freeze({
|
|
157
|
+
connection: (0, _connection.resolveBullMqConnection)(fromFactory?.connection),
|
|
158
|
+
autoStartWorker: fromFactory?.autoStartWorker ?? false
|
|
159
|
+
});
|
|
160
|
+
},
|
|
161
|
+
inject: [
|
|
162
|
+
OPTIONS_FACTORY
|
|
163
|
+
]
|
|
164
|
+
};
|
|
165
|
+
// The static provider list is the same as `forRoot` except
|
|
166
|
+
// the value provider for `BULLMQ_MODULE_OPTIONS` is replaced
|
|
167
|
+
// with the async factory above (a duplicate `provide` would
|
|
168
|
+
// crash Nest's container). We seed `buildStaticProviders`
|
|
169
|
+
// with a placeholder resolved bag (its value is discarded
|
|
170
|
+
// — the async provider overrides the slot) so the function
|
|
171
|
+
// can be the single source of truth for the rest of the
|
|
172
|
+
// provider list.
|
|
173
|
+
const baseProviders = buildStaticProviders(Object.freeze({
|
|
174
|
+
connection: (0, _connection.resolveBullMqConnection)(undefined),
|
|
175
|
+
autoStartWorker: false
|
|
176
|
+
}));
|
|
177
|
+
const filtered = baseProviders.filter((p)=>!(typeof p === 'object' && p !== null && 'provide' in p && p.provide === _moduleoptions.BULLMQ_MODULE_OPTIONS));
|
|
178
|
+
return {
|
|
179
|
+
name: 'bullmq',
|
|
180
|
+
module: buildBullmqDynamicModule({
|
|
181
|
+
providers: [
|
|
182
|
+
factoryProvider,
|
|
183
|
+
mergedOptionsProvider,
|
|
184
|
+
...filtered
|
|
185
|
+
],
|
|
186
|
+
imports: asyncOptions.imports
|
|
187
|
+
})
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
};
|
|
191
|
+
/**
|
|
192
|
+
* Build the static provider list shared by `forRoot()` and
|
|
193
|
+
* `forRootAsync()`.
|
|
194
|
+
*
|
|
195
|
+
* Centralised so the sync and async paths declare the same set of
|
|
196
|
+
* providers (and any future addition — e.g. a per-role client
|
|
197
|
+
* builder — only needs to be added here).
|
|
198
|
+
*
|
|
199
|
+
* The async path then filters the `BULLMQ_MODULE_OPTIONS` entry
|
|
200
|
+
* out of the returned array and replaces it with the factory
|
|
201
|
+
* pair. Everything else is shared.
|
|
202
|
+
*/ function buildStaticProviders(resolved) {
|
|
203
|
+
return [
|
|
204
|
+
_bullmqexecutionstrategy.BullMqExecutionStrategy,
|
|
205
|
+
_bullmqruntimeservice.BullmqRuntimeService,
|
|
206
|
+
_bullmqscheduleservice.BullmqScheduleService,
|
|
207
|
+
{
|
|
208
|
+
provide: _core.EXECUTION_STRATEGY,
|
|
209
|
+
useExisting: _bullmqexecutionstrategy.BullMqExecutionStrategy
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
provide: _moduleoptions.BULLMQ_MODULE_OPTIONS,
|
|
213
|
+
useValue: resolved
|
|
214
|
+
}
|
|
215
|
+
];
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Build the `DynamicModule` payload for the BullMQ adapter.
|
|
219
|
+
*
|
|
220
|
+
* Extracted from the two factory methods so the provider /
|
|
221
|
+
* export / global-true shape lives in one place. NestJS's
|
|
222
|
+
* `validateExportedProvider` check rejects an `exports` entry
|
|
223
|
+
* that is not in `providers` (or imported), so adding to one
|
|
224
|
+
* without the other is a silent runtime failure — keeping the
|
|
225
|
+
* two arrays synchronised by construction is the safest
|
|
226
|
+
* pattern.
|
|
227
|
+
*
|
|
228
|
+
* `imports` is optional: `forRoot` does not need any (it has no
|
|
229
|
+
* async providers), `forRootAsync` forwards the user's
|
|
230
|
+
* `imports` (typically `ConfigModule`) so the factory's
|
|
231
|
+
* `inject` targets resolve.
|
|
232
|
+
*/ function buildBullmqDynamicModule(args) {
|
|
233
|
+
const module = {
|
|
234
|
+
module: BullmqModule,
|
|
235
|
+
global: true,
|
|
236
|
+
providers: args.providers,
|
|
237
|
+
exports: [
|
|
238
|
+
...ADAPTER_EXPORTS
|
|
239
|
+
]
|
|
240
|
+
};
|
|
241
|
+
if (args.imports !== undefined) {
|
|
242
|
+
return {
|
|
243
|
+
...module,
|
|
244
|
+
imports: [
|
|
245
|
+
...args.imports
|
|
246
|
+
]
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return module;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//# sourceMappingURL=bullmq.adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/adapters/bullmq.adapter.ts"],"sourcesContent":["import { Module, type DynamicModule, type Provider } from '@nestjs/common';\nimport { EXECUTION_STRATEGY, type BatchAdapter } from '@nest-batch/core';\n\nimport { BullMqExecutionStrategy } from '../bullmq-execution-strategy';\nimport { BullmqRuntimeService } from '../bullmq-runtime.service';\nimport { BullmqScheduleService } from '../bullmq-schedule.service';\nimport { resolveBullMqConnection } from '../connection';\nimport {\n BULLMQ_MODULE_OPTIONS,\n type BullMqModuleOptions,\n type ResolvedBullMqModuleOptions,\n} from '../module-options';\n\n/**\n * Empty Nest module class that owns the BullMQ transport's\n * provider graph.\n *\n * Mirrors `InProcessModule` in `@nest-batch/core/src/adapters/\n * in-process.adapter.ts`: the class has no body on purpose. It is\n * purely a `DynamicModule` carrier — Nest's module system requires\n * *some* class to identify the module, and the empty class is the\n * minimum possible surface (no decorators, no lifecycle hooks, no\n * metadata). All real behaviour lives on the providers.\n */\n@Module({})\nexport class BullmqModule {}\n\n/**\n * Sentinel token for the async-options factory chain.\n *\n * `forRootAsync` registers a `useFactory` provider under this token\n * that runs the user's factory, then a second provider\n * (`BULLMQ_MODULE_OPTIONS`) that depends on it and freezes the\n * resolved options. A duplicate `provide` for\n * `BULLMQ_MODULE_OPTIONS` would crash Nest's container, so the\n * chain uses this private symbol as the intermediate step.\n *\n * Mirrors the `Symbol.for('@nest-batch/bullmq/OPTIONS_FACTORY')`\n * used by the legacy `BullmqBatchModule.forRootAsync()` — the\n * `Symbol.for` key is process-scoped and stable across module\n * versions, so any host still wiring up the legacy class is not\n * affected.\n */\nconst OPTIONS_FACTORY: symbol = Symbol.for('@nest-batch/bullmq/OPTIONS_FACTORY');\n\n/**\n * The list of exports the BullMQ adapter's `DynamicModule` exposes\n * to the host application.\n *\n * Centralised so the sync and async paths stay in lockstep — any\n * future addition (e.g. a `BullmqScheduler` controller) only needs\n * to be added here.\n *\n * The set mirrors the legacy `BullmqBatchModule.forRoot()` exports\n * (the `forRootAsync()` legacy path was missing\n * `BullmqRuntimeService` from `exports` — that omission is fixed\n * here, both paths now export the same five entries).\n *\n * - `EXECUTION_STRATEGY` — the DI token, so host code (e.g. a\n * `/healthz` endpoint) can resolve the strategy class via\n * `moduleRef.get(EXECUTION_STRATEGY)`.\n * - `BULLMQ_MODULE_OPTIONS` — the resolved connection / worker\n * config bag, for inspection and (future) for per-role client\n * builders.\n * - `BullMqExecutionStrategy` — the concrete class, for type-\n * strict consumers that prefer class injection.\n * - `BullmqRuntimeService` — the runtime that owns the\n * `Queue` / `Worker` / `QueueEvents` lifecycle.\n * - `BullmqScheduleService` — the runtime that owns the\n * `@BatchScheduled` cron-to-BullMQ translation.\n */\nconst ADAPTER_EXPORTS: ReadonlyArray<symbol | typeof BullMqExecutionStrategy | typeof BullmqRuntimeService | typeof BullmqScheduleService> = [\n EXECUTION_STRATEGY,\n BULLMQ_MODULE_OPTIONS,\n BullMqExecutionStrategy,\n BullmqRuntimeService,\n BullmqScheduleService,\n];\n\n/**\n * `BullmqAdapter` — the transport adapter for `@nest-batch/bullmq`\n * used by the new factory-pattern\n * `NestBatchModule.forRoot({ adapters: { transport, ... } })` API.\n *\n * Overrides the default `EXECUTION_STRATEGY` token with a BullMQ-\n * backed `IExecutionStrategy` (`BullMqExecutionStrategy`) and wires\n * the runtime services that own the BullMQ client lifecycle\n * (`BullmqRuntimeService` for step enqueue + worker, plus\n * `BullmqScheduleService` for `@BatchScheduled` cron entries).\n *\n * Two static methods:\n *\n * - `forRoot(options)` — synchronous configuration. The\n * connection options are resolved up-front and frozen under\n * the `BULLMQ_MODULE_OPTIONS` token. Use this when the Redis\n * host is known at module composition time.\n *\n * - `forRootAsync({ imports, inject, useFactory })` — async\n * configuration. The factory is registered as a sentinel\n * provider; the `BULLMQ_MODULE_OPTIONS` provider depends on\n * it. Use this when the connection comes from a config\n * service or another async source.\n *\n * The two methods share the same provider list via the\n * `buildStaticProviders` helper — the only difference is whether\n * `BULLMQ_MODULE_OPTIONS` is a value provider (sync) or a factory\n * provider that resolves the user's `useFactory` result (async).\n *\n * `globalProviders` is intentionally omitted. The recommended path\n * is to expose host-visible providers via the module's own\n * `exports` (see `ADAPTER_EXPORTS` above) — the `BatchAdapter`\n * interface's `globalProviders` field is for runtime classes the\n * adapter's own module needs but that core itself would also\n * re-export. `JobLauncher` (registered by `NestBatchModule`, not\n * by this adapter) injects the strategy by the `EXECUTION_STRATEGY`\n * token, which is already in `exports`, so the resolution chain\n * works without core having to know which adapter is active.\n *\n * @example\n * ```ts\n * // Synchronous wiring (connection known at module-build time)\n * import { Module } from '@nestjs/common';\n * import { NestBatchModule, InProcessAdapter } from '@nest-batch/core';\n * import { MikroOrmAdapter } from '@nest-batch/mikro-orm';\n * import { BullmqAdapter } from '@nest-batch/bullmq';\n *\n * @Module({\n * imports: [\n * NestBatchModule.forRoot({\n * adapters: {\n * persistence: MikroOrmAdapter,\n * transport: BullmqAdapter.forRoot({\n * connection: {\n * host: process.env.REDIS_HOST,\n * port: Number(process.env.REDIS_PORT),\n * keyPrefix: 'nest-batch:',\n * },\n * autoStartWorker: true,\n * }),\n * },\n * }),\n * ],\n * })\n * class AppModule {}\n * ```\n *\n * @example\n * ```ts\n * // Async wiring (connection sourced from ConfigService)\n * BullmqAdapter.forRootAsync({\n * imports: [ConfigModule],\n * inject: [ConfigService],\n * useFactory: (cfg: ConfigService) => ({\n * connection: {\n * host: cfg.get<string>('redis.host'),\n * port: cfg.get<number>('redis.port'),\n * password: cfg.get<string>('redis.password'),\n * },\n * }),\n * });\n * ```\n */\nexport class BullmqAdapter {\n /**\n * Synchronous configuration.\n *\n * Resolves the connection options up-front (`resolveBullMqConnection`\n * fills in defaults + freezes the bag) and emits a\n * `BatchAdapter` whose `module` is a `global: true`\n * `DynamicModule` registering the strategy class, the runtime\n * services, the `EXECUTION_STRATEGY` binding, and the resolved\n * options as a value provider under `BULLMQ_MODULE_OPTIONS`.\n *\n * No options object is required: the module accepts an empty\n * `{}` and applies all defaults (host `127.0.0.1`, port `6379`,\n * keyPrefix `nest-batch:`, no auth, no TLS, `autoStartWorker:\n * false`).\n *\n * @param options - Connection + worker config. All fields optional.\n * @returns A `BatchAdapter` with `name: 'bullmq'` and the\n * `BullmqModule` dynamic module.\n */\n static forRoot(options: BullMqModuleOptions = {}): BatchAdapter {\n const resolved: ResolvedBullMqModuleOptions = Object.freeze({\n connection: resolveBullMqConnection(options.connection),\n autoStartWorker: options.autoStartWorker ?? false,\n });\n return {\n name: 'bullmq',\n module: buildBullmqDynamicModule({\n providers: buildStaticProviders(resolved),\n }),\n };\n }\n\n /**\n * Async configuration — useful when the Redis connection comes\n * from a config service or another async provider.\n *\n * The shape mirrors `NestBatchModule.forRootAsync`:\n * - `imports` is forwarded to the resulting\n * `DynamicModule.imports` (so `ConfigModule` is available\n * when the factory runs).\n * - `inject` lists the providers the factory needs in its\n * argument list.\n * - `useFactory` resolves the options bag at module-build\n * time. The factory's return value is treated as\n * `BullMqModuleOptions` and is fed through\n * `resolveBullMqConnection` by the `BULLMQ_MODULE_OPTIONS`\n * factory provider (defaults applied, bag frozen).\n *\n * Implementation note: the factory is registered under the\n * package-private `OPTIONS_FACTORY` sentinel token; the\n * `BULLMQ_MODULE_OPTIONS` provider depends on it. This is the\n * same chain the legacy `BullmqBatchModule.forRootAsync` used\n * — the dynamic module is built off the static provider list,\n * with the static `BULLMQ_MODULE_OPTIONS` value provider\n * replaced by the async factory pair.\n *\n * @param asyncOptions - `{ imports, inject, useFactory }` bag.\n * `useFactory` is required; `imports` and `inject` are\n * optional and default to `[]`.\n * @returns A `BatchAdapter` with `name: 'bullmq'` and the\n * `BullmqModule` dynamic module (with `imports` wired).\n */\n static forRootAsync(asyncOptions: {\n imports?: DynamicModule['imports'];\n inject?: readonly unknown[];\n useFactory: (\n ...args: unknown[]\n ) => Promise<BullMqModuleOptions> | BullMqModuleOptions;\n }): BatchAdapter {\n const factoryProvider: Provider = {\n provide: OPTIONS_FACTORY,\n useFactory: asyncOptions.useFactory as (...args: unknown[]) => unknown,\n inject: [...(asyncOptions.inject ?? [])] as Array<string | symbol | Function>,\n };\n\n const mergedOptionsProvider: Provider = {\n provide: BULLMQ_MODULE_OPTIONS,\n useFactory: (\n fromFactory: BullMqModuleOptions | undefined,\n ): ResolvedBullMqModuleOptions => {\n return Object.freeze({\n connection: resolveBullMqConnection(fromFactory?.connection),\n autoStartWorker: fromFactory?.autoStartWorker ?? false,\n });\n },\n inject: [OPTIONS_FACTORY],\n };\n\n // The static provider list is the same as `forRoot` except\n // the value provider for `BULLMQ_MODULE_OPTIONS` is replaced\n // with the async factory above (a duplicate `provide` would\n // crash Nest's container). We seed `buildStaticProviders`\n // with a placeholder resolved bag (its value is discarded\n // — the async provider overrides the slot) so the function\n // can be the single source of truth for the rest of the\n // provider list.\n const baseProviders = buildStaticProviders(\n Object.freeze({\n connection: resolveBullMqConnection(undefined),\n autoStartWorker: false,\n }),\n );\n const filtered = baseProviders.filter(\n (p) =>\n !(\n typeof p === 'object' &&\n p !== null &&\n 'provide' in p &&\n (p as { provide: unknown }).provide === BULLMQ_MODULE_OPTIONS\n ),\n );\n\n return {\n name: 'bullmq',\n module: buildBullmqDynamicModule({\n providers: [factoryProvider, mergedOptionsProvider, ...filtered],\n imports: asyncOptions.imports,\n }),\n };\n }\n}\n\n/**\n * Build the static provider list shared by `forRoot()` and\n * `forRootAsync()`.\n *\n * Centralised so the sync and async paths declare the same set of\n * providers (and any future addition — e.g. a per-role client\n * builder — only needs to be added here).\n *\n * The async path then filters the `BULLMQ_MODULE_OPTIONS` entry\n * out of the returned array and replaces it with the factory\n * pair. Everything else is shared.\n */\nfunction buildStaticProviders(\n resolved: ResolvedBullMqModuleOptions,\n): Provider[] {\n return [\n BullMqExecutionStrategy,\n BullmqRuntimeService,\n BullmqScheduleService,\n {\n provide: EXECUTION_STRATEGY,\n useExisting: BullMqExecutionStrategy,\n },\n {\n provide: BULLMQ_MODULE_OPTIONS,\n useValue: resolved,\n },\n ];\n}\n\n/**\n * Build the `DynamicModule` payload for the BullMQ adapter.\n *\n * Extracted from the two factory methods so the provider /\n * export / global-true shape lives in one place. NestJS's\n * `validateExportedProvider` check rejects an `exports` entry\n * that is not in `providers` (or imported), so adding to one\n * without the other is a silent runtime failure — keeping the\n * two arrays synchronised by construction is the safest\n * pattern.\n *\n * `imports` is optional: `forRoot` does not need any (it has no\n * async providers), `forRootAsync` forwards the user's\n * `imports` (typically `ConfigModule`) so the factory's\n * `inject` targets resolve.\n */\nfunction buildBullmqDynamicModule(args: {\n providers: Provider[];\n imports?: DynamicModule['imports'];\n}): DynamicModule {\n const module: DynamicModule = {\n module: BullmqModule,\n global: true,\n providers: args.providers,\n exports: [...ADAPTER_EXPORTS],\n };\n if (args.imports !== undefined) {\n return { ...module, imports: [...args.imports] };\n }\n return module;\n}\n"],"names":["BullmqAdapter","BullmqModule","OPTIONS_FACTORY","Symbol","for","ADAPTER_EXPORTS","EXECUTION_STRATEGY","BULLMQ_MODULE_OPTIONS","BullMqExecutionStrategy","BullmqRuntimeService","BullmqScheduleService","forRoot","options","resolved","Object","freeze","connection","resolveBullMqConnection","autoStartWorker","name","module","buildBullmqDynamicModule","providers","buildStaticProviders","forRootAsync","asyncOptions","factoryProvider","provide","useFactory","inject","mergedOptionsProvider","fromFactory","baseProviders","undefined","filtered","filter","p","imports","useExisting","useValue","args","global","exports"],"mappings":";;;;;;;;;;;QAkKaA;eAAAA;;QAzIAC;eAAAA;;;wBAzB6C;sBACJ;yCAEd;sCACH;uCACC;4BACE;+BAKjC;;;;;;;AAcA,IAAA,AAAMA,eAAN,MAAMA;AAAc;;;;AAE3B;;;;;;;;;;;;;;;CAeC,GACD,MAAMC,kBAA0BC,OAAOC,GAAG,CAAC;AAE3C;;;;;;;;;;;;;;;;;;;;;;;;;CAyBC,GACD,MAAMC,kBAAuI;IAC3IC,wBAAkB;IAClBC,oCAAqB;IACrBC,gDAAuB;IACvBC,0CAAoB;IACpBC,4CAAqB;CACtB;AAqFM,IAAA,AAAMV,gBAAN,MAAMA;IACX;;;;;;;;;;;;;;;;;;GAkBC,GACD,OAAOW,QAAQC,UAA+B,CAAC,CAAC,EAAgB;QAC9D,MAAMC,WAAwCC,OAAOC,MAAM,CAAC;YAC1DC,YAAYC,IAAAA,mCAAuB,EAACL,QAAQI,UAAU;YACtDE,iBAAiBN,QAAQM,eAAe,IAAI;QAC9C;QACA,OAAO;YACLC,MAAM;YACNC,QAAQC,yBAAyB;gBAC/BC,WAAWC,qBAAqBV;YAClC;QACF;IACF;IAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BC,GACD,OAAOW,aAAaC,YAMnB,EAAgB;QACf,MAAMC,kBAA4B;YAChCC,SAASzB;YACT0B,YAAYH,aAAaG,UAAU;YACnCC,QAAQ;mBAAKJ,aAAaI,MAAM,IAAI,EAAE;aAAE;QAC1C;QAEA,MAAMC,wBAAkC;YACtCH,SAASpB,oCAAqB;YAC9BqB,YAAY,CACVG;gBAEA,OAAOjB,OAAOC,MAAM,CAAC;oBACnBC,YAAYC,IAAAA,mCAAuB,EAACc,aAAaf;oBACjDE,iBAAiBa,aAAab,mBAAmB;gBACnD;YACF;YACAW,QAAQ;gBAAC3B;aAAgB;QAC3B;QAEA,2DAA2D;QAC3D,6DAA6D;QAC7D,4DAA4D;QAC5D,0DAA0D;QAC1D,0DAA0D;QAC1D,2DAA2D;QAC3D,wDAAwD;QACxD,iBAAiB;QACjB,MAAM8B,gBAAgBT,qBACpBT,OAAOC,MAAM,CAAC;YACZC,YAAYC,IAAAA,mCAAuB,EAACgB;YACpCf,iBAAiB;QACnB;QAEF,MAAMgB,WAAWF,cAAcG,MAAM,CACnC,CAACC,IACC,CACE,CAAA,OAAOA,MAAM,YACbA,MAAM,QACN,aAAaA,KACb,AAACA,EAA2BT,OAAO,KAAKpB,oCAAqB,AAAD;QAIlE,OAAO;YACLY,MAAM;YACNC,QAAQC,yBAAyB;gBAC/BC,WAAW;oBAACI;oBAAiBI;uBAA0BI;iBAAS;gBAChEG,SAASZ,aAAaY,OAAO;YAC/B;QACF;IACF;AACF;AAEA;;;;;;;;;;;CAWC,GACD,SAASd,qBACPV,QAAqC;IAErC,OAAO;QACLL,gDAAuB;QACvBC,0CAAoB;QACpBC,4CAAqB;QACrB;YACEiB,SAASrB,wBAAkB;YAC3BgC,aAAa9B,gDAAuB;QACtC;QACA;YACEmB,SAASpB,oCAAqB;YAC9BgC,UAAU1B;QACZ;KACD;AACH;AAEA;;;;;;;;;;;;;;;CAeC,GACD,SAASQ,yBAAyBmB,IAGjC;IACC,MAAMpB,SAAwB;QAC5BA,QAAQnB;QACRwC,QAAQ;QACRnB,WAAWkB,KAAKlB,SAAS;QACzBoB,SAAS;eAAIrC;SAAgB;IAC/B;IACA,IAAImC,KAAKH,OAAO,KAAKJ,WAAW;QAC9B,OAAO;YAAE,GAAGb,MAAM;YAAEiB,SAAS;mBAAIG,KAAKH,OAAO;aAAC;QAAC;IACjD;IACA,OAAOjB;AACT"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the BullMQ adapter factory.
|
|
3
|
+
*
|
|
4
|
+
* The `BullmqAdapter` is the only entry point the host should
|
|
5
|
+
* depend on for the new factory-pattern API. The internal module
|
|
6
|
+
* class (`BullmqModule`) is exported alongside it as a NestJS
|
|
7
|
+
* identifier — it is safe to reference from test code that needs
|
|
8
|
+
* to assert on the `module` field of the adapter value, but it
|
|
9
|
+
* has no runtime surface beyond the empty class body.
|
|
10
|
+
*/
|
|
11
|
+
export * from './bullmq.adapter';
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,cAAc,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public surface for the BullMQ adapter factory.
|
|
3
|
+
*
|
|
4
|
+
* The `BullmqAdapter` is the only entry point the host should
|
|
5
|
+
* depend on for the new factory-pattern API. The internal module
|
|
6
|
+
* class (`BullmqModule`) is exported alongside it as a NestJS
|
|
7
|
+
* identifier — it is safe to reference from test code that needs
|
|
8
|
+
* to assert on the `module` field of the adapter value, but it
|
|
9
|
+
* has no runtime surface beyond the empty class body.
|
|
10
|
+
*/ "use strict";
|
|
11
|
+
Object.defineProperty(exports, "__esModule", {
|
|
12
|
+
value: true
|
|
13
|
+
});
|
|
14
|
+
_export_star(require("./bullmq.adapter"), exports);
|
|
15
|
+
function _export_star(from, to) {
|
|
16
|
+
Object.keys(from).forEach(function(k) {
|
|
17
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
18
|
+
Object.defineProperty(to, k, {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function() {
|
|
21
|
+
return from[k];
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return from;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/adapters/index.ts"],"sourcesContent":["/**\n * Public surface for the BullMQ adapter factory.\n *\n * The `BullmqAdapter` is the only entry point the host should\n * depend on for the new factory-pattern API. The internal module\n * class (`BullmqModule`) is exported alongside it as a NestJS\n * identifier — it is safe to reference from test code that needs\n * to assert on the `module` field of the adapter value, but it\n * has no runtime surface beyond the empty class body.\n */\nexport * from './bullmq.adapter';\n"],"names":[],"mappings":"AAAA;;;;;;;;;CASC;;;;qBACa"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { type ExecutionStrategyContext, type IExecutionStrategy, type JobDefinition, type JobParameters, type LaunchResult } from '@nest-batch/core';
|
|
2
|
+
import { BullmqRuntimeService, BULLMQ_STRATEGY_NAME } from './bullmq-runtime.service';
|
|
3
|
+
/**
|
|
4
|
+
* BullMQ execution strategy — the `@nest-batch/core`-facing
|
|
5
|
+
* transport that hands a `JobExecution` off to a BullMQ `Queue`
|
|
6
|
+
* and lets a `Worker` process the work.
|
|
7
|
+
*
|
|
8
|
+
* Design (T18):
|
|
9
|
+
* - The actual BullMQ resource ownership (queue / worker /
|
|
10
|
+
* queue-events lifecycle, connection tuning, event bridge)
|
|
11
|
+
* lives in `BullmqRuntimeService`. This class is a thin
|
|
12
|
+
* adapter that maps the `IExecutionStrategy` contract to
|
|
13
|
+
* the runtime service's `launch()` shape.
|
|
14
|
+
* - Splitting the two lets the runtime service be
|
|
15
|
+
* independently testable (e.g. a test that wants to drive
|
|
16
|
+
* the worker without going through the launcher can
|
|
17
|
+
* instantiate the runtime service alone), and lets the
|
|
18
|
+
* strategy class stay as a stable public surface for
|
|
19
|
+
* `EXECUTION_STRATEGY` consumers.
|
|
20
|
+
* - The strategy inherits the runtime service's
|
|
21
|
+
* `name` (`'bullmq'`) — the runtime service is the
|
|
22
|
+
* single source of truth for the strategy name.
|
|
23
|
+
*
|
|
24
|
+
* `name` and `launch()` together comprise the T18 contract:
|
|
25
|
+
* - `name = 'bullmq'` — replaces the T17 stub's
|
|
26
|
+
* `'bullmq-stub'` so log lines and boundary reports can
|
|
27
|
+
* tell the real implementation from the skeleton.
|
|
28
|
+
* - `launch()` enqueues exactly one BullMQ job per step
|
|
29
|
+
* (one job per step, NEVER one job per row/chunk) and
|
|
30
|
+
* returns `{ kind: 'enqueued', queueJobId }`. The launch
|
|
31
|
+
* is fire-and-forget; the launcher re-resolves the
|
|
32
|
+
* canonical `JobExecution` from the repository.
|
|
33
|
+
*/
|
|
34
|
+
export declare class BullMqExecutionStrategy implements IExecutionStrategy {
|
|
35
|
+
private readonly runtime;
|
|
36
|
+
/** Strategy name. Mirrors the runtime service's name. */
|
|
37
|
+
readonly name = "bullmq";
|
|
38
|
+
private readonly logger;
|
|
39
|
+
constructor(runtime: BullmqRuntimeService);
|
|
40
|
+
/**
|
|
41
|
+
* Enqueue the work and return the BullMQ job id. The DB
|
|
42
|
+
* execution row was created by the launcher BEFORE this
|
|
43
|
+
* method was called — this method MUST NOT re-create it
|
|
44
|
+
* (the launcher's atomic create-or-lock would race with us).
|
|
45
|
+
*
|
|
46
|
+
* Throws on producer failure. The launcher propagates the
|
|
47
|
+
* error to its caller; the canonical `JobExecution` row
|
|
48
|
+
* stays in `STARTING` and the host's recovery path is
|
|
49
|
+
* responsible for transitioning it (a future task will
|
|
50
|
+
* wire a "dead letter" cleanup).
|
|
51
|
+
*/
|
|
52
|
+
launch(job: JobDefinition, params: JobParameters, ctx: ExecutionStrategyContext): Promise<LaunchResult>;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Re-export the canonical `name` for tests that want to assert
|
|
56
|
+
* on it without importing the runtime service directly.
|
|
57
|
+
*/
|
|
58
|
+
export { BULLMQ_STRATEGY_NAME };
|
|
59
|
+
//# sourceMappingURL=bullmq-execution-strategy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bullmq-execution-strategy.d.ts","sourceRoot":"","sources":["../../src/bullmq-execution-strategy.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,KAAK,wBAAwB,EAC7B,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,YAAY,EAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBACa,uBAAwB,YAAW,kBAAkB;IAMpD,OAAO,CAAC,QAAQ,CAAC,OAAO;IALpC,yDAAyD;IACzD,QAAQ,CAAC,IAAI,YAAwB;IAErC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAA4C;gBAEtC,OAAO,EAAE,oBAAoB;IAE1D;;;;;;;;;;;OAWG;IACG,MAAM,CACV,GAAG,EAAE,aAAa,EAClB,MAAM,EAAE,aAAa,EACrB,GAAG,EAAE,wBAAwB,GAC5B,OAAO,CAAC,YAAY,CAAC;CAGzB;AAED;;;GAGG;AACH,OAAO,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
function _export(target, all) {
|
|
6
|
+
for(var name in all)Object.defineProperty(target, name, {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
_export(exports, {
|
|
12
|
+
get BULLMQ_STRATEGY_NAME () {
|
|
13
|
+
return _bullmqruntimeservice.BULLMQ_STRATEGY_NAME;
|
|
14
|
+
},
|
|
15
|
+
get BullMqExecutionStrategy () {
|
|
16
|
+
return BullMqExecutionStrategy;
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
const _common = require("@nestjs/common");
|
|
20
|
+
const _bullmqruntimeservice = require("./bullmq-runtime.service");
|
|
21
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
22
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
23
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
24
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
25
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
26
|
+
}
|
|
27
|
+
function _ts_metadata(k, v) {
|
|
28
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
29
|
+
}
|
|
30
|
+
let BullMqExecutionStrategy = class BullMqExecutionStrategy {
|
|
31
|
+
runtime;
|
|
32
|
+
/** Strategy name. Mirrors the runtime service's name. */ name = _bullmqruntimeservice.BULLMQ_STRATEGY_NAME;
|
|
33
|
+
logger = new _common.Logger(BullMqExecutionStrategy.name);
|
|
34
|
+
constructor(runtime){
|
|
35
|
+
this.runtime = runtime;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Enqueue the work and return the BullMQ job id. The DB
|
|
39
|
+
* execution row was created by the launcher BEFORE this
|
|
40
|
+
* method was called — this method MUST NOT re-create it
|
|
41
|
+
* (the launcher's atomic create-or-lock would race with us).
|
|
42
|
+
*
|
|
43
|
+
* Throws on producer failure. The launcher propagates the
|
|
44
|
+
* error to its caller; the canonical `JobExecution` row
|
|
45
|
+
* stays in `STARTING` and the host's recovery path is
|
|
46
|
+
* responsible for transitioning it (a future task will
|
|
47
|
+
* wire a "dead letter" cleanup).
|
|
48
|
+
*/ async launch(job, params, ctx) {
|
|
49
|
+
return this.runtime.launch(job, params, ctx);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
BullMqExecutionStrategy = _ts_decorate([
|
|
53
|
+
(0, _common.Injectable)(),
|
|
54
|
+
_ts_metadata("design:type", Function),
|
|
55
|
+
_ts_metadata("design:paramtypes", [
|
|
56
|
+
typeof _bullmqruntimeservice.BullmqRuntimeService === "undefined" ? Object : _bullmqruntimeservice.BullmqRuntimeService
|
|
57
|
+
])
|
|
58
|
+
], BullMqExecutionStrategy);
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=bullmq-execution-strategy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/bullmq-execution-strategy.ts"],"sourcesContent":["import { Injectable, Logger } from '@nestjs/common';\n\nimport {\n type ExecutionStrategyContext,\n type IExecutionStrategy,\n type JobDefinition,\n type JobParameters,\n type LaunchResult,\n} from '@nest-batch/core';\n\nimport {\n BullmqRuntimeService,\n BULLMQ_STRATEGY_NAME,\n} from './bullmq-runtime.service';\n\n/**\n * BullMQ execution strategy — the `@nest-batch/core`-facing\n * transport that hands a `JobExecution` off to a BullMQ `Queue`\n * and lets a `Worker` process the work.\n *\n * Design (T18):\n * - The actual BullMQ resource ownership (queue / worker /\n * queue-events lifecycle, connection tuning, event bridge)\n * lives in `BullmqRuntimeService`. This class is a thin\n * adapter that maps the `IExecutionStrategy` contract to\n * the runtime service's `launch()` shape.\n * - Splitting the two lets the runtime service be\n * independently testable (e.g. a test that wants to drive\n * the worker without going through the launcher can\n * instantiate the runtime service alone), and lets the\n * strategy class stay as a stable public surface for\n * `EXECUTION_STRATEGY` consumers.\n * - The strategy inherits the runtime service's\n * `name` (`'bullmq'`) — the runtime service is the\n * single source of truth for the strategy name.\n *\n * `name` and `launch()` together comprise the T18 contract:\n * - `name = 'bullmq'` — replaces the T17 stub's\n * `'bullmq-stub'` so log lines and boundary reports can\n * tell the real implementation from the skeleton.\n * - `launch()` enqueues exactly one BullMQ job per step\n * (one job per step, NEVER one job per row/chunk) and\n * returns `{ kind: 'enqueued', queueJobId }`. The launch\n * is fire-and-forget; the launcher re-resolves the\n * canonical `JobExecution` from the repository.\n */\n@Injectable()\nexport class BullMqExecutionStrategy implements IExecutionStrategy {\n /** Strategy name. Mirrors the runtime service's name. */\n readonly name = BULLMQ_STRATEGY_NAME;\n\n private readonly logger = new Logger(BullMqExecutionStrategy.name);\n\n constructor(private readonly runtime: BullmqRuntimeService) {}\n\n /**\n * Enqueue the work and return the BullMQ job id. The DB\n * execution row was created by the launcher BEFORE this\n * method was called — this method MUST NOT re-create it\n * (the launcher's atomic create-or-lock would race with us).\n *\n * Throws on producer failure. The launcher propagates the\n * error to its caller; the canonical `JobExecution` row\n * stays in `STARTING` and the host's recovery path is\n * responsible for transitioning it (a future task will\n * wire a \"dead letter\" cleanup).\n */\n async launch(\n job: JobDefinition,\n params: JobParameters,\n ctx: ExecutionStrategyContext,\n ): Promise<LaunchResult> {\n return this.runtime.launch(job, params, ctx);\n }\n}\n\n/**\n * Re-export the canonical `name` for tests that want to assert\n * on it without importing the runtime service directly.\n */\nexport { BULLMQ_STRATEGY_NAME };\n"],"names":["BULLMQ_STRATEGY_NAME","BullMqExecutionStrategy","name","logger","Logger","runtime","launch","job","params","ctx"],"mappings":";;;;;;;;;;;QAgFSA;eAAAA,0CAAoB;;QAjChBC;eAAAA;;;wBA/CsB;sCAa5B;;;;;;;;;;AAkCA,IAAA,AAAMA,0BAAN,MAAMA;;IACX,uDAAuD,GACvD,AAASC,OAAOF,0CAAoB,CAAC;IAEpBG,SAAS,IAAIC,cAAM,CAACH,wBAAwBC,IAAI,EAAE;IAEnE,YAAY,AAAiBG,OAA6B,CAAE;aAA/BA,UAAAA;IAAgC;IAE7D;;;;;;;;;;;GAWC,GACD,MAAMC,OACJC,GAAkB,EAClBC,MAAqB,EACrBC,GAA6B,EACN;QACvB,OAAO,IAAI,CAACJ,OAAO,CAACC,MAAM,CAACC,KAAKC,QAAQC;IAC1C;AACF"}
|