light-async-queue 1.1.0 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/README.md +314 -30
  2. package/dist/src/constants.d.ts +24 -5
  3. package/dist/src/constants.d.ts.map +1 -1
  4. package/dist/src/constants.js +20 -0
  5. package/dist/src/constants.js.map +1 -1
  6. package/dist/src/dashboard/Dashboard.d.ts +70 -0
  7. package/dist/src/dashboard/Dashboard.d.ts.map +1 -0
  8. package/dist/src/dashboard/Dashboard.js +308 -0
  9. package/dist/src/dashboard/Dashboard.js.map +1 -0
  10. package/dist/src/dashboard/index.d.ts +3 -0
  11. package/dist/src/dashboard/index.d.ts.map +1 -0
  12. package/dist/src/dashboard/index.js +2 -0
  13. package/dist/src/dashboard/index.js.map +1 -0
  14. package/dist/src/index.d.ts +13 -2
  15. package/dist/src/index.d.ts.map +1 -1
  16. package/dist/src/index.js +11 -1
  17. package/dist/src/index.js.map +1 -1
  18. package/dist/src/queue/Job.d.ts +35 -4
  19. package/dist/src/queue/Job.d.ts.map +1 -1
  20. package/dist/src/queue/Job.js +92 -8
  21. package/dist/src/queue/Job.js.map +1 -1
  22. package/dist/src/queue/Queue.d.ts +73 -3
  23. package/dist/src/queue/Queue.d.ts.map +1 -1
  24. package/dist/src/queue/Queue.js +357 -35
  25. package/dist/src/queue/Queue.js.map +1 -1
  26. package/dist/src/queue/Scheduler.d.ts.map +1 -1
  27. package/dist/src/queue/Scheduler.js +8 -1
  28. package/dist/src/queue/Scheduler.js.map +1 -1
  29. package/dist/src/types.d.ts +79 -5
  30. package/dist/src/types.d.ts.map +1 -1
  31. package/dist/src/types.js +1 -1
  32. package/dist/src/types.js.map +1 -1
  33. package/dist/src/utils/CronParser.d.ts +12 -0
  34. package/dist/src/utils/CronParser.d.ts.map +1 -0
  35. package/dist/src/utils/CronParser.js +28 -0
  36. package/dist/src/utils/CronParser.js.map +1 -0
  37. package/dist/src/utils/RateLimiter.d.ts +37 -0
  38. package/dist/src/utils/RateLimiter.d.ts.map +1 -0
  39. package/dist/src/utils/RateLimiter.js +68 -0
  40. package/dist/src/utils/RateLimiter.js.map +1 -0
  41. package/dist/src/utils/WebhookManager.d.ts +29 -0
  42. package/dist/src/utils/WebhookManager.d.ts.map +1 -0
  43. package/dist/src/utils/WebhookManager.js +82 -0
  44. package/dist/src/utils/WebhookManager.js.map +1 -0
  45. package/dist/src/worker/Worker.d.ts +2 -2
  46. package/dist/src/worker/Worker.d.ts.map +1 -1
  47. package/dist/src/worker/Worker.js +57 -36
  48. package/dist/src/worker/Worker.js.map +1 -1
  49. package/dist/src/worker/childProcessor.js +17 -1
  50. package/dist/src/worker/childProcessor.js.map +1 -1
  51. package/package.json +27 -5
