Skip to content

Commit 0b1894c

Browse files
committed
remove onJob references
1 parent f02a8f9 commit 0b1894c

7 files changed

Lines changed: 95 additions & 78 deletions

File tree

CLAUDE.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ This is `@muniter/queue`, a TypeScript queue system inspired by Yii2-Queue archi
1010

1111
**@muniter/queue** is an event-driven job queue system that allows you to:
1212
- Define job types as TypeScript interfaces (not classes) for type safety
13-
- Register job handlers using simple `onJob()` callbacks
13+
- Register job handlers using type-safe `setHandlers()` method
1414
- Add jobs to queues with compile-time validation of payloads and options
1515
- Process jobs asynchronously with configurable workers
1616
- Switch between storage backends (File, Database, SQS) without changing job code
@@ -48,7 +48,7 @@ The CLI worker supports these arguments:
4848
- **DbQueue** (`src/drivers/db.ts`): Database-backed queue using DatabaseAdapter interface
4949
- **SqsQueue** (`src/drivers/sqs.ts`): Amazon SQS-backed queue
5050
- **FileQueue** (`src/drivers/file.ts`): File-based queue storing jobs as individual files with JSON index
51-
3. **Jobs**: Defined as TypeScript interfaces in a JobMap, with handlers registered via `onJob()` method
51+
3. **Jobs**: Defined as TypeScript interfaces in a JobMap, with handlers registered via `setHandlers()` method
5252
4. **Workers**: Long-running processes that consume and execute jobs
5353
5. **Serialization**: Pluggable serialization system for job payloads
5454

@@ -76,7 +76,7 @@ The queue emits lifecycle events:
7676
## Development Patterns
7777

7878
### Job Implementation
79-
Jobs are defined as TypeScript interfaces in a JobMap type, and handlers are registered using the `onJob()` method. The payload is serialized using JSON by default.
79+
Jobs are defined as TypeScript interfaces in a JobMap type, and handlers are registered using the `setHandlers()` method. The payload is serialized using JSON by default.
8080

8181
### Database Adapters
8282
When implementing DatabaseAdapter, you must provide:

