@happyvertical/jobs 0.74.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. package/AGENT.md +33 -0
  2. package/LICENSE +7 -0
  3. package/dist/adapters/bull.d.ts +103 -0
  4. package/dist/adapters/bull.d.ts.map +1 -0
  5. package/dist/adapters/bull.js +349 -0
  6. package/dist/adapters/bull.js.map +1 -0
  7. package/dist/adapters/bullmq.d.ts +85 -0
  8. package/dist/adapters/bullmq.d.ts.map +1 -0
  9. package/dist/adapters/bullmq.js +391 -0
  10. package/dist/adapters/bullmq.js.map +1 -0
  11. package/dist/adapters/cloud-tasks.d.ts +110 -0
  12. package/dist/adapters/cloud-tasks.d.ts.map +1 -0
  13. package/dist/adapters/cloud-tasks.js +336 -0
  14. package/dist/adapters/cloud-tasks.js.map +1 -0
  15. package/dist/adapters/postgres.d.ts +55 -0
  16. package/dist/adapters/postgres.d.ts.map +1 -0
  17. package/dist/adapters/postgres.js +437 -0
  18. package/dist/adapters/postgres.js.map +1 -0
  19. package/dist/adapters/sqlite.d.ts +44 -0
  20. package/dist/adapters/sqlite.d.ts.map +1 -0
  21. package/dist/adapters/sqlite.js +323 -0
  22. package/dist/adapters/sqlite.js.map +1 -0
  23. package/dist/adapters/sqs.d.ts +112 -0
  24. package/dist/adapters/sqs.d.ts.map +1 -0
  25. package/dist/adapters/sqs.js +411 -0
  26. package/dist/adapters/sqs.js.map +1 -0
  27. package/dist/base-store.d.ts +69 -0
  28. package/dist/base-store.d.ts.map +1 -0
  29. package/dist/chunks/base-store-DlNksWvQ.js +324 -0
  30. package/dist/chunks/base-store-DlNksWvQ.js.map +1 -0
  31. package/dist/cli/claude-context.d.ts +3 -0
  32. package/dist/cli/claude-context.d.ts.map +1 -0
  33. package/dist/cli/claude-context.js +21 -0
  34. package/dist/cli/claude-context.js.map +1 -0
  35. package/dist/index.d.ts +16 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +252 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/retry.d.ts +84 -0
  40. package/dist/retry.d.ts.map +1 -0
  41. package/dist/types.d.ts +311 -0
  42. package/dist/types.d.ts.map +1 -0
  43. package/dist/worker.d.ts +74 -0
  44. package/dist/worker.d.ts.map +1 -0
  45. package/metadata.json +34 -0
  46. package/package.json +114 -0