@@ -0,0 +1,308 @@
1
+ import { createServer } from "http";
2
+ import { readFileSync } from "node:fs";
3
+ import { resolve } from "node:path";
4
+ import { WebSocketServer, WebSocket } from "ws";
5
+ import { JobStatus } from "../constants.js";
6
+ export class Dashboard {
7
+ queue;
8
+ server;
9
+ wss;
10
+ updateInterval = null;
11
+ config;
12
+ clients = new Set();
13
+ htmlTemplate;
14
+ constructor(queue, config) {
15
+ this.queue = queue;
16
+ this.config = {
17
+ ...config,
18
+ updateInterval: config.updateInterval || 1000,
19
+ };
20
+ this.htmlTemplate = this.loadTemplate();
21
+ // Create HTTP server
22
+ this.server = createServer((req, res) => {
23
+ this.handleRequest(req, res);
24
+ });
25
+ // Create WebSocket server
26
+ this.wss = new WebSocketServer({ server: this.server });
27
+ this.setupWebSocketHandlers();
28
+ }
29
+ /**
30
+ * Start the dashboard server
31
+ */
32
+ async start() {
33
+ return new Promise((resolve) => {
34
+ const host = this.config.host || "localhost";
35
+ this.server.listen(this.config.port, host, () => {
36
+ console.log(`[Dashboard] Queue dashboard running at http://${host}:${this.config.port}`);
37
+ this.startUpdateInterval();
38
+ resolve();
39
+ });
40
+ });
41
+ }
42
+ /**
43
+ * Stop the dashboard server
44
+ */
45
+ async stop() {
46
+ if (this.updateInterval) {
47
+ clearInterval(this.updateInterval);
48
+ }
49
+ // Close all WebSocket connections
50
+ for (const client of this.clients) {
51
+ client.close();
52
+ }
53
+ return new Promise((resolve) => {
54
+ this.server.close(() => {
55
+ console.log("[Dashboard] Dashboard server stopped");
56
+ resolve();
57
+ });
58
+ });
59
+ }
60
+ /**
61
+ * Handle HTTP requests
62
+ */
63
+ handleRequest(req, res) {
64
+ if (req.url === "/" || req.url === "/index.html") {
65
+ this.serveHTML(res);
66
+ }
67
+ else if (req.url === "/api/stats") {
68
+ this.serveStats(res);
69
+ }
70
+ else if (req.url === "/api/jobs") {
71
+ this.serveJobs(res);
72
+ }
73
+ else if (req.url === "/api/failed-jobs") {
74
+ this.serveFailedJobs(res);
75
+ }
76
+ else if (req.url === "/api/reprocess-failed" && req.method === "POST") {
77
+ this.handleReprocessFailed(req, res);
78
+ }
79
+ else {
80
+ res.writeHead(404, { "Content-Type": "application/json" });
81
+ res.end(JSON.stringify({ error: "Not found" }));
82
+ }
83
+ }
84
+ /**
85
+ * Serve the HTML dashboard
86
+ */
87
+ serveHTML(res) {
88
+ const html = this.generateHTML();
89
+ res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
90
+ res.end(html);
91
+ }
92
+ /**
93
+ * Generate HTML dashboard
94
+ */
95
+ generateHTML() {
96
+ return this.htmlTemplate;
97
+ }
98
+ loadTemplate() {
99
+ const templatePath = resolve(process.cwd(), "src", "dashboard", "dashboard.html");
100
+ return readFileSync(templatePath, "utf8");
101
+ }
102
+ /**
103
+ * Setup WebSocket handlers
104
+ */
105
+ setupWebSocketHandlers() {
106
+ this.wss.on("connection", (ws) => {
107
+ console.log("[Dashboard] New WebSocket client connected");
108
+ this.clients.add(ws);
109
+ // Send initial data
110
+ this.sendStatsToClient(ws).catch((error) => {
111
+ console.error("[Dashboard] Error sending initial stats:", error);
112
+ });
113
+ ws.on("message", (message) => {
114
+ try {
115
+ const data = JSON.parse(message);
116
+ if (data.action === "getUpdate") {
117
+ this.sendStatsToClient(ws).catch((error) => {
118
+ console.error("[Dashboard] Error sending stats:", error);
119
+ });
120
+ }
121
+ }
122
+ catch (error) {
123
+ console.error("[Dashboard] Error parsing message:", error);
124
+ }
125
+ });
126
+ ws.on("close", () => {
127
+ console.log("[Dashboard] WebSocket client disconnected");
128
+ this.clients.delete(ws);
129
+ });
130
+ ws.on("error", (error) => {
131
+ console.error("[Dashboard] WebSocket error:", error);
132
+ });
133
+ });
134
+ }
135
+ /**
136
+ * Serve stats API
137
+ */
138
+ serveStats(res) {
139
+ this.queue
140
+ .getStats()
141
+ .then((stats) => {
142
+ res.writeHead(200, { "Content-Type": "application/json" });
143
+ res.end(JSON.stringify({
144
+ stats,
145
+ meta: {
146
+ concurrency: this.queue.getConcurrency(),
147
+ },
148
+ }));
149
+ })
150
+ .catch((error) => {
151
+ console.error("[Dashboard] Error getting stats:", error);
152
+ res.writeHead(500, { "Content-Type": "application/json" });
153
+ res.end(JSON.stringify({ error: "Failed to get stats" }));
154
+ });
155
+ }
156
+ /**
157
+ * Serve jobs list
158
+ */
159
+ serveJobs(res) {
160
+ this.queue
161
+ .getAllJobs()
162
+ .then((jobs) => {
163
+ const filtered = jobs
164
+ .filter((j) => j.status === JobStatus.PROCESSING ||
165
+ j.status === JobStatus.WAITING ||
166
+ j.status === JobStatus.DELAYED ||
167
+ j.status === JobStatus.PENDING ||
168
+ j.status === JobStatus.STALLED)
169
+ .sort((a, b) => b.createdAt - a.createdAt)
170
+ .slice(0, 100);
171
+ res.writeHead(200, { "Content-Type": "application/json" });
172
+ res.end(JSON.stringify(filtered));
173
+ })
174
+ .catch((error) => {
175
+ console.error("[Dashboard] Error getting jobs:", error);
176
+ res.writeHead(500, { "Content-Type": "application/json" });
177
+ res.end(JSON.stringify({ error: "Failed to get jobs" }));
178
+ });
179
+ }
180
+ /**
181
+ * Serve failed jobs
182
+ */
183
+ serveFailedJobs(res) {
184
+ this.queue
185
+ .getFailedJobs()
186
+ .then((failedJobs) => {
187
+ res.writeHead(200, { "Content-Type": "application/json" });
188
+ res.end(JSON.stringify(failedJobs.sort((a, b) => b.updatedAt - a.updatedAt).slice(0, 50)));
189
+ })
190
+ .catch((error) => {
191
+ console.error("[Dashboard] Error getting failed jobs:", error);
192
+ res.writeHead(500, { "Content-Type": "application/json" });
193
+ res.end(JSON.stringify({ error: "Failed to get failed jobs" }));
194
+ });
195
+ }
196
+ /**
197
+ * Handle reprocess failed job request
198
+ */
199
+ handleReprocessFailed(req, res) {
200
+ let body = "";
201
+ req.on("data", (chunk) => {
202
+ body += chunk;
203
+ });
204
+ req.on("end", () => {
205
+ try {
206
+ const data = JSON.parse(body);
207
+ const { jobId } = data;
208
+ this.queue
209
+ .reprocessFailed(jobId)
210
+ .then((success) => {
211
+ res.writeHead(200, { "Content-Type": "application/json" });
212
+ res.end(JSON.stringify({ success }));
213
+ // Broadcast update to all clients
214
+ this.broadcastStats().catch((error) => {
215
+ console.error("[Dashboard] Error broadcasting after reprocess:", error);
216
+ });
217
+ })
218
+ .catch((error) => {
219
+ console.error("[Dashboard] Error reprocessing failed job:", error);
220
+ res.writeHead(500, { "Content-Type": "application/json" });
221
+ res.end(JSON.stringify({ error: "Failed to reprocess job" }));
222
+ });
223
+ }
224
+ catch (error) {
225
+ console.error("[Dashboard] Error parsing reprocess request:", error);
226
+ res.writeHead(400, { "Content-Type": "application/json" });
227
+ res.end(JSON.stringify({ error: "Invalid request" }));
228
+ }
229
+ });
230
+ }
231
+ /**
232
+ * Send stats to a specific client
233
+ */
234
+ async sendStatsToClient(ws) {
235
+ try {
236
+ const stats = await this.queue.getStats();
237
+ const allJobs = await this.queue.getAllJobs();
238
+ const failedJobs = await this.queue.getFailedJobs();
239
+ const jobs = allJobs
240
+ .filter((j) => j.status === JobStatus.PROCESSING ||
241
+ j.status === JobStatus.WAITING ||
242
+ j.status === JobStatus.DELAYED ||
243
+ j.status === JobStatus.PENDING ||
244
+ j.status === JobStatus.STALLED)
245
+ .sort((a, b) => b.createdAt - a.createdAt)
246
+ .slice(0, 100);
247
+ ws.send(JSON.stringify({
248
+ stats,
249
+ jobs,
250
+ failedJobs: failedJobs.slice(0, 50),
251
+ meta: {
252
+ concurrency: this.queue.getConcurrency(),
253
+ },
254
+ }));
255
+ }
256
+ catch (error) {
257
+ console.error("[Dashboard] Error getting data for client:", error);
258
+ }
259
+ }
260
+ /**
261
+ * Broadcast stats to all clients
262
+ */
263
+ async broadcastStats() {
264
+ if (this.clients.size === 0) {
265
+ return;
266
+ }
267
+ try {
268
+ const stats = await this.queue.getStats();
269
+ const allJobs = await this.queue.getAllJobs();
270
+ const failedJobs = await this.queue.getFailedJobs();
271
+ const jobs = allJobs
272
+ .filter((j) => j.status === JobStatus.PROCESSING ||
273
+ j.status === JobStatus.WAITING ||
274
+ j.status === JobStatus.DELAYED ||
275
+ j.status === JobStatus.PENDING ||
276
+ j.status === JobStatus.STALLED)
277
+ .sort((a, b) => b.createdAt - a.createdAt)
278
+ .slice(0, 100);
279
+ const data = JSON.stringify({
280
+ stats,
281
+ jobs,
282
+ failedJobs: failedJobs.slice(0, 50),
283
+ meta: {
284
+ concurrency: this.queue.getConcurrency(),
285
+ },
286
+ });
287
+ for (const client of this.clients) {
288
+ if (client.readyState === WebSocket.OPEN) {
289
+ client.send(data);
290
+ }
291
+ }
292
+ }
293
+ catch (error) {
294
+ console.error("[Dashboard] Error broadcasting stats:", error);
295
+ }
296
+ }
297
+ /**
298
+ * Start periodic update interval
299
+ */
300
+ startUpdateInterval() {
301
+ this.updateInterval = setInterval(() => {
302
+ this.broadcastStats().catch((error) => {
303
+ console.error("[Dashboard] Error in update interval:", error);
304
+ });
305
+ }, this.config.updateInterval || 1000);
306
+ }
307
+ }
308
+ //# sourceMappingURL=Dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Dashboard.js","sourceRoot":"","sources":["../../../src/dashboard/Dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { Dashboard } from './Dashboard.js';
2
+ export type { DashboardConfig } from './Dashboard.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,YAAY,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { Dashboard } from './Dashboard.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
@@ -7,9 +7,20 @@
7
7
  * - Retry with exponential backoff
