1+ import {
2+ JobBase ,
3+ dispatch ,
4+ chain ,
5+ type ShouldQueue ,
6+ } from '../packages/bun-queue/src'
7+
8+ // Define a simple job class like Laravel
9+ class SendWelcomeEmailJob extends JobBase implements ShouldQueue {
10+ public queue = 'emails'
11+ public tries = 3
12+ public timeout = 30000
13+
14+ constructor (
15+ private userEmail : string ,
16+ private userName : string
17+ ) {
18+ super ( )
19+ }
20+
21+ async handle ( ) : Promise < { sent : boolean ; messageId : string } > {
22+ console . log ( `[SendWelcomeEmailJob] Sending welcome email to ${ this . userEmail } ` )
23+ console . log ( `[SendWelcomeEmailJob] User: ${ this . userName } ` )
24+
25+ // Simulate email sending delay
26+ await new Promise ( resolve => setTimeout ( resolve , 1000 ) )
27+
28+ // Simulate occasional failures
29+ if ( Math . random ( ) < 0.2 ) {
30+ throw new Error ( 'Email service temporarily unavailable' )
31+ }
32+
33+ const messageId = `msg_${ Date . now ( ) } _${ Math . random ( ) . toString ( 36 ) . substring ( 2 ) } `
34+ console . log ( `[SendWelcomeEmailJob] ✅ Email sent successfully! Message ID: ${ messageId } ` )
35+
36+ return {
37+ sent : true ,
38+ messageId,
39+ }
40+ }
41+
42+ uniqueId ( ) : string {
43+ return `welcome_${ this . userEmail } `
44+ }
45+ }
46+
47+ class ProcessUserAvatarJob extends JobBase implements ShouldQueue {
48+ public queue = 'images'
49+ public tries = 2
50+
51+ constructor (
52+ private userId : string ,
53+ private imageUrl : string
54+ ) {
55+ super ( )
56+ }
57+
58+ async handle ( ) : Promise < { processed : boolean ; thumbnailUrl : string } > {
59+ console . log ( `[ProcessUserAvatarJob] Processing avatar for user ${ this . userId } ` )
60+ console . log ( `[ProcessUserAvatarJob] Image URL: ${ this . imageUrl } ` )
61+
62+ // Simulate image processing
63+ await new Promise ( resolve => setTimeout ( resolve , 1500 ) )
64+
65+ const thumbnailUrl = `https://cdn.example.com/avatars/${ this . userId } _thumb.jpg`
66+ console . log ( `[ProcessUserAvatarJob] ✅ Avatar processed! Thumbnail: ${ thumbnailUrl } ` )
67+
68+ return {
69+ processed : true ,
70+ thumbnailUrl,
71+ }
72+ }
73+
74+ uniqueId ( ) : string {
75+ return `avatar_${ this . userId } `
76+ }
77+ }
78+
79+ async function demonstrateLaravelAPI ( ) {
80+ console . log ( '🚀 Laravel-like Queue API Demo\n' )
81+
82+ // 1. Basic job dispatching (Laravel style)
83+ console . log ( '1. Basic job dispatching:' )
84+ const emailJob = new SendWelcomeEmailJob ( '[email protected] ' , 'John Doe' ) 85+ const dispatchedEmailJob = await dispatch ( emailJob )
86+ console . log ( `✅ Email job dispatched with ID: ${ dispatchedEmailJob . id } \n` )
87+
88+ // 2. Fluent job chaining (Laravel style)
89+ console . log ( '2. Fluent job chaining:' )
90+ await chain ( new SendWelcomeEmailJob ( '[email protected] ' , 'Jane Smith' ) ) 91+ . onQueue ( 'priority-emails' )
92+ . withTries ( 5 )
93+ . delay ( 2000 ) // 2 second delay
94+ . dispatch ( )
95+ console . log ( '✅ Priority email job queued with delay and custom tries\n' )
96+
97+ // 3. Multiple jobs with different configurations
98+ console . log ( '3. Multiple jobs with different configurations:' )
99+
100+ // Create jobs with method chaining
101+ const avatarJob = new ProcessUserAvatarJob ( 'user123' , 'https://example.com/avatar.jpg' )
102+ . withTries ( 3 )
103+ . withTimeout ( 60000 )
104+
105+ const marketingEmail = new SendWelcomeEmailJob ( '[email protected] ' , 'Marketing Team' ) 106+ . onQueue ( 'marketing-emails' )
107+ . withTries ( 1 )
108+
109+ // Dispatch them
110+ await Promise . all ( [
111+ dispatch ( avatarJob ) ,
112+ dispatch ( marketingEmail ) ,
113+ ] )
114+
115+ console . log ( '✅ Avatar processing and marketing email jobs dispatched\n' )
116+
117+ // 4. Conditional dispatching
118+ console . log ( '4. Conditional dispatching:' )
119+ const isNewUser = Math . random ( ) > 0.5
120+ const welcomeJob = new SendWelcomeEmailJob ( '[email protected] ' , 'New User' ) 121+
122+ if ( isNewUser ) {
123+ await dispatch ( welcomeJob )
124+ console . log ( '✅ Welcome email dispatched for new user' )
125+ } else {
126+ console . log ( 'ℹ️ User not new, skipping welcome email' )
127+ }
128+
129+ console . log ( '\n🎉 Demo completed! Jobs are now being processed...' )
130+ console . log ( 'Note: In a real application, you would start workers to process these jobs.' )
131+ }
132+
133+ // Simple worker simulation for demo purposes
134+ async function simulateWorkers ( ) {
135+ console . log ( '\n👷 Starting simulated workers...\n' )
136+
137+ // This is just for demo - in reality you'd use the actual queue processing
138+ const jobs = [
139+ new SendWelcomeEmailJob ( '[email protected] ' , 'Demo User' ) , 140+ new ProcessUserAvatarJob ( 'demo123' , 'https://example.com/demo.jpg' ) ,
141+ ]
142+
143+ for ( const job of jobs ) {
144+ try {
145+ console . log ( `🔄 Processing ${ job . constructor . name } ...` )
146+ const result = await job . handle ( )
147+ console . log ( `✅ Job completed:` , result )
148+ } catch ( error ) {
149+ console . log ( `❌ Job failed:` , ( error as Error ) . message )
150+ }
151+ console . log ( '' ) // Empty line for readability
152+ }
153+ }
154+
155+ async function main ( ) {
156+ await demonstrateLaravelAPI ( )
157+ await simulateWorkers ( )
158+ }
159+
160+ main ( ) . catch ( ( error ) => {
161+ console . error ( '❌ Demo failed:' , error )
162+ process . exit ( 1 )
163+ } )
0 commit comments