@@ -3,6 +3,7 @@ import type {
33 FlowJob as BullFlowJob ,
44 Job as BullJob ,
55 QueueOptions as BullQueueOptions ,
6+ FlowJob ,
67} from 'bullmq'
78import type {
89 DefineFlowOptions ,
@@ -21,19 +22,21 @@ import IORedis from 'ioredis'
2122import { mapValues } from 'remeda'
2223import { FlowBuilder , flowSymbol , jobSymbol , StandardSchemaV1Error } from './types'
2324
25+ export { RateLimitError , UnrecoverableError } from 'bullmq'
26+
2427export function defineJob < Schema extends StandardSchemaV1 , Output > (
2528 opts : DefineJobOptions < Schema , Output > ,
2629) : Job < Schema , Output > {
2730 return {
2831 ...opts ,
2932 [ jobSymbol ] : < Job < Schema , Output > [ typeof jobSymbol ] > {
30- async addToQueue ( queue , payload ) {
33+ async addToQueue ( queue , payload , jobOpts ) {
3134 const parsed = await opts . schema [ '~standard' ] . validate ( payload )
3235 if ( parsed . issues ) throw new StandardSchemaV1Error ( parsed . issues )
3336
34- return queue . add ( queue . name , parsed . value )
37+ return queue . add ( queue . name , parsed . value , jobOpts )
3538 } ,
36- async addToQueueBulk ( queue , payloads ) {
39+ async addToQueueBulk ( queue , payloads , jobOpts ) {
3740 return queue . addBulk (
3841 await Promise . all (
3942 payloads . map ( async ( payload ) => {
@@ -43,6 +46,7 @@ export function defineJob<Schema extends StandardSchemaV1, Output>(
4346 return {
4447 name : queue . name ,
4548 data : parsed . value ,
49+ opts : jobOpts ,
4650 }
4751 } ) ,
4852 ) ,
@@ -57,6 +61,7 @@ function buildFlowJobStack(opts: {
5761 rootInputPayload : unknown
5862 steps : FlowStep < any , any > [ ]
5963 flowName : string
64+ flowOpts ?: FlowJob [ 'opts' ]
6065} ) {
6166 if ( opts . steps . length === 0 ) throw new Error ( `Flow ${ opts . flowName } has no steps` )
6267 const firstStep = opts . steps [ 0 ] !
@@ -65,21 +70,19 @@ function buildFlowJobStack(opts: {
6570 name : `${ opts . flowName } _${ firstStep . name } ` ,
6671 queueName : `${ opts . flowName } _${ firstStep . name } ` ,
6772 data : opts . rootInputPayload ,
73+ opts : opts . flowOpts ,
6874 }
6975
7076 for ( const step of opts . steps . slice ( 1 ) ) {
7177 currentStep = {
7278 name : `${ opts . flowName } _${ step . name } ` ,
7379 queueName : `${ opts . flowName } _${ step . name } ` ,
7480 children : [ currentStep ] ,
81+ opts : opts . flowOpts ,
7582 }
7683 }
7784
78- return {
79- name : `${ opts . flowName } ` ,
80- queueName : `${ opts . flowName } ` ,
81- children : [ currentStep ] ,
82- } satisfies BullFlowJob
85+ return currentStep
8386}
8487
8588export function defineFlow < Schema extends StandardSchemaV1 , Output > (
@@ -90,7 +93,7 @@ export function defineFlow<Schema extends StandardSchemaV1, Output>(
9093 ...opts ,
9194 [ flowSymbol ] : < Flow < Schema , Output > [ typeof flowSymbol ] > {
9295 steps,
93- async addToQueue ( flowName , flowProducer , payload ) {
96+ async addToQueue ( flowName , flowProducer , payload , flowOpts ) {
9497 const parsed = await opts . schema [ '~standard' ] . validate ( payload )
9598 if ( parsed . issues ) throw new StandardSchemaV1Error ( parsed . issues )
9699
@@ -100,9 +103,10 @@ export function defineFlow<Schema extends StandardSchemaV1, Output>(
100103 steps,
101104 flowName,
102105 } ) ,
106+ flowOpts ,
103107 )
104108 } ,
105- async addToQueueBulk ( flowName , flowProducer , payloads ) {
109+ async addToQueueBulk ( flowName , flowProducer , payloads , flowOpts ) {
106110 return flowProducer . addBulk (
107111 await Promise . all (
108112 payloads . map ( async ( payload ) => {
@@ -113,6 +117,7 @@ export function defineFlow<Schema extends StandardSchemaV1, Output>(
113117 flowName,
114118 rootInputPayload : parsed . value ,
115119 steps,
120+ flowOpts,
116121 } )
117122 } ) ,
118123 ) ,
@@ -242,32 +247,6 @@ export async function startWorkers<J extends JobDefinitionsObject>(
242247 } else if ( flowSymbol in value ) {
243248 const flowName = fullPath . join ( '-' )
244249
245- const worker = new BullWorker (
246- flowName ,
247- async ( job ) => {
248- // eslint-disable-next-line ts/no-unsafe-return
249- const results = await job . getChildrenValues ( ) . then ( ( res ) => Object . values ( res ) )
250- if ( results . length !== 1 )
251- throw new Error ( 'Flow root job should have exactly one child job' )
252-
253- // eslint-disable-next-line ts/no-unsafe-return
254- return results [ 0 ]
255- } ,
256- {
257- ...opts ,
258- ...value . workerOptions ,
259- connection,
260- } ,
261- )
262-
263- const hooks = value . workerOptions ?. hooks ?? opts ?. hooks
264- if ( hooks )
265- for ( const [ hookName , hook ] of Object . entries ( hooks ) ) {
266- worker . addListener ( hookName , hook )
267- }
268-
269- workers . set ( flowName , worker )
270-
271250 // add workers for each step
272251 for ( const step of value [ flowSymbol ] . steps ) {
273252 const jobName = `${ flowName } _${ step . name } `
@@ -295,6 +274,7 @@ export async function startWorkers<J extends JobDefinitionsObject>(
295274 } ,
296275 )
297276
277+ const hooks = value . workerOptions ?. hooks ?? opts ?. hooks
298278 if ( hooks )
299279 for ( const [ hookName , hook ] of Object . entries ( hooks ) ) {
300280 stepWorker . addListener ( hookName , hook )
0 commit comments