8
8
  * - Dead letter queue for failed jobs
9
9
  * - Graceful shutdown handling
10
+ * - Job events and progress tracking
11
+ * - Job priorities and dependencies
12
+ * - Repeating jobs with cron support
13
+ * - Rate limiting
14
+ * - Webhooks
15
+ * - HTML Dashboard for monitoring
10
16
  */
11
17
  export { Queue } from './queue/Queue.js';
12
18
  export { Job } from './queue/Job.js';
13
- export type { QueueConfig, JobData, JobProcessor, RetryConfig, BackoffConfig, } from './types.js';
14
- export { JobStatus, BackoffStrategyType, StorageType, WorkerMessageType, WorkerResponseType, WorkerSignalType, } from './types.js';
19
+ export type { QueueConfig, JobData, JobProcessor, JobOptions, RetryConfig, BackoffConfig, RepeatConfig, RateLimiterConfig, WebhookConfig, QueueEvents, JobWithMethods, } from './types.js';
20
+ export { JobStatus, BackoffStrategyType, StorageType, WorkerMessageType, WorkerResponseType, WorkerSignalType, QueueEventType, } from './types.js';
21
+ export { CronParser } from './utils/CronParser.js';
22
+ export { RateLimiter } from './utils/RateLimiter.js';
23
+ export { WebhookManager } from './utils/WebhookManager.js';
24
+ export { Dashboard } from './dashboard/Dashboard.js';
25
+ export type { DashboardConfig } from './dashboard/Dashboard.js';
15
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,YAAY,EACV,WAAW,EACX,OAAO,EACP,YAAY,EACZ,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,YAAY,EACV,WAAW,EACX,OAAO,EACP,YAAY,EACZ,UAAU,EACV,WAAW,EACX,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,WAAW,EACX,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC"}
package/dist/src/index.js CHANGED
@@ -7,8 +7,18 @@
7
7
  * - Retry with exponential backoff
