@happyvertical/jobs 0.80.0 → 0.80.1
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/dist/adapters/bull.js +343 -346
- package/dist/adapters/bull.js.map +1 -1
- package/dist/adapters/bullmq.js +351 -388
- package/dist/adapters/bullmq.js.map +1 -1
- package/dist/adapters/cloud-tasks.js +307 -333
- package/dist/adapters/cloud-tasks.js.map +1 -1
- package/dist/adapters/postgres.js +288 -328
- package/dist/adapters/postgres.js.map +1 -1
- package/dist/adapters/sqlite.js +236 -258
- package/dist/adapters/sqlite.js.map +1 -1
- package/dist/adapters/sqs.js +363 -408
- package/dist/adapters/sqs.js.map +1 -1
- package/dist/chunks/base-store-DIasEzL0.js +386 -0
- package/dist/chunks/base-store-DIasEzL0.js.map +1 -0
- package/dist/cli/claude-context.js +17 -17
- package/dist/cli/claude-context.js.map +1 -1
- package/dist/index.js +219 -242
- package/dist/index.js.map +1 -1
- package/package.json +7 -7
- package/dist/chunks/base-store-DlNksWvQ.js +0 -324
- package/dist/chunks/base-store-DlNksWvQ.js.map +0 -1
package/dist/adapters/bull.js
CHANGED
|
@@ -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
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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
|
-
|
|
341
|
+
return new BullJobStore(config);
|
|
343
342
|
}
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
};
|
|
349
|
-
//# sourceMappingURL=bull.js.map
|
|
343
|
+
//#endregion
|
|
344
|
+
export { BullJobStore, BullJobStore as default, createBullJobStore };
|
|
345
|
+
|
|
346
|
+
//# sourceMappingURL=bull.js.map
|