@riktajs/queue 0.1.0

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.
Files changed (62) hide show
  1. package/README.md +476 -0
  2. package/dist/config/queue.config.d.ts +137 -0
  3. package/dist/config/queue.config.d.ts.map +1 -0
  4. package/dist/config/queue.config.js +82 -0
  5. package/dist/config/queue.config.js.map +1 -0
  6. package/dist/constants.d.ts +33 -0
  7. package/dist/constants.d.ts.map +1 -0
  8. package/dist/constants.js +37 -0
  9. package/dist/constants.js.map +1 -0
  10. package/dist/decorators/events.decorator.d.ts +85 -0
  11. package/dist/decorators/events.decorator.d.ts.map +1 -0
  12. package/dist/decorators/events.decorator.js +120 -0
  13. package/dist/decorators/events.decorator.js.map +1 -0
  14. package/dist/decorators/index.d.ts +8 -0
  15. package/dist/decorators/index.d.ts.map +1 -0
  16. package/dist/decorators/index.js +8 -0
  17. package/dist/decorators/index.js.map +1 -0
  18. package/dist/decorators/process.decorator.d.ts +41 -0
  19. package/dist/decorators/process.decorator.d.ts.map +1 -0
  20. package/dist/decorators/process.decorator.js +61 -0
  21. package/dist/decorators/process.decorator.js.map +1 -0
  22. package/dist/decorators/processor.decorator.d.ts +41 -0
  23. package/dist/decorators/processor.decorator.d.ts.map +1 -0
  24. package/dist/decorators/processor.decorator.js +59 -0
  25. package/dist/decorators/processor.decorator.js.map +1 -0
  26. package/dist/decorators/queue.decorator.d.ts +35 -0
  27. package/dist/decorators/queue.decorator.d.ts.map +1 -0
  28. package/dist/decorators/queue.decorator.js +49 -0
  29. package/dist/decorators/queue.decorator.js.map +1 -0
  30. package/dist/events/queue-events.d.ts +32 -0
  31. package/dist/events/queue-events.d.ts.map +1 -0
  32. package/dist/events/queue-events.js +103 -0
  33. package/dist/events/queue-events.js.map +1 -0
  34. package/dist/index.d.ts +22 -0
  35. package/dist/index.d.ts.map +1 -0
  36. package/dist/index.js +30 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/monitoring/bull-board.d.ts +77 -0
  39. package/dist/monitoring/bull-board.d.ts.map +1 -0
  40. package/dist/monitoring/bull-board.js +112 -0
  41. package/dist/monitoring/bull-board.js.map +1 -0
  42. package/dist/providers/queue.provider.d.ts +94 -0
  43. package/dist/providers/queue.provider.d.ts.map +1 -0
  44. package/dist/providers/queue.provider.js +333 -0
  45. package/dist/providers/queue.provider.js.map +1 -0
  46. package/dist/services/queue.service.d.ts +133 -0
  47. package/dist/services/queue.service.d.ts.map +1 -0
  48. package/dist/services/queue.service.js +192 -0
  49. package/dist/services/queue.service.js.map +1 -0
  50. package/dist/types.d.ts +133 -0
  51. package/dist/types.d.ts.map +1 -0
  52. package/dist/types.js +5 -0
  53. package/dist/types.js.map +1 -0
  54. package/dist/utils/connection.d.ts +47 -0
  55. package/dist/utils/connection.d.ts.map +1 -0
  56. package/dist/utils/connection.js +104 -0
  57. package/dist/utils/connection.js.map +1 -0
  58. package/dist/utils/validation.d.ts +187 -0
  59. package/dist/utils/validation.d.ts.map +1 -0
  60. package/dist/utils/validation.js +156 -0
  61. package/dist/utils/validation.js.map +1 -0
  62. package/package.json +69 -0
@@ -0,0 +1,333 @@
1
+ /**
2
+ * QueueProvider - Main provider for queue lifecycle management
3
+ *
4
+ * Implements OnProviderInit and OnProviderDestroy for Rikta lifecycle integration.
5
+ * Not @Injectable - use createQueueProvider() factory function.
6
+ */
7
+ import { Queue, Worker, QueueEvents } from 'bullmq';
8
+ import { QUEUE_PROVIDER, QUEUE_SERVICE, getQueueToken, getWorkerToken } from '../constants.js';
9
+ import { loadQueueConfig } from '../config/queue.config.js';
10
+ import { RedisConnectionManager, QueueConnectionError } from '../utils/connection.js';
11
+ import { getProcessorOptions, isProcessor } from '../decorators/processor.decorator.js';
12
+ import { getJobHandlers } from '../decorators/process.decorator.js';
13
+ import { getEventHandlers } from '../decorators/events.decorator.js';
14
+ import { publishQueueEvent } from '../events/queue-events.js';
15
+ import { QueueService } from '../services/queue.service.js';
16
+ /**
17
+ * QueueProvider manages the lifecycle of all queues and workers.
18
+ *
19
+ * @example
20
+ * ```typescript
21
+ * const provider = createQueueProvider({
22
+ * config: { redis: { host: 'localhost', port: 6379 } }
23
+ * });
24
+ *
25
+ * // In Rikta bootstrap:
26
+ * await app.register(provider);
27
+ * ```
28
+ */
29
+ export class QueueProvider {
30
+ connectionManager = new RedisConnectionManager();
31
+ config;
32
+ queues = new Map();
33
+ workers = new Map();
34
+ processorClasses = [];
35
+ initialized = false;
36
+ eventBus = null;
37
+ options = {
38
+ autoInitialize: true,
39
+ retryAttempts: 0,
40
+ retryDelay: 3000,
41
+ };
42
+ /**
43
+ * Configure the provider with options
44
+ */
45
+ configure(options) {
46
+ this.options = { ...this.options, ...options };
47
+ return this;
48
+ }
49
+ /**
50
+ * Register processor classes for auto-discovery
51
+ */
52
+ registerProcessors(...processors) {
53
+ this.processorClasses.push(...processors);
54
+ return this;
55
+ }
56
+ /**
57
+ * Set EventBus for event emission (optional)
58
+ */
59
+ setEventBus(eventBus) {
60
+ this.eventBus = eventBus;
61
+ return this;
62
+ }
63
+ /**
64
+ * Initialize all queues and workers (called by Rikta lifecycle)
65
+ */
66
+ async onProviderInit() {
67
+ console.log('🚀 Queue: Initializing queue system...');
68
+ try {
69
+ // Load configuration
70
+ this.config = loadQueueConfig(this.options.config);
71
+ // Configure Redis connection
72
+ this.connectionManager.configure(this.config.redis);
73
+ // Test connection
74
+ await this.testConnection();
75
+ // Discover and register processors
76
+ await this.discoverAndRegisterProcessors();
77
+ // Register in container
78
+ this.registerInContainer();
79
+ this.initialized = true;
80
+ console.log(`✅ Queue: Initialized ${this.queues.size} queue(s), ${this.workers.size} worker(s)`);
81
+ }
82
+ catch (error) {
83
+ console.error('❌ Queue: Failed to initialize queue system');
84
+ throw error;
85
+ }
86
+ }
87
+ /**
88
+ * Gracefully shutdown all workers and close connections
89
+ */
90
+ async onProviderDestroy() {
91
+ if (!this.initialized)
92
+ return;
93
+ console.log('🔌 Queue: Shutting down queue system...');
94
+ try {
95
+ const timeout = this.config.shutdownTimeout || 30000;
96
+ // Close all workers gracefully
97
+ const workerClosePromises = Array.from(this.workers.values()).map(async ({ worker, queueName }) => {
98
+ console.log(` ⏳ Closing worker for ${queueName}...`);
99
+ await Promise.race([
100
+ worker.close(),
101
+ this.delay(timeout),
102
+ ]);
103
+ });
104
+ await Promise.all(workerClosePromises);
105
+ // Close all queue event listeners
106
+ for (const { queueEvents } of this.queues.values()) {
107
+ if (queueEvents) {
108
+ await queueEvents.close();
109
+ }
110
+ }
111
+ // Close all queues
112
+ for (const { queue } of this.queues.values()) {
113
+ await queue.close();
114
+ }
115
+ // Close Redis connection
116
+ await this.connectionManager.close();
117
+ this.initialized = false;
118
+ console.log('✅ Queue: Queue system shut down');
119
+ }
120
+ catch (error) {
121
+ console.error('❌ Queue: Error during shutdown:', error);
122
+ }
123
+ }
124
+ /**
125
+ * Get a queue by name
126
+ */
127
+ getQueue(name) {
128
+ return this.queues.get(name)?.queue;
129
+ }
130
+ /**
131
+ * Get all registered queues
132
+ */
133
+ getAllQueues() {
134
+ return Array.from(this.queues.values()).map(q => q.queue);
135
+ }
136
+ /**
137
+ * Check if the provider is initialized
138
+ */
139
+ isInitialized() {
140
+ return this.initialized;
141
+ }
142
+ /**
143
+ * Get configuration
144
+ */
145
+ getConfig() {
146
+ return this.config;
147
+ }
148
+ // --- Private methods ---
149
+ async testConnection() {
150
+ const client = this.connectionManager.getClient();
151
+ const { retryAttempts = 0, retryDelay = 3000 } = this.options;
152
+ let lastError;
153
+ for (let attempt = 0; attempt <= retryAttempts; attempt++) {
154
+ try {
155
+ await client.ping();
156
+ return;
157
+ }
158
+ catch (error) {
159
+ lastError = error;
160
+ if (attempt < retryAttempts) {
161
+ console.warn(`⚠️ Queue: Connection attempt ${attempt + 1}/${retryAttempts + 1} failed. Retrying in ${retryDelay}ms...`);
162
+ await this.delay(retryDelay);
163
+ }
164
+ }
165
+ }
166
+ throw new QueueConnectionError(`Failed to connect to Redis: ${lastError?.message}`, this.config.redis.host, this.config.redis.port, lastError);
167
+ }
168
+ async discoverAndRegisterProcessors() {
169
+ for (const processorClass of this.processorClasses) {
170
+ if (!isProcessor(processorClass)) {
171
+ console.warn(`⚠️ Queue: ${processorClass.name} is not decorated with @Processor, skipping`);
172
+ continue;
173
+ }
174
+ const options = getProcessorOptions(processorClass);
175
+ if (!options)
176
+ continue;
177
+ await this.registerProcessor(processorClass, options);
178
+ }
179
+ }
180
+ async registerProcessor(processorClass, options) {
181
+ const { queueName, concurrency, rateLimiter, workerOptions } = options;
182
+ // Create queue if not exists
183
+ if (!this.queues.has(queueName)) {
184
+ await this.createQueue(queueName);
185
+ }
186
+ // Get job handlers
187
+ const jobHandlers = getJobHandlers(processorClass);
188
+ const eventHandlers = getEventHandlers(processorClass);
189
+ // Create processor instance
190
+ const processor = new processorClass();
191
+ // Create worker
192
+ const worker = new Worker(queueName, async (job) => {
193
+ // Find handler for this job
194
+ const handler = jobHandlers.find(h => h.name === job.name);
195
+ if (!handler) {
196
+ throw new Error(`No handler found for job: ${job.name}`);
197
+ }
198
+ // Call handler method
199
+ const method = processor[handler.methodName];
200
+ if (typeof method !== 'function') {
201
+ throw new Error(`Handler method ${handler.methodName} not found`);
202
+ }
203
+ return method.call(processor, job);
204
+ }, {
205
+ connection: this.connectionManager.getClient(),
206
+ concurrency: concurrency || this.config.defaultConcurrency || 1,
207
+ limiter: rateLimiter || this.config.defaultRateLimiter,
208
+ ...workerOptions,
209
+ });
210
+ // Attach event handlers
211
+ this.attachWorkerEvents(worker, queueName, processor, eventHandlers);
212
+ // Store worker
213
+ this.workers.set(queueName, {
214
+ queueName,
215
+ worker,
216
+ processor,
217
+ processorClass,
218
+ });
219
+ console.log(` 📦 Registered processor for queue: ${queueName} (${jobHandlers.length} handlers)`);
220
+ }
221
+ async createQueue(name) {
222
+ const queue = new Queue(name, {
223
+ connection: this.connectionManager.getClient(),
224
+ });
225
+ // Create queue events for monitoring
226
+ const queueEvents = new QueueEvents(name, {
227
+ connection: this.connectionManager.getClient(),
228
+ });
229
+ this.queues.set(name, { name, queue, queueEvents });
230
+ }
231
+ attachWorkerEvents(worker, queueName, processor, eventHandlers) {
232
+ worker.on('completed', async (job, result) => {
233
+ await this.handleEvent('job:completed', queueName, processor, eventHandlers, job, result);
234
+ });
235
+ worker.on('failed', async (job, error) => {
236
+ await this.handleEvent('job:failed', queueName, processor, eventHandlers, job, error);
237
+ });
238
+ worker.on('progress', async (job, progress) => {
239
+ await this.handleEvent('job:progress', queueName, processor, eventHandlers, job, progress);
240
+ });
241
+ worker.on('stalled', async (jobId) => {
242
+ await this.handleEvent('job:stalled', queueName, processor, eventHandlers, jobId);
243
+ });
244
+ worker.on('ready', async () => {
245
+ await this.handleEvent('worker:ready', queueName, processor, eventHandlers);
246
+ });
247
+ worker.on('error', async (error) => {
248
+ await this.handleEvent('worker:error', queueName, processor, eventHandlers, error);
249
+ });
250
+ }
251
+ async handleEvent(event, queueName, processor, eventHandlers, ...args) {
252
+ // Call processor event handlers
253
+ const handlers = eventHandlers.filter(h => h.event === event);
254
+ for (const handler of handlers) {
255
+ const method = processor[handler.methodName];
256
+ if (typeof method === 'function') {
257
+ try {
258
+ await method.call(processor, ...args);
259
+ }
260
+ catch (error) {
261
+ console.error(`Error in event handler ${handler.methodName}:`, error);
262
+ }
263
+ }
264
+ }
265
+ // Emit to EventBus if available
266
+ if (this.eventBus) {
267
+ try {
268
+ await publishQueueEvent(this.eventBus, event, queueName, ...args);
269
+ }
270
+ catch {
271
+ // Ignore EventBus errors
272
+ }
273
+ }
274
+ }
275
+ registerInContainer() {
276
+ try {
277
+ // Dynamic import to avoid circular dependency
278
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
279
+ const { Container } = require('@riktajs/core');
280
+ const container = Container.getInstance();
281
+ // Register provider
282
+ container.registerValue(QUEUE_PROVIDER, this);
283
+ // Register queues
284
+ for (const [name, { queue }] of this.queues) {
285
+ container.registerValue(getQueueToken(name), queue);
286
+ }
287
+ // Register workers
288
+ for (const [name, { worker }] of this.workers) {
289
+ container.registerValue(getWorkerToken(name), worker);
290
+ }
291
+ // Create and register QueueService
292
+ const queueService = new QueueService(this);
293
+ container.registerValue(QUEUE_SERVICE, queueService);
294
+ }
295
+ catch {
296
+ // Container not available, skip registration
297
+ }
298
+ }
299
+ delay(ms) {
300
+ return new Promise(resolve => setTimeout(resolve, ms));
301
+ }
302
+ }
303
+ /**
304
+ * Factory function to create a QueueProvider
305
+ */
306
+ export function createQueueProvider(options) {
307
+ const provider = new QueueProvider();
308
+ if (options) {
309
+ provider.configure(options);
310
+ }
311
+ return provider;
312
+ }
313
+ /**
314
+ * Error thrown when queue initialization fails
315
+ */
316
+ export class QueueInitializationError extends Error {
317
+ cause;
318
+ constructor(message, cause) {
319
+ super(message);
320
+ this.cause = cause;
321
+ this.name = 'QueueInitializationError';
322
+ }
323
+ }
324
+ /**
325
+ * Error thrown when a duplicate queue is detected
326
+ */
327
+ export class DuplicateQueueError extends Error {
328
+ constructor(queueName) {
329
+ super(`Duplicate queue registration: ${queueName}`);
330
+ this.name = 'DuplicateQueueError';
331
+ }
332
+ }
333
+ //# sourceMappingURL=queue.provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.provider.js","sourceRoot":"","sources":["../../src/providers/queue.provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * QueueService - Injectable service for adding jobs to queues
3
+ */
4
+ import type { Job, JobsOptions, RepeatOptions } from 'bullmq';
5
+ import type { QueueProvider } from '../providers/queue.provider.js';
6
+ import type { AddJobOptions, ScheduleOptions } from '../types.js';
7
+ /**
8
+ * Service for adding jobs to queues from anywhere in the application.
9
+ *
10
+ * @example
11
+ * ```typescript
12
+ * @Injectable()
13
+ * class NotificationService {
14
+ * @Autowired()
15
+ * private queueService!: QueueService;
16
+ *
17
+ * async sendNotification(userId: string, message: string) {
18
+ * await this.queueService.addJob('notifications', 'send', {
19
+ * userId,
20
+ * message,
21
+ * });
22
+ * }
23
+ * }
24
+ * ```
25
+ */
26
+ export declare class QueueService {
27
+ private readonly provider;
28
+ constructor(provider: QueueProvider);
29
+ /**
30
+ * Add a job to a queue
31
+ *
32
+ * @param queueName - Name of the queue
33
+ * @param jobName - Name of the job (matches @Process decorator)
34
+ * @param data - Job payload data
35
+ * @param options - Optional job options
36
+ * @returns The created job
37
+ */
38
+ addJob<TData = unknown, TResult = unknown>(queueName: string, jobName: string, data: TData, options?: AddJobOptions): Promise<Job<TData, TResult>>;
39
+ /**
40
+ * Add multiple jobs to a queue in bulk
41
+ *
42
+ * @param queueName - Name of the queue
43
+ * @param jobs - Array of jobs to add
44
+ * @returns Array of created jobs
45
+ */
46
+ addJobs<TData = unknown, TResult = unknown>(queueName: string, jobs: Array<{
47
+ name: string;
48
+ data: TData;
49
+ options?: JobsOptions;
50
+ }>): Promise<Job<TData, TResult>[]>;
51
+ /**
52
+ * Add a delayed job
53
+ *
54
+ * @param queueName - Name of the queue
55
+ * @param jobName - Name of the job
56
+ * @param data - Job payload data
57
+ * @param delay - Delay in milliseconds
58
+ * @param options - Optional job options
59
+ */
60
+ addDelayedJob<TData = unknown, TResult = unknown>(queueName: string, jobName: string, data: TData, delay: number, options?: JobsOptions): Promise<Job<TData, TResult>>;
61
+ /**
62
+ * Add a repeatable job (scheduled)
63
+ *
64
+ * @param queueName - Name of the queue
65
+ * @param jobName - Name of the job
66
+ * @param data - Job payload data
67
+ * @param repeat - Repeat options (cron pattern, interval, etc.)
68
+ * @param options - Optional schedule options
69
+ */
70
+ addRepeatableJob<TData = unknown, TResult = unknown>(queueName: string, jobName: string, data: TData, repeat: RepeatOptions, options?: ScheduleOptions): Promise<Job<TData, TResult>>;
71
+ /**
72
+ * Remove a repeatable job
73
+ *
74
+ * @param queueName - Name of the queue
75
+ * @param jobName - Name of the job
76
+ * @param repeat - The repeat options used when creating the job
77
+ */
78
+ removeRepeatableJob(queueName: string, jobName: string, repeat: RepeatOptions): Promise<boolean>;
79
+ /**
80
+ * Get a job by ID
81
+ *
82
+ * @param queueName - Name of the queue
83
+ * @param jobId - Job ID
84
+ */
85
+ getJob<TData = unknown, TResult = unknown>(queueName: string, jobId: string): Promise<Job<TData, TResult> | undefined>;
86
+ /**
87
+ * Get queue statistics
88
+ *
89
+ * @param queueName - Name of the queue
90
+ */
91
+ getQueueStats(queueName: string): Promise<{
92
+ waiting: number;
93
+ active: number;
94
+ completed: number;
95
+ failed: number;
96
+ delayed: number;
97
+ paused: number;
98
+ }>;
99
+ /**
100
+ * Pause a queue
101
+ */
102
+ pauseQueue(queueName: string): Promise<void>;
103
+ /**
104
+ * Resume a queue
105
+ */
106
+ resumeQueue(queueName: string): Promise<void>;
107
+ /**
108
+ * Clear all jobs from a queue
109
+ *
110
+ * @param queueName - Name of the queue
111
+ * @param status - Which jobs to clear (default: all)
112
+ */
113
+ clearQueue(queueName: string, status?: 'completed' | 'failed' | 'delayed' | 'wait' | 'active'): Promise<void>;
114
+ /**
115
+ * Get all queue names
116
+ */
117
+ getQueueNames(): string[];
118
+ private getQueueOrThrow;
119
+ }
120
+ /**
121
+ * Error thrown when a queue is not found
122
+ */
123
+ export declare class QueueNotFoundError extends Error {
124
+ constructor(queueName: string);
125
+ }
126
+ /**
127
+ * Error thrown when job validation fails
128
+ */
129
+ export declare class JobValidationError extends Error {
130
+ readonly errors: unknown[];
131
+ constructor(message: string, errors: unknown[]);
132
+ }
133
+ //# sourceMappingURL=queue.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"queue.service.d.ts","sourceRoot":"","sources":["../../src/services/queue.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * QueueService - Injectable service for adding jobs to queues
3
+ */
4
+ /**
5
+ * Service for adding jobs to queues from anywhere in the application.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * @Injectable()
10
+ * class NotificationService {
11
+ * @Autowired()
12
+ * private queueService!: QueueService;
13
+ *
14
+ * async sendNotification(userId: string, message: string) {
15
+ * await this.queueService.addJob('notifications', 'send', {
16
+ * userId,
17
+ * message,
18
+ * });
19
+ * }
20
+ * }
21
+ * ```
22
+ */
23
+ export class QueueService {
24
+ provider;
25
+ constructor(provider) {
26
+ this.provider = provider;
27
+ }
28
+ /**
29
+ * Add a job to a queue
30
+ *
31
+ * @param queueName - Name of the queue
32
+ * @param jobName - Name of the job (matches @Process decorator)
33
+ * @param data - Job payload data
34
+ * @param options - Optional job options
35
+ * @returns The created job
36
+ */
37
+ async addJob(queueName, jobName, data, options) {
38
+ const queue = this.getQueueOrThrow(queueName);
39
+ // Handle deduplication
40
+ const jobOptions = { ...options };
41
+ if (options?.deduplicationKey) {
42
+ jobOptions.jobId = options.deduplicationKey;
43
+ }
44
+ return queue.add(jobName, data, jobOptions);
45
+ }
46
+ /**
47
+ * Add multiple jobs to a queue in bulk
48
+ *
49
+ * @param queueName - Name of the queue
50
+ * @param jobs - Array of jobs to add
51
+ * @returns Array of created jobs
52
+ */
53
+ async addJobs(queueName, jobs) {
54
+ const queue = this.getQueueOrThrow(queueName);
55
+ const bulkJobs = jobs.map(j => ({
56
+ name: j.name,
57
+ data: j.data,
58
+ opts: j.options,
59
+ }));
60
+ return queue.addBulk(bulkJobs);
61
+ }
62
+ /**
63
+ * Add a delayed job
64
+ *
65
+ * @param queueName - Name of the queue
66
+ * @param jobName - Name of the job
67
+ * @param data - Job payload data
68
+ * @param delay - Delay in milliseconds
69
+ * @param options - Optional job options
70
+ */
71
+ async addDelayedJob(queueName, jobName, data, delay, options) {
72
+ return this.addJob(queueName, jobName, data, { ...options, delay });
73
+ }
74
+ /**
75
+ * Add a repeatable job (scheduled)
76
+ *
77
+ * @param queueName - Name of the queue
78
+ * @param jobName - Name of the job
79
+ * @param data - Job payload data
80
+ * @param repeat - Repeat options (cron pattern, interval, etc.)
81
+ * @param options - Optional schedule options
82
+ */
83
+ async addRepeatableJob(queueName, jobName, data, repeat, options) {
84
+ const queue = this.getQueueOrThrow(queueName);
85
+ return queue.add(jobName, data, {
86
+ ...options,
87
+ repeat,
88
+ jobId: options?.jobId,
89
+ });
90
+ }
91
+ /**
92
+ * Remove a repeatable job
93
+ *
94
+ * @param queueName - Name of the queue
95
+ * @param jobName - Name of the job
96
+ * @param repeat - The repeat options used when creating the job
97
+ */
98
+ async removeRepeatableJob(queueName, jobName, repeat) {
99
+ const queue = this.getQueueOrThrow(queueName);
100
+ return queue.removeRepeatableByKey(`${jobName}:${JSON.stringify(repeat)}`);
101
+ }
102
+ /**
103
+ * Get a job by ID
104
+ *
105
+ * @param queueName - Name of the queue
106
+ * @param jobId - Job ID
107
+ */
108
+ async getJob(queueName, jobId) {
109
+ const queue = this.getQueueOrThrow(queueName);
110
+ return queue.getJob(jobId);
111
+ }
112
+ /**
113
+ * Get queue statistics
114
+ *
115
+ * @param queueName - Name of the queue
116
+ */
117
+ async getQueueStats(queueName) {
118
+ const queue = this.getQueueOrThrow(queueName);
119
+ const [waiting, active, completed, failed, delayed, paused] = await Promise.all([
120
+ queue.getWaitingCount(),
121
+ queue.getActiveCount(),
122
+ queue.getCompletedCount(),
123
+ queue.getFailedCount(),
124
+ queue.getDelayedCount(),
125
+ queue.isPaused().then(p => (p ? 1 : 0)),
126
+ ]);
127
+ return { waiting, active, completed, failed, delayed, paused };
128
+ }
129
+ /**
130
+ * Pause a queue
131
+ */
132
+ async pauseQueue(queueName) {
133
+ const queue = this.getQueueOrThrow(queueName);
134
+ await queue.pause();
135
+ }
136
+ /**
137
+ * Resume a queue
138
+ */
139
+ async resumeQueue(queueName) {
140
+ const queue = this.getQueueOrThrow(queueName);
141
+ await queue.resume();
142
+ }
143
+ /**
144
+ * Clear all jobs from a queue
145
+ *
146
+ * @param queueName - Name of the queue
147
+ * @param status - Which jobs to clear (default: all)
148
+ */
149
+ async clearQueue(queueName, status) {
150
+ const queue = this.getQueueOrThrow(queueName);
151
+ if (status) {
152
+ await queue.clean(0, 0, status);
153
+ }
154
+ else {
155
+ await queue.obliterate({ force: true });
156
+ }
157
+ }
158
+ /**
159
+ * Get all queue names
160
+ */
161
+ getQueueNames() {
162
+ return this.provider.getAllQueues().map(q => q.name);
163
+ }
164
+ getQueueOrThrow(queueName) {
165
+ const queue = this.provider.getQueue(queueName);
166
+ if (!queue) {
167
+ throw new QueueNotFoundError(queueName);
168
+ }
169
+ return queue;
170
+ }
171
+ }
172
+ /**
173
+ * Error thrown when a queue is not found
174
+ */
175
+ export class QueueNotFoundError extends Error {
176
+ constructor(queueName) {
177
+ super(`Queue not found: ${queueName}`);
178
+ this.name = 'QueueNotFoundError';
179
+ }
180
+ }
181
+ /**
182
+ * Error thrown when job validation fails
183
+ */
184
+ export class JobValidationError extends Error {
185
+ errors;
186
+ constructor(message, errors) {
187
+ super(message);
188
+ this.errors = errors;
189
+ this.name = 'JobValidationError';
190
+ }
191
+ }
192
+ //# sourceMappingURL=queue.service.js.map