8
8
  * - Dead letter queue for failed jobs
9
9
  * - Graceful shutdown handling
10
+ * - Job events and progress tracking
11
+ * - Job priorities and dependencies
12
+ * - Repeating jobs with cron support
13
+ * - Rate limiting
14
+ * - Webhooks
15
+ * - HTML Dashboard for monitoring
10
16
  */
11
17
  export { Queue } from './queue/Queue.js';
12
18
  export { Job } from './queue/Job.js';
13
- export { JobStatus, BackoffStrategyType, StorageType, WorkerMessageType, WorkerResponseType, WorkerSignalType, } from './types.js';
19
+ export { JobStatus, BackoffStrategyType, StorageType, WorkerMessageType, WorkerResponseType, WorkerSignalType, QueueEventType, } from './types.js';
20
+ export { CronParser } from './utils/CronParser.js';
21
+ export { RateLimiter } from './utils/RateLimiter.js';
22
+ export { WebhookManager } from './utils/WebhookManager.js';
23
+ export { Dashboard } from './dashboard/Dashboard.js';
14
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAQrC,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GACjB,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAcrC,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,WAAW,EACX,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,cAAc,GACf,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC"}
@@ -1,4 +1,4 @@
1
- import { JobData, JobStatus } from '../types.js';
1
+ import { JobData, JobStatus, JobOptions, RepeatConfig } from '../types.js';
2
2
  /**
3
3
  * Job class representing a single unit of work in the queue
4
4
  */
@@ -8,10 +8,21 @@ export declare class Job {
8
8
  attempts: number;
9
9
  maxAttempts: number;
10
10
  status: JobStatus;
11
+ priority: number;
12
+ progress: number;
11
13
  nextRunAt: number;
14
+ delay: number;
15
+ repeatConfig?: RepeatConfig;
16
+ repeatCount: number;
17
+ dependsOn?: string[];
18
+ parentJobId?: string;
19
+ result?: unknown;
20
+ error?: string;
12
21
  readonly createdAt: number;
13
22
  updatedAt: number;
14
- constructor(payload: unknown, maxAttempts: number, nextRunAt?: number);
23
+ startedAt?: number;
24
+ completedAt?: number;
25
+ constructor(payload: unknown, maxAttempts: number, options?: JobOptions);
15
26
  /**
16
27
  * Create a Job instance from stored data
17
28
  */
@@ -27,11 +38,11 @@ export declare class Job {
27
38
  /**
28
39
  * Mark job as completed
29
40
  */
30
- markCompleted(): void;
41
+ markCompleted(result?: unknown): void;
31
42
  /**
32
43
  * Mark job as failed and increment attempts
33
44
  */
34
- markFailed(nextRunAt?: number): void;
45
+ markFailed(error: string, nextRunAt?: number): void;
35
46
  /**
36
47
  * Check if job has exceeded max attempts
37
48
  */
@@ -40,5 +51,25 @@ export declare class Job {
40
51
  * Reset job for reprocessing (used when recovering from DLQ)
41
52
  */
42
53
  reset(): void;
54
+ /**
55
+ * Update job progress
56
+ */
57
+ updateProgress(progress: number): void;
58
+ /**
59
+ * Mark job as stalled
60
+ */
61
+ markStalled(): void;
62
+ /**
63
+ * Check if job is stalled (processing for too long)
64
+ */
65
+ isStalled(stalledThreshold?: number): boolean;
66
+ /**
67
+ * Check if dependencies are satisfied
68
+ */
69
+ areDependenciesSatisfied(completedJobIds: Set<string>): boolean;
70
+ /**
71
+ * Create a repeated instance of this job
72
+ */
73
+ createRepeatInstance(): Job;
43
74
  }
44
75
  //# sourceMappingURL=Job.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"Job.d.ts","sourceRoot":"","sources":["../../../src/queue/Job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGjD;;GAEG;AACH,qBAAa,GAAG;IACd,SAAgB,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IACzB,SAAgB,SAAS,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM;IAYrE;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG;IAMnC;;OAEG;IACH,MAAM,IAAI,OAAO;IAajB;;OAEG;IACH,cAAc,IAAI,IAAI;IAKtB;;OAEG;IACH,aAAa,IAAI,IAAI;IAKrB;;OAEG;IACH,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IASpC;;OAEG;IACH,sBAAsB,IAAI,OAAO;IAIjC;;OAEG;IACH,KAAK,IAAI,IAAI;CAMd"}
1
+ {"version":3,"file":"Job.d.ts","sourceRoot":"","sources":["../../../src/queue/Job.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3E;;GAEG;AACH,qBAAa,GAAG;IACd,SAAgB,EAAE,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,SAAS,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,YAAY,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACtB,SAAgB,SAAS,EAAE,MAAM,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;gBAEhB,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,UAAe;IAkB3E;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,GAAG,GAAG;IAMnC;;OAEG;IACH,MAAM,IAAI,OAAO;IAwBjB;;OAEG;IACH,cAAc,IAAI,IAAI;IAMtB;;OAEG;IACH,aAAa,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAQrC;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;IAUnD;;OAEG;IACH,sBAAsB,IAAI,OAAO;IAIjC;;OAEG;IACH,KAAK,IAAI,IAAI;IAWb;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAKtC;;OAEG;IACH,WAAW,IAAI,IAAI;IAKnB;;OAEG;IACH,SAAS,CAAC,gBAAgB,GAAE,MAAc,GAAG,OAAO;IAOpD;;OAEG;IACH,wBAAwB,CAAC,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO;IAO/D;;OAEG;IACH,oBAAoB,IAAI,GAAG;CAY5B"}
@@ -9,17 +9,34 @@ export class Job {
9
9
  attempts;
10
10
  maxAttempts;
11
11
  status;
12
+ priority;
13
+ progress;
12
14
  nextRunAt;
15
+ delay;
16
+ repeatConfig;
17
+ repeatCount;
18
+ dependsOn;
19
+ parentJobId;
20
+ result;
21
+ error;
13
22
  createdAt;
14
23
  updatedAt;
15
- constructor(payload, maxAttempts, nextRunAt) {
24
+ startedAt;
25
+ completedAt;
26
+ constructor(payload, maxAttempts, options = {}) {
16
27
  const now = Date.now();
17
- this.id = randomUUID();
28
+ this.id = options.jobId || randomUUID();
18
29
  this.payload = payload;
19
30
  this.attempts = 0;
20
31
  this.maxAttempts = maxAttempts;
21
- this.status = JobStatus.PENDING;
22
- this.nextRunAt = nextRunAt ?? now;
32
+ this.status = options.delay ? JobStatus.DELAYED : options.dependsOn?.length ? JobStatus.WAITING : JobStatus.PENDING;
33
+ this.priority = options.priority ?? 0;
34
+ this.progress = 0;
35
+ this.delay = options.delay ?? 0;
36
+ this.nextRunAt = now + (options.delay ?? 0);
37
+ this.repeatConfig = options.repeat;
38
+ this.repeatCount = 0;
39
+ this.dependsOn = options.dependsOn;
23
40
  this.createdAt = now;
24
41
  this.updatedAt = now;
25
42
  }
@@ -41,9 +58,20 @@ export class Job {
41
58
  attempts: this.attempts,
42
59
  maxAttempts: this.maxAttempts,
43
60
  status: this.status,
61
+ priority: this.priority,
62
+ progress: this.progress,
44
63
  nextRunAt: this.nextRunAt,
64
+ delay: this.delay,
65
+ repeatConfig: this.repeatConfig,
66
+ repeatCount: this.repeatCount,
67
+ dependsOn: this.dependsOn,
68
+ parentJobId: this.parentJobId,
69
+ result: this.result,
70
+ error: this.error,
45
71
  createdAt: this.createdAt,
46
72
  updatedAt: this.updatedAt,
73
+ startedAt: this.startedAt,
74
+ completedAt: this.completedAt,
47
75
  };
48
76
  }
49
77
  /**
@@ -51,20 +79,25 @@ export class Job {
51
79
  */
52
80
  markProcessing() {
53
81
  this.status = JobStatus.PROCESSING;
54
- this.updatedAt = Date.now();
82
+ this.startedAt = Date.now();
83
+ this.updatedAt = this.startedAt;
55
84
  }
56
85
  /**
57
86
  * Mark job as completed
58
87
  */
59
- markCompleted() {
88
+ markCompleted(result) {
60
89
  this.status = JobStatus.COMPLETED;
61
- this.updatedAt = Date.now();
90
+ this.result = result;
91
+ this.completedAt = Date.now();
92
+ this.updatedAt = this.completedAt;
93
+ this.progress = 100;
62
94
  }
63
95
  /**
64
96
  * Mark job as failed and increment attempts
65
97
  */
66
- markFailed(nextRunAt) {
98
+ markFailed(error, nextRunAt) {
67
99
  this.attempts += 1;
100
+ this.error = error;
68
101
  this.status = this.attempts >= this.maxAttempts ? JobStatus.FAILED : JobStatus.PENDING;
69
102
  if (nextRunAt !== undefined) {
70
103
  this.nextRunAt = nextRunAt;
@@ -85,6 +118,57 @@ export class Job {
85
118
  this.status = JobStatus.PENDING;
86
119
  this.nextRunAt = Date.now();
87
120
  this.updatedAt = Date.now();
121
+ this.error = undefined;
122
+ this.progress = 0;
123
+ this.startedAt = undefined;
124
+ this.completedAt = undefined;
125
+ }
126
+ /**
127
+ * Update job progress
128
+ */
129
+ updateProgress(progress) {
130
+ this.progress = Math.min(100, Math.max(0, progress));
131
+ this.updatedAt = Date.now();
132
+ }
133
+ /**
134
+ * Mark job as stalled
135
+ */
136
+ markStalled() {
137
+ this.status = JobStatus.STALLED;
138
+ this.updatedAt = Date.now();
139
+ }
140
+ /**
141
+ * Check if job is stalled (processing for too long)
142
+ */
143
+ isStalled(stalledThreshold = 30000) {
144
+ if (this.status !== JobStatus.PROCESSING || !this.startedAt) {
145
+ return false;
146
+ }
147
+ return Date.now() - this.startedAt > stalledThreshold;
148
+ }
149
+ /**
150
+ * Check if dependencies are satisfied
151
+ */
152
+ areDependenciesSatisfied(completedJobIds) {
153
+ if (!this.dependsOn || this.dependsOn.length === 0) {
154
+ return true;
155
+ }
156
+ return this.dependsOn.every(id => completedJobIds.has(id));
157
+ }
158
+ /**
159
+ * Create a repeated instance of this job
160
+ */
161
+ createRepeatInstance() {
162
+ const job = Job.fromData(this.toData());
163
+ job.attempts = 0;
164
+ job.status = JobStatus.PENDING;
165
+ job.repeatCount += 1;
166
+ job.progress = 0;
167
+ job.error = undefined;
168
+ job.result = undefined;
169
+ job.startedAt = undefined;
170
+ job.completedAt = undefined;
171
+ return job;
88
172
  }
89
173
  }
90
174
  //# sourceMappingURL=Job.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Job.js","sourceRoot":"","sources":["../../../src/queue/Job.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Job.js","sourceRoot":"","sources":["../../../src/queue/Job.ts"],"names":[],"mappings":"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"}