@happyvertical/jobs 0.80.0 → 0.80.2

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.
@@ -1,349 +1,346 @@
1
+ import { n as priorityToNumber, t as BaseJobStore } from "../chunks/base-store-DIasEzL0.js";
1
2
  import { createId } from "@happyvertical/utils";
2
- import { B as BaseJobStore, p as priorityToNumber } from "../chunks/base-store-DlNksWvQ.js";
3
- class BullJobStore extends BaseJobStore {
4
- config;
5
- queues = /* @__PURE__ */ new Map();
6
- // biome-ignore lint/style/useNamingConvention: bull module reference
7
- bullModule = null;
8
- constructor(config = {}) {
9
- super();
10
- this.config = {
11
- prefix: "smrt_jobs",
12
- defaultJobOptions: {
13
- removeOnComplete: 100,
14
- removeOnFail: 500
15
- },
16
- ...config
17
- };
18
- }
19
- /**
20
- * Initialize the store - dynamically imports Bull
21
- */
22
- async initialize() {
23
- if (this.initialized) return;
24
- try {
25
- this.bullModule = (await import("bull")).default;
26
- } catch {
27
- throw new Error(
28
- "Bull is required for BullJobStore. Install it with: npm install bull"
29
- );
30
- }
31
- this.initialized = true;
32
- }
33
- /**
34
- * Get or create a Bull queue for a queue name
35
- */
36
- getQueue(queueName) {
37
- if (!this.bullModule) {
38
- throw new Error("BullJobStore not initialized");
39
- }
40
- if (!this.queues.has(queueName)) {
41
- const queue = new this.bullModule(queueName, {
42
- redis: this.config.redis,
43
- prefix: this.config.prefix,
44
- defaultJobOptions: this.config.defaultJobOptions
45
- });
46
- queue.on("completed", (bullJob) => {
47
- this.handleJobCompleted(bullJob, queueName);
48
- });
49
- queue.on("failed", (bullJob, error) => {
50
- this.handleJobFailed(bullJob, error, queueName);
51
- });
52
- this.queues.set(queueName, queue);
53
- }
54
- const result = this.queues.get(queueName);
55
- if (!result) {
56
- throw new Error(`Queue ${queueName} was not found after initialization`);
57
- }
58
- return result;
59
- }
60
- /**
61
- * Handle Bull job completed event
62
- */
63
- async handleJobCompleted(bullJob, queueName) {
64
- const job = this.bullJobToJob(bullJob, queueName);
65
- await this.emitEvent("job.completed", job);
66
- }
67
- /**
68
- * Handle Bull job failed event
69
- */
70
- async handleJobFailed(bullJob, error, queueName) {
71
- const job = this.bullJobToJob(bullJob, queueName);
72
- job.lastError = error.message;
73
- await this.emitEvent("job.failed", job, { error: error.message });
74
- }
75
- /**
76
- * Convert Bull job to our Job format
77
- */
78
- bullJobToJob(bullJob, queueName) {
79
- const data = bullJob.data;
80
- const status = this.mapBullStatus(bullJob);
81
- return {
82
- id: String(bullJob.id),
83
- queue: queueName,
84
- payload: data.payload,
85
- status,
86
- priority: bullJob.opts.priority ?? 50,
87
- attempts: bullJob.attemptsMade,
88
- maxAttempts: data.meta.maxAttempts,
89
- runAt: bullJob.opts.delay ? new Date(bullJob.timestamp + bullJob.opts.delay) : new Date(bullJob.timestamp),
90
- startedAt: bullJob.processedOn ? new Date(bullJob.processedOn) : null,
91
- completedAt: bullJob.finishedOn ? new Date(bullJob.finishedOn) : null,
92
- timeout: data.meta.timeout,
93
- timeoutBehavior: data.meta.timeoutBehavior,
94
- lastError: bullJob.failedReason ?? null,
95
- resultPointer: bullJob.returnvalue?.resultPointer ?? null,
96
- retryStrategy: data.meta.retryStrategy,
97
- workerId: data.meta.workerId,
98
- workerHeartbeat: null,
99
- createdAt: new Date(bullJob.timestamp),
100
- updatedAt: /* @__PURE__ */ new Date()
101
- };
102
- }
103
- /**
104
- * Map Bull job state to our JobStatus
105
- */
106
- mapBullStatus(bullJob) {
107
- if (bullJob.finishedOn) {
108
- return bullJob.failedReason ? "failed" : "completed";
109
- }
110
- if (bullJob.processedOn) {
111
- return "running";
112
- }
113
- return "pending";
114
- }
115
- /**
116
- * Enqueue a new job
117
- */
118
- async enqueue(options) {
119
- if (!this.initialized) {
120
- throw new Error("BullJobStore not initialized");
121
- }
122
- const queueName = options.queue ?? "default";
123
- const queue = this.getQueue(queueName);
124
- const jobData = {
125
- payload: options.payload,
126
- meta: {
127
- maxAttempts: options.maxAttempts ?? 3,
128
- timeout: options.timeout ?? 3e5,
129
- timeoutBehavior: options.timeoutBehavior ?? "fail",
130
- retryStrategy: options.retryStrategy && "toConfig" in options.retryStrategy ? options.retryStrategy.toConfig() : options.retryStrategy ?? {
131
- type: "exponential",
132
- config: { initialDelay: 1e3, multiplier: 2 }
133
- },
134
- workerId: null
135
- }
136
- };
137
- const bullJobOptions = {
138
- priority: priorityToNumber(options.priority),
139
- attempts: options.maxAttempts ?? 3,
140
- timeout: options.timeout ?? 3e5,
141
- delay: options.runAt ? Math.max(0, options.runAt.getTime() - Date.now()) : void 0,
142
- jobId: createId()
143
- };
144
- const bullJob = await queue.add(jobData, bullJobOptions);
145
- const job = this.bullJobToJob(bullJob, queueName);
146
- await this.emitEvent("job.created", job);
147
- return job;
148
- }
149
- /**
150
- * Dequeue jobs ready for processing
151
- */
152
- async dequeue(queues, limit, workerId) {
153
- if (!this.initialized) {
154
- throw new Error("BullJobStore not initialized");
155
- }
156
- const jobs = [];
157
- for (const queueName of queues) {
158
- if (jobs.length >= limit) break;
159
- const queue = this.getQueue(queueName);
160
- const waiting = await queue.getWaiting(0, limit - jobs.length - 1);
161
- for (const bullJob of waiting) {
162
- bullJob.data.meta.workerId = workerId;
163
- await bullJob.update(bullJob.data);
164
- jobs.push(this.bullJobToJob(bullJob, queueName));
165
- }
166
- }
167
- return jobs;
168
- }
169
- /**
170
- * Update a job
171
- */
172
- async update(id, updates) {
173
- if (!this.initialized) {
174
- throw new Error("BullJobStore not initialized");
175
- }
176
- for (const [queueName, queue] of this.queues) {
177
- const bullJob = await queue.getJob(id);
178
- if (bullJob) {
179
- if (updates.payload) {
180
- bullJob.data.payload = updates.payload;
181
- }
182
- if (updates.maxAttempts !== void 0) {
183
- bullJob.data.meta.maxAttempts = updates.maxAttempts;
184
- }
185
- if (updates.timeout !== void 0) {
186
- bullJob.data.meta.timeout = updates.timeout;
187
- }
188
- if (updates.workerId !== void 0) {
189
- bullJob.data.meta.workerId = updates.workerId;
190
- }
191
- await bullJob.update(bullJob.data);
192
- return this.bullJobToJob(bullJob, queueName);
193
- }
194
- }
195
- throw new Error(`Job ${id} not found`);
196
- }
197
- /**
198
- * Get a job by ID
199
- */
200
- async get(id) {
201
- if (!this.initialized) {
202
- throw new Error("BullJobStore not initialized");
203
- }
204
- for (const [queueName, queue] of this.queues) {
205
- const bullJob = await queue.getJob(id);
206
- if (bullJob) {
207
- return this.bullJobToJob(bullJob, queueName);
208
- }
209
- }
210
- return null;
211
- }
212
- /**
213
- * List jobs with filtering
214
- */
215
- async list(filter) {
216
- if (!this.initialized) {
217
- throw new Error("BullJobStore not initialized");
218
- }
219
- const jobs = [];
220
- const limit = filter.limit ?? 100;
221
- const offset = filter.offset ?? 0;
222
- const targetQueues = filter.queue ? [this.getQueue(filter.queue)] : Array.from(this.queues.values());
223
- for (const queue of targetQueues) {
224
- const queueName = Array.from(this.queues.entries()).find(([, q]) => q === queue)?.[0] ?? "unknown";
225
- const statuses = filter.status ? Array.isArray(filter.status) ? filter.status : [filter.status] : ["pending", "running", "completed", "failed"];
226
- for (const status of statuses) {
227
- let bullJobs = [];
228
- switch (status) {
229
- case "pending":
230
- bullJobs = await queue.getWaiting(offset, offset + limit - 1);
231
- break;
232
- case "running":
233
- bullJobs = await queue.getActive(offset, offset + limit - 1);
234
- break;
235
- case "completed":
236
- bullJobs = await queue.getCompleted(offset, offset + limit - 1);
237
- break;
238
- case "failed":
239
- bullJobs = await queue.getFailed(offset, offset + limit - 1);
240
- break;
241
- }
242
- for (const bullJob of bullJobs) {
243
- const job = this.bullJobToJob(bullJob, queueName);
244
- if (filter.objectType && job.payload.objectType !== filter.objectType)
245
- continue;
246
- if (filter.method && job.payload.method !== filter.method) continue;
247
- if (filter.createdAfter && job.createdAt < filter.createdAfter)
248
- continue;
249
- if (filter.createdBefore && job.createdAt > filter.createdBefore)
250
- continue;
251
- jobs.push(job);
252
- if (jobs.length >= limit) break;
253
- }
254
- if (jobs.length >= limit) break;
255
- }
256
- }
257
- return jobs.slice(0, limit);
258
- }
259
- /**
260
- * Cancel a job
261
- */
262
- async cancel(id) {
263
- if (!this.initialized) {
264
- throw new Error("BullJobStore not initialized");
265
- }
266
- for (const [queueName, queue] of this.queues) {
267
- const bullJob = await queue.getJob(id);
268
- if (bullJob) {
269
- await bullJob.remove();
270
- const job = this.bullJobToJob(bullJob, queueName);
271
- job.status = "cancelled";
272
- await this.emitEvent("job.cancelled", job);
273
- return;
274
- }
275
- }
276
- throw new Error(`Job ${id} not found`);
277
- }
278
- /**
279
- * Clean up old jobs
280
- */
281
- async cleanup(options) {
282
- if (!this.initialized) {
283
- throw new Error("BullJobStore not initialized");
284
- }
285
- let cleaned = 0;
286
- for (const queue of this.queues.values()) {
287
- if (options.completedBefore) {
288
- const grace = Date.now() - options.completedBefore.getTime();
289
- const result = await queue.clean(grace, "completed", options.limit);
290
- cleaned += result.length;
291
- }
292
- if (options.failedBefore) {
293
- const grace = Date.now() - options.failedBefore.getTime();
294
- const result = await queue.clean(grace, "failed", options.limit);
295
- cleaned += result.length;
296
- }
297
- }
298
- return cleaned;
299
- }
300
- /**
301
- * Update worker heartbeat (no-op for Bull - handled internally)
302
- */
303
- async heartbeat(_jobId, _workerId) {
304
- }
305
- /**
306
- * Get queue statistics
307
- */
308
- async stats(queue) {
309
- if (!this.initialized) {
310
- throw new Error("BullJobStore not initialized");
311
- }
312
- const totals = {
313
- pending: 0,
314
- running: 0,
315
- completed: 0,
316
- failed: 0,
317
- cancelled: 0,
318
- avgDuration: null
319
- };
320
- const targetQueues = queue ? [this.getQueue(queue)] : Array.from(this.queues.values());
321
- for (const q of targetQueues) {
322
- const counts = await q.getJobCounts();
323
- totals.pending += counts.waiting + counts.delayed;
324
- totals.running += counts.active;
325
- totals.completed += counts.completed;
326
- totals.failed += counts.failed;
327
- }
328
- return totals;
329
- }
330
- /**
331
- * Close all queues
332
- */
333
- async close() {
334
- for (const queue of this.queues.values()) {
335
- await queue.close();
336
- }
337
- this.queues.clear();
338
- this.initialized = false;
339
- }
340
- }
3
+ //#region src/adapters/bull.ts
4
+ /**
5
+ * Bull (Redis) Job Store Adapter
6
+ *
7
+ * Uses Bull queue library for Redis-based job storage with real-time updates.
8
+ * Bull provides robust job processing with features like priority queues,
9
+ * delayed jobs, retries, and job events.
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * import { BullJobStore } from '@happyvertical/jobs/adapters/bull';
14
+ *
15
+ * const store = new BullJobStore({
16
+ * redis: {
17
+ * host: 'localhost',
18
+ * port: 6379,
19
+ * },
20
+ * defaultJobOptions: {
21
+ * removeOnComplete: 100,
22
+ * removeOnFail: 500,
23
+ * },
24
+ * });
25
+ *
26
+ * await store.initialize();
27
+ * ```
28
+ *
29
+ * Note: This adapter requires the `bull` package as a peer dependency.
30
+ * Install it with: npm install bull @types/bull
31
+ */
32
+ /**
33
+ * Bull-based job store implementation
34
+ */
35
+ var BullJobStore = class extends BaseJobStore {
36
+ config;
37
+ queues = /* @__PURE__ */ new Map();
38
+ bullModule = null;
39
+ constructor(config = {}) {
40
+ super();
41
+ this.config = {
42
+ prefix: "smrt_jobs",
43
+ defaultJobOptions: {
44
+ removeOnComplete: 100,
45
+ removeOnFail: 500
46
+ },
47
+ ...config
48
+ };
49
+ }
50
+ /**
51
+ * Initialize the store - dynamically imports Bull
52
+ */
53
+ async initialize() {
54
+ if (this.initialized) return;
55
+ try {
56
+ this.bullModule = (await import("bull")).default;
57
+ } catch {
58
+ throw new Error("Bull is required for BullJobStore. Install it with: npm install bull");
59
+ }
60
+ this.initialized = true;
61
+ }
62
+ /**
63
+ * Get or create a Bull queue for a queue name
64
+ */
65
+ getQueue(queueName) {
66
+ if (!this.bullModule) throw new Error("BullJobStore not initialized");
67
+ if (!this.queues.has(queueName)) {
68
+ const queue = new this.bullModule(queueName, {
69
+ redis: this.config.redis,
70
+ prefix: this.config.prefix,
71
+ defaultJobOptions: this.config.defaultJobOptions
72
+ });
73
+ queue.on("completed", (bullJob) => {
74
+ this.handleJobCompleted(bullJob, queueName);
75
+ });
76
+ queue.on("failed", (bullJob, error) => {
77
+ this.handleJobFailed(bullJob, error, queueName);
78
+ });
79
+ this.queues.set(queueName, queue);
80
+ }
81
+ const result = this.queues.get(queueName);
82
+ if (!result) throw new Error(`Queue ${queueName} was not found after initialization`);
83
+ return result;
84
+ }
85
+ /**
86
+ * Handle Bull job completed event
87
+ */
88
+ async handleJobCompleted(bullJob, queueName) {
89
+ const job = this.bullJobToJob(bullJob, queueName);
90
+ await this.emitEvent("job.completed", job);
91
+ }
92
+ /**
93
+ * Handle Bull job failed event
94
+ */
95
+ async handleJobFailed(bullJob, error, queueName) {
96
+ const job = this.bullJobToJob(bullJob, queueName);
97
+ job.lastError = error.message;
98
+ await this.emitEvent("job.failed", job, { error: error.message });
99
+ }
100
+ /**
101
+ * Convert Bull job to our Job format
102
+ */
103
+ bullJobToJob(bullJob, queueName) {
104
+ const data = bullJob.data;
105
+ const status = this.mapBullStatus(bullJob);
106
+ return {
107
+ id: String(bullJob.id),
108
+ queue: queueName,
109
+ payload: data.payload,
110
+ status,
111
+ priority: bullJob.opts.priority ?? 50,
112
+ attempts: bullJob.attemptsMade,
113
+ maxAttempts: data.meta.maxAttempts,
114
+ runAt: bullJob.opts.delay ? new Date(bullJob.timestamp + bullJob.opts.delay) : new Date(bullJob.timestamp),
115
+ startedAt: bullJob.processedOn ? new Date(bullJob.processedOn) : null,
116
+ completedAt: bullJob.finishedOn ? new Date(bullJob.finishedOn) : null,
117
+ timeout: data.meta.timeout,
118
+ timeoutBehavior: data.meta.timeoutBehavior,
119
+ lastError: bullJob.failedReason ?? null,
120
+ resultPointer: bullJob.returnvalue?.resultPointer ?? null,
121
+ retryStrategy: data.meta.retryStrategy,
122
+ workerId: data.meta.workerId,
123
+ workerHeartbeat: null,
124
+ createdAt: new Date(bullJob.timestamp),
125
+ updatedAt: /* @__PURE__ */ new Date()
126
+ };
127
+ }
128
+ /**
129
+ * Map Bull job state to our JobStatus
130
+ */
131
+ mapBullStatus(bullJob) {
132
+ if (bullJob.finishedOn) return bullJob.failedReason ? "failed" : "completed";
133
+ if (bullJob.processedOn) return "running";
134
+ return "pending";
135
+ }
136
+ /**
137
+ * Enqueue a new job
138
+ */
139
+ async enqueue(options) {
140
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
141
+ const queueName = options.queue ?? "default";
142
+ const queue = this.getQueue(queueName);
143
+ const jobData = {
144
+ payload: options.payload,
145
+ meta: {
146
+ maxAttempts: options.maxAttempts ?? 3,
147
+ timeout: options.timeout ?? 3e5,
148
+ timeoutBehavior: options.timeoutBehavior ?? "fail",
149
+ retryStrategy: options.retryStrategy && "toConfig" in options.retryStrategy ? options.retryStrategy.toConfig() : options.retryStrategy ?? {
150
+ type: "exponential",
151
+ config: {
152
+ initialDelay: 1e3,
153
+ multiplier: 2
154
+ }
155
+ },
156
+ workerId: null
157
+ }
158
+ };
159
+ const bullJobOptions = {
160
+ priority: priorityToNumber(options.priority),
161
+ attempts: options.maxAttempts ?? 3,
162
+ timeout: options.timeout ?? 3e5,
163
+ delay: options.runAt ? Math.max(0, options.runAt.getTime() - Date.now()) : void 0,
164
+ jobId: createId()
165
+ };
166
+ const bullJob = await queue.add(jobData, bullJobOptions);
167
+ const job = this.bullJobToJob(bullJob, queueName);
168
+ await this.emitEvent("job.created", job);
169
+ return job;
170
+ }
171
+ /**
172
+ * Dequeue jobs ready for processing
173
+ */
174
+ async dequeue(queues, limit, workerId) {
175
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
176
+ const jobs = [];
177
+ for (const queueName of queues) {
178
+ if (jobs.length >= limit) break;
179
+ const waiting = await this.getQueue(queueName).getWaiting(0, limit - jobs.length - 1);
180
+ for (const bullJob of waiting) {
181
+ bullJob.data.meta.workerId = workerId;
182
+ await bullJob.update(bullJob.data);
183
+ jobs.push(this.bullJobToJob(bullJob, queueName));
184
+ }
185
+ }
186
+ return jobs;
187
+ }
188
+ /**
189
+ * Update a job
190
+ */
191
+ async update(id, updates) {
192
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
193
+ for (const [queueName, queue] of this.queues) {
194
+ const bullJob = await queue.getJob(id);
195
+ if (bullJob) {
196
+ if (updates.payload) bullJob.data.payload = updates.payload;
197
+ if (updates.maxAttempts !== void 0) bullJob.data.meta.maxAttempts = updates.maxAttempts;
198
+ if (updates.timeout !== void 0) bullJob.data.meta.timeout = updates.timeout;
199
+ if (updates.workerId !== void 0) bullJob.data.meta.workerId = updates.workerId;
200
+ await bullJob.update(bullJob.data);
201
+ return this.bullJobToJob(bullJob, queueName);
202
+ }
203
+ }
204
+ throw new Error(`Job ${id} not found`);
205
+ }
206
+ /**
207
+ * Get a job by ID
208
+ */
209
+ async get(id) {
210
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
211
+ for (const [queueName, queue] of this.queues) {
212
+ const bullJob = await queue.getJob(id);
213
+ if (bullJob) return this.bullJobToJob(bullJob, queueName);
214
+ }
215
+ return null;
216
+ }
217
+ /**
218
+ * List jobs with filtering
219
+ */
220
+ async list(filter) {
221
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
222
+ const jobs = [];
223
+ const limit = filter.limit ?? 100;
224
+ const offset = filter.offset ?? 0;
225
+ const targetQueues = filter.queue ? [this.getQueue(filter.queue)] : Array.from(this.queues.values());
226
+ for (const queue of targetQueues) {
227
+ const queueName = Array.from(this.queues.entries()).find(([, q]) => q === queue)?.[0] ?? "unknown";
228
+ const statuses = filter.status ? Array.isArray(filter.status) ? filter.status : [filter.status] : [
229
+ "pending",
230
+ "running",
231
+ "completed",
232
+ "failed"
233
+ ];
234
+ for (const status of statuses) {
235
+ let bullJobs = [];
236
+ switch (status) {
237
+ case "pending":
238
+ bullJobs = await queue.getWaiting(offset, offset + limit - 1);
239
+ break;
240
+ case "running":
241
+ bullJobs = await queue.getActive(offset, offset + limit - 1);
242
+ break;
243
+ case "completed":
244
+ bullJobs = await queue.getCompleted(offset, offset + limit - 1);
245
+ break;
246
+ case "failed":
247
+ bullJobs = await queue.getFailed(offset, offset + limit - 1);
248
+ break;
249
+ }
250
+ for (const bullJob of bullJobs) {
251
+ const job = this.bullJobToJob(bullJob, queueName);
252
+ if (filter.objectType && job.payload.objectType !== filter.objectType) continue;
253
+ if (filter.method && job.payload.method !== filter.method) continue;
254
+ if (filter.createdAfter && job.createdAt < filter.createdAfter) continue;
255
+ if (filter.createdBefore && job.createdAt > filter.createdBefore) continue;
256
+ jobs.push(job);
257
+ if (jobs.length >= limit) break;
258
+ }
259
+ if (jobs.length >= limit) break;
260
+ }
261
+ }
262
+ return jobs.slice(0, limit);
263
+ }
264
+ /**
265
+ * Cancel a job
266
+ */
267
+ async cancel(id) {
268
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
269
+ for (const [queueName, queue] of this.queues) {
270
+ const bullJob = await queue.getJob(id);
271
+ if (bullJob) {
272
+ await bullJob.remove();
273
+ const job = this.bullJobToJob(bullJob, queueName);
274
+ job.status = "cancelled";
275
+ await this.emitEvent("job.cancelled", job);
276
+ return;
277
+ }
278
+ }
279
+ throw new Error(`Job ${id} not found`);
280
+ }
281
+ /**
282
+ * Clean up old jobs
283
+ */
284
+ async cleanup(options) {
285
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
286
+ let cleaned = 0;
287
+ for (const queue of this.queues.values()) {
288
+ if (options.completedBefore) {
289
+ const grace = Date.now() - options.completedBefore.getTime();
290
+ const result = await queue.clean(grace, "completed", options.limit);
291
+ cleaned += result.length;
292
+ }
293
+ if (options.failedBefore) {
294
+ const grace = Date.now() - options.failedBefore.getTime();
295
+ const result = await queue.clean(grace, "failed", options.limit);
296
+ cleaned += result.length;
297
+ }
298
+ }
299
+ return cleaned;
300
+ }
301
+ /**
302
+ * Update worker heartbeat (no-op for Bull - handled internally)
303
+ */
304
+ async heartbeat(_jobId, _workerId) {}
305
+ /**
306
+ * Get queue statistics
307
+ */
308
+ async stats(queue) {
309
+ if (!this.initialized) throw new Error("BullJobStore not initialized");
310
+ const totals = {
311
+ pending: 0,
312
+ running: 0,
313
+ completed: 0,
314
+ failed: 0,
315
+ cancelled: 0,
316
+ avgDuration: null
317
+ };
318
+ const targetQueues = queue ? [this.getQueue(queue)] : Array.from(this.queues.values());
319
+ for (const q of targetQueues) {
320
+ const counts = await q.getJobCounts();
321
+ totals.pending += counts.waiting + counts.delayed;
322
+ totals.running += counts.active;
323
+ totals.completed += counts.completed;
324
+ totals.failed += counts.failed;
325
+ }
326
+ return totals;
327
+ }
328
+ /**
329
+ * Close all queues
330
+ */
331
+ async close() {
332
+ for (const queue of this.queues.values()) await queue.close();
333
+ this.queues.clear();
334
+ this.initialized = false;
335
+ }
336
+ };
337
+ /**
338
+ * Create a Bull job store instance
339
+ */
341
340
  function createBullJobStore(config) {
342
- return new BullJobStore(config);
341
+ return new BullJobStore(config);
343
342
  }
344
- export {
345
- BullJobStore,
346
- createBullJobStore,
347
- BullJobStore as default
348
- };
349
- //# sourceMappingURL=bull.js.map
343
+ //#endregion
344
+ export { BullJobStore, BullJobStore as default, createBullJobStore };
345
+
346
+ //# sourceMappingURL=bull.js.map