README.md

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,22 @@ interface MyJobs {
3737

3838
const queue = new FileQueue<MyJobs>({ path: './queue-data' });
3939

40-
// Register event-based handlers
41-
queue.onJob('send-email', async (payload) => {
42-
// payload is automatically typed as { to: string; subject: string; body: string }
43-
console.log(`Sending email to ${payload.to}: ${payload.subject}`);
44-
await sendEmail(payload.to, payload.subject, payload.body);
45-
});
46-
47-
queue.onJob('resize-image', async (payload) => {
48-
// payload is automatically typed as { url: string; width: number; height: number }
49-
console.log(`Resizing image ${payload.url} to ${payload.width}x${payload.height}`);
50-
await resizeImage(payload.url, payload.width, payload.height);
40+
// Register type-safe handlers
41+
queue.setHandlers({
42+
'send-email': async ({ payload }) => {
43+
// payload is automatically typed as { to: string; subject: string; body: string }
44+
console.log(`Sending email to ${payload.to}: ${payload.subject}`);
45+
await sendEmail(payload.to, payload.subject, payload.body);
46+
},
47+
'resize-image': async ({ payload }) => {
48+
// payload is automatically typed as { url: string; width: number; height: number }
49+
console.log(`Resizing image ${payload.url} to ${payload.width}x${payload.height}`);
50+
await resizeImage(payload.url, payload.width, payload.height);
51+
},
52+
'generate-report': async ({ payload }) => {
53+
// Handle report generation
54+
console.log(`Generating ${payload.type} report for ${payload.period}`);
55+
}
5156
});
5257
```
5358

@@ -309,7 +314,7 @@ pnpm run queue:worker -- --timeout 10
309314
### Queue Methods
310315

311316
- `addJob<K>(name: K, request: { payload: JobMap[K], ...options }): Promise<string>` - Add job to queue
312-
- `onJob<K>(name: K, handler: (payload: JobMap[K]) => Promise<void>): this` - Register job handler
317+
- `setHandlers(handlers: JobHandlers<JobMap>): void` - Register all job handlers with type safety
313318
- `run(repeat?: boolean, timeout?: number): Promise<void>` - Start processing jobs
314319
- `status(id: string): Promise<JobStatus>` - Get job status
315320

@@ -329,7 +334,7 @@ interface JobMap {
329334
}
330335

331336
// Jobs are defined as TypeScript interfaces, not classes
332-
// Handlers are registered with queue.onJob()
337+
// Handlers are registered with queue.setHandlers()
333338
```
334339

335340
## Testing

docs/design/plugin-architecture.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,10 @@ const queue = new FileQueue<MyJobs>({
390390
});
391391

392392
// Register job handlers
393-
queue.onJob('send-email', async (payload) => {
394-
await emailService.send(payload);
393+
queue.setHandlers({
394+
'send-email': async ({ payload }) => {
395+
await emailService.send(payload);
396+
}
395397
});
396398

397399
// Simple run call - plugins are already configured

example-queue-project/src/email-queue.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FileQueue, Queue } from "@muniter/queue";
1+
import { FileQueue } from "@muniter/queue";
22
import { createSQSQueue } from "@muniter/queue/sqs";
33

44
interface EmailJobs {
@@ -22,29 +22,30 @@ export const emailQueueSqs = createSQSQueue<EmailJobs>(
2222
export const emailQueue = emailQueueSqs;
2323

2424
// Register job handlers for email queue
25-
emailQueue.onJob("welcome-email", async (payload) => {
26-
const { to, name } = payload;
27-
console.log(`Sending welcome email to ${to} (${name})`);
28-
await new Promise((resolve) => setTimeout(resolve, 1000));
25+
emailQueue.setHandlers({
26+
"welcome-email": async ({ payload }) => {
27+
const { to, name } = payload;
28+
console.log(`Sending welcome email to ${to} (${name})`);
29+
await new Promise((resolve) => setTimeout(resolve, 1000));
2930

30-
if (Math.random() > 0.8) {
31-
throw new Error("Email service temporarily unavailable");
32-
}
33-
34-
console.log(`Welcome email sent successfully to ${to}`);
35-
});
31+
if (Math.random() > 0.8) {
32+
throw new Error("Email service temporarily unavailable");
33+
}
3634

37-
emailQueue.onJob("notification", async (payload) => {
38-
const { to, subject, body } = payload;
39-
console.log(`Sending notification email to ${to}: ${subject}`);
40-
await new Promise((resolve) => setTimeout(resolve, 500));
41-
emailQueue.addJob("welcome-email", {
42-
payload: {
43-
to: "javier@muniter.com",
44-
name: "Javier",
45-
},
46-
});
47-
console.log(`Notification sent successfully`);
35+
console.log(`Welcome email sent successfully to ${to}`);
36+
},
37+
"notification": async ({ payload }, queue) => {
38+
const { to, subject, body } = payload;
39+
console.log(`Sending notification email to ${to}: ${subject}`);
40+
await new Promise((resolve) => setTimeout(resolve, 500));
41+
queue.addJob("welcome-email", {
42+
payload: {
43+
to: "javier@muniter.com",
44+
name: "Javier",
45+
},
46+
});
47+
console.log(`Notification sent successfully`);
48+
}
4849
});
4950

5051
emailQueue.on("beforeExec", (event) => {

example-queue-project/src/general-queue.ts

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,30 +8,31 @@ export interface GeneralJobs {
88
export const generalQueue = createSQLiteQueue<GeneralJobs>('queue.db');
99

1010
// Register job handlers for general queue
11-
generalQueue.onJob('process-image', async (payload) => {
12-
const { url, width, height } = payload;
13-
console.log(`Processing image from ${url} to ${width}x${height}`);
14-
15-
const steps = ['Downloading', 'Resizing', 'Optimizing', 'Saving'];
16-
for (const step of steps) {
17-
console.log(` - ${step}...`);
18-
await new Promise(resolve => setTimeout(resolve, 800));
11+
generalQueue.setHandlers({
12+
'process-image': async ({ payload }) => {
13+
const { url, width, height } = payload;
14+
console.log(`Processing image from ${url} to ${width}x${height}`);
15+
16+
const steps = ['Downloading', 'Resizing', 'Optimizing', 'Saving'];
17+
for (const step of steps) {
18+
console.log(` - ${step}...`);
19+
await new Promise(resolve => setTimeout(resolve, 800));
20+
}
21+
22+
console.log(`Image processed successfully`);
23+
},
24+
'generate-report': async ({ payload }) => {
25+
const { type, period } = payload;
26+
console.log(`Generating ${type} report for ${period}`);
27+
28+
const steps = ['Fetching data', 'Processing', 'Formatting', 'Saving'];
29+
for (const step of steps) {
30+
console.log(` - ${step}...`);
31+
await new Promise(resolve => setTimeout(resolve, 600));
32+
}
33+
34+
console.log(`Report generated: ${type} for ${period}`);
1935
}
20-
21-
console.log(`Image processed successfully`);
22-
})
23-
24-
generalQueue.onJob('generate-report', async (payload) => {
25-
const { type, period } = payload;
26-
console.log(`Generating ${type} report for ${period}`);
27-
28-
const steps = ['Fetching data', 'Processing', 'Formatting', 'Saving'];
29-
for (const step of steps) {
30-
console.log(` - ${step}...`);
31-
await new Promise(resolve => setTimeout(resolve, 600));
32-
}
33-
34-
console.log(`Report generated: ${type} for ${period}`);
3536
});
3637

3738
// Add event listeners for both queues

example-queue-project/src/redis-queue.ts

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,19 @@ interface EmailJobs {
99
export const emailQueue = createRedisQueue<EmailJobs>('redis://localhost:6379');
1010

1111
// Register job handlers
12-
emailQueue.onJob("welcome-email", async (payload) => {
13-
const { to, name } = payload;
14-
console.log(`[Redis] Sending welcome email to ${to} (${name})`);
15-
await new Promise((resolve) => setTimeout(resolve, 1000));
16-
console.log(`[Redis] Welcome email sent successfully to ${to}`);
17-
});
18-
19-
emailQueue.onJob("notification", async (payload) => {
20-
const { to, subject, body } = payload;
21-
console.log(`[Redis] Sending notification email to ${to}: ${subject}`);
22-
await new Promise((resolve) => setTimeout(resolve, 500));
23-
console.log(`[Redis] Notification sent successfully`);
12+
emailQueue.setHandlers({
13+
"welcome-email": async ({ payload }) => {
14+
const { to, name } = payload;
15+
console.log(`[Redis] Sending welcome email to ${to} (${name})`);
16+
await new Promise((resolve) => setTimeout(resolve, 1000));
17+
console.log(`[Redis] Welcome email sent successfully to ${to}`);
18+
},
19+
"notification": async ({ payload }) => {
20+
const { to, subject, body } = payload;
21+
console.log(`[Redis] Sending notification email to ${to}: ${subject}`);
22+
await new Promise((resolve) => setTimeout(resolve, 500));
23+
console.log(`[Redis] Notification sent successfully`);
24+
}
2425
});
2526

2627
// Event listeners

src/core/queue.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,19 @@ import type { QueuePlugin, QueueOptions } from '../interfaces/plugin.ts';
1717
* const queue = new FileQueue<MyJobs>({ path: './queue-data' });
1818
*
1919
* // Register job handlers
20-
* queue.onJob('send-email', async (payload) => {
21-
* await sendEmail(payload.to, payload.subject, payload.body);
20+
* queue.setHandlers({
21+
* 'send-email': async ({ payload }) => {
22+
* await sendEmail(payload.to, payload.subject, payload.body);
23+
* },
24+
* 'resize-image': async ({ payload }) => {
25+
* await resizeImage(payload.url, payload.width, payload.height);
26+
* }
2227
* });
2328
*
2429
* // Add jobs with type safety
25-
* await queue.addJob('send-email', { to: 'user@example.com', subject: 'Hello', body: 'World' });
30+
* await queue.addJob('send-email', {
31+
* payload: { to: 'user@example.com', subject: 'Hello', body: 'World' }
32+
* });
2633
*
2734
* // Start processing
2835
* await queue.run();

0 commit comments

Comments
 (0)