import { EventEmitter } from "events"; import type { JobStatus, JobMeta, QueueMessage, BaseJobRequest, JobContext, JobHandlers } from "../interfaces/job.ts"; import type { QueuePlugin, QueueOptions } from "../interfaces/plugin.ts"; /** * Abstract queue class providing event-based job processing. * * @template TJobMap - A map of job names to their payload types for type safety. * * @example * ```typescript * interface MyJobs { * 'send-email': { to: string; subject: string; body: string }; * 'resize-image': { url: string; width: number; height: number }; * } * * const queue = new FileQueue({ path: './queue-data' }); * * // Register job handlers * queue.setHandlers({ * 'send-email': async ({ payload }) => { * await sendEmail(payload.to, payload.subject, payload.body); * }, * 'resize-image': async ({ payload }) => { * await resizeImage(payload.url, payload.width, payload.height); * } * }); * * // Add jobs with type safety * await queue.addJob('send-email', { * payload: { to: 'user@example.com', subject: 'Hello', body: 'World' } * }); * * // Start processing * await queue.run(); * ``` */ export declare abstract class Queue, TJobRequest extends BaseJobRequest = BaseJobRequest> extends EventEmitter { protected ttrDefault: number; protected plugins: QueuePlugin[]; protected pluginDisposers: Array<() => Promise>; readonly name: string; /** * Registry of job handlers mapping job names to their handler functions. */ handlers: Map; /** * Flag indicating whether handlers have been registered. */ handlersRegistered: boolean; /** * Indicates whether this queue driver supports long polling. * Drivers that support long polling (like SQS) can efficiently wait for messages. * Drivers that don't support long polling will have a minimum 0.5s sleep between polls. */ protected supportsLongPolling: boolean; /** * Creates a new Queue instance. * * @param options - Configuration options * @param options.name - Required name for the queue * @param options.ttrDefault - Default time-to-run for jobs in seconds (default: 300) * @param options.plugins - Array of plugins to use with this queue */ constructor(options: QueueOptions); /** * Adds a new job to the queue with type-safe payload validation. * * @template K - The job name type from TJobMap * @param name - The name of the job type to add * @param request - Job request containing payload and options * @returns Promise that resolves to the unique job ID * * @example * ```typescript * // Simple job addition * const id = await queue.addJob('send-email', { * payload: { * to: 'user@example.com', * subject: 'Hello', * body: 'World' * } * }); * * // With options * await queue.addJob('backup', { * payload: { path: '/data' }, * ttr: 3600, * delaySeconds: 60 * }); * ``` */ addJob(name: K, request: TJobRequest & { payload: TJobMap[K]; }): Promise; /** * Sets all job handlers at once. This method must be called before starting the queue. * All job types defined in TJobMap must have corresponding handlers. * * @param handlers - Complete mapping of job names to their handler functions * * @example * ```typescript * queue.setHandlers({ * 'send-email': async ({ payload }, queue) => { * await emailService.send(payload.to, payload.subject, payload.body); * }, * 'resize-image': async (job, queue) => { * const { payload, id } = job; * console.log(`Processing image resize job ${id}`); * await imageService.resize(payload.url, payload.width, payload.height); * } * }); * ``` */ setHandlers(handlers: JobHandlers): void; /** * Sets or replaces a handler for a specific job type. * Useful for testing or dynamically updating handlers. * * @template K - The job name type from TJobMap * @param jobName - The name of the job type to handle * @param handler - Function to execute when this job type is processed * * @example * ```typescript * // Replace handler for testing * queue.setHandler('send-email', async ({ payload }, queue) => { * console.log('Mock email sent to:', payload.to); * }); * ``` */ setHandler(jobName: K, handler: (job: JobContext, queue: Queue) => Promise | void): void; /** * Gets the current handler for a specific job type. * Useful for testing or introspection. * * @template K - The job name type from TJobMap * @param jobName - The name of the job type * @returns The handler function or undefined if not registered */ getHandler(jobName: K): Function | undefined; /** * Validates that handlers have been registered before starting the queue. */ validateHandlers(): void; on(event: string | symbol, listener: (...args: any[]) => void): this; /** * Starts the queue worker to process jobs continuously or once. * * @param repeat - Whether to continue processing jobs after completing all available jobs (default: false) * @param timeout - Polling timeout in seconds when no jobs are available (default: 0) * @returns Promise that resolves when processing stops * * @example * ```typescript * // Process all available jobs once and stop * await queue.run(); * * // Run continuously, polling every 3 seconds when no jobs available * await queue.run(true, 3); * * // Run continuously with immediate polling (no delay) * await queue.run(true); * ``` */ run(repeat?: boolean, timeout?: number): Promise; /** * Processes a single queue message by executing its registered handlers. * * @param message - The queue message to process * @returns Promise resolving to true if processing succeeded, false if it failed * @protected */ protected handleMessage(message: QueueMessage): Promise<{ success: true; } | { success: false; error: Error; }>; /** * Handles errors that occur during job processing by emitting error events. * * @param message - The queue message that failed to process * @param error - The error that occurred during processing * @returns Promise resolving to false (job failed) * @protected */ protected handleError(message: QueueMessage, error: unknown): Promise; protected sleep(ms: number): Promise; /** * Pushes a new message to the queue storage backend. * * @param payload - Job data before serialization * @param meta - Job metadata including TTR, delaySeconds, priority * @returns Promise resolving to unique job ID * @protected * @abstract */ protected abstract pushMessage(payload: unknown, meta: JobMeta): Promise; /** * Reserves the next available job from the queue for processing. * * @param timeout - Polling timeout in seconds * @returns Promise resolving to queue message or null if no jobs available * @protected * @abstract */ protected abstract reserve(timeout: number): Promise; /** * Marks a job as successfully completed and removes it from the queue. * * @param message - The queue message to complete * @returns Promise that resolves when job is marked as complete * @protected * @abstract */ protected abstract completeJob(message: QueueMessage): Promise; /** * Marks a job as failed and handles failure appropriately (remove or retry). * * @param message - The queue message that failed * @param error - The error that caused the failure * @returns Promise that resolves when job failure is handled * @protected * @abstract */ protected abstract failJob(message: QueueMessage, error: unknown): Promise; /** * Retrieves the current status of a job by its ID. * * @param id - The job ID to check * @returns Promise resolving to job status ('waiting', 'reserved', 'done', 'failed') * @abstract */ abstract status(id: string): Promise; } export declare class QueueError extends Error { constructor({ name, message, cause, }: { name?: string; message: string; cause: unknown; }); static fromError({ message, cause, }: { message: string; cause: unknown; }): QueueError; }