@elysiumjs/heracles 0.4.1

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/src/utils.ts ADDED
@@ -0,0 +1,61 @@
1
+ // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { Job, JobClass, JobMetadata } from './job';
16
+
17
+ export namespace Symbols {
18
+ /**
19
+ * Symbol for job metadata
20
+ */
21
+ export const job = Symbol('elysium:job');
22
+
23
+ /**
24
+ * Symbol for queue metadata
25
+ */
26
+ export const queue = Symbol('elysium:queue');
27
+
28
+ /**
29
+ * Symbol for worker metadata
30
+ */
31
+ export const worker = Symbol('elysium:worker');
32
+
33
+ /**
34
+ * Symbol for transport metadata
35
+ */
36
+ export const transport = Symbol('elysium:transport');
37
+
38
+ /**
39
+ * Symbol for job transaction data
40
+ */
41
+ export const jobTransaction = Symbol('elysium:jobTransaction');
42
+
43
+ /**
44
+ * Symbol for worker pool metadata
45
+ */
46
+ export const workerPool = Symbol('elysium:workerPool');
47
+ }
48
+
49
+ /**
50
+ * Get job metadata from a job class
51
+ * @author Axel Nana <axel.nana@workbud.com>
52
+ * @param jobClass The job class
53
+ * @returns The job metadata or null if not found
54
+ */
55
+ export const getJobMetadata = <T extends Job>(jobClass: JobClass<T>): JobMetadata | null => {
56
+ if (!Reflect.hasMetadata(Symbols.job, jobClass)) {
57
+ return null;
58
+ }
59
+
60
+ return Reflect.getMetadata(Symbols.job, jobClass) as JobMetadata;
61
+ };
package/src/worker.ts ADDED
@@ -0,0 +1,312 @@
1
+ // Copyright (c) 2025-present Workbud Technologies Inc. All rights reserved.
2
+ //
3
+ // Licensed under the Apache License, Version 2.0 (the "License");
4
+ // you may not use this file except in compliance with the License.
5
+ // You may obtain a copy of the License at
6
+ //
7
+ // http://www.apache.org/licenses/LICENSE-2.0
8
+ //
9
+ // Unless required by applicable law or agreed to in writing, software
10
+ // distributed under the License is distributed on an "AS IS" BASIS,
11
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ // See the License for the specific language governing permissions and
13
+ // limitations under the License.
14
+
15
+ import type { Job, JobOverlapBehavior } from './job';
16
+ import type { QueueOptions } from './queue';
17
+ import type { Transport } from './transport';
18
+
19
+ /**
20
+ * Represents a job in the queue with its metadata.
21
+ * @author Axel Nana <axel.nana@workbud.com>
22
+ */
23
+ export type QueuedJob = {
24
+ /**
25
+ * The job instance.
26
+ */
27
+ job: Job;
28
+
29
+ /**
30
+ * The number of times this job has been retried.
31
+ */
32
+ retries: number;
33
+
34
+ /**
35
+ * The queue this job belongs to.
36
+ */
37
+ queueName: string;
38
+
39
+ /**
40
+ * When the job was added to the queue.
41
+ */
42
+ enqueuedAt: Date;
43
+
44
+ /**
45
+ * When the job is scheduled to be processed.
46
+ * This is used for delayed jobs or retry scheduling.
47
+ */
48
+ scheduledFor?: Date;
49
+
50
+ /**
51
+ * Priority of this job (lower number = higher priority).
52
+ * @see JobDispatchOptions.priority
53
+ */
54
+ priority?: number;
55
+
56
+ /**
57
+ * Maximum number of retries for this specific job.
58
+ * Overrides queue-level setting if specified.
59
+ * @see JobDispatchOptions.maxRetries
60
+ */
61
+ maxRetries?: number;
62
+
63
+ /**
64
+ * Delay between retries in milliseconds for this specific job.
65
+ * Overrides queue-level setting if specified.
66
+ * @see JobDispatchOptions.retryDelay
67
+ */
68
+ retryDelay?: number;
69
+
70
+ /**
71
+ * Defines how the job handles overlap with other instances of the same job ID.
72
+ * @see JobOverlapBehavior
73
+ */
74
+ overlapBehavior?: JobOverlapBehavior;
75
+
76
+ /**
77
+ * When using NO_OVERLAP behavior, specifies the delay in milliseconds
78
+ * between sequential executions of jobs with the same ID.
79
+ */
80
+ overlapDelay?: number;
81
+ };
82
+
83
+ /**
84
+ * State associated with a job queue managed by a worker.
85
+ * @author Axel Nana <axel.nana@workbud.com>
86
+ */
87
+ export type QueueState = {
88
+ /**
89
+ * The queue configuration options.
90
+ */
91
+ options: QueueOptions;
92
+
93
+ /**
94
+ * The jobs waiting to be processed.
95
+ */
96
+ jobs: QueuedJob[];
97
+
98
+ /**
99
+ * The jobs currently being processed.
100
+ */
101
+ activeJobs: Map<string, QueuedJob>;
102
+
103
+ /**
104
+ * The number of jobs currently being processed.
105
+ */
106
+ processing: number;
107
+
108
+ /**
109
+ * Whether the queue is currently paused.
110
+ */
111
+ paused: boolean;
112
+
113
+ /**
114
+ * Whether the queue is currently being drained (completing existing jobs but not accepting new ones).
115
+ */
116
+ draining: boolean;
117
+
118
+ /**
119
+ * The transport used by this queue, if different from the worker's default.
120
+ */
121
+ transport?: Transport;
122
+ };
123
+
124
+ /**
125
+ * Worker status information.
126
+ * @author Axel Nana <axel.nana@workbud.com>
127
+ */
128
+ export enum WorkerStatus {
129
+ /**
130
+ * Worker is idle - no jobs are being processed.
131
+ */
132
+ IDLE = 'idle',
133
+
134
+ /**
135
+ * Worker is active - processing jobs.
136
+ */
137
+ ACTIVE = 'active',
138
+
139
+ /**
140
+ * Worker is paused - not accepting new jobs.
141
+ */
142
+ PAUSED = 'paused',
143
+
144
+ /**
145
+ * Worker is draining - completing current jobs but not accepting new ones.
146
+ */
147
+ DRAINING = 'draining',
148
+
149
+ /**
150
+ * Worker is stopping - gracefully shutting down.
151
+ */
152
+ STOPPING = 'stopping',
153
+
154
+ /**
155
+ * Worker is stopped - no longer processing jobs.
156
+ */
157
+ STOPPED = 'stopped',
158
+
159
+ /**
160
+ * Worker is disconnected - lost connection.
161
+ */
162
+ DISCONNECTED = 'disconnected'
163
+ }
164
+
165
+ /**
166
+ * Worker information used by the worker pool.
167
+ * @author Axel Nana <axel.nana@workbud.com>
168
+ */
169
+ export type WorkerInfo = {
170
+ /**
171
+ * The worker ID.
172
+ */
173
+ id: string;
174
+
175
+ /**
176
+ * The worker status.
177
+ */
178
+ status: WorkerStatus;
179
+
180
+ /**
181
+ * The queues handled by this worker.
182
+ */
183
+ queues: string[];
184
+
185
+ /**
186
+ * The jobs being processed by this worker.
187
+ */
188
+ activeJobs: number;
189
+
190
+ /**
191
+ * The transport used by this worker.
192
+ */
193
+ transport: string;
194
+
195
+ /**
196
+ * Start time of this worker.
197
+ */
198
+ startedAt: Date;
199
+
200
+ /**
201
+ * Add a job to this worker.
202
+ */
203
+ addJob(job: Job, queueName?: string): Promise<boolean>;
204
+
205
+ /**
206
+ * Cancel a job on this worker.
207
+ */
208
+ cancelJob(jobId: string, queueName?: string): Promise<boolean>;
209
+
210
+ /**
211
+ * Cancel all jobs on this worker.
212
+ */
213
+ cancelAllJobs(queueName?: string): Promise<number>;
214
+ };
215
+
216
+ /**
217
+ * Standardized interface for a worker managing job queues.
218
+ * @author Axel Nana <axel.nana@workbud.com>
219
+ */
220
+ export interface Worker {
221
+ /**
222
+ * The worker ID.
223
+ */
224
+ id: string;
225
+
226
+ /**
227
+ * The worker status.
228
+ */
229
+ status: WorkerStatus;
230
+
231
+ /**
232
+ * Create a new queue with the specified options.
233
+ */
234
+ createQueue(options: QueueOptions): Promise<Worker>;
235
+
236
+ /**
237
+ * Add a job to a queue.
238
+ */
239
+ addJob(job: Job, queueName?: string): Promise<Worker>;
240
+
241
+ /**
242
+ * Pause a queue to stop processing new jobs.
243
+ */
244
+ pause(queueName?: string): Promise<Worker>;
245
+
246
+ /**
247
+ * Resume a paused queue.
248
+ */
249
+ resume(queueName?: string): Promise<Worker>;
250
+
251
+ /**
252
+ * Drain a queue - complete current jobs but don't accept new ones.
253
+ */
254
+ drain(queueName?: string): Promise<Worker>;
255
+
256
+ /**
257
+ * Clear all jobs from a queue.
258
+ */
259
+ clear(queueName?: string): Promise<Worker>;
260
+
261
+ /**
262
+ * Get the number of jobs in a queue.
263
+ */
264
+ size(queueName?: string): Promise<number>;
265
+
266
+ /**
267
+ * Get the total number of jobs across all queues.
268
+ */
269
+ totalSize(): Promise<number>;
270
+
271
+ /**
272
+ * Get statistics about all queues.
273
+ */
274
+ getStats(): Promise<
275
+ Record<string, { waiting: number; processing: number; paused: boolean; draining: boolean }>
276
+ >;
277
+
278
+ /**
279
+ * Get information about this worker for the worker pool.
280
+ */
281
+ getInfo(): WorkerInfo;
282
+
283
+ /**
284
+ * Cancel a job.
285
+ */
286
+ cancelJob(jobId: string, queueName?: string): Promise<boolean>;
287
+
288
+ /**
289
+ * Cancel all jobs.
290
+ */
291
+ cancelAllJobs(queueName?: string): Promise<number>;
292
+
293
+ /**
294
+ * Get the job with the given ID.
295
+ */
296
+ getJob(jobId: string, queueName?: string): Promise<Job | null>;
297
+
298
+ /**
299
+ * Start the worker.
300
+ */
301
+ start(): Promise<void>;
302
+
303
+ /**
304
+ * Stop the worker.
305
+ */
306
+ stop(force?: boolean): Promise<void>;
307
+
308
+ /**
309
+ * Set the concurrency for a queue.
310
+ */
311
+ setConcurrency(queueName: string, concurrency: number): Promise<void>;
312
+ }