@igniter-js/jobs 0.1.0 → 0.1.12
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/AGENTS.md +1006 -410
- package/CHANGELOG.md +13 -0
- package/README.md +2092 -277
- package/dist/adapter-CXZxomI9.d.mts +529 -0
- package/dist/adapter-CXZxomI9.d.ts +529 -0
- package/dist/adapters/bullmq.adapter.d.mts +56 -111
- package/dist/adapters/bullmq.adapter.d.ts +56 -111
- package/dist/adapters/bullmq.adapter.js +432 -530
- package/dist/adapters/bullmq.adapter.js.map +1 -1
- package/dist/adapters/bullmq.adapter.mjs +432 -530
- package/dist/adapters/bullmq.adapter.mjs.map +1 -1
- package/dist/adapters/index.d.mts +142 -4
- package/dist/adapters/index.d.ts +142 -4
- package/dist/adapters/index.js +1701 -939
- package/dist/adapters/index.js.map +1 -1
- package/dist/adapters/index.mjs +1699 -938
- package/dist/adapters/index.mjs.map +1 -1
- package/dist/adapters/memory.adapter.d.mts +53 -99
- package/dist/adapters/memory.adapter.d.ts +53 -99
- package/dist/adapters/memory.adapter.js +554 -464
- package/dist/adapters/memory.adapter.js.map +1 -1
- package/dist/adapters/memory.adapter.mjs +554 -464
- package/dist/adapters/memory.adapter.mjs.map +1 -1
- package/dist/index.d.mts +524 -887
- package/dist/index.d.ts +524 -887
- package/dist/index.js +2917 -860
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2914 -860
- package/dist/index.mjs.map +1 -1
- package/dist/shim.d.mts +36 -0
- package/dist/shim.d.ts +36 -0
- package/dist/shim.js +75 -0
- package/dist/shim.js.map +1 -0
- package/dist/shim.mjs +67 -0
- package/dist/shim.mjs.map +1 -0
- package/dist/telemetry/index.d.mts +281 -0
- package/dist/telemetry/index.d.ts +281 -0
- package/dist/telemetry/index.js +97 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/index.mjs +95 -0
- package/dist/telemetry/index.mjs.map +1 -0
- package/package.json +71 -20
- package/dist/adapter-CcQCatSa.d.mts +0 -1411
- package/dist/adapter-CcQCatSa.d.ts +0 -1411
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/errors/igniter-jobs.error.ts","../src/builders/igniter-worker.builder.ts","../src/core/igniter-jobs.ts","../src/builders/igniter-jobs.builder.ts","../src/builders/igniter-queue.builder.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * @fileoverview Error class and error codes for @igniter-js/jobs\n * @module @igniter-js/jobs/errors\n */\n\nimport { IgniterError, type IgniterLogger } from '@igniter-js/core'\n\n/**\n * All possible error codes for IgniterJobs.\n * Use these codes for programmatic error handling.\n *\n * @example\n * ```typescript\n * try {\n * await jobs.email.sendWelcome.dispatch(input)\n * } catch (error) {\n * if (error instanceof IgniterJobsError) {\n * switch (error.code) {\n * case 'JOBS_ADAPTER_REQUIRED':\n * // Handle missing adapter\n * break\n * case 'JOBS_DISPATCH_FAILED':\n * // Handle dispatch failure\n * break\n * }\n * }\n * }\n * ```\n */\nexport const IGNITER_JOBS_ERROR_CODES = {\n // Configuration errors\n JOBS_ADAPTER_REQUIRED: 'JOBS_ADAPTER_REQUIRED',\n JOBS_CONTEXT_REQUIRED: 'JOBS_CONTEXT_REQUIRED',\n JOBS_QUEUE_REQUIRED: 'JOBS_QUEUE_REQUIRED',\n JOBS_CONFIGURATION_INVALID: 'JOBS_CONFIGURATION_INVALID',\n\n // Queue errors\n JOBS_QUEUE_NOT_FOUND: 'JOBS_QUEUE_NOT_FOUND',\n JOBS_QUEUE_ALREADY_EXISTS: 'JOBS_QUEUE_ALREADY_EXISTS',\n JOBS_QUEUE_NAME_INVALID: 'JOBS_QUEUE_NAME_INVALID',\n JOBS_QUEUE_PAUSE_FAILED: 'JOBS_QUEUE_PAUSE_FAILED',\n JOBS_QUEUE_RESUME_FAILED: 'JOBS_QUEUE_RESUME_FAILED',\n JOBS_QUEUE_DRAIN_FAILED: 'JOBS_QUEUE_DRAIN_FAILED',\n JOBS_QUEUE_CLEAN_FAILED: 'JOBS_QUEUE_CLEAN_FAILED',\n JOBS_QUEUE_OBLITERATE_FAILED: 'JOBS_QUEUE_OBLITERATE_FAILED',\n\n // Job definition errors\n JOBS_JOB_NOT_FOUND: 'JOBS_JOB_NOT_FOUND',\n JOBS_JOB_ALREADY_EXISTS: 'JOBS_JOB_ALREADY_EXISTS',\n JOBS_JOB_NAME_INVALID: 'JOBS_JOB_NAME_INVALID',\n JOBS_JOB_HANDLER_REQUIRED: 'JOBS_JOB_HANDLER_REQUIRED',\n\n // Cron errors\n JOBS_CRON_NOT_FOUND: 'JOBS_CRON_NOT_FOUND',\n JOBS_CRON_ALREADY_EXISTS: 'JOBS_CRON_ALREADY_EXISTS',\n JOBS_CRON_EXPRESSION_INVALID: 'JOBS_CRON_EXPRESSION_INVALID',\n JOBS_CRON_HANDLER_REQUIRED: 'JOBS_CRON_HANDLER_REQUIRED',\n\n // Dispatch errors\n JOBS_DISPATCH_FAILED: 'JOBS_DISPATCH_FAILED',\n JOBS_SCHEDULE_FAILED: 'JOBS_SCHEDULE_FAILED',\n JOBS_INPUT_REQUIRED: 'JOBS_INPUT_REQUIRED',\n JOBS_INPUT_VALIDATION_FAILED: 'JOBS_INPUT_VALIDATION_FAILED',\n\n // Scope errors\n JOBS_SCOPE_REQUIRED: 'JOBS_SCOPE_REQUIRED',\n JOBS_SCOPE_ALREADY_DEFINED: 'JOBS_SCOPE_ALREADY_DEFINED',\n JOBS_SCOPE_INVALID: 'JOBS_SCOPE_INVALID',\n\n // Actor errors\n JOBS_ACTOR_ALREADY_DEFINED: 'JOBS_ACTOR_ALREADY_DEFINED',\n JOBS_ACTOR_INVALID: 'JOBS_ACTOR_INVALID',\n\n // Job management errors\n JOBS_GET_FAILED: 'JOBS_GET_FAILED',\n JOBS_RETRY_FAILED: 'JOBS_RETRY_FAILED',\n JOBS_REMOVE_FAILED: 'JOBS_REMOVE_FAILED',\n JOBS_PROMOTE_FAILED: 'JOBS_PROMOTE_FAILED',\n JOBS_MOVE_FAILED: 'JOBS_MOVE_FAILED',\n JOBS_STATE_FAILED: 'JOBS_STATE_FAILED',\n JOBS_PROGRESS_FAILED: 'JOBS_PROGRESS_FAILED',\n JOBS_LOGS_FAILED: 'JOBS_LOGS_FAILED',\n\n // Worker errors\n JOBS_WORKER_CREATE_FAILED: 'JOBS_WORKER_CREATE_FAILED',\n JOBS_WORKER_START_FAILED: 'JOBS_WORKER_START_FAILED',\n JOBS_WORKER_STOP_FAILED: 'JOBS_WORKER_STOP_FAILED',\n JOBS_WORKER_NOT_FOUND: 'JOBS_WORKER_NOT_FOUND',\n JOBS_WORKER_ALREADY_RUNNING: 'JOBS_WORKER_ALREADY_RUNNING',\n\n // Event/Subscribe errors\n JOBS_SUBSCRIBE_FAILED: 'JOBS_SUBSCRIBE_FAILED',\n JOBS_UNSUBSCRIBE_FAILED: 'JOBS_UNSUBSCRIBE_FAILED',\n JOBS_EVENT_EMIT_FAILED: 'JOBS_EVENT_EMIT_FAILED',\n\n // Search errors\n JOBS_SEARCH_FAILED: 'JOBS_SEARCH_FAILED',\n JOBS_SEARCH_INVALID_TARGET: 'JOBS_SEARCH_INVALID_TARGET',\n\n // Shutdown errors\n JOBS_SHUTDOWN_FAILED: 'JOBS_SHUTDOWN_FAILED',\n\n // Handler errors\n JOBS_HANDLER_FAILED: 'JOBS_HANDLER_FAILED',\n JOBS_HANDLER_TIMEOUT: 'JOBS_HANDLER_TIMEOUT',\n} as const\n\n/**\n * Type for all possible error codes.\n */\nexport type IgniterJobsErrorCode = keyof typeof IGNITER_JOBS_ERROR_CODES\n\n/**\n * Options for creating an IgniterJobsError.\n */\nexport interface IgniterJobsErrorOptions {\n /**\n * Error code from IGNITER_JOBS_ERROR_CODES.\n */\n code: IgniterJobsErrorCode\n\n /**\n * Human-readable error message.\n */\n message: string\n\n /**\n * HTTP status code (for REST API responses).\n * @default 500\n */\n statusCode?: number\n\n /**\n * Original error that caused this error.\n */\n cause?: Error\n\n /**\n * Additional details for debugging.\n */\n details?: Record<string, unknown>\n\n /**\n * Logger instance for logging the error.\n */\n logger?: IgniterLogger\n}\n\n/**\n * Custom error class for @igniter-js/jobs.\n * Extends IgniterError for consistent error handling across the Igniter ecosystem.\n *\n * @example\n * ```typescript\n * throw new IgniterJobsError({\n * code: 'JOBS_DISPATCH_FAILED',\n * message: 'Failed to dispatch job to queue',\n * statusCode: 500,\n * details: { queue: 'email', job: 'sendWelcome' },\n * })\n * ```\n */\nexport class IgniterJobsError extends IgniterError {\n /**\n * Error code for programmatic handling.\n */\n public readonly code: IgniterJobsErrorCode\n\n /**\n * Additional error details.\n */\n public readonly details?: Record<string, unknown>\n\n constructor(options: IgniterJobsErrorOptions) {\n super({\n code: options.code,\n message: options.message,\n statusCode: options.statusCode ?? 500,\n causer: '@igniter-js/jobs',\n cause: options.cause,\n details: options.details,\n logger: options.logger,\n })\n\n this.code = options.code\n this.details = options.details\n this.name = 'IgniterJobsError'\n\n // Maintain proper stack trace\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, IgniterJobsError)\n }\n }\n\n /**\n * Convert error to a plain object for serialization.\n */\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n statusCode: this.statusCode,\n details: this.details,\n stack: this.stack,\n }\n }\n}\n","/**\n * @fileoverview Builder for creating workers\n * @module @igniter-js/jobs/builders/igniter-worker\n */\n\nimport type { IgniterWorkerBuilderState, IgniterWorkerHandle } from '../types'\nimport type { IgniterJobsAdapter, AdapterJobHandler } from '../types/adapter'\nimport { IgniterJobsError } from '../errors'\n\n/**\n * Builder for configuring and starting workers.\n *\n * @example\n * ```typescript\n * const worker = await jobs.worker\n * .create()\n * .forQueues('email', 'payment')\n * .withConcurrency(10)\n * .withLimiter({ max: 100, duration: 60000 })\n * .start()\n * ```\n */\nexport class IgniterWorkerBuilder {\n private state: IgniterWorkerBuilderState\n private adapter: IgniterJobsAdapter\n private jobHandler: AdapterJobHandler\n private availableQueues: string[]\n\n constructor(\n adapter: IgniterJobsAdapter,\n jobHandler: AdapterJobHandler,\n availableQueues: string[]\n ) {\n this.adapter = adapter\n this.jobHandler = jobHandler\n this.availableQueues = availableQueues\n this.state = {\n queues: [],\n concurrency: 1,\n }\n }\n\n /**\n * Specify which queues this worker should process.\n * If not called, worker processes all queues.\n *\n * @param queues - Queue names to process\n * @returns The builder for chaining\n *\n * @example\n * ```typescript\n * .forQueues('email', 'payment')\n * ```\n */\n forQueues(...queues: string[]): this {\n // Validate queue names exist\n for (const queue of queues) {\n if (!this.availableQueues.includes(queue)) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_NOT_FOUND',\n message: `Queue \"${queue}\" is not registered. Available queues: ${this.availableQueues.join(', ')}`,\n statusCode: 400,\n details: { queue, availableQueues: this.availableQueues },\n })\n }\n }\n\n this.state.queues = queues\n return this\n }\n\n /**\n * Set the concurrency level (jobs processed in parallel per queue).\n *\n * @param concurrency - Number of parallel jobs\n * @returns The builder for chaining\n *\n * @example\n * ```typescript\n * .withConcurrency(10)\n * ```\n */\n withConcurrency(concurrency: number): this {\n if (concurrency < 1) {\n throw new IgniterJobsError({\n code: 'JOBS_CONFIGURATION_INVALID',\n message: 'Concurrency must be at least 1',\n statusCode: 400,\n details: { concurrency },\n })\n }\n\n this.state.concurrency = concurrency\n return this\n }\n\n /**\n * Set the lock duration in milliseconds.\n * Jobs are locked for this duration while being processed.\n *\n * @param duration - Lock duration in milliseconds\n * @returns The builder for chaining\n *\n * @example\n * ```typescript\n * .withLockDuration(30000) // 30 seconds\n * ```\n */\n withLockDuration(duration: number): this {\n if (duration < 1000) {\n throw new IgniterJobsError({\n code: 'JOBS_CONFIGURATION_INVALID',\n message: 'Lock duration must be at least 1000ms',\n statusCode: 400,\n details: { duration },\n })\n }\n\n this.state.lockDuration = duration\n return this\n }\n\n /**\n * Configure rate limiting for the worker.\n *\n * @param config - Rate limiter configuration\n * @returns The builder for chaining\n *\n * @example\n * ```typescript\n * .withLimiter({ max: 100, duration: 60000 }) // 100 jobs per minute\n * ```\n */\n withLimiter(config: { max: number; duration: number }): this {\n if (config.max < 1) {\n throw new IgniterJobsError({\n code: 'JOBS_CONFIGURATION_INVALID',\n message: 'Limiter max must be at least 1',\n statusCode: 400,\n details: { max: config.max },\n })\n }\n\n if (config.duration < 1) {\n throw new IgniterJobsError({\n code: 'JOBS_CONFIGURATION_INVALID',\n message: 'Limiter duration must be at least 1ms',\n statusCode: 400,\n details: { duration: config.duration },\n })\n }\n\n this.state.limiter = config\n return this\n }\n\n /**\n * Set a callback to be called when the worker becomes idle.\n *\n * @param callback - Idle callback\n * @returns The builder for chaining\n *\n * @example\n * ```typescript\n * .onIdle(() => console.log('Worker is idle'))\n * ```\n */\n onIdle(callback: () => void): this {\n this.state.onIdle = callback\n return this\n }\n\n /**\n * Start the worker.\n *\n * @returns Worker handle for management\n *\n * @example\n * ```typescript\n * const worker = await jobs.worker\n * .create()\n * .forQueues('email')\n * .start()\n *\n * // Later\n * await worker.pause()\n * await worker.close()\n * ```\n */\n async start(): Promise<IgniterWorkerHandle> {\n // If no queues specified, use all available queues\n const queuesToProcess = this.state.queues.length > 0\n ? this.state.queues\n : this.availableQueues\n\n try {\n const handle = await this.adapter.createWorker(\n {\n queues: queuesToProcess,\n concurrency: this.state.concurrency,\n lockDuration: this.state.lockDuration,\n limiter: this.state.limiter,\n onIdle: this.state.onIdle,\n },\n this.jobHandler\n )\n\n return {\n id: handle.id,\n pause: () => handle.pause(),\n resume: () => handle.resume(),\n close: () => handle.close(),\n isRunning: () => handle.isRunning(),\n isPaused: () => handle.isPaused(),\n getMetrics: () => handle.getMetrics(),\n }\n } catch (error) {\n throw new IgniterJobsError({\n code: 'JOBS_WORKER_START_FAILED',\n message: 'Failed to start worker',\n statusCode: 500,\n cause: error instanceof Error ? error : undefined,\n details: { queues: queuesToProcess },\n })\n }\n }\n}\n","/**\n * @fileoverview IgniterJobs runtime class with proxy-based API\n * @module @igniter-js/jobs/core/igniter-jobs\n */\n\nimport type { IgniterLogger } from '@igniter-js/core'\nimport type { IgniterTelemetry } from '@igniter-js/telemetry'\nimport type {\n IgniterJobsAdapter,\n IgniterQueueBuilderState,\n IgniterJobDefinition,\n IgniterCronDefinition,\n IgniterJobScopeEntry,\n IgniterJobActorEntry,\n IgniterJobHandlerContext,\n IgniterCronHandlerContext,\n AdapterDispatchParams,\n AdapterScheduleParams,\n IgniterJobScopeOptions,\n IgniterJobActorOptions,\n IgniterJobEventHandler,\n IgniterJobUnsubscribeFn,\n IgniterQueueInfo,\n IgniterJobSearchResult,\n} from '../types'\nimport { IgniterJobsError } from '../errors'\nimport { IgniterWorkerBuilder } from '../builders/igniter-worker.builder'\n\n/**\n * Standard prefix for all job queues.\n */\nconst IGNITER_JOBS_PREFIX = 'igniter:jobs'\n\n/**\n * Get the full queue name with prefix.\n */\nfunction getFullQueueName(queueName: string): string {\n return `${IGNITER_JOBS_PREFIX}:${queueName}`\n}\n\n/**\n * Configuration passed to IgniterJobsRuntime.\n */\nexport interface IgniterJobsRuntimeConfig<\n TContext,\n TQueues extends Record<string, IgniterQueueBuilderState<TContext, any, any>>,\n TScope extends string,\n TActor extends string,\n> {\n adapter: IgniterJobsAdapter\n context: () => TContext | Promise<TContext>\n queues: TQueues\n scope?: { key: TScope; options?: IgniterJobScopeOptions }\n actor?: { key: TActor; options?: IgniterJobActorOptions }\n telemetry?: IgniterTelemetry\n logger?: IgniterLogger\n defaults?: {\n retry?: { attempts?: number; backoff?: any }\n timeout?: number\n removeOnComplete?: boolean | { count?: number; age?: number }\n removeOnFail?: boolean | { count?: number; age?: number }\n }\n}\n\n/**\n * Main runtime class for IgniterJobs.\n * Creates proxy-based API for type-safe job access.\n */\nexport class IgniterJobsRuntime<\n TContext,\n TQueues extends Record<string, IgniterQueueBuilderState<TContext, any, any>>,\n TScope extends string,\n TActor extends string,\n> {\n private readonly config: IgniterJobsRuntimeConfig<TContext, TQueues, TScope, TActor>\n private readonly queueNames: string[]\n\n constructor(config: IgniterJobsRuntimeConfig<TContext, TQueues, TScope, TActor>) {\n this.config = config\n this.queueNames = Object.keys(config.queues)\n\n // Return a proxy that provides the full API\n return this.createProxy()\n }\n\n /**\n * Create the main proxy that provides queue access and global methods.\n */\n private createProxy(): any {\n const self = this\n\n return new Proxy({}, {\n get(_, prop: string) {\n // Global methods\n if (prop === 'subscribe') {\n return self.createGlobalSubscribe()\n }\n\n if (prop === 'search') {\n return self.createSearch()\n }\n\n if (prop === 'worker') {\n return self.createWorkerBuilder()\n }\n\n if (prop === 'shutdown') {\n return () => self.shutdown()\n }\n\n // Queue access\n if (self.queueNames.includes(prop)) {\n return self.createQueueProxy(prop)\n }\n\n return undefined\n },\n\n has(_, prop: string) {\n return ['subscribe', 'search', 'worker', 'shutdown', ...self.queueNames].includes(prop)\n },\n\n ownKeys() {\n return ['subscribe', 'search', 'worker', 'shutdown', ...self.queueNames]\n },\n\n getOwnPropertyDescriptor(_, prop) {\n if (['subscribe', 'search', 'worker', 'shutdown', ...self.queueNames].includes(prop as string)) {\n return { configurable: true, enumerable: true }\n }\n return undefined\n },\n })\n }\n\n /**\n * Create a proxy for a specific queue.\n */\n private createQueueProxy(queueName: string): any {\n const self = this\n const queueConfig = this.config.queues[queueName]\n const jobNames = Object.keys(queueConfig.jobs)\n\n return new Proxy({}, {\n get(_, prop: string) {\n // Queue-level methods\n if (prop === 'subscribe') {\n return self.createQueueSubscribe(queueName)\n }\n\n if (prop === 'list') {\n return (options?: { status?: string[]; limit?: number }) =>\n self.listQueueJobs(queueName, options)\n }\n\n if (prop === 'get') {\n return () => self.createQueueManagement(queueName)\n }\n\n // Job access\n if (jobNames.includes(prop)) {\n return self.createJobProxy(queueName, prop)\n }\n\n return undefined\n },\n })\n }\n\n /**\n * Create a proxy for a specific job.\n */\n private createJobProxy(queueName: string, jobName: string): any {\n const self = this\n\n return {\n dispatch: (input: unknown, options?: any) =>\n self.dispatchJob(queueName, jobName, input, options),\n\n schedule: (params: any) =>\n self.scheduleJob(queueName, jobName, params),\n\n get: (jobId: string) =>\n self.createJobManagement(queueName, jobId),\n\n many: (jobIds: string[]) =>\n self.createJobBatchManagement(queueName, jobIds),\n\n pause: () =>\n self.pauseJobType(queueName, jobName),\n\n resume: () =>\n self.resumeJobType(queueName, jobName),\n\n subscribe: (handler: IgniterJobEventHandler) =>\n self.subscribeToJob(queueName, jobName, handler),\n }\n }\n\n /**\n * Dispatch a job.\n */\n private async dispatchJob(\n queueName: string,\n jobName: string,\n input: unknown,\n options?: {\n jobId?: string\n delay?: number\n priority?: number\n scope?: IgniterJobScopeEntry\n actor?: IgniterJobActorEntry\n }\n ): Promise<string> {\n const queueConfig = this.config.queues[queueName]\n const jobDef = queueConfig.jobs[jobName] as IgniterJobDefinition<TContext, any, any>\n\n // Validate input if schema provided\n if (jobDef.input) {\n try {\n const result = await (jobDef.input as any)['~standard'].validate(input)\n if (result.issues) {\n throw new IgniterJobsError({\n code: 'JOBS_INPUT_VALIDATION_FAILED',\n message: `Input validation failed for job \"${jobName}\"`,\n statusCode: 400,\n details: { issues: result.issues },\n })\n }\n input = result.value\n } catch (error) {\n if (error instanceof IgniterJobsError) throw error\n // Fallback to Zod-style validation\n if (typeof (jobDef.input as any).parse === 'function') {\n input = (jobDef.input as any).parse(input)\n }\n }\n }\n\n // Validate scope if required\n if (this.config.scope?.options?.required && !options?.scope) {\n throw new IgniterJobsError({\n code: 'JOBS_SCOPE_REQUIRED',\n message: `Scope \"${this.config.scope.key}\" is required for job dispatch`,\n statusCode: 400,\n details: { queue: queueName, job: jobName },\n })\n }\n\n const params: AdapterDispatchParams = {\n queue: getFullQueueName(queueName),\n name: jobName,\n data: input,\n jobId: options?.jobId,\n delay: options?.delay,\n priority: options?.priority ?? jobDef.priority,\n attempts: jobDef.retry?.attempts ?? this.config.defaults?.retry?.attempts ?? 3,\n backoff: jobDef.retry?.backoff ?? this.config.defaults?.retry?.backoff,\n removeOnComplete: jobDef.removeOnComplete ?? this.config.defaults?.removeOnComplete,\n removeOnFail: jobDef.removeOnFail ?? this.config.defaults?.removeOnFail,\n scope: options?.scope,\n actor: options?.actor,\n }\n\n try {\n const jobId = await this.config.adapter.dispatch(params)\n\n // Emit telemetry event\n if (this.config.telemetry) {\n // Telemetry emission would go here\n }\n\n return jobId\n } catch (error) {\n throw new IgniterJobsError({\n code: 'JOBS_DISPATCH_FAILED',\n message: `Failed to dispatch job \"${jobName}\" to queue \"${queueName}\"`,\n statusCode: 500,\n cause: error instanceof Error ? error : undefined,\n details: { queue: queueName, job: jobName },\n })\n }\n }\n\n /**\n * Schedule a job for future execution.\n */\n private async scheduleJob(\n queueName: string,\n jobName: string,\n params: {\n input: unknown\n at?: Date\n cron?: string\n every?: number\n timezone?: string\n jobId?: string\n scope?: IgniterJobScopeEntry\n actor?: IgniterJobActorEntry\n }\n ): Promise<string> {\n const queueConfig = this.config.queues[queueName]\n const jobDef = queueConfig.jobs[jobName] as IgniterJobDefinition<TContext, any, any>\n\n // Validate input if schema provided\n let validatedInput = params.input\n if (jobDef.input) {\n try {\n const result = await (jobDef.input as any)['~standard'].validate(params.input)\n if (result.issues) {\n throw new IgniterJobsError({\n code: 'JOBS_INPUT_VALIDATION_FAILED',\n message: `Input validation failed for job \"${jobName}\"`,\n statusCode: 400,\n details: { issues: result.issues },\n })\n }\n validatedInput = result.value\n } catch (error) {\n if (error instanceof IgniterJobsError) throw error\n if (typeof (jobDef.input as any).parse === 'function') {\n validatedInput = (jobDef.input as any).parse(params.input)\n }\n }\n }\n\n const scheduleParams: AdapterScheduleParams = {\n queue: getFullQueueName(queueName),\n name: jobName,\n data: validatedInput,\n jobId: params.jobId,\n at: params.at,\n cron: params.cron,\n every: params.every,\n timezone: params.timezone,\n attempts: jobDef.retry?.attempts ?? this.config.defaults?.retry?.attempts ?? 3,\n backoff: jobDef.retry?.backoff ?? this.config.defaults?.retry?.backoff,\n removeOnComplete: jobDef.removeOnComplete ?? this.config.defaults?.removeOnComplete,\n removeOnFail: jobDef.removeOnFail ?? this.config.defaults?.removeOnFail,\n scope: params.scope,\n actor: params.actor,\n }\n\n try {\n return await this.config.adapter.schedule(scheduleParams)\n } catch (error) {\n throw new IgniterJobsError({\n code: 'JOBS_SCHEDULE_FAILED',\n message: `Failed to schedule job \"${jobName}\" in queue \"${queueName}\"`,\n statusCode: 500,\n cause: error instanceof Error ? error : undefined,\n details: { queue: queueName, job: jobName },\n })\n }\n }\n\n /**\n * Create job management methods.\n */\n private createJobManagement(queueName: string, jobId: string) {\n const adapter = this.config.adapter\n const fullQueueName = getFullQueueName(queueName)\n\n return {\n retrieve: () => adapter.getJob(fullQueueName, jobId),\n retry: () => adapter.retryJob(fullQueueName, jobId),\n remove: () => adapter.removeJob(fullQueueName, jobId),\n state: () => adapter.getJobState(fullQueueName, jobId),\n progress: () => adapter.getJobProgress(fullQueueName, jobId),\n logs: () => adapter.getJobLogs(fullQueueName, jobId),\n promote: () => adapter.promoteJob(fullQueueName, jobId),\n move: (state: 'failed' | 'completed', reason?: string) =>\n adapter.moveJob(fullQueueName, jobId, state, reason),\n }\n }\n\n /**\n * Create batch job management methods.\n */\n private createJobBatchManagement(queueName: string, jobIds: string[]) {\n const adapter = this.config.adapter\n const fullQueueName = getFullQueueName(queueName)\n\n return {\n retry: () => adapter.retryJobs(fullQueueName, jobIds),\n remove: () => adapter.removeJobs(fullQueueName, jobIds),\n }\n }\n\n /**\n * Create queue management methods.\n */\n private createQueueManagement(queueName: string) {\n const adapter = this.config.adapter\n const fullQueueName = getFullQueueName(queueName)\n\n return {\n retrieve: () => adapter.getQueue(fullQueueName),\n pause: () => adapter.pauseQueue(fullQueueName),\n resume: () => adapter.resumeQueue(fullQueueName),\n drain: () => adapter.drainQueue(fullQueueName),\n clean: (options: { status: string | string[]; olderThan?: number; limit?: number }) =>\n adapter.cleanQueue(fullQueueName, {\n status: options.status as any,\n olderThan: options.olderThan,\n limit: options.limit,\n }),\n obliterate: (options?: { force?: boolean }) =>\n adapter.obliterateQueue(fullQueueName, options),\n retryAll: () => adapter.retryAllFailed(fullQueueName),\n }\n }\n\n /**\n * Pause a specific job type.\n */\n private async pauseJobType(queueName: string, jobName: string): Promise<void> {\n const fullQueueName = getFullQueueName(queueName)\n await this.config.adapter.pauseJobType(fullQueueName, jobName)\n }\n\n /**\n * Resume a specific job type.\n */\n private async resumeJobType(queueName: string, jobName: string): Promise<void> {\n const fullQueueName = getFullQueueName(queueName)\n await this.config.adapter.resumeJobType(fullQueueName, jobName)\n }\n\n /**\n * Subscribe to events for a specific job.\n */\n private async subscribeToJob(\n queueName: string,\n jobName: string,\n handler: IgniterJobEventHandler\n ): Promise<IgniterJobUnsubscribeFn> {\n const pattern = `${queueName}:${jobName}:*`\n return this.config.adapter.subscribe(pattern, handler)\n }\n\n /**\n * Create queue-level subscribe.\n */\n private createQueueSubscribe(queueName: string) {\n return async (handler: IgniterJobEventHandler): Promise<IgniterJobUnsubscribeFn> => {\n const pattern = `${queueName}:*`\n return this.config.adapter.subscribe(pattern, handler)\n }\n }\n\n /**\n * List jobs in a queue.\n */\n private async listQueueJobs(\n queueName: string,\n options?: { status?: string[]; limit?: number }\n ): Promise<IgniterJobSearchResult[]> {\n const fullQueueName = getFullQueueName(queueName)\n return this.config.adapter.listJobs(fullQueueName, {\n status: options?.status as any,\n end: options?.limit,\n })\n }\n\n /**\n * Create global subscribe.\n */\n private createGlobalSubscribe() {\n return async (handler: IgniterJobEventHandler): Promise<IgniterJobUnsubscribeFn> => {\n return this.config.adapter.subscribe('*', handler)\n }\n }\n\n /**\n * Create search function.\n */\n private createSearch() {\n const adapter = this.config.adapter\n\n return async (target: 'queues' | 'jobs' | 'workers', filter?: any) => {\n switch (target) {\n case 'queues':\n return adapter.searchQueues(filter || {})\n case 'jobs':\n return adapter.searchJobs(filter || {})\n case 'workers':\n // Workers search would return active worker info\n return []\n default:\n throw new IgniterJobsError({\n code: 'JOBS_SEARCH_INVALID_TARGET',\n message: `Invalid search target \"${target}\". Use \"queues\", \"jobs\", or \"workers\".`,\n statusCode: 400,\n })\n }\n }\n }\n\n /**\n * Create worker builder.\n */\n private createWorkerBuilder() {\n const self = this\n\n return {\n create: () => new IgniterWorkerBuilder(\n this.config.adapter,\n this.createJobHandler(),\n this.queueNames.map(q => getFullQueueName(q))\n ),\n }\n }\n\n /**\n * Create the job handler function for workers.\n */\n private createJobHandler() {\n const self = this\n\n return async (job: {\n id: string\n name: string\n queue: string\n data: unknown\n attempt: number\n timestamp: number\n scope?: IgniterJobScopeEntry\n actor?: IgniterJobActorEntry\n log: (level: 'info' | 'warn' | 'error', message: string) => Promise<void>\n updateProgress: (progress: number) => Promise<void>\n }): Promise<unknown> => {\n // Extract queue name from full queue name\n const queueName = job.queue.replace(`${IGNITER_JOBS_PREFIX}:`, '')\n const queueConfig = self.config.queues[queueName]\n\n if (!queueConfig) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_NOT_FOUND',\n message: `Queue \"${queueName}\" not found`,\n statusCode: 404,\n })\n }\n\n const jobDef = queueConfig.jobs[job.name] as IgniterJobDefinition<TContext, any, any>\n\n if (!jobDef) {\n throw new IgniterJobsError({\n code: 'JOBS_JOB_NOT_FOUND',\n message: `Job \"${job.name}\" not found in queue \"${queueName}\"`,\n statusCode: 404,\n })\n }\n\n // Get application context\n const context = await self.config.context()\n\n // Create handler context\n const ctx: IgniterJobHandlerContext<TContext, unknown> = {\n input: job.data,\n context,\n job: {\n id: job.id,\n name: job.name,\n queue: queueName,\n timestamp: job.timestamp,\n },\n attempt: job.attempt,\n scope: job.scope,\n actor: job.actor,\n log: job.log,\n updateProgress: job.updateProgress,\n }\n\n try {\n const result = await jobDef.handler(ctx)\n\n // Call onComplete hook if defined\n if (jobDef.onComplete) {\n await jobDef.onComplete(ctx, result)\n }\n\n return result\n } catch (error) {\n // Call onFailure hook if defined\n if (jobDef.onFailure) {\n await jobDef.onFailure(ctx, error instanceof Error ? error : new Error(String(error)))\n }\n\n throw error\n }\n }\n }\n\n /**\n * Shutdown the jobs instance.\n */\n private async shutdown(): Promise<void> {\n try {\n await this.config.adapter.shutdown()\n } catch (error) {\n throw new IgniterJobsError({\n code: 'JOBS_SHUTDOWN_FAILED',\n message: 'Failed to shutdown jobs instance',\n statusCode: 500,\n cause: error instanceof Error ? error : undefined,\n })\n }\n }\n}\n","/**\n * @fileoverview Builder for creating IgniterJobs instances\n * @module @igniter-js/jobs/builders/igniter-jobs\n *\n * @description\n * Provides a fluent builder API for configuring and creating IgniterJobs instances.\n * Supports adapter configuration, context provider, queues, scopes, actors, and telemetry.\n *\n * @example\n * ```typescript\n * import { IgniterJobs, IgniterQueue } from '@igniter-js/jobs'\n * import { BullMQAdapter } from '@igniter-js/jobs/adapters'\n * import Redis from 'ioredis'\n *\n * const redis = new Redis()\n *\n * const emailQueue = IgniterQueue.create<AppContext>('email')\n * .addJob('sendWelcome', { ... })\n * .build()\n *\n * const jobs = IgniterJobs.create<AppContext>()\n * .withAdapter(BullMQAdapter.create({ redis }))\n * .withContext(() => ({ db, mailer }))\n * .addQueue(emailQueue)\n * .addScope('organization')\n * .addActor('user')\n * .build()\n * ```\n */\n\nimport type { IgniterLogger } from '@igniter-js/core'\nimport type { IgniterTelemetry } from '@igniter-js/telemetry'\nimport type {\n IgniterJobsAdapter,\n IgniterJobsBuilderState,\n IgniterQueueBuilderState,\n IgniterJobDefinition,\n IgniterCronDefinition,\n IgniterJobScopeOptions,\n IgniterJobActorOptions,\n} from '../types'\nimport { IgniterJobsError } from '../errors'\nimport { IgniterJobsRuntime } from '../core/igniter-jobs'\n\n/**\n * Builder for creating IgniterJobs instances.\n *\n * @typeParam TContext - Application context type\n * @typeParam TQueues - Map of queue names to queue configs\n * @typeParam TScope - Scope key (only one allowed)\n * @typeParam TActor - Actor key (only one allowed)\n */\nexport class IgniterJobsBuilder<\n TContext = unknown,\n TQueues extends Record<string, IgniterQueueBuilderState<TContext, any, any>> = Record<string, never>,\n TScope extends string = never,\n TActor extends string = never,\n> {\n private readonly state: IgniterJobsBuilderState<TContext, TQueues, TScope, TActor>\n\n private constructor(state: IgniterJobsBuilderState<TContext, TQueues, TScope, TActor>) {\n this.state = state\n }\n\n /**\n * Create a new IgniterJobs builder.\n *\n * @returns A new IgniterJobsBuilder instance\n *\n * @example\n * ```typescript\n * const jobs = IgniterJobs.create<AppContext>()\n * .withAdapter(...)\n * .build()\n * ```\n */\n static create<TContext = unknown>(): IgniterJobsBuilder<TContext> {\n return new IgniterJobsBuilder<TContext>({\n queues: {} as Record<string, never>,\n })\n }\n\n /**\n * Configure the queue adapter (required).\n *\n * @param adapter - The queue adapter (e.g., BullMQAdapter)\n * @returns The builder with adapter configured\n *\n * @example\n * ```typescript\n * .withAdapter(BullMQAdapter.create({ redis }))\n * ```\n */\n withAdapter(\n adapter: IgniterJobsAdapter\n ): IgniterJobsBuilder<TContext, TQueues, TScope, TActor> {\n return new IgniterJobsBuilder({\n ...this.state,\n adapter,\n })\n }\n\n /**\n * Configure the application context provider (required).\n * This function is called for each job to provide the application context.\n *\n * @param contextFn - Function that returns the application context\n * @returns The builder with context configured\n *\n * @example\n * ```typescript\n * .withContext(() => ({\n * db: prisma,\n * mailer: mailerService,\n * cache: redis,\n * }))\n * ```\n */\n withContext(\n contextFn: () => TContext | Promise<TContext>\n ): IgniterJobsBuilder<TContext, TQueues, TScope, TActor> {\n return new IgniterJobsBuilder({\n ...this.state,\n context: contextFn,\n })\n }\n\n /**\n * Add a queue to the jobs instance.\n *\n * @param queue - Queue configuration from IgniterQueue.create().build()\n * @returns The builder with the queue added\n *\n * @example\n * ```typescript\n * const emailQueue = IgniterQueue.create<AppContext>('email')\n * .addJob('sendWelcome', { ... })\n * .build()\n *\n * const jobs = IgniterJobs.create<AppContext>()\n * .addQueue(emailQueue)\n * .build()\n * ```\n */\n addQueue<\n TQueueState extends IgniterQueueBuilderState<TContext, any, any>,\n >(\n queue: TQueueState\n ): IgniterJobsBuilder<\n TContext,\n TQueues & { [K in TQueueState['name']]: TQueueState },\n TScope,\n TActor\n > {\n const queueName = queue.name\n\n if (queueName in this.state.queues) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_ALREADY_EXISTS',\n message: `Queue \"${queueName}\" has already been added`,\n statusCode: 400,\n details: { queue: queueName },\n })\n }\n\n return new IgniterJobsBuilder({\n ...this.state,\n queues: {\n ...this.state.queues,\n [queueName]: queue,\n },\n } as IgniterJobsBuilderState<\n TContext,\n TQueues & { [K in TQueueState['name']]: TQueueState },\n TScope,\n TActor\n >)\n }\n\n /**\n * Add a scope for multi-tenancy (only one scope allowed).\n * Scopes are used to isolate jobs by organization, tenant, etc.\n *\n * @param key - Scope key (e.g., 'organization', 'tenant')\n * @param options - Optional scope configuration\n * @returns The builder with scope configured\n *\n * @example\n * ```typescript\n * .addScope('organization', { required: true })\n * ```\n */\n addScope<TScopeKey extends string>(\n key: TScope extends never ? TScopeKey : never,\n options?: IgniterJobScopeOptions\n ): IgniterJobsBuilder<TContext, TQueues, TScopeKey, TActor> {\n if (this.state.scope) {\n throw new IgniterJobsError({\n code: 'JOBS_SCOPE_ALREADY_DEFINED',\n message: `Scope \"${this.state.scope.key}\" is already defined. Only one scope is allowed.`,\n statusCode: 400,\n details: { existingScope: this.state.scope.key, newScope: key },\n })\n }\n\n return new IgniterJobsBuilder({\n ...this.state,\n scope: { key, options },\n } as unknown as IgniterJobsBuilderState<TContext, TQueues, TScopeKey, TActor>)\n }\n\n /**\n * Add an actor for auditing (only one actor type allowed).\n * Actors are used to track who initiated jobs.\n *\n * @param key - Actor key (e.g., 'user', 'system')\n * @param options - Optional actor configuration\n * @returns The builder with actor configured\n *\n * @example\n * ```typescript\n * .addActor('user', { description: 'The user who initiated the job' })\n * ```\n */\n addActor<TActorKey extends string>(\n key: TActor extends never ? TActorKey : never,\n options?: IgniterJobActorOptions\n ): IgniterJobsBuilder<TContext, TQueues, TScope, TActorKey> {\n if (this.state.actor) {\n throw new IgniterJobsError({\n code: 'JOBS_ACTOR_ALREADY_DEFINED',\n message: `Actor \"${this.state.actor.key}\" is already defined. Only one actor is allowed.`,\n statusCode: 400,\n details: { existingActor: this.state.actor.key, newActor: key },\n })\n }\n\n return new IgniterJobsBuilder({\n ...this.state,\n actor: { key, options },\n } as unknown as IgniterJobsBuilderState<TContext, TQueues, TScope, TActorKey>)\n }\n\n /**\n * Configure telemetry for observability (optional).\n *\n * @param telemetry - IgniterTelemetry instance\n * @returns The builder with telemetry configured\n *\n * @example\n * ```typescript\n * .withTelemetry(telemetry)\n * ```\n */\n withTelemetry(\n telemetry: IgniterTelemetry\n ): IgniterJobsBuilder<TContext, TQueues, TScope, TActor> {\n return new IgniterJobsBuilder({\n ...this.state,\n telemetry,\n })\n }\n\n /**\n * Configure a custom logger (optional).\n *\n * @param logger - Logger instance\n * @returns The builder with logger configured\n *\n * @example\n * ```typescript\n * .withLogger(customLogger)\n * ```\n */\n withLogger(\n logger: IgniterLogger\n ): IgniterJobsBuilder<TContext, TQueues, TScope, TActor> {\n return new IgniterJobsBuilder({\n ...this.state,\n logger,\n })\n }\n\n /**\n * Configure default job options applied to all jobs.\n *\n * @param defaults - Default job configuration\n * @returns The builder with defaults configured\n *\n * @example\n * ```typescript\n * .withDefaults({\n * retry: { attempts: 3, backoff: { type: 'exponential', delay: 1000 } },\n * timeout: 30000,\n * removeOnComplete: { count: 1000 },\n * })\n * ```\n */\n withDefaults(defaults: {\n retry?: {\n attempts?: number\n backoff?: {\n type: 'exponential' | 'fixed' | 'linear'\n delay: number\n maxDelay?: number\n }\n }\n timeout?: number\n removeOnComplete?: boolean | { count?: number; age?: number }\n removeOnFail?: boolean | { count?: number; age?: number }\n }): IgniterJobsBuilder<TContext, TQueues, TScope, TActor> {\n return new IgniterJobsBuilder({\n ...this.state,\n defaults,\n })\n }\n\n /**\n * Build the IgniterJobs instance.\n * Validates configuration and returns a fully typed jobs instance.\n *\n * @returns The IgniterJobs instance with proxy for typed access\n *\n * @throws {IgniterJobsError} If adapter is not configured\n * @throws {IgniterJobsError} If context is not configured\n * @throws {IgniterJobsError} If no queues are defined\n *\n * @example\n * ```typescript\n * const jobs = IgniterJobs.create<AppContext>()\n * .withAdapter(adapter)\n * .withContext(() => context)\n * .addQueue(emailQueue)\n * .build()\n *\n * // Now use with full type safety\n * await jobs.email.sendWelcome.dispatch({ userId: '123' })\n * ```\n */\n build(): IgniterJobsInstance<TContext, TQueues, TScope, TActor> {\n // Validate required configuration\n if (!this.state.adapter) {\n throw new IgniterJobsError({\n code: 'JOBS_ADAPTER_REQUIRED',\n message: 'Adapter is required. Use .withAdapter() to configure.',\n statusCode: 400,\n })\n }\n\n if (!this.state.context) {\n throw new IgniterJobsError({\n code: 'JOBS_CONTEXT_REQUIRED',\n message: 'Context provider is required. Use .withContext() to configure.',\n statusCode: 400,\n })\n }\n\n if (Object.keys(this.state.queues).length === 0) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_REQUIRED',\n message: 'At least one queue is required. Use .addQueue() to add queues.',\n statusCode: 400,\n })\n }\n\n // Create the runtime instance\n return new IgniterJobsRuntime<TContext, TQueues, TScope, TActor>(\n this.state as Required<Pick<typeof this.state, 'adapter' | 'context'>> & typeof this.state\n ) as unknown as IgniterJobsInstance<TContext, TQueues, TScope, TActor>\n }\n}\n\n/**\n * Type for the built IgniterJobs instance.\n * Provides typed access to queues, jobs, and management APIs.\n */\nexport type IgniterJobsInstance<\n TContext,\n TQueues extends Record<string, IgniterQueueBuilderState<TContext, any, any>>,\n TScope extends string,\n TActor extends string,\n> = {\n // Queue proxies (jobs.email.sendWelcome.dispatch(...))\n [QueueName in keyof TQueues]: IgniterQueueProxy<\n TContext,\n TQueues[QueueName]['jobs'],\n TQueues[QueueName]['crons'],\n TScope,\n TActor\n >\n} & {\n // Global subscribe\n subscribe: IgniterJobsGlobalSubscribe\n\n // Global search\n search: IgniterJobsSearch\n\n // Worker builder\n worker: IgniterJobsWorkerBuilder<TQueues>\n\n // Shutdown\n shutdown: () => Promise<void>\n}\n\n/**\n * Queue proxy type providing access to jobs and queue management.\n */\nexport type IgniterQueueProxy<\n TContext,\n TJobs extends Record<string, IgniterJobDefinition<TContext, any, any>>,\n TCrons extends Record<string, IgniterCronDefinition<TContext, any>>,\n TScope extends string,\n TActor extends string,\n> = {\n // Job proxies (jobs.email.sendWelcome)\n [JobName in keyof TJobs]: IgniterJobProxy<\n TContext,\n TJobs[JobName] extends IgniterJobDefinition<TContext, infer TInput, infer TOutput>\n ? TInput\n : unknown,\n TJobs[JobName] extends IgniterJobDefinition<TContext, infer TInput, infer TOutput>\n ? TOutput\n : unknown,\n TScope,\n TActor\n >\n} & {\n // Queue-level subscribe\n subscribe: (handler: (event: any) => void | Promise<void>) => Promise<() => Promise<void>>\n\n // Queue-level list\n list: (options?: { status?: string[]; limit?: number }) => Promise<any[]>\n\n // Queue management via .get()\n get: () => IgniterQueueManagement\n}\n\n/**\n * Job proxy type providing dispatch, schedule, and job management.\n */\nexport interface IgniterJobProxy<\n TContext,\n TInput,\n TOutput,\n TScope extends string,\n TActor extends string,\n> {\n // Dispatch job\n dispatch: IgniterJobDispatch<TInput, TScope, TActor>\n\n // Schedule job\n schedule: IgniterJobSchedule<TInput, TScope, TActor>\n\n // Get specific job by ID\n get: (jobId: string) => IgniterJobManagement\n\n // Batch operations\n many: (jobIds: string[]) => IgniterJobBatchManagement\n\n // Pause/Resume this job type\n pause: () => Promise<void>\n resume: () => Promise<void>\n\n // Subscribe to events for this job type\n subscribe: (handler: (event: any) => void | Promise<void>) => Promise<() => Promise<void>>\n}\n\n/**\n * Job dispatch function type.\n */\nexport type IgniterJobDispatch<TInput, TScope extends string, TActor extends string> = (\n input: TInput,\n options?: IgniterJobDispatchOptions<TScope, TActor>\n) => Promise<string>\n\n/**\n * Job dispatch options.\n */\nexport interface IgniterJobDispatchOptions<TScope extends string, TActor extends string> {\n jobId?: string\n delay?: number\n priority?: number\n scope?: TScope extends never ? never : { id: string; tags?: Record<string, string | number | boolean> }\n actor?: TActor extends never ? never : { id?: string; tags?: Record<string, string | number | boolean> }\n}\n\n/**\n * Job schedule function type.\n */\nexport type IgniterJobSchedule<TInput, TScope extends string, TActor extends string> = (params: {\n input: TInput\n at?: Date\n cron?: string\n every?: number\n timezone?: string\n jobId?: string\n scope?: TScope extends never ? never : { id: string; tags?: Record<string, string | number | boolean> }\n actor?: TActor extends never ? never : { id?: string; tags?: Record<string, string | number | boolean> }\n}) => Promise<string>\n\n/**\n * Single job management operations.\n */\nexport interface IgniterJobManagement {\n retrieve: () => Promise<any>\n retry: () => Promise<void>\n remove: () => Promise<void>\n state: () => Promise<string | null>\n progress: () => Promise<number>\n logs: () => Promise<any[]>\n promote: () => Promise<void>\n move: (state: 'failed' | 'completed', reason?: string) => Promise<void>\n}\n\n/**\n * Batch job management operations.\n */\nexport interface IgniterJobBatchManagement {\n retry: () => Promise<void>\n remove: () => Promise<void>\n}\n\n/**\n * Queue management operations.\n */\nexport interface IgniterQueueManagement {\n retrieve: () => Promise<any>\n pause: () => Promise<void>\n resume: () => Promise<void>\n drain: () => Promise<number>\n clean: (options: { status: string | string[]; olderThan?: number; limit?: number }) => Promise<number>\n obliterate: (options?: { force?: boolean }) => Promise<void>\n retryAll: () => Promise<number>\n}\n\n/**\n * Global subscribe function.\n */\nexport type IgniterJobsGlobalSubscribe = (\n handler: (event: any) => void | Promise<void>\n) => Promise<() => Promise<void>>\n\n/**\n * Search function.\n */\nexport interface IgniterJobsSearch {\n (target: 'queues', filter?: any): Promise<any[]>\n (target: 'jobs', filter?: any): Promise<any[]>\n (target: 'workers', filter?: any): Promise<any[]>\n}\n\n/**\n * Worker builder interface.\n */\nexport interface IgniterJobsWorkerBuilder<TQueues> {\n create: () => IgniterJobsWorkerConfig<TQueues>\n}\n\n/**\n * Worker configuration builder.\n */\nexport interface IgniterJobsWorkerConfig<TQueues> {\n forQueues: (...queues: (keyof TQueues)[]) => IgniterJobsWorkerConfig<TQueues>\n withConcurrency: (concurrency: number) => IgniterJobsWorkerConfig<TQueues>\n withLockDuration: (duration: number) => IgniterJobsWorkerConfig<TQueues>\n withLimiter: (config: { max: number; duration: number }) => IgniterJobsWorkerConfig<TQueues>\n onIdle: (callback: () => void) => IgniterJobsWorkerConfig<TQueues>\n start: () => Promise<any>\n}\n\n/**\n * Convenience alias for IgniterJobsBuilder.create().\n *\n * @example\n * ```typescript\n * import { IgniterJobs } from '@igniter-js/jobs'\n *\n * const jobs = IgniterJobs.create<AppContext>()\n * .withAdapter(adapter)\n * .withContext(() => context)\n * .addQueue(emailQueue)\n * .build()\n * ```\n */\nexport const IgniterJobs = {\n create: IgniterJobsBuilder.create,\n}\n","/**\n * @fileoverview Builder for creating IgniterQueue instances\n * @module @igniter-js/jobs/builders/igniter-queue\n *\n * @description\n * Provides a fluent builder API for defining queues with jobs and cron jobs.\n * Queues group related jobs together and provide type-safe job definitions.\n *\n * @example\n * ```typescript\n * import { IgniterQueue } from '@igniter-js/jobs'\n * import { z } from 'zod'\n *\n * const emailQueue = IgniterQueue.create<AppContext>('email')\n * .addJob('sendWelcome', {\n * input: z.object({\n * userId: z.string(),\n * email: z.string().email(),\n * }),\n * retry: { attempts: 3 },\n * handler: async (ctx) => {\n * await ctx.context.mailer.send({\n * to: ctx.input.email,\n * template: 'welcome',\n * })\n * },\n * })\n * .addCron('cleanupExpired', {\n * expression: '0 0 * * *',\n * handler: async (ctx) => {\n * await ctx.context.db.cleanup.expiredSessions()\n * },\n * })\n * .build()\n * ```\n */\n\nimport type { StandardSchemaV1 } from '@igniter-js/core'\nimport type {\n IgniterJobDefinition,\n IgniterCronDefinition,\n IgniterQueueBuilderState,\n} from '../types'\nimport { IgniterJobsError } from '../errors'\n\n/**\n * Validates a queue name.\n */\nfunction validateQueueName(name: string): void {\n if (!name || typeof name !== 'string') {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_NAME_INVALID',\n message: 'Queue name must be a non-empty string',\n statusCode: 400,\n })\n }\n\n if (!/^[a-z][a-z0-9-]*$/.test(name)) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_NAME_INVALID',\n message: `Queue name \"${name}\" must start with a lowercase letter and contain only lowercase letters, numbers, and hyphens`,\n statusCode: 400,\n details: { name },\n })\n }\n}\n\n/**\n * Validates a job name.\n */\nfunction validateJobName(name: string): void {\n if (!name || typeof name !== 'string') {\n throw new IgniterJobsError({\n code: 'JOBS_JOB_NAME_INVALID',\n message: 'Job name must be a non-empty string',\n statusCode: 400,\n })\n }\n\n if (!/^[a-zA-Z][a-zA-Z0-9]*$/.test(name)) {\n throw new IgniterJobsError({\n code: 'JOBS_JOB_NAME_INVALID',\n message: `Job name \"${name}\" must start with a letter and contain only letters and numbers (camelCase recommended)`,\n statusCode: 400,\n details: { name },\n })\n }\n}\n\n/**\n * Builder for creating queue configurations.\n *\n * @typeParam TContext - Application context type\n * @typeParam TJobs - Map of job names to definitions\n * @typeParam TCrons - Map of cron names to definitions\n */\nexport class IgniterQueueBuilder<\n TContext = unknown,\n TJobs extends Record<string, IgniterJobDefinition<TContext, any, any>> = Record<string, never>,\n TCrons extends Record<string, IgniterCronDefinition<TContext, any>> = Record<string, never>,\n> {\n private readonly state: IgniterQueueBuilderState<TContext, TJobs, TCrons>\n\n private constructor(state: IgniterQueueBuilderState<TContext, TJobs, TCrons>) {\n this.state = state\n }\n\n /**\n * Create a new queue builder.\n *\n * @param name - Queue name (kebab-case, e.g., 'email', 'payment-processing')\n * @returns A new IgniterQueueBuilder instance\n *\n * @example\n * ```typescript\n * const emailQueue = IgniterQueue.create<AppContext>('email')\n * ```\n */\n static create<TContext = unknown>(name: string): IgniterQueueBuilder<TContext> {\n validateQueueName(name)\n\n return new IgniterQueueBuilder<TContext>({\n name,\n jobs: {} as Record<string, never>,\n crons: {} as Record<string, never>,\n })\n }\n\n /**\n * Add a job definition to the queue.\n *\n * @param name - Job name (camelCase, e.g., 'sendWelcome', 'processPayment')\n * @param definition - Job definition with input schema, handler, retry config, etc.\n * @returns The builder with the new job added\n *\n * @example\n * ```typescript\n * .addJob('sendWelcome', {\n * input: z.object({\n * userId: z.string(),\n * email: z.string().email(),\n * }),\n * retry: { attempts: 3, backoff: { type: 'exponential', delay: 1000 } },\n * handler: async (ctx) => {\n * await ctx.context.mailer.send({\n * to: ctx.input.email,\n * template: 'welcome',\n * })\n * },\n * })\n * ```\n */\n addJob<\n TName extends string,\n TInput,\n TOutput = void,\n >(\n name: TName extends keyof TJobs ? never : TName,\n definition: IgniterJobDefinition<TContext, TInput, TOutput>\n ): IgniterQueueBuilder<\n TContext,\n TJobs & { [K in TName]: IgniterJobDefinition<TContext, TInput, TOutput> },\n TCrons\n > {\n validateJobName(name)\n\n if (name in this.state.jobs) {\n throw new IgniterJobsError({\n code: 'JOBS_JOB_ALREADY_EXISTS',\n message: `Job \"${name}\" already exists in queue \"${this.state.name}\"`,\n statusCode: 400,\n details: { queue: this.state.name, job: name },\n })\n }\n\n if (!definition.handler || typeof definition.handler !== 'function') {\n throw new IgniterJobsError({\n code: 'JOBS_JOB_HANDLER_REQUIRED',\n message: `Job \"${name}\" must have a handler function`,\n statusCode: 400,\n details: { queue: this.state.name, job: name },\n })\n }\n\n return new IgniterQueueBuilder({\n ...this.state,\n jobs: {\n ...this.state.jobs,\n [name]: definition,\n },\n } as IgniterQueueBuilderState<\n TContext,\n TJobs & { [K in TName]: IgniterJobDefinition<TContext, TInput, TOutput> },\n TCrons\n >)\n }\n\n /**\n * Add a cron job definition to the queue.\n *\n * @param name - Cron job name (camelCase)\n * @param definition - Cron definition with expression, handler, etc.\n * @returns The builder with the new cron added\n *\n * @example\n * ```typescript\n * .addCron('cleanupExpired', {\n * expression: '0 0 * * *', // Every day at midnight\n * timezone: 'America/New_York',\n * handler: async (ctx) => {\n * await ctx.context.db.cleanup.expiredSessions()\n * },\n * })\n * ```\n */\n addCron<TName extends string, TOutput = void>(\n name: TName extends keyof TCrons ? never : TName,\n definition: IgniterCronDefinition<TContext, TOutput>\n ): IgniterQueueBuilder<\n TContext,\n TJobs,\n TCrons & { [K in TName]: IgniterCronDefinition<TContext, TOutput> }\n > {\n validateJobName(name)\n\n if (name in this.state.crons) {\n throw new IgniterJobsError({\n code: 'JOBS_CRON_ALREADY_EXISTS',\n message: `Cron \"${name}\" already exists in queue \"${this.state.name}\"`,\n statusCode: 400,\n details: { queue: this.state.name, cron: name },\n })\n }\n\n if (!definition.expression || typeof definition.expression !== 'string') {\n throw new IgniterJobsError({\n code: 'JOBS_CRON_EXPRESSION_INVALID',\n message: `Cron \"${name}\" must have a valid expression`,\n statusCode: 400,\n details: { queue: this.state.name, cron: name },\n })\n }\n\n if (!definition.handler || typeof definition.handler !== 'function') {\n throw new IgniterJobsError({\n code: 'JOBS_CRON_HANDLER_REQUIRED',\n message: `Cron \"${name}\" must have a handler function`,\n statusCode: 400,\n details: { queue: this.state.name, cron: name },\n })\n }\n\n return new IgniterQueueBuilder({\n ...this.state,\n crons: {\n ...this.state.crons,\n [name]: definition,\n },\n } as IgniterQueueBuilderState<\n TContext,\n TJobs,\n TCrons & { [K in TName]: IgniterCronDefinition<TContext, TOutput> }\n >)\n }\n\n /**\n * Build the queue configuration.\n *\n * @returns The queue configuration ready to be registered with IgniterJobs\n *\n * @example\n * ```typescript\n * const emailQueue = IgniterQueue.create<AppContext>('email')\n * .addJob('sendWelcome', { ... })\n * .build()\n * ```\n */\n build(): IgniterQueueBuilderState<TContext, TJobs, TCrons> {\n return { ...this.state }\n }\n}\n\n/**\n * Convenience alias for IgniterQueueBuilder.create().\n * Use this to create queue configurations with a fluent API.\n *\n * @example\n * ```typescript\n * import { IgniterQueue } from '@igniter-js/jobs'\n *\n * const emailQueue = IgniterQueue.create<AppContext>('email')\n * .addJob('sendWelcome', { ... })\n * .build()\n * ```\n */\nexport const IgniterQueue = {\n create: IgniterQueueBuilder.create,\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/errors/jobs.error.ts","../src/builders/worker.builder.ts","../src/utils/prefix.ts","../src/utils/events.utils.ts","../src/utils/scope.ts","../src/utils/validation.ts","../src/core/manager.ts","../src/builders/queue.builder.ts","../src/core/queue.ts","../src/builders/main.builder.ts","../src/adapters/bullmq.adapter.ts","../src/utils/id-generator.ts","../src/adapters/memory.adapter.ts","../src/adapters/sqlite.adapter.ts"],"names":["options"],"mappings":"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","file":"index.mjs","sourcesContent":["import { IgniterError } from \"@igniter-js/common\";\n\n/**\n * Canonical error codes for `@igniter-js/jobs`.\n */\nexport const IGNITER_JOBS_ERROR_CODES = {\n JOBS_ADAPTER_REQUIRED: 'JOBS_ADAPTER_REQUIRED',\n JOBS_SERVICE_REQUIRED: 'JOBS_SERVICE_REQUIRED',\n JOBS_CONTEXT_REQUIRED: 'JOBS_CONTEXT_REQUIRED',\n JOBS_CONFIGURATION_INVALID: 'JOBS_CONFIGURATION_INVALID',\n JOBS_QUEUE_NOT_FOUND: 'JOBS_QUEUE_NOT_FOUND',\n JOBS_QUEUE_DUPLICATE: 'JOBS_QUEUE_DUPLICATE',\n JOBS_QUEUE_OPERATION_FAILED: 'JOBS_QUEUE_OPERATION_FAILED',\n JOBS_INVALID_DEFINITION: 'JOBS_INVALID_DEFINITION',\n JOBS_HANDLER_REQUIRED: 'JOBS_HANDLER_REQUIRED',\n JOBS_DUPLICATE_JOB: 'JOBS_DUPLICATE_JOB',\n JOBS_NOT_FOUND: 'JOBS_NOT_FOUND',\n JOBS_NOT_REGISTERED: 'JOBS_NOT_REGISTERED',\n JOBS_EXECUTION_FAILED: 'JOBS_EXECUTION_FAILED',\n JOBS_TIMEOUT: 'JOBS_TIMEOUT',\n JOBS_CONTEXT_FACTORY_FAILED: 'JOBS_CONTEXT_FACTORY_FAILED',\n JOBS_VALIDATION_FAILED: 'JOBS_VALIDATION_FAILED',\n JOBS_INVALID_INPUT: 'JOBS_INVALID_INPUT',\n JOBS_INVALID_CRON: 'JOBS_INVALID_CRON',\n JOBS_INVALID_SCHEDULE: 'JOBS_INVALID_SCHEDULE',\n JOBS_SCOPE_ALREADY_DEFINED: 'JOBS_SCOPE_ALREADY_DEFINED',\n JOBS_WORKER_FAILED: 'JOBS_WORKER_FAILED',\n JOBS_ADAPTER_ERROR: 'JOBS_ADAPTER_ERROR',\n JOBS_ADAPTER_CONNECTION_FAILED: 'JOBS_ADAPTER_CONNECTION_FAILED',\n JOBS_SUBSCRIBE_FAILED: 'JOBS_SUBSCRIBE_FAILED',\n} as const\n\nexport type IgniterJobsErrorCode = keyof typeof IGNITER_JOBS_ERROR_CODES\n\nexport interface IgniterJobsErrorOptions {\n /** Error code scoped to Igniter Jobs. */\n code: IgniterJobsErrorCode\n /** Human-readable message. */\n message: string\n /** HTTP-like status code hint (default: 500). */\n statusCode?: number\n /** Optional structured details for debugging and clients. */\n details?: unknown\n /** Optional metadata for logs and tracing. */\n metadata?: Record<string, unknown>\n /** Optional causer tag used by some Igniter tooling. */\n causer?: string\n /** Underlying cause for debugging (optional). */\n cause?: Error\n /** Optional logger passthrough to align with other Igniter errors. */\n logger?: any\n}\n\n/**\n * Typed error class for the Jobs package.\n *\n * @example\n * ```typescript\n * throw new IgniterJobsError({\n * code: 'JOBS_INVALID_INPUT',\n * message: 'Input payload failed validation',\n * })\n * ```\n */\nexport class IgniterJobsError extends IgniterError {\n constructor(options: IgniterJobsErrorOptions) {\n super(options)\n }\n}\n","/**\n * @fileoverview Worker builder for @igniter-js/jobs\n * @module @igniter-js/jobs/builders/igniter-worker\n */\n\nimport type { IgniterJobsAdapter } from '../types/adapter'\nimport type { IgniterJobsLimiter } from '../types/job'\nimport type { IgniterJobsWorkerHandle, IgniterJobsWorkerHandlers } from '../types/worker'\nimport { IgniterJobsError } from '../errors'\n\ntype IgniterJobsWorkerBuilderState<TAllowedQueues extends string> = {\n queues: TAllowedQueues[]\n concurrency?: number\n limiter?: IgniterJobsLimiter\n handlers: IgniterJobsWorkerHandlers\n}\n\n/**\n * Fluent builder for creating workers tied to registered queues.\n *\n * Instances of this builder are created by `jobs.worker.create()` so it can be\n * automatically scoped to registered queue names.\n */\nexport class IgniterWorkerBuilder<TAllowedQueues extends string> {\n private readonly adapter: IgniterJobsAdapter\n private readonly allowedQueues: readonly TAllowedQueues[]\n private readonly state: IgniterJobsWorkerBuilderState<TAllowedQueues>\n\n constructor(params: {\n adapter: IgniterJobsAdapter\n allowedQueues: readonly TAllowedQueues[]\n state?: Partial<IgniterJobsWorkerBuilderState<TAllowedQueues>>\n }) {\n this.adapter = params.adapter\n this.allowedQueues = params.allowedQueues\n this.state = {\n queues: params.state?.queues ?? [],\n concurrency: params.state?.concurrency,\n limiter: params.state?.limiter,\n handlers: params.state?.handlers ?? {},\n }\n }\n\n private clone(patch: Partial<IgniterJobsWorkerBuilderState<TAllowedQueues>>): IgniterWorkerBuilder<TAllowedQueues> {\n return new IgniterWorkerBuilder<TAllowedQueues>({\n adapter: this.adapter,\n allowedQueues: this.allowedQueues,\n state: { ...this.state, ...patch },\n })\n }\n\n /**\n * Adds a queue to the worker.\n *\n * @param queue - Queue name registered on the jobs instance.\n */\n public addQueue(queue: TAllowedQueues): IgniterWorkerBuilder<TAllowedQueues> {\n if (!this.allowedQueues.includes(queue)) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_NOT_FOUND',\n message: `Queue \"${queue}\" is not registered on this jobs instance.`,\n })\n }\n\n if (this.state.queues.includes(queue)) return this\n return this.clone({ queues: [...this.state.queues, queue] })\n }\n\n /**\n * Sets the worker concurrency.\n */\n public withConcurrency(concurrency: number): IgniterWorkerBuilder<TAllowedQueues> {\n if (!Number.isFinite(concurrency) || concurrency <= 0) {\n throw new IgniterJobsError({\n code: 'JOBS_CONFIGURATION_INVALID',\n message: 'Worker concurrency must be a positive number.',\n })\n }\n return this.clone({ concurrency })\n }\n\n /**\n * Sets a worker-level rate limiter.\n */\n public withLimiter(limiter: IgniterJobsLimiter): IgniterWorkerBuilder<TAllowedQueues> {\n if (!limiter || !Number.isFinite(limiter.max) || !Number.isFinite(limiter.duration) || limiter.max <= 0 || limiter.duration <= 0) {\n throw new IgniterJobsError({\n code: 'JOBS_CONFIGURATION_INVALID',\n message: 'Limiter must include positive max and duration.',\n })\n }\n return this.clone({ limiter })\n }\n\n public onActive(handler: NonNullable<IgniterJobsWorkerHandlers['onActive']>): IgniterWorkerBuilder<TAllowedQueues> {\n return this.clone({ handlers: { ...this.state.handlers, onActive: handler } })\n }\n\n public onSuccess(handler: NonNullable<IgniterJobsWorkerHandlers['onSuccess']>): IgniterWorkerBuilder<TAllowedQueues> {\n return this.clone({ handlers: { ...this.state.handlers, onSuccess: handler } })\n }\n\n public onFailure(handler: NonNullable<IgniterJobsWorkerHandlers['onFailure']>): IgniterWorkerBuilder<TAllowedQueues> {\n return this.clone({ handlers: { ...this.state.handlers, onFailure: handler } })\n }\n\n public onIdle(handler: NonNullable<IgniterJobsWorkerHandlers['onIdle']>): IgniterWorkerBuilder<TAllowedQueues> {\n return this.clone({ handlers: { ...this.state.handlers, onIdle: handler } })\n }\n\n /**\n * Builds and starts the worker.\n *\n * If no queues are added explicitly, the adapter should interpret it as \"all queues\".\n */\n public async start(): Promise<IgniterJobsWorkerHandle> {\n const concurrency = this.state.concurrency ?? 1\n return this.adapter.createWorker({\n queues: this.state.queues,\n concurrency,\n limiter: this.state.limiter,\n handlers: this.state.handlers,\n })\n }\n}\n\n","/**\n * Helpers for building consistent key/queue prefixes.\n */\nexport class IgniterJobsPrefix {\n public static readonly BASE_PREFIX = 'igniter:jobs'\n\n /**\n * Builds a normalized queue name using the global prefix and queue id.\n *\n * @example\n * ```typescript\n * const name = IgniterJobsPrefix.buildQueueName('email')\n * // -> igniter:jobs:email\n * ```\n */\n public static buildQueueName(queue: string): string {\n return `${IgniterJobsPrefix.BASE_PREFIX}:${queue}`\n }\n\n /**\n * Builds the event channel used for pub/sub.\n *\n * Unscoped events are published to a global channel per service/environment.\n * Scoped events are also published to an additional channel for that scope.\n */\n public static buildEventsChannel(params: {\n service: string\n environment: string\n scope?: { type: string; id: string | number }\n }): string {\n const base = `${IgniterJobsPrefix.BASE_PREFIX}:events:${params.environment}:${params.service}`\n if (!params.scope) return base\n return `${base}:scope:${params.scope.type}:${params.scope.id}`\n }\n}\n","/**\n * @fileoverview Event utilities for @igniter-js/jobs\n * @module @igniter-js/jobs/utils/events.utils\n */\n\nimport type { IgniterJobsAdapter } from \"../types/adapter\";\nimport type { IgniterJobsEvent } from \"../types/events\";\nimport type { IgniterJobsScopeEntry } from \"../types/scope\";\nimport { IgniterJobsPrefix } from \"./prefix\";\n\n/**\n * Static utility class for building and publishing job events.\n */\nexport class IgniterJobsEventsUtils {\n /**\n * Constructs a standardized job event type string.\n *\n * @param queue - The queue name.\n * @param jobName - The job name.\n * @param event - The specific event name (e.g., 'started', 'completed').\n * @returns A string in the format `queue:jobName:event`.\n */\n public static buildJobEventType(\n queue: string,\n jobName: string,\n event: string,\n ): string {\n return `${queue}:${jobName}:${event}`;\n }\n\n /**\n * Publishes a job event to the configured adapter.\n * Handles publishing to both the base channel and the scope-specific channel if a scope is provided.\n *\n * @param params - Configuration parameters for publishing the event.\n */\n public static async publishJobsEvent(params: {\n adapter: IgniterJobsAdapter;\n service: string;\n environment: string;\n scope?: IgniterJobsScopeEntry;\n event: IgniterJobsEvent;\n }): Promise<void> {\n const baseChannel = IgniterJobsPrefix.buildEventsChannel({\n service: params.service,\n environment: params.environment,\n });\n await params.adapter.publishEvent(baseChannel, params.event);\n\n if (params.scope) {\n const scopeChannel = IgniterJobsPrefix.buildEventsChannel({\n service: params.service,\n environment: params.environment,\n scope: { type: params.scope.type, id: params.scope.id },\n });\n await params.adapter.publishEvent(scopeChannel, params.event);\n }\n }\n}\n","/**\n * @fileoverview Scope utilities for @igniter-js/jobs\n * @module @igniter-js/jobs/utils/scope.utils\n */\n\nimport type { IgniterJobsScopeEntry } from \"../types/scope\";\n\n/**\n * Static utility class for handling job scopes and metadata.\n */\nexport class IgniterJobsScopeUtils {\n /**\n * The key used to store scope information in job metadata.\n */\n public static readonly SCOPE_METADATA_KEY = \"__igniter_jobs_scope\";\n\n /**\n * Merges a scope entry into a metadata object.\n *\n * @param metadata - Existing metadata object.\n * @param scope - The scope entry to merge.\n * @returns A new metadata object containing the scope information, or the original metadata if no scope is provided.\n */\n public static mergeMetadataWithScope(\n metadata: Record<string, unknown> | undefined,\n scope: IgniterJobsScopeEntry | undefined,\n ): Record<string, unknown> | undefined {\n if (!scope) return metadata;\n return {\n ...(metadata ?? {}),\n [this.SCOPE_METADATA_KEY]: scope,\n };\n }\n\n /**\n * Extracts a scope entry from a metadata object.\n *\n * @param metadata - The metadata object to inspect.\n * @returns The extracted scope entry, or undefined if not found.\n */\n public static extractScopeFromMetadata(\n metadata: Record<string, unknown> | undefined,\n ): IgniterJobsScopeEntry | undefined {\n if (!metadata) return undefined;\n const value = (metadata as any)[this.SCOPE_METADATA_KEY];\n if (!value || typeof value !== \"object\") return undefined;\n if (!(\"type\" in value) || !(\"id\" in value)) return undefined;\n return value as IgniterJobsScopeEntry;\n }\n}\n","/**\n * @fileoverview Validation utilities for @igniter-js/jobs\n * @module @igniter-js/jobs/utils/validation.utils\n */\n\nimport { IgniterJobsError } from \"../errors\";\nimport type { IgniterJobsSchema } from \"../types/schema\";\n\n/**\n * Static utility class for runtime input validation.\n */\nexport class IgniterJobsValidationUtils {\n /**\n * Checks if a value conforms to the Standard Schema V1 interface.\n *\n * @param value - The value to check.\n * @returns True if the value is a Standard Schema.\n */\n public static isStandardSchema(\n value: unknown,\n ): value is { \"~standard\": { validate: (value: unknown) => any } } {\n return Boolean(\n value && typeof value === \"object\" && \"~standard\" in (value as any),\n );\n }\n\n /**\n * Checks if a value conforms to a Zod-like schema interface.\n *\n * @param value - The value to check.\n * @returns True if the value is a Zod-like schema.\n */\n public static isZodLikeSchema(value: unknown): value is {\n safeParse?: (value: unknown) => any;\n parse: (value: unknown) => any;\n } {\n return Boolean(\n value && typeof value === \"object\" && \"parse\" in (value as any),\n );\n }\n\n /**\n * Validates input against a provided schema (Standard Schema or Zod-like).\n *\n * @param schema - The schema definition.\n * @param input - The input data to validate.\n * @returns The validated (and possibly transformed) data.\n * @throws {IgniterJobsError} If validation fails.\n */\n public static async validateInput(\n schema: IgniterJobsSchema,\n input: unknown,\n ): Promise<unknown> {\n if (this.isStandardSchema(schema)) {\n const result = await (schema as any)[\"~standard\"].validate(input);\n if (\"issues\" in result && result.issues) {\n const message = result.issues.map((i: any) => i.message).join(\"; \");\n throw new IgniterJobsError({\n code: \"JOBS_VALIDATION_FAILED\",\n message: `Input validation failed: ${message}`,\n details: { issues: result.issues },\n statusCode: 400,\n });\n }\n return (result as any).value;\n }\n\n if (this.isZodLikeSchema(schema)) {\n if (typeof (schema as any).safeParse === \"function\") {\n const result = (schema as any).safeParse(input);\n if (!result.success) {\n throw new IgniterJobsError({\n code: \"JOBS_VALIDATION_FAILED\",\n message: \"Input validation failed.\",\n details: { error: result.error },\n statusCode: 400,\n });\n }\n return result.data;\n }\n try {\n return (schema as any).parse(input);\n } catch (error) {\n throw new IgniterJobsError({\n code: \"JOBS_VALIDATION_FAILED\",\n message: \"Input validation failed.\",\n details: { error },\n statusCode: 400,\n });\n }\n }\n\n return input;\n }\n}\n","/**\n * @fileoverview Core IgniterJobsManager class with all job operations\n * @module @igniter-js/jobs/core\n *\n * @description\n * The main IgniterJobsManager class provides a type-safe, scoped API for background job processing.\n * It supports job dispatching, scheduling, worker management, queue operations, and scoped instances\n * for multi-tenant applications.\n *\n * @example\n * ```typescript\n * import { IgniterJobs, IgniterJobsMemoryAdapter } from '@igniter-js/jobs'\n * import { z } from 'zod'\n *\n * const emailQueue = IgniterQueue.create('email')\n * .addJob('sendWelcome', {\n * input: z.object({ to: z.string(), name: z.string() }),\n * handler: async (ctx) => {\n * await sendEmail(ctx.input.to, `Welcome ${ctx.input.name}!`)\n * },\n * })\n * .build()\n *\n * const jobs = IgniterJobs.create()\n * .withAdapter(IgniterJobsMemoryAdapter.create())\n * .withService('my-api')\n * .withEnvironment('production')\n * .withContext(async () => ({ db }))\n * .addQueue(emailQueue)\n * .build()\n *\n * // Dispatch a job\n * await jobs.email.sendWelcome.dispatch({ input: { to: 'user@example.com', name: 'Alice' } })\n *\n * // Scoped operations\n * const orgJobs = jobs.scope('organization', 'org_123')\n * await orgJobs.email.sendWelcome.dispatch({ input: { to: 'user@example.com', name: 'Bob' } })\n * ```\n */\n\nimport type { IgniterJobsConfig } from \"../types/config\";\nimport type { IgniterJobsRuntime } from \"../types/runtime\";\nimport type { IgniterJobsAdapter } from \"../types/adapter\";\nimport type {\n IgniterCronDefinition,\n IgniterJobDefinition,\n IgniterJobStatus,\n IgniterJobsDispatchParams,\n IgniterJobsExecutionContext,\n IgniterJobsHookContext,\n IgniterJobsScheduleParams,\n} from \"../types/job\";\nimport type {\n IgniterJobsEvent,\n IgniterJobsEventHandler,\n IgniterJobsTelemetry,\n} from \"../types/events\";\nimport type {\n IgniterJobsScopeEntry,\n IgniterJobsScopeOptions,\n} from \"../types/scope\";\nimport type { IgniterJobsQueue } from \"../types/queue\";\n\nimport { IgniterWorkerBuilder } from \"../builders/worker.builder\";\nimport { IgniterJobsError } from \"../errors\";\nimport { IgniterJobsPrefix } from \"../utils/prefix\";\nimport { IgniterJobsEventsUtils } from \"../utils/events.utils\";\nimport { IgniterJobsScopeUtils } from \"../utils/scope\";\nimport { IgniterJobsValidationUtils } from \"../utils/validation\";\n\n/**\n * WeakSet to track which adapters have already been registered.\n * This ensures that scoped instances don't re-register jobs.\n * @internal\n */\nconst registeredAdapters = new WeakSet<IgniterJobsAdapter>();\n\n/**\n * Main IgniterJobsManager class providing background job processing operations.\n *\n * Features:\n * - **Job Dispatching**: Enqueue jobs for immediate or delayed processing\n * - **Job Scheduling**: Schedule jobs with cron expressions or specific times\n * - **Worker Management**: Create and manage workers with configurable concurrency\n * - **Queue Operations**: Pause, resume, drain, clean queues\n * - **Scopes**: Multi-tenant isolation with scoped job instances\n * - **Telemetry**: Built-in observability with typed telemetry events\n *\n * @typeParam TConfig - The jobs configuration type\n */\nexport class IgniterJobsManager<\n TConfig extends IgniterJobsConfig<any, any, any> = IgniterJobsConfig<\n any,\n any,\n any\n >,\n> {\n /** @internal */\n private readonly config: TConfig;\n\n /** @internal */\n private readonly adapter: IgniterJobsAdapter;\n\n /** @internal */\n private readonly telemetry?: IgniterJobsTelemetry;\n\n /** @internal */\n private readonly scopeEntry?: IgniterJobsScopeEntry;\n\n /**\n * @internal\n * Constructor is internal. Use `IgniterJobs.create()` instead.\n */\n constructor(config: TConfig, scopeEntry?: IgniterJobsScopeEntry) {\n this.config = config;\n this.adapter = config.adapter;\n this.telemetry = config.telemetry;\n this.scopeEntry = scopeEntry;\n }\n\n // ---------------------------------------------------------------------------\n // Public Methods\n // ---------------------------------------------------------------------------\n\n /**\n * Creates a scoped jobs instance.\n *\n * Scopes provide multi-tenant isolation by adding scope metadata to all jobs.\n * Jobs dispatched from a scoped instance will include scope information in their metadata.\n *\n * @param type - The scope type (e.g., 'organization', 'workspace')\n * @param id - The scope identifier (e.g., 'org_123')\n * @param tags - Optional additional tags for the scope\n * @returns A new scoped IgniterJobsManager instance\n *\n * @example\n * ```typescript\n * const orgJobs = jobs.scope('organization', 'org_123')\n * await orgJobs.email.sendWelcome.dispatch({ input: { to: 'user@example.com' } })\n * ```\n */\n public scope(\n type: string,\n id: string | number,\n tags?: Record<string, unknown>,\n ): IgniterJobsManager<TConfig> {\n const entry: IgniterJobsScopeEntry = { type, id: String(id), tags };\n return new IgniterJobsManager(this.config, entry);\n }\n\n /**\n * Subscribes to all job events from this jobs instance.\n *\n * @param handler - The event handler function\n * @returns A function to unsubscribe\n *\n * @example\n * ```typescript\n * const unsubscribe = await jobs.subscribe((event) => {\n * console.log('Job event:', event.type, event.data)\n * })\n * // Later: await unsubscribe()\n * ```\n */\n public async subscribe(\n handler: IgniterJobsEventHandler,\n ): Promise<() => Promise<void>> {\n const channel = this.buildEventsChannel();\n return this.adapter.subscribeEvent(channel, async (payload: unknown) => {\n await handler(payload as IgniterJobsEvent);\n });\n }\n\n /**\n * Searches for jobs, queues, or workers based on filters.\n *\n * @param target - The target to search ('jobs', 'queues', or 'workers')\n * @param filter - The filter criteria\n * @returns The search results\n *\n * @example\n * ```typescript\n * const failedJobs = await jobs.search('jobs', { status: 'failed', queue: 'email' })\n * const queues = await jobs.search('queues', {})\n * ```\n */\n public async search(\n target: \"jobs\" | \"queues\" | \"workers\",\n filter: Record<string, unknown>,\n ): Promise<unknown[]> {\n switch (target) {\n case \"jobs\":\n return this.adapter.searchJobs(filter);\n case \"queues\":\n return this.adapter.searchQueues(filter);\n case \"workers\":\n return this.adapter.searchWorkers(filter);\n default:\n return [];\n }\n }\n\n /**\n * Gracefully shuts down the jobs instance.\n *\n * This will close all connections and stop all workers.\n *\n * @example\n * ```typescript\n * await jobs.shutdown()\n * ```\n */\n public async shutdown(): Promise<void> {\n await this.adapter.shutdown();\n }\n\n /**\n * Creates a new worker builder for processing jobs.\n *\n * @returns A new IgniterWorkerBuilder instance\n *\n * @example\n * ```typescript\n * const worker = await jobs.worker\n * .create()\n * .addQueue('email')\n * .withConcurrency(5)\n * .start()\n * ```\n */\n public get worker() {\n return {\n create: () =>\n new IgniterWorkerBuilder({\n adapter: this.adapter,\n allowedQueues: Object.keys(this.config.queues) as any,\n }),\n };\n }\n\n /**\n * Converts the manager to a runtime proxy with typed queue accessors.\n *\n * @internal\n * @returns The runtime proxy\n */\n public toRuntime(): IgniterJobsRuntime<TConfig> {\n this.ensureRegistered();\n\n const self = this;\n const queueNames = Object.keys(this.config.queues);\n\n // Create proxy to handle dynamic queue access\n const handler: ProxyHandler<IgniterJobsManager<TConfig>> = {\n get(target, prop: string) {\n // Handle known properties\n if (prop === \"config\") return target.config;\n if (prop === \"subscribe\") return target.subscribe.bind(target);\n if (prop === \"search\") return target.search.bind(target);\n if (prop === \"shutdown\") return target.shutdown.bind(target);\n if (prop === \"worker\") return target.worker;\n if (prop === \"scope\" && target.config.scopeDefinition) {\n return (\n type: string,\n id: string | number,\n tags?: Record<string, unknown>,\n ) => target.scope(type, id, tags).toRuntime();\n }\n\n // Handle queue access\n if (queueNames.includes(prop)) {\n return self.createQueueAccessor(prop);\n }\n\n return undefined;\n },\n };\n\n return new Proxy(this, handler) as unknown as IgniterJobsRuntime<TConfig>;\n }\n\n // ---------------------------------------------------------------------------\n // Private Methods - Registration\n // ---------------------------------------------------------------------------\n\n /**\n * Ensures all jobs and crons are registered with the adapter.\n * Uses a shared WeakSet to prevent duplicate registration across scoped instances.\n * @internal\n */\n private ensureRegistered(): void {\n if (registeredAdapters.has(this.adapter)) return;\n\n for (const [queueName, queue] of Object.entries(\n this.config.queues as Record<string, IgniterJobsQueue<any, any, any>>,\n )) {\n // Register jobs\n for (const [jobName, def] of Object.entries(\n queue.jobs as Record<string, IgniterJobDefinition<any, any, any>>,\n )) {\n this.adapter.registerJob(\n queueName,\n jobName,\n this.wrapJobDefinition(queueName, jobName, def),\n );\n }\n\n // Register crons\n for (const [cronName, cron] of Object.entries(\n queue.crons as Record<string, IgniterCronDefinition<any, any>>,\n )) {\n this.adapter.registerCron(\n queueName,\n cronName,\n this.wrapCronDefinition(queueName, cronName, cron),\n );\n }\n }\n\n registeredAdapters.add(this.adapter);\n }\n\n // ---------------------------------------------------------------------------\n // Private Methods - Accessors\n // ---------------------------------------------------------------------------\n\n /**\n * Creates a queue accessor with job accessors and management methods.\n * @internal\n */\n private createQueueAccessor(queueName: string): unknown {\n const queueConfig = this.config.queues[queueName] as IgniterJobsQueue<\n any,\n any,\n any\n >;\n const self = this;\n\n const queueAccessor: Record<string, unknown> = {\n async list(filter?: {\n status?: IgniterJobStatus[];\n limit?: number;\n offset?: number;\n }) {\n return self.adapter.queues.getJobs(queueName, filter);\n },\n\n get() {\n return {\n retrieve: () => self.adapter.getQueueInfo(queueName),\n pause: () => self.adapter.pauseQueue(queueName),\n resume: () => self.adapter.resumeQueue(queueName),\n drain: () => self.adapter.drainQueue(queueName),\n clean: (options: any) => self.adapter.cleanQueue(queueName, options),\n obliterate: (options?: { force?: boolean }) =>\n self.adapter.obliterateQueue(queueName, options),\n retryAll: () => self.adapter.retryAllInQueue(queueName),\n };\n },\n\n async subscribe(handler: IgniterJobsEventHandler) {\n const channel = self.buildEventsChannel();\n return self.adapter.subscribeEvent(channel, async (event: unknown) => {\n const typed = event as IgniterJobsEvent;\n if (\n typeof typed?.type === \"string\" &&\n typed.type.startsWith(`${queueName}:`)\n ) {\n await handler(typed);\n }\n });\n },\n\n jobs: {},\n };\n\n // Create job accessors\n for (const jobName of Object.keys(queueConfig.jobs)) {\n const jobAccessor = this.createJobAccessor(queueName, jobName);\n (queueAccessor.jobs as Record<string, unknown>)[jobName] = jobAccessor;\n queueAccessor[jobName] = jobAccessor;\n }\n\n return queueAccessor;\n }\n\n /**\n * Creates a job accessor with dispatch, schedule, and management methods.\n * @internal\n */\n private createJobAccessor(queueName: string, jobName: string): unknown {\n const self = this;\n\n return {\n async dispatch(params: IgniterJobsDispatchParams<any>) {\n return self.dispatchJob(queueName, jobName, params);\n },\n\n async schedule(params: IgniterJobsScheduleParams<any>) {\n return self.scheduleJob(queueName, jobName, params);\n },\n\n get(id: string) {\n return {\n retrieve: () => self.adapter.getJob(id, queueName),\n retry: () => self.adapter.retryJob(id, queueName),\n remove: () => self.adapter.removeJob(id, queueName),\n promote: () => self.adapter.promoteJob(id, queueName),\n move: (state: \"failed\", reason: string) => {\n if (state !== \"failed\") return Promise.resolve();\n return self.adapter.moveJobToFailed(id, reason, queueName);\n },\n state: () => self.adapter.getJobState(id, queueName),\n progress: () => self.adapter.getJobProgress(id, queueName),\n logs: () => self.adapter.getJobLogs(id, queueName),\n };\n },\n\n many(ids: string[]) {\n return {\n retry: () => self.adapter.retryManyJobs(ids, queueName),\n remove: () => self.adapter.removeManyJobs(ids, queueName),\n };\n },\n\n pause: () => self.adapter.pauseJobType(queueName, jobName),\n resume: () => self.adapter.resumeJobType(queueName, jobName),\n\n async subscribe(handler: IgniterJobsEventHandler) {\n const channel = self.buildEventsChannel();\n return self.adapter.subscribeEvent(channel, async (event: unknown) => {\n const typed = event as IgniterJobsEvent;\n if (\n typeof typed?.type === \"string\" &&\n typed.type.startsWith(`${queueName}:${jobName}:`)\n ) {\n await handler(typed);\n }\n });\n },\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private Methods - Job Operations\n // ---------------------------------------------------------------------------\n\n /**\n * Dispatches a job for immediate or delayed processing.\n * @internal\n */\n private async dispatchJob(\n queueName: string,\n jobName: string,\n params: IgniterJobsDispatchParams<any>,\n ): Promise<string> {\n const definition = this.getJobDefinition(queueName, jobName);\n\n // Validate input if schema exists\n if (definition?.input) {\n await IgniterJobsValidationUtils.validateInput(\n definition.input as any,\n params.input,\n );\n }\n\n // Resolve scope\n const scope = this.resolveScope(params.scope);\n const metadata = IgniterJobsScopeUtils.mergeMetadataWithScope(\n params.metadata as any,\n scope,\n );\n\n // Dispatch to adapter\n const jobId = await this.adapter.dispatch({\n queue: queueName,\n jobName,\n ...params,\n scope,\n metadata,\n });\n\n // Publish event\n await this.publishJobEvent(\n queueName,\n jobName,\n \"enqueued\",\n { jobId, queue: queueName, jobName },\n scope,\n );\n\n // Emit telemetry\n this.emitTelemetry(\"igniter.jobs.job.enqueued\", {\n \"ctx.job.id\": jobId,\n \"ctx.job.name\": jobName,\n \"ctx.job.queue\": queueName,\n \"ctx.job.priority\": (params as any).priority ?? null,\n \"ctx.job.delay\": (params as any).delay ?? null,\n });\n\n return jobId;\n }\n\n /**\n * Schedules a job for future processing.\n * @internal\n */\n private async scheduleJob(\n queueName: string,\n jobName: string,\n params: IgniterJobsScheduleParams<any>,\n ): Promise<string> {\n const definition = this.getJobDefinition(queueName, jobName);\n\n // Validate input if schema exists\n if (definition?.input) {\n await IgniterJobsValidationUtils.validateInput(\n definition.input as any,\n params.input,\n );\n }\n\n // Resolve scope\n const scope = this.resolveScope(params.scope);\n const metadata = IgniterJobsScopeUtils.mergeMetadataWithScope(\n params.metadata as any,\n scope,\n );\n\n // Schedule via adapter\n const jobId = await this.adapter.schedule({\n queue: queueName,\n jobName,\n ...params,\n scope,\n metadata,\n } as any);\n\n // Publish event\n await this.publishJobEvent(\n queueName,\n jobName,\n \"scheduled\",\n { jobId, queue: queueName, jobName },\n scope,\n );\n\n // Emit telemetry\n this.emitTelemetry(\"igniter.jobs.job.scheduled\", {\n \"ctx.job.id\": jobId,\n \"ctx.job.name\": jobName,\n \"ctx.job.queue\": queueName,\n \"ctx.job.scheduledAt\": (params as any).runAt?.toISOString?.() ?? null,\n \"ctx.job.cron\": (params as any).cron ?? null,\n });\n\n return jobId;\n }\n\n // ---------------------------------------------------------------------------\n // Private Methods - Handler Wrapping\n // ---------------------------------------------------------------------------\n\n /**\n * Wraps a job definition with context building, validation, and telemetry.\n * @internal\n */\n private wrapJobDefinition(\n queueName: string,\n jobName: string,\n definition: IgniterJobDefinition<any, any, any>,\n ): IgniterJobDefinition<any, any, any> {\n const self = this;\n\n return {\n ...definition,\n\n handler: async (ctx: IgniterJobsExecutionContext<any, any>) => {\n const enhanced = await self.buildExecutionContext(\n ctx,\n queueName,\n jobName,\n );\n\n // Validate input if schema exists\n if (definition.input) {\n const validated = await IgniterJobsValidationUtils.validateInput(\n definition.input as any,\n enhanced.input,\n );\n (enhanced as any).input = validated;\n }\n\n return definition.handler(enhanced);\n },\n\n onStart: async (ctx: IgniterJobsHookContext<any, any>) => {\n const enhanced = await self.buildExecutionContext(\n ctx as any,\n queueName,\n jobName,\n );\n\n // Publish lifecycle event\n await self.publishJobEvent(\n queueName,\n jobName,\n \"started\",\n {\n jobId: enhanced.job.id,\n jobName,\n queue: queueName,\n attemptsMade: enhanced.job.attemptsMade,\n startedAt: new Date().toISOString(),\n },\n (enhanced as any).scope,\n );\n\n // Emit telemetry\n self.emitTelemetry(\"igniter.jobs.job.started\", {\n \"ctx.job.id\": enhanced.job.id,\n \"ctx.job.name\": jobName,\n \"ctx.job.queue\": queueName,\n \"ctx.job.attempt\": enhanced.job.attemptsMade,\n \"ctx.job.maxAttempts\": definition.attempts ?? 3,\n });\n\n await definition.onStart?.(enhanced as any);\n },\n\n onSuccess: async (ctx: any) => {\n const enhanced = await self.buildExecutionContext(\n ctx as any,\n queueName,\n jobName,\n );\n const duration = ctx.duration ?? ctx.executionTime ?? 0;\n\n // Publish lifecycle event\n await self.publishJobEvent(\n queueName,\n jobName,\n \"completed\",\n {\n jobId: enhanced.job.id,\n jobName,\n queue: queueName,\n result: ctx.result,\n duration,\n completedAt: new Date().toISOString(),\n },\n (enhanced as any).scope,\n );\n\n // Emit telemetry\n self.emitTelemetry(\"igniter.jobs.job.completed\", {\n \"ctx.job.id\": enhanced.job.id,\n \"ctx.job.name\": jobName,\n \"ctx.job.queue\": queueName,\n \"ctx.job.duration\": typeof duration === \"number\" ? duration : 0,\n });\n\n await definition.onSuccess?.(enhanced as any);\n },\n\n onFailure: async (ctx: any) => {\n const enhanced = await self.buildExecutionContext(\n ctx as any,\n queueName,\n jobName,\n );\n const duration = ctx.duration ?? ctx.executionTime ?? 0;\n const isFinalAttempt = Boolean(ctx.isFinalAttempt);\n const errorMessage = ctx.error?.message ?? String(ctx.error);\n const errorCode = ctx.error?.code;\n const maxAttempts = definition.attempts ?? 3;\n\n // Publish lifecycle event\n await self.publishJobEvent(\n queueName,\n jobName,\n \"failed\",\n {\n jobId: enhanced.job.id,\n jobName,\n queue: queueName,\n error: { message: errorMessage },\n attemptsMade: enhanced.job.attemptsMade,\n isFinalAttempt,\n duration,\n failedAt: new Date().toISOString(),\n },\n (enhanced as any).scope,\n );\n\n // Emit telemetry\n self.emitTelemetry(\n \"igniter.jobs.job.failed\",\n {\n \"ctx.job.id\": enhanced.job.id,\n \"ctx.job.name\": jobName,\n \"ctx.job.queue\": queueName,\n \"ctx.job.error.message\": errorMessage,\n \"ctx.job.error.code\": errorCode ?? null,\n \"ctx.job.attempt\": enhanced.job.attemptsMade,\n \"ctx.job.maxAttempts\": maxAttempts,\n \"ctx.job.isFinalAttempt\": isFinalAttempt,\n },\n \"error\",\n );\n\n await definition.onFailure?.(enhanced as any);\n },\n\n onProgress: definition.onProgress\n ? async (ctx: any) => {\n const enhanced = await self.buildExecutionContext(\n ctx as any,\n queueName,\n jobName,\n );\n const progress = ctx.progress ?? 0;\n const message = ctx.message;\n\n // Publish lifecycle event\n await self.publishJobEvent(\n queueName,\n jobName,\n \"progress\",\n {\n jobId: enhanced.job.id,\n jobName,\n queue: queueName,\n progress,\n message,\n timestamp: new Date().toISOString(),\n },\n (enhanced as any).scope,\n );\n\n // Emit telemetry\n self.emitTelemetry(\"igniter.jobs.job.progress\", {\n \"ctx.job.id\": enhanced.job.id,\n \"ctx.job.name\": jobName,\n \"ctx.job.queue\": queueName,\n \"ctx.job.progress\": typeof progress === \"number\" ? progress : 0,\n \"ctx.job.progress.message\": message ?? null,\n });\n\n await definition.onProgress?.(enhanced as any);\n }\n : undefined,\n };\n }\n\n /**\n * Wraps a cron definition with context building and lifecycle events.\n * @internal\n */\n private wrapCronDefinition(\n queueName: string,\n cronName: string,\n definition: IgniterCronDefinition<any, any>,\n ): IgniterCronDefinition<any, any> {\n const self = this;\n\n return {\n ...definition,\n\n handler: async (ctx: any) => {\n const enhanced = await self.buildCronExecutionContext(\n ctx,\n queueName,\n cronName,\n );\n\n // Publish started event\n await self.publishJobEvent(\n queueName,\n cronName,\n \"started\",\n {\n jobId: enhanced.job?.id,\n jobName: cronName,\n queue: queueName,\n startedAt: new Date().toISOString(),\n },\n (enhanced as any).scope,\n );\n\n try {\n const result = await definition.handler(enhanced as any);\n\n // Publish completed event\n await self.publishJobEvent(\n queueName,\n cronName,\n \"completed\",\n {\n jobId: enhanced.job?.id,\n jobName: cronName,\n queue: queueName,\n result,\n completedAt: new Date().toISOString(),\n },\n (enhanced as any).scope,\n );\n\n return result;\n } catch (error) {\n // Publish failed event\n await self.publishJobEvent(\n queueName,\n cronName,\n \"failed\",\n {\n jobId: enhanced.job?.id,\n jobName: cronName,\n queue: queueName,\n error: { message: (error as any)?.message ?? String(error) },\n failedAt: new Date().toISOString(),\n },\n (enhanced as any).scope,\n );\n\n throw error;\n }\n },\n };\n }\n\n // ---------------------------------------------------------------------------\n // Private Methods - Helpers\n // ---------------------------------------------------------------------------\n\n /**\n * Builds the execution context for a job.\n * @internal\n */\n private async buildExecutionContext(\n ctx: IgniterJobsExecutionContext<any, any>,\n queueName: string,\n jobName: string,\n ): Promise<IgniterJobsExecutionContext<any, any>> {\n const realContext = await this.config.contextFactory();\n const scope =\n ctx.scope ??\n IgniterJobsScopeUtils.extractScopeFromMetadata(ctx.job.metadata as any);\n\n return {\n ...ctx,\n context: realContext,\n job: { ...ctx.job, name: jobName, queue: queueName },\n scope,\n };\n }\n\n /**\n * Builds the execution context for a cron job.\n * @internal\n */\n private async buildCronExecutionContext(\n ctx: Omit<IgniterJobsExecutionContext<any, unknown>, \"input\">,\n queueName: string,\n cronName: string,\n ): Promise<Omit<IgniterJobsExecutionContext<any, unknown>, \"input\">> {\n const realContext = await this.config.contextFactory();\n const scope =\n (ctx as any).scope ??\n IgniterJobsScopeUtils.extractScopeFromMetadata(\n (ctx as any).job?.metadata,\n );\n\n return {\n ...ctx,\n context: realContext,\n job: { ...(ctx as any).job, name: cronName, queue: queueName },\n scope,\n } as any;\n }\n\n /**\n * Gets a job definition by queue and job name.\n * @internal\n */\n private getJobDefinition(\n queueName: string,\n jobName: string,\n ): IgniterJobDefinition<any, any, any> | undefined {\n const queue = this.config.queues[queueName] as\n | IgniterJobsQueue<any, any, any>\n | undefined;\n return queue?.jobs?.[jobName];\n }\n\n /**\n * Resolves the effective scope for a job operation.\n * @internal\n */\n private resolveScope(\n paramsScope?: IgniterJobsScopeEntry,\n ): IgniterJobsScopeEntry | undefined {\n if (!this.config.scopeDefinition) return undefined;\n\n const required =\n Object.values(\n this.config.scopeDefinition as Record<string, IgniterJobsScopeOptions>,\n )[0]?.required ?? false;\n\n const effective = this.scopeEntry ?? paramsScope;\n\n if (required && !effective) {\n throw new IgniterJobsError({\n code: \"JOBS_CONFIGURATION_INVALID\",\n message: \"Scope is required for this jobs instance.\",\n });\n }\n\n if (this.scopeEntry && paramsScope) {\n if (\n this.scopeEntry.type !== paramsScope.type ||\n this.scopeEntry.id !== paramsScope.id\n ) {\n throw new IgniterJobsError({\n code: \"JOBS_CONFIGURATION_INVALID\",\n message: \"Cannot override scope on a scoped jobs instance.\",\n });\n }\n }\n\n return effective;\n }\n\n /**\n * Builds the events channel string for subscriptions.\n * @internal\n */\n private buildEventsChannel(): string {\n return this.scopeEntry\n ? IgniterJobsPrefix.buildEventsChannel({\n service: this.config.service,\n environment: this.config.environment,\n scope: { type: this.scopeEntry.type, id: this.scopeEntry.id },\n })\n : IgniterJobsPrefix.buildEventsChannel({\n service: this.config.service,\n environment: this.config.environment,\n });\n }\n\n /**\n * Publishes a job lifecycle event.\n * @internal\n */\n private async publishJobEvent(\n queueName: string,\n jobName: string,\n eventType: string,\n data: Record<string, unknown>,\n scope?: IgniterJobsScopeEntry,\n ): Promise<void> {\n await IgniterJobsEventsUtils.publishJobsEvent({\n adapter: this.adapter,\n service: this.config.service,\n environment: this.config.environment,\n scope,\n event: {\n type: IgniterJobsEventsUtils.buildJobEventType(\n queueName,\n jobName,\n eventType,\n ),\n data,\n timestamp: new Date(),\n scope,\n },\n });\n }\n\n /**\n * Emits a telemetry event if telemetry is configured.\n * @internal\n */\n private emitTelemetry(\n eventName: string,\n attributes: Record<string, string | number | boolean | null>,\n level: \"debug\" | \"info\" | \"error\" = \"info\",\n ): void {\n if (!this.telemetry) return;\n\n this.telemetry.emit(eventName, {\n attributes: attributes as any,\n level,\n });\n }\n}\n","/**\n * @fileoverview Queue builder for @igniter-js/jobs\n * @module @igniter-js/jobs/builders/igniter-queue\n */\n\nimport type {\n IgniterCronDefinition,\n IgniterJobDefinition,\n IgniterJobsQueue,\n} from '../types'\nimport type { IgniterJobsSchema } from '../types/schema'\nimport { IgniterJobsError } from '../errors'\n\ninterface IgniterQueueBuilderState<\n TContext,\n TJobs extends Record<string, IgniterJobDefinition<TContext, any, any>>,\n TCron extends Record<string, IgniterCronDefinition<TContext, any>>,\n TName extends string,\n> {\n name: TName\n jobs: TJobs\n crons: TCron\n}\n\n/**\n * Builder for defining queues, jobs, and cron tasks.\n *\n * @example\n * ```typescript\n * import { IgniterQueue } from '@igniter-js/jobs'\n * import { z } from 'zod'\n *\n * const emailQueue = IgniterQueue.create('email')\n * .withContext<{ mailer: Mailer }>()\n * .addJob('sendWelcome', {\n * input: z.object({ email: z.string().email() }),\n * handler: async ({ input, context }) => {\n * await context.mailer.send(input)\n * },\n * })\n * .addCron('cleanup', {\n * cron: '0 2 * * *',\n * handler: async ({ context }) => {\n * await context.mailer.cleanup()\n * },\n * })\n * .build()\n * ```\n */\nexport class IgniterQueueBuilder<\n TContext,\n TJobs extends Record<string, IgniterJobDefinition<TContext, any, any>> = {},\n TCron extends Record<string, IgniterCronDefinition<TContext, any>> = {},\n TName extends string = string,\n> {\n private readonly state: IgniterQueueBuilderState<TContext, TJobs, TCron, TName>\n\n private constructor(state: IgniterQueueBuilderState<TContext, TJobs, TCron, TName>) {\n this.state = state\n }\n\n /**\n * Creates a new queue builder for the given queue name.\n */\n public static create<const TName extends string>(\n name: TName,\n ): IgniterQueueBuilder<unknown, {}, {}, TName> {\n if (!name || typeof name !== 'string') {\n throw new IgniterJobsError({\n code: 'JOBS_CONFIGURATION_INVALID',\n message: 'Queue name must be a non-empty string.',\n })\n }\n\n return new IgniterQueueBuilder<unknown, {}, {}, TName>({\n name,\n jobs: {} as Record<string, any>,\n crons: {} as Record<string, any>,\n })\n }\n\n private clone<\n TNewJobs extends Record<string, IgniterJobDefinition<TContext, any, any>> = TJobs,\n TNewCron extends Record<string, IgniterCronDefinition<TContext, any>> = TCron,\n >(\n patch: Partial<IgniterQueueBuilderState<TContext, TNewJobs, TNewCron, TName>>,\n ): IgniterQueueBuilder<TContext, TNewJobs, TNewCron, TName> {\n return new IgniterQueueBuilder<TContext, TNewJobs, TNewCron, TName>({\n ...(this.state as unknown as IgniterQueueBuilderState<TContext, TNewJobs, TNewCron, TName>),\n ...patch,\n })\n }\n\n /**\n * Registers a job on the queue.\n *\n * @param jobName - Unique name of the job inside the queue.\n * @param definition - Job definition (handler, schemas, options, hooks).\n */\n public addJob<\n TJobName extends string,\n TInput extends IgniterJobsSchema | unknown,\n TResult = unknown,\n >(\n jobName: TJobName,\n definition: IgniterJobDefinition<TContext, TInput, TResult>,\n ): IgniterQueueBuilder<\n TContext,\n TJobs & Record<TJobName, IgniterJobDefinition<TContext, TInput, TResult>>,\n TCron,\n TName\n > {\n if (!jobName || typeof jobName !== 'string') {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_DEFINITION',\n message: 'Job name must be a non-empty string.',\n })\n }\n\n if ((this.state.jobs as Record<string, unknown>)[jobName]) {\n throw new IgniterJobsError({\n code: 'JOBS_DUPLICATE_JOB',\n message: `Job \"${jobName}\" is already registered in queue \"${this.state.name}\".`,\n })\n }\n\n if ((this.state.crons as Record<string, unknown>)[jobName]) {\n throw new IgniterJobsError({\n code: 'JOBS_DUPLICATE_JOB',\n message: `Job \"${jobName}\" conflicts with an existing cron in queue \"${this.state.name}\".`,\n })\n }\n\n if (!definition || typeof definition !== 'object') {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_DEFINITION',\n message: `Job \"${jobName}\" definition must be an object.`,\n })\n }\n\n if (!definition.handler || typeof definition.handler !== 'function') {\n throw new IgniterJobsError({\n code: 'JOBS_HANDLER_REQUIRED',\n message: `Job \"${jobName}\" handler is required and must be a function.`,\n })\n }\n\n const nextJobs = {\n ...(this.state.jobs as Record<string, any>),\n [jobName]: definition,\n } as TJobs & Record<TJobName, IgniterJobDefinition<TContext, TInput, TResult>>\n\n return this.clone<TJobs & Record<TJobName, IgniterJobDefinition<TContext, TInput, TResult>>>({\n jobs: nextJobs,\n })\n }\n\n /**\n * Registers a cron task on the queue.\n *\n * @param cronName - Unique name of the cron task inside the queue.\n * @param definition - Cron definition (cron string, tz, handler, options).\n */\n public addCron<TCronName extends string, TResult = unknown>(\n cronName: TCronName,\n definition: IgniterCronDefinition<TContext, TResult>,\n ): IgniterQueueBuilder<\n TContext,\n TJobs,\n TCron & Record<TCronName, IgniterCronDefinition<TContext, TResult>>,\n TName\n > {\n if (!cronName || typeof cronName !== 'string') {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_CRON',\n message: 'Cron name must be a non-empty string.',\n })\n }\n\n if ((this.state.crons as Record<string, unknown>)[cronName]) {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_CRON',\n message: `Cron \"${cronName}\" is already registered in queue \"${this.state.name}\".`,\n })\n }\n\n if ((this.state.jobs as Record<string, unknown>)[cronName]) {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_CRON',\n message: `Cron \"${cronName}\" conflicts with an existing job in queue \"${this.state.name}\".`,\n })\n }\n\n if (!definition || typeof definition !== 'object') {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_CRON',\n message: `Cron \"${cronName}\" definition must be an object.`,\n })\n }\n\n if (!definition.cron || typeof definition.cron !== 'string') {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_CRON',\n message: `Cron \"${cronName}\" must include a valid cron expression string.`,\n })\n }\n\n if (!definition.handler || typeof definition.handler !== 'function') {\n throw new IgniterJobsError({\n code: 'JOBS_HANDLER_REQUIRED',\n message: `Cron \"${cronName}\" handler is required and must be a function.`,\n })\n }\n\n const nextCrons = {\n ...(this.state.crons as Record<string, any>),\n [cronName]: definition,\n } as TCron & Record<TCronName, IgniterCronDefinition<TContext, TResult>>\n\n return this.clone<TJobs, TCron & Record<TCronName, IgniterCronDefinition<TContext, TResult>>>({\n crons: nextCrons,\n })\n }\n\n /**\n * Finalizes the queue definition.\n */\n public build(): IgniterJobsQueue<TContext, TJobs, TCron> & { name: TName } {\n return {\n name: this.state.name,\n jobs: this.state.jobs,\n crons: this.state.crons,\n } as IgniterJobsQueue<TContext, TJobs, TCron> & { name: TName }\n }\n}\n","/**\n * @fileoverview Public queue entry point for @igniter-js/jobs\n * @module @igniter-js/jobs/core/igniter-queue\n */\n\nimport { IgniterQueueBuilder } from '../builders/queue.builder'\n\n/**\n * Queue facade that exposes the fluent queue builder API.\n */\nexport class IgniterQueue {\n /**\n * Creates a new queue builder for the given name.\n *\n * @example\n * ```typescript\n * const queue = IgniterQueue.create('email')\n * .withContext<AppContext>()\n * .addJob('sendWelcome', { handler: async () => {} })\n * .build()\n * ```\n */\n public static create<const TName extends string>(name: TName) {\n return IgniterQueueBuilder.create(name)\n }\n}\n","/**\n * @fileoverview Builder for creating IgniterJobs instances\n * @module @igniter-js/jobs/builders/main\n *\n * @description\n * Provides a fluent builder API for configuring and creating IgniterJobs instances.\n * Supports adapter configuration, service naming, environment settings, queues,\n * scopes, telemetry, and more.\n *\n * @example\n * ```typescript\n * import { IgniterJobs, IgniterQueue } from '@igniter-js/jobs'\n * import { IgniterJobsMemoryAdapter } from '@igniter-js/jobs/adapters'\n * import { z } from 'zod'\n *\n * const emailQueue = IgniterQueue.create('email')\n * .addJob('sendWelcome', {\n * input: z.object({ to: z.string(), name: z.string() }),\n * handler: async (ctx) => {\n * await sendEmail(ctx.input.to, `Welcome ${ctx.input.name}!`)\n * },\n * })\n * .build()\n *\n * const jobs = IgniterJobs.create()\n * .withAdapter(IgniterJobsMemoryAdapter.create())\n * .withService('my-api')\n * .withEnvironment('production')\n * .withContext(async () => ({ db }))\n * .addQueue(emailQueue)\n * .build()\n * ```\n */\nimport type { IgniterLogger } from \"@igniter-js/common\";\nimport type { IgniterJobsConfig } from \"../types/config\";\nimport type { IgniterJobsRuntime } from \"../types/runtime\";\nimport type { IgniterJobsAdapter } from \"../types/adapter\";\nimport type { IgniterJobsQueue } from \"../types/queue\";\nimport type { IgniterJobsTelemetry } from \"../types/events\";\nimport type { IgniterJobsScopeOptions } from \"../types/scope\";\nimport type { IgniterJobsScopeDefinition } from \"../types/scope\";\nimport type { IgniterJobDefinition, IgniterJobsLimiter } from \"../types/job\";\nimport type { IgniterJobsWorkerBuilderConfig } from \"../types/worker\";\nimport { IgniterJobsError } from \"../errors\";\nimport { IgniterJobsManager } from \"../core/manager\";\n\ninterface IgniterJobsBuilderState<\n TContext,\n TQueues extends Record<string, IgniterJobsQueue<TContext, any, any>>,\n TScope extends string,\n> {\n adapter?: IgniterJobsAdapter;\n service?: string;\n environment?: string;\n contextFactory?: () => TContext | Promise<TContext>;\n queues: TQueues;\n scope?: { name: TScope; options?: IgniterJobsScopeOptions };\n queueDefaults?: Partial<IgniterJobDefinition<TContext, any, any>>;\n workerDefaults?: Partial<IgniterJobsWorkerBuilderConfig>;\n autoStartWorker?: {\n queues: (keyof TQueues)[];\n concurrency?: number;\n limiter?: IgniterJobsLimiter;\n };\n logger?: IgniterLogger;\n telemetry?: IgniterJobsTelemetry;\n}\n\n/**\n * Fluent builder responsible for configuring and constructing an `IgniterJobs` instance.\n *\n * The builder follows the immutable pattern used across Igniter packages: each\n * method returns a new builder with refined types. Only a single scope is\n * supported per the current specification (no actor support).\n */\nexport class IgniterJobsBuilder<\n TContext,\n TQueues extends Record<string, IgniterJobsQueue<TContext, any, any>> = {},\n TScope extends string = never,\n> {\n private readonly state: IgniterJobsBuilderState<TContext, TQueues, TScope>;\n\n private constructor(\n state?: Partial<IgniterJobsBuilderState<TContext, TQueues, TScope>>,\n ) {\n this.state = {\n queues: (state?.queues ?? ({} as TQueues)) as TQueues,\n ...state,\n } as IgniterJobsBuilderState<TContext, TQueues, TScope>;\n }\n\n /**\n * Creates the initial builder with no configuration.\n *\n * Context type is inferred from `withContext()` - no explicit generic needed.\n *\n * @example\n * ```typescript\n * // Context is inferred from the factory return type\n * const jobs = IgniterJobs.create()\n * .withContext(async () => ({ db: prisma, cache: redis }))\n * // TContext is now { db: PrismaClient, cache: Redis }\n * .build()\n * ```\n */\n public static create(): IgniterJobsBuilder<unknown> {\n return new IgniterJobsBuilder<unknown>({\n queues: {} as Record<string, any>,\n });\n }\n\n /**\n * Returns a new builder with updated state while preserving generics.\n */\n private clone<\n TNewQueues extends Record<string, IgniterJobsQueue<TContext, any, any>> =\n TQueues,\n TNewScope extends string = TScope,\n >(\n patch: Partial<IgniterJobsBuilderState<TContext, any, any>>,\n ): IgniterJobsBuilder<TContext, TNewQueues, TNewScope> {\n return new IgniterJobsBuilder<TContext, TNewQueues, TNewScope>({\n ...(this.state as any),\n ...(patch as any),\n queues: ((patch as any).queues ??\n (this.state.queues as unknown as TNewQueues)) as TNewQueues,\n scope: (patch as any).scope ?? (this.state.scope as any),\n });\n }\n\n /**\n * Attaches the jobs adapter.\n *\n * @param adapter - Backend adapter implementation (BullMQ, memory, etc.).\n */\n public withAdapter(\n adapter: IgniterJobsAdapter,\n ): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ adapter });\n }\n\n /**\n * Sets the service identifier for telemetry and metrics.\n *\n * @param service - Service name (e.g., \"my-api\").\n */\n public withService(\n service: string,\n ): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ service });\n }\n\n /**\n * Sets the environment name (e.g., development, staging, production).\n */\n public withEnvironment(\n environment: string,\n ): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ environment });\n }\n\n /**\n * Provides a context factory used when executing jobs.\n *\n * The context type is inferred from the factory return type, eliminating\n * the need for explicit generics on `IgniterJobs.create()`.\n *\n * **Note:** This must be called before adding any queues, as the context\n * type affects queue type compatibility.\n *\n * @param factory - Function that returns the context (sync or async)\n * @returns A new builder with the inferred context type\n *\n * @example\n * ```typescript\n * // Context type is inferred as { db: PrismaClient, cache: Redis }\n * const jobs = IgniterJobs.create()\n * .withContext(async () => ({\n * db: new PrismaClient(),\n * cache: new Redis(),\n * }))\n * .addQueue(emailQueue)\n * .build()\n * ```\n */\n public withContext<TNewContext>(\n this: IgniterJobsBuilder<unknown, {}, TScope>,\n factory: () => TNewContext | Promise<TNewContext>,\n ): IgniterJobsBuilder<TNewContext, {}, TScope> {\n return new IgniterJobsBuilder<TNewContext, {}, TScope>({\n ...(this.state as any),\n contextFactory: factory,\n queues: {},\n });\n }\n\n /**\n * Adds a scope definition (single scope supported).\n */\n public addScope<TNewScope extends string>(\n name: TNewScope,\n options?: IgniterJobsScopeOptions,\n ): IgniterJobsBuilder<TContext, TQueues, TScope | TNewScope> {\n if (this.state.scope) {\n throw new IgniterJobsError({\n code: \"JOBS_SCOPE_ALREADY_DEFINED\",\n message: \"Only one scope can be defined for IgniterJobs.\",\n });\n }\n return this.clone({ scope: { name: name as TScope | TNewScope, options } });\n }\n\n /**\n * Registers a queue definition on the builder.\n */\n public addQueue<\n TName extends string,\n TQueue extends IgniterJobsQueue<TContext, any, any>,\n >(\n queue: TQueue & { name: TName },\n ): IgniterJobsBuilder<TContext, TQueues & Record<TName, TQueue>, TScope> {\n if ((this.state.queues as Record<string, unknown>)[queue.name]) {\n throw new IgniterJobsError({\n code: \"JOBS_QUEUE_DUPLICATE\",\n message: `Queue \"${queue.name}\" is already registered.`,\n });\n }\n const nextQueues = {\n ...(this.state.queues as unknown as Record<string, TQueue>),\n [queue.name]: queue,\n } as TQueues & Record<TName, TQueue>;\n\n return this.clone<TQueues & Record<TName, TQueue>>({ queues: nextQueues });\n }\n\n /**\n * Applies default job options to all queues.\n */\n public withQueueDefaults(\n defaults: Partial<IgniterJobDefinition<TContext, any, any>>,\n ): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ queueDefaults: defaults });\n }\n\n /**\n * Applies default worker options.\n */\n public withWorkerDefaults(\n defaults: Partial<IgniterJobsWorkerBuilderConfig>,\n ): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ workerDefaults: defaults });\n }\n\n /**\n * Configures automatic worker startup.\n */\n public withAutoStartWorker(config: {\n queues: (keyof TQueues)[];\n concurrency?: number;\n limiter?: IgniterJobsLimiter;\n }): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ autoStartWorker: config });\n }\n\n /**\n * Attaches telemetry support.\n */\n public withTelemetry(\n telemetry: IgniterJobsTelemetry,\n ): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ telemetry });\n }\n\n /**\n * Attaches a custom logger.\n */\n public withLogger(\n logger: IgniterLogger,\n ): IgniterJobsBuilder<TContext, TQueues, TScope> {\n return this.clone({ logger });\n }\n\n /**\n * Finalizes the configuration and returns the runtime instance.\n */\n public build(): IgniterJobsRuntime<\n IgniterJobsConfig<TContext, TQueues, TScope>\n > {\n if (!this.state.adapter) {\n throw new IgniterJobsError({\n code: \"JOBS_ADAPTER_REQUIRED\",\n message: \"Jobs adapter is required. Call withAdapter() before build().\",\n });\n }\n\n if (!this.state.service) {\n throw new IgniterJobsError({\n code: \"JOBS_SERVICE_REQUIRED\",\n message: \"Service name is required. Call withService() before build().\",\n });\n }\n\n if (!this.state.environment) {\n throw new IgniterJobsError({\n code: \"JOBS_CONFIGURATION_INVALID\",\n message:\n \"Environment is required. Call withEnvironment() before build().\",\n });\n }\n\n if (!this.state.contextFactory) {\n throw new IgniterJobsError({\n code: \"JOBS_CONTEXT_REQUIRED\",\n message:\n \"Context factory is required. Call withContext() before build().\",\n });\n }\n\n const config: IgniterJobsConfig<TContext, TQueues, TScope> = {\n adapter: this.state.adapter,\n service: this.state.service,\n environment: this.state.environment,\n contextFactory: this.state.contextFactory,\n queues: this.state.queues,\n scopeDefinition: this.state.scope\n ? ({\n [this.state.scope.name]: (this.state.scope.options ??\n {}) as IgniterJobsScopeOptions,\n } as IgniterJobsScopeDefinition<TScope>)\n : undefined,\n queueDefaults: this.state.queueDefaults,\n workerDefaults: this.state.workerDefaults,\n autoStartWorker: this.state.autoStartWorker,\n logger: this.state.logger,\n telemetry: this.state.telemetry,\n };\n\n return new IgniterJobsManager(config).toRuntime();\n }\n}\n\n/**\n * Factory for creating and configuring IgniterJobs instances.\n *\n * This is the main entry point for creating a jobs runtime with a fluent builder API.\n * It provides type-safe configuration for adapters, queues, scopes, context, and telemetry.\n *\n * @example\n * ```typescript\n * import { IgniterJobs, IgniterQueue } from '@igniter-js/jobs'\n * import { IgniterJobsMemoryAdapter } from '@igniter-js/jobs/adapters'\n * import { z } from 'zod'\n *\n * const emailQueue = IgniterQueue.create('email')\n * .addJob('sendWelcome', {\n * input: z.object({ to: z.string(), name: z.string() }),\n * handler: async (ctx) => {\n * await sendEmail(ctx.input.to, `Welcome ${ctx.input.name}!`)\n * },\n * })\n * .build()\n *\n * const jobs = IgniterJobs.create()\n * .withAdapter(IgniterJobsMemoryAdapter.create())\n * .withService('my-api')\n * .withEnvironment('production')\n * .withContext(async () => ({ db }))\n * .addQueue(emailQueue)\n * .build()\n *\n * // Dispatch jobs\n * await jobs.email.sendWelcome.dispatch({ input: { to: 'user@example.com', name: 'Alice' } })\n *\n * // Use scopes for multi-tenancy\n * const orgJobs = jobs.scope('organization', 'org_123')\n * await orgJobs.email.sendWelcome.dispatch({ input: { to: 'user@example.com', name: 'Bob' } })\n * ```\n *\n * @see {@link IgniterJobsBuilder} for detailed method documentation\n */\nexport const IgniterJobs = {\n create: IgniterJobsBuilder.create,\n};\n","/**\n * @fileoverview BullMQ adapter for @igniter-js/jobs (wraps @igniter-js/adapter-bullmq)\n * @module @igniter-js/jobs/adapters/bullmq\n */\n\nimport type { Redis } from 'ioredis'\nimport type {\n AdvancedScheduleOptions,\n IgniterJobQueueAdapter,\n JobsRouter,\n JobDefinition as CoreJobDefinition,\n JobExecutionContext as CoreJobExecutionContext,\n JobWorkerConfig,\n} from '@igniter-js/core'\nimport { createBullMQAdapter } from '@igniter-js/adapter-bullmq'\nimport type {\n IgniterCronDefinition,\n IgniterJobDefinition,\n IgniterJobSearchResult,\n IgniterJobStatus,\n IgniterJobsAdapter,\n IgniterJobsAdapterDispatchParams,\n IgniterJobsAdapterScheduleParams,\n IgniterJobsBullMQAdapterOptions,\n IgniterJobsEventHandler,\n IgniterJobsJobLog,\n IgniterJobsQueueCleanOptions,\n IgniterJobsQueueInfo,\n IgniterJobsQueueManager,\n IgniterJobsWorkerBuilderConfig,\n IgniterJobsWorkerHandle,\n IgniterJobsWorkerMetrics,\n} from '../types'\nimport { IgniterJobsPrefix } from '../utils/prefix'\nimport { IgniterJobsError } from '../errors'\n\ntype CoreMergedExecutor = ReturnType<IgniterJobQueueAdapter<any>['merge']>\n\nfunction toDateArray(values?: Array<string | Date>): Date[] | undefined {\n if (!values) return undefined\n return values.map((v) => (v instanceof Date ? v : new Date(v)))\n}\n\n/**\n * BullMQ adapter facade.\n *\n * It reuses the mature BullMQ integration from `@igniter-js/adapter-bullmq` to keep\n * feature parity (workers, queue/job management, advanced scheduling, hooks).\n */\nexport class IgniterJobsBullMQAdapter implements IgniterJobsAdapter {\n public readonly client: unknown\n\n private readonly redis: Redis\n private readonly publisher: Redis\n private readonly subscriber: Redis\n private readonly subscribers = new Map<string, Set<(payload: any) => void>>()\n\n private coreAdapter: IgniterJobQueueAdapter<any> | null = null\n private coreExecutor: CoreMergedExecutor | null = null\n private executorDirty = true\n\n private readonly jobsByQueue = new Map<string, Map<string, IgniterJobDefinition<any, any, any>>>()\n private readonly cronsByQueue = new Map<string, Map<string, IgniterCronDefinition<any, any>>>()\n\n public readonly queues: IgniterJobsQueueManager\n\n private constructor(options: IgniterJobsBullMQAdapterOptions) {\n this.redis = options.redis\n this.publisher = this.redis\n this.subscriber = this.redis.duplicate()\n this.client = { redis: this.redis }\n\n this.subscriber.on('message', (channel: string, message: string) => {\n const set = this.subscribers.get(channel)\n if (!set || set.size === 0) return\n let payload: any = message\n try {\n payload = JSON.parse(message)\n } catch {\n // ignore, treat as raw\n }\n for (const handler of set) handler(payload)\n })\n\n this.queues = {\n list: async () => this.listQueues(),\n get: async (name) => this.getQueueInfo(name),\n getJobCounts: async (name) => this.getQueueJobCounts(name),\n getJobs: async (name, filter) => {\n const full = this.toCoreQueueName(name)\n return this.core().queues.getJobs(full, filter as any) as any\n },\n pause: async (name) => this.pauseQueue(name),\n resume: async (name) => this.resumeQueue(name),\n isPaused: async (name) => {\n const full = this.toCoreQueueName(name)\n return this.core().queues.isPaused(full)\n },\n drain: async (name) => this.drainQueue(name),\n clean: async (name, options) => this.cleanQueue(name, options),\n obliterate: async (name, options) => this.obliterateQueue(name, options),\n }\n }\n\n public static create(options: IgniterJobsBullMQAdapterOptions): IgniterJobsAdapter {\n return new IgniterJobsBullMQAdapter(options)\n }\n\n public registerJob(queueName: string, jobName: string, definition: IgniterJobDefinition<any, any, any>): void {\n const map = this.jobsByQueue.get(queueName) ?? new Map()\n if (map.has(jobName)) {\n throw new IgniterJobsError({\n code: 'JOBS_DUPLICATE_JOB',\n message: `Job \"${jobName}\" is already registered in queue \"${queueName}\".`,\n })\n }\n map.set(jobName, definition)\n this.jobsByQueue.set(queueName, map)\n this.executorDirty = true\n }\n\n public registerCron(queueName: string, cronName: string, definition: IgniterCronDefinition<any, any>): void {\n const map = this.cronsByQueue.get(queueName) ?? new Map()\n if (map.has(cronName)) {\n throw new IgniterJobsError({\n code: 'JOBS_INVALID_CRON',\n message: `Cron \"${cronName}\" is already registered in queue \"${queueName}\".`,\n })\n }\n map.set(cronName, definition)\n this.cronsByQueue.set(queueName, map)\n this.executorDirty = true\n }\n\n public async dispatch(params: IgniterJobsAdapterDispatchParams): Promise<string> {\n const executor = await this.executor()\n const namespace = (executor as any)[params.queue]\n if (!namespace) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_NOT_FOUND',\n message: `Queue \"${params.queue}\" is not registered in the adapter.`,\n })\n }\n return namespace.enqueue({\n task: params.jobName,\n input: params.input,\n jobId: params.jobId,\n delay: params.delay,\n priority: params.priority,\n attempts: params.attempts,\n metadata: params.metadata as any,\n removeOnComplete: params.removeOnComplete as any,\n removeOnFail: params.removeOnFail as any,\n limiter: params.limiter as any,\n })\n }\n\n public async schedule(params: IgniterJobsAdapterScheduleParams): Promise<string> {\n const executor = await this.executor()\n const namespace = (executor as any)[params.queue]\n if (!namespace) {\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_NOT_FOUND',\n message: `Queue \"${params.queue}\" is not registered in the adapter.`,\n })\n }\n\n const schedule: AdvancedScheduleOptions = {\n jobId: params.jobId,\n delay: params.delay,\n priority: params.priority,\n attempts: params.attempts,\n metadata: params.metadata as any,\n removeOnComplete: params.removeOnComplete as any,\n removeOnFail: params.removeOnFail as any,\n limiter: params.limiter as any,\n at: params.at,\n repeat:\n params.cron ||\n params.every ||\n params.maxExecutions ||\n params.skipWeekends ||\n params.onlyBusinessHours ||\n params.businessHours ||\n params.onlyWeekdays ||\n params.skipDates\n ? {\n cron: params.cron,\n every: params.every,\n times: params.maxExecutions,\n skipWeekends: params.skipWeekends,\n onlyBusinessHours: params.onlyBusinessHours,\n businessHours: params.businessHours,\n onlyWeekdays: params.onlyWeekdays,\n skipDates: toDateArray(params.skipDates),\n }\n : undefined,\n }\n\n return namespace.schedule({\n task: params.jobName,\n input: params.input,\n ...schedule,\n })\n }\n\n public async getJob(jobId: string, queue?: string): Promise<IgniterJobSearchResult | null> {\n const result = await this.core().job.get(jobId, queue ? this.toCoreQueueName(queue) : undefined)\n return result ? this.mapJob(result, queue) : null\n }\n\n public async getJobState(jobId: string, queue?: string): Promise<IgniterJobStatus | null> {\n const state = await this.core().job.getState(jobId, queue ? this.toCoreQueueName(queue) : undefined)\n return state as any\n }\n\n public async getJobLogs(jobId: string, queue?: string): Promise<IgniterJobsJobLog[]> {\n const logs = await this.core().job.getLogs(jobId, queue ? this.toCoreQueueName(queue) : undefined)\n return logs as any\n }\n\n public async getJobProgress(jobId: string, queue?: string): Promise<number> {\n return this.core().job.getProgress(jobId, queue ? this.toCoreQueueName(queue) : undefined)\n }\n\n public async retryJob(jobId: string, queue?: string): Promise<void> {\n await this.core().job.retry(jobId, queue ? this.toCoreQueueName(queue) : undefined)\n }\n\n public async removeJob(jobId: string, queue?: string): Promise<void> {\n await this.core().job.remove(jobId, queue ? this.toCoreQueueName(queue) : undefined)\n }\n\n public async promoteJob(jobId: string, queue?: string): Promise<void> {\n await this.core().job.promote(jobId, queue ? this.toCoreQueueName(queue) : undefined)\n }\n\n public async moveJobToFailed(jobId: string, reason: string, queue?: string): Promise<void> {\n await this.core().job.moveToFailed(jobId, reason, queue ? this.toCoreQueueName(queue) : undefined)\n }\n\n public async retryManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await this.core().job.retryMany(jobIds, queue ? this.toCoreQueueName(queue) : undefined)\n }\n\n public async removeManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await this.core().job.removeMany(jobIds, queue ? this.toCoreQueueName(queue) : undefined)\n }\n\n public async getQueueInfo(queue: string): Promise<IgniterJobsQueueInfo | null> {\n const info = await this.core().queues.get(this.toCoreQueueName(queue))\n if (!info) return null\n return this.mapQueueInfo(info)\n }\n\n public async getQueueJobCounts(queue: string): Promise<any> {\n const counts = await this.core().queues.getJobCounts(this.toCoreQueueName(queue))\n return counts as any\n }\n\n public async listQueues(): Promise<IgniterJobsQueueInfo[]> {\n const list = await this.core().queues.list()\n return list.map((q) => this.mapQueueInfo(q))\n }\n\n public async pauseQueue(queue: string): Promise<void> {\n await this.core().queues.pause(this.toCoreQueueName(queue))\n }\n\n public async resumeQueue(queue: string): Promise<void> {\n await this.core().queues.resume(this.toCoreQueueName(queue))\n }\n\n public async drainQueue(queue: string): Promise<number> {\n return this.core().queues.drain(this.toCoreQueueName(queue))\n }\n\n public async cleanQueue(queue: string, options: IgniterJobsQueueCleanOptions): Promise<number> {\n return this.core().queues.clean(this.toCoreQueueName(queue), options as any)\n }\n\n public async obliterateQueue(queue: string, options?: { force?: boolean }): Promise<void> {\n await this.core().queues.obliterate(this.toCoreQueueName(queue), options)\n }\n\n public async retryAllInQueue(queue: string): Promise<number> {\n const jobs = await this.core().queues.getJobs(this.toCoreQueueName(queue), { status: ['failed'], limit: 1000 } as any)\n await Promise.all(jobs.map((j) => this.core().job.retry(j.id, this.toCoreQueueName(queue))))\n return jobs.length\n }\n\n public async pauseJobType(queue: string, jobName: string): Promise<void> {\n void queue\n void jobName\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_OPERATION_FAILED',\n message: 'BullMQ backend does not support pausing a single job type; pause the queue or adjust worker filters.',\n })\n }\n\n public async resumeJobType(queue: string, jobName: string): Promise<void> {\n void queue\n void jobName\n throw new IgniterJobsError({\n code: 'JOBS_QUEUE_OPERATION_FAILED',\n message: 'BullMQ backend does not support resuming a single job type; resume the queue or adjust worker filters.',\n })\n }\n\n public async searchJobs(filter: any): Promise<IgniterJobSearchResult[]> {\n // Minimal implementation: list jobs from a specific queue when provided, otherwise aggregate known queues.\n const queue = filter?.queue as string | undefined\n const status = filter?.status as IgniterJobStatus[] | undefined\n const limit = filter?.limit ?? 100\n const offset = filter?.offset ?? 0\n\n if (queue) {\n const jobs = await this.core().queues.getJobs(this.toCoreQueueName(queue), { status, limit, offset } as any)\n return jobs.map((j) => this.mapJob(j as any, queue))\n }\n\n const queues = await this.listQueues()\n const results: IgniterJobSearchResult[] = []\n for (const q of queues) {\n const jobs = await this.core().queues.getJobs(this.toCoreQueueName(q.name), { status, limit, offset } as any)\n results.push(...jobs.map((j) => this.mapJob(j as any, q.name)))\n if (results.length >= limit) break\n }\n return results.slice(0, limit)\n }\n\n public async searchQueues(filter: any): Promise<IgniterJobsQueueInfo[]> {\n const all = await this.listQueues()\n const name = filter?.name as string | undefined\n const isPaused = filter?.isPaused as boolean | undefined\n return all\n .filter((q) => (name ? q.name.includes(name) : true))\n .filter((q) => (typeof isPaused === 'boolean' ? q.isPaused === isPaused : true))\n }\n\n public async searchWorkers(filter: any): Promise<IgniterJobsWorkerHandle[]> {\n const queue = filter?.queue as string | undefined\n const isRunning = filter?.isRunning as boolean | undefined\n\n const all = Array.from(this.core().getWorkers().values())\n return all\n .filter((w) => {\n if (!queue) return true\n const coreQueue = this.toCoreQueueName(queue)\n const queues = (w as any).config?.queues ?? [(w as any).queueName]\n return Array.isArray(queues) ? queues.includes(coreQueue) : false\n })\n .filter((w) => (typeof isRunning === 'boolean' ? (isRunning ? w.isRunning() : !w.isRunning()) : true))\n .map((w) => this.mapWorker(w))\n }\n\n public async createWorker(config: IgniterJobsWorkerBuilderConfig): Promise<IgniterJobsWorkerHandle> {\n // Ensure jobs/crons are registered in the underlying BullMQ adapter before starting workers.\n await this.executor()\n\n const queuesSource =\n config.queues?.length\n ? config.queues\n : Array.from(new Set([...this.jobsByQueue.keys(), ...this.cronsByQueue.keys()]))\n const queues = queuesSource.map((q) => this.toCoreQueueName(q))\n const coreConfig: JobWorkerConfig = {\n queues,\n concurrency: config.concurrency ?? 1,\n limiter: config.limiter as any,\n onActive: config.handlers?.onActive as any,\n onSuccess: config.handlers?.onSuccess as any,\n onFailure: config.handlers?.onFailure as any,\n onIdle: config.handlers?.onIdle as any,\n }\n const handle = await (this.core() as any).worker(coreConfig)\n return this.mapWorker(handle)\n }\n\n public getWorkers(): Map<string, IgniterJobsWorkerHandle> {\n const out = new Map<string, IgniterJobsWorkerHandle>()\n for (const [id, handle] of this.core().getWorkers()) out.set(id, this.mapWorker(handle))\n return out\n }\n\n public async publishEvent(channel: string, payload: unknown): Promise<void> {\n await this.publisher.publish(channel, JSON.stringify(payload))\n }\n\n public async subscribeEvent(channel: string, handler: IgniterJobsEventHandler): Promise<() => Promise<void>> {\n const set = this.subscribers.get(channel) ?? new Set<(payload: any) => void>()\n const wrapped = (payload: any) => void handler(payload as any)\n set.add(wrapped)\n this.subscribers.set(channel, set)\n\n if (set.size === 1) {\n await this.subscriber.subscribe(channel)\n }\n\n return async () => {\n const current = this.subscribers.get(channel)\n if (!current) return\n current.delete(wrapped)\n if (current.size === 0) {\n this.subscribers.delete(channel)\n await this.subscriber.unsubscribe(channel)\n }\n }\n }\n\n public async shutdown(): Promise<void> {\n await this.subscriber.quit()\n // BullMQ adapter does not expose global shutdown on the core adapter in a single method;\n // queue/worker cleanup is handled by worker close and queue obliterate.\n }\n\n private core(): IgniterJobQueueAdapter<any> {\n if (!this.coreAdapter) {\n // We only need the Redis connection. The wrapped job handlers can create real context.\n this.coreAdapter = createBullMQAdapter({\n store: ({ client: this.redis } as any),\n }) as unknown as IgniterJobQueueAdapter<any>\n }\n\n return this.coreAdapter\n }\n\n private async executor(): Promise<CoreMergedExecutor> {\n if (!this.executorDirty && this.coreExecutor) return this.coreExecutor\n\n const routers: Record<string, JobsRouter<any>> = {}\n const flattened: Record<string, CoreJobDefinition<any, any, any>> = {}\n\n const allQueues = new Set<string>([...this.jobsByQueue.keys(), ...this.cronsByQueue.keys()])\n\n for (const queueName of allQueues) {\n const coreJobs: Record<string, CoreJobDefinition<any, any, any>> = {}\n\n const jobs = this.jobsByQueue.get(queueName)\n if (jobs) {\n for (const [jobName, def] of jobs.entries()) {\n const queue = def.queue ? `${queueName}.${def.queue}` : queueName\n const fullQueue = IgniterJobsPrefix.buildQueueName(queue)\n coreJobs[jobName] = this.toCoreJobDefinition(queueName, jobName, def, fullQueue)\n }\n }\n\n const crons = this.cronsByQueue.get(queueName)\n if (crons) {\n for (const [cronName, def] of crons.entries()) {\n const fullQueue = IgniterJobsPrefix.buildQueueName(queueName)\n coreJobs[cronName] = this.toCoreCronJobDefinition(queueName, cronName, def, fullQueue)\n }\n }\n\n if (Object.keys(coreJobs).length === 0) continue\n\n routers[queueName] = this.core().router({\n jobs: coreJobs as any,\n namespace: queueName,\n })\n\n for (const [jobName, def] of Object.entries(coreJobs)) {\n flattened[`${queueName}.${jobName}`] = def\n }\n }\n\n // Register jobs in bulk so management APIs and workers can resolve handlers.\n await this.core().bulkRegister(flattened as any)\n\n this.coreExecutor = this.core().merge(routers as any) as any\n this.executorDirty = false\n return this.coreExecutor as CoreMergedExecutor\n }\n\n private toCoreQueueName(queueName: string): string {\n return IgniterJobsPrefix.buildQueueName(queueName)\n }\n\n private mapQueueInfo(info: any): IgniterJobsQueueInfo {\n return {\n name: this.fromCoreQueueName(info.name),\n isPaused: info.isPaused,\n jobCounts: info.jobCounts,\n }\n }\n\n private fromCoreQueueName(full: string): string {\n const prefix = `${IgniterJobsPrefix.BASE_PREFIX}:`\n return full.startsWith(prefix) ? full.slice(prefix.length) : full\n }\n\n private mapJob(job: any, queue?: string): IgniterJobSearchResult {\n const q = queue ?? this.fromCoreQueueName(job.metadata?.queue ?? job.queueName ?? '')\n const scope = (job.metadata as any)?.__igniter_jobs_scope\n return {\n id: job.id,\n name: job.name,\n queue: q,\n status: job.status,\n input: job.payload,\n result: job.result,\n error: job.error,\n progress: 0,\n attemptsMade: job.attemptsMade ?? 0,\n priority: job.priority ?? 0,\n createdAt: job.createdAt,\n startedAt: job.processedAt,\n completedAt: job.completedAt,\n metadata: job.metadata,\n scope,\n }\n }\n\n private mapWorker(handle: any): IgniterJobsWorkerHandle {\n const queues = (handle as any).config?.queues ?? [(handle as any).queueName]\n return {\n id: handle.id,\n queues: (queues as string[]).map((q) => this.fromCoreQueueName(q)),\n pause: () => handle.pause(),\n resume: () => handle.resume(),\n close: () => handle.close(),\n isRunning: () => handle.isRunning(),\n isPaused: () => handle.isPaused(),\n isClosed: () => handle.isClosed(),\n getMetrics: async () => handle.getMetrics() as IgniterJobsWorkerMetrics,\n }\n }\n\n private toCoreJobDefinition(\n queueName: string,\n jobName: string,\n def: IgniterJobDefinition<any, any, any>,\n fullQueueName: string,\n ): CoreJobDefinition<any, any, any> {\n const handler = async (ctx: CoreJobExecutionContext<any, any>) => {\n return def.handler({\n input: ctx.input as any,\n context: ctx.context as any,\n job: {\n id: ctx.job.id,\n name: jobName,\n queue: queueName,\n attemptsMade: ctx.job.attemptsMade,\n createdAt: (ctx.job as any).createdAt,\n metadata: ctx.job.metadata,\n },\n scope: (ctx.job.metadata as any)?.__igniter_jobs_scope,\n } as any)\n }\n\n return {\n name: jobName,\n input: def.input as any,\n handler,\n queue: { name: fullQueueName },\n attempts: def.attempts,\n priority: def.priority,\n delay: def.delay,\n removeOnComplete: def.removeOnComplete as any,\n removeOnFail: def.removeOnFail as any,\n metadata: def.metadata as any,\n limiter: def.limiter as any,\n onStart: def.onStart as any,\n onSuccess: def.onSuccess as any,\n onFailure: def.onFailure as any,\n onProgress: def.onProgress as any,\n } as any\n }\n\n private toCoreCronJobDefinition(\n queueName: string,\n cronName: string,\n def: IgniterCronDefinition<any, any>,\n fullQueueName: string,\n ): CoreJobDefinition<any, any, any> {\n const handler = async (ctx: CoreJobExecutionContext<any, any>) => {\n return def.handler({\n context: ctx.context as any,\n job: {\n id: ctx.job.id,\n name: cronName,\n queue: queueName,\n attemptsMade: ctx.job.attemptsMade,\n createdAt: (ctx.job as any).createdAt,\n metadata: ctx.job.metadata,\n },\n scope: (ctx.job.metadata as any)?.__igniter_jobs_scope,\n } as any)\n }\n\n return {\n name: cronName,\n handler,\n queue: { name: fullQueueName },\n repeat: {\n cron: def.cron,\n tz: def.tz,\n limit: def.maxExecutions,\n startDate: def.startDate,\n endDate: def.endDate,\n },\n metadata:\n def.onlyBusinessHours || def.skipWeekends || def.businessHours || def.onlyWeekdays || def.skipDates || (def.startDate && def.endDate)\n ? {\n advancedScheduling: {\n onlyBusinessHours: def.onlyBusinessHours,\n skipWeekends: def.skipWeekends,\n businessHours: def.businessHours,\n skipDates: toDateArray(def.skipDates),\n onlyWeekdays: def.onlyWeekdays,\n between: def.startDate && def.endDate ? [def.startDate, def.endDate] : undefined,\n },\n }\n : undefined,\n } as any\n }\n}\n","/**\n * Generates consistent identifiers for jobs, workers, and schedules.\n */\nexport class IgniterJobsIdGenerator {\n /**\n * Generates a unique identifier with a prefix.\n *\n * @example\n * ```typescript\n * const jobId = IgniterJobsIdGenerator.generate('job')\n * ```\n */\n public static generate(prefix: string): string {\n const now = Date.now().toString(36)\n const random = Math.random().toString(36).slice(2, 8)\n return `${prefix}_${now}_${random}`\n }\n}\n","/**\n * @fileoverview In-memory adapter for @igniter-js/jobs (tests/dev only)\n * @module @igniter-js/jobs/adapters/memory\n */\n\nimport type {\n IgniterCronDefinition,\n IgniterJobCounts,\n IgniterJobDefinition,\n IgniterJobSearchResult,\n IgniterJobStatus,\n IgniterJobsAdapter,\n IgniterJobsAdapterDispatchParams,\n IgniterJobsAdapterScheduleParams,\n IgniterJobsEventHandler,\n IgniterJobsJobLog,\n IgniterJobsQueueCleanOptions,\n IgniterJobsQueueInfo,\n IgniterJobsQueueManager,\n IgniterJobsWorkerBuilderConfig,\n IgniterJobsWorkerHandle,\n IgniterJobsWorkerMetrics,\n} from \"../types\";\nimport { IgniterJobsIdGenerator } from \"../utils/id-generator\";\nimport { IgniterJobsError } from \"../errors\";\n\ntype MemoryJob = {\n id: string;\n name: string;\n queue: string;\n input: unknown;\n status: IgniterJobStatus;\n progress: number;\n attemptsMade: number;\n maxAttempts: number;\n priority: number;\n createdAt: Date;\n startedAt?: Date;\n completedAt?: Date;\n result?: unknown;\n error?: string;\n metadata?: Record<string, unknown>;\n scope?: unknown;\n logs: IgniterJobsJobLog[];\n};\n\ntype MemoryWorkerState = {\n id: string;\n queues: string[];\n concurrency: number;\n paused: boolean;\n closed: boolean;\n startedAt: Date;\n metrics: {\n processed: number;\n failed: number;\n totalDuration: number;\n };\n handlers?: IgniterJobsWorkerBuilderConfig[\"handlers\"];\n};\n\n/**\n * Lightweight in-memory adapter used for unit tests and local development.\n *\n * This adapter is not suitable for production use.\n */\nexport class IgniterJobsMemoryAdapter implements IgniterJobsAdapter {\n public readonly client = {\n type: \"memory\" as const,\n };\n\n private readonly jobsById = new Map<string, MemoryJob>();\n private readonly jobsByQueue = new Map<string, string[]>();\n private readonly registeredJobs = new Map<\n string,\n Map<string, IgniterJobDefinition<any, any, any>>\n >();\n private readonly registeredCrons = new Map<\n string,\n Map<string, IgniterCronDefinition<any, any>>\n >();\n\n private readonly workers = new Map<string, MemoryWorkerState>();\n\n private readonly subscribers = new Map<\n string,\n Set<IgniterJobsEventHandler>\n >();\n\n public readonly queues: IgniterJobsQueueManager = {\n list: async () => this.listQueues(),\n get: async (name) => this.getQueueInfo(name),\n getJobCounts: async (name) => this.getQueueJobCounts(name),\n getJobs: async (name, filter) => {\n const statuses = filter?.status;\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n const results = await this.searchJobs({\n queue: name,\n status: statuses,\n limit,\n offset,\n } as any);\n return results;\n },\n pause: async (name) => this.pauseQueue(name),\n resume: async (name) => this.resumeQueue(name),\n isPaused: async (name) => {\n // Queue-level pause is stored as a special marker job list state.\n // For memory adapter, we model it by a metadata flag in queue info.\n const info = await this.getQueueInfo(name);\n return info?.isPaused ?? false;\n },\n drain: async (name) => this.drainQueue(name),\n clean: async (name, options) => this.cleanQueue(name, options),\n obliterate: async (name, options) => this.obliterateQueue(name, options),\n };\n\n private readonly pausedQueues = new Set<string>();\n\n public static create(): IgniterJobsAdapter {\n return new IgniterJobsMemoryAdapter();\n }\n\n public registerJob(\n queueName: string,\n jobName: string,\n definition: IgniterJobDefinition<any, any, any>,\n ): void {\n const queueJobs =\n this.registeredJobs.get(queueName) ??\n new Map<string, IgniterJobDefinition<any, any, any>>();\n if (queueJobs.has(jobName)) {\n throw new IgniterJobsError({\n code: \"JOBS_DUPLICATE_JOB\",\n message: `Job \"${jobName}\" already registered for queue \"${queueName}\".`,\n });\n }\n queueJobs.set(jobName, definition);\n this.registeredJobs.set(queueName, queueJobs);\n }\n\n public registerCron(\n queueName: string,\n cronName: string,\n definition: IgniterCronDefinition<any, any>,\n ): void {\n const queueCrons =\n this.registeredCrons.get(queueName) ??\n new Map<string, IgniterCronDefinition<any, any>>();\n if (queueCrons.has(cronName)) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_CRON\",\n message: `Cron \"${cronName}\" already registered for queue \"${queueName}\".`,\n });\n }\n queueCrons.set(cronName, definition);\n this.registeredCrons.set(queueName, queueCrons);\n }\n\n public async dispatch(\n params: IgniterJobsAdapterDispatchParams,\n ): Promise<string> {\n const jobId = params.jobId ?? IgniterJobsIdGenerator.generate(\"job\");\n const maxAttempts = params.attempts ?? 1;\n\n const metadata = params.metadata ?? {};\n\n const job: MemoryJob = {\n id: jobId,\n name: params.jobName,\n queue: params.queue,\n input: params.input,\n status: this.pausedQueues.has(params.queue)\n ? \"paused\"\n : params.delay && params.delay > 0\n ? \"delayed\"\n : \"waiting\",\n progress: 0,\n attemptsMade: 0,\n maxAttempts,\n priority: params.priority ?? 0,\n createdAt: new Date(),\n metadata: metadata as Record<string, unknown>,\n scope: params.scope,\n logs: [],\n };\n\n this.jobsById.set(jobId, job);\n const queueList = this.jobsByQueue.get(params.queue) ?? [];\n queueList.push(jobId);\n this.jobsByQueue.set(params.queue, queueList);\n\n if (params.delay && params.delay > 0) {\n setTimeout(() => {\n const stored = this.jobsById.get(jobId);\n if (!stored) return;\n if (!this.pausedQueues.has(params.queue)) stored.status = \"waiting\";\n void this.kickWorkers(params.queue);\n }, params.delay);\n return jobId;\n }\n\n void this.kickWorkers(params.queue);\n return jobId;\n }\n\n public async schedule(\n params: IgniterJobsAdapterScheduleParams,\n ): Promise<string> {\n if (params.at) {\n const delay = params.at.getTime() - Date.now();\n if (delay <= 0) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_SCHEDULE\",\n message: \"Scheduled time must be in the future.\",\n });\n }\n return this.dispatch({ ...params, delay });\n }\n if (params.cron || params.every) {\n // Memory adapter does not implement a cron engine. It stores the job as delayed and relies on tests\n // to invoke dispatch manually if needed.\n return this.dispatch({ ...params, delay: params.delay ?? 0 });\n }\n return this.dispatch(params);\n }\n\n public async getJob(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobSearchResult | null> {\n const job = this.jobsById.get(jobId);\n if (!job) return null;\n if (queue && job.queue !== queue) return null;\n return this.toSearchResult(job);\n }\n\n public async getJobState(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobStatus | null> {\n const job = this.jobsById.get(jobId);\n if (!job) return null;\n if (queue && job.queue !== queue) return null;\n return job.status;\n }\n\n public async getJobLogs(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobsJobLog[]> {\n const job = this.jobsById.get(jobId);\n if (!job) return [];\n if (queue && job.queue !== queue) return [];\n return job.logs;\n }\n\n public async getJobProgress(jobId: string, queue?: string): Promise<number> {\n const job = this.jobsById.get(jobId);\n if (!job) return 0;\n if (queue && job.queue !== queue) return 0;\n return job.progress;\n }\n\n public async retryJob(jobId: string, queue?: string): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n if (queue && job.queue !== queue) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found in queue \"${queue}\".`,\n });\n }\n job.status = \"waiting\";\n job.error = undefined;\n job.completedAt = undefined;\n job.progress = 0;\n void this.kickWorkers(job.queue);\n }\n\n public async removeJob(jobId: string, queue?: string): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) return;\n if (queue && job.queue !== queue) return;\n this.jobsById.delete(jobId);\n const list = this.jobsByQueue.get(job.queue);\n if (list)\n this.jobsByQueue.set(\n job.queue,\n list.filter((id) => id !== jobId),\n );\n }\n\n public async promoteJob(jobId: string, queue?: string): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n if (queue && job.queue !== queue) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found in queue \"${queue}\".`,\n });\n }\n if (job.status === \"delayed\" || job.status === \"paused\") {\n job.status = this.pausedQueues.has(job.queue) ? \"paused\" : \"waiting\";\n void this.kickWorkers(job.queue);\n }\n }\n\n public async moveJobToFailed(\n jobId: string,\n reason: string,\n queue?: string,\n ): Promise<void> {\n const job = this.jobsById.get(jobId);\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n if (queue && job.queue !== queue) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found in queue \"${queue}\".`,\n });\n }\n job.status = \"failed\";\n job.error = reason;\n job.completedAt = new Date();\n }\n\n public async retryManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((id) => this.retryJob(id, queue)));\n }\n\n public async removeManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((id) => this.removeJob(id, queue)));\n }\n\n public async getQueueInfo(\n queue: string,\n ): Promise<IgniterJobsQueueInfo | null> {\n const counts = await this.getQueueJobCounts(queue);\n return {\n name: queue,\n isPaused: this.pausedQueues.has(queue),\n jobCounts: counts,\n };\n }\n\n public async getQueueJobCounts(queue: string): Promise<IgniterJobCounts> {\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n const counts: IgniterJobCounts = {\n waiting: 0,\n active: 0,\n completed: 0,\n failed: 0,\n delayed: 0,\n paused: 0,\n };\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status in counts) {\n (counts as any)[job.status]++;\n }\n }\n return counts;\n }\n\n public async listQueues(): Promise<IgniterJobsQueueInfo[]> {\n const queues = Array.from(\n new Set([\n ...this.jobsByQueue.keys(),\n ...this.registeredJobs.keys(),\n ...this.registeredCrons.keys(),\n ]),\n );\n const result: IgniterJobsQueueInfo[] = [];\n for (const q of queues) {\n result.push((await this.getQueueInfo(q))!);\n }\n return result;\n }\n\n public async pauseQueue(queue: string): Promise<void> {\n this.pausedQueues.add(queue);\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"waiting\") job.status = \"paused\";\n }\n }\n\n public async resumeQueue(queue: string): Promise<void> {\n this.pausedQueues.delete(queue);\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"paused\") job.status = \"waiting\";\n }\n void this.kickWorkers(queue);\n }\n\n public async drainQueue(queue: string): Promise<number> {\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n let removed = 0;\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"waiting\" || job.status === \"paused\") {\n this.jobsById.delete(id);\n removed++;\n }\n }\n this.jobsByQueue.set(\n queue,\n jobIds.filter((id) => this.jobsById.has(id)),\n );\n return removed;\n }\n\n public async cleanQueue(\n queue: string,\n options: IgniterJobsQueueCleanOptions,\n ): Promise<number> {\n const statuses = Array.isArray(options.status)\n ? options.status\n : [options.status];\n const olderThan = options.olderThan ?? 0;\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n const now = Date.now();\n let cleaned = 0;\n\n for (const id of [...jobIds]) {\n if (cleaned >= limit) break;\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (!statuses.includes(job.status)) continue;\n const ageMs = now - job.createdAt.getTime();\n if (ageMs < olderThan) continue;\n this.jobsById.delete(id);\n cleaned++;\n }\n\n this.jobsByQueue.set(\n queue,\n jobIds.filter((id) => this.jobsById.has(id)),\n );\n return cleaned;\n }\n\n public async obliterateQueue(\n queue: string,\n options?: { force?: boolean },\n ): Promise<void> {\n void options;\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) this.jobsById.delete(id);\n this.jobsByQueue.delete(queue);\n this.registeredJobs.delete(queue);\n this.registeredCrons.delete(queue);\n this.pausedQueues.delete(queue);\n }\n\n public async retryAllInQueue(queue: string): Promise<number> {\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n let retried = 0;\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.status === \"failed\") {\n await this.retryJob(id, queue);\n retried++;\n }\n }\n return retried;\n }\n\n public async pauseJobType(queue: string, jobName: string): Promise<void> {\n // Memory adapter supports job-type pause by blocking processing inside workers.\n // We model it by marking matching waiting jobs as paused.\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.name === jobName && job.status === \"waiting\")\n job.status = \"paused\";\n }\n }\n\n public async resumeJobType(queue: string, jobName: string): Promise<void> {\n const jobIds = this.jobsByQueue.get(queue) ?? [];\n for (const id of jobIds) {\n const job = this.jobsById.get(id);\n if (!job) continue;\n if (job.name === jobName && job.status === \"paused\")\n job.status = \"waiting\";\n }\n void this.kickWorkers(queue);\n }\n\n public async searchJobs(filter: any): Promise<IgniterJobSearchResult[]> {\n const queue = filter?.queue as string | undefined;\n const statuses: IgniterJobStatus[] | undefined = filter?.status;\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n\n const all = Array.from(this.jobsById.values())\n .filter((j) => (queue ? j.queue === queue : true))\n .filter((j) => (statuses ? statuses.includes(j.status) : true))\n .sort(\n (a, b) =>\n b.priority - a.priority ||\n a.createdAt.getTime() - b.createdAt.getTime(),\n );\n\n return all.slice(offset, offset + limit).map((j) => this.toSearchResult(j));\n }\n\n public async searchQueues(filter: any): Promise<IgniterJobsQueueInfo[]> {\n const name = filter?.name as string | undefined;\n const isPaused = filter?.isPaused as boolean | undefined;\n const all = await this.listQueues();\n return all\n .filter((q) => (name ? q.name.includes(name) : true))\n .filter((q) =>\n typeof isPaused === \"boolean\" ? q.isPaused === isPaused : true,\n );\n }\n\n public async searchWorkers(filter: any): Promise<IgniterJobsWorkerHandle[]> {\n const queue = filter?.queue as string | undefined;\n const isRunning = filter?.isRunning as boolean | undefined;\n return Array.from(this.workers.values())\n .filter((w) => (queue ? w.queues.includes(queue) : true))\n .filter((w) =>\n typeof isRunning === \"boolean\"\n ? isRunning\n ? !w.closed\n : w.closed\n : true,\n )\n .map((w) => this.toWorkerHandle(w));\n }\n\n public async createWorker(\n config: IgniterJobsWorkerBuilderConfig,\n ): Promise<IgniterJobsWorkerHandle> {\n const workerId = IgniterJobsIdGenerator.generate(\"worker\");\n const state: MemoryWorkerState = {\n id: workerId,\n queues: config.queues ?? [],\n concurrency: config.concurrency ?? 1,\n paused: false,\n closed: false,\n startedAt: new Date(),\n metrics: { processed: 0, failed: 0, totalDuration: 0 },\n handlers: config.handlers,\n };\n this.workers.set(workerId, state);\n\n // Kick initial processing.\n for (const q of state.queues) void this.kickWorkers(q);\n\n return this.toWorkerHandle(state);\n }\n\n public getWorkers(): Map<string, IgniterJobsWorkerHandle> {\n const out = new Map<string, IgniterJobsWorkerHandle>();\n for (const [id, state] of this.workers)\n out.set(id, this.toWorkerHandle(state));\n return out;\n }\n\n public async publishEvent(channel: string, payload: unknown): Promise<void> {\n const handlers = this.subscribers.get(channel);\n if (!handlers) return;\n await Promise.all(Array.from(handlers).map(async (h) => h(payload as any)));\n }\n\n public async subscribeEvent(\n channel: string,\n handler: IgniterJobsEventHandler,\n ): Promise<() => Promise<void>> {\n const set =\n this.subscribers.get(channel) ?? new Set<IgniterJobsEventHandler>();\n set.add(handler);\n this.subscribers.set(channel, set);\n\n return async () => {\n const current = this.subscribers.get(channel);\n if (!current) return;\n current.delete(handler);\n if (current.size === 0) this.subscribers.delete(channel);\n };\n }\n\n public async shutdown(): Promise<void> {\n this.workers.clear();\n this.subscribers.clear();\n }\n\n private toSearchResult(job: MemoryJob): IgniterJobSearchResult {\n return {\n id: job.id,\n name: job.name,\n queue: job.queue,\n status: job.status,\n input: job.input,\n result: job.result,\n error: job.error,\n progress: job.progress,\n attemptsMade: job.attemptsMade,\n priority: job.priority,\n createdAt: job.createdAt,\n startedAt: job.startedAt,\n completedAt: job.completedAt,\n metadata: job.metadata,\n scope: job.scope as any,\n };\n }\n\n private toWorkerHandle(worker: MemoryWorkerState): IgniterJobsWorkerHandle {\n return {\n id: worker.id,\n queues: worker.queues,\n pause: async () => {\n worker.paused = true;\n },\n resume: async () => {\n worker.paused = false;\n for (const q of worker.queues) void this.kickWorkers(q);\n },\n close: async () => {\n worker.closed = true;\n },\n isRunning: () => !worker.closed && !worker.paused,\n isPaused: () => worker.paused,\n isClosed: () => worker.closed,\n getMetrics: async () => this.toWorkerMetrics(worker),\n };\n }\n\n private toWorkerMetrics(worker: MemoryWorkerState): IgniterJobsWorkerMetrics {\n const uptime = Date.now() - worker.startedAt.getTime();\n const processed = worker.metrics.processed;\n return {\n processed,\n failed: worker.metrics.failed,\n avgDuration: processed > 0 ? worker.metrics.totalDuration / processed : 0,\n concurrency: worker.concurrency,\n uptime,\n };\n }\n\n private async kickWorkers(queue: string): Promise<void> {\n if (this.pausedQueues.has(queue)) return;\n const relevant = Array.from(this.workers.values()).filter(\n (w) =>\n !w.closed &&\n !w.paused &&\n (w.queues.length === 0 || w.queues.includes(queue)),\n );\n if (relevant.length === 0) return;\n\n for (const w of relevant) {\n void this.processLoop(w, queue);\n }\n }\n\n private async processLoop(\n worker: MemoryWorkerState,\n queue: string,\n ): Promise<void> {\n if (worker.closed || worker.paused) return;\n const concurrency = Math.max(1, worker.concurrency);\n\n const running = (worker as any).__running as number | undefined;\n const currentRunning = running ?? 0;\n if (currentRunning >= concurrency) return;\n (worker as any).__running = currentRunning + 1;\n\n try {\n const next = this.nextJob(queue);\n if (!next) return;\n await this.processJob(worker, next);\n } finally {\n (worker as any).__running = ((worker as any).__running as number) - 1;\n // Continue draining if more work exists.\n if (this.nextJob(queue)) void this.processLoop(worker, queue);\n else if (worker.handlers?.onIdle) await worker.handlers.onIdle();\n }\n }\n\n private nextJob(queue: string): MemoryJob | null {\n const ids = this.jobsByQueue.get(queue) ?? [];\n const candidates = ids\n .map((id) => this.jobsById.get(id))\n .filter((j): j is MemoryJob => Boolean(j))\n .filter((j) => j.status === \"waiting\")\n .sort(\n (a, b) =>\n b.priority - a.priority ||\n a.createdAt.getTime() - b.createdAt.getTime(),\n );\n return candidates[0] ?? null;\n }\n\n private async processJob(\n worker: MemoryWorkerState,\n job: MemoryJob,\n ): Promise<void> {\n if (this.pausedQueues.has(job.queue)) {\n job.status = \"paused\";\n return;\n }\n\n job.status = \"active\";\n job.startedAt = new Date();\n job.attemptsMade += 1;\n job.logs.push({\n timestamp: new Date(),\n level: \"info\",\n message: \"Job started\",\n });\n\n if (worker.handlers?.onActive)\n await worker.handlers.onActive({ job: this.toSearchResult(job) });\n\n const start = Date.now();\n\n try {\n const definition = this.registeredJobs.get(job.queue)?.get(job.name);\n if (!definition) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_REGISTERED\",\n message: `Job \"${job.name}\" is not registered for queue \"${job.queue}\".`,\n });\n }\n\n if (definition.onStart) {\n await definition.onStart({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n },\n scope: job.scope as any,\n startedAt: job.startedAt,\n } as any);\n }\n\n const result = await definition.handler({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n },\n scope: job.scope as any,\n } as any);\n\n const duration = Date.now() - start;\n job.status = \"completed\";\n job.completedAt = new Date();\n job.result = result;\n job.progress = 100;\n job.logs.push({\n timestamp: new Date(),\n level: \"info\",\n message: `Job completed in ${duration}ms`,\n });\n\n worker.metrics.processed += 1;\n worker.metrics.totalDuration += duration;\n\n if (definition.onSuccess) {\n await definition.onSuccess({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n },\n scope: job.scope as any,\n result,\n duration,\n } as any);\n }\n\n if (worker.handlers?.onSuccess)\n await worker.handlers.onSuccess({\n job: this.toSearchResult(job),\n result,\n });\n } catch (error: any) {\n const duration = Date.now() - start;\n job.error = error?.message ?? String(error);\n job.logs.push({\n timestamp: new Date(),\n level: \"error\",\n message: job.error ?? \"Unknown error\",\n });\n\n const isFinalAttempt = job.attemptsMade >= job.maxAttempts;\n if (isFinalAttempt) {\n job.status = \"failed\";\n job.completedAt = new Date();\n worker.metrics.failed += 1;\n\n const definition = this.registeredJobs.get(job.queue)?.get(job.name);\n if (definition?.onFailure) {\n await definition.onFailure({\n input: job.input as any,\n context: {} as any,\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade,\n metadata: job.metadata,\n },\n scope: job.scope as any,\n error,\n isFinalAttempt: true,\n } as any);\n }\n\n if (worker.handlers?.onFailure)\n await worker.handlers.onFailure({\n job: this.toSearchResult(job),\n error,\n });\n } else {\n job.status = \"waiting\";\n void this.kickWorkers(job.queue);\n }\n }\n }\n}\n","/**\n * @fileoverview SQLite adapter for @igniter-js/jobs (local/desktop/CLI environments)\n * @module @igniter-js/jobs/adapters/sqlite\n *\n * This adapter provides persistent job queue storage using SQLite, ideal for:\n * - Desktop applications (Tauri, Electron)\n * - CLI tools\n * - MCP Servers\n * - Local development\n * - Edge/embedded environments\n */\n\nimport type {\n IgniterCronDefinition,\n IgniterJobCounts,\n IgniterJobDefinition,\n IgniterJobSearchResult,\n IgniterJobStatus,\n IgniterJobsAdapter,\n IgniterJobsAdapterDispatchParams,\n IgniterJobsAdapterScheduleParams,\n IgniterJobsEventHandler,\n IgniterJobsJobLog,\n IgniterJobsQueueCleanOptions,\n IgniterJobsQueueInfo,\n IgniterJobsQueueManager,\n IgniterJobsWorkerBuilderConfig,\n IgniterJobsWorkerHandle,\n IgniterJobsWorkerMetrics,\n} from \"../types\";\nimport { IgniterJobsIdGenerator } from \"../utils/id-generator\";\nimport { IgniterJobsError } from \"../errors\";\n\n/**\n * Configuration options for the SQLite adapter.\n */\nexport interface IgniterJobsSQLiteAdapterOptions {\n /**\n * Path to the SQLite database file.\n * Use `:memory:` for an in-memory database (useful for testing).\n * @example './data/jobs.sqlite'\n * @example ':memory:'\n */\n path: string;\n\n /**\n * Interval in milliseconds for the worker polling loop.\n * Lower values mean faster job pickup but higher CPU usage.\n * @default 500\n */\n pollingInterval?: number;\n\n /**\n * Whether to enable WAL mode for better concurrent read/write performance.\n * @default true\n */\n enableWAL?: boolean;\n}\n\ntype SQLiteDatabase = {\n exec(sql: string): void;\n prepare<T = unknown>(sql: string): SQLiteStatement<T>;\n close(): void;\n};\n\ntype SQLiteStatement<T = unknown> = {\n run(...params: unknown[]): { changes: number; lastInsertRowid: number | bigint };\n get(...params: unknown[]): T | undefined;\n all(...params: unknown[]): T[];\n};\n\ntype JobRow = {\n id: string;\n name: string;\n queue: string;\n input: string;\n status: IgniterJobStatus;\n progress: number;\n attempts_made: number;\n max_attempts: number;\n priority: number;\n created_at: string;\n started_at: string | null;\n completed_at: string | null;\n scheduled_at: string | null;\n result: string | null;\n error: string | null;\n metadata: string | null;\n scope: string | null;\n};\n\ntype LogRow = {\n id: number;\n job_id: string;\n timestamp: string;\n level: \"info\" | \"warn\" | \"error\";\n message: string;\n};\n\ntype WorkerState = {\n id: string;\n queues: string[];\n concurrency: number;\n paused: boolean;\n closed: boolean;\n startedAt: Date;\n metrics: {\n processed: number;\n failed: number;\n totalDuration: number;\n };\n handlers?: IgniterJobsWorkerBuilderConfig[\"handlers\"];\n pollingTimer?: ReturnType<typeof setInterval>;\n activeJobs: number;\n};\n\n/**\n * SQLite-based adapter for local/desktop/CLI job queue persistence.\n *\n * Features:\n * - Full persistence across process restarts\n * - Zero external dependencies (SQLite is embedded)\n * - WAL mode for concurrent access\n * - Automatic schema migrations\n * - Compatible with Tauri, Electron, Node.js CLIs\n *\n * @example\n * ```ts\n * const adapter = IgniterJobsSQLiteAdapter.create({\n * path: './data/jobs.sqlite'\n * });\n *\n * const jobs = IgniterJobs.create()\n * .withAdapter(adapter)\n * .build();\n * ```\n */\nexport class IgniterJobsSQLiteAdapter implements IgniterJobsAdapter {\n public readonly client: { type: \"sqlite\"; path: string };\n\n private db: SQLiteDatabase;\n private readonly options: Required<IgniterJobsSQLiteAdapterOptions>;\n\n private readonly registeredJobs = new Map<\n string,\n Map<string, IgniterJobDefinition<any, any, any>>\n >();\n private readonly registeredCrons = new Map<\n string,\n Map<string, IgniterCronDefinition<any, any>>\n >();\n\n private readonly workers = new Map<string, WorkerState>();\n\n private readonly subscribers = new Map<\n string,\n Set<IgniterJobsEventHandler>\n >();\n\n private readonly pausedQueues = new Set<string>();\n\n public readonly queues: IgniterJobsQueueManager = {\n list: async () => this.listQueues(),\n get: async (name) => this.getQueueInfo(name),\n getJobCounts: async (name) => this.getQueueJobCounts(name),\n getJobs: async (name, filter) => {\n const statuses = filter?.status;\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n const results = await this.searchJobs({\n queue: name,\n status: statuses,\n limit,\n offset,\n } as any);\n return results;\n },\n pause: async (name) => this.pauseQueue(name),\n resume: async (name) => this.resumeQueue(name),\n isPaused: async (name) => {\n const info = await this.getQueueInfo(name);\n return info?.isPaused ?? false;\n },\n drain: async (name) => this.drainQueue(name),\n clean: async (name, options) => this.cleanQueue(name, options),\n obliterate: async (name, options) => this.obliterateQueue(name, options),\n };\n\n private constructor(options: IgniterJobsSQLiteAdapterOptions) {\n this.options = {\n path: options.path,\n pollingInterval: options.pollingInterval ?? 500,\n enableWAL: options.enableWAL ?? true,\n };\n\n this.client = {\n type: \"sqlite\",\n path: this.options.path,\n };\n\n // Dynamic import of better-sqlite3\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const Database = require(\"better-sqlite3\");\n this.db = new Database(this.options.path) as SQLiteDatabase;\n\n this.initializeSchema();\n }\n\n /**\n * Creates a new SQLite adapter instance.\n *\n * @param options - Configuration options\n * @returns A new adapter instance\n *\n * @example\n * ```ts\n * // File-based database (persistent)\n * const adapter = IgniterJobsSQLiteAdapter.create({\n * path: './data/jobs.sqlite'\n * });\n *\n * // In-memory database (for testing)\n * const testAdapter = IgniterJobsSQLiteAdapter.create({\n * path: ':memory:'\n * });\n * ```\n */\n public static create(\n options: IgniterJobsSQLiteAdapterOptions\n ): IgniterJobsAdapter {\n return new IgniterJobsSQLiteAdapter(options);\n }\n\n private initializeSchema(): void {\n // Enable WAL mode for better concurrent performance\n if (this.options.enableWAL) {\n this.db.exec(\"PRAGMA journal_mode = WAL;\");\n }\n\n // Jobs table\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS jobs (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n queue TEXT NOT NULL,\n input TEXT NOT NULL,\n status TEXT NOT NULL DEFAULT 'waiting',\n progress REAL NOT NULL DEFAULT 0,\n attempts_made INTEGER NOT NULL DEFAULT 0,\n max_attempts INTEGER NOT NULL DEFAULT 1,\n priority INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n started_at TEXT,\n completed_at TEXT,\n scheduled_at TEXT,\n result TEXT,\n error TEXT,\n metadata TEXT,\n scope TEXT\n );\n\n CREATE INDEX IF NOT EXISTS idx_jobs_queue_status ON jobs(queue, status);\n CREATE INDEX IF NOT EXISTS idx_jobs_status ON jobs(status);\n CREATE INDEX IF NOT EXISTS idx_jobs_scheduled_at ON jobs(scheduled_at);\n CREATE INDEX IF NOT EXISTS idx_jobs_priority ON jobs(priority DESC, created_at ASC);\n `);\n\n // Logs table\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS job_logs (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n job_id TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n level TEXT NOT NULL,\n message TEXT NOT NULL,\n FOREIGN KEY (job_id) REFERENCES jobs(id) ON DELETE CASCADE\n );\n\n CREATE INDEX IF NOT EXISTS idx_job_logs_job_id ON job_logs(job_id);\n `);\n\n // Paused queues table\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS paused_queues (\n name TEXT PRIMARY KEY\n );\n `);\n\n // Load paused queues from database\n const pausedRows = this.db.prepare<{ name: string }>(\n \"SELECT name FROM paused_queues\"\n ).all();\n for (const row of pausedRows) {\n this.pausedQueues.add(row.name);\n }\n }\n\n public registerJob(\n queueName: string,\n jobName: string,\n definition: IgniterJobDefinition<any, any, any>\n ): void {\n const queueJobs =\n this.registeredJobs.get(queueName) ??\n new Map<string, IgniterJobDefinition<any, any, any>>();\n if (queueJobs.has(jobName)) {\n throw new IgniterJobsError({\n code: \"JOBS_DUPLICATE_JOB\",\n message: `Job \"${jobName}\" already registered for queue \"${queueName}\".`,\n });\n }\n queueJobs.set(jobName, definition);\n this.registeredJobs.set(queueName, queueJobs);\n }\n\n public registerCron(\n queueName: string,\n cronName: string,\n definition: IgniterCronDefinition<any, any>\n ): void {\n const queueCrons =\n this.registeredCrons.get(queueName) ??\n new Map<string, IgniterCronDefinition<any, any>>();\n if (queueCrons.has(cronName)) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_CRON\",\n message: `Cron \"${cronName}\" already registered for queue \"${queueName}\".`,\n });\n }\n queueCrons.set(cronName, definition);\n this.registeredCrons.set(queueName, queueCrons);\n }\n\n public async dispatch(\n params: IgniterJobsAdapterDispatchParams\n ): Promise<string> {\n const jobId = params.jobId ?? IgniterJobsIdGenerator.generate(\"job\");\n const maxAttempts = params.attempts ?? 1;\n const now = new Date();\n\n let status: IgniterJobStatus = \"waiting\";\n let scheduledAt: Date | null = null;\n\n if (this.pausedQueues.has(params.queue)) {\n status = \"paused\";\n } else if (params.delay && params.delay > 0) {\n status = \"delayed\";\n scheduledAt = new Date(now.getTime() + params.delay);\n }\n\n const stmt = this.db.prepare(`\n INSERT INTO jobs (\n id, name, queue, input, status, progress, attempts_made, max_attempts,\n priority, created_at, scheduled_at, metadata, scope\n ) VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?, ?, ?, ?, ?)\n `);\n\n stmt.run(\n jobId,\n params.jobName,\n params.queue,\n JSON.stringify(params.input ?? {}),\n status,\n maxAttempts,\n params.priority ?? 0,\n now.toISOString(),\n scheduledAt?.toISOString() ?? null,\n params.metadata ? JSON.stringify(params.metadata) : null,\n params.scope ? JSON.stringify(params.scope) : null\n );\n\n // If delayed, schedule promotion\n if (params.delay && params.delay > 0) {\n setTimeout(() => {\n this.promoteDelayedJob(jobId, params.queue);\n }, params.delay);\n }\n\n return jobId;\n }\n\n private promoteDelayedJob(jobId: string, queue: string): void {\n if (this.pausedQueues.has(queue)) return;\n\n const stmt = this.db.prepare(`\n UPDATE jobs SET status = 'waiting', scheduled_at = NULL\n WHERE id = ? AND status = 'delayed'\n `);\n stmt.run(jobId);\n }\n\n public async schedule(\n params: IgniterJobsAdapterScheduleParams\n ): Promise<string> {\n if (params.at) {\n const delay = params.at.getTime() - Date.now();\n if (delay <= 0) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_SCHEDULE\",\n message: \"Scheduled time must be in the future.\",\n });\n }\n return this.dispatch({ ...params, delay });\n }\n if (params.cron || params.every) {\n // SQLite adapter doesn't implement a cron engine.\n // Store as delayed and rely on external cron setup if needed.\n return this.dispatch({ ...params, delay: params.delay ?? 0 });\n }\n return this.dispatch(params);\n }\n\n public async getJob(\n jobId: string,\n queue?: string\n ): Promise<IgniterJobSearchResult | null> {\n let sql = \"SELECT * FROM jobs WHERE id = ?\";\n const params: unknown[] = [jobId];\n\n if (queue) {\n sql += \" AND queue = ?\";\n params.push(queue);\n }\n\n const row = this.db.prepare<JobRow>(sql).get(...params);\n if (!row) return null;\n return this.rowToSearchResult(row);\n }\n\n public async getJobState(\n jobId: string,\n queue?: string\n ): Promise<IgniterJobStatus | null> {\n let sql = \"SELECT status FROM jobs WHERE id = ?\";\n const params: unknown[] = [jobId];\n\n if (queue) {\n sql += \" AND queue = ?\";\n params.push(queue);\n }\n\n const row = this.db.prepare<{ status: IgniterJobStatus }>(sql).get(...params);\n return row?.status ?? null;\n }\n\n public async getJobLogs(\n jobId: string,\n queue?: string\n ): Promise<IgniterJobsJobLog[]> {\n // Verify job exists and belongs to queue if specified\n if (queue) {\n const job = await this.getJob(jobId, queue);\n if (!job) return [];\n }\n\n const rows = this.db\n .prepare<LogRow>(\"SELECT * FROM job_logs WHERE job_id = ? ORDER BY timestamp ASC\")\n .all(jobId);\n\n return rows.map((row) => ({\n timestamp: new Date(row.timestamp),\n level: row.level,\n message: row.message,\n }));\n }\n\n public async getJobProgress(jobId: string, queue?: string): Promise<number> {\n let sql = \"SELECT progress FROM jobs WHERE id = ?\";\n const params: unknown[] = [jobId];\n\n if (queue) {\n sql += \" AND queue = ?\";\n params.push(queue);\n }\n\n const row = this.db.prepare<{ progress: number }>(sql).get(...params);\n return row?.progress ?? 0;\n }\n\n public async retryJob(jobId: string, queue?: string): Promise<void> {\n let sql = \"SELECT id FROM jobs WHERE id = ?\";\n const checkParams: unknown[] = [jobId];\n\n if (queue) {\n sql += \" AND queue = ?\";\n checkParams.push(queue);\n }\n\n const exists = this.db.prepare<{ id: string }>(sql).get(...checkParams);\n if (!exists) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found${queue ? ` in queue \"${queue}\"` : \"\"}.`,\n });\n }\n\n let updateSql = \"UPDATE jobs SET status = 'waiting', error = NULL, completed_at = NULL, progress = 0 WHERE id = ?\";\n const updateParams: unknown[] = [jobId];\n\n if (queue) {\n updateSql = updateSql.replace(\"WHERE id = ?\", \"WHERE id = ? AND queue = ?\");\n updateParams.push(queue);\n }\n\n this.db.prepare(updateSql).run(...updateParams);\n }\n\n public async removeJob(jobId: string, queue?: string): Promise<void> {\n let sql = \"DELETE FROM jobs WHERE id = ?\";\n const params: unknown[] = [jobId];\n\n if (queue) {\n sql += \" AND queue = ?\";\n params.push(queue);\n }\n\n this.db.prepare(sql).run(...params);\n }\n\n public async promoteJob(jobId: string, queue?: string): Promise<void> {\n let sql = \"SELECT id, status, queue FROM jobs WHERE id = ?\";\n const checkParams: unknown[] = [jobId];\n\n if (queue) {\n sql += \" AND queue = ?\";\n checkParams.push(queue);\n }\n\n const row = this.db.prepare<{ id: string; status: string; queue: string }>(sql).get(...checkParams);\n if (!row) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found${queue ? ` in queue \"${queue}\"` : \"\"}.`,\n });\n }\n\n if (row.status === \"delayed\" || row.status === \"paused\") {\n const newStatus = this.pausedQueues.has(row.queue) ? \"paused\" : \"waiting\";\n this.db.prepare(\"UPDATE jobs SET status = ?, scheduled_at = NULL WHERE id = ?\").run(newStatus, jobId);\n }\n }\n\n public async moveJobToFailed(\n jobId: string,\n reason: string,\n queue?: string\n ): Promise<void> {\n let sql = \"SELECT id FROM jobs WHERE id = ?\";\n const checkParams: unknown[] = [jobId];\n\n if (queue) {\n sql += \" AND queue = ?\";\n checkParams.push(queue);\n }\n\n const exists = this.db.prepare<{ id: string }>(sql).get(...checkParams);\n if (!exists) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found${queue ? ` in queue \"${queue}\"` : \"\"}.`,\n });\n }\n\n this.db.prepare(`\n UPDATE jobs SET status = 'failed', error = ?, completed_at = ?\n WHERE id = ?\n `).run(reason, new Date().toISOString(), jobId);\n }\n\n public async retryManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((id) => this.retryJob(id, queue)));\n }\n\n public async removeManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((id) => this.removeJob(id, queue)));\n }\n\n public async getQueueInfo(\n queue: string\n ): Promise<IgniterJobsQueueInfo | null> {\n const counts = await this.getQueueJobCounts(queue);\n return {\n name: queue,\n isPaused: this.pausedQueues.has(queue),\n jobCounts: counts,\n };\n }\n\n public async getQueueJobCounts(queue: string): Promise<IgniterJobCounts> {\n const counts: IgniterJobCounts = {\n waiting: 0,\n active: 0,\n completed: 0,\n failed: 0,\n delayed: 0,\n paused: 0,\n };\n\n const rows = this.db\n .prepare<{ status: IgniterJobStatus; count: number }>(\n \"SELECT status, COUNT(*) as count FROM jobs WHERE queue = ? GROUP BY status\"\n )\n .all(queue);\n\n for (const row of rows) {\n if (row.status in counts) {\n (counts as any)[row.status] = row.count;\n }\n }\n\n return counts;\n }\n\n public async listQueues(): Promise<IgniterJobsQueueInfo[]> {\n // Get queues from jobs table\n const jobQueues = this.db\n .prepare<{ queue: string }>(\"SELECT DISTINCT queue FROM jobs\")\n .all()\n .map((r) => r.queue);\n\n // Combine with registered job queues\n const allQueues = new Set([\n ...jobQueues,\n ...this.registeredJobs.keys(),\n ...this.registeredCrons.keys(),\n ]);\n\n const result: IgniterJobsQueueInfo[] = [];\n for (const q of allQueues) {\n const info = await this.getQueueInfo(q);\n if (info) result.push(info);\n }\n return result;\n }\n\n public async pauseQueue(queue: string): Promise<void> {\n this.pausedQueues.add(queue);\n this.db.prepare(\"INSERT OR IGNORE INTO paused_queues (name) VALUES (?)\").run(queue);\n\n // Mark waiting jobs as paused\n this.db.prepare(\n \"UPDATE jobs SET status = 'paused' WHERE queue = ? AND status = 'waiting'\"\n ).run(queue);\n }\n\n public async resumeQueue(queue: string): Promise<void> {\n this.pausedQueues.delete(queue);\n this.db.prepare(\"DELETE FROM paused_queues WHERE name = ?\").run(queue);\n\n // Mark paused jobs as waiting\n this.db.prepare(\n \"UPDATE jobs SET status = 'waiting' WHERE queue = ? AND status = 'paused'\"\n ).run(queue);\n }\n\n public async drainQueue(queue: string): Promise<number> {\n const result = this.db.prepare(\n \"DELETE FROM jobs WHERE queue = ? AND status IN ('waiting', 'paused')\"\n ).run(queue);\n return result.changes;\n }\n\n public async cleanQueue(\n queue: string,\n options: IgniterJobsQueueCleanOptions\n ): Promise<number> {\n const statuses = Array.isArray(options.status)\n ? options.status\n : [options.status];\n const olderThan = options.olderThan ?? 0;\n const limit = options.limit ?? Number.POSITIVE_INFINITY;\n\n const cutoffTime = new Date(Date.now() - olderThan).toISOString();\n const statusPlaceholders = statuses.map(() => \"?\").join(\", \");\n\n let sql = `\n DELETE FROM jobs WHERE id IN (\n SELECT id FROM jobs\n WHERE queue = ? AND status IN (${statusPlaceholders}) AND created_at < ?\n ORDER BY created_at ASC\n LIMIT ?\n )\n `;\n\n const result = this.db.prepare(sql).run(\n queue,\n ...statuses,\n cutoffTime,\n limit === Number.POSITIVE_INFINITY ? -1 : limit\n );\n\n return result.changes;\n }\n\n public async obliterateQueue(\n queue: string,\n _options?: { force?: boolean }\n ): Promise<void> {\n this.db.prepare(\"DELETE FROM jobs WHERE queue = ?\").run(queue);\n this.registeredJobs.delete(queue);\n this.registeredCrons.delete(queue);\n this.pausedQueues.delete(queue);\n this.db.prepare(\"DELETE FROM paused_queues WHERE name = ?\").run(queue);\n }\n\n public async retryAllInQueue(queue: string): Promise<number> {\n const result = this.db.prepare(`\n UPDATE jobs SET status = 'waiting', error = NULL, completed_at = NULL, progress = 0\n WHERE queue = ? AND status = 'failed'\n `).run(queue);\n return result.changes;\n }\n\n public async pauseJobType(queue: string, jobName: string): Promise<void> {\n this.db.prepare(\n \"UPDATE jobs SET status = 'paused' WHERE queue = ? AND name = ? AND status = 'waiting'\"\n ).run(queue, jobName);\n }\n\n public async resumeJobType(queue: string, jobName: string): Promise<void> {\n this.db.prepare(\n \"UPDATE jobs SET status = 'waiting' WHERE queue = ? AND name = ? AND status = 'paused'\"\n ).run(queue, jobName);\n }\n\n public async searchJobs(filter: any): Promise<IgniterJobSearchResult[]> {\n const queue = filter?.queue as string | undefined;\n const statuses: IgniterJobStatus[] | undefined = filter?.status;\n const limit = filter?.limit ?? 100;\n const offset = filter?.offset ?? 0;\n\n let sql = \"SELECT * FROM jobs WHERE 1=1\";\n const params: unknown[] = [];\n\n if (queue) {\n sql += \" AND queue = ?\";\n params.push(queue);\n }\n\n if (statuses && statuses.length > 0) {\n const placeholders = statuses.map(() => \"?\").join(\", \");\n sql += ` AND status IN (${placeholders})`;\n params.push(...statuses);\n }\n\n sql += \" ORDER BY priority DESC, created_at ASC LIMIT ? OFFSET ?\";\n params.push(limit, offset);\n\n const rows = this.db.prepare<JobRow>(sql).all(...params);\n return rows.map((row) => this.rowToSearchResult(row));\n }\n\n public async searchQueues(filter: any): Promise<IgniterJobsQueueInfo[]> {\n const name = filter?.name as string | undefined;\n const isPaused = filter?.isPaused as boolean | undefined;\n const all = await this.listQueues();\n return all\n .filter((q) => (name ? q.name.includes(name) : true))\n .filter((q) =>\n typeof isPaused === \"boolean\" ? q.isPaused === isPaused : true\n );\n }\n\n public async searchWorkers(filter: any): Promise<IgniterJobsWorkerHandle[]> {\n const queue = filter?.queue as string | undefined;\n const isRunning = filter?.isRunning as boolean | undefined;\n return Array.from(this.workers.values())\n .filter((w) => (queue ? w.queues.includes(queue) : true))\n .filter((w) =>\n typeof isRunning === \"boolean\"\n ? isRunning\n ? !w.closed\n : w.closed\n : true\n )\n .map((w) => this.toWorkerHandle(w));\n }\n\n public async createWorker(\n config: IgniterJobsWorkerBuilderConfig\n ): Promise<IgniterJobsWorkerHandle> {\n const workerId = IgniterJobsIdGenerator.generate(\"worker\");\n const state: WorkerState = {\n id: workerId,\n queues: config.queues ?? [],\n concurrency: config.concurrency ?? 1,\n paused: false,\n closed: false,\n startedAt: new Date(),\n metrics: { processed: 0, failed: 0, totalDuration: 0 },\n handlers: config.handlers,\n activeJobs: 0,\n };\n this.workers.set(workerId, state);\n\n // Start polling loop\n this.startPollingLoop(state);\n\n return this.toWorkerHandle(state);\n }\n\n public getWorkers(): Map<string, IgniterJobsWorkerHandle> {\n const out = new Map<string, IgniterJobsWorkerHandle>();\n for (const [id, state] of this.workers) {\n out.set(id, this.toWorkerHandle(state));\n }\n return out;\n }\n\n public async publishEvent(channel: string, payload: unknown): Promise<void> {\n const handlers = this.subscribers.get(channel);\n if (!handlers) return;\n await Promise.all(Array.from(handlers).map(async (h) => h(payload as any)));\n }\n\n public async subscribeEvent(\n channel: string,\n handler: IgniterJobsEventHandler\n ): Promise<() => Promise<void>> {\n const set =\n this.subscribers.get(channel) ?? new Set<IgniterJobsEventHandler>();\n set.add(handler);\n this.subscribers.set(channel, set);\n\n return async () => {\n const current = this.subscribers.get(channel);\n if (!current) return;\n current.delete(handler);\n if (current.size === 0) this.subscribers.delete(channel);\n };\n }\n\n public async shutdown(): Promise<void> {\n // Stop all workers\n for (const worker of this.workers.values()) {\n worker.closed = true;\n if (worker.pollingTimer) {\n clearInterval(worker.pollingTimer);\n }\n }\n this.workers.clear();\n this.subscribers.clear();\n\n // Close database connection\n this.db.close();\n }\n\n // ─────────────────────────────────────────────────────────────────────────────\n // Private helpers\n // ─────────────────────────────────────────────────────────────────────────────\n\n private rowToSearchResult(row: JobRow): IgniterJobSearchResult {\n return {\n id: row.id,\n name: row.name,\n queue: row.queue,\n status: row.status,\n input: JSON.parse(row.input),\n result: row.result ? JSON.parse(row.result) : undefined,\n error: row.error ?? undefined,\n progress: row.progress,\n attemptsMade: row.attempts_made,\n priority: row.priority,\n createdAt: new Date(row.created_at),\n startedAt: row.started_at ? new Date(row.started_at) : undefined,\n completedAt: row.completed_at ? new Date(row.completed_at) : undefined,\n metadata: row.metadata ? JSON.parse(row.metadata) : undefined,\n scope: row.scope ? JSON.parse(row.scope) : undefined,\n };\n }\n\n private toWorkerHandle(worker: WorkerState): IgniterJobsWorkerHandle {\n return {\n id: worker.id,\n queues: worker.queues,\n pause: async () => {\n worker.paused = true;\n },\n resume: async () => {\n worker.paused = false;\n },\n close: async () => {\n worker.closed = true;\n if (worker.pollingTimer) {\n clearInterval(worker.pollingTimer);\n }\n },\n isRunning: () => !worker.closed && !worker.paused,\n isPaused: () => worker.paused,\n isClosed: () => worker.closed,\n getMetrics: async () => this.toWorkerMetrics(worker),\n };\n }\n\n private toWorkerMetrics(worker: WorkerState): IgniterJobsWorkerMetrics {\n const uptime = Date.now() - worker.startedAt.getTime();\n const processed = worker.metrics.processed;\n return {\n processed,\n failed: worker.metrics.failed,\n avgDuration: processed > 0 ? worker.metrics.totalDuration / processed : 0,\n concurrency: worker.concurrency,\n uptime,\n };\n }\n\n private startPollingLoop(worker: WorkerState): void {\n const poll = () => {\n if (worker.closed || worker.paused) return;\n void this.processNextJobs(worker);\n };\n\n // Initial poll\n poll();\n\n // Set up polling interval\n worker.pollingTimer = setInterval(poll, this.options.pollingInterval);\n }\n\n private async processNextJobs(worker: WorkerState): Promise<void> {\n if (worker.closed || worker.paused) return;\n\n const availableSlots = worker.concurrency - worker.activeJobs;\n if (availableSlots <= 0) return;\n\n // Build queue filter\n const queueFilter = worker.queues.length > 0\n ? `queue IN (${worker.queues.map(() => \"?\").join(\", \")})`\n : \"1=1\";\n\n const params: unknown[] = worker.queues.length > 0 ? [...worker.queues, availableSlots] : [availableSlots];\n\n // Get next jobs to process\n const rows = this.db.prepare<JobRow>(`\n SELECT * FROM jobs\n WHERE status = 'waiting' AND ${queueFilter}\n ORDER BY priority DESC, created_at ASC\n LIMIT ?\n `).all(...params);\n\n for (const row of rows) {\n if (worker.closed || worker.paused) break;\n if (worker.activeJobs >= worker.concurrency) break;\n\n // Mark as active\n const claimed = this.db.prepare(`\n UPDATE jobs SET status = 'active', started_at = ?\n WHERE id = ? AND status = 'waiting'\n `).run(new Date().toISOString(), row.id);\n\n if (claimed.changes === 0) continue; // Job was claimed by another worker\n\n worker.activeJobs++;\n void this.processJob(worker, row.id).finally(() => {\n worker.activeJobs--;\n if (worker.handlers?.onIdle && worker.activeJobs === 0) {\n void worker.handlers.onIdle();\n }\n });\n }\n }\n\n private async processJob(worker: WorkerState, jobId: string): Promise<void> {\n const row = this.db.prepare<JobRow>(\"SELECT * FROM jobs WHERE id = ?\").get(jobId);\n if (!row) return;\n\n const job = this.rowToSearchResult(row);\n\n // Add log entry\n this.addJobLog(jobId, \"info\", \"Job started\");\n\n if (worker.handlers?.onActive) {\n await worker.handlers.onActive({ job });\n }\n\n const start = Date.now();\n\n try {\n const definition = this.registeredJobs.get(row.queue)?.get(row.name);\n if (!definition) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_REGISTERED\",\n message: `Job \"${row.name}\" is not registered for queue \"${row.queue}\".`,\n });\n }\n\n // Update attempts\n this.db.prepare(\"UPDATE jobs SET attempts_made = attempts_made + 1 WHERE id = ?\").run(jobId);\n\n if (definition.onStart) {\n await definition.onStart({\n input: job.input,\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade + 1,\n metadata: job.metadata,\n },\n scope: job.scope,\n startedAt: new Date(),\n } as any);\n }\n\n const result = await definition.handler({\n input: job.input,\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade + 1,\n metadata: job.metadata,\n },\n scope: job.scope,\n } as any);\n\n const duration = Date.now() - start;\n\n // Mark as completed\n this.db.prepare(`\n UPDATE jobs SET status = 'completed', completed_at = ?, result = ?, progress = 100\n WHERE id = ?\n `).run(new Date().toISOString(), JSON.stringify(result), jobId);\n\n this.addJobLog(jobId, \"info\", `Job completed in ${duration}ms`);\n\n worker.metrics.processed++;\n worker.metrics.totalDuration += duration;\n\n if (definition.onSuccess) {\n await definition.onSuccess({\n input: job.input,\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: job.attemptsMade + 1,\n metadata: job.metadata,\n },\n scope: job.scope,\n result,\n duration,\n } as any);\n }\n\n if (worker.handlers?.onSuccess) {\n const updatedJob = await this.getJob(jobId);\n if (updatedJob) {\n await worker.handlers.onSuccess({ job: updatedJob, result });\n }\n }\n } catch (error: any) {\n const duration = Date.now() - start;\n const errorMessage = error?.message ?? String(error);\n\n this.addJobLog(jobId, \"error\", errorMessage);\n\n // Get current attempts\n const current = this.db.prepare<{ attempts_made: number; max_attempts: number }>(\n \"SELECT attempts_made, max_attempts FROM jobs WHERE id = ?\"\n ).get(jobId);\n\n const isFinalAttempt = (current?.attempts_made ?? 0) >= (current?.max_attempts ?? 1);\n\n if (isFinalAttempt) {\n this.db.prepare(`\n UPDATE jobs SET status = 'failed', error = ?, completed_at = ?\n WHERE id = ?\n `).run(errorMessage, new Date().toISOString(), jobId);\n\n worker.metrics.failed++;\n\n const definition = this.registeredJobs.get(row.queue)?.get(row.name);\n if (definition?.onFailure) {\n await definition.onFailure({\n input: job.input,\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: job.queue,\n attemptsMade: current?.attempts_made ?? 1,\n metadata: job.metadata,\n },\n scope: job.scope,\n error,\n isFinalAttempt: true,\n } as any);\n }\n\n if (worker.handlers?.onFailure) {\n const updatedJob = await this.getJob(jobId);\n if (updatedJob) {\n await worker.handlers.onFailure({ job: updatedJob, error });\n }\n }\n } else {\n // Retry - put back to waiting\n this.db.prepare(\"UPDATE jobs SET status = 'waiting' WHERE id = ?\").run(jobId);\n }\n }\n }\n\n private addJobLog(jobId: string, level: \"info\" | \"warn\" | \"error\", message: string): void {\n this.db.prepare(`\n INSERT INTO job_logs (job_id, timestamp, level, message)\n VALUES (?, ?, ?, ?)\n `).run(jobId, new Date().toISOString(), level, message);\n }\n}\n"]}
|