@basaltkit/queue 1.0.0 → 1.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 +1 -1
- package/README.md +14 -0
- package/dist/index.d.ts +77 -1
- package/dist/index.js +114 -8
- package/package.json +1 -1
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -184,6 +184,20 @@ queuePlugin({
|
|
|
184
184
|
|
|
185
185
|
If a job reaches a worker that hasn't registered it, `UnknownJobError` is thrown.
|
|
186
186
|
|
|
187
|
+
### CLI commands (`basalt queue:*`)
|
|
188
|
+
|
|
189
|
+
Registering `queuePlugin` also wires three CLI commands (run via the `@basaltkit/cli` runner):
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
basalt queue:work --queue=default --concurrency=5 # run a worker until Ctrl+C
|
|
193
|
+
basalt queue:stats --queue=billing # waiting/active/completed/failed/delayed
|
|
194
|
+
basalt queue:retry --queue=billing --limit=100 # re-enqueue failed jobs
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`queue:stats` and `queue:retry` need a driver that can introspect job state — the
|
|
198
|
+
**BullMQ** driver (a Redis `connection`). With the inline `sync` driver they
|
|
199
|
+
report the operation as unsupported (it keeps no job state), rather than guessing.
|
|
200
|
+
|
|
187
201
|
### Manual use without a plugin (e.g. in tests)
|
|
188
202
|
|
|
189
203
|
```ts
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,11 @@ import { DurationInput, BasaltError } from '@basaltkit/core';
|
|
|
3
3
|
import { ConnectionOptions } from 'bullmq';
|
|
4
4
|
import { EventBus, BasaltEvent } from '@basaltkit/events';
|
|
5
5
|
|
|
6
|
+
/** Driver-neutral retention: `true`/`false`, a count, or `{ ageMs, count }`. */
|
|
7
|
+
type RetentionOption = boolean | number | {
|
|
8
|
+
ageMs?: number;
|
|
9
|
+
count?: number;
|
|
10
|
+
};
|
|
6
11
|
interface AddJobOptions {
|
|
7
12
|
attempts: number;
|
|
8
13
|
backoff?: {
|
|
@@ -11,6 +16,10 @@ interface AddJobOptions {
|
|
|
11
16
|
} | undefined;
|
|
12
17
|
delayMs?: number | undefined;
|
|
13
18
|
priority?: number | undefined;
|
|
19
|
+
/** Retention for completed jobs. Undefined → the driver's default. */
|
|
20
|
+
removeOnComplete?: RetentionOption | undefined;
|
|
21
|
+
/** Retention for failed jobs. Undefined → the driver's default. */
|
|
22
|
+
removeOnFail?: RetentionOption | undefined;
|
|
14
23
|
}
|
|
15
24
|
type JobExecutor = (jobName: string, data: unknown) => Promise<void>;
|
|
16
25
|
/**
|
|
@@ -30,6 +39,14 @@ interface DriverCapabilities {
|
|
|
30
39
|
/** Waits `backoff` between retries (vs retrying immediately). */
|
|
31
40
|
backoff: boolean;
|
|
32
41
|
}
|
|
42
|
+
/** Job counts per state, for `basalt queue:stats`. */
|
|
43
|
+
interface QueueStats {
|
|
44
|
+
waiting: number;
|
|
45
|
+
active: number;
|
|
46
|
+
completed: number;
|
|
47
|
+
failed: number;
|
|
48
|
+
delayed: number;
|
|
49
|
+
}
|
|
33
50
|
/** Queue driver contract. BullMQ in production; sync in tests/dev. */
|
|
34
51
|
interface QueueDriver {
|
|
35
52
|
/** Short identifier used in diagnostics (e.g. 'bullmq', 'sync'). */
|
|
@@ -43,6 +60,19 @@ interface QueueDriver {
|
|
|
43
60
|
startWorker(queue: string, options?: {
|
|
44
61
|
concurrency?: number;
|
|
45
62
|
}): void;
|
|
63
|
+
/**
|
|
64
|
+
* Optional: job counts per state, for `basalt queue:stats`. Backends that
|
|
65
|
+
* cannot introspect (e.g. the inline sync driver) omit it — the CLI then
|
|
66
|
+
* reports the operation as unsupported rather than guessing.
|
|
67
|
+
*/
|
|
68
|
+
stats?(queue: string): Promise<QueueStats>;
|
|
69
|
+
/**
|
|
70
|
+
* Optional: re-enqueue failed jobs (`basalt queue:retry`). Returns how many
|
|
71
|
+
* were retried. `limit` caps how many are processed (default driver's choice).
|
|
72
|
+
*/
|
|
73
|
+
retryFailed?(queue: string, options?: {
|
|
74
|
+
limit?: number;
|
|
75
|
+
}): Promise<number>;
|
|
46
76
|
close(): Promise<void>;
|
|
47
77
|
}
|
|
48
78
|
|
|
@@ -68,6 +98,10 @@ declare class BullmqQueueDriver implements QueueDriver {
|
|
|
68
98
|
startWorker(queue: string, options?: {
|
|
69
99
|
concurrency?: number;
|
|
70
100
|
}): void;
|
|
101
|
+
stats(queue: string): Promise<QueueStats>;
|
|
102
|
+
retryFailed(queue: string, options?: {
|
|
103
|
+
limit?: number;
|
|
104
|
+
}): Promise<number>;
|
|
71
105
|
close(): Promise<void>;
|
|
72
106
|
private queue;
|
|
73
107
|
}
|
|
@@ -96,12 +130,26 @@ interface JobBackoff {
|
|
|
96
130
|
type: 'exponential' | 'fixed';
|
|
97
131
|
delay: DurationInput;
|
|
98
132
|
}
|
|
133
|
+
/**
|
|
134
|
+
* Redis retention for finished jobs (BullMQ driver): `true` removes it as soon as
|
|
135
|
+
* it finishes, `false` keeps it forever, a number keeps that many most-recent, and
|
|
136
|
+
* `{ age, count }` keeps by age and/or count. Defaults: completed `{ count: 1000 }`,
|
|
137
|
+
* failed `false` (keep all). The sync driver ignores it (it stores nothing).
|
|
138
|
+
*/
|
|
139
|
+
type JobRetention = boolean | number | {
|
|
140
|
+
age?: DurationInput;
|
|
141
|
+
count?: number;
|
|
142
|
+
};
|
|
99
143
|
interface JobDefinition<T = unknown> {
|
|
100
144
|
readonly name: string;
|
|
101
145
|
readonly schema?: JobSchema<T> | undefined;
|
|
102
146
|
readonly queue: string;
|
|
103
147
|
readonly attempts: number;
|
|
104
148
|
readonly backoff?: JobBackoff | undefined;
|
|
149
|
+
/** Retention for completed jobs. Overrides the queuePlugin default. */
|
|
150
|
+
readonly removeOnComplete?: JobRetention | undefined;
|
|
151
|
+
/** Retention for failed jobs. Overrides the queuePlugin default. */
|
|
152
|
+
readonly removeOnFail?: JobRetention | undefined;
|
|
105
153
|
handle(payload: T): void | Promise<void>;
|
|
106
154
|
/** Enqueues the job — available after registration in a QueueManager. */
|
|
107
155
|
dispatch(payload: T, options?: DispatchOptions): Promise<void>;
|
|
@@ -128,6 +176,8 @@ declare function defineJob<T = unknown>(config: {
|
|
|
128
176
|
queue?: string;
|
|
129
177
|
attempts?: number;
|
|
130
178
|
backoff?: JobBackoff;
|
|
179
|
+
removeOnComplete?: JobRetention;
|
|
180
|
+
removeOnFail?: JobRetention;
|
|
131
181
|
handle(payload: T): void | Promise<void>;
|
|
132
182
|
}): JobDefinition<T>;
|
|
133
183
|
|
|
@@ -151,6 +201,10 @@ interface QueueManagerOptions {
|
|
|
151
201
|
onUnsupported?: UnsupportedPolicy;
|
|
152
202
|
/** Sink for 'warn' diagnostics. Default console.warn. */
|
|
153
203
|
warn?: (message: string) => void;
|
|
204
|
+
/** Default retention for completed jobs (a job can override). Driver default: keep 1000. */
|
|
205
|
+
removeOnComplete?: JobRetention;
|
|
206
|
+
/** Default retention for failed jobs (a job can override). Driver default: keep all. */
|
|
207
|
+
removeOnFail?: JobRetention;
|
|
154
208
|
}
|
|
155
209
|
declare class QueueManager implements JobDispatcher {
|
|
156
210
|
private readonly driver;
|
|
@@ -158,6 +212,8 @@ declare class QueueManager implements JobDispatcher {
|
|
|
158
212
|
private readonly onUnsupported;
|
|
159
213
|
private readonly warn;
|
|
160
214
|
private readonly warned;
|
|
215
|
+
private readonly defaultRemoveOnComplete;
|
|
216
|
+
private readonly defaultRemoveOnFail;
|
|
161
217
|
constructor(driver: QueueDriver, options?: QueueManagerOptions);
|
|
162
218
|
/**
|
|
163
219
|
* Checks the dispatch's options against the driver's declared capabilities.
|
|
@@ -170,6 +226,15 @@ declare class QueueManager implements JobDispatcher {
|
|
|
170
226
|
work(queue?: string, options?: {
|
|
171
227
|
concurrency?: number;
|
|
172
228
|
}): void;
|
|
229
|
+
/** Job counts per state, or `undefined` if the driver can't introspect. */
|
|
230
|
+
stats(queue?: string): Promise<QueueStats | undefined>;
|
|
231
|
+
/**
|
|
232
|
+
* Re-enqueues failed jobs; returns the count, or `undefined` if the driver
|
|
233
|
+
* doesn't support retrying (e.g. the inline sync driver).
|
|
234
|
+
*/
|
|
235
|
+
retryFailed(queue?: string, options?: {
|
|
236
|
+
limit?: number;
|
|
237
|
+
}): Promise<number | undefined>;
|
|
173
238
|
close(): Promise<void>;
|
|
174
239
|
/** Executes a job received from the driver: validates, restores the context, runs the handler. */
|
|
175
240
|
private execute;
|
|
@@ -236,7 +301,18 @@ interface QueuePluginOptions {
|
|
|
236
301
|
* 'throw' in production for a hard guarantee, 'ignore' for the old behavior.
|
|
237
302
|
*/
|
|
238
303
|
onUnsupported?: UnsupportedPolicy;
|
|
304
|
+
/**
|
|
305
|
+
* Default retention for completed jobs in Redis (BullMQ). `true` removes on
|
|
306
|
+
* finish, a number keeps that many, `{ age: '7d', count: 500 }` caps both.
|
|
307
|
+
* Default: keep the last 1000. A job can override via `defineJob`.
|
|
308
|
+
*/
|
|
309
|
+
removeOnComplete?: JobRetention;
|
|
310
|
+
/**
|
|
311
|
+
* Default retention for failed jobs. Default `false` (keep all, for inspection
|
|
312
|
+
* and retries) — set e.g. `{ age: '14d' }` so failures don't grow unbounded.
|
|
313
|
+
*/
|
|
314
|
+
removeOnFail?: JobRetention;
|
|
239
315
|
}
|
|
240
316
|
declare function queuePlugin(options?: QueuePluginOptions): _basaltkit_core.BasaltPlugin<unknown>;
|
|
241
317
|
|
|
242
|
-
export { type AddJobOptions, type BullmqDriverOptions, BullmqQueueDriver, type DispatchOptions, type DriverCapabilities, type JobBackoff, type JobDefinition, type JobExecutor, JobNotRegisteredError, type JobSchema, JobValidationError, QUEUE, type QueueDriver, QueueManager, type QueueManagerOptions, type QueuePluginOptions, type QueuedListenerOptions, SyncQueueDriver, UnknownJobError, UnsupportedJobOptionError, type UnsupportedPolicy, defineJob, queuePlugin, queuedOn };
|
|
318
|
+
export { type AddJobOptions, type BullmqDriverOptions, BullmqQueueDriver, type DispatchOptions, type DriverCapabilities, type JobBackoff, type JobDefinition, type JobExecutor, JobNotRegisteredError, type JobRetention, type JobSchema, JobValidationError, QUEUE, type QueueDriver, QueueManager, type QueueManagerOptions, type QueuePluginOptions, type QueueStats, type QueuedListenerOptions, SyncQueueDriver, UnknownJobError, UnsupportedJobOptionError, type UnsupportedPolicy, defineJob, queuePlugin, queuedOn };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
-
import { createToken, definePlugin } from "@basaltkit/core";
|
|
2
|
+
import { createToken, definePlugin, ensureMetadata } from "@basaltkit/core";
|
|
3
3
|
|
|
4
4
|
// src/drivers/bullmq.ts
|
|
5
5
|
import { Queue, Worker } from "bullmq";
|
|
6
|
+
function toBullRetention(retention, fallback) {
|
|
7
|
+
if (retention === void 0) return fallback;
|
|
8
|
+
if (typeof retention === "boolean" || typeof retention === "number") return retention;
|
|
9
|
+
const out = {};
|
|
10
|
+
if (retention.ageMs !== void 0) out.age = Math.max(1, Math.round(retention.ageMs / 1e3));
|
|
11
|
+
if (retention.count !== void 0) out.count = retention.count;
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
6
14
|
var BullmqQueueDriver = class {
|
|
7
15
|
name = "bullmq";
|
|
8
16
|
capabilities = { delayed: true, priority: true, retries: true, backoff: true };
|
|
@@ -22,8 +30,8 @@ var BullmqQueueDriver = class {
|
|
|
22
30
|
...options.backoff ? { backoff: { type: options.backoff.type, delay: options.backoff.delayMs } } : {},
|
|
23
31
|
...options.delayMs !== void 0 ? { delay: options.delayMs } : {},
|
|
24
32
|
...options.priority !== void 0 ? { priority: options.priority } : {},
|
|
25
|
-
removeOnComplete: { count: 1e3 },
|
|
26
|
-
removeOnFail: false
|
|
33
|
+
removeOnComplete: toBullRetention(options.removeOnComplete, { count: 1e3 }),
|
|
34
|
+
removeOnFail: toBullRetention(options.removeOnFail, false)
|
|
27
35
|
});
|
|
28
36
|
}
|
|
29
37
|
startWorker(queue, options = {}) {
|
|
@@ -34,6 +42,26 @@ var BullmqQueueDriver = class {
|
|
|
34
42
|
})
|
|
35
43
|
);
|
|
36
44
|
}
|
|
45
|
+
async stats(queue) {
|
|
46
|
+
const c = await this.queue(queue).getJobCounts("waiting", "active", "completed", "failed", "delayed");
|
|
47
|
+
return {
|
|
48
|
+
waiting: c["waiting"] ?? 0,
|
|
49
|
+
active: c["active"] ?? 0,
|
|
50
|
+
completed: c["completed"] ?? 0,
|
|
51
|
+
failed: c["failed"] ?? 0,
|
|
52
|
+
delayed: c["delayed"] ?? 0
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
async retryFailed(queue, options = {}) {
|
|
56
|
+
const limit = options.limit ?? 1e3;
|
|
57
|
+
const failed = await this.queue(queue).getFailed(0, limit - 1);
|
|
58
|
+
let retried = 0;
|
|
59
|
+
for (const job of failed) {
|
|
60
|
+
await job.retry();
|
|
61
|
+
retried++;
|
|
62
|
+
}
|
|
63
|
+
return retried;
|
|
64
|
+
}
|
|
37
65
|
async close() {
|
|
38
66
|
await Promise.all(this.workers.map((worker) => worker.close()));
|
|
39
67
|
await Promise.all([...this.queues.values()].map((queue) => queue.close()));
|
|
@@ -128,6 +156,8 @@ function defineJob(config) {
|
|
|
128
156
|
queue: config.queue ?? "default",
|
|
129
157
|
attempts: config.attempts ?? 1,
|
|
130
158
|
backoff: config.backoff,
|
|
159
|
+
removeOnComplete: config.removeOnComplete,
|
|
160
|
+
removeOnFail: config.removeOnFail,
|
|
131
161
|
handle: config.handle,
|
|
132
162
|
async dispatch(payload, options) {
|
|
133
163
|
if (!dispatcher) throw new JobNotRegisteredError(config.name);
|
|
@@ -150,6 +180,14 @@ function validatePayload(job, payload) {
|
|
|
150
180
|
}
|
|
151
181
|
|
|
152
182
|
// src/manager.ts
|
|
183
|
+
function resolveRetention(retention) {
|
|
184
|
+
if (retention === void 0) return void 0;
|
|
185
|
+
if (typeof retention === "boolean" || typeof retention === "number") return retention;
|
|
186
|
+
const out = {};
|
|
187
|
+
if (retention.age !== void 0) out.ageMs = parseDuration(retention.age);
|
|
188
|
+
if (retention.count !== void 0) out.count = retention.count;
|
|
189
|
+
return out;
|
|
190
|
+
}
|
|
153
191
|
var UnknownJobError = class extends BasaltError2 {
|
|
154
192
|
constructor(job) {
|
|
155
193
|
super(
|
|
@@ -187,6 +225,8 @@ var QueueManager = class {
|
|
|
187
225
|
this.driver = driver;
|
|
188
226
|
this.onUnsupported = options.onUnsupported ?? "warn";
|
|
189
227
|
this.warn = options.warn ?? ((message) => console.warn(message));
|
|
228
|
+
this.defaultRemoveOnComplete = options.removeOnComplete;
|
|
229
|
+
this.defaultRemoveOnFail = options.removeOnFail;
|
|
190
230
|
driver.setExecutor((jobName, data) => this.execute(jobName, data));
|
|
191
231
|
}
|
|
192
232
|
driver;
|
|
@@ -194,6 +234,8 @@ var QueueManager = class {
|
|
|
194
234
|
onUnsupported;
|
|
195
235
|
warn;
|
|
196
236
|
warned = /* @__PURE__ */ new Set();
|
|
237
|
+
defaultRemoveOnComplete;
|
|
238
|
+
defaultRemoveOnFail;
|
|
197
239
|
/**
|
|
198
240
|
* Checks the dispatch's options against the driver's declared capabilities.
|
|
199
241
|
* A driver that omits `capabilities` is assumed fully capable (back-compat).
|
|
@@ -228,7 +270,10 @@ var QueueManager = class {
|
|
|
228
270
|
attempts: job.attempts,
|
|
229
271
|
backoff: job.backoff ? { type: job.backoff.type, delayMs: parseDuration(job.backoff.delay) } : void 0,
|
|
230
272
|
delayMs: options.delay === void 0 ? void 0 : parseDuration(options.delay),
|
|
231
|
-
priority: options.priority
|
|
273
|
+
priority: options.priority,
|
|
274
|
+
// Per-job overrides the queuePlugin default; undefined leaves the driver default.
|
|
275
|
+
removeOnComplete: resolveRetention(job.removeOnComplete ?? this.defaultRemoveOnComplete),
|
|
276
|
+
removeOnFail: resolveRetention(job.removeOnFail ?? this.defaultRemoveOnFail)
|
|
232
277
|
};
|
|
233
278
|
this.assertSupported(job.name, addOptions);
|
|
234
279
|
await this.driver.add(job.queue, job.name, envelope, addOptions);
|
|
@@ -237,6 +282,17 @@ var QueueManager = class {
|
|
|
237
282
|
work(queue = "default", options = {}) {
|
|
238
283
|
this.driver.startWorker(queue, options);
|
|
239
284
|
}
|
|
285
|
+
/** Job counts per state, or `undefined` if the driver can't introspect. */
|
|
286
|
+
async stats(queue = "default") {
|
|
287
|
+
return this.driver.stats?.(queue);
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* Re-enqueues failed jobs; returns the count, or `undefined` if the driver
|
|
291
|
+
* doesn't support retrying (e.g. the inline sync driver).
|
|
292
|
+
*/
|
|
293
|
+
async retryFailed(queue = "default", options = {}) {
|
|
294
|
+
return this.driver.retryFailed?.(queue, options);
|
|
295
|
+
}
|
|
240
296
|
async close() {
|
|
241
297
|
await this.driver.close();
|
|
242
298
|
}
|
|
@@ -285,12 +341,14 @@ function queuePlugin(options = {}) {
|
|
|
285
341
|
return definePlugin({
|
|
286
342
|
name: "basalt:queue",
|
|
287
343
|
register({ container }) {
|
|
344
|
+
registerQueueCommands(container);
|
|
288
345
|
container.singleton(QUEUE, () => {
|
|
289
346
|
const driver = options.driver ?? (options.connection ? new BullmqQueueDriver({ connection: options.connection }) : new SyncQueueDriver());
|
|
290
|
-
const manager = new QueueManager(
|
|
291
|
-
|
|
292
|
-
options.
|
|
293
|
-
|
|
347
|
+
const manager = new QueueManager(driver, {
|
|
348
|
+
...options.onUnsupported !== void 0 ? { onUnsupported: options.onUnsupported } : {},
|
|
349
|
+
...options.removeOnComplete !== void 0 ? { removeOnComplete: options.removeOnComplete } : {},
|
|
350
|
+
...options.removeOnFail !== void 0 ? { removeOnFail: options.removeOnFail } : {}
|
|
351
|
+
});
|
|
294
352
|
for (const job of options.jobs ?? []) manager.register(job);
|
|
295
353
|
return manager;
|
|
296
354
|
});
|
|
@@ -309,6 +367,54 @@ function queuePlugin(options = {}) {
|
|
|
309
367
|
}
|
|
310
368
|
});
|
|
311
369
|
}
|
|
370
|
+
function registerQueueCommands(container) {
|
|
371
|
+
const manager = () => container.get(QUEUE);
|
|
372
|
+
const unsupported = "Not supported by the active queue driver \u2014 the inline sync driver keeps no job state. Use the BullMQ driver (a Redis `connection`).";
|
|
373
|
+
ensureMetadata(container).add("commands", {
|
|
374
|
+
name: "queue:work",
|
|
375
|
+
description: "Run a worker that processes jobs for a queue (Ctrl+C to stop)",
|
|
376
|
+
async handle({ io, flags }) {
|
|
377
|
+
const queue = typeof flags["queue"] === "string" ? flags["queue"] : "default";
|
|
378
|
+
const concurrency = typeof flags["concurrency"] === "string" ? Number(flags["concurrency"]) : void 0;
|
|
379
|
+
manager().work(queue, concurrency !== void 0 ? { concurrency } : {});
|
|
380
|
+
io.log(`Worker started on queue "${queue}"${concurrency ? ` (concurrency ${concurrency})` : ""}. Ctrl+C to stop.`);
|
|
381
|
+
await new Promise((resolve) => process.once("SIGINT", resolve));
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
ensureMetadata(container).add("commands", {
|
|
385
|
+
name: "queue:stats",
|
|
386
|
+
description: "Show job counts (waiting/active/completed/failed/delayed) for a queue",
|
|
387
|
+
async handle({
|
|
388
|
+
io,
|
|
389
|
+
flags
|
|
390
|
+
}) {
|
|
391
|
+
const queue = typeof flags["queue"] === "string" ? flags["queue"] : "default";
|
|
392
|
+
const stats = await manager().stats(queue);
|
|
393
|
+
if (!stats) {
|
|
394
|
+
io.log(unsupported);
|
|
395
|
+
return;
|
|
396
|
+
}
|
|
397
|
+
io.table([{ queue, ...stats }]);
|
|
398
|
+
}
|
|
399
|
+
});
|
|
400
|
+
ensureMetadata(container).add("commands", {
|
|
401
|
+
name: "queue:retry",
|
|
402
|
+
description: "Re-enqueue failed jobs on a queue",
|
|
403
|
+
async handle({
|
|
404
|
+
io,
|
|
405
|
+
flags
|
|
406
|
+
}) {
|
|
407
|
+
const queue = typeof flags["queue"] === "string" ? flags["queue"] : "default";
|
|
408
|
+
const limit = typeof flags["limit"] === "string" ? Number(flags["limit"]) : void 0;
|
|
409
|
+
const retried = await manager().retryFailed(queue, limit !== void 0 ? { limit } : {});
|
|
410
|
+
if (retried === void 0) {
|
|
411
|
+
io.log(unsupported);
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
io.log(`Re-enqueued ${retried} failed job(s) on "${queue}".`);
|
|
415
|
+
}
|
|
416
|
+
});
|
|
417
|
+
}
|
|
312
418
|
export {
|
|
313
419
|
BullmqQueueDriver,
|
|
314
420
|
JobNotRegisteredError,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@basaltkit/queue",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Basalt queues on top of BullMQ: declarative jobs with Zod payloads, context propagation (tenant/requestId) to workers and a sync driver for tests.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|