@@ -0,0 +1,391 @@
1
+ import { createId } from "@happyvertical/utils";
2
+ import { B as BaseJobStore, p as priorityToNumber } from "../chunks/base-store-DlNksWvQ.js";
3
+ class BullMQJobStore extends BaseJobStore {
4
+ config;
5
+ queues = /* @__PURE__ */ new Map();
6
+ // biome-ignore lint/style/useNamingConvention: bullmq module reference
7
+ bullmqModule = 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 BullMQ
21
+ */
22
+ async initialize() {
23
+ if (this.initialized) return;
24
+ try {
25
+ this.bullmqModule = await import("bullmq");
26
+ } catch {
27
+ throw new Error(
28
+ "BullMQ is required for BullMQJobStore. Install it with: npm install bullmq"
29
+ );
30
+ }
31
+ this.initialized = true;
32
+ }
33
+ /**
34
+ * Get or create a BullMQ queue for a queue name
35
+ */
36
+ getQueueWrapper(queueName) {
37
+ if (!this.bullmqModule) {
38
+ throw new Error("BullMQJobStore not initialized");
39
+ }
40
+ if (!this.queues.has(queueName)) {
41
+ const queueOptions = {
42
+ prefix: this.config.prefix,
43
+ defaultJobOptions: this.config.defaultJobOptions
44
+ };
45
+ if (this.config.connection) {
46
+ queueOptions.connection = this.config.connection;
47
+ }
48
+ const queue = new this.bullmqModule.Queue(
49
+ queueName,
50
+ queueOptions
51
+ );
52
+ const eventsOptions = {
53
+ prefix: this.config.prefix
54
+ };
55
+ if (this.config.connection) {
56
+ eventsOptions.connection = this.config.connection;
57
+ }
58
+ const events = new this.bullmqModule.QueueEvents(
59
+ queueName,
60
+ eventsOptions
61
+ );
62
+ events.on("completed", async ({ jobId }) => {
63
+ const job = await this.get(jobId);
64
+ if (job) {
65
+ await this.emitEvent("job.completed", job);
66
+ }
67
+ });
68
+ events.on("failed", async ({ jobId, failedReason }) => {
69
+ const job = await this.get(jobId);
70
+ if (job) {
71
+ job.lastError = failedReason;
72
+ await this.emitEvent("job.failed", job, { error: failedReason });
73
+ }
74
+ });
75
+ this.queues.set(queueName, { queue, events });
76
+ }
77
+ return this.queues.get(queueName);
78
+ }
79
+ /**
80
+ * Convert BullMQ job to our Job format
81
+ */
82
+ async bullMQJobToJob(bullMQJob, queueName) {
83
+ const data = bullMQJob.data;
84
+ const state = await bullMQJob.getState();
85
+ const status = this.mapBullMQStatus(state);
86
+ return {
87
+ id: bullMQJob.id ?? createId(),
88
+ queue: queueName,
89
+ payload: data.payload,
90
+ status,
91
+ priority: bullMQJob.opts.priority ?? 50,
92
+ attempts: bullMQJob.attemptsMade,
93
+ maxAttempts: data.meta.maxAttempts,
94
+ runAt: bullMQJob.opts.delay ? new Date(bullMQJob.timestamp + bullMQJob.opts.delay) : new Date(bullMQJob.timestamp),
95
+ startedAt: bullMQJob.processedOn ? new Date(bullMQJob.processedOn) : null,
96
+ completedAt: bullMQJob.finishedOn ? new Date(bullMQJob.finishedOn) : null,
97
+ timeout: data.meta.timeout,
98
+ timeoutBehavior: data.meta.timeoutBehavior,
99
+ lastError: bullMQJob.failedReason ?? null,
100
+ resultPointer: bullMQJob.returnvalue?.resultPointer ?? null,
101
+ retryStrategy: data.meta.retryStrategy,
102
+ workerId: data.meta.workerId,
103
+ workerHeartbeat: null,
104
+ createdAt: new Date(bullMQJob.timestamp),
105
+ updatedAt: /* @__PURE__ */ new Date()
106
+ };
107
+ }
108
+ /**
109
+ * Map BullMQ job state to our JobStatus
110
+ */
111
+ mapBullMQStatus(state) {
112
+ switch (state) {
113
+ case "completed":
114
+ return "completed";
115
+ case "failed":
116
+ return "failed";
117
+ case "active":
118
+ return "running";
119
+ case "waiting":
120
+ case "delayed":
121
+ case "prioritized":
122
+ case "waiting-children":
123
+ default:
124
+ return "pending";
125
+ }
126
+ }
127
+ /**
128
+ * Enqueue a new job
129
+ */
130
+ async enqueue(options) {
131
+ if (!this.initialized) {
132
+ throw new Error("BullMQJobStore not initialized");
133
+ }
134
+ const queueName = options.queue ?? "default";
135
+ const { queue } = this.getQueueWrapper(queueName);
136
+ const jobData = {
137
+ payload: options.payload,
138
+ meta: {
139
+ maxAttempts: options.maxAttempts ?? 3,
140
+ timeout: options.timeout ?? 3e5,
141
+ timeoutBehavior: options.timeoutBehavior ?? "fail",
142
+ retryStrategy: options.retryStrategy && "toConfig" in options.retryStrategy ? options.retryStrategy.toConfig() : options.retryStrategy ?? {
143
+ type: "exponential",
144
+ config: { initialDelay: 1e3, multiplier: 2 }
145
+ },
146
+ workerId: null
147
+ }
148
+ };
149
+ const bullMQJobOptions = {
150
+ priority: priorityToNumber(options.priority),
151
+ attempts: options.maxAttempts ?? 3,
152
+ delay: options.runAt ? Math.max(0, options.runAt.getTime() - Date.now()) : void 0,
153
+ jobId: createId()
154
+ };
155
+ const bullMQJob = await queue.add(
156
+ options.payload.method,
157
+ jobData,
158
+ bullMQJobOptions
159
+ );
160
+ const job = await this.bullMQJobToJob(bullMQJob, queueName);
161
+ await this.emitEvent("job.created", job);
162
+ return job;
163
+ }
164
+ /**
165
+ * Dequeue jobs ready for processing
166
+ */
167
+ async dequeue(queues, limit, workerId) {
168
+ if (!this.initialized) {
169
+ throw new Error("BullMQJobStore not initialized");
170
+ }
171
+ const jobs = [];
172
+ for (const queueName of queues) {
173
+ if (jobs.length >= limit) break;
174
+ const { queue } = this.getQueueWrapper(queueName);
175
+ const waiting = await queue.getWaiting(0, limit - jobs.length - 1);
176
+ for (const bullMQJob of waiting) {
177
+ bullMQJob.data.meta.workerId = workerId;
178
+ await bullMQJob.updateData(bullMQJob.data);
179
+ jobs.push(await this.bullMQJobToJob(bullMQJob, queueName));
180
+ }
181
+ }
182
+ return jobs;
183
+ }
184
+ /**
185
+ * Update a job
186
+ */
187
+ async update(id, updates) {
188
+ if (!this.initialized) {
189
+ throw new Error("BullMQJobStore not initialized");
190
+ }
191
+ for (const [queueName, { queue }] of this.queues) {
192
+ const bullMQJob = await queue.getJob(id);
193
+ if (bullMQJob) {
194
+ const newData = { ...bullMQJob.data };
195
+ if (updates.payload) {
196
+ newData.payload = updates.payload;
197
+ }
198
+ if (updates.maxAttempts !== void 0) {
199
+ newData.meta.maxAttempts = updates.maxAttempts;
200
+ }
201
+ if (updates.timeout !== void 0) {
202
+ newData.meta.timeout = updates.timeout;
203
+ }
204
+ if (updates.workerId !== void 0) {
205
+ newData.meta.workerId = updates.workerId;
206
+ }
207
+ await bullMQJob.updateData(newData);
208
+ return await this.bullMQJobToJob(bullMQJob, queueName);
209
+ }
210
+ }
211
+ throw new Error(`Job ${id} not found`);
212
+ }
213
+ /**
214
+ * Get a job by ID
215
+ */
216
+ async get(id) {
217
+ if (!this.initialized) {
218
+ throw new Error("BullMQJobStore not initialized");
219
+ }
220
+ for (const [queueName, { queue }] of this.queues) {
221
+ const bullMQJob = await queue.getJob(id);
222
+ if (bullMQJob) {
223
+ return await this.bullMQJobToJob(bullMQJob, queueName);
224
+ }
225
+ }
226
+ return null;
227
+ }
228
+ /**
229
+ * List jobs with filtering
230
+ */
231
+ async list(filter) {
232
+ if (!this.initialized) {
233
+ throw new Error("BullMQJobStore not initialized");
234
+ }
235
+ const jobs = [];
236
+ const limit = filter.limit ?? 100;
237
+ const offset = filter.offset ?? 0;
238
+ const targetQueues = filter.queue ? [
239
+ {
240
+ name: filter.queue,
241
+ wrapper: this.getQueueWrapper(filter.queue)
242
+ }
243
+ ] : Array.from(this.queues.entries()).map(([name, wrapper]) => ({
244
+ name,
245
+ wrapper
246
+ }));
247
+ for (const { name, wrapper } of targetQueues) {
248
+ const { queue } = wrapper;
249
+ const statuses = filter.status ? Array.isArray(filter.status) ? filter.status : [filter.status] : ["pending", "running", "completed", "failed"];
250
+ for (const status of statuses) {
251
+ let bullMQJobs = [];
252
+ switch (status) {
253
+ case "pending":
254
+ bullMQJobs = [
255
+ ...await queue.getWaiting(offset, offset + limit - 1),
256
+ ...await queue.getDelayed(offset, offset + limit - 1)
257
+ ];
258
+ break;
259
+ case "running":
260
+ bullMQJobs = await queue.getActive(offset, offset + limit - 1);
261
+ break;
262
+ case "completed":
263
+ bullMQJobs = await queue.getCompleted(offset, offset + limit - 1);
264
+ break;
265
+ case "failed":
266
+ bullMQJobs = await queue.getFailed(offset, offset + limit - 1);
267
+ break;
268
+ }
269
+ for (const bullMQJob of bullMQJobs) {
270
+ const job = await this.bullMQJobToJob(bullMQJob, name);
271
+ if (filter.objectType && job.payload.objectType !== filter.objectType)
272
+ continue;
273
+ if (filter.method && job.payload.method !== filter.method) continue;
274
+ if (filter.createdAfter && job.createdAt < filter.createdAfter)
275
+ continue;
276
+ if (filter.createdBefore && job.createdAt > filter.createdBefore)
277
+ continue;
278
+ jobs.push(job);
279
+ if (jobs.length >= limit) break;
280
+ }
281
+ if (jobs.length >= limit) break;
282
+ }
283
+ }
284
+ return jobs.slice(0, limit);
285
+ }
286
+ /**
287
+ * Cancel a job
288
+ */
289
+ async cancel(id) {
290
+ if (!this.initialized) {
291
+ throw new Error("BullMQJobStore not initialized");
292
+ }
293
+ for (const [queueName, { queue }] of this.queues) {
294
+ const bullMQJob = await queue.getJob(id);
295
+ if (bullMQJob) {
296
+ await bullMQJob.remove();
297
+ const job = await this.bullMQJobToJob(bullMQJob, queueName);
298
+ job.status = "cancelled";
299
+ await this.emitEvent("job.cancelled", job);
300
+ return;
301
+ }
302
+ }
303
+ throw new Error(`Job ${id} not found`);
304
+ }
305
+ /**
306
+ * Clean up old jobs
307
+ */
308
+ async cleanup(options) {
309
+ if (!this.initialized) {
310
+ throw new Error("BullMQJobStore not initialized");
311
+ }
312
+ let cleaned = 0;
313
+ for (const { queue } of this.queues.values()) {
314
+ if (options.completedBefore) {
315
+ const grace = Date.now() - options.completedBefore.getTime();
316
+ const result = await queue.clean(
317
+ grace,
318
+ options.limit ?? 1e3,
319
+ "completed"
320
+ );
321
+ cleaned += result.length;
322
+ }
323
+ if (options.failedBefore) {
324
+ const grace = Date.now() - options.failedBefore.getTime();
325
+ const result = await queue.clean(
326
+ grace,
327
+ options.limit ?? 1e3,
328
+ "failed"
329
+ );
330
+ cleaned += result.length;
331
+ }
332
+ }
333
+ return cleaned;
334
+ }
335
+ /**
336
+ * Update worker heartbeat (no-op for BullMQ - handled internally)
337
+ */
338
+ async heartbeat(_jobId, _workerId) {
339
+ }
340
+ /**
341
+ * Get queue statistics
342
+ */
343
+ async stats(queue) {
344
+ if (!this.initialized) {
345
+ throw new Error("BullMQJobStore not initialized");
346
+ }
347
+ const totals = {
348
+ pending: 0,
349
+ running: 0,
350
+ completed: 0,
351
+ failed: 0,
352
+ cancelled: 0,
353
+ avgDuration: null
354
+ };
355
+ const targetQueues = queue ? [this.getQueueWrapper(queue).queue] : Array.from(this.queues.values()).map((w) => w.queue);
356
+ for (const q of targetQueues) {
357
+ const counts = await q.getJobCounts(
358
+ "waiting",
359
+ "active",
360
+ "completed",
361
+ "failed",
362
+ "delayed"
363
+ );
364
+ totals.pending += counts.waiting + counts.delayed;
365
+ totals.running += counts.active;
366
+ totals.completed += counts.completed;
367
+ totals.failed += counts.failed;
368
+ }
369
+ return totals;
370
+ }
371
+ /**
372
+ * Close all queues
373
+ */
374
+ async close() {
375
+ for (const { queue, events } of this.queues.values()) {
376
+ await events.close();
377
+ await queue.close();
378
+ }
379
+ this.queues.clear();
380
+ this.initialized = false;
381
+ }
382
+ }
383
+ function createBullMQJobStore(config) {
384
+ return new BullMQJobStore(config);
385
+ }
386
+ export {
387
+ BullMQJobStore,
388
+ createBullMQJobStore,
389
+ BullMQJobStore as default
390
+ };
391
+ //# sourceMappingURL=bullmq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bullmq.js","sources":["../../src/adapters/bullmq.ts"],"sourcesContent":["/**\n * BullMQ (Redis) Job Store Adapter\n *\n * Uses BullMQ library for Redis-based job storage with real-time updates.\n * BullMQ is the successor to Bull with improved performance and TypeScript support.\n *\n * @example\n * ```typescript\n * import { BullMQJobStore } from '@happyvertical/jobs/adapters/bullmq';\n *\n * const store = new BullMQJobStore({\n * connection: {\n * host: 'localhost',\n * port: 6379,\n * },\n * defaultJobOptions: {\n * removeOnComplete: 100,\n * removeOnFail: 500,\n * },\n * });\n *\n * await store.initialize();\n * ```\n *\n * Note: This adapter requires the `bullmq` package as a peer dependency.\n * Install it with: npm install bullmq\n */\n\nimport { createId } from '@happyvertical/utils';\nimport type {\n Job as BullMQJob,\n JobsOptions as BullMQJobOptions,\n Queue as BullMQQueue,\n QueueEvents as BullMQQueueEvents,\n ConnectionOptions,\n} from 'bullmq';\nimport { BaseJobStore, priorityToNumber } from '../base-store.js';\nimport type {\n CleanupOptions,\n Job,\n JobCreateOptions,\n JobFilter,\n QueueStats,\n} from '../types.js';\n\n/**\n * BullMQ adapter configuration\n */\nexport interface BullMQJobStoreConfig {\n /** Redis connection options */\n connection?: ConnectionOptions;\n /** Default queue name prefix */\n prefix?: string;\n /** Default job options */\n defaultJobOptions?: BullMQJobOptions;\n}\n\n/**\n * Job data stored in BullMQ\n */\ninterface BullMQJobData {\n /** Original job payload */\n payload: Job['payload'];\n /** Additional metadata */\n meta: {\n maxAttempts: number;\n timeout: number;\n timeoutBehavior: Job['timeoutBehavior'];\n retryStrategy: Job['retryStrategy'];\n workerId: string | null;\n };\n}\n\n/**\n * Queue wrapper to hold queue and events\n */\ninterface QueueWrapper {\n queue: BullMQQueue<BullMQJobData>;\n events: BullMQQueueEvents;\n}\n\n/**\n * BullMQ-based job store implementation\n */\nexport class BullMQJobStore extends BaseJobStore {\n private config: BullMQJobStoreConfig;\n private queues: Map<string, QueueWrapper> = new Map();\n // biome-ignore lint/style/useNamingConvention: bullmq module reference\n private bullmqModule: typeof import('bullmq') | null = null;\n\n constructor(config: BullMQJobStoreConfig = {}) {\n super();\n this.config = {\n prefix: 'smrt_jobs',\n defaultJobOptions: {\n removeOnComplete: 100,\n removeOnFail: 500,\n },\n ...config,\n };\n }\n\n /**\n * Initialize the store - dynamically imports BullMQ\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Dynamic import to avoid requiring bullmq as a hard dependency\n this.bullmqModule = await import('bullmq');\n } catch {\n throw new Error(\n 'BullMQ is required for BullMQJobStore. Install it with: npm install bullmq',\n );\n }\n\n this.initialized = true;\n }\n\n /**\n * Get or create a BullMQ queue for a queue name\n */\n private getQueueWrapper(queueName: string): QueueWrapper {\n if (!this.bullmqModule) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n if (!this.queues.has(queueName)) {\n // Build options conditionally - BullMQ types require connection but it can be omitted for local Redis\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const queueOptions: any = {\n prefix: this.config.prefix,\n defaultJobOptions: this.config.defaultJobOptions,\n };\n if (this.config.connection) {\n queueOptions.connection = this.config.connection;\n }\n\n const queue = new this.bullmqModule.Queue<BullMQJobData>(\n queueName,\n queueOptions,\n ) as BullMQQueue<BullMQJobData>;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const eventsOptions: any = {\n prefix: this.config.prefix,\n };\n if (this.config.connection) {\n eventsOptions.connection = this.config.connection;\n }\n\n const events = new this.bullmqModule.QueueEvents(\n queueName,\n eventsOptions,\n );\n\n // Set up event listeners\n events.on('completed', async ({ jobId }) => {\n const job = await this.get(jobId);\n if (job) {\n await this.emitEvent('job.completed', job);\n }\n });\n\n events.on('failed', async ({ jobId, failedReason }) => {\n const job = await this.get(jobId);\n if (job) {\n job.lastError = failedReason;\n await this.emitEvent('job.failed', job, { error: failedReason });\n }\n });\n\n this.queues.set(queueName, { queue, events });\n }\n\n return this.queues.get(queueName)!;\n }\n\n /**\n * Convert BullMQ job to our Job format\n */\n private async bullMQJobToJob(\n bullMQJob: BullMQJob<BullMQJobData>,\n queueName: string,\n ): Promise<Job> {\n const data = bullMQJob.data;\n const state = await bullMQJob.getState();\n const status = this.mapBullMQStatus(state);\n\n return {\n id: bullMQJob.id ?? createId(),\n queue: queueName,\n payload: data.payload,\n status,\n priority: bullMQJob.opts.priority ?? 50,\n attempts: bullMQJob.attemptsMade,\n maxAttempts: data.meta.maxAttempts,\n runAt: bullMQJob.opts.delay\n ? new Date(bullMQJob.timestamp + bullMQJob.opts.delay)\n : new Date(bullMQJob.timestamp),\n startedAt: bullMQJob.processedOn ? new Date(bullMQJob.processedOn) : null,\n completedAt: bullMQJob.finishedOn ? new Date(bullMQJob.finishedOn) : null,\n timeout: data.meta.timeout,\n timeoutBehavior: data.meta.timeoutBehavior,\n lastError: bullMQJob.failedReason ?? null,\n resultPointer: bullMQJob.returnvalue?.resultPointer ?? null,\n retryStrategy: data.meta.retryStrategy,\n workerId: data.meta.workerId,\n workerHeartbeat: null,\n createdAt: new Date(bullMQJob.timestamp),\n updatedAt: new Date(),\n };\n }\n\n /**\n * Map BullMQ job state to our JobStatus\n */\n private mapBullMQStatus(\n state:\n | 'completed'\n | 'failed'\n | 'delayed'\n | 'active'\n | 'waiting'\n | 'waiting-children'\n | 'prioritized'\n | 'unknown',\n ): Job['status'] {\n switch (state) {\n case 'completed':\n return 'completed';\n case 'failed':\n return 'failed';\n case 'active':\n return 'running';\n case 'waiting':\n case 'delayed':\n case 'prioritized':\n case 'waiting-children':\n default:\n return 'pending';\n }\n }\n\n /**\n * Enqueue a new job\n */\n async enqueue(options: JobCreateOptions): Promise<Job> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n const queueName = options.queue ?? 'default';\n const { queue } = this.getQueueWrapper(queueName);\n\n const jobData: BullMQJobData = {\n payload: options.payload,\n meta: {\n maxAttempts: options.maxAttempts ?? 3,\n timeout: options.timeout ?? 300000,\n timeoutBehavior: options.timeoutBehavior ?? 'fail',\n retryStrategy:\n options.retryStrategy && 'toConfig' in options.retryStrategy\n ? options.retryStrategy.toConfig()\n : ((options.retryStrategy as Job['retryStrategy']) ?? {\n type: 'exponential',\n config: { initialDelay: 1000, multiplier: 2 },\n }),\n workerId: null,\n },\n };\n\n const bullMQJobOptions: BullMQJobOptions = {\n priority: priorityToNumber(options.priority),\n attempts: options.maxAttempts ?? 3,\n delay: options.runAt\n ? Math.max(0, options.runAt.getTime() - Date.now())\n : undefined,\n jobId: createId(),\n };\n\n const bullMQJob = await queue.add(\n options.payload.method,\n jobData,\n bullMQJobOptions,\n );\n const job = await this.bullMQJobToJob(bullMQJob, queueName);\n\n await this.emitEvent('job.created', job);\n return job;\n }\n\n /**\n * Dequeue jobs ready for processing\n */\n async dequeue(\n queues: string[],\n limit: number,\n workerId: string,\n ): Promise<Job[]> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n // BullMQ handles job claiming internally through its Worker\n // This method is primarily for compatibility with the interface\n\n const jobs: Job[] = [];\n\n for (const queueName of queues) {\n if (jobs.length >= limit) break;\n\n const { queue } = this.getQueueWrapper(queueName);\n const waiting = await queue.getWaiting(0, limit - jobs.length - 1);\n\n for (const bullMQJob of waiting) {\n // Update worker ID in job data\n bullMQJob.data.meta.workerId = workerId;\n await bullMQJob.updateData(bullMQJob.data);\n\n jobs.push(await this.bullMQJobToJob(bullMQJob, queueName));\n }\n }\n\n return jobs;\n }\n\n /**\n * Update a job\n */\n async update(id: string, updates: Partial<Job>): Promise<Job> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n // Find the job across queues\n for (const [queueName, { queue }] of this.queues) {\n const bullMQJob = await queue.getJob(id);\n if (bullMQJob) {\n // Update the job data\n const newData = { ...bullMQJob.data };\n if (updates.payload) {\n newData.payload = updates.payload;\n }\n if (updates.maxAttempts !== undefined) {\n newData.meta.maxAttempts = updates.maxAttempts;\n }\n if (updates.timeout !== undefined) {\n newData.meta.timeout = updates.timeout;\n }\n if (updates.workerId !== undefined) {\n newData.meta.workerId = updates.workerId;\n }\n\n await bullMQJob.updateData(newData);\n return await this.bullMQJobToJob(bullMQJob, queueName);\n }\n }\n\n throw new Error(`Job ${id} not found`);\n }\n\n /**\n * Get a job by ID\n */\n async get(id: string): Promise<Job | null> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n // Search across all queues\n for (const [queueName, { queue }] of this.queues) {\n const bullMQJob = await queue.getJob(id);\n if (bullMQJob) {\n return await this.bullMQJobToJob(bullMQJob, queueName);\n }\n }\n\n return null;\n }\n\n /**\n * List jobs with filtering\n */\n async list(filter: JobFilter): Promise<Job[]> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n const jobs: Job[] = [];\n const limit = filter.limit ?? 100;\n const offset = filter.offset ?? 0;\n\n const targetQueues = filter.queue\n ? [\n {\n name: filter.queue,\n wrapper: this.getQueueWrapper(filter.queue),\n },\n ]\n : Array.from(this.queues.entries()).map(([name, wrapper]) => ({\n name,\n wrapper,\n }));\n\n for (const { name, wrapper } of targetQueues) {\n const { queue } = wrapper;\n\n // Get jobs by status\n const statuses = filter.status\n ? Array.isArray(filter.status)\n ? filter.status\n : [filter.status]\n : ['pending', 'running', 'completed', 'failed'];\n\n for (const status of statuses) {\n let bullMQJobs: BullMQJob<BullMQJobData>[] = [];\n\n switch (status) {\n case 'pending':\n bullMQJobs = [\n ...(await queue.getWaiting(offset, offset + limit - 1)),\n ...(await queue.getDelayed(offset, offset + limit - 1)),\n ];\n break;\n case 'running':\n bullMQJobs = await queue.getActive(offset, offset + limit - 1);\n break;\n case 'completed':\n bullMQJobs = await queue.getCompleted(offset, offset + limit - 1);\n break;\n case 'failed':\n bullMQJobs = await queue.getFailed(offset, offset + limit - 1);\n break;\n }\n\n for (const bullMQJob of bullMQJobs) {\n const job = await this.bullMQJobToJob(bullMQJob, name);\n\n // Apply additional filters\n if (filter.objectType && job.payload.objectType !== filter.objectType)\n continue;\n if (filter.method && job.payload.method !== filter.method) continue;\n if (filter.createdAfter && job.createdAt < filter.createdAfter)\n continue;\n if (filter.createdBefore && job.createdAt > filter.createdBefore)\n continue;\n\n jobs.push(job);\n\n if (jobs.length >= limit) break;\n }\n\n if (jobs.length >= limit) break;\n }\n }\n\n return jobs.slice(0, limit);\n }\n\n /**\n * Cancel a job\n */\n async cancel(id: string): Promise<void> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n for (const [queueName, { queue }] of this.queues) {\n const bullMQJob = await queue.getJob(id);\n if (bullMQJob) {\n await bullMQJob.remove();\n const job = await this.bullMQJobToJob(bullMQJob, queueName);\n job.status = 'cancelled';\n await this.emitEvent('job.cancelled', job);\n return;\n }\n }\n\n throw new Error(`Job ${id} not found`);\n }\n\n /**\n * Clean up old jobs\n */\n async cleanup(options: CleanupOptions): Promise<number> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n let cleaned = 0;\n\n for (const { queue } of this.queues.values()) {\n if (options.completedBefore) {\n const grace = Date.now() - options.completedBefore.getTime();\n const result = await queue.clean(\n grace,\n options.limit ?? 1000,\n 'completed',\n );\n cleaned += result.length;\n }\n\n if (options.failedBefore) {\n const grace = Date.now() - options.failedBefore.getTime();\n const result = await queue.clean(\n grace,\n options.limit ?? 1000,\n 'failed',\n );\n cleaned += result.length;\n }\n }\n\n return cleaned;\n }\n\n /**\n * Update worker heartbeat (no-op for BullMQ - handled internally)\n */\n async heartbeat(_jobId: string, _workerId: string): Promise<void> {\n // BullMQ handles heartbeat/stalled job detection internally\n }\n\n /**\n * Get queue statistics\n */\n async stats(queue?: string): Promise<QueueStats> {\n if (!this.initialized) {\n throw new Error('BullMQJobStore not initialized');\n }\n\n const totals: QueueStats = {\n pending: 0,\n running: 0,\n completed: 0,\n failed: 0,\n cancelled: 0,\n avgDuration: null,\n };\n\n const targetQueues = queue\n ? [this.getQueueWrapper(queue).queue]\n : Array.from(this.queues.values()).map((w) => w.queue);\n\n for (const q of targetQueues) {\n const counts = await q.getJobCounts(\n 'waiting',\n 'active',\n 'completed',\n 'failed',\n 'delayed',\n );\n totals.pending += counts.waiting + counts.delayed;\n totals.running += counts.active;\n totals.completed += counts.completed;\n totals.failed += counts.failed;\n }\n\n return totals;\n }\n\n /**\n * Close all queues\n */\n async close(): Promise<void> {\n for (const { queue, events } of this.queues.values()) {\n await events.close();\n await queue.close();\n }\n this.queues.clear();\n this.initialized = false;\n }\n}\n\n/**\n * Create a BullMQ job store instance\n */\nexport function createBullMQJobStore(\n config?: BullMQJobStoreConfig,\n): BullMQJobStore {\n return new BullMQJobStore(config);\n}\n\nexport default BullMQJobStore;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ import { BaseJobStore } from '../base-store.js';
2
+ import { CleanupOptions, Job, JobCreateOptions, JobFilter, QueueStats } from '../types.js';
3
+ /**
4
+ * Cloud Tasks adapter configuration
5
+ */
6
+ export interface CloudTasksJobStoreConfig {
7
+ /** GCP project ID */
8
+ projectId: string;
9
+ /** GCP location (e.g., 'us-central1') */
10
+ location: string;
11
+ /** Queue name prefix */
12
+ queuePrefix?: string;
13
+ /** HTTP handler URL for job execution */
14
+ handlerUrl: string;
15
+ /** Service account email for OIDC authentication */
16
+ serviceAccountEmail?: string;
17
+ /** Default retry configuration */
18
+ defaultRetry?: {
19
+ maxAttempts?: number;
20
+ minBackoff?: string;
21
+ maxBackoff?: string;
22
+ };
23
+ }
24
+ /**
25
+ * Cloud Tasks-based job store implementation
26
+ *
27
+ * Note: Cloud Tasks operates differently from traditional job queues:
28
+ * - Jobs are HTTP tasks sent to your handler URL
29
+ * - No pull-based dequeue (Cloud Tasks pushes to your handler)
30
+ * - Updates are limited (tasks can be deleted but not modified)
31
+ */
32
+ export declare class CloudTasksJobStore extends BaseJobStore {
33
+ private config;
34
+ private client;
35
+ private cloudTasksModule;
36
+ private jobStates;
37
+ constructor(config: CloudTasksJobStoreConfig);
38
+ /**
39
+ * Initialize the store - dynamically imports Google Cloud Tasks
40
+ */
41
+ initialize(): Promise<void>;
42
+ /**
43
+ * Get the full queue path
44
+ */
45
+ private getQueuePath;
46
+ /**
47
+ * Get the full task path
48
+ */
49
+ private getTaskPath;
50
+ /**
51
+ * Enqueue a new job
52
+ */
53
+ enqueue(options: JobCreateOptions): Promise<Job>;
54
+ /**
55
+ * Dequeue jobs - NOT SUPPORTED in Cloud Tasks
56
+ * Cloud Tasks is push-based; jobs are delivered to your handler URL
57
+ */
58
+ dequeue(_queues: string[], _limit: number, _workerId: string): Promise<Job[]>;
59
+ /**
60
+ * Update a job - LIMITED SUPPORT in Cloud Tasks
61
+ */
62
+ update(_id: string, _updates: Partial<Job>): Promise<Job>;
63
+ /**
64
+ * Get a job by ID
65
+ */
66
+ get(id: string): Promise<Job | null>;
67
+ /**
68
+ * List jobs with filtering
69
+ * Note: Only returns jobs from in-memory state
70
+ */
71
+ list(filter: JobFilter): Promise<Job[]>;
72
+ /**
73
+ * Cancel a job by deleting its Cloud Task
74
+ */
75
+ cancel(id: string): Promise<void>;
76
+ /**
77
+ * Mark job as started (called by your handler when it receives the job)
78
+ */
79
+ markStarted(id: string, workerId: string): Promise<void>;
80
+ /**
81
+ * Mark job as completed (called by your handler after successful execution)
82
+ */
83
+ markCompleted(id: string, resultPointer?: string): Promise<void>;
84
+ /**
85
+ * Mark job as failed (called by your handler after failed execution)
86
+ */
87
+ markFailed(id: string, error: string): Promise<void>;
88
+ /**
89
+ * Clean up old jobs from in-memory state
90
+ */
91
+ cleanup(options: CleanupOptions): Promise<number>;
92
+ /**
93
+ * Update worker heartbeat - stored in memory only
94
+ */
95
+ heartbeat(jobId: string, _workerId: string): Promise<void>;
96
+ /**
97
+ * Get queue statistics from in-memory state
98
+ */
99
+ stats(queue?: string): Promise<QueueStats>;
100
+ /**
101
+ * Close the Cloud Tasks client
102
+ */
103
+ close(): Promise<void>;
104
+ }
105
+ /**
106
+ * Create a Cloud Tasks job store instance
107
+ */
108
+ export declare function createCloudTasksJobStore(config: CloudTasksJobStoreConfig): CloudTasksJobStore;
109
+ export default CloudTasksJobStore;
110
+ //# sourceMappingURL=cloud-tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cloud-tasks.d.ts","sourceRoot":"","sources":["../../src/adapters/cloud-tasks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,EAAE,YAAY,EAAoB,MAAM,kBAAkB,CAAC;AAClE,OAAO,KAAK,EACV,cAAc,EACd,GAAG,EACH,gBAAgB,EAChB,SAAS,EACT,UAAU,EACX,MAAM,aAAa,CAAC;AAErB;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,yCAAyC;IACzC,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,yCAAyC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,oDAAoD;IACpD,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,kCAAkC;IAClC,YAAY,CAAC,EAAE;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,UAAU,CAAC,EAAE,MAAM,CAAC;KACrB,CAAC;CACH;AAyBD;;;;;;;GAOG;AACH,qBAAa,kBAAmB,SAAQ,YAAY;IAClD,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAqC;IAEnD,OAAO,CAAC,gBAAgB,CAAqD;IAC7E,OAAO,CAAC,SAAS,CAAoC;gBAEzC,MAAM,EAAE,wBAAwB;IAa5C;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAiBjC;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAmGtD;;;OAGG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,EAAE,EACjB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,GAAG,EAAE,CAAC;IAQjB;;OAEG;IACG,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC;IAO/D;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAW1C;;;OAGG;IACG,IAAI,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IA6B7C;;OAEG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BvC;;OAEG;IACG,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAc9D;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatE;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa1D;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC;IA6CvD;;OAEG;IACG,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAOhE;;OAEG;IACG,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAmChD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAQ7B;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,wBAAwB,GAC/B,kBAAkB,CAEpB;AAED,eAAe,kBAAkB,CAAC"}