@nexusts/queue 0.9.7 → 0.9.8

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/dist/index.d.ts CHANGED
@@ -26,7 +26,7 @@
26
26
  * import { QueueService } from '@nexusts/queue';
27
27
  *
28
28
  * class SignupController {
29
- * constructor(@Inject(QueueService.TOKEN) private queue: QueueService) {}
29
+ * @Inject(QueueService.TOKEN) declare private queue: QueueService;
30
30
  *
31
31
  * @Post('/')
32
32
  * async signup(@Body() body: { email: string }) {
@@ -37,7 +37,7 @@
37
37
  *
38
38
  * // any service — register a worker
39
39
  * class EmailWorker {
40
- * constructor(@Inject(QueueService.TOKEN) private queue: QueueService) {}
40
+ * @Inject(QueueService.TOKEN) declare private queue: QueueService;
41
41
  * @OnQueueReady()
42
42
  * async register() {
43
43
  * await this.queue.process('send-welcome-email', this.handle);
package/dist/index.js.map CHANGED
@@ -6,7 +6,7 @@
6
6
  "/**\n * BullMQ backend — Redis-backed queue for Bun / Node.\n *\n * Wraps `bullmq.Queue` (producer) and `bullmq.Worker` (consumer) with\n * the common `QueueBackend` interface. We use the `Job` wrapper class\n * (vs the lower-level `QueueBase`) so we can read job IDs back as\n * strings without leaking BullMQ types to user code.\n *\n * Usage:\n * const backend = new BullMQBackend({\n * connection: 'redis://localhost:6379',\n * prefix: '@nexusts',\n * });\n * await backend.process('send-email', async (data) => {\n * // ...\n * });\n * await backend.add('send-email', { to: 'a@b.c' });\n */\n\nimport {\n\tQueue,\n\tWorker,\n\ttype ConnectionOptions,\n\ttype JobsOptions,\n} from \"bullmq\";\nimport IORedis from \"ioredis\";\nimport type {\n\tQueueBackend,\n\tJobHandler,\n\tWorkerHandle,\n\tWorkerOptions,\n\tAddedJob,\n\tAddOptions,\n\tQueueEvent,\n\tQueueEventListener,\n\tJobContext,\n} from \"../types.js\";\n\nexport interface BullMQBackendOptions {\n\tconnection: string | ConnectionOptions;\n\tprefix?: string;\n\tdefaultJobOptions?: AddOptions;\n}\n\nclass BullMQWorkerHandle implements WorkerHandle {\n\t#worker: Worker;\n\t#name: string;\n\tconstructor(name: string, worker: Worker) {\n\t\tthis.#name = name;\n\t\tthis.#worker = worker;\n\t}\n\tget name() {\n\t\treturn this.#name;\n\t}\n\tasync close() {\n\t\tawait this.#worker.close();\n\t}\n\tasync pause() {\n\t\tawait this.#worker.pause();\n\t}\n\tasync resume() {\n\t\tawait this.#worker.resume();\n\t}\n\tisRunning() {\n\t\treturn !this.#worker.closing;\n\t}\n}\n\nexport class BullMQBackend implements QueueBackend {\n\treadonly name = \"bullmq\" as const;\n\t#queue: Queue;\n\t#connection: ConnectionOptions;\n\t#prefix: string;\n\t#defaultJobOptions: AddOptions;\n\t#workers = new Map<string, Worker>();\n\t#listeners = new Set<QueueEventListener>();\n\t#closed = false;\n\n\tconstructor(options: BullMQBackendOptions) {\n\t\tthis.#connection =\n\t\t\ttypeof options.connection === \"string\"\n\t\t\t\t? (new IORedis(options.connection, {\n\t\t\t\t\t\tmaxRetriesPerRequest: null,\n\t\t\t\t\t}) as unknown as ConnectionOptions)\n\t\t\t\t: options.connection;\n\t\tthis.#prefix = options.prefix ?? \"nexusts\";\n\t\tthis.#defaultJobOptions = options.defaultJobOptions ?? {};\n\n\t\tthis.#queue = new Queue(\"nexus-queue\", {\n\t\t\tconnection: this.#connection,\n\t\t\tprefix: this.#prefix,\n\t\t\tdefaultJobOptions: this.#toBullJobOptions(this.#defaultJobOptions),\n\t\t});\n\t}\n\n\t// ===========================================================================\n\t// Producer\n\t// ===========================================================================\n\n\tasync add(\n\t\tname: string,\n\t\tdata: unknown,\n\t\toptions: AddOptions = {},\n\t): Promise<AddedJob> {\n\t\tconst merged = { ...this.#defaultJobOptions, ...options };\n\t\tconst job = await this.#queue.add(\n\t\t\tname,\n\t\t\tdata,\n\t\t\tthis.#toBullJobOptions(merged),\n\t\t);\n\t\tthis.#emit({ kind: \"job:added\", jobId: String(job.id ?? \"\"), name });\n\t\treturn { jobId: String(job.id ?? \"\"), name, handle: job };\n\t}\n\n\tasync addBatch(\n\t\tjobs: Array<{ name: string; data: unknown; options?: AddOptions }>,\n\t): Promise<AddedJob[]> {\n\t\tconst bullJobs = jobs.map((j) => ({\n\t\t\tname: j.name,\n\t\t\tdata: j.data,\n\t\t\topts: this.#toBullJobOptions({\n\t\t\t\t...this.#defaultJobOptions,\n\t\t\t\t...j.options,\n\t\t\t}),\n\t\t}));\n\t\tconst added = await this.#queue.addBulk(bullJobs);\n\t\tfor (const job of added) {\n\t\t\tthis.#emit({\n\t\t\t\tkind: \"job:added\",\n\t\t\t\tjobId: String(job.id ?? \"\"),\n\t\t\t\tname: job.name,\n\t\t\t});\n\t\t}\n\t\treturn added.map((job) => ({\n\t\t\tjobId: String(job.id ?? \"\"),\n\t\t\tname: job.name,\n\t\t\thandle: job,\n\t\t}));\n\t}\n\n\t// ===========================================================================\n\t// Worker\n\t// ===========================================================================\n\n\tasync process<T = unknown>(\n\t\tname: string,\n\t\thandler: JobHandler<T>,\n\t\toptions: WorkerOptions = {},\n\t): Promise<WorkerHandle> {\n\t\tconst worker = new Worker(\n\t\t\t\"nexus-queue\",\n\t\t\tasync (job) => {\n\t\t\t\tconst ctx: JobContext = {\n\t\t\t\t\tjobId: String(job.id ?? \"\"),\n\t\t\t\t\tattempts: job.attemptsMade + 1,\n\t\t\t\t\tjob: { name: job.name, data: job.data },\n\t\t\t\t\tprefix: `[queue:${job.name}]`,\n\t\t\t\t};\n\t\t\t\tthis.#emit({\n\t\t\t\t\tkind: \"job:active\",\n\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\tname: job.name,\n\t\t\t\t\tattempts: ctx.attempts,\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await handler(job.data as T, ctx);\n\t\t\t\t\tif (result && typeof result === \"object\" && \"status\" in result) {\n\t\t\t\t\t\tconst r = result as { status: string; returnvalue?: unknown };\n\t\t\t\t\t\tif (r.status === \"completed\") {\n\t\t\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\t\t\tkind: \"job:completed\",\n\t\t\t\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\t\t\t\tname: job.name,\n\t\t\t\t\t\t\t\treturnvalue: r.returnvalue,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\treturn r.returnvalue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (r.status === \"retry\") {\n\t\t\t\t\t\t\tconst r2 = result as { delaySeconds?: number; reason?: string };\n\t\t\t\t\t\t\tthrow new RetryError(\n\t\t\t\t\t\t\t\tr2.reason ?? \"retry requested\",\n\t\t\t\t\t\t\t\tr2.delaySeconds,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\tkind: \"job:completed\",\n\t\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\t\tname: job.name,\n\t\t\t\t\t\treturnvalue: result,\n\t\t\t\t\t});\n\t\t\t\t\treturn result;\n\t\t\t\t} catch (err) {\n\t\t\t\t\tif (err instanceof RetryError) {\n\t\t\t\t\t\t// Force a retry with optional delay.\n\t\t\t\t\t\tawait job.moveToDelayed(\n\t\t\t\t\t\t\tDate.now() + (err.delaySeconds ?? 0) * 1000,\n\t\t\t\t\t\t\tjob.token!,\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\t\t\tconst willRetry = (job.opts.attempts ?? 1) > job.attemptsMade;\n\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\tkind: \"job:failed\",\n\t\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\t\tname: job.name,\n\t\t\t\t\t\terror,\n\t\t\t\t\t\twillRetry,\n\t\t\t\t\t});\n\t\t\t\t\tthrow err; // let BullMQ handle the retry\n\t\t\t\t}\n\t\t\t},\n\t\t\t{\n\t\t\t\tconnection: this.#connection,\n\t\t\t\tprefix: this.#prefix,\n\t\t\t\tconcurrency: options.concurrency ?? 1,\n\t\t\t\tlockDuration: options.lockDurationMs ?? 30000,\n\t\t\t\tlimiter: options.limiter\n\t\t\t\t\t? { max: options.limiter.max, duration: options.limiter.durationMs }\n\t\t\t\t\t: undefined,\n\t\t\t},\n\t\t);\n\n\t\tthis.#workers.set(name, worker);\n\t\tthis.#emit({\n\t\t\tkind: \"worker:started\",\n\t\t\tname,\n\t\t\tconcurrency: options.concurrency ?? 1,\n\t\t});\n\t\treturn new BullMQWorkerHandle(name, worker);\n\t}\n\n\t// ===========================================================================\n\t// Lifecycle\n\t// ===========================================================================\n\n\tasync drain(): Promise<void> {\n\t\t// Wait for active jobs on every worker to reach zero.\n\t\tconst workers = [...this.#workers.values()];\n\t\tawait Promise.all(workers.map((w) => w.waitUntilReady()));\n\t\twhile (\n\t\t\tworkers.some(\n\t\t\t\t(w) => (w as unknown as { _job?: unknown })._job !== undefined,\n\t\t\t)\n\t\t) {\n\t\t\tawait new Promise((r) => setTimeout(r, 50));\n\t\t}\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tif (this.#closed) return;\n\t\tthis.#closed = true;\n\t\tfor (const [name, worker] of this.#workers) {\n\t\t\tawait worker.close();\n\t\t\tthis.#emit({ kind: \"worker:stopped\", name });\n\t\t}\n\t\tawait this.#queue.close();\n\t\t// If we own the connection, close it.\n\t\ttry {\n\t\t\tconst conn = this.#connection as { quit?: () => Promise<unknown> };\n\t\t\tif (typeof conn?.quit === \"function\") await conn.quit();\n\t\t} catch {\n\t\t\t// ignore\n\t\t}\n\t}\n\n\t// ===========================================================================\n\t// Events\n\t// ===========================================================================\n\n\ton(listener: QueueEventListener): () => void {\n\t\tthis.#listeners.add(listener);\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\t// ===========================================================================\n\t// Internal\n\t// ===========================================================================\n\n\t#toBullJobOptions(opts: AddOptions): JobsOptions {\n\t\tconst out: JobsOptions = {};\n\t\tif (opts.delaySeconds !== undefined) out.delay = opts.delaySeconds * 1000;\n\t\tif (opts.attempts !== undefined) out.attempts = opts.attempts;\n\t\tif (opts.backoff)\n\t\t\tout.backoff = { type: opts.backoff.type, delay: opts.backoff.delayMs };\n\t\tif (opts.priority !== undefined) out.priority = opts.priority;\n\t\tif (opts.jobId !== undefined) out.jobId = opts.jobId;\n\t\tif (opts.removeOnComplete !== undefined)\n\t\t\tout.removeOnComplete = opts.removeOnComplete;\n\t\tif (opts.removeOnFail !== undefined) out.removeOnFail = opts.removeOnFail;\n\t\treturn out;\n\t}\n\n\t#emit(event: QueueEvent) {\n\t\tfor (const l of this.#listeners) {\n\t\t\tvoid Promise.resolve(l(event));\n\t\t}\n\t}\n}\n\n/** Internal marker error to ask BullMQ to retry with optional delay. */\nclass RetryError extends Error {\n\treadonly __retry = true;\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly delaySeconds?: number,\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"RetryError\";\n\t}\n}\n",
7
7
  "/**\n * Cloudflare Queues backend — Workers-native, edge-friendly.\n *\n * Cloudflare Queues has a different shape from BullMQ:\n * - The producer calls `queue.send(body)` / `queue.sendBatch(...)`.\n * - The consumer is a Worker's `queue()` handler that receives a\n * `MessageBatch`.\n *\n * We adapt the two halves to our common `QueueBackend` interface:\n * - `add(name, data)` calls `queue.send({ name, data })` so the\n * consumer knows which handler to route to.\n * - `process(name, handler)` registers the handler in a local\n * `Map`. When the consumer's `queue()` callback fires, we\n * dispatch each message to the matching handler.\n *\n * Because Workers can't start a long-running process, `process()` is\n * a no-op on the producer side. The actual `queue()` handler must be\n * registered separately by the user (or by `QueueModule`'s\n * `workerHandler(env, ctx, batch)` export).\n */\n\nimport type {\n\tQueueBackend,\n\tJobHandler,\n\tWorkerHandle,\n\tWorkerOptions,\n\tAddedJob,\n\tAddOptions,\n\tQueueEvent,\n\tQueueEventListener,\n\tJobContext,\n} from \"../types.js\";\n\n// ---------------------------------------------------------------------------\n// Cloudflare type stubs (mirrored from @cloudflare/workers-types).\n// We don't import the package to keep the queue module light.\n// ---------------------------------------------------------------------------\n\ninterface CFQueue<Body = unknown> {\n\tsend(\n\t\tbody: Body,\n\t\toptions?: { contentType?: string; delaySeconds?: number },\n\t): Promise<unknown>;\n\tsendBatch(\n\t\tmessages: Array<{\n\t\t\tbody: unknown;\n\t\t\tcontentType?: string;\n\t\t\tdelaySeconds?: number;\n\t\t}>,\n\t\toptions?: { delaySeconds?: number },\n\t): Promise<unknown>;\n}\n\ninterface CFMessage<Body = unknown> {\n\treadonly id: string;\n\treadonly timestamp: Date;\n\treadonly body: Body;\n\treadonly attempts: number;\n\tack(): void;\n\tretry(options?: { delaySeconds?: number }): void;\n}\n\ninterface CFMessageBatch<Body = unknown> {\n\treadonly queue: string;\n\treadonly messages: readonly CFMessage<Body>[];\n\tackAll(): void;\n\tretryAll(options?: { delaySeconds?: number }): void;\n}\n\n// ---------------------------------------------------------------------------\n// Worker handle\n// ---------------------------------------------------------------------------\n\nclass CloudflareWorkerHandle implements WorkerHandle {\n\t#name: string;\n\t#running = true;\n\tconstructor(name: string) {\n\t\tthis.#name = name;\n\t}\n\tget name() {\n\t\treturn this.#name;\n\t}\n\tasync close() {\n\t\tthis.#running = false;\n\t}\n\tasync pause() {\n\t\tthis.#running = false;\n\t}\n\tasync resume() {\n\t\tthis.#running = true;\n\t}\n\tisRunning() {\n\t\treturn this.#running;\n\t}\n}\n\nexport interface CloudflareBackendOptions {\n\t/** Resolver that pulls the Queue binding from the Worker's env. */\n\tresolveBinding: (env: Record<string, unknown>) => CFQueue;\n\t/** Queue name (for diagnostics + MessageBatch.queue matching). */\n\tname?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Backend\n// ---------------------------------------------------------------------------\n\nexport class CloudflareQueueBackend implements QueueBackend {\n\treadonly name = \"cloudflare\" as const;\n\t#queue: CFQueue | null = null;\n\t#resolveBinding: (env: Record<string, unknown>) => CFQueue;\n\t#handlers = new Map<string, JobHandler>();\n\t#workerOptions = new Map<string, WorkerOptions>();\n\t#listeners = new Set<QueueEventListener>();\n\t#queueName: string;\n\n\tconstructor(options: CloudflareBackendOptions) {\n\t\tthis.#resolveBinding = options.resolveBinding;\n\t\tthis.#queueName = options.name ?? \"queue\";\n\t}\n\n\t/** Bind to the Worker's `env` once it's available. */\n\tbind(env: Record<string, unknown>): void {\n\t\tthis.#queue = this.#resolveBinding(env);\n\t}\n\n\t// ===========================================================================\n\t// Producer\n\t// ===========================================================================\n\n\tasync add(\n\t\tname: string,\n\t\tdata: unknown,\n\t\toptions: AddOptions = {},\n\t): Promise<AddedJob> {\n\t\tif (!this.#queue)\n\t\t\tthrow new Error(\"[queue/cloudflare] bind() must be called before add()\");\n\t\tconst id = `cf-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n\t\tawait this.#queue.send(\n\t\t\t{ name, data, jobId: id, options },\n\t\t\t{ delaySeconds: options.delaySeconds },\n\t\t);\n\t\tthis.#emit({ kind: \"job:added\", jobId: id, name });\n\t\treturn { jobId: id, name };\n\t}\n\n\tasync addBatch(\n\t\tjobs: Array<{ name: string; data: unknown; options?: AddOptions }>,\n\t): Promise<AddedJob[]> {\n\t\tif (!this.#queue)\n\t\t\tthrow new Error(\n\t\t\t\t\"[queue/cloudflare] bind() must be called before addBatch()\",\n\t\t\t);\n\t\tconst ids = jobs.map(\n\t\t\t() => `cf-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n\t\t);\n\t\tawait this.#queue.sendBatch(\n\t\t\tjobs.map((j, i) => ({\n\t\t\t\tbody: { name: j.name, data: j.data, jobId: ids[i], options: j.options },\n\t\t\t\tdelaySeconds: j.options?.delaySeconds,\n\t\t\t})),\n\t\t);\n\t\tfor (let i = 0; i < jobs.length; i++) {\n\t\t\tconst j = jobs[i]!;\n\t\t\tthis.#emit({ kind: \"job:added\", jobId: ids[i]!, name: j.name });\n\t\t}\n\t\treturn jobs.map((j, i) => ({ jobId: ids[i]!, name: j.name }));\n\t}\n\n\t// ===========================================================================\n\t// Worker registration\n\t// ===========================================================================\n\n\tasync process<T = unknown>(\n\t\tname: string,\n\t\thandler: JobHandler<T>,\n\t\toptions: WorkerOptions = {},\n\t): Promise<WorkerHandle> {\n\t\tthis.#handlers.set(name, handler as JobHandler);\n\t\tthis.#workerOptions.set(name, options);\n\t\tthis.#emit({\n\t\t\tkind: \"worker:started\",\n\t\t\tname,\n\t\t\tconcurrency: options.concurrency ?? 1,\n\t\t});\n\t\treturn new CloudflareWorkerHandle(name);\n\t}\n\n\t// ===========================================================================\n\t// Cloudflare consumer entry point\n\t// ===========================================================================\n\n\t/**\n\t * Build the Worker's `queue()` handler. Mount it as\n\t * `export default { queue: backend.consumerHandler() }` in the\n\t * Worker entry file.\n\t */\n\tconsumerHandler(): (batch: CFMessageBatch<unknown>) => Promise<void> {\n\t\treturn async (batch: CFMessageBatch<unknown>) => {\n\t\t\tfor (const message of batch.messages) {\n\t\t\t\tconst body = (message.body ?? {}) as {\n\t\t\t\t\tname?: string;\n\t\t\t\t\tdata?: unknown;\n\t\t\t\t\tjobId?: string;\n\t\t\t\t\toptions?: AddOptions;\n\t\t\t\t};\n\t\t\t\tconst jobName = body.name ?? \"\";\n\t\t\t\tconst handler = this.#handlers.get(jobName);\n\t\t\t\tif (!handler) {\n\t\t\t\t\t// No handler registered — fail so the message is retried.\n\t\t\t\t\tmessage.retry();\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tconst ctx: JobContext = {\n\t\t\t\t\tjobId: body.jobId ?? message.id,\n\t\t\t\t\tattempts: message.attempts,\n\t\t\t\t\tjob: { name: jobName, data: body.data },\n\t\t\t\t\tprefix: `[queue:${jobName}]`,\n\t\t\t\t};\n\t\t\t\tthis.#emit({\n\t\t\t\t\tkind: \"job:active\",\n\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\tname: jobName,\n\t\t\t\t\tattempts: ctx.attempts,\n\t\t\t\t});\n\t\t\t\ttry {\n\t\t\t\t\tconst result = await handler(body.data, ctx);\n\t\t\t\t\tif (result && typeof result === \"object\" && \"status\" in result) {\n\t\t\t\t\t\tconst r = result as {\n\t\t\t\t\t\t\tstatus: string;\n\t\t\t\t\t\t\treturnvalue?: unknown;\n\t\t\t\t\t\t\terror?: Error;\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (r.status === \"failed\") {\n\t\t\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\t\t\tkind: \"job:failed\",\n\t\t\t\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\t\t\t\tname: jobName,\n\t\t\t\t\t\t\t\terror: r.error ?? new Error(\"failed\"),\n\t\t\t\t\t\t\t\twillRetry: true,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tmessage.retry();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (r.status === \"retry\") {\n\t\t\t\t\t\t\tconst r2 = result as { delaySeconds?: number };\n\t\t\t\t\t\t\tmessage.retry({ delaySeconds: r2.delaySeconds });\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\t\tkind: \"job:completed\",\n\t\t\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\t\t\tname: jobName,\n\t\t\t\t\t\t\treturnvalue: r.returnvalue,\n\t\t\t\t\t\t});\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\t\tkind: \"job:completed\",\n\t\t\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\t\t\tname: jobName,\n\t\t\t\t\t\t\treturnvalue: result,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t} catch (err) {\n\t\t\t\t\tconst error = err instanceof Error ? err : new Error(String(err));\n\t\t\t\t\tconst willRetry = (body.options?.attempts ?? 1) > message.attempts;\n\t\t\t\t\tthis.#emit({\n\t\t\t\t\t\tkind: \"job:failed\",\n\t\t\t\t\t\tjobId: ctx.jobId,\n\t\t\t\t\t\tname: jobName,\n\t\t\t\t\t\terror,\n\t\t\t\t\t\twillRetry,\n\t\t\t\t\t});\n\t\t\t\t\tif (willRetry) message.retry();\n\t\t\t\t\telse message.ack();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t// ===========================================================================\n\t// Lifecycle\n\t// ===========================================================================\n\n\tasync drain(): Promise<void> {\n\t\t// Cloudflare handles draining at the platform level (between\n\t\t// requests, the isolate is torn down). Nothing to do here.\n\t}\n\n\tasync stop(): Promise<void> {\n\t\tfor (const name of this.#handlers.keys()) {\n\t\t\tthis.#emit({ kind: \"worker:stopped\", name });\n\t\t}\n\t\tthis.#handlers.clear();\n\t\tthis.#workerOptions.clear();\n\t}\n\n\t// ===========================================================================\n\t// Events\n\t// ===========================================================================\n\n\ton(listener: QueueEventListener): () => void {\n\t\tthis.#listeners.add(listener);\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\t// ===========================================================================\n\t// Internal\n\t// ===========================================================================\n\n\t#emit(event: QueueEvent) {\n\t\tfor (const l of this.#listeners) {\n\t\t\tvoid Promise.resolve(l(event));\n\t\t}\n\t}\n\n\tget queueName() {\n\t\treturn this.#queueName;\n\t}\n}\n",
8
8
  "/**\n * `QueueService` — DI-friendly facade over a `QueueBackend`.\n *\n * Controllers and other services inject this via `@Inject(QueueService.TOKEN)`\n * (or just `@Inject(QueueService)`) and call high-level methods without\n * caring whether the underlying backend is BullMQ, Cloudflare Queues,\n * or the in-memory test backend.\n *\n * Two layers:\n * - `QueueService.add(name, data, options?)` → schedule a job\n * - `QueueService.process(name, handler)` → register a worker\n *\n * The lifecycle is owned by `QueueService.start()` (called by\n * `QueueModule.forRoot` when the application boots) and\n * `QueueService.stop()` (called on shutdown).\n */\n\nimport { Inject, Injectable } from '@nexusts/core';\nimport type {\n\tQueueBackend,\n\tQueueConfig,\n\tJobHandler,\n\tWorkerHandle,\n\tAddedJob,\n\tAddOptions,\n\tQueueEvent,\n\tQueueEventListener,\n} from './types.js';\nimport {\n\tMemoryQueueBackend,\n\tBullMQBackend,\n\tCloudflareQueueBackend,\n} from './backends/index.js';\n\n@Injectable()\nexport class QueueService {\n\t/** DI token — use with `@Inject(QueueService.TOKEN)`. */\n\tstatic readonly TOKEN = Symbol.for('nexus:QueueService');\n\n\t/** Queue config — injected by DI container. */\n\t@Inject('QUEUE_CONFIG') declare private readonly config: QueueConfig;\n\n\t#_backend: QueueBackend | null = null;\n\tget backend(): QueueBackend {\n\t\tif (!this.#_backend) {\n\t\t\tthis.#_backend = this.#createBackend(this.config ?? { backend: 'memory' });\n\t\t}\n\t\treturn this.#_backend;\n\t}\n\t#workers = new Map<string, WorkerHandle>();\n\t#listeners = new Set<QueueEventListener>();\n\t#started = false;\n\n\tconstructor() {\n\t\t// DI sets @Inject fields before first use.\n\t}\n\n\t// ===========================================================================\n\t// Producer API\n\t// ===========================================================================\n\n\t/**\n\t * Enqueue a job. Returns immediately (the backend may still be\n\t * persisting). On Cloudflare, returns once the message is on disk.\n\t */\n\tasync add<T = unknown>(\n\t\tname: string,\n\t\tdata: T,\n\t\toptions: AddOptions = {},\n\t): Promise<AddedJob> {\n\t\tconst cfg = this.config ?? { backend: 'memory' as const };\n\t\tconst merged = { ...cfg.defaults, ...options };\n\t\treturn this.backend.add(name, data, merged);\n\t}\n\n\t/** Enqueue many jobs at once (atomic on Cloudflare; batched on BullMQ). */\n\tasync addBatch<T = unknown>(\n\t\tjobs: Array<{ name: string; data: T; options?: AddOptions }>,\n\t): Promise<AddedJob[]> {\n\t\treturn this.backend.addBatch(jobs);\n\t}\n\n\t// ===========================================================================\n\t// Worker API\n\t// ===========================================================================\n\n\t/**\n\t * Register a worker for the given job name. Call this from\n\t * `Application.bootstrap` (or a feature module's `onInit`) — the\n\t * module wires it via DI so user code doesn't have to call this\n\t * manually.\n\t */\n\tasync process<T = unknown>(\n\t\tname: string,\n\t\thandler: JobHandler<T>,\n\t): Promise<WorkerHandle> {\n\t\tconst handle = await this.backend.process(name, handler);\n\t\tthis.#workers.set(name, handle);\n\t\treturn handle;\n\t}\n\n\t// ===========================================================================\n\t// Events\n\t// ===========================================================================\n\n\ton(listener: QueueEventListener): () => void {\n\t\tthis.#listeners.add(listener);\n\t\treturn () => this.#listeners.delete(listener);\n\t}\n\n\t// ===========================================================================\n\t// Lifecycle\n\t// ===========================================================================\n\n\t/** Called by `QueueModule.forRoot` when the app boots. */\n\tasync start(): Promise<void> {\n\t\tif (this.#started) return;\n\t\tthis.#started = true;\n\t\t// Bridge backend events through our listener set.\n\t\tthis.backend.on((event) => this.#broadcast(event));\n\t}\n\n\t/** Drain in-flight jobs and close all workers. */\n\tasync stop(): Promise<void> {\n\t\tif (!this.#started) return;\n\t\tthis.#started = false;\n\t\tawait this.backend.drain();\n\t\tfor (const handle of this.#workers.values()) {\n\t\t\tawait handle.close();\n\t\t}\n\t\tawait this.backend.stop();\n\t\tthis.#workers.clear();\n\t}\n\n\t// ===========================================================================\n\t// Cloudflare binding helper\n\t// ===========================================================================\n\n\t/**\n\t * For Cloudflare backends, call this once with the Worker's env so\n\t * the producer can find the Queue binding.\n\t *\n\t * const service = app.container.resolve(QueueService.TOKEN);\n\t * if (service.backend.name === 'cloudflare') {\n\t * (service.backend as CloudflareQueueBackend).bind(env);\n\t * }\n\t */\n\tgetCloudflareBackend(): CloudflareQueueBackend | null {\n\t\treturn this.backend instanceof CloudflareQueueBackend ? this.backend : null;\n\t}\n\n\t// ===========================================================================\n\t// Internal\n\t// ===========================================================================\n\n\t#createBackend(config: QueueConfig): QueueBackend {\n\t\tswitch (config.backend) {\n\t\t\tcase 'memory':\n\t\t\t\treturn new MemoryQueueBackend();\n\t\t\tcase 'bullmq': {\n\t\t\t\tif (!config.bullmq) {\n\t\t\t\t\tthrow new Error('[queue] backend=bullmq requires `bullmq.connection` in config.');\n\t\t\t\t}\n\t\t\t\treturn new BullMQBackend({\n\t\t\t\t\tconnection: config.bullmq.connection,\n\t\t\t\t\tprefix: config.bullmq.prefix,\n\t\t\t\t\tdefaultJobOptions: config.bullmq.defaultJobOptions,\n\t\t\t\t});\n\t\t\t}\n\t\t\tcase 'cloudflare': {\n\t\t\t\tif (!config.cloudflare) {\n\t\t\t\t\tthrow new Error('[queue] backend=cloudflare requires `cloudflare.resolveBinding` in config.');\n\t\t\t\t}\n\t\t\t\treturn new CloudflareQueueBackend({\n\t\t\t\t\tresolveBinding: config.cloudflare.resolveBinding as never,\n\t\t\t\t\tname: config.cloudflare.name,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\n\t#broadcast(event: QueueEvent) {\n\t\tfor (const l of this.#listeners) {\n\t\t\tvoid Promise.resolve(l(event));\n\t\t}\n\t}\n}",
9
- "/**\n * `QueueModule` — drop-in module for adding background jobs to a\n * NexusTS app.\n *\n * Usage:\n * // src/app/app.module.ts\n * @Module({\n * imports: [\n * QueueModule.forRoot({\n * backend: 'bullmq',\n * bullmq: { connection: 'redis://localhost:6379' },\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * // any controller or service\n * constructor(@Inject(QueueService.TOKEN) private queue: QueueService) {}\n * await this.queue.add('send-email', { to: 'a@b.c' });\n *\n * // any service — register a worker\n * class EmailWorker {\n * constructor(@Inject(QueueService.TOKEN) private queue: QueueService) {}\n * async onInit() {\n * await this.queue.process('send-email', async (data) => {\n * // ... send the email\n * return { status: 'completed' };\n * });\n * }\n * }\n */\n\nimport { Module } from \"@nexusts/core\";\nimport { QueueService } from \"./queue.service.js\";\nimport type { QueueConfig } from \"./types.js\";\n\n@Module({\n\tproviders: [\n\t\tQueueService,\n\t\t{ provide: QueueService.TOKEN, useExisting: QueueService },\n\t],\n\texports: [QueueService, QueueService.TOKEN],\n})\nexport class QueueModule {\n\t/**\n\t * Build a configured `QueueModule` class with the given queue config.\n\t *\n\t * The returned class can be `imports`-ed by any other module and\n\t * will provide the `QueueService` (and a `QUEUE_CONFIG` value\n\t * provider) to its container.\n\t */\n\tstatic forRoot(config: QueueConfig) {\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tQueueService,\n\t\t\t\t{ provide: QueueService.TOKEN, useExisting: QueueService },\n\t\t\t\t{ provide: \"QUEUE_CONFIG\", useValue: config },\n\t\t\t],\n\t\t\texports: [QueueService, QueueService.TOKEN],\n\t\t})\n\t\tclass ConfiguredQueueModule {}\n\n\t\tObject.defineProperty(ConfiguredQueueModule, \"name\", {\n\t\t\tvalue: \"ConfiguredQueueModule\",\n\t\t});\n\n\t\treturn ConfiguredQueueModule;\n\t}\n}\n",
9
+ "/**\n * `QueueModule` — drop-in module for adding background jobs to a\n * NexusTS app.\n *\n * Usage:\n * // src/app/app.module.ts\n * @Module({\n * imports: [\n * QueueModule.forRoot({\n * backend: 'bullmq',\n * bullmq: { connection: 'redis://localhost:6379' },\n * }),\n * ],\n * })\n * export class AppModule {}\n *\n * // any controller or service\n * @Inject(QueueService.TOKEN) declare private queue: QueueService;\n * await this.queue.add('send-email', { to: 'a@b.c' });\n *\n * // any service — register a worker\n * class EmailWorker {\n * @Inject(QueueService.TOKEN) declare private queue: QueueService;\n * async onInit() {\n * await this.queue.process('send-email', async (data) => {\n * // ... send the email\n * return { status: 'completed' };\n * });\n * }\n * }\n */\n\nimport { Module } from \"@nexusts/core\";\nimport { QueueService } from \"./queue.service.js\";\nimport type { QueueConfig } from \"./types.js\";\n\n@Module({\n\tproviders: [\n\t\tQueueService,\n\t\t{ provide: QueueService.TOKEN, useExisting: QueueService },\n\t],\n\texports: [QueueService, QueueService.TOKEN],\n})\nexport class QueueModule {\n\t/**\n\t * Build a configured `QueueModule` class with the given queue config.\n\t *\n\t * The returned class can be `imports`-ed by any other module and\n\t * will provide the `QueueService` (and a `QUEUE_CONFIG` value\n\t * provider) to its container.\n\t */\n\tstatic forRoot(config: QueueConfig) {\n\t\t@Module({\n\t\t\tproviders: [\n\t\t\t\tQueueService,\n\t\t\t\t{ provide: QueueService.TOKEN, useExisting: QueueService },\n\t\t\t\t{ provide: \"QUEUE_CONFIG\", useValue: config },\n\t\t\t],\n\t\t\texports: [QueueService, QueueService.TOKEN],\n\t\t})\n\t\tclass ConfiguredQueueModule {}\n\n\t\tObject.defineProperty(ConfiguredQueueModule, \"name\", {\n\t\t\tvalue: \"ConfiguredQueueModule\",\n\t\t});\n\n\t\treturn ConfiguredQueueModule;\n\t}\n}\n",
10
10
  "/**\n * `@OnQueueReady()` — lifecycle hook that runs once when the\n * application has booted and the queue service is ready.\n *\n * Dual-mode: supports TC39 standard ES decorators + legacy.\n *\n * Use this to register workers without coupling to the `Application`\n * lifecycle directly.\n */\nimport type { QueueService } from \"../queue.service.js\";\nimport { safeGetMeta, safeDefineMeta } from \"@nexusts/core/di/safe-reflect\";\n\n/** Symbol for stashing hook on the method function. */\nconst FN_HOOK_KEY = Symbol.for(\"nexus:queue:fn:hook\");\n\n/**\n * Method decorator. The decorated method is invoked once with no\n * arguments after the application has booted. Pair it with\n * `QueueService.start()` — typically called by `Application.bootstrap`.\n */\nexport function OnQueueReady(): any {\n\treturn function (this: any, targetOrFn: any, contextOrKey?: any): void {\n\t\t// Standard (TC39) decorator mode\n\t\tif (contextOrKey?.kind === \"method\") {\n\t\t\tconst fn = targetOrFn;\n\t\t\tconst { name, metadata } = contextOrKey;\n\t\t\t// Stash on context.metadata AND on the function itself.\n\t\t\tconst hooks: Array<string | symbol> = (metadata[\"nexus:queue:ready-hooks\"] as Array<string | symbol>) ?? [];\n\t\t\thooks.push(name);\n\t\t\tmetadata[\"nexus:queue:ready-hooks\"] = hooks;\n\t\t\t(fn as any)[FN_HOOK_KEY] = name;\n\t\t\treturn;\n\t\t}\n\n\t\t// Legacy (experimentalDecorators) mode\n\t\tconst target = targetOrFn;\n\t\tconst propertyKey = contextOrKey as string | symbol;\n\t\tconst descriptor = arguments[2];\n\t\tif (!descriptor || typeof descriptor.value !== \"function\") {\n\t\t\tthrow new Error(\"@OnQueueReady can only decorate methods.\");\n\t\t}\n\t\tconst ctor = target.constructor as object;\n\t\tconst hooks: Array<string | symbol> =\n\t\t\t(safeGetMeta(\"nexus:queue:ready-hooks\", ctor) as Array<string | symbol> | undefined) ?? [];\n\t\thooks.push(propertyKey);\n\t\tsafeDefineMeta(\"nexus:queue:ready-hooks\", hooks, ctor);\n\t};\n}\n\n/**\n * Get the queue-ready hooks declared on a class.\n */\nexport function getQueueReadyHooks(target: unknown): Array<string | symbol> {\n\t// Legacy: check safeGetMeta on constructor\n\tconst ctor = (target as { constructor?: object }).constructor ?? (target as object);\n\tconst fromLegacy = safeGetMeta(\"nexus:queue:ready-hooks\", ctor) as Array<string | symbol> | undefined;\n\tif (fromLegacy) return fromLegacy;\n\n\t// Standard: check prototype methods for FN_HOOK_KEY\n\tconst cls = typeof target === \"function\" ? target : (target as any)?.constructor;\n\tif (cls?.prototype) {\n\t\tconst hooks: Array<string | symbol> = [];\n\t\tfor (const key of Object.getOwnPropertyNames(cls.prototype)) {\n\t\t\tconst fn = cls.prototype[key];\n\t\t\tif (typeof fn === \"function\" && (fn as any)[FN_HOOK_KEY]) {\n\t\t\t\thooks.push((fn as any)[FN_HOOK_KEY]);\n\t\t\t}\n\t\t}\n\t\treturn hooks;\n\t}\n\treturn [];\n}\n\n/**\n * Helper — invoke all `@OnQueueReady` hooks on an instance.\n * Pair this with `QueueService.start()` for a complete bootstrap.\n */\nexport async function invokeQueueReadyHooks(instance: object): Promise<void> {\n\tconst hooks = getQueueReadyHooks(instance);\n\tfor (const key of hooks) {\n\t\tconst fn = (instance as Record<string | symbol, unknown>)[key] as\n\t\t\t| ((...args: unknown[]) => Promise<void> | void)\n\t\t\t| undefined;\n\t\tif (typeof fn === \"function\") {\n\t\t\tawait fn.call(instance);\n\t\t}\n\t}\n}\n\n// Re-export for convenience.\nexport type { QueueService };\n"
11
11
  ],
12
12
  "mappings": "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",
@@ -15,12 +15,12 @@
15
15
  * export class AppModule {}
16
16
  *
17
17
  * // any controller or service
18
- * constructor(@Inject(QueueService.TOKEN) private queue: QueueService) {}
18
+ * @Inject(QueueService.TOKEN) declare private queue: QueueService;
19
19
  * await this.queue.add('send-email', { to: 'a@b.c' });
20
20
  *
21
21
  * // any service — register a worker
22
22
  * class EmailWorker {
23
- * constructor(@Inject(QueueService.TOKEN) private queue: QueueService) {}
23
+ * @Inject(QueueService.TOKEN) declare private queue: QueueService;
24
24
  * async onInit() {
25
25
  * await this.queue.process('send-email', async (data) => {
26
26
  * // ... send the email
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nexusts/queue",
3
- "version": "0.9.7",
3
+ "version": "0.9.8",
4
4
  "description": "Background jobs (BullMQ / Cloudflare / memory)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -38,7 +38,7 @@
38
38
  }
39
39
  },
40
40
  "dependencies": {
41
- "@nexusts/core": "^0.9.7"
41
+ "@nexusts/core": "^0.9.8"
42
42
  },
43
43
  "repository": {
44
44
  "type": "git",