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.
- package/README.md +314 -30
- package/dist/src/constants.d.ts +24 -5
- package/dist/src/constants.d.ts.map +1 -1
- package/dist/src/constants.js +20 -0
- package/dist/src/constants.js.map +1 -1
- package/dist/src/dashboard/Dashboard.d.ts +70 -0
- package/dist/src/dashboard/Dashboard.d.ts.map +1 -0
- package/dist/src/dashboard/Dashboard.js +308 -0
- package/dist/src/dashboard/Dashboard.js.map +1 -0
- package/dist/src/dashboard/index.d.ts +3 -0
- package/dist/src/dashboard/index.d.ts.map +1 -0
- package/dist/src/dashboard/index.js +2 -0
- package/dist/src/dashboard/index.js.map +1 -0
- package/dist/src/index.d.ts +13 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +11 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/queue/Job.d.ts +35 -4
- package/dist/src/queue/Job.d.ts.map +1 -1
- package/dist/src/queue/Job.js +92 -8
- package/dist/src/queue/Job.js.map +1 -1
- package/dist/src/queue/Queue.d.ts +73 -3
- package/dist/src/queue/Queue.d.ts.map +1 -1
- package/dist/src/queue/Queue.js +357 -35
- package/dist/src/queue/Queue.js.map +1 -1
- package/dist/src/queue/Scheduler.d.ts.map +1 -1
- package/dist/src/queue/Scheduler.js +8 -1
- package/dist/src/queue/Scheduler.js.map +1 -1
- package/dist/src/types.d.ts +79 -5
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js +1 -1
- package/dist/src/types.js.map +1 -1
- package/dist/src/utils/CronParser.d.ts +12 -0
- package/dist/src/utils/CronParser.d.ts.map +1 -0
- package/dist/src/utils/CronParser.js +28 -0
- package/dist/src/utils/CronParser.js.map +1 -0
- package/dist/src/utils/RateLimiter.d.ts +37 -0
- package/dist/src/utils/RateLimiter.d.ts.map +1 -0
- package/dist/src/utils/RateLimiter.js +68 -0
- package/dist/src/utils/RateLimiter.js.map +1 -0
- package/dist/src/utils/WebhookManager.d.ts +29 -0
- package/dist/src/utils/WebhookManager.d.ts.map +1 -0
- package/dist/src/utils/WebhookManager.js +82 -0
- package/dist/src/utils/WebhookManager.js.map +1 -0
- package/dist/src/worker/Worker.d.ts +2 -2
- package/dist/src/worker/Worker.d.ts.map +1 -1
- package/dist/src/worker/Worker.js +57 -36
- package/dist/src/worker/Worker.js.map +1 -1
- package/dist/src/worker/childProcessor.js +17 -1
- package/dist/src/worker/childProcessor.js.map +1 -1
- package/package.json +27 -5
package/README.md
CHANGED
|
@@ -7,19 +7,41 @@
|
|
|
7
7
|
[](https://nodejs.org)
|
|
8
8
|
[](https://www.typescriptlang.org/)
|
|
9
9
|
|
|
10
|
-
A production-ready, Redis-free async job queue for Node.js with TypeScript.
|
|
10
|
+
A production-ready, **Redis-free** async job queue for Node.js with TypeScript. A powerful BullMQ alternative designed for single-node reliability with file-based persistence, worker process isolation, and enterprise-grade features.
|
|
11
|
+
|
|
12
|
+
## ðĨ Demo Video
|
|
13
|
+
|
|
14
|
+
GitHub README often does not render local `.mp4` files inline. Use the direct raw link:
|
|
15
|
+
|
|
16
|
+
- [âķïļ Watch dashboard demo (streamable MP4)](https://raw.githubusercontent.com/gaikwadakshay79/light-async-queue/main/Light-Async-Queue-Dashboard.mp4)
|
|
17
|
+
- [ð Repo file link](./Light-Async-Queue-Dashboard.mp4)
|
|
11
18
|
|
|
12
19
|
## âĻ Features
|
|
13
20
|
|
|
21
|
+
### Core Features
|
|
22
|
+
|
|
14
23
|
- **ð Reliable Job Processing** - File-based persistence with crash recovery
|
|
15
24
|
- **ð· Worker Isolation** - Jobs execute in separate child processes using `child_process.fork()`
|
|
16
25
|
- **ð Smart Retry Logic** - Exponential backoff with configurable attempts
|
|
17
26
|
- **ð Dead Letter Queue** - Failed jobs are preserved and can be reprocessed
|
|
18
27
|
- **⥠Concurrency Control** - Configurable parallel job execution
|
|
19
28
|
- **ðĄïļ Graceful Shutdown** - Waits for active jobs before exiting
|
|
20
|
-
- **ð Queue Statistics** - Monitor active, pending, completed, and failed jobs
|
|
21
29
|
- **ðŊ TypeScript First** - Full type safety with no `any` types
|
|
22
|
-
- **ðŠķ
|
|
30
|
+
- **ðŠķ Minimal Dependencies** - Only 2 runtime dependencies (`cron-parser`, `ws`)
|
|
31
|
+
|
|
32
|
+
### Advanced Features (BullMQ Compatible)
|
|
33
|
+
|
|
34
|
+
- **ðĒ Job Events** - Listen to waiting, active, completed, failed, progress, stalled events
|
|
35
|
+
- **â° Delayed Jobs** - Schedule jobs to run after a delay
|
|
36
|
+
- **ð Repeating Jobs** - Interval-based and cron-pattern recurring jobs
|
|
37
|
+
- **ðŊ Job Priorities** - High-priority jobs run first
|
|
38
|
+
- **ð Progress Tracking** - Real-time job progress updates
|
|
39
|
+
- **ð Job Dependencies** - Jobs can wait for other jobs to complete
|
|
40
|
+
- **⥠Rate Limiting** - Control job execution rate
|
|
41
|
+
- **ð Webhooks** - HTTP callbacks for job events
|
|
42
|
+
- **âąïļ Stalled Job Detection** - Automatically detect and handle stuck jobs
|
|
43
|
+
- **ð Enhanced Metrics** - Detailed queue statistics by job status
|
|
44
|
+
- **ðĨïļ HTML Dashboard** - Real-time web UI for monitoring (Zookeeper-style)
|
|
23
45
|
|
|
24
46
|
## ðĶ Installation
|
|
25
47
|
|
|
@@ -91,7 +113,11 @@ Create a new queue instance.
|
|
|
91
113
|
**Config Options:**
|
|
92
114
|
|
|
93
115
|
```typescript
|
|
94
|
-
import {
|
|
116
|
+
import {
|
|
117
|
+
StorageType,
|
|
118
|
+
BackoffStrategyType,
|
|
119
|
+
QueueEventType,
|
|
120
|
+
} from "light-async-queue";
|
|
95
121
|
|
|
96
122
|
interface QueueConfig {
|
|
97
123
|
storage: StorageType;
|
|
@@ -104,32 +130,183 @@ interface QueueConfig {
|
|
|
104
130
|
delay: number; // Base delay in ms
|
|
105
131
|
};
|
|
106
132
|
};
|
|
133
|
+
rateLimiter?: {
|
|
134
|
+
max: number; // Max jobs
|
|
135
|
+
duration: number; // Per duration in ms
|
|
136
|
+
};
|
|
137
|
+
webhooks?: Array<{
|
|
138
|
+
url: string;
|
|
139
|
+
events: QueueEventType[];
|
|
140
|
+
headers?: Record<string, string>;
|
|
141
|
+
}>;
|
|
142
|
+
stalledInterval?: number; // Check for stalled jobs every X ms (default: 30000)
|
|
107
143
|
}
|
|
108
144
|
```
|
|
109
145
|
|
|
110
146
|
### `queue.process(processor)`
|
|
111
147
|
|
|
112
|
-
Set the job processor function.
|
|
148
|
+
Set the job processor function with progress tracking support.
|
|
113
149
|
|
|
114
150
|
```typescript
|
|
115
|
-
queue.process(async (job
|
|
116
|
-
//
|
|
117
|
-
|
|
151
|
+
queue.process(async (job) => {
|
|
152
|
+
// Access job data
|
|
153
|
+
console.log(job.payload);
|
|
154
|
+
|
|
155
|
+
// Report progress
|
|
156
|
+
await job.updateProgress(50);
|
|
157
|
+
|
|
158
|
+
// Log messages
|
|
159
|
+
job.log("Processing step 1");
|
|
160
|
+
|
|
161
|
+
// Return result
|
|
162
|
+
return { success: true };
|
|
118
163
|
});
|
|
119
164
|
```
|
|
120
165
|
|
|
121
|
-
### `queue.add(payload)`
|
|
166
|
+
### `queue.add(payload, options?)`
|
|
122
167
|
|
|
123
|
-
Add a job to the queue.
|
|
168
|
+
Add a job to the queue with advanced options.
|
|
124
169
|
|
|
125
170
|
```typescript
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
171
|
+
// Simple job
|
|
172
|
+
const jobId = await queue.add({ userId: 123 });
|
|
173
|
+
|
|
174
|
+
// Job with priority (higher = more important)
|
|
175
|
+
await queue.add({ urgent: true }, { priority: 10 });
|
|
176
|
+
|
|
177
|
+
// Delayed job (runs after delay)
|
|
178
|
+
await queue.add({ task: "cleanup" }, { delay: 5000 });
|
|
179
|
+
|
|
180
|
+
// Repeating job (every X milliseconds)
|
|
181
|
+
await queue.add(
|
|
182
|
+
{ type: "heartbeat" },
|
|
183
|
+
{
|
|
184
|
+
repeat: {
|
|
185
|
+
every: 60000, // Every minute
|
|
186
|
+
limit: 100, // Max 100 repetitions
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
// Cron-style repeating job
|
|
192
|
+
await queue.add(
|
|
193
|
+
{ type: "daily-report" },
|
|
194
|
+
{
|
|
195
|
+
repeat: {
|
|
196
|
+
pattern: "0 0 * * *", // Every day at midnight
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
// Job with dependencies
|
|
202
|
+
const job1 = await queue.add({ step: 1 });
|
|
203
|
+
await queue.add({ step: 2 }, { dependsOn: [job1] });
|
|
204
|
+
|
|
205
|
+
// Custom job ID
|
|
206
|
+
await queue.add({ data: "test" }, { jobId: "custom-id-123" });
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### Queue Events
|
|
210
|
+
|
|
211
|
+
Listen to job lifecycle events:
|
|
212
|
+
|
|
213
|
+
```typescript
|
|
214
|
+
import { QueueEventType } from "light-async-queue";
|
|
215
|
+
|
|
216
|
+
queue.on(QueueEventType.WAITING, (job) => {
|
|
217
|
+
console.log("Job waiting for dependencies:", job.id);
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
queue.on(QueueEventType.DELAYED, (job) => {
|
|
221
|
+
console.log("Job delayed until:", new Date(job.nextRunAt));
|
|
222
|
+
});
|
|
223
|
+
|
|
224
|
+
queue.on(QueueEventType.ACTIVE, (job) => {
|
|
225
|
+
console.log("Job started:", job.id);
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
queue.on(QueueEventType.PROGRESS, (job, progress) => {
|
|
229
|
+
console.log(`Job ${job.id} progress: ${progress}%`);
|
|
230
|
+
});
|
|
231
|
+
|
|
232
|
+
queue.on(QueueEventType.COMPLETED, (job, result) => {
|
|
233
|
+
console.log("Job completed:", job.id, result);
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
queue.on(QueueEventType.FAILED, (job, error) => {
|
|
237
|
+
console.error("Job failed:", job.id, error.message);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
queue.on(QueueEventType.STALLED, (job) => {
|
|
241
|
+
console.warn("Job appears stalled:", job.id);
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
queue.on(QueueEventType.DRAINED, () => {
|
|
245
|
+
console.log("Queue drained - all jobs processed");
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
queue.on(QueueEventType.ERROR, (error) => {
|
|
249
|
+
console.error("Queue error:", error);
|
|
129
250
|
});
|
|
130
251
|
```
|
|
131
252
|
|
|
132
|
-
###
|
|
253
|
+
### Queue Methods
|
|
254
|
+
|
|
255
|
+
#### `queue.getJob(jobId)`
|
|
256
|
+
|
|
257
|
+
Get a specific job by ID.
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
const job = await queue.getJob("job-id-123");
|
|
261
|
+
if (job) {
|
|
262
|
+
console.log(job.status, job.progress);
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
#### `queue.removeJob(jobId)`
|
|
267
|
+
|
|
268
|
+
Remove a specific job (only if not currently active).
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
const removed = await queue.removeJob("job-id-123");
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
#### `queue.pause()`
|
|
275
|
+
|
|
276
|
+
Pause job processing.
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
queue.pause();
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
#### `queue.resume()`
|
|
283
|
+
|
|
284
|
+
Resume job processing.
|
|
285
|
+
|
|
286
|
+
```typescript
|
|
287
|
+
queue.resume();
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
#### `queue.drain()`
|
|
291
|
+
|
|
292
|
+
Wait for all pending jobs to be processed.
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
await queue.drain();
|
|
296
|
+
console.log("All jobs completed!");
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
#### `queue.clean(maxAge)`
|
|
300
|
+
|
|
301
|
+
Remove completed jobs older than maxAge (in milliseconds).
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
// Clean jobs older than 24 hours
|
|
305
|
+
const cleaned = await queue.clean(24 * 60 * 60 * 1000);
|
|
306
|
+
console.log(`Cleaned ${cleaned} old jobs`);
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
#### `queue.getFailedJobs()`
|
|
133
310
|
|
|
134
311
|
Get all jobs in the Dead Letter Queue.
|
|
135
312
|
|
|
@@ -137,7 +314,7 @@ Get all jobs in the Dead Letter Queue.
|
|
|
137
314
|
const failedJobs = await queue.getFailedJobs();
|
|
138
315
|
```
|
|
139
316
|
|
|
140
|
-
|
|
317
|
+
#### `queue.reprocessFailed(jobId)`
|
|
141
318
|
|
|
142
319
|
Reprocess a failed job from the DLQ.
|
|
143
320
|
|
|
@@ -145,21 +322,24 @@ Reprocess a failed job from the DLQ.
|
|
|
145
322
|
await queue.reprocessFailed("job-id-here");
|
|
146
323
|
```
|
|
147
324
|
|
|
148
|
-
|
|
325
|
+
#### `queue.getStats()`
|
|
149
326
|
|
|
150
|
-
Get queue statistics.
|
|
327
|
+
Get enhanced queue statistics.
|
|
151
328
|
|
|
152
329
|
```typescript
|
|
153
330
|
const stats = await queue.getStats();
|
|
154
331
|
// {
|
|
155
332
|
// active: 2,
|
|
333
|
+
// waiting: 1,
|
|
334
|
+
// delayed: 3,
|
|
156
335
|
// pending: 5,
|
|
157
336
|
// completed: 100,
|
|
158
|
-
// failed: 3
|
|
337
|
+
// failed: 3,
|
|
338
|
+
// stalled: 0
|
|
159
339
|
// }
|
|
160
340
|
```
|
|
161
341
|
|
|
162
|
-
|
|
342
|
+
#### `queue.shutdown()`
|
|
163
343
|
|
|
164
344
|
Gracefully shutdown the queue.
|
|
165
345
|
|
|
@@ -263,16 +443,103 @@ The queue handles `SIGINT` and `SIGTERM` signals:
|
|
|
263
443
|
await queue.shutdown();
|
|
264
444
|
```
|
|
265
445
|
|
|
266
|
-
##
|
|
446
|
+
## ïŋ―ïļ HTML Dashboard - Real-Time Monitoring
|
|
447
|
+
|
|
448
|
+
Light Async Queue includes a built-in HTML dashboard for real-time monitoring, similar to Zookeeper. The dashboard provides a modern, responsive web interface for tracking job statuses and managing your queue.
|
|
449
|
+
|
|
450
|
+
### Quick Start
|
|
267
451
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
452
|
+
```typescript
|
|
453
|
+
import { Queue, Dashboard, StorageType } from "light-async-queue";
|
|
454
|
+
|
|
455
|
+
const queue = new Queue({
|
|
456
|
+
storage: StorageType.FILE,
|
|
457
|
+
filePath: "./jobs.log",
|
|
458
|
+
concurrency: 3,
|
|
459
|
+
retry: {
|
|
460
|
+
/* ... */
|
|
461
|
+
},
|
|
462
|
+
});
|
|
463
|
+
|
|
464
|
+
// Create and start dashboard
|
|
465
|
+
const dashboard = new Dashboard(queue, {
|
|
466
|
+
port: 3000,
|
|
467
|
+
host: "localhost",
|
|
468
|
+
updateInterval: 1000, // Update every 1 second
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
await dashboard.start();
|
|
472
|
+
console.log("ð Dashboard: http://localhost:3000");
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### Dashboard Features
|
|
476
|
+
|
|
477
|
+
- **ð Real-time Statistics** - Live job counts (active, waiting, delayed, pending, completed, failed, stalled)
|
|
478
|
+
- **ð Job Tracking** - View active/waiting jobs with progress bars
|
|
479
|
+
- **â ïļ Dead Letter Queue** - Monitor and retry failed jobs from the UI
|
|
480
|
+
- **ð WebSocket Updates** - Fast, real-time data synchronization
|
|
481
|
+
- **ðĻ Modern UI** - Responsive design with color-coded status badges
|
|
482
|
+
- **ð Progress Visualization** - Track job completion with visual indicators
|
|
483
|
+
|
|
484
|
+
### API Endpoints
|
|
485
|
+
|
|
486
|
+
The dashboard exposes REST API endpoints:
|
|
487
|
+
|
|
488
|
+
- `GET /` - HTML dashboard interface
|
|
489
|
+
- `GET /api/stats` - Queue statistics (JSON)
|
|
490
|
+
- `GET /api/jobs` - Active and waiting jobs
|
|
491
|
+
- `GET /api/failed-jobs` - Failed jobs in DLQ
|
|
492
|
+
- `POST /api/reprocess-failed` - Retry a failed job
|
|
493
|
+
|
|
494
|
+
### Example Usage
|
|
495
|
+
|
|
496
|
+
See the [complete dashboard example](./example/dashboard-example.ts) for a working implementation with:
|
|
497
|
+
|
|
498
|
+
- Real-time job processing
|
|
499
|
+
- Progress tracking
|
|
500
|
+
- Event handling
|
|
501
|
+
- Failed job retry from UI
|
|
502
|
+
|
|
503
|
+
```bash
|
|
504
|
+
# Run the example
|
|
505
|
+
npm run build:examples
|
|
506
|
+
node dist/example/dashboard-example.js
|
|
507
|
+
# Open http://localhost:3000
|
|
508
|
+
```
|
|
509
|
+
|
|
510
|
+
For detailed dashboard documentation, see [Dashboard README](./src/dashboard/README.md).
|
|
511
|
+
|
|
512
|
+
## ïŋ―ð Comparison with BullMQ and Bull
|
|
513
|
+
|
|
514
|
+
| Feature | light-async-queue | BullMQ | Bull |
|
|
515
|
+
| ----------------- | ----------------------------- | ---------------- | --------------- |
|
|
516
|
+
| Redis Required | â No | â
Yes | â
Yes |
|
|
517
|
+
| File Persistence | â
Yes | â No | â No |
|
|
518
|
+
| Worker Isolation | â
Child Process | â ïļ Same Process | â ïļ Same Process |
|
|
519
|
+
| Crash Recovery | â
Built-in | â ïļ Needs Redis | â ïļ Needs Redis |
|
|
520
|
+
| Job Events | â
Yes | â
Yes | â
Yes |
|
|
521
|
+
| Job Priorities | â
Yes | â
Yes | â
Yes |
|
|
522
|
+
| Delayed Jobs | â
Yes | â
Yes | â
Yes |
|
|
523
|
+
| Repeating Jobs | â
Yes | â
Yes | â
Yes |
|
|
524
|
+
| Cron Patterns | â
Yes | â
Yes | â
Yes |
|
|
525
|
+
| Job Dependencies | â
Yes | â
Yes | â No |
|
|
526
|
+
| Progress Tracking | â
Yes | â
Yes | â
Yes |
|
|
527
|
+
| Rate Limiting | â
Yes | â
Yes | â
Yes |
|
|
528
|
+
| Webhooks | â
Yes | â No | â No |
|
|
529
|
+
| Stalled Detection | â
Yes | â
Yes | â
Yes |
|
|
530
|
+
| HTML Dashboard | â
Built-in | â ïļ Bull Board | â ïļ Bull Board |
|
|
531
|
+
| Setup Complexity | ðĒ Low | ðĄ Medium | ðĄ Medium |
|
|
532
|
+
| Dependencies | ðĒ Minimal (cron-parser + ws) | ðī Redis + deps | ðī Redis + deps |
|
|
533
|
+
| Best For | Single-node apps | Distributed apps | Legacy apps |
|
|
534
|
+
|
|
535
|
+
**Why choose light-async-queue?**
|
|
536
|
+
|
|
537
|
+
- â
No Redis infrastructure or maintenance
|
|
538
|
+
- â
Built-in crash recovery with file persistence
|
|
539
|
+
- â
True process isolation for better fault tolerance
|
|
540
|
+
- â
Minimal runtime dependencies (`cron-parser`, `ws`)
|
|
541
|
+
- â
Perfect for edge deployments, serverless, or single-server apps
|
|
542
|
+
- â
All BullMQ features without the complexity
|
|
276
543
|
|
|
277
544
|
## ðŊ Use Cases
|
|
278
545
|
|
|
@@ -281,7 +548,7 @@ Perfect for:
|
|
|
281
548
|
- **Single-server applications** that don't need Redis
|
|
282
549
|
- **Background job processing** (emails, reports, etc.)
|
|
283
550
|
- **Reliable task queues** with crash recovery
|
|
284
|
-
- **Development environments**
|
|
551
|
+
- **Development environments** with minimal external dependencies
|
|
285
552
|
- **Edge deployments** where Redis isn't available
|
|
286
553
|
|
|
287
554
|
## ð§ Advanced Example
|
|
@@ -357,10 +624,27 @@ npm run build
|
|
|
357
624
|
npm run example
|
|
358
625
|
```
|
|
359
626
|
|
|
360
|
-
**Test Results:** â
|
|
627
|
+
**Test Results:** â
85+ tests passing across 8 test suites (powered by Vitest)
|
|
361
628
|
|
|
362
629
|
See [TEST_SUITE.md](./TEST_SUITE.md) for detailed test documentation.
|
|
363
630
|
|
|
631
|
+
## ð Examples
|
|
632
|
+
|
|
633
|
+
Check out the `example/` directory for comprehensive examples:
|
|
634
|
+
|
|
635
|
+
- **[basic.ts](./example/basic.ts)** - Simple queue setup and job processing
|
|
636
|
+
- **[concurrency.ts](./example/concurrency.ts)** - Concurrent job processing
|
|
637
|
+
- **[crash-recovery.ts](./example/crash-recovery.ts)** - Crash recovery demonstration
|
|
638
|
+
- **[advanced-features.ts](./example/advanced-features.ts)** - All BullMQ-compatible features:
|
|
639
|
+
- Job events and listeners
|
|
640
|
+
- Job priorities
|
|
641
|
+
- Delayed and repeating jobs
|
|
642
|
+
- Cron patterns
|
|
643
|
+
- Job dependencies
|
|
644
|
+
- Progress tracking
|
|
645
|
+
- Rate limiting
|
|
646
|
+
- Webhooks
|
|
647
|
+
|
|
364
648
|
## ð License
|
|
365
649
|
|
|
366
650
|
MIT
|
package/dist/src/constants.d.ts
CHANGED
|
@@ -3,10 +3,13 @@
|
|
|
3
3
|
* Represents the different states a job can be in
|
|
4
4
|
*/
|
|
5
5
|
export declare enum JobStatus {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
WAITING = "waiting",// Waiting to be picked up (new default)
|
|
7
|
+
DELAYED = "delayed",// Scheduled for future execution
|
|
8
|
+
PENDING = "pending",// Ready to be processed
|
|
9
|
+
PROCESSING = "processing",// Currently being processed
|
|
10
|
+
COMPLETED = "completed",// Successfully completed
|
|
11
|
+
FAILED = "failed",// Failed after all retries
|
|
12
|
+
STALLED = "stalled"
|
|
10
13
|
}
|
|
11
14
|
/**
|
|
12
15
|
* Backoff Strategy Type Enum
|
|
@@ -44,6 +47,22 @@ export declare enum WorkerResponseType {
|
|
|
44
47
|
* Special signals for worker communication
|
|
45
48
|
*/
|
|
46
49
|
export declare enum WorkerSignalType {
|
|
47
|
-
READY = "ready"
|
|
50
|
+
READY = "ready",
|
|
51
|
+
PROGRESS = "progress"
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Queue Event Type Enum
|
|
55
|
+
* Events emitted by the queue
|
|
56
|
+
*/
|
|
57
|
+
export declare enum QueueEventType {
|
|
58
|
+
WAITING = "waiting",
|
|
59
|
+
DELAYED = "delayed",
|
|
60
|
+
ACTIVE = "active",
|
|
61
|
+
PROGRESS = "progress",
|
|
62
|
+
COMPLETED = "completed",
|
|
63
|
+
FAILED = "failed",
|
|
64
|
+
STALLED = "stalled",
|
|
65
|
+
DRAINED = "drained",
|
|
66
|
+
ERROR = "error"
|
|
48
67
|
}
|
|
49
68
|
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,SAAS;IACnB,OAAO,YAAY;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,oBAAY,SAAS;IACnB,OAAO,YAAY,CAAO,wCAAwC;IAClE,OAAO,YAAY,CAAO,iCAAiC;IAC3D,OAAO,YAAY,CAAO,wBAAwB;IAClD,UAAU,eAAe,CAAE,4BAA4B;IACvD,SAAS,cAAc,CAAI,yBAAyB;IACpD,MAAM,WAAW,CAAU,2BAA2B;IACtD,OAAO,YAAY;CACpB;AAED;;;GAGG;AACH,oBAAY,mBAAmB;IAC7B,WAAW,gBAAgB;IAC3B,KAAK,UAAU;CAChB;AAED;;;GAGG;AACH,oBAAY,WAAW;IACrB,MAAM,WAAW;IACjB,IAAI,SAAS;CACd;AAED;;;GAGG;AACH,oBAAY,iBAAiB;IAC3B,OAAO,YAAY;IACnB,aAAa,iBAAiB;CAC/B;AAED;;;GAGG;AACH,oBAAY,kBAAkB;IAC5B,MAAM,WAAW;CAClB;AAED;;;GAGG;AACH,oBAAY,gBAAgB;IAC1B,KAAK,UAAU;IACf,QAAQ,aAAa;CACtB;AAED;;;GAGG;AACH,oBAAY,cAAc;IACxB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,KAAK,UAAU;CAChB"}
|
package/dist/src/constants.js
CHANGED
|
@@ -4,10 +4,13 @@
|
|
|
4
4
|
*/
|
|
5
5
|
export var JobStatus;
|
|
6
6
|
(function (JobStatus) {
|
|
7
|
+
JobStatus["WAITING"] = "waiting";
|
|
8
|
+
JobStatus["DELAYED"] = "delayed";
|
|
7
9
|
JobStatus["PENDING"] = "pending";
|
|
8
10
|
JobStatus["PROCESSING"] = "processing";
|
|
9
11
|
JobStatus["COMPLETED"] = "completed";
|
|
10
12
|
JobStatus["FAILED"] = "failed";
|
|
13
|
+
JobStatus["STALLED"] = "stalled";
|
|
11
14
|
})(JobStatus || (JobStatus = {}));
|
|
12
15
|
/**
|
|
13
16
|
* Backoff Strategy Type Enum
|
|
@@ -51,5 +54,22 @@ export var WorkerResponseType;
|
|
|
51
54
|
export var WorkerSignalType;
|
|
52
55
|
(function (WorkerSignalType) {
|
|
53
56
|
WorkerSignalType["READY"] = "ready";
|
|
57
|
+
WorkerSignalType["PROGRESS"] = "progress";
|
|
54
58
|
})(WorkerSignalType || (WorkerSignalType = {}));
|
|
59
|
+
/**
|
|
60
|
+
* Queue Event Type Enum
|
|
61
|
+
* Events emitted by the queue
|
|
62
|
+
*/
|
|
63
|
+
export var QueueEventType;
|
|
64
|
+
(function (QueueEventType) {
|
|
65
|
+
QueueEventType["WAITING"] = "waiting";
|
|
66
|
+
QueueEventType["DELAYED"] = "delayed";
|
|
67
|
+
QueueEventType["ACTIVE"] = "active";
|
|
68
|
+
QueueEventType["PROGRESS"] = "progress";
|
|
69
|
+
QueueEventType["COMPLETED"] = "completed";
|
|
70
|
+
QueueEventType["FAILED"] = "failed";
|
|
71
|
+
QueueEventType["STALLED"] = "stalled";
|
|
72
|
+
QueueEventType["DRAINED"] = "drained";
|
|
73
|
+
QueueEventType["ERROR"] = "error";
|
|
74
|
+
})(QueueEventType || (QueueEventType = {}));
|
|
55
75
|
//# sourceMappingURL=constants.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAN,IAAY,
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAN,IAAY,SAQX;AARD,WAAY,SAAS;IACnB,gCAAmB,CAAA;IACnB,gCAAmB,CAAA;IACnB,gCAAmB,CAAA;IACnB,sCAAyB,CAAA;IACzB,oCAAuB,CAAA;IACvB,8BAAiB,CAAA;IACjB,gCAAmB,CAAA;AACrB,CAAC,EARW,SAAS,KAAT,SAAS,QAQpB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,mBAGX;AAHD,WAAY,mBAAmB;IAC7B,kDAA2B,CAAA;IAC3B,sCAAe,CAAA;AACjB,CAAC,EAHW,mBAAmB,KAAnB,mBAAmB,QAG9B;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,WAGX;AAHD,WAAY,WAAW;IACrB,gCAAiB,CAAA;IACjB,4BAAa,CAAA;AACf,CAAC,EAHW,WAAW,KAAX,WAAW,QAGtB;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,iBAGX;AAHD,WAAY,iBAAiB;IAC3B,wCAAmB,CAAA;IACnB,mDAA8B,CAAA;AAChC,CAAC,EAHW,iBAAiB,KAAjB,iBAAiB,QAG5B;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,kBAEX;AAFD,WAAY,kBAAkB;IAC5B,uCAAiB,CAAA;AACnB,CAAC,EAFW,kBAAkB,KAAlB,kBAAkB,QAE7B;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,gBAGX;AAHD,WAAY,gBAAgB;IAC1B,mCAAe,CAAA;IACf,yCAAqB,CAAA;AACvB,CAAC,EAHW,gBAAgB,KAAhB,gBAAgB,QAG3B;AAED;;;GAGG;AACH,MAAM,CAAN,IAAY,cAUX;AAVD,WAAY,cAAc;IACxB,qCAAmB,CAAA;IACnB,qCAAmB,CAAA;IACnB,mCAAiB,CAAA;IACjB,uCAAqB,CAAA;IACrB,yCAAuB,CAAA;IACvB,mCAAiB,CAAA;IACjB,qCAAmB,CAAA;IACnB,qCAAmB,CAAA;IACnB,iCAAe,CAAA;AACjB,CAAC,EAVW,cAAc,KAAd,cAAc,QAUzB"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Queue } from "../queue/Queue.js";
|
|
2
|
+
export interface DashboardConfig {
|
|
3
|
+
port: number;
|
|
4
|
+
host?: string;
|
|
5
|
+
updateInterval?: number;
|
|
6
|
+
}
|
|
7
|
+
export declare class Dashboard {
|
|
8
|
+
private queue;
|
|
9
|
+
private server;
|
|
10
|
+
private wss;
|
|
11
|
+
private updateInterval;
|
|
12
|
+
private config;
|
|
13
|
+
private clients;
|
|
14
|
+
private htmlTemplate;
|
|
15
|
+
constructor(queue: Queue, config: DashboardConfig);
|
|
16
|
+
/**
|
|
17
|
+
* Start the dashboard server
|
|
18
|
+
*/
|
|
19
|
+
start(): Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Stop the dashboard server
|
|
22
|
+
*/
|
|
23
|
+
stop(): Promise<void>;
|
|
24
|
+
/**
|
|
25
|
+
* Handle HTTP requests
|
|
26
|
+
*/
|
|
27
|
+
private handleRequest;
|
|
28
|
+
/**
|
|
29
|
+
* Serve the HTML dashboard
|
|
30
|
+
*/
|
|
31
|
+
private serveHTML;
|
|
32
|
+
/**
|
|
33
|
+
* Generate HTML dashboard
|
|
34
|
+
*/
|
|
35
|
+
private generateHTML;
|
|
36
|
+
private loadTemplate;
|
|
37
|
+
/**
|
|
38
|
+
* Setup WebSocket handlers
|
|
39
|
+
*/
|
|
40
|
+
private setupWebSocketHandlers;
|
|
41
|
+
/**
|
|
42
|
+
* Serve stats API
|
|
43
|
+
*/
|
|
44
|
+
private serveStats;
|
|
45
|
+
/**
|
|
46
|
+
* Serve jobs list
|
|
47
|
+
*/
|
|
48
|
+
private serveJobs;
|
|
49
|
+
/**
|
|
50
|
+
* Serve failed jobs
|
|
51
|
+
*/
|
|
52
|
+
private serveFailedJobs;
|
|
53
|
+
/**
|
|
54
|
+
* Handle reprocess failed job request
|
|
55
|
+
*/
|
|
56
|
+
private handleReprocessFailed;
|
|
57
|
+
/**
|
|
58
|
+
* Send stats to a specific client
|
|
59
|
+
*/
|
|
60
|
+
private sendStatsToClient;
|
|
61
|
+
/**
|
|
62
|
+
* Broadcast stats to all clients
|
|
63
|
+
*/
|
|
64
|
+
private broadcastStats;
|
|
65
|
+
/**
|
|
66
|
+
* Start periodic update interval
|
|
67
|
+
*/
|
|
68
|
+
private startUpdateInterval;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=Dashboard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Dashboard.d.ts","sourceRoot":"","sources":["../../../src/dashboard/Dashboard.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG1C,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAQ;IACrB,OAAO,CAAC,MAAM,CAAkC;IAChD,OAAO,CAAC,GAAG,CAAkB;IAC7B,OAAO,CAAC,cAAc,CAA+B;IACrD,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,OAAO,CAA6B;IAC5C,OAAO,CAAC,YAAY,CAAS;gBAEjB,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe;IAkBjD;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAa5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkB3B;;OAEG;IACH,OAAO,CAAC,aAAa;IAiBrB;;OAEG;IACH,OAAO,CAAC,SAAS;IAMjB;;OAEG;IACH,OAAO,CAAC,YAAY;IAIpB,OAAO,CAAC,YAAY;IAUpB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkC9B;;OAEG;IACH,OAAO,CAAC,UAAU;IAqBlB;;OAEG;IACH,OAAO,CAAC,SAAS;IA0BjB;;OAEG;IACH,OAAO,CAAC,eAAe;IAkBvB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0C7B;;OAEG;YACW,iBAAiB;IAiC/B;;OAEG;YACW,cAAc;IAyC5B;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAO5B"}
|