@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,323 @@
1
+ import { getDatabase, syncSchema } from "@happyvertical/sql";
2
+ import { B as BaseJobStore, v as validateTableName } from "../chunks/base-store-DlNksWvQ.js";
3
+ class SqliteJobStore extends BaseJobStore {
4
+ db = null;
5
+ url;
6
+ externalDb;
7
+ tableName;
8
+ capabilities;
9
+ constructor(config = {}) {
10
+ super();
11
+ this.url = config.url ?? ":memory:";
12
+ this.externalDb = config.db ?? null;
13
+ this.tableName = validateTableName(config.tableName ?? "_jobs");
14
+ this.capabilities = config.capabilities;
15
+ }
16
+ async initialize() {
17
+ if (this.initialized) return;
18
+ this.db = this.externalDb ?? await getDatabase({
19
+ type: "sqlite",
20
+ url: this.url,
21
+ capabilities: this.capabilities
22
+ });
23
+ const schema = `
24
+ CREATE TABLE IF NOT EXISTS "${this.tableName}" (
25
+ id TEXT PRIMARY KEY,
26
+ queue TEXT NOT NULL DEFAULT 'default',
27
+ payload TEXT NOT NULL,
28
+ status TEXT NOT NULL DEFAULT 'pending',
29
+ priority INTEGER NOT NULL DEFAULT 50,
30
+ attempts INTEGER NOT NULL DEFAULT 0,
31
+ max_attempts INTEGER NOT NULL DEFAULT 3,
32
+ run_at TEXT NOT NULL,
33
+ started_at TEXT,
34
+ completed_at TEXT,
35
+ timeout INTEGER NOT NULL DEFAULT 300000,
36
+ timeout_behavior TEXT NOT NULL DEFAULT 'fail',
37
+ last_error TEXT,
38
+ result_pointer TEXT,
39
+ retry_strategy TEXT NOT NULL,
40
+ worker_id TEXT,
41
+ worker_heartbeat TEXT,
42
+ created_at TEXT NOT NULL,
43
+ updated_at TEXT NOT NULL
44
+ );
45
+
46
+ CREATE INDEX IF NOT EXISTS "idx_${this.tableName}_status_queue" ON "${this.tableName}" (status, queue, run_at, priority DESC);
47
+ CREATE INDEX IF NOT EXISTS "idx_${this.tableName}_created_at" ON "${this.tableName}" (created_at);
48
+ CREATE INDEX IF NOT EXISTS "idx_${this.tableName}_queue" ON "${this.tableName}" (queue);
49
+ `;
50
+ await syncSchema({ db: this.db, schema });
51
+ this.initialized = true;
52
+ }
53
+ async enqueue(options) {
54
+ if (!this.db) throw new Error("Store not initialized");
55
+ const job = this.createJobRecord(options);
56
+ await this.db.insert(this.tableName, {
57
+ id: job.id,
58
+ queue: job.queue,
59
+ payload: JSON.stringify(job.payload),
60
+ status: job.status,
61
+ priority: job.priority,
62
+ attempts: job.attempts,
63
+ max_attempts: job.maxAttempts,
64
+ run_at: job.runAt.toISOString(),
65
+ started_at: job.startedAt?.toISOString() ?? null,
66
+ completed_at: job.completedAt?.toISOString() ?? null,
67
+ timeout: job.timeout,
68
+ timeout_behavior: job.timeoutBehavior,
69
+ last_error: job.lastError,
70
+ result_pointer: job.resultPointer,
71
+ retry_strategy: JSON.stringify(job.retryStrategy),
72
+ worker_id: job.workerId,
73
+ worker_heartbeat: job.workerHeartbeat?.toISOString() ?? null,
74
+ created_at: job.createdAt.toISOString(),
75
+ updated_at: job.updatedAt.toISOString()
76
+ });
77
+ await this.emitEvent("job.created", job);
78
+ if (job.runAt <= /* @__PURE__ */ new Date()) {
79
+ await this.emitEvent("job.ready", job);
80
+ }
81
+ return job;
82
+ }
83
+ async dequeue(queues, limit, workerId) {
84
+ if (!this.db) throw new Error("Store not initialized");
85
+ const now = (/* @__PURE__ */ new Date()).toISOString();
86
+ const queuePlaceholders = queues.map(() => "?").join(", ");
87
+ const { rows } = await this.db.query(
88
+ `
89
+ SELECT * FROM ${this.tableName}
90
+ WHERE status = 'pending'
91
+ AND queue IN (${queuePlaceholders})
92
+ AND run_at <= ?
93
+ ORDER BY priority DESC, run_at ASC
94
+ LIMIT ?
95
+ `,
96
+ [...queues, now, limit]
97
+ );
98
+ if (!rows.length) return [];
99
+ const jobIds = rows.map((r) => r.id);
100
+ const idPlaceholders = jobIds.map(() => "?").join(", ");
101
+ await this.db.query(
102
+ `
103
+ UPDATE ${this.tableName}
104
+ SET status = 'running',
105
+ worker_id = ?,
106
+ worker_heartbeat = ?,
107
+ started_at = ?,
108
+ attempts = attempts + 1,
109
+ updated_at = ?
110
+ WHERE id IN (${idPlaceholders})
111
+ AND status = 'pending'
112
+ `,
113
+ [workerId, now, now, now, ...jobIds]
114
+ );
115
+ const jobs = rows.map((row) => {
116
+ const job = this.parseJobRow(row);
117
+ job.status = "running";
118
+ job.workerId = workerId;
119
+ job.workerHeartbeat = /* @__PURE__ */ new Date();
120
+ job.startedAt = /* @__PURE__ */ new Date();
121
+ job.attempts += 1;
122
+ return job;
123
+ });
124
+ for (const job of jobs) {
125
+ await this.emitEvent("job.started", job);
126
+ }
127
+ return jobs;
128
+ }
129
+ async update(id, updates) {
130
+ if (!this.db) throw new Error("Store not initialized");
131
+ const setClause = [];
132
+ const params = [];
133
+ const fieldMap = {
134
+ queue: "queue",
135
+ payload: "payload",
136
+ status: "status",
137
+ priority: "priority",
138
+ attempts: "attempts",
139
+ maxAttempts: "max_attempts",
140
+ runAt: "run_at",
141
+ startedAt: "started_at",
142
+ completedAt: "completed_at",
143
+ timeout: "timeout",
144
+ timeoutBehavior: "timeout_behavior",
145
+ lastError: "last_error",
146
+ resultPointer: "result_pointer",
147
+ retryStrategy: "retry_strategy",
148
+ workerId: "worker_id",
149
+ workerHeartbeat: "worker_heartbeat"
150
+ };
151
+ for (const [key, value] of Object.entries(updates)) {
152
+ const column = fieldMap[key];
153
+ if (!column) continue;
154
+ setClause.push(`${column} = ?`);
155
+ if (value instanceof Date) {
156
+ params.push(value.toISOString());
157
+ } else if (typeof value === "object" && value !== null) {
158
+ params.push(JSON.stringify(value));
159
+ } else {
160
+ params.push(value);
161
+ }
162
+ }
163
+ if (setClause.length === 0) {
164
+ const job2 = await this.get(id);
165
+ if (!job2) throw new Error(`Job not found: ${id}`);
166
+ return job2;
167
+ }
168
+ setClause.push("updated_at = ?");
169
+ params.push((/* @__PURE__ */ new Date()).toISOString());
170
+ params.push(id);
171
+ await this.db.query(
172
+ `UPDATE ${this.tableName} SET ${setClause.join(", ")} WHERE id = ?`,
173
+ params
174
+ );
175
+ const job = await this.get(id);
176
+ if (!job) throw new Error(`Job not found after update: ${id}`);
177
+ if (updates.status === "completed") {
178
+ await this.emitEvent("job.completed", job, {
179
+ resultPointer: job.resultPointer ?? void 0
180
+ });
181
+ } else if (updates.status === "failed") {
182
+ await this.emitEvent("job.failed", job, {
183
+ error: job.lastError ?? void 0
184
+ });
185
+ } else if (updates.status === "cancelled") {
186
+ await this.emitEvent("job.cancelled", job);
187
+ }
188
+ return job;
189
+ }
190
+ async get(id) {
191
+ if (!this.db) throw new Error("Store not initialized");
192
+ const row = await this.db.get(this.tableName, { id });
193
+ if (!row) return null;
194
+ return this.parseJobRow(row);
195
+ }
196
+ async list(filter) {
197
+ if (!this.db) throw new Error("Store not initialized");
198
+ const { where, params: whereParams } = this.buildFilterWhere(filter);
199
+ const orderBy = this.buildOrderBy(filter);
200
+ const { clause: limitOffset, params: limitParams } = this.buildLimitOffset(filter);
201
+ const { rows } = await this.db.query(
202
+ `SELECT * FROM ${this.tableName} ${where} ${orderBy} ${limitOffset}`,
203
+ [...whereParams, ...limitParams]
204
+ );
205
+ return rows.map((row) => this.parseJobRow(row));
206
+ }
207
+ async cancel(id) {
208
+ if (!this.db) throw new Error("Store not initialized");
209
+ const job = await this.get(id);
210
+ if (!job) throw new Error(`Job not found: ${id}`);
211
+ if (job.status === "completed" || job.status === "cancelled") {
212
+ throw new Error(`Cannot cancel job with status: ${job.status}`);
213
+ }
214
+ await this.update(id, {
215
+ status: "cancelled",
216
+ completedAt: /* @__PURE__ */ new Date()
217
+ });
218
+ }
219
+ async cleanup(options) {
220
+ if (!this.db) throw new Error("Store not initialized");
221
+ const conditions = [];
222
+ const params = [];
223
+ if (options.completedBefore) {
224
+ conditions.push("(status = 'completed' AND completed_at < ?)");
225
+ params.push(options.completedBefore.toISOString());
226
+ }
227
+ if (options.failedBefore) {
228
+ conditions.push("(status = 'failed' AND completed_at < ?)");
229
+ params.push(options.failedBefore.toISOString());
230
+ }
231
+ if (options.cancelledBefore) {
232
+ conditions.push("(status = 'cancelled' AND completed_at < ?)");
233
+ params.push(options.cancelledBefore.toISOString());
234
+ }
235
+ if (conditions.length === 0) return 0;
236
+ let query = `DELETE FROM ${this.tableName} WHERE (${conditions.join(" OR ")})`;
237
+ if (options.limit) {
238
+ query = `
239
+ DELETE FROM ${this.tableName}
240
+ WHERE id IN (
241
+ SELECT id FROM ${this.tableName}
242
+ WHERE (${conditions.join(" OR ")})
243
+ LIMIT ?
244
+ )
245
+ `;
246
+ params.push(options.limit);
247
+ }
248
+ const result = await this.db.query(query, params);
249
+ return result.rowCount ?? 0;
250
+ }
251
+ async heartbeat(jobId, workerId) {
252
+ if (!this.db) throw new Error("Store not initialized");
253
+ await this.db.query(
254
+ `
255
+ UPDATE ${this.tableName}
256
+ SET worker_heartbeat = ?, updated_at = ?
257
+ WHERE id = ? AND worker_id = ? AND status = 'running'
258
+ `,
259
+ [(/* @__PURE__ */ new Date()).toISOString(), (/* @__PURE__ */ new Date()).toISOString(), jobId, workerId]
260
+ );
261
+ }
262
+ async stats(queue) {
263
+ if (!this.db) throw new Error("Store not initialized");
264
+ const queueFilter = queue ? "WHERE queue = ?" : "";
265
+ const params = queue ? [queue] : [];
266
+ const { rows: countRows } = await this.db.query(
267
+ `
268
+ SELECT status, COUNT(*) as count
269
+ FROM ${this.tableName}
270
+ ${queueFilter}
271
+ GROUP BY status
272
+ `,
273
+ params
274
+ );
275
+ const counts = {};
276
+ for (const row of countRows) {
277
+ counts[row.status] = row.count;
278
+ }
279
+ const { rows: durationRows } = await this.db.query(
280
+ `
281
+ SELECT AVG(
282
+ (julianday(completed_at) - julianday(started_at)) * 86400000
283
+ ) as avg_duration
284
+ FROM ${this.tableName}
285
+ WHERE status = 'completed'
286
+ AND started_at IS NOT NULL
287
+ AND completed_at IS NOT NULL
288
+ ${queue ? "AND queue = ?" : ""}
289
+ `,
290
+ params
291
+ );
292
+ const avgDuration = durationRows[0]?.avg_duration ?? null;
293
+ return {
294
+ pending: counts["pending"] ?? 0,
295
+ running: counts["running"] ?? 0,
296
+ completed: counts["completed"] ?? 0,
297
+ failed: counts["failed"] ?? 0,
298
+ cancelled: counts["cancelled"] ?? 0,
299
+ avgDuration: avgDuration ? Math.round(avgDuration) : null
300
+ };
301
+ }
302
+ async close() {
303
+ if (this.db && !this.externalDb) {
304
+ await this.db.close?.();
305
+ }
306
+ this.db = null;
307
+ this.initialized = false;
308
+ }
309
+ async waitForUpdate(timeoutMs) {
310
+ if (!this.db?.notifications) {
311
+ if (timeoutMs && timeoutMs > 0) {
312
+ await new Promise((resolve) => setTimeout(resolve, timeoutMs));
313
+ }
314
+ return false;
315
+ }
316
+ return this.db.notifications.waitForUpdate({ timeoutMs });
317
+ }
318
+ }
319
+ export {
320
+ SqliteJobStore,
321
+ SqliteJobStore as default
322
+ };
323
+ //# sourceMappingURL=sqlite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite.js","sources":["../../src/adapters/sqlite.ts"],"sourcesContent":["import {\n type DatabaseInterface,\n getDatabase,\n type SqliteCapabilitiesOptions,\n syncSchema,\n} from '@happyvertical/sql';\nimport { BaseJobStore, validateTableName } from '../base-store.js';\nimport type {\n CleanupOptions,\n Job,\n JobCreateOptions,\n JobFilter,\n QueueStats,\n} from '../types.js';\n\n/**\n * SQLite job store configuration\n */\nexport interface SqliteJobStoreConfig {\n /** Database URL or path (default: ':memory:') */\n url?: string;\n /** Existing database instance to use */\n db?: DatabaseInterface;\n /** Table name for jobs (default: '_jobs') */\n tableName?: string;\n /** Optional SQLite native capabilities for development/test modes */\n capabilities?: SqliteCapabilitiesOptions;\n}\n\n/**\n * SQLite-based job store\n *\n * Uses SQLite for job persistence. Supports polling-based job retrieval.\n * Good for single-instance deployments or development.\n */\nexport class SqliteJobStore extends BaseJobStore {\n private db: DatabaseInterface | null = null;\n private readonly url: string;\n private readonly externalDb: DatabaseInterface | null;\n private readonly tableName: string;\n private readonly capabilities: SqliteCapabilitiesOptions | undefined;\n\n constructor(config: SqliteJobStoreConfig = {}) {\n super();\n this.url = config.url ?? ':memory:';\n this.externalDb = config.db ?? null;\n this.tableName = validateTableName(config.tableName ?? '_jobs');\n this.capabilities = config.capabilities;\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // Use existing database or create new one\n this.db =\n this.externalDb ??\n (await getDatabase({\n type: 'sqlite',\n url: this.url,\n capabilities: this.capabilities,\n }));\n\n // Create jobs table and indexes using syncSchema\n const schema = `\n CREATE TABLE IF NOT EXISTS \"${this.tableName}\" (\n id TEXT PRIMARY KEY,\n queue TEXT NOT NULL DEFAULT 'default',\n payload TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'pending',\n priority INTEGER NOT NULL DEFAULT 50,\n attempts INTEGER NOT NULL DEFAULT 0,\n max_attempts INTEGER NOT NULL DEFAULT 3,\n run_at TEXT NOT NULL,\n started_at TEXT,\n completed_at TEXT,\n timeout INTEGER NOT NULL DEFAULT 300000,\n timeout_behavior TEXT NOT NULL DEFAULT 'fail',\n last_error TEXT,\n result_pointer TEXT,\n retry_strategy TEXT NOT NULL,\n worker_id TEXT,\n worker_heartbeat TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n );\n\n CREATE INDEX IF NOT EXISTS \"idx_${this.tableName}_status_queue\" ON \"${this.tableName}\" (status, queue, run_at, priority DESC);\n CREATE INDEX IF NOT EXISTS \"idx_${this.tableName}_created_at\" ON \"${this.tableName}\" (created_at);\n CREATE INDEX IF NOT EXISTS \"idx_${this.tableName}_queue\" ON \"${this.tableName}\" (queue);\n `;\n\n await syncSchema({ db: this.db, schema });\n\n this.initialized = true;\n }\n\n async enqueue(options: JobCreateOptions): Promise<Job> {\n if (!this.db) throw new Error('Store not initialized');\n\n const job = this.createJobRecord(options);\n\n await this.db.insert(this.tableName, {\n id: job.id,\n queue: job.queue,\n payload: JSON.stringify(job.payload),\n status: job.status,\n priority: job.priority,\n attempts: job.attempts,\n max_attempts: job.maxAttempts,\n run_at: job.runAt.toISOString(),\n started_at: job.startedAt?.toISOString() ?? null,\n completed_at: job.completedAt?.toISOString() ?? null,\n timeout: job.timeout,\n timeout_behavior: job.timeoutBehavior,\n last_error: job.lastError,\n result_pointer: job.resultPointer,\n retry_strategy: JSON.stringify(job.retryStrategy),\n worker_id: job.workerId,\n worker_heartbeat: job.workerHeartbeat?.toISOString() ?? null,\n created_at: job.createdAt.toISOString(),\n updated_at: job.updatedAt.toISOString(),\n });\n\n await this.emitEvent('job.created', job);\n\n // Also emit ready if job should run immediately\n if (job.runAt <= new Date()) {\n await this.emitEvent('job.ready', job);\n }\n\n return job;\n }\n\n async dequeue(\n queues: string[],\n limit: number,\n workerId: string,\n ): Promise<Job[]> {\n if (!this.db) throw new Error('Store not initialized');\n\n const now = new Date().toISOString();\n const queuePlaceholders = queues.map(() => '?').join(', ');\n\n // Find jobs ready to process\n const { rows } = await this.db.query(\n `\n SELECT * FROM ${this.tableName}\n WHERE status = 'pending'\n AND queue IN (${queuePlaceholders})\n AND run_at <= ?\n ORDER BY priority DESC, run_at ASC\n LIMIT ?\n `,\n [...queues, now, limit],\n );\n\n if (!rows.length) return [];\n\n // Claim the jobs by updating their status\n const jobIds = rows.map((r) => r.id as string);\n const idPlaceholders = jobIds.map(() => '?').join(', ');\n\n await this.db.query(\n `\n UPDATE ${this.tableName}\n SET status = 'running',\n worker_id = ?,\n worker_heartbeat = ?,\n started_at = ?,\n attempts = attempts + 1,\n updated_at = ?\n WHERE id IN (${idPlaceholders})\n AND status = 'pending'\n `,\n [workerId, now, now, now, ...jobIds],\n );\n\n // Return the claimed jobs\n const jobs = rows.map((row) => {\n const job = this.parseJobRow(row as Record<string, unknown>);\n job.status = 'running';\n job.workerId = workerId;\n job.workerHeartbeat = new Date();\n job.startedAt = new Date();\n job.attempts += 1;\n return job;\n });\n\n // Emit started events\n for (const job of jobs) {\n await this.emitEvent('job.started', job);\n }\n\n return jobs;\n }\n\n async update(id: string, updates: Partial<Job>): Promise<Job> {\n if (!this.db) throw new Error('Store not initialized');\n\n const setClause: string[] = [];\n const params: unknown[] = [];\n\n // Map Job fields to database columns\n const fieldMap: Record<string, string> = {\n queue: 'queue',\n payload: 'payload',\n status: 'status',\n priority: 'priority',\n attempts: 'attempts',\n maxAttempts: 'max_attempts',\n runAt: 'run_at',\n startedAt: 'started_at',\n completedAt: 'completed_at',\n timeout: 'timeout',\n timeoutBehavior: 'timeout_behavior',\n lastError: 'last_error',\n resultPointer: 'result_pointer',\n retryStrategy: 'retry_strategy',\n workerId: 'worker_id',\n workerHeartbeat: 'worker_heartbeat',\n };\n\n for (const [key, value] of Object.entries(updates)) {\n const column = fieldMap[key];\n if (!column) continue;\n\n setClause.push(`${column} = ?`);\n\n if (value instanceof Date) {\n params.push(value.toISOString());\n } else if (typeof value === 'object' && value !== null) {\n params.push(JSON.stringify(value));\n } else {\n params.push(value);\n }\n }\n\n if (setClause.length === 0) {\n const job = await this.get(id);\n if (!job) throw new Error(`Job not found: ${id}`);\n return job;\n }\n\n // Always update updated_at\n setClause.push('updated_at = ?');\n params.push(new Date().toISOString());\n\n params.push(id);\n\n await this.db.query(\n `UPDATE ${this.tableName} SET ${setClause.join(', ')} WHERE id = ?`,\n params,\n );\n\n const job = await this.get(id);\n if (!job) throw new Error(`Job not found after update: ${id}`);\n\n // Emit events based on status changes\n if (updates.status === 'completed') {\n await this.emitEvent('job.completed', job, {\n resultPointer: job.resultPointer ?? undefined,\n });\n } else if (updates.status === 'failed') {\n await this.emitEvent('job.failed', job, {\n error: job.lastError ?? undefined,\n });\n } else if (updates.status === 'cancelled') {\n await this.emitEvent('job.cancelled', job);\n }\n\n return job;\n }\n\n async get(id: string): Promise<Job | null> {\n if (!this.db) throw new Error('Store not initialized');\n\n const row = await this.db.get(this.tableName, { id });\n if (!row) return null;\n\n return this.parseJobRow(row as Record<string, unknown>);\n }\n\n async list(filter: JobFilter): Promise<Job[]> {\n if (!this.db) throw new Error('Store not initialized');\n\n const { where, params: whereParams } = this.buildFilterWhere(filter);\n const orderBy = this.buildOrderBy(filter);\n const { clause: limitOffset, params: limitParams } =\n this.buildLimitOffset(filter);\n\n const { rows } = await this.db.query(\n `SELECT * FROM ${this.tableName} ${where} ${orderBy} ${limitOffset}`,\n [...whereParams, ...limitParams],\n );\n\n return rows.map((row) => this.parseJobRow(row as Record<string, unknown>));\n }\n\n async cancel(id: string): Promise<void> {\n if (!this.db) throw new Error('Store not initialized');\n\n const job = await this.get(id);\n if (!job) throw new Error(`Job not found: ${id}`);\n\n if (job.status === 'completed' || job.status === 'cancelled') {\n throw new Error(`Cannot cancel job with status: ${job.status}`);\n }\n\n await this.update(id, {\n status: 'cancelled',\n completedAt: new Date(),\n });\n }\n\n async cleanup(options: CleanupOptions): Promise<number> {\n if (!this.db) throw new Error('Store not initialized');\n\n const conditions: string[] = [];\n const params: unknown[] = [];\n\n if (options.completedBefore) {\n conditions.push(\"(status = 'completed' AND completed_at < ?)\");\n params.push(options.completedBefore.toISOString());\n }\n\n if (options.failedBefore) {\n conditions.push(\"(status = 'failed' AND completed_at < ?)\");\n params.push(options.failedBefore.toISOString());\n }\n\n if (options.cancelledBefore) {\n conditions.push(\"(status = 'cancelled' AND completed_at < ?)\");\n params.push(options.cancelledBefore.toISOString());\n }\n\n if (conditions.length === 0) return 0;\n\n let query = `DELETE FROM ${this.tableName} WHERE (${conditions.join(' OR ')})`;\n\n if (options.limit) {\n // SQLite doesn't support LIMIT in DELETE directly, so we need a subquery\n query = `\n DELETE FROM ${this.tableName}\n WHERE id IN (\n SELECT id FROM ${this.tableName}\n WHERE (${conditions.join(' OR ')})\n LIMIT ?\n )\n `;\n params.push(options.limit);\n }\n\n const result = await this.db.query(query, params);\n\n return result.rowCount ?? 0;\n }\n\n async heartbeat(jobId: string, workerId: string): Promise<void> {\n if (!this.db) throw new Error('Store not initialized');\n\n await this.db.query(\n `\n UPDATE ${this.tableName}\n SET worker_heartbeat = ?, updated_at = ?\n WHERE id = ? AND worker_id = ? AND status = 'running'\n `,\n [new Date().toISOString(), new Date().toISOString(), jobId, workerId],\n );\n }\n\n async stats(queue?: string): Promise<QueueStats> {\n if (!this.db) throw new Error('Store not initialized');\n\n const queueFilter = queue ? 'WHERE queue = ?' : '';\n const params = queue ? [queue] : [];\n\n // Get status counts\n const { rows: countRows } = await this.db.query(\n `\n SELECT status, COUNT(*) as count\n FROM ${this.tableName}\n ${queueFilter}\n GROUP BY status\n `,\n params,\n );\n\n const counts: Record<string, number> = {};\n for (const row of countRows) {\n counts[row.status as string] = row.count as number;\n }\n\n // Get average duration for completed jobs\n const { rows: durationRows } = await this.db.query(\n `\n SELECT AVG(\n (julianday(completed_at) - julianday(started_at)) * 86400000\n ) as avg_duration\n FROM ${this.tableName}\n WHERE status = 'completed'\n AND started_at IS NOT NULL\n AND completed_at IS NOT NULL\n ${queue ? 'AND queue = ?' : ''}\n `,\n params,\n );\n\n const avgDuration =\n (durationRows[0] as { avg_duration: number | null })?.avg_duration ??\n null;\n\n return {\n pending: counts['pending'] ?? 0,\n running: counts['running'] ?? 0,\n completed: counts['completed'] ?? 0,\n failed: counts['failed'] ?? 0,\n cancelled: counts['cancelled'] ?? 0,\n avgDuration: avgDuration ? Math.round(avgDuration) : null,\n };\n }\n\n async close(): Promise<void> {\n if (this.db && !this.externalDb) {\n await this.db.close?.();\n }\n this.db = null;\n this.initialized = false;\n }\n\n async waitForUpdate(timeoutMs?: number): Promise<boolean> {\n if (!this.db?.notifications) {\n if (timeoutMs && timeoutMs > 0) {\n await new Promise((resolve) => setTimeout(resolve, timeoutMs));\n }\n return false;\n }\n\n return this.db.notifications.waitForUpdate({ timeoutMs });\n }\n}\n\nexport default SqliteJobStore;\n"],"names":["job"],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ import { BaseJobStore } from '../base-store.js';
2
+ import { CleanupOptions, Job, JobCreateOptions, JobFilter, QueueStats } from '../types.js';
3
+ /**
4
+ * AWS credentials configuration
5
+ */
6
+ export interface AWSCredentials {
7
+ accessKeyId: string;
8
+ secretAccessKey: string;
9
+ sessionToken?: string;
10
+ }
11
+ /**
12
+ * SQS adapter configuration
13
+ */
14
+ export interface SQSJobStoreConfig {
15
+ /** AWS region */
16
+ region?: string;
17
+ /** AWS credentials (optional - uses default chain if not provided) */
18
+ credentials?: AWSCredentials;
19
+ /** Queue URL prefix (queues will be named {prefix}{queueName}) */
20
+ queueUrlPrefix: string;
21
+ /** Default visibility timeout in seconds */
22
+ visibilityTimeout?: number;
23
+ /** Message retention in days (1-14, default: 4) */
24
+ messageRetentionDays?: number;
25
+ /** Use FIFO queues for ordering guarantees */
26
+ useFifo?: boolean;
27
+ }
28
+ /**
29
+ * SQS-based job store implementation
30
+ *
31
+ * Note: SQS has limitations that make some operations different:
32
+ * - `update()` throws error (messages are immutable)
33
+ * - `list()` only returns pending jobs from SQS
34
+ * - `cancel()` requires the job to have been dequeued first
35
+ * - For full job tracking, consider using DynamoDB alongside SQS
36
+ */
37
+ export declare class SQSJobStore extends BaseJobStore {
38
+ private config;
39
+ private client;
40
+ private awsSdkModule;
41
+ private queueUrls;
42
+ private jobStates;
43
+ constructor(config: SQSJobStoreConfig);
44
+ /**
45
+ * Initialize the store - dynamically imports AWS SDK
46
+ */
47
+ initialize(): Promise<void>;
48
+ /**
49
+ * Get or create queue URL for a queue name
50
+ */
51
+ private getQueueUrl;
52
+ /**
53
+ * Convert SQS message to Job format
54
+ */
55
+ private sqsMessageToJob;
56
+ /**
57
+ * Enqueue a new job
58
+ */
59
+ enqueue(options: JobCreateOptions): Promise<Job>;
60
+ /**
61
+ * Dequeue jobs ready for processing
62
+ */
63
+ dequeue(queues: string[], limit: number, workerId: string): Promise<Job[]>;
64
+ /**
65
+ * Update a job - NOT SUPPORTED in SQS (messages are immutable)
66
+ */
67
+ update(_id: string, _updates: Partial<Job>): Promise<Job>;
68
+ /**
69
+ * Get a job by ID (from in-memory state only)
70
+ */
71
+ get(id: string): Promise<Job | null>;
72
+ /**
73
+ * List jobs with filtering
74
+ * Note: SQS doesn't support efficient listing - this only returns in-memory state
75
+ */
76
+ list(filter: JobFilter): Promise<Job[]>;
77
+ /**
78
+ * Cancel a job by deleting its message from SQS
79
+ */
80
+ cancel(id: string): Promise<void>;
81
+ /**
82
+ * Mark job as completed
83
+ */
84
+ markCompleted(id: string, resultPointer?: string): Promise<void>;
85
+ /**
86
+ * Mark job as failed
87
+ */
88
+ markFailed(id: string, error: string): Promise<void>;
89
+ /**
90
+ * Clean up old jobs from in-memory state
91
+ * Note: SQS handles message retention automatically
92
+ */
93
+ cleanup(options: CleanupOptions): Promise<number>;
94
+ /**
95
+ * Update visibility timeout for a job (extends processing time)
96
+ */
97
+ heartbeat(jobId: string, _workerId: string): Promise<void>;
98
+ /**
99
+ * Get queue statistics
100
+ */
101
+ stats(queue?: string): Promise<QueueStats>;
102
+ /**
103
+ * Close the SQS client
104
+ */
105
+ close(): Promise<void>;
106
+ }
107
+ /**
108
+ * Create an SQS job store instance
109
+ */
110
+ export declare function createSQSJobStore(config: SQSJobStoreConfig): SQSJobStore;
111
+ export default SQSJobStore;
112
+ //# sourceMappingURL=sqs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqs.d.ts","sourceRoot":"","sources":["../../src/adapters/sqs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;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,cAAc;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,iBAAiB;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,sEAAsE;IACtE,WAAW,CAAC,EAAE,cAAc,CAAC;IAC7B,kEAAkE;IAClE,cAAc,EAAE,MAAM,CAAC;IACvB,4CAA4C;IAC5C,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,mDAAmD;IACnD,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,8CAA8C;IAC9C,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AA0BD;;;;;;;;GAQG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,MAAM,CAA8B;IAE5C,OAAO,CAAC,YAAY,CAAqD;IACzE,OAAO,CAAC,SAAS,CAAkC;IAEnD,OAAO,CAAC,SAAS,CAAoC;gBAEzC,MAAM,EAAE,iBAAiB;IAUrC;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoBjC;;OAEG;IACH,OAAO,CAAC,WAAW;IAWnB;;OAEG;IACH,OAAO,CAAC,eAAe;IAiDvB;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,GAAG,CAAC;IAoFtD;;OAEG;IACG,OAAO,CACX,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,GAAG,EAAE,CAAC;IAwCjB;;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;IAK1C;;;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;IA+BvC;;OAEG;IACG,aAAa,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BtE;;OAEG;IACG,UAAU,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB1D;;;OAGG;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;IAuBhE;;OAEG;IACG,KAAK,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAwChD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAS7B;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,iBAAiB,GAAG,WAAW,CAExE;AAED,eAAe,WAAW,CAAC"}