nmtjs 0.15.0-beta.2 → 0.15.0-beta.20

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 (254) hide show
  1. package/dist/cli.d.ts +2 -0
  2. package/dist/cli.js +3 -2
  3. package/dist/cli.js.map +1 -0
  4. package/dist/config.d.ts +51 -0
  5. package/dist/config.js +1 -0
  6. package/dist/config.js.map +1 -0
  7. package/dist/entrypoints/cli.d.ts +1 -0
  8. package/dist/entrypoints/cli.js +1 -0
  9. package/dist/entrypoints/cli.js.map +1 -0
  10. package/dist/entrypoints/main.d.ts +5 -0
  11. package/dist/entrypoints/main.js +83 -15
  12. package/dist/entrypoints/main.js.map +1 -0
  13. package/dist/entrypoints/thread.d.ts +14 -0
  14. package/dist/entrypoints/thread.js +130 -24
  15. package/dist/entrypoints/thread.js.map +1 -0
  16. package/dist/entrypoints/worker.d.ts +3 -0
  17. package/dist/entrypoints/worker.js +4 -3
  18. package/dist/entrypoints/worker.js.map +1 -0
  19. package/dist/index.d.ts +69 -0
  20. package/dist/{_exports/index.js → index.js} +9 -5
  21. package/dist/index.js.map +1 -0
  22. package/dist/resolver.d.ts +2 -0
  23. package/dist/resolver.js +1 -0
  24. package/dist/resolver.js.map +1 -0
  25. package/dist/runtime/application/api/api.d.ts +49 -0
  26. package/dist/runtime/application/api/api.js +193 -0
  27. package/dist/runtime/application/api/api.js.map +1 -0
  28. package/dist/runtime/application/api/constants.d.ts +14 -0
  29. package/dist/runtime/application/api/constants.js +8 -0
  30. package/dist/runtime/application/api/constants.js.map +1 -0
  31. package/dist/runtime/application/api/filters.d.ts +14 -0
  32. package/dist/runtime/application/api/filters.js +11 -0
  33. package/dist/runtime/application/api/filters.js.map +1 -0
  34. package/dist/runtime/application/api/guards.d.ts +13 -0
  35. package/dist/runtime/application/api/guards.js +8 -0
  36. package/dist/runtime/application/api/guards.js.map +1 -0
  37. package/dist/runtime/application/api/index.d.ts +8 -0
  38. package/dist/runtime/application/api/index.js +9 -0
  39. package/dist/runtime/application/api/index.js.map +1 -0
  40. package/dist/runtime/application/api/middlewares.d.ts +14 -0
  41. package/dist/runtime/application/api/middlewares.js +12 -0
  42. package/dist/runtime/application/api/middlewares.js.map +1 -0
  43. package/dist/runtime/application/api/procedure.d.ts +67 -0
  44. package/dist/runtime/application/api/procedure.js +50 -0
  45. package/dist/runtime/application/api/procedure.js.map +1 -0
  46. package/dist/runtime/application/api/router.d.ts +71 -0
  47. package/dist/runtime/application/api/router.js +51 -0
  48. package/dist/runtime/application/api/router.js.map +1 -0
  49. package/dist/runtime/application/api/types.d.ts +32 -0
  50. package/dist/runtime/application/api/types.js +2 -0
  51. package/dist/runtime/application/api/types.js.map +1 -0
  52. package/dist/runtime/application/config.d.ts +26 -0
  53. package/dist/runtime/application/config.js +21 -0
  54. package/dist/runtime/application/config.js.map +1 -0
  55. package/dist/runtime/application/constants.d.ts +2 -0
  56. package/dist/runtime/application/constants.js +2 -0
  57. package/dist/runtime/application/constants.js.map +1 -0
  58. package/dist/runtime/application/hook.d.ts +19 -0
  59. package/dist/runtime/application/hook.js +11 -0
  60. package/dist/runtime/application/hook.js.map +1 -0
  61. package/dist/runtime/application/hooks.d.ts +3 -0
  62. package/dist/runtime/application/hooks.js +4 -0
  63. package/dist/runtime/application/hooks.js.map +1 -0
  64. package/dist/runtime/application/index.d.ts +5 -0
  65. package/dist/runtime/application/index.js +6 -0
  66. package/dist/runtime/application/index.js.map +1 -0
  67. package/dist/runtime/constants.d.ts +8 -0
  68. package/dist/runtime/constants.js +5 -0
  69. package/dist/runtime/constants.js.map +1 -0
  70. package/dist/runtime/core/hooks.d.ts +4 -0
  71. package/dist/runtime/core/hooks.js +4 -0
  72. package/dist/runtime/core/hooks.js.map +1 -0
  73. package/dist/runtime/core/plugin.d.ts +8 -0
  74. package/dist/runtime/core/plugin.js +4 -0
  75. package/dist/runtime/core/plugin.js.map +1 -0
  76. package/dist/runtime/core/runtime.d.ts +27 -0
  77. package/dist/runtime/core/runtime.js +81 -0
  78. package/dist/runtime/core/runtime.js.map +1 -0
  79. package/dist/runtime/enums.d.ts +21 -0
  80. package/dist/runtime/enums.js +26 -0
  81. package/dist/runtime/enums.js.map +1 -0
  82. package/dist/runtime/index.d.ts +21 -0
  83. package/dist/runtime/index.js +22 -0
  84. package/dist/runtime/index.js.map +1 -0
  85. package/dist/runtime/injectables.d.ts +23 -0
  86. package/dist/runtime/injectables.js +20 -0
  87. package/dist/runtime/injectables.js.map +1 -0
  88. package/dist/runtime/jobs/job.d.ts +132 -0
  89. package/dist/runtime/jobs/job.js +68 -0
  90. package/dist/runtime/jobs/job.js.map +1 -0
  91. package/dist/runtime/jobs/manager.d.ts +103 -0
  92. package/dist/runtime/jobs/manager.js +200 -0
  93. package/dist/runtime/jobs/manager.js.map +1 -0
  94. package/dist/runtime/jobs/router.d.ts +251 -0
  95. package/dist/runtime/jobs/router.js +396 -0
  96. package/dist/runtime/jobs/router.js.map +1 -0
  97. package/dist/runtime/jobs/runner.d.ts +64 -0
  98. package/dist/runtime/jobs/runner.js +256 -0
  99. package/dist/runtime/jobs/runner.js.map +1 -0
  100. package/dist/runtime/jobs/step.d.ts +22 -0
  101. package/dist/runtime/jobs/step.js +18 -0
  102. package/dist/runtime/jobs/step.js.map +1 -0
  103. package/dist/runtime/jobs/ui.d.ts +3 -0
  104. package/dist/runtime/jobs/ui.js +17 -0
  105. package/dist/runtime/jobs/ui.js.map +1 -0
  106. package/dist/runtime/pubsub/manager.d.ts +48 -0
  107. package/dist/runtime/pubsub/manager.js +119 -0
  108. package/dist/runtime/pubsub/manager.js.map +1 -0
  109. package/dist/runtime/pubsub/redis.d.ts +16 -0
  110. package/dist/runtime/pubsub/redis.js +98 -0
  111. package/dist/runtime/pubsub/redis.js.map +1 -0
  112. package/dist/runtime/scheduler/index.d.ts +22 -0
  113. package/dist/runtime/scheduler/index.js +20 -0
  114. package/dist/runtime/scheduler/index.js.map +1 -0
  115. package/dist/runtime/server/applications.d.ts +52 -0
  116. package/dist/runtime/server/applications.js +133 -0
  117. package/dist/runtime/server/applications.js.map +1 -0
  118. package/dist/runtime/server/config.d.ts +121 -0
  119. package/dist/runtime/server/config.js +33 -0
  120. package/dist/runtime/server/config.js.map +1 -0
  121. package/dist/runtime/server/jobs.d.ts +41 -0
  122. package/dist/runtime/server/jobs.js +181 -0
  123. package/dist/runtime/server/jobs.js.map +1 -0
  124. package/dist/runtime/server/pool.d.ts +54 -0
  125. package/dist/runtime/server/pool.js +194 -0
  126. package/dist/runtime/server/pool.js.map +1 -0
  127. package/dist/runtime/server/proxy.d.ts +21 -0
  128. package/dist/runtime/server/proxy.js +79 -0
  129. package/dist/runtime/server/proxy.js.map +1 -0
  130. package/dist/runtime/server/server.d.ts +53 -0
  131. package/dist/runtime/server/server.js +90 -0
  132. package/dist/runtime/server/server.js.map +1 -0
  133. package/dist/runtime/store/index.d.ts +3 -0
  134. package/dist/runtime/store/index.js +23 -0
  135. package/dist/runtime/store/index.js.map +1 -0
  136. package/dist/runtime/types.d.ts +103 -0
  137. package/dist/runtime/types.js +2 -0
  138. package/dist/runtime/types.js.map +1 -0
  139. package/dist/runtime/workers/application.d.ts +47 -0
  140. package/dist/runtime/workers/application.js +162 -0
  141. package/dist/runtime/workers/application.js.map +1 -0
  142. package/dist/runtime/workers/base.d.ts +16 -0
  143. package/dist/runtime/workers/base.js +46 -0
  144. package/dist/runtime/workers/base.js.map +1 -0
  145. package/dist/runtime/workers/cli.d.ts +1 -0
  146. package/dist/runtime/workers/cli.js +2 -0
  147. package/dist/runtime/workers/cli.js.map +1 -0
  148. package/dist/runtime/workers/job.d.ts +20 -0
  149. package/dist/runtime/workers/job.js +172 -0
  150. package/dist/runtime/workers/job.js.map +1 -0
  151. package/dist/typings.d.ts +5 -0
  152. package/dist/typings.js +4 -3
  153. package/dist/typings.js.map +1 -0
  154. package/dist/vite/builder.d.ts +5 -0
  155. package/dist/vite/builder.js +5 -1
  156. package/dist/vite/builder.js.map +1 -0
  157. package/dist/vite/config.d.ts +28 -0
  158. package/dist/vite/config.js +1 -0
  159. package/dist/vite/config.js.map +1 -0
  160. package/dist/vite/plugins.d.ts +2 -0
  161. package/dist/vite/plugins.js +1 -0
  162. package/dist/vite/plugins.js.map +1 -0
  163. package/dist/vite/runners/worker.d.ts +4 -0
  164. package/dist/vite/runners/worker.js +1 -0
  165. package/dist/vite/runners/worker.js.map +1 -0
  166. package/dist/vite/server.d.ts +3 -0
  167. package/dist/vite/server.js +6 -1
  168. package/dist/vite/server.js.map +1 -0
  169. package/dist/vite/servers/main.d.ts +8 -0
  170. package/dist/vite/servers/main.js +1 -0
  171. package/dist/vite/servers/main.js.map +1 -0
  172. package/dist/vite/servers/worker.d.ts +11 -0
  173. package/dist/vite/servers/worker.js +28 -0
  174. package/dist/vite/servers/worker.js.map +1 -0
  175. package/package.json +31 -18
  176. package/src/cli.ts +144 -0
  177. package/src/config.ts +64 -0
  178. package/src/entrypoints/cli.ts +13 -0
  179. package/src/entrypoints/main.ts +200 -0
  180. package/src/entrypoints/thread.ts +184 -0
  181. package/src/entrypoints/worker.ts +48 -0
  182. package/src/index.ts +82 -0
  183. package/src/resolver.ts +16 -0
  184. package/src/runtime/application/api/api.ts +265 -0
  185. package/src/runtime/application/api/constants.ts +22 -0
  186. package/src/runtime/application/api/filters.ts +39 -0
  187. package/src/runtime/application/api/guards.ts +29 -0
  188. package/src/runtime/application/api/index.ts +8 -0
  189. package/src/runtime/application/api/middlewares.ts +37 -0
  190. package/src/runtime/application/api/procedure.ts +229 -0
  191. package/src/runtime/application/api/router.ts +193 -0
  192. package/src/runtime/application/api/types.ts +124 -0
  193. package/src/runtime/application/config.ts +69 -0
  194. package/src/runtime/application/constants.ts +4 -0
  195. package/src/runtime/application/hook.ts +51 -0
  196. package/src/runtime/application/hooks.ts +3 -0
  197. package/src/runtime/application/index.ts +5 -0
  198. package/src/runtime/constants.ts +13 -0
  199. package/src/runtime/core/hooks.ts +5 -0
  200. package/src/runtime/core/plugin.ts +13 -0
  201. package/src/runtime/core/runtime.ts +109 -0
  202. package/src/runtime/enums.ts +24 -0
  203. package/src/runtime/index.ts +21 -0
  204. package/src/runtime/injectables.ts +61 -0
  205. package/src/runtime/jobs/job.ts +370 -0
  206. package/src/runtime/jobs/manager.ts +332 -0
  207. package/src/runtime/jobs/router.ts +835 -0
  208. package/src/runtime/jobs/runner.ts +320 -0
  209. package/src/runtime/jobs/step.ts +65 -0
  210. package/src/runtime/jobs/ui.ts +21 -0
  211. package/src/runtime/pubsub/manager.ts +211 -0
  212. package/src/runtime/pubsub/redis.ts +108 -0
  213. package/src/runtime/scheduler/index.ts +39 -0
  214. package/src/runtime/server/applications.ts +210 -0
  215. package/src/runtime/server/config.ts +158 -0
  216. package/src/runtime/server/jobs.ts +250 -0
  217. package/src/runtime/server/pool.ts +260 -0
  218. package/src/runtime/server/proxy.ts +118 -0
  219. package/src/runtime/server/server.ts +155 -0
  220. package/src/runtime/store/index.ts +30 -0
  221. package/src/runtime/types.ts +93 -0
  222. package/src/runtime/workers/application.ts +209 -0
  223. package/src/runtime/workers/base.ts +68 -0
  224. package/src/runtime/workers/cli.ts +0 -0
  225. package/src/runtime/workers/job.ts +153 -0
  226. package/src/typings.ts +30 -0
  227. package/src/vite/builder.ts +122 -0
  228. package/src/vite/config.ts +45 -0
  229. package/src/vite/plugins.ts +26 -0
  230. package/src/vite/runners/worker.ts +57 -0
  231. package/src/vite/server.ts +39 -0
  232. package/src/vite/servers/main.ts +34 -0
  233. package/src/vite/servers/worker.ts +143 -0
  234. package/dist/_exports/application.js +0 -1
  235. package/dist/_exports/common.js +0 -1
  236. package/dist/_exports/contract.js +0 -2
  237. package/dist/_exports/core.js +0 -1
  238. package/dist/_exports/gateway.js +0 -1
  239. package/dist/_exports/http-transport/bun.js +0 -1
  240. package/dist/_exports/http-transport/deno.js +0 -1
  241. package/dist/_exports/http-transport/node.js +0 -1
  242. package/dist/_exports/http-transport.js +0 -1
  243. package/dist/_exports/json-format.js +0 -1
  244. package/dist/_exports/protocol/client.js +0 -1
  245. package/dist/_exports/protocol/server.js +0 -1
  246. package/dist/_exports/protocol.js +0 -1
  247. package/dist/_exports/runtime/types.js +0 -1
  248. package/dist/_exports/runtime.js +0 -1
  249. package/dist/_exports/type.js +0 -2
  250. package/dist/_exports/ws-transport/bun.js +0 -1
  251. package/dist/_exports/ws-transport/deno.js +0 -1
  252. package/dist/_exports/ws-transport/node.js +0 -1
  253. package/dist/_exports/ws-transport.js +0 -1
  254. package/dist/command.js +0 -30
@@ -0,0 +1,332 @@
1
+ import assert from 'node:assert'
2
+ import { randomUUID } from 'node:crypto'
3
+
4
+ import type {
5
+ Job,
6
+ JobState,
7
+ JobType,
8
+ QueueEventsListener,
9
+ RedisClient,
10
+ } from 'bullmq'
11
+ import { pick } from '@nmtjs/core'
12
+ import {
13
+ Queue,
14
+ QueueEvents,
15
+ QueueEventsProducer,
16
+ UnrecoverableError,
17
+ } from 'bullmq'
18
+
19
+ import type { ServerStoreConfig } from '../server/config.ts'
20
+ import type { Store } from '../types.ts'
21
+ import type { AnyJob, JobBackoffOptions } from './job.ts'
22
+ import { createStoreClient } from '../store/index.ts'
23
+
24
+ /**
25
+ * Get the dedicated BullMQ queue name for a job
26
+ */
27
+ export function getJobQueueName(job: AnyJob): string {
28
+ return `job.${job.options.name}`
29
+ }
30
+
31
+ type QueueJobResultOptions<T extends AnyJob = AnyJob> = {
32
+ job: T
33
+ bullJob: Job<T['_']['input'], T['_']['output'], T['options']['name']>
34
+ events: QueueEvents
35
+ }
36
+
37
+ type QueueJobAddOptions = {
38
+ jobId?: string
39
+ priority?: number
40
+ forceMissingWorkers?: boolean
41
+ attempts?: number
42
+ backoff?: JobBackoffOptions
43
+ oneoff?: boolean
44
+ delay?: number
45
+ }
46
+
47
+ export class QueueJobResult<T extends AnyJob = AnyJob> {
48
+ #options: QueueJobResultOptions<T>
49
+
50
+ constructor(options: QueueJobResultOptions<T>) {
51
+ this.#options = options
52
+ }
53
+
54
+ get id() {
55
+ return this.#options.bullJob.id
56
+ }
57
+
58
+ get name() {
59
+ return this.#options.job.options.name
60
+ }
61
+
62
+ async waitResult() {
63
+ return await this.#options.bullJob.waitUntilFinished(this.#options.events)
64
+ }
65
+ }
66
+
67
+ export type JobItem<T extends AnyJob = AnyJob> = Pick<
68
+ Job<T['_']['input'], T['_']['output'], T['options']['name']>,
69
+ | 'queueName'
70
+ | 'priority'
71
+ | 'progress'
72
+ | 'name'
73
+ | 'data'
74
+ | 'returnvalue'
75
+ | 'attemptsMade'
76
+ | 'processedOn'
77
+ | 'finishedOn'
78
+ | 'failedReason'
79
+ | 'stacktrace'
80
+ > & { id: string; status: JobState | 'unknown' }
81
+
82
+ export interface JobManagerInstance {
83
+ list<T extends AnyJob>(
84
+ job: T,
85
+ options?: { page?: number; limit?: number; state?: JobState[] },
86
+ ): Promise<{
87
+ items: JobItem<T>[]
88
+ page: number
89
+ limit: number
90
+ pages: number
91
+ total: number
92
+ }>
93
+ get<T extends AnyJob>(job: T, id: string): Promise<JobItem<T> | null>
94
+ add<T extends AnyJob>(
95
+ job: T,
96
+ data: T['_']['input'],
97
+ options?: QueueJobAddOptions,
98
+ ): Promise<QueueJobResult<T>>
99
+ retry(
100
+ job: AnyJob,
101
+ id: string,
102
+ options?: { clearState?: boolean },
103
+ ): Promise<void>
104
+ remove(job: AnyJob, id: string): Promise<void>
105
+ cancel(job: AnyJob, id: string): Promise<void>
106
+ }
107
+
108
+ export type CustomJobsEvents = QueueEventsListener & {
109
+ [K in `cancel:${string}`]: (args: {}, id: string) => void
110
+ }
111
+
112
+ type JobQueueEntry = {
113
+ queue: Queue
114
+ events: QueueEvents
115
+ custom: QueueEventsProducer
116
+ }
117
+
118
+ export class JobManager {
119
+ protected store!: Store
120
+ /**
121
+ * Per-job dedicated queues. Each job has its own queue for granular control.
122
+ */
123
+ protected jobQueues = new Map<string, JobQueueEntry>()
124
+
125
+ constructor(
126
+ protected storeConfig: ServerStoreConfig,
127
+ protected jobs: AnyJob[],
128
+ ) {}
129
+
130
+ get publicInstance(): JobManagerInstance {
131
+ return {
132
+ // @ts-expect-error
133
+ list: this.list.bind(this),
134
+ add: this.add.bind(this),
135
+ get: this.get.bind(this),
136
+ retry: this.retry.bind(this),
137
+ remove: this.remove.bind(this),
138
+ cancel: this.cancel.bind(this),
139
+ }
140
+ }
141
+
142
+ async initialize() {
143
+ this.store = await createStoreClient(this.storeConfig)
144
+ await this.store.connect()
145
+
146
+ // Create a dedicated queue for each job
147
+ for (const job of this.jobs) {
148
+ const queueName = getJobQueueName(job)
149
+ const entry: JobQueueEntry = {
150
+ queue: new Queue(queueName, { connection: this.store as RedisClient }),
151
+ events: new QueueEvents(queueName, {
152
+ connection: this.store as RedisClient,
153
+ autorun: true,
154
+ }),
155
+ custom: new QueueEventsProducer(queueName, {
156
+ connection: this.store as RedisClient,
157
+ }),
158
+ }
159
+ this.jobQueues.set(job.options.name, entry)
160
+ }
161
+
162
+ // Wait for all queues to be ready
163
+ await Promise.all(
164
+ Array.from(this.jobQueues.values()).flatMap((entry) => [
165
+ entry.queue.waitUntilReady(),
166
+ entry.events.waitUntilReady(),
167
+ entry.custom.waitUntilReady(),
168
+ ]),
169
+ )
170
+ }
171
+
172
+ async terminate() {
173
+ await Promise.allSettled(
174
+ Array.from(this.jobQueues.values()).flatMap((entry) => [
175
+ entry.queue.close(),
176
+ entry.events.close(),
177
+ entry.custom.close(),
178
+ ]),
179
+ )
180
+ this.store.disconnect(false)
181
+ }
182
+
183
+ protected getJobQueue(job: AnyJob): JobQueueEntry {
184
+ const entry = this.jobQueues.get(job.options.name)
185
+ if (!entry) {
186
+ throw new Error(`Job queue for [${job.options.name}] not found`)
187
+ }
188
+ return entry
189
+ }
190
+
191
+ async list<T extends AnyJob>(
192
+ job: T,
193
+ {
194
+ limit = 20,
195
+ page = 1,
196
+ state = [],
197
+ }: { page?: number; limit?: number; state?: JobType[] },
198
+ ) {
199
+ const { queue } = this.getJobQueue(job)
200
+ const jobsCount = await queue.getJobCountByTypes(...state)
201
+ const totalPages = Math.ceil(jobsCount / limit)
202
+ if (page > totalPages) return []
203
+ const jobs = await queue.getJobs(
204
+ state,
205
+ (page - 1) * limit,
206
+ page * limit - 1,
207
+ )
208
+ const items = await Promise.all(jobs.map((job) => this._mapJob(job)))
209
+ return { items, page, limit, pages: totalPages, total: jobsCount }
210
+ }
211
+
212
+ async get<T extends AnyJob>(job: T, id: string) {
213
+ const { queue } = this.getJobQueue(job)
214
+ const bullJob = await queue.getJob(id)
215
+ if (!bullJob) return null
216
+ return await this._mapJob(bullJob)
217
+ }
218
+
219
+ async add<T extends AnyJob>(
220
+ job: T,
221
+ data: T['_']['input'],
222
+ {
223
+ forceMissingWorkers = false,
224
+ jobId = randomUUID(),
225
+ priority,
226
+ attempts = job.options.attempts,
227
+ backoff = job.options.backoff,
228
+ oneoff = job.options.oneoff ?? true,
229
+ delay,
230
+ }: QueueJobAddOptions = {},
231
+ ) {
232
+ const { queue, events } = this.getJobQueue(job)
233
+
234
+ if (!forceMissingWorkers) {
235
+ if ((await queue.getWorkersCount()) === 0) {
236
+ throw new Error(
237
+ `No workers available for [${getJobQueueName(job)}] queue`,
238
+ )
239
+ }
240
+ }
241
+ const bullJob = await queue.add(job.options.name as any, data as any, {
242
+ attempts,
243
+ backoff,
244
+ jobId,
245
+ priority,
246
+ delay,
247
+ removeOnComplete: oneoff,
248
+ removeOnFail: oneoff,
249
+ })
250
+
251
+ return new QueueJobResult({ job, bullJob, events })
252
+ }
253
+
254
+ async retry(job: AnyJob, id: string, options?: { clearState?: boolean }) {
255
+ const { queue } = this.getJobQueue(job)
256
+ const bullJob = await queue.getJob(id)
257
+ if (!bullJob) throw new Error(`Job with id [${id}] not found`)
258
+
259
+ const state = await bullJob.getState()
260
+ // For completed jobs, clear state by default so it reruns from scratch
261
+ // For failed jobs, keep state by default so it resumes from checkpoint
262
+ const shouldClearState = options?.clearState ?? state === 'completed'
263
+
264
+ if (shouldClearState) {
265
+ await bullJob.updateProgress({})
266
+ }
267
+
268
+ await bullJob.retry()
269
+ }
270
+
271
+ async remove(job: AnyJob, id: string) {
272
+ const { queue } = this.getJobQueue(job)
273
+ const bullJob = await queue.getJob(id)
274
+ if (!bullJob) throw new Error(`Job with id [${id}] not found`)
275
+ await bullJob.remove()
276
+ }
277
+
278
+ async cancel(job: AnyJob, id: string) {
279
+ const { custom, queue } = this.getJobQueue(job)
280
+ const bullJob = await queue.getJob(id)
281
+ if (!bullJob) throw new Error(`Job with id [${id}] not found`)
282
+ if (bullJob.finishedOn) return
283
+ if ((await bullJob.getState()) === 'waiting') {
284
+ return await bullJob.remove()
285
+ }
286
+ if ((await bullJob.getState()) === 'active') {
287
+ await custom.publishEvent({ eventName: `cancel:${id}` })
288
+ }
289
+ }
290
+
291
+ cancellationSignal(job: AnyJob, id: string) {
292
+ const { events } = this.getJobQueue(job)
293
+ const controller = new AbortController()
294
+ const handler = () => {
295
+ controller.abort(new UnrecoverableError('Job cancelled'))
296
+ }
297
+ events.on<CustomJobsEvents>(`cancel:${id}`, handler)
298
+ const signal = controller.signal
299
+ return Object.assign(signal, {
300
+ [Symbol.dispose]: () => {
301
+ events.off<CustomJobsEvents>(`cancel:${id}`, handler)
302
+ },
303
+ })
304
+ }
305
+
306
+ getQueue(job: AnyJob) {
307
+ return this.getJobQueue(job)
308
+ }
309
+
310
+ protected async _mapJob(bullJob: Job): Promise<JobItem> {
311
+ const status = await bullJob.getState()
312
+ const id = bullJob.id
313
+ assert(typeof id === 'string', 'Expected job id to be a string')
314
+ return {
315
+ ...pick(bullJob, {
316
+ queueName: true,
317
+ priority: true,
318
+ progress: true,
319
+ name: true,
320
+ data: true,
321
+ returnvalue: true,
322
+ attemptsMade: true,
323
+ processedOn: true,
324
+ finishedOn: true,
325
+ failedReason: true,
326
+ stacktrace: true,
327
+ }),
328
+ id,
329
+ status,
330
+ }
331
+ }
332
+ }