@igniter-js/jobs 0.1.14 → 0.1.15

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.
@@ -1,5 +1,9 @@
1
+ import { mkdir } from 'fs/promises';
2
+ import { dirname } from 'path';
1
3
  import { IgniterError } from '@igniter-js/common';
2
4
 
5
+ // src/adapters/bun-sqlite.adapter.ts
6
+
3
7
  // src/utils/id-generator.ts
4
8
  var IgniterJobsIdGenerator = class {
5
9
  /**
@@ -46,7 +50,9 @@ var IgniterJobsBunSQLiteAdapter = class _IgniterJobsBunSQLiteAdapter {
46
50
  this.queueRuntimes = /* @__PURE__ */ new Map();
47
51
  this.workers = /* @__PURE__ */ new Map();
48
52
  this.subscribers = /* @__PURE__ */ new Map();
53
+ this.streamSubscribers = /* @__PURE__ */ new Map();
49
54
  this.registeredJobs = /* @__PURE__ */ new Map();
55
+ this.streamDatabasePromise = null;
50
56
  this.registeredCrons = /* @__PURE__ */ new Map();
51
57
  this.options = {
52
58
  path: options.path,
@@ -399,6 +405,87 @@ var IgniterJobsBunSQLiteAdapter = class _IgniterJobsBunSQLiteAdapter {
399
405
  if (current.size === 0) this.subscribers.delete(channel);
400
406
  };
401
407
  }
408
+ async writeJobStreamEvent(params) {
409
+ const key = this.getStreamKey(params.queue, params.jobId);
410
+ let eventId = String(Date.now());
411
+ if (params.persistence?.enabled) {
412
+ const db = await this.getStreamDatabase();
413
+ const result = db.prepare(
414
+ `
415
+ INSERT INTO igniter_jobs_stream_events (
416
+ queue, job_id, job_name, type, data, timestamp, scope
417
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
418
+ `
419
+ ).run(
420
+ params.queue,
421
+ params.jobId,
422
+ params.jobName,
423
+ params.event.type,
424
+ JSON.stringify(params.event.data),
425
+ params.event.timestamp.toISOString(),
426
+ params.scope ? JSON.stringify(params.scope) : null
427
+ );
428
+ eventId = String(result.lastInsertRowid);
429
+ const maxEvents = params.persistence.maxEvents;
430
+ if (typeof maxEvents === "number" && maxEvents > 0) {
431
+ db.prepare(
432
+ `
433
+ DELETE FROM igniter_jobs_stream_events
434
+ WHERE id IN (
435
+ SELECT id FROM igniter_jobs_stream_events
436
+ WHERE queue = ? AND job_id = ?
437
+ ORDER BY id DESC
438
+ LIMIT -1 OFFSET ?
439
+ )
440
+ `
441
+ ).run(params.queue, params.jobId, maxEvents);
442
+ }
443
+ }
444
+ const event = {
445
+ ...params.event,
446
+ id: eventId
447
+ };
448
+ const handlers = this.streamSubscribers.get(key);
449
+ if (handlers?.size) {
450
+ await Promise.all(
451
+ Array.from(handlers).map(async (handler) => handler(event))
452
+ );
453
+ }
454
+ return eventId;
455
+ }
456
+ async readJobStream(params) {
457
+ const db = await this.getStreamDatabase();
458
+ const after = params.after ? Number(params.after) : 0;
459
+ const limit = params.limit ?? 100;
460
+ const rows = db.prepare(
461
+ `
462
+ SELECT id, type, data, timestamp, job_id, job_name, queue, scope
463
+ FROM igniter_jobs_stream_events
464
+ WHERE queue = ? AND job_id = ? AND id > ?
465
+ ORDER BY id ASC
466
+ LIMIT ?
467
+ `
468
+ ).all(params.queue, params.jobId, after, limit + 1);
469
+ const hasMore = rows.length > limit;
470
+ const items = rows.slice(0, limit).map((row) => this.mapStreamRow(row));
471
+ return {
472
+ items,
473
+ nextCursor: items.at(-1)?.id,
474
+ hasMore
475
+ };
476
+ }
477
+ async subscribeJobStream(params) {
478
+ const key = this.getStreamKey(params.queue, params.jobId);
479
+ const set = this.streamSubscribers.get(key) ?? /* @__PURE__ */ new Set();
480
+ set.add(params.handler);
481
+ this.streamSubscribers.set(key, set);
482
+ return async () => {
483
+ const current = this.streamSubscribers.get(key);
484
+ if (!current) return;
485
+ current.delete(params.handler);
486
+ if (current.size === 0) this.streamSubscribers.delete(key);
487
+ };
488
+ }
402
489
  async shutdown() {
403
490
  for (const worker of this.workers.values()) {
404
491
  await this.closeWorkerState(worker);
@@ -409,6 +496,12 @@ var IgniterJobsBunSQLiteAdapter = class _IgniterJobsBunSQLiteAdapter {
409
496
  }
410
497
  this.queueRuntimes.clear();
411
498
  this.subscribers.clear();
499
+ this.streamSubscribers.clear();
500
+ if (this.streamDatabasePromise) {
501
+ const db = await this.streamDatabasePromise;
502
+ db.close();
503
+ this.streamDatabasePromise = null;
504
+ }
412
505
  if (this.bunqueueModulePromise) {
413
506
  const bunqueue = await this.bunqueueModulePromise;
414
507
  bunqueue.shutdownManager();
@@ -424,10 +517,36 @@ var IgniterJobsBunSQLiteAdapter = class _IgniterJobsBunSQLiteAdapter {
424
517
  this.bunqueueModulePromise ?? (this.bunqueueModulePromise = import('bunqueue/client'));
425
518
  return this.bunqueueModulePromise;
426
519
  }
520
+ async getStreamDatabase() {
521
+ this.streamDatabasePromise ?? (this.streamDatabasePromise = (async () => {
522
+ await mkdir(dirname(this.options.path), { recursive: true });
523
+ const sqlite = await import('bun:sqlite');
524
+ const db = new sqlite.Database(this.options.path, {
525
+ create: true
526
+ });
527
+ db.exec(`
528
+ CREATE TABLE IF NOT EXISTS igniter_jobs_stream_events (
529
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
530
+ queue TEXT NOT NULL,
531
+ job_id TEXT NOT NULL,
532
+ job_name TEXT NOT NULL,
533
+ type TEXT NOT NULL,
534
+ data TEXT NOT NULL,
535
+ timestamp TEXT NOT NULL,
536
+ scope TEXT
537
+ );
538
+ CREATE INDEX IF NOT EXISTS idx_igniter_jobs_stream_events_job
539
+ ON igniter_jobs_stream_events(queue, job_id, id);
540
+ `);
541
+ return db;
542
+ })());
543
+ return this.streamDatabasePromise;
544
+ }
427
545
  async getQueue(queueName) {
428
546
  const existing = this.queueRuntimes.get(queueName);
429
547
  if (existing) return existing.queue;
430
548
  const bunqueue = await this.loadBunqueue();
549
+ await mkdir(dirname(this.options.path), { recursive: true });
431
550
  const queue = new bunqueue.Queue(queueName, {
432
551
  embedded: true,
433
552
  dataPath: this.options.path,
@@ -764,6 +883,21 @@ var IgniterJobsBunSQLiteAdapter = class _IgniterJobsBunSQLiteAdapter {
764
883
  }
765
884
  return null;
766
885
  }
886
+ getStreamKey(queue, jobId) {
887
+ return `${queue}:${jobId}`;
888
+ }
889
+ mapStreamRow(row) {
890
+ return {
891
+ id: String(row.id),
892
+ type: row.type,
893
+ data: JSON.parse(row.data),
894
+ timestamp: new Date(row.timestamp),
895
+ jobId: row.job_id,
896
+ jobName: row.job_name,
897
+ queue: row.queue,
898
+ scope: row.scope ? JSON.parse(row.scope) : void 0
899
+ };
900
+ }
767
901
  async mapJob(job, queueName, forcedState) {
768
902
  const queue = await this.getQueue(queueName);
769
903
  const rawState = await job.getState();
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/id-generator.ts","../../src/errors/jobs.error.ts","../../src/adapters/bun-sqlite.adapter.ts"],"names":["job"],"mappings":"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","file":"bun.mjs","sourcesContent":["/**\n * Generates consistent identifiers for jobs, workers, and schedules.\n */\nexport class IgniterJobsIdGenerator {\n /**\n * Generates a unique identifier with a prefix.\n *\n * @example\n * ```typescript\n * const jobId = IgniterJobsIdGenerator.generate('job')\n * ```\n */\n public static generate(prefix: string): string {\n const now = Date.now().toString(36)\n const random = Math.random().toString(36).slice(2, 8)\n return `${prefix}_${now}_${random}`\n }\n}\n","import { IgniterError } from \"@igniter-js/common\";\n\n/**\n * Canonical error codes for `@igniter-js/jobs`.\n */\nexport const IGNITER_JOBS_ERROR_CODES = {\n JOBS_ADAPTER_REQUIRED: 'JOBS_ADAPTER_REQUIRED',\n JOBS_SERVICE_REQUIRED: 'JOBS_SERVICE_REQUIRED',\n JOBS_CONTEXT_REQUIRED: 'JOBS_CONTEXT_REQUIRED',\n JOBS_CONFIGURATION_INVALID: 'JOBS_CONFIGURATION_INVALID',\n JOBS_QUEUE_NOT_FOUND: 'JOBS_QUEUE_NOT_FOUND',\n JOBS_QUEUE_DUPLICATE: 'JOBS_QUEUE_DUPLICATE',\n JOBS_QUEUE_OPERATION_FAILED: 'JOBS_QUEUE_OPERATION_FAILED',\n JOBS_INVALID_DEFINITION: 'JOBS_INVALID_DEFINITION',\n JOBS_HANDLER_REQUIRED: 'JOBS_HANDLER_REQUIRED',\n JOBS_DUPLICATE_JOB: 'JOBS_DUPLICATE_JOB',\n JOBS_NOT_FOUND: 'JOBS_NOT_FOUND',\n JOBS_NOT_REGISTERED: 'JOBS_NOT_REGISTERED',\n JOBS_EXECUTION_FAILED: 'JOBS_EXECUTION_FAILED',\n JOBS_TIMEOUT: 'JOBS_TIMEOUT',\n JOBS_CONTEXT_FACTORY_FAILED: 'JOBS_CONTEXT_FACTORY_FAILED',\n JOBS_VALIDATION_FAILED: 'JOBS_VALIDATION_FAILED',\n JOBS_INVALID_INPUT: 'JOBS_INVALID_INPUT',\n JOBS_INVALID_CRON: 'JOBS_INVALID_CRON',\n JOBS_INVALID_SCHEDULE: 'JOBS_INVALID_SCHEDULE',\n JOBS_SCOPE_ALREADY_DEFINED: 'JOBS_SCOPE_ALREADY_DEFINED',\n JOBS_WORKER_FAILED: 'JOBS_WORKER_FAILED',\n JOBS_ADAPTER_ERROR: 'JOBS_ADAPTER_ERROR',\n JOBS_ADAPTER_CONNECTION_FAILED: 'JOBS_ADAPTER_CONNECTION_FAILED',\n JOBS_SUBSCRIBE_FAILED: 'JOBS_SUBSCRIBE_FAILED',\n} as const\n\nexport type IgniterJobsErrorCode = keyof typeof IGNITER_JOBS_ERROR_CODES\n\nexport interface IgniterJobsErrorOptions {\n /** Error code scoped to Igniter Jobs. */\n code: IgniterJobsErrorCode\n /** Human-readable message. */\n message: string\n /** HTTP-like status code hint (default: 500). */\n statusCode?: number\n /** Optional structured details for debugging and clients. */\n details?: unknown\n /** Optional metadata for logs and tracing. */\n metadata?: Record<string, unknown>\n /** Optional causer tag used by some Igniter tooling. */\n causer?: string\n /** Underlying cause for debugging (optional). */\n cause?: Error\n /** Optional logger passthrough to align with other Igniter errors. */\n logger?: any\n}\n\n/**\n * Typed error class for the Jobs package.\n *\n * @example\n * ```typescript\n * throw new IgniterJobsError({\n * code: 'JOBS_INVALID_INPUT',\n * message: 'Input payload failed validation',\n * })\n * ```\n */\nexport class IgniterJobsError extends IgniterError {\n constructor(options: IgniterJobsErrorOptions) {\n super(options)\n }\n}\n","/**\n * @fileoverview Bun SQLite adapter for @igniter-js/jobs\n * @module @igniter-js/jobs/adapters/bun-sqlite\n */\n\nimport type {\n Job as BunqueueJob,\n JobOptions as BunqueueJobOptions,\n Queue as BunqueueQueue,\n Worker as BunqueueWorker,\n} from \"bunqueue/client\";\n\nimport type {\n IgniterCronDefinition,\n IgniterJobCounts,\n IgniterJobDefinition,\n IgniterJobSearchResult,\n IgniterJobStatus,\n IgniterJobsAdapter,\n IgniterJobsAdapterDispatchParams,\n IgniterJobsAdapterScheduleParams,\n IgniterJobsBunSQLiteAdapterOptions,\n IgniterJobsEventHandler,\n IgniterJobsJobLog,\n IgniterJobsQueueCleanOptions,\n IgniterJobsQueueInfo,\n IgniterJobsQueueManager,\n IgniterJobsWorkerBuilderConfig,\n IgniterJobsWorkerHandle,\n IgniterJobsWorkerMetrics,\n IgniterJobsScopeEntry,\n} from \"../types\";\nimport { IgniterJobsIdGenerator } from \"../utils/id-generator\";\nimport { IgniterJobsError } from \"../errors\";\n\ntype BunqueueClientModule = typeof import(\"bunqueue/client\");\n\ntype JobsEnvelope = {\n __igniterJobs: true;\n input?: unknown;\n metadata?: Record<string, unknown>;\n scope?: IgniterJobsScopeEntry;\n schedule?: {\n skipWeekends?: boolean;\n onlyBusinessHours?: boolean;\n businessHours?: {\n start: number;\n end: number;\n timezone?: string;\n };\n onlyWeekdays?: number[];\n skipDates?: string[];\n };\n};\n\ntype QueueRuntime = {\n queue: BunqueueQueue<JobsEnvelope>;\n cronsSynced: boolean;\n};\n\ntype WorkerState = {\n id: string;\n queues: string[];\n concurrency: number;\n paused: boolean;\n closed: boolean;\n startedAt: Date;\n activeJobs: Set<string>;\n metrics: {\n processed: number;\n failed: number;\n totalDuration: number;\n };\n workers: Map<string, BunqueueWorker<JobsEnvelope, unknown>>;\n handlers?: IgniterJobsWorkerBuilderConfig[\"handlers\"];\n};\n\ntype StructuredLog = {\n timestamp: string;\n level: \"info\" | \"warn\" | \"error\";\n message: string;\n};\n\nconst SUPPORTED_JOB_STATES = new Set([\n \"waiting\",\n \"prioritized\",\n \"delayed\",\n \"active\",\n \"completed\",\n \"failed\",\n \"paused\",\n]);\n\n/**\n * Bun-native SQLite adapter for local, embedded, and desktop workloads.\n */\nexport class IgniterJobsBunSQLiteAdapter implements IgniterJobsAdapter {\n public readonly client: { type: \"bun-sqlite\"; path: string };\n\n public readonly queues: IgniterJobsQueueManager = {\n list: async () => this.listQueues(),\n get: async (name) => this.getQueueInfo(name),\n getJobCounts: async (name) => this.getQueueJobCounts(name),\n getJobs: async (name, filter) =>\n this.searchJobs({\n queue: name,\n status: filter?.status,\n limit: filter?.limit,\n offset: filter?.offset,\n }),\n pause: async (name) => this.pauseQueue(name),\n resume: async (name) => this.resumeQueue(name),\n isPaused: async (name) =>\n (await this.getQueueInfo(name))?.isPaused ?? false,\n drain: async (name) => this.drainQueue(name),\n clean: async (name, options) => this.cleanQueue(name, options),\n obliterate: async (name, options) => this.obliterateQueue(name, options),\n };\n\n private readonly options: Required<IgniterJobsBunSQLiteAdapterOptions>;\n private bunqueueModulePromise: Promise<BunqueueClientModule> | null = null;\n private readonly queueRuntimes = new Map<string, QueueRuntime>();\n private readonly workers = new Map<string, WorkerState>();\n private readonly subscribers = new Map<\n string,\n Set<IgniterJobsEventHandler>\n >();\n private readonly registeredJobs = new Map<\n string,\n Map<string, IgniterJobDefinition<any, any, any>>\n >();\n private readonly registeredCrons = new Map<\n string,\n Map<string, IgniterCronDefinition<any, any>>\n >();\n\n private constructor(options: IgniterJobsBunSQLiteAdapterOptions) {\n this.options = {\n path: options.path,\n durable: options.durable ?? false,\n heartbeatInterval: options.heartbeatInterval ?? 10_000,\n pollTimeout: options.pollTimeout ?? 0,\n batchSize: options.batchSize ?? 10,\n lockDuration: options.lockDuration ?? 30_000,\n maxStalledCount: options.maxStalledCount ?? 1,\n };\n\n this.client = {\n type: \"bun-sqlite\",\n path: this.options.path,\n };\n }\n\n public static create(\n options: IgniterJobsBunSQLiteAdapterOptions,\n ): IgniterJobsAdapter {\n return new IgniterJobsBunSQLiteAdapter(options);\n }\n\n public registerJob(\n queueName: string,\n jobName: string,\n definition: IgniterJobDefinition<any, any, any>,\n ): void {\n const jobs =\n this.registeredJobs.get(queueName) ??\n new Map<string, IgniterJobDefinition<any, any, any>>();\n\n if (jobs.has(jobName)) {\n throw new IgniterJobsError({\n code: \"JOBS_DUPLICATE_JOB\",\n message: `Job \"${jobName}\" already registered for queue \"${queueName}\".`,\n });\n }\n\n jobs.set(jobName, definition);\n this.registeredJobs.set(queueName, jobs);\n this.markQueueCronsDirty(queueName);\n }\n\n public registerCron(\n queueName: string,\n cronName: string,\n definition: IgniterCronDefinition<any, any>,\n ): void {\n const crons =\n this.registeredCrons.get(queueName) ??\n new Map<string, IgniterCronDefinition<any, any>>();\n\n if (crons.has(cronName)) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_CRON\",\n message: `Cron \"${cronName}\" already registered for queue \"${queueName}\".`,\n });\n }\n\n crons.set(cronName, definition);\n this.registeredCrons.set(queueName, crons);\n this.markQueueCronsDirty(queueName);\n }\n\n public async dispatch(\n params: IgniterJobsAdapterDispatchParams,\n ): Promise<string> {\n const queue = await this.getQueue(params.queue);\n const job = await queue.add(\n params.jobName,\n this.createEnvelope(params.input, params.metadata, params.scope),\n this.toJobOptions(params),\n );\n\n return job.id;\n }\n\n public async schedule(\n params: IgniterJobsAdapterScheduleParams,\n ): Promise<string> {\n const queue = await this.getQueue(params.queue);\n\n if (params.at) {\n const delay = params.at.getTime() - Date.now();\n if (delay <= 0) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_SCHEDULE\",\n message: \"Scheduled time must be in the future.\",\n });\n }\n\n const job = await queue.add(\n params.jobName,\n this.createEnvelope(params.input, params.metadata, params.scope),\n this.toJobOptions({ ...params, delay }),\n );\n return job.id;\n }\n\n const scheduleEnvelope = this.createEnvelope(\n params.input,\n params.metadata,\n params.scope,\n params,\n );\n\n if (params.cron || params.every) {\n const job = await queue.add(\n params.jobName,\n scheduleEnvelope,\n this.toJobOptions(params, {\n repeat: {\n pattern: params.cron,\n every: params.every,\n limit: params.maxExecutions,\n tz: params.tz,\n },\n }),\n );\n return job.id;\n }\n\n const job = await queue.add(\n params.jobName,\n scheduleEnvelope,\n this.toJobOptions(params),\n );\n return job.id;\n }\n\n public async getJob(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobSearchResult | null> {\n if (queue) {\n const job = await this.getQueue(queue).then((q) => q.getJob(jobId));\n return job ? this.mapJob(job, queue) : null;\n }\n\n for (const queueName of await this.getAllQueueNames()) {\n const job = await this.getQueue(queueName).then((q) => q.getJob(jobId));\n if (job) return this.mapJob(job, queueName);\n }\n\n return null;\n }\n\n public async getJobState(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobStatus | null> {\n const job = await this.getJob(jobId, queue);\n return job?.status ?? null;\n }\n\n public async getJobLogs(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobsJobLog[]> {\n const queueName = queue ?? (await this.findQueueByJobId(jobId));\n if (!queueName) return [];\n\n const logs = await this.getQueue(queueName).then((q) =>\n q.getJobLogs(jobId),\n );\n\n return logs.logs.map((entry) => this.parseLogEntry(entry));\n }\n\n public async getJobProgress(jobId: string, queue?: string): Promise<number> {\n const job = await this.getJob(jobId, queue);\n return job?.progress ?? 0;\n }\n\n public async retryJob(jobId: string, queue?: string): Promise<void> {\n const job = await this.requireJob(jobId, queue);\n await job.retry();\n }\n\n public async removeJob(jobId: string, queue?: string): Promise<void> {\n const job = await this.requireJob(jobId, queue);\n await job.remove();\n }\n\n public async promoteJob(jobId: string, queue?: string): Promise<void> {\n const job = await this.requireJob(jobId, queue);\n await job.promote();\n }\n\n public async moveJobToFailed(\n jobId: string,\n reason: string,\n queue?: string,\n ): Promise<void> {\n const queueName = queue ?? (await this.findQueueByJobId(jobId));\n if (!queueName) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n\n await this.getQueue(queueName).then((q) =>\n q.moveJobToFailed(jobId, new Error(reason)),\n );\n }\n\n public async retryManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((jobId) => this.retryJob(jobId, queue)));\n }\n\n public async removeManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((jobId) => this.removeJob(jobId, queue)));\n }\n\n public async getQueueInfo(\n queue: string,\n ): Promise<IgniterJobsQueueInfo | null> {\n const counts = await this.getQueueJobCounts(queue);\n return {\n name: queue,\n isPaused: await this.getQueue(queue).then((q) => q.isPausedAsync()),\n jobCounts: counts,\n };\n }\n\n public async getQueueJobCounts(queue: string): Promise<IgniterJobCounts> {\n const counts = await this.getQueue(queue).then((q) =>\n q.getJobCountsAsync(),\n );\n return {\n waiting: counts.waiting + counts.prioritized,\n active: counts.active,\n completed: counts.completed,\n failed: counts.failed,\n delayed: counts.delayed,\n paused: counts.paused,\n };\n }\n\n public async listQueues(): Promise<IgniterJobsQueueInfo[]> {\n const queueNames = await this.getAllQueueNames();\n return Promise.all(\n queueNames.map((queueName) => this.getQueueInfo(queueName)),\n ).then((queues) => queues.filter(Boolean) as IgniterJobsQueueInfo[]);\n }\n\n public async pauseQueue(queue: string): Promise<void> {\n const queueClient = await this.getQueue(queue);\n queueClient.pause();\n for (const worker of this.workers.values()) {\n if (worker.workers.has(queue)) {\n worker.paused = true;\n worker.workers.get(queue)?.pause();\n }\n }\n }\n\n public async resumeQueue(queue: string): Promise<void> {\n const queueClient = await this.getQueue(queue);\n queueClient.resume();\n for (const worker of this.workers.values()) {\n if (worker.workers.has(queue)) {\n worker.paused = false;\n worker.workers.get(queue)?.resume();\n }\n }\n }\n\n public async drainQueue(queue: string): Promise<number> {\n const queueClient = await this.getQueue(queue);\n const before = await this.getQueueJobCounts(queue);\n queueClient.drain();\n const after = await this.getQueueJobCounts(queue);\n return Math.max(\n 0,\n before.waiting +\n before.delayed +\n before.paused -\n after.waiting -\n after.delayed -\n after.paused,\n );\n }\n\n public async cleanQueue(\n queue: string,\n options: IgniterJobsQueueCleanOptions,\n ): Promise<number> {\n const statuses = Array.isArray(options.status)\n ? options.status\n : [options.status];\n\n let cleaned = 0;\n const queueClient = await this.getQueue(queue);\n for (const status of statuses) {\n const removed = await queueClient.cleanAsync(\n options.olderThan ?? 0,\n options.limit ?? 1_000,\n this.toBunqueueStatus(status),\n );\n cleaned += removed.length;\n }\n\n return cleaned;\n }\n\n public async obliterateQueue(\n queue: string,\n _options?: { force?: boolean },\n ): Promise<void> {\n const queueClient = await this.getQueue(queue);\n queueClient.obliterate();\n this.registeredJobs.delete(queue);\n this.registeredCrons.delete(queue);\n this.queueRuntimes.delete(queue);\n }\n\n public async retryAllInQueue(queue: string): Promise<number> {\n const queueClient = await this.getQueue(queue);\n const failedJobs = await queueClient.getFailedAsync(0, 10_000);\n await queueClient.retryJobs({\n state: \"failed\",\n count: failedJobs.length || 10_000,\n });\n return failedJobs.length;\n }\n\n public async searchJobs(\n filter: Record<string, unknown>,\n ): Promise<IgniterJobSearchResult[]> {\n const queueName = filter.queue as string | undefined;\n const statuses = filter.status as IgniterJobStatus[] | undefined;\n const limit = (filter.limit as number | undefined) ?? 100;\n const offset = (filter.offset as number | undefined) ?? 0;\n\n const queueNames = queueName ? [queueName] : await this.getAllQueueNames();\n const mappedStates = statuses?.flatMap((status) =>\n this.toBunqueueStates(status),\n );\n const results: IgniterJobSearchResult[] = [];\n\n for (const currentQueue of queueNames) {\n const queueClient = await this.getQueue(currentQueue);\n const jobs = await queueClient.getJobsAsync({\n state: mappedStates,\n start: 0,\n end: offset + limit - 1,\n });\n\n for (const job of jobs) {\n results.push(\n await this.mapJob(job as BunqueueJob<JobsEnvelope>, currentQueue),\n );\n }\n }\n\n return results.slice(offset, offset + limit);\n }\n\n public async searchQueues(\n filter: Record<string, unknown>,\n ): Promise<IgniterJobsQueueInfo[]> {\n const queues = await this.listQueues();\n const name = filter.name as string | undefined;\n const isPaused = filter.isPaused as boolean | undefined;\n\n return queues\n .filter((queue) => (name ? queue.name.includes(name) : true))\n .filter((queue) =>\n typeof isPaused === \"boolean\" ? queue.isPaused === isPaused : true,\n );\n }\n\n public async searchWorkers(\n filter: Record<string, unknown>,\n ): Promise<IgniterJobsWorkerHandle[]> {\n const queue = filter.queue as string | undefined;\n const isRunning = filter.isRunning as boolean | undefined;\n\n return Array.from(this.workers.values())\n .filter((worker) => (queue ? worker.queues.includes(queue) : true))\n .filter((worker) =>\n typeof isRunning === \"boolean\"\n ? isRunning\n ? !worker.closed && !worker.paused\n : worker.closed || worker.paused\n : true,\n )\n .map((worker) => this.toWorkerHandle(worker));\n }\n\n public async createWorker(\n config: IgniterJobsWorkerBuilderConfig,\n ): Promise<IgniterJobsWorkerHandle> {\n const bunqueue = await this.loadBunqueue();\n const queueNames = config.queues.length\n ? config.queues\n : await this.getAllQueueNames();\n\n const workerId = IgniterJobsIdGenerator.generate(\"worker\");\n const workerState: WorkerState = {\n id: workerId,\n queues: [...queueNames],\n concurrency: config.concurrency ?? 1,\n paused: false,\n closed: false,\n startedAt: new Date(),\n activeJobs: new Set<string>(),\n metrics: { processed: 0, failed: 0, totalDuration: 0 },\n workers: new Map(),\n handlers: config.handlers,\n };\n\n const perQueueConcurrency = this.distributeConcurrency(\n workerState.concurrency,\n queueNames,\n );\n\n for (const queueName of queueNames) {\n await this.getQueue(queueName);\n await this.syncCronSchedulers(queueName);\n\n const worker = new bunqueue.Worker<JobsEnvelope, unknown>(\n queueName,\n async (job) => this.processJob(workerState, queueName, job),\n {\n embedded: true,\n dataPath: this.options.path,\n autorun: false,\n concurrency: perQueueConcurrency.get(queueName) ?? 1,\n heartbeatInterval: this.options.heartbeatInterval,\n batchSize: this.options.batchSize,\n pollTimeout: this.options.pollTimeout,\n lockDuration: this.options.lockDuration,\n maxStalledCount: this.options.maxStalledCount,\n limiter: config.limiter\n ? { max: config.limiter.max, duration: config.limiter.duration }\n : undefined,\n },\n );\n\n this.attachWorkerEvents(workerState, queueName, worker);\n worker.run();\n workerState.workers.set(queueName, worker);\n }\n\n this.workers.set(workerId, workerState);\n return this.toWorkerHandle(workerState);\n }\n\n public getWorkers(): Map<string, IgniterJobsWorkerHandle> {\n return new Map(\n Array.from(this.workers.entries()).map(([id, worker]) => [\n id,\n this.toWorkerHandle(worker),\n ]),\n );\n }\n\n public async publishEvent(channel: string, payload: unknown): Promise<void> {\n const handlers = this.subscribers.get(channel);\n if (!handlers) return;\n\n await Promise.all(\n Array.from(handlers).map(async (handler) => handler(payload as never)),\n );\n }\n\n public async subscribeEvent(\n channel: string,\n handler: IgniterJobsEventHandler,\n ): Promise<() => Promise<void>> {\n const handlers =\n this.subscribers.get(channel) ?? new Set<IgniterJobsEventHandler>();\n handlers.add(handler);\n this.subscribers.set(channel, handlers);\n\n return async () => {\n const current = this.subscribers.get(channel);\n if (!current) return;\n current.delete(handler);\n if (current.size === 0) this.subscribers.delete(channel);\n };\n }\n\n public async shutdown(): Promise<void> {\n for (const worker of this.workers.values()) {\n await this.closeWorkerState(worker);\n }\n this.workers.clear();\n\n for (const runtime of this.queueRuntimes.values()) {\n runtime.queue.close();\n }\n this.queueRuntimes.clear();\n this.subscribers.clear();\n\n if (this.bunqueueModulePromise) {\n const bunqueue = await this.bunqueueModulePromise;\n bunqueue.shutdownManager();\n }\n }\n\n private async loadBunqueue(): Promise<BunqueueClientModule> {\n if (typeof (globalThis as { Bun?: unknown }).Bun === \"undefined\") {\n throw new IgniterJobsError({\n code: \"JOBS_ADAPTER_ERROR\",\n message:\n \"The Bun SQLite adapter can only run inside Bun. Use the BullMQ adapter in Node.js runtimes.\",\n });\n }\n\n this.bunqueueModulePromise ??= import(\"bunqueue/client\");\n return this.bunqueueModulePromise;\n }\n\n private async getQueue(\n queueName: string,\n ): Promise<BunqueueQueue<JobsEnvelope>> {\n const existing = this.queueRuntimes.get(queueName);\n if (existing) return existing.queue;\n\n const bunqueue = await this.loadBunqueue();\n const queue = new bunqueue.Queue<JobsEnvelope>(queueName, {\n embedded: true,\n dataPath: this.options.path,\n defaultJobOptions: {\n durable: this.options.durable,\n },\n });\n\n await queue.waitUntilReady();\n this.queueRuntimes.set(queueName, { queue, cronsSynced: false });\n return queue;\n }\n\n private async getAllQueueNames(): Promise<string[]> {\n return Array.from(\n new Set([\n ...this.registeredJobs.keys(),\n ...this.registeredCrons.keys(),\n ...this.queueRuntimes.keys(),\n ]),\n );\n }\n\n private markQueueCronsDirty(queueName: string): void {\n const runtime = this.queueRuntimes.get(queueName);\n if (runtime) runtime.cronsSynced = false;\n }\n\n private async syncCronSchedulers(queueName: string): Promise<void> {\n const runtime = this.queueRuntimes.get(queueName);\n if (!runtime || runtime.cronsSynced) return;\n\n const cronDefinitions = this.registeredCrons.get(queueName) ?? new Map();\n const existing = await runtime.queue.getJobSchedulers(0, 10_000);\n const existingIds = new Set(existing.map((scheduler) => scheduler.id));\n\n for (const [cronName, definition] of cronDefinitions.entries()) {\n await runtime.queue.upsertJobScheduler(\n cronName,\n {\n pattern: definition.cron,\n limit: definition.maxExecutions,\n timezone: definition.tz,\n },\n {\n name: cronName,\n data: this.createEnvelope(\n undefined,\n undefined,\n undefined,\n definition,\n ),\n opts: { durable: this.options.durable },\n },\n );\n existingIds.delete(cronName);\n }\n\n for (const schedulerId of existingIds) {\n await runtime.queue.removeJobScheduler(schedulerId);\n }\n\n runtime.cronsSynced = true;\n }\n\n private createEnvelope(\n input?: unknown,\n metadata?: Record<string, unknown>,\n scope?: IgniterJobsScopeEntry,\n scheduleSource?:\n | IgniterJobsAdapterScheduleParams\n | IgniterCronDefinition<any, any>,\n ): JobsEnvelope {\n return {\n __igniterJobs: true,\n input,\n metadata,\n scope,\n schedule: scheduleSource\n ? {\n skipWeekends: scheduleSource.skipWeekends,\n onlyBusinessHours: scheduleSource.onlyBusinessHours,\n businessHours: scheduleSource.businessHours,\n onlyWeekdays: scheduleSource.onlyWeekdays,\n skipDates: scheduleSource.skipDates?.map((value) =>\n value instanceof Date ? value.toISOString() : value,\n ),\n }\n : undefined,\n };\n }\n\n private toJobOptions(\n params: IgniterJobsAdapterDispatchParams | IgniterJobsAdapterScheduleParams,\n overrides?: Partial<BunqueueJobOptions>,\n ): BunqueueJobOptions {\n return {\n jobId: params.jobId,\n priority: params.priority,\n delay: params.delay,\n attempts: params.attempts,\n removeOnComplete: params.removeOnComplete,\n removeOnFail: params.removeOnFail,\n durable: this.options.durable,\n ...overrides,\n };\n }\n\n private async processJob(\n workerState: WorkerState,\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n ): Promise<unknown> {\n const envelope = this.normalizeEnvelope(job.data);\n\n if (!this.shouldExecuteScheduledJob(envelope.schedule, new Date())) {\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n \"Scheduled run skipped by adapter rules.\",\n );\n return { skipped: true };\n }\n\n const registeredJob = this.registeredJobs.get(queueName)?.get(job.name);\n if (registeredJob) {\n return this.processRegisteredDefinition(\n workerState,\n queueName,\n job,\n envelope,\n registeredJob,\n );\n }\n\n const registeredCron = this.registeredCrons.get(queueName)?.get(job.name);\n if (registeredCron) {\n return this.processRegisteredCron(\n queueName,\n job,\n envelope,\n registeredCron,\n );\n }\n\n throw new IgniterJobsError({\n code: \"JOBS_NOT_REGISTERED\",\n message: `Job \"${job.name}\" is not registered for queue \"${queueName}\".`,\n });\n }\n\n private async processRegisteredDefinition(\n workerState: WorkerState,\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n envelope: JobsEnvelope,\n definition: IgniterJobDefinition<any, any, any>,\n ): Promise<unknown> {\n const baseContext = this.createExecutionContext(\n queueName,\n job,\n envelope,\n definition,\n );\n const startedAt = new Date();\n\n await this.writeLog(queueName, job.id, \"info\", \"Job started.\");\n await this.invokeHook(() =>\n definition.onStart?.({ ...baseContext, startedAt } as never),\n );\n\n try {\n const result = await definition.handler(baseContext as never);\n const duration = Date.now() - startedAt.getTime();\n workerState.metrics.processed += 1;\n workerState.metrics.totalDuration += duration;\n\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n `Job completed in ${duration}ms.`,\n );\n await this.invokeHook(() =>\n definition.onSuccess?.({\n ...baseContext,\n startedAt,\n duration,\n result,\n } as never),\n );\n\n return result;\n } catch (error) {\n const runtimeError =\n error instanceof Error ? error : new Error(String(error));\n const duration = Date.now() - startedAt.getTime();\n const maxAttempts = definition.attempts ?? job.opts.attempts ?? 1;\n const isFinalAttempt = job.attemptsMade >= maxAttempts;\n workerState.metrics.failed += 1;\n\n await this.writeLog(queueName, job.id, \"error\", runtimeError.message);\n await this.invokeHook(() =>\n definition.onFailure?.({\n ...baseContext,\n startedAt,\n duration,\n error: runtimeError,\n isFinalAttempt,\n } as never),\n );\n\n throw runtimeError;\n }\n }\n\n private async processRegisteredCron(\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n envelope: JobsEnvelope,\n definition: IgniterCronDefinition<any, any>,\n ): Promise<unknown> {\n await this.writeLog(queueName, job.id, \"info\", \"Cron execution started.\");\n\n try {\n const result = await definition.handler({\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: queueName,\n attemptsMade: job.attemptsMade,\n createdAt: new Date(job.timestamp),\n metadata: envelope.metadata,\n },\n scope: envelope.scope,\n } as never);\n\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n \"Cron execution completed.\",\n );\n return result;\n } catch (error) {\n const runtimeError =\n error instanceof Error ? error : new Error(String(error));\n await this.writeLog(queueName, job.id, \"error\", runtimeError.message);\n throw runtimeError;\n }\n }\n\n private createExecutionContext(\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n envelope: JobsEnvelope,\n definition: IgniterJobDefinition<any, any, any>,\n ) {\n const baseContext = {\n input: envelope.input,\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: queueName,\n attemptsMade: job.attemptsMade,\n createdAt: new Date(job.timestamp),\n metadata: envelope.metadata,\n updateProgress: async (progress: number, message?: string) => {\n await job.updateProgress(progress, message);\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n `Progress updated to ${progress}%.`,\n );\n await this.invokeHook(() =>\n definition.onProgress?.({\n ...baseContext,\n progress,\n message,\n } as never),\n );\n },\n },\n scope: envelope.scope,\n };\n\n return baseContext;\n }\n\n private attachWorkerEvents(\n workerState: WorkerState,\n queueName: string,\n worker: BunqueueWorker<JobsEnvelope, unknown>,\n ): void {\n worker.on(\"active\", async (job) => {\n workerState.activeJobs.add(job.id);\n await this.invokeHandler(() =>\n workerState.handlers?.onActive?.({\n job: this.mapJobSync(job, queueName),\n }),\n );\n });\n\n worker.on(\"completed\", async (job, result) => {\n workerState.activeJobs.delete(job.id);\n await this.invokeHandler(() =>\n workerState.handlers?.onSuccess?.({\n job: this.mapJobSync(job, queueName, \"completed\"),\n result,\n }),\n );\n });\n\n worker.on(\"failed\", async (job, error) => {\n workerState.activeJobs.delete(job.id);\n await this.invokeHandler(() =>\n workerState.handlers?.onFailure?.({\n job: this.mapJobSync(job, queueName, \"failed\"),\n error,\n }),\n );\n });\n\n worker.on(\"drained\", async () => {\n if (workerState.activeJobs.size === 0) {\n await this.invokeHandler(() => workerState.handlers?.onIdle?.());\n }\n });\n\n worker.on(\"error\", async (error) => {\n await this.writeQueueLog(\n queueName,\n \"error\",\n `Worker error: ${error.message}`,\n );\n });\n }\n\n private toWorkerHandle(worker: WorkerState): IgniterJobsWorkerHandle {\n return {\n id: worker.id,\n queues: [...worker.queues],\n pause: async () => {\n worker.paused = true;\n for (const runtime of worker.workers.values()) runtime.pause();\n },\n resume: async () => {\n worker.paused = false;\n for (const runtime of worker.workers.values()) runtime.resume();\n },\n close: async () => {\n await this.closeWorkerState(worker);\n },\n isRunning: () => !worker.closed && !worker.paused,\n isPaused: () => worker.paused,\n isClosed: () => worker.closed,\n getMetrics: async () => this.buildWorkerMetrics(worker),\n };\n }\n\n private buildWorkerMetrics(worker: WorkerState): IgniterJobsWorkerMetrics {\n return {\n processed: worker.metrics.processed,\n failed: worker.metrics.failed,\n avgDuration:\n worker.metrics.processed > 0\n ? worker.metrics.totalDuration / worker.metrics.processed\n : 0,\n concurrency: worker.concurrency,\n uptime: Date.now() - worker.startedAt.getTime(),\n };\n }\n\n private async closeWorkerState(worker: WorkerState): Promise<void> {\n worker.closed = true;\n await Promise.all(\n Array.from(worker.workers.values()).map((runtime) => runtime.close()),\n );\n worker.workers.clear();\n }\n\n private async requireJob(\n jobId: string,\n queue?: string,\n ): Promise<BunqueueJob<JobsEnvelope>> {\n const queueName = queue ?? (await this.findQueueByJobId(jobId));\n if (!queueName) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n\n const job = await this.getQueue(queueName).then((queueClient) =>\n queueClient.getJob(jobId),\n );\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found${queue ? ` in queue \"${queue}\"` : \"\"}.`,\n });\n }\n\n return job;\n }\n\n private async findQueueByJobId(jobId: string): Promise<string | null> {\n for (const queueName of await this.getAllQueueNames()) {\n const job = await this.getQueue(queueName).then((queueClient) =>\n queueClient.getJob(jobId),\n );\n if (job) return queueName;\n }\n return null;\n }\n\n private async mapJob(\n job: BunqueueJob<JobsEnvelope>,\n queueName: string,\n forcedState?: IgniterJobStatus,\n ): Promise<IgniterJobSearchResult> {\n const queue = await this.getQueue(queueName);\n const rawState = await job.getState();\n return this.mapJobSync(\n job,\n queueName,\n forcedState ?? this.toPublicStatus(rawState, queue.isPaused()),\n );\n }\n\n private mapJobSync(\n job: BunqueueJob<JobsEnvelope>,\n queueName: string,\n status?: IgniterJobStatus,\n ): IgniterJobSearchResult {\n const envelope = this.normalizeEnvelope(job.data);\n\n return {\n id: job.id,\n name: job.name,\n queue: queueName,\n status: status ?? this.toPublicStatus(\"waiting\", false),\n input: envelope.input,\n result: job.returnvalue,\n error: job.failedReason ?? undefined,\n progress: typeof job.progress === \"number\" ? job.progress : 0,\n attemptsMade: job.attemptsMade,\n priority: job.priority ?? 0,\n createdAt: new Date(job.timestamp),\n startedAt: job.processedOn ? new Date(job.processedOn) : undefined,\n completedAt: job.finishedOn ? new Date(job.finishedOn) : undefined,\n metadata: envelope.metadata,\n scope: envelope.scope,\n };\n }\n\n private normalizeEnvelope(data: JobsEnvelope | unknown): JobsEnvelope {\n if (\n data &&\n typeof data === \"object\" &&\n (data as JobsEnvelope).__igniterJobs === true\n ) {\n return data as JobsEnvelope;\n }\n\n return {\n __igniterJobs: true,\n input: data,\n };\n }\n\n private toPublicStatus(\n rawState: string,\n isQueuePaused: boolean,\n ): IgniterJobStatus {\n if (\n (rawState === \"waiting\" || rawState === \"prioritized\") &&\n isQueuePaused\n ) {\n return \"paused\";\n }\n\n switch (rawState) {\n case \"prioritized\":\n case \"waiting-children\":\n return \"waiting\";\n case \"waiting\":\n case \"active\":\n case \"completed\":\n case \"failed\":\n case \"delayed\":\n case \"paused\":\n return rawState;\n default:\n return \"waiting\";\n }\n }\n\n private toBunqueueStatus(status: IgniterJobStatus): string {\n switch (status) {\n case \"waiting\":\n return \"waiting\";\n default:\n return status;\n }\n }\n\n private toBunqueueStates(status: IgniterJobStatus): string[] {\n switch (status) {\n case \"waiting\":\n return [\"waiting\", \"prioritized\"];\n case \"paused\":\n return [\"paused\"];\n default:\n return [status];\n }\n }\n\n private distributeConcurrency(\n total: number,\n queues: string[],\n ): Map<string, number> {\n const result = new Map<string, number>();\n if (queues.length === 0) return result;\n\n const base = Math.max(1, Math.floor(total / queues.length));\n let remainder = Math.max(0, total - base * queues.length);\n\n for (const queue of queues) {\n const value = base + (remainder > 0 ? 1 : 0);\n result.set(queue, value);\n remainder = Math.max(0, remainder - 1);\n }\n\n return result;\n }\n\n private shouldExecuteScheduledJob(\n schedule: JobsEnvelope[\"schedule\"],\n now: Date,\n ): boolean {\n if (!schedule) return true;\n const day = now.getDay();\n const isoDate = now.toISOString().slice(0, 10);\n\n if (schedule.skipWeekends && (day === 0 || day === 6)) return false;\n if (schedule.onlyWeekdays?.length && !schedule.onlyWeekdays.includes(day))\n return false;\n if (schedule.skipDates?.some((value) => value.slice(0, 10) === isoDate))\n return false;\n\n if (schedule.onlyBusinessHours && schedule.businessHours) {\n const hour = now.getHours();\n return (\n hour >= schedule.businessHours.start &&\n hour < schedule.businessHours.end\n );\n }\n\n return true;\n }\n\n private parseLogEntry(entry: string): IgniterJobsJobLog {\n try {\n const parsed = JSON.parse(entry) as StructuredLog;\n if (\n parsed &&\n typeof parsed.message === \"string\" &&\n typeof parsed.timestamp === \"string\" &&\n (parsed.level === \"info\" ||\n parsed.level === \"warn\" ||\n parsed.level === \"error\")\n ) {\n return {\n timestamp: new Date(parsed.timestamp),\n level: parsed.level,\n message: parsed.message,\n };\n }\n } catch {\n // fall back to plain string\n }\n\n return {\n timestamp: new Date(),\n level: \"info\",\n message: entry,\n };\n }\n\n private async writeLog(\n queueName: string,\n jobId: string,\n level: \"info\" | \"warn\" | \"error\",\n message: string,\n ): Promise<void> {\n const queue = await this.getQueue(queueName);\n await queue.addJobLog(\n jobId,\n JSON.stringify({ timestamp: new Date().toISOString(), level, message }),\n );\n }\n\n private async writeQueueLog(\n queueName: string,\n level: \"info\" | \"warn\" | \"error\",\n message: string,\n ): Promise<void> {\n void queueName;\n void level;\n void message;\n }\n\n private async invokeHook(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch {\n // Hooks must not break worker state transitions.\n }\n }\n\n private async invokeHandler(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch {\n // Worker observers are isolated from backend processing.\n }\n }\n}\n\nexport type { IgniterJobsBunSQLiteAdapterOptions };\n"]}
1
+ {"version":3,"sources":["../../src/utils/id-generator.ts","../../src/errors/jobs.error.ts","../../src/adapters/bun-sqlite.adapter.ts"],"names":["job"],"mappings":"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","file":"bun.mjs","sourcesContent":["/**\n * Generates consistent identifiers for jobs, workers, and schedules.\n */\nexport class IgniterJobsIdGenerator {\n /**\n * Generates a unique identifier with a prefix.\n *\n * @example\n * ```typescript\n * const jobId = IgniterJobsIdGenerator.generate('job')\n * ```\n */\n public static generate(prefix: string): string {\n const now = Date.now().toString(36)\n const random = Math.random().toString(36).slice(2, 8)\n return `${prefix}_${now}_${random}`\n }\n}\n","import { IgniterError } from \"@igniter-js/common\";\n\n/**\n * Canonical error codes for `@igniter-js/jobs`.\n */\nexport const IGNITER_JOBS_ERROR_CODES = {\n JOBS_ADAPTER_REQUIRED: 'JOBS_ADAPTER_REQUIRED',\n JOBS_SERVICE_REQUIRED: 'JOBS_SERVICE_REQUIRED',\n JOBS_CONTEXT_REQUIRED: 'JOBS_CONTEXT_REQUIRED',\n JOBS_CONFIGURATION_INVALID: 'JOBS_CONFIGURATION_INVALID',\n JOBS_QUEUE_NOT_FOUND: 'JOBS_QUEUE_NOT_FOUND',\n JOBS_QUEUE_DUPLICATE: 'JOBS_QUEUE_DUPLICATE',\n JOBS_QUEUE_OPERATION_FAILED: 'JOBS_QUEUE_OPERATION_FAILED',\n JOBS_INVALID_DEFINITION: 'JOBS_INVALID_DEFINITION',\n JOBS_HANDLER_REQUIRED: 'JOBS_HANDLER_REQUIRED',\n JOBS_DUPLICATE_JOB: 'JOBS_DUPLICATE_JOB',\n JOBS_NOT_FOUND: 'JOBS_NOT_FOUND',\n JOBS_NOT_REGISTERED: 'JOBS_NOT_REGISTERED',\n JOBS_EXECUTION_FAILED: 'JOBS_EXECUTION_FAILED',\n JOBS_TIMEOUT: 'JOBS_TIMEOUT',\n JOBS_CONTEXT_FACTORY_FAILED: 'JOBS_CONTEXT_FACTORY_FAILED',\n JOBS_VALIDATION_FAILED: 'JOBS_VALIDATION_FAILED',\n JOBS_INVALID_INPUT: 'JOBS_INVALID_INPUT',\n JOBS_INVALID_CRON: 'JOBS_INVALID_CRON',\n JOBS_INVALID_SCHEDULE: 'JOBS_INVALID_SCHEDULE',\n JOBS_SCOPE_ALREADY_DEFINED: 'JOBS_SCOPE_ALREADY_DEFINED',\n JOBS_WORKER_FAILED: 'JOBS_WORKER_FAILED',\n JOBS_ADAPTER_ERROR: 'JOBS_ADAPTER_ERROR',\n JOBS_ADAPTER_CONNECTION_FAILED: 'JOBS_ADAPTER_CONNECTION_FAILED',\n JOBS_SUBSCRIBE_FAILED: 'JOBS_SUBSCRIBE_FAILED',\n} as const\n\nexport type IgniterJobsErrorCode = keyof typeof IGNITER_JOBS_ERROR_CODES\n\nexport interface IgniterJobsErrorOptions {\n /** Error code scoped to Igniter Jobs. */\n code: IgniterJobsErrorCode\n /** Human-readable message. */\n message: string\n /** HTTP-like status code hint (default: 500). */\n statusCode?: number\n /** Optional structured details for debugging and clients. */\n details?: unknown\n /** Optional metadata for logs and tracing. */\n metadata?: Record<string, unknown>\n /** Optional causer tag used by some Igniter tooling. */\n causer?: string\n /** Underlying cause for debugging (optional). */\n cause?: Error\n /** Optional logger passthrough to align with other Igniter errors. */\n logger?: any\n}\n\n/**\n * Typed error class for the Jobs package.\n *\n * @example\n * ```typescript\n * throw new IgniterJobsError({\n * code: 'JOBS_INVALID_INPUT',\n * message: 'Input payload failed validation',\n * })\n * ```\n */\nexport class IgniterJobsError extends IgniterError {\n constructor(options: IgniterJobsErrorOptions) {\n super(options)\n }\n}\n","/**\n * @fileoverview Bun SQLite adapter for @igniter-js/jobs\n * @module @igniter-js/jobs/adapters/bun-sqlite\n */\n\nimport { mkdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\nimport type {\n Job as BunqueueJob,\n JobOptions as BunqueueJobOptions,\n Queue as BunqueueQueue,\n Worker as BunqueueWorker,\n} from \"bunqueue/client\";\n\nimport type {\n IgniterJobsAdapterJobStreamReadParams,\n IgniterJobsAdapterJobStreamSubscribeParams,\n IgniterJobsAdapterJobStreamWriteParams,\n IgniterCronDefinition,\n IgniterJobCounts,\n IgniterJobDefinition,\n IgniterJobSearchResult,\n IgniterJobStatus,\n IgniterJobsAdapter,\n IgniterJobsAdapterDispatchParams,\n IgniterJobsAdapterScheduleParams,\n IgniterJobsBunSQLiteAdapterOptions,\n IgniterJobsEventHandler,\n IgniterJobsJobLog,\n IgniterJobsQueueCleanOptions,\n IgniterJobsQueueInfo,\n IgniterJobsQueueManager,\n IgniterJobsWorkerBuilderConfig,\n IgniterJobsWorkerHandle,\n IgniterJobsWorkerMetrics,\n IgniterJobsScopeEntry,\n} from \"../types\";\nimport { IgniterJobsIdGenerator } from \"../utils/id-generator\";\nimport { IgniterJobsError } from \"../errors\";\nimport type {\n IgniterJobsJobStreamEvent,\n IgniterJobsJobStreamReadResult,\n} from \"../types/stream\";\n\ntype BunqueueClientModule = typeof import(\"bunqueue/client\");\n\ntype JobsEnvelope = {\n __igniterJobs: true;\n input?: unknown;\n metadata?: Record<string, unknown>;\n scope?: IgniterJobsScopeEntry;\n schedule?: {\n skipWeekends?: boolean;\n onlyBusinessHours?: boolean;\n businessHours?: {\n start: number;\n end: number;\n timezone?: string;\n };\n onlyWeekdays?: number[];\n skipDates?: string[];\n };\n};\n\ntype QueueRuntime = {\n queue: BunqueueQueue<JobsEnvelope>;\n cronsSynced: boolean;\n};\n\ntype WorkerState = {\n id: string;\n queues: string[];\n concurrency: number;\n paused: boolean;\n closed: boolean;\n startedAt: Date;\n activeJobs: Set<string>;\n metrics: {\n processed: number;\n failed: number;\n totalDuration: number;\n };\n workers: Map<string, BunqueueWorker<JobsEnvelope, unknown>>;\n handlers?: IgniterJobsWorkerBuilderConfig[\"handlers\"];\n};\n\ntype StructuredLog = {\n timestamp: string;\n level: \"info\" | \"warn\" | \"error\";\n message: string;\n};\n\ntype SQLiteDatabase = {\n exec(sql: string): void;\n prepare<T = unknown>(\n sql: string,\n ): {\n run(...params: unknown[]): {\n changes: number;\n lastInsertRowid: number | bigint;\n };\n get(...params: unknown[]): T | undefined;\n all(...params: unknown[]): T[];\n };\n close(): void;\n};\n\nconst SUPPORTED_JOB_STATES = new Set([\n \"waiting\",\n \"prioritized\",\n \"delayed\",\n \"active\",\n \"completed\",\n \"failed\",\n \"paused\",\n]);\n\n/**\n * Bun-native SQLite adapter for local, embedded, and desktop workloads.\n */\nexport class IgniterJobsBunSQLiteAdapter implements IgniterJobsAdapter {\n public readonly client: { type: \"bun-sqlite\"; path: string };\n\n public readonly queues: IgniterJobsQueueManager = {\n list: async () => this.listQueues(),\n get: async (name) => this.getQueueInfo(name),\n getJobCounts: async (name) => this.getQueueJobCounts(name),\n getJobs: async (name, filter) =>\n this.searchJobs({\n queue: name,\n status: filter?.status,\n limit: filter?.limit,\n offset: filter?.offset,\n }),\n pause: async (name) => this.pauseQueue(name),\n resume: async (name) => this.resumeQueue(name),\n isPaused: async (name) =>\n (await this.getQueueInfo(name))?.isPaused ?? false,\n drain: async (name) => this.drainQueue(name),\n clean: async (name, options) => this.cleanQueue(name, options),\n obliterate: async (name, options) => this.obliterateQueue(name, options),\n };\n\n private readonly options: Required<IgniterJobsBunSQLiteAdapterOptions>;\n private bunqueueModulePromise: Promise<BunqueueClientModule> | null = null;\n private readonly queueRuntimes = new Map<string, QueueRuntime>();\n private readonly workers = new Map<string, WorkerState>();\n private readonly subscribers = new Map<\n string,\n Set<IgniterJobsEventHandler>\n >();\n private readonly streamSubscribers = new Map<\n string,\n Set<\n (\n event: IgniterJobsJobStreamEvent<string, unknown>,\n ) => void | Promise<void>\n >\n >();\n private readonly registeredJobs = new Map<\n string,\n Map<string, IgniterJobDefinition<any, any, any>>\n >();\n private streamDatabasePromise: Promise<SQLiteDatabase> | null = null;\n private readonly registeredCrons = new Map<\n string,\n Map<string, IgniterCronDefinition<any, any>>\n >();\n\n private constructor(options: IgniterJobsBunSQLiteAdapterOptions) {\n this.options = {\n path: options.path,\n durable: options.durable ?? false,\n heartbeatInterval: options.heartbeatInterval ?? 10_000,\n pollTimeout: options.pollTimeout ?? 0,\n batchSize: options.batchSize ?? 10,\n lockDuration: options.lockDuration ?? 30_000,\n maxStalledCount: options.maxStalledCount ?? 1,\n };\n\n this.client = {\n type: \"bun-sqlite\",\n path: this.options.path,\n };\n }\n\n public static create(\n options: IgniterJobsBunSQLiteAdapterOptions,\n ): IgniterJobsAdapter {\n return new IgniterJobsBunSQLiteAdapter(options);\n }\n\n public registerJob(\n queueName: string,\n jobName: string,\n definition: IgniterJobDefinition<any, any, any>,\n ): void {\n const jobs =\n this.registeredJobs.get(queueName) ??\n new Map<string, IgniterJobDefinition<any, any, any>>();\n\n if (jobs.has(jobName)) {\n throw new IgniterJobsError({\n code: \"JOBS_DUPLICATE_JOB\",\n message: `Job \"${jobName}\" already registered for queue \"${queueName}\".`,\n });\n }\n\n jobs.set(jobName, definition);\n this.registeredJobs.set(queueName, jobs);\n this.markQueueCronsDirty(queueName);\n }\n\n public registerCron(\n queueName: string,\n cronName: string,\n definition: IgniterCronDefinition<any, any>,\n ): void {\n const crons =\n this.registeredCrons.get(queueName) ??\n new Map<string, IgniterCronDefinition<any, any>>();\n\n if (crons.has(cronName)) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_CRON\",\n message: `Cron \"${cronName}\" already registered for queue \"${queueName}\".`,\n });\n }\n\n crons.set(cronName, definition);\n this.registeredCrons.set(queueName, crons);\n this.markQueueCronsDirty(queueName);\n }\n\n public async dispatch(\n params: IgniterJobsAdapterDispatchParams,\n ): Promise<string> {\n const queue = await this.getQueue(params.queue);\n const job = await queue.add(\n params.jobName,\n this.createEnvelope(params.input, params.metadata, params.scope),\n this.toJobOptions(params),\n );\n\n return job.id;\n }\n\n public async schedule(\n params: IgniterJobsAdapterScheduleParams,\n ): Promise<string> {\n const queue = await this.getQueue(params.queue);\n\n if (params.at) {\n const delay = params.at.getTime() - Date.now();\n if (delay <= 0) {\n throw new IgniterJobsError({\n code: \"JOBS_INVALID_SCHEDULE\",\n message: \"Scheduled time must be in the future.\",\n });\n }\n\n const job = await queue.add(\n params.jobName,\n this.createEnvelope(params.input, params.metadata, params.scope),\n this.toJobOptions({ ...params, delay }),\n );\n return job.id;\n }\n\n const scheduleEnvelope = this.createEnvelope(\n params.input,\n params.metadata,\n params.scope,\n params,\n );\n\n if (params.cron || params.every) {\n const job = await queue.add(\n params.jobName,\n scheduleEnvelope,\n this.toJobOptions(params, {\n repeat: {\n pattern: params.cron,\n every: params.every,\n limit: params.maxExecutions,\n tz: params.tz,\n },\n }),\n );\n return job.id;\n }\n\n const job = await queue.add(\n params.jobName,\n scheduleEnvelope,\n this.toJobOptions(params),\n );\n return job.id;\n }\n\n public async getJob(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobSearchResult | null> {\n if (queue) {\n const job = await this.getQueue(queue).then((q) => q.getJob(jobId));\n return job ? this.mapJob(job, queue) : null;\n }\n\n for (const queueName of await this.getAllQueueNames()) {\n const job = await this.getQueue(queueName).then((q) => q.getJob(jobId));\n if (job) return this.mapJob(job, queueName);\n }\n\n return null;\n }\n\n public async getJobState(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobStatus | null> {\n const job = await this.getJob(jobId, queue);\n return job?.status ?? null;\n }\n\n public async getJobLogs(\n jobId: string,\n queue?: string,\n ): Promise<IgniterJobsJobLog[]> {\n const queueName = queue ?? (await this.findQueueByJobId(jobId));\n if (!queueName) return [];\n\n const logs = await this.getQueue(queueName).then((q) =>\n q.getJobLogs(jobId),\n );\n\n return logs.logs.map((entry) => this.parseLogEntry(entry));\n }\n\n public async getJobProgress(jobId: string, queue?: string): Promise<number> {\n const job = await this.getJob(jobId, queue);\n return job?.progress ?? 0;\n }\n\n public async retryJob(jobId: string, queue?: string): Promise<void> {\n const job = await this.requireJob(jobId, queue);\n await job.retry();\n }\n\n public async removeJob(jobId: string, queue?: string): Promise<void> {\n const job = await this.requireJob(jobId, queue);\n await job.remove();\n }\n\n public async promoteJob(jobId: string, queue?: string): Promise<void> {\n const job = await this.requireJob(jobId, queue);\n await job.promote();\n }\n\n public async moveJobToFailed(\n jobId: string,\n reason: string,\n queue?: string,\n ): Promise<void> {\n const queueName = queue ?? (await this.findQueueByJobId(jobId));\n if (!queueName) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n\n await this.getQueue(queueName).then((q) =>\n q.moveJobToFailed(jobId, new Error(reason)),\n );\n }\n\n public async retryManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((jobId) => this.retryJob(jobId, queue)));\n }\n\n public async removeManyJobs(jobIds: string[], queue?: string): Promise<void> {\n await Promise.all(jobIds.map((jobId) => this.removeJob(jobId, queue)));\n }\n\n public async getQueueInfo(\n queue: string,\n ): Promise<IgniterJobsQueueInfo | null> {\n const counts = await this.getQueueJobCounts(queue);\n return {\n name: queue,\n isPaused: await this.getQueue(queue).then((q) => q.isPausedAsync()),\n jobCounts: counts,\n };\n }\n\n public async getQueueJobCounts(queue: string): Promise<IgniterJobCounts> {\n const counts = await this.getQueue(queue).then((q) =>\n q.getJobCountsAsync(),\n );\n return {\n waiting: counts.waiting + counts.prioritized,\n active: counts.active,\n completed: counts.completed,\n failed: counts.failed,\n delayed: counts.delayed,\n paused: counts.paused,\n };\n }\n\n public async listQueues(): Promise<IgniterJobsQueueInfo[]> {\n const queueNames = await this.getAllQueueNames();\n return Promise.all(\n queueNames.map((queueName) => this.getQueueInfo(queueName)),\n ).then((queues) => queues.filter(Boolean) as IgniterJobsQueueInfo[]);\n }\n\n public async pauseQueue(queue: string): Promise<void> {\n const queueClient = await this.getQueue(queue);\n queueClient.pause();\n for (const worker of this.workers.values()) {\n if (worker.workers.has(queue)) {\n worker.paused = true;\n worker.workers.get(queue)?.pause();\n }\n }\n }\n\n public async resumeQueue(queue: string): Promise<void> {\n const queueClient = await this.getQueue(queue);\n queueClient.resume();\n for (const worker of this.workers.values()) {\n if (worker.workers.has(queue)) {\n worker.paused = false;\n worker.workers.get(queue)?.resume();\n }\n }\n }\n\n public async drainQueue(queue: string): Promise<number> {\n const queueClient = await this.getQueue(queue);\n const before = await this.getQueueJobCounts(queue);\n queueClient.drain();\n const after = await this.getQueueJobCounts(queue);\n return Math.max(\n 0,\n before.waiting +\n before.delayed +\n before.paused -\n after.waiting -\n after.delayed -\n after.paused,\n );\n }\n\n public async cleanQueue(\n queue: string,\n options: IgniterJobsQueueCleanOptions,\n ): Promise<number> {\n const statuses = Array.isArray(options.status)\n ? options.status\n : [options.status];\n\n let cleaned = 0;\n const queueClient = await this.getQueue(queue);\n for (const status of statuses) {\n const removed = await queueClient.cleanAsync(\n options.olderThan ?? 0,\n options.limit ?? 1_000,\n this.toBunqueueStatus(status),\n );\n cleaned += removed.length;\n }\n\n return cleaned;\n }\n\n public async obliterateQueue(\n queue: string,\n _options?: { force?: boolean },\n ): Promise<void> {\n const queueClient = await this.getQueue(queue);\n queueClient.obliterate();\n this.registeredJobs.delete(queue);\n this.registeredCrons.delete(queue);\n this.queueRuntimes.delete(queue);\n }\n\n public async retryAllInQueue(queue: string): Promise<number> {\n const queueClient = await this.getQueue(queue);\n const failedJobs = await queueClient.getFailedAsync(0, 10_000);\n await queueClient.retryJobs({\n state: \"failed\",\n count: failedJobs.length || 10_000,\n });\n return failedJobs.length;\n }\n\n public async searchJobs(\n filter: Record<string, unknown>,\n ): Promise<IgniterJobSearchResult[]> {\n const queueName = filter.queue as string | undefined;\n const statuses = filter.status as IgniterJobStatus[] | undefined;\n const limit = (filter.limit as number | undefined) ?? 100;\n const offset = (filter.offset as number | undefined) ?? 0;\n\n const queueNames = queueName ? [queueName] : await this.getAllQueueNames();\n const mappedStates = statuses?.flatMap((status) =>\n this.toBunqueueStates(status),\n );\n const results: IgniterJobSearchResult[] = [];\n\n for (const currentQueue of queueNames) {\n const queueClient = await this.getQueue(currentQueue);\n const jobs = await queueClient.getJobsAsync({\n state: mappedStates,\n start: 0,\n end: offset + limit - 1,\n });\n\n for (const job of jobs) {\n results.push(\n await this.mapJob(job as BunqueueJob<JobsEnvelope>, currentQueue),\n );\n }\n }\n\n return results.slice(offset, offset + limit);\n }\n\n public async searchQueues(\n filter: Record<string, unknown>,\n ): Promise<IgniterJobsQueueInfo[]> {\n const queues = await this.listQueues();\n const name = filter.name as string | undefined;\n const isPaused = filter.isPaused as boolean | undefined;\n\n return queues\n .filter((queue) => (name ? queue.name.includes(name) : true))\n .filter((queue) =>\n typeof isPaused === \"boolean\" ? queue.isPaused === isPaused : true,\n );\n }\n\n public async searchWorkers(\n filter: Record<string, unknown>,\n ): Promise<IgniterJobsWorkerHandle[]> {\n const queue = filter.queue as string | undefined;\n const isRunning = filter.isRunning as boolean | undefined;\n\n return Array.from(this.workers.values())\n .filter((worker) => (queue ? worker.queues.includes(queue) : true))\n .filter((worker) =>\n typeof isRunning === \"boolean\"\n ? isRunning\n ? !worker.closed && !worker.paused\n : worker.closed || worker.paused\n : true,\n )\n .map((worker) => this.toWorkerHandle(worker));\n }\n\n public async createWorker(\n config: IgniterJobsWorkerBuilderConfig,\n ): Promise<IgniterJobsWorkerHandle> {\n const bunqueue = await this.loadBunqueue();\n const queueNames = config.queues.length\n ? config.queues\n : await this.getAllQueueNames();\n\n const workerId = IgniterJobsIdGenerator.generate(\"worker\");\n const workerState: WorkerState = {\n id: workerId,\n queues: [...queueNames],\n concurrency: config.concurrency ?? 1,\n paused: false,\n closed: false,\n startedAt: new Date(),\n activeJobs: new Set<string>(),\n metrics: { processed: 0, failed: 0, totalDuration: 0 },\n workers: new Map(),\n handlers: config.handlers,\n };\n\n const perQueueConcurrency = this.distributeConcurrency(\n workerState.concurrency,\n queueNames,\n );\n\n for (const queueName of queueNames) {\n await this.getQueue(queueName);\n await this.syncCronSchedulers(queueName);\n\n const worker = new bunqueue.Worker<JobsEnvelope, unknown>(\n queueName,\n async (job) => this.processJob(workerState, queueName, job),\n {\n embedded: true,\n dataPath: this.options.path,\n autorun: false,\n concurrency: perQueueConcurrency.get(queueName) ?? 1,\n heartbeatInterval: this.options.heartbeatInterval,\n batchSize: this.options.batchSize,\n pollTimeout: this.options.pollTimeout,\n lockDuration: this.options.lockDuration,\n maxStalledCount: this.options.maxStalledCount,\n limiter: config.limiter\n ? { max: config.limiter.max, duration: config.limiter.duration }\n : undefined,\n },\n );\n\n this.attachWorkerEvents(workerState, queueName, worker);\n worker.run();\n workerState.workers.set(queueName, worker);\n }\n\n this.workers.set(workerId, workerState);\n return this.toWorkerHandle(workerState);\n }\n\n public getWorkers(): Map<string, IgniterJobsWorkerHandle> {\n return new Map(\n Array.from(this.workers.entries()).map(([id, worker]) => [\n id,\n this.toWorkerHandle(worker),\n ]),\n );\n }\n\n public async publishEvent(channel: string, payload: unknown): Promise<void> {\n const handlers = this.subscribers.get(channel);\n if (!handlers) return;\n\n await Promise.all(\n Array.from(handlers).map(async (handler) => handler(payload as never)),\n );\n }\n\n public async subscribeEvent(\n channel: string,\n handler: IgniterJobsEventHandler,\n ): Promise<() => Promise<void>> {\n const handlers =\n this.subscribers.get(channel) ?? new Set<IgniterJobsEventHandler>();\n handlers.add(handler);\n this.subscribers.set(channel, handlers);\n\n return async () => {\n const current = this.subscribers.get(channel);\n if (!current) return;\n current.delete(handler);\n if (current.size === 0) this.subscribers.delete(channel);\n };\n }\n\n public async writeJobStreamEvent(\n params: IgniterJobsAdapterJobStreamWriteParams,\n ): Promise<string> {\n const key = this.getStreamKey(params.queue, params.jobId);\n let eventId = String(Date.now());\n\n if (params.persistence?.enabled) {\n const db = await this.getStreamDatabase();\n const result = db\n .prepare(\n `\n INSERT INTO igniter_jobs_stream_events (\n queue, job_id, job_name, type, data, timestamp, scope\n ) VALUES (?, ?, ?, ?, ?, ?, ?)\n `,\n )\n .run(\n params.queue,\n params.jobId,\n params.jobName,\n params.event.type,\n JSON.stringify(params.event.data),\n params.event.timestamp.toISOString(),\n params.scope ? JSON.stringify(params.scope) : null,\n );\n\n eventId = String(result.lastInsertRowid);\n\n const maxEvents = params.persistence.maxEvents;\n if (typeof maxEvents === \"number\" && maxEvents > 0) {\n db.prepare(\n `\n DELETE FROM igniter_jobs_stream_events\n WHERE id IN (\n SELECT id FROM igniter_jobs_stream_events\n WHERE queue = ? AND job_id = ?\n ORDER BY id DESC\n LIMIT -1 OFFSET ?\n )\n `,\n ).run(params.queue, params.jobId, maxEvents);\n }\n }\n\n const event: IgniterJobsJobStreamEvent<string, unknown> = {\n ...params.event,\n id: eventId,\n };\n\n const handlers = this.streamSubscribers.get(key);\n if (handlers?.size) {\n await Promise.all(\n Array.from(handlers).map(async (handler) => handler(event)),\n );\n }\n\n return eventId;\n }\n\n public async readJobStream(\n params: IgniterJobsAdapterJobStreamReadParams,\n ): Promise<\n IgniterJobsJobStreamReadResult<IgniterJobsJobStreamEvent<string, unknown>>\n > {\n const db = await this.getStreamDatabase();\n const after = params.after ? Number(params.after) : 0;\n const limit = params.limit ?? 100;\n const rows = db\n .prepare<{\n id: number;\n type: string;\n data: string;\n timestamp: string;\n job_id: string;\n job_name: string;\n queue: string;\n scope: string | null;\n }>(\n `\n SELECT id, type, data, timestamp, job_id, job_name, queue, scope\n FROM igniter_jobs_stream_events\n WHERE queue = ? AND job_id = ? AND id > ?\n ORDER BY id ASC\n LIMIT ?\n `,\n )\n .all(params.queue, params.jobId, after, limit + 1);\n\n const hasMore = rows.length > limit;\n const items = rows.slice(0, limit).map((row) => this.mapStreamRow(row));\n return {\n items,\n nextCursor: items.at(-1)?.id,\n hasMore,\n };\n }\n\n public async subscribeJobStream(\n params: IgniterJobsAdapterJobStreamSubscribeParams,\n ): Promise<() => Promise<void>> {\n const key = this.getStreamKey(params.queue, params.jobId);\n const set = this.streamSubscribers.get(key) ?? new Set();\n set.add(params.handler);\n this.streamSubscribers.set(key, set);\n\n return async () => {\n const current = this.streamSubscribers.get(key);\n if (!current) return;\n current.delete(params.handler);\n if (current.size === 0) this.streamSubscribers.delete(key);\n };\n }\n\n public async shutdown(): Promise<void> {\n for (const worker of this.workers.values()) {\n await this.closeWorkerState(worker);\n }\n this.workers.clear();\n\n for (const runtime of this.queueRuntimes.values()) {\n runtime.queue.close();\n }\n this.queueRuntimes.clear();\n this.subscribers.clear();\n this.streamSubscribers.clear();\n\n if (this.streamDatabasePromise) {\n const db = await this.streamDatabasePromise;\n db.close();\n this.streamDatabasePromise = null;\n }\n\n if (this.bunqueueModulePromise) {\n const bunqueue = await this.bunqueueModulePromise;\n bunqueue.shutdownManager();\n }\n }\n\n private async loadBunqueue(): Promise<BunqueueClientModule> {\n if (typeof (globalThis as { Bun?: unknown }).Bun === \"undefined\") {\n throw new IgniterJobsError({\n code: \"JOBS_ADAPTER_ERROR\",\n message:\n \"The Bun SQLite adapter can only run inside Bun. Use the BullMQ adapter in Node.js runtimes.\",\n });\n }\n\n this.bunqueueModulePromise ??= import(\"bunqueue/client\");\n return this.bunqueueModulePromise;\n }\n\n private async getStreamDatabase(): Promise<SQLiteDatabase> {\n this.streamDatabasePromise ??= (async () => {\n await mkdir(dirname(this.options.path), { recursive: true });\n const sqlite = await import(\"bun:sqlite\");\n const db = new sqlite.Database(this.options.path, {\n create: true,\n }) as SQLiteDatabase;\n\n db.exec(`\n CREATE TABLE IF NOT EXISTS igniter_jobs_stream_events (\n id INTEGER PRIMARY KEY AUTOINCREMENT,\n queue TEXT NOT NULL,\n job_id TEXT NOT NULL,\n job_name TEXT NOT NULL,\n type TEXT NOT NULL,\n data TEXT NOT NULL,\n timestamp TEXT NOT NULL,\n scope TEXT\n );\n CREATE INDEX IF NOT EXISTS idx_igniter_jobs_stream_events_job\n ON igniter_jobs_stream_events(queue, job_id, id);\n `);\n\n return db;\n })();\n\n return this.streamDatabasePromise;\n }\n\n private async getQueue(\n queueName: string,\n ): Promise<BunqueueQueue<JobsEnvelope>> {\n const existing = this.queueRuntimes.get(queueName);\n if (existing) return existing.queue;\n\n const bunqueue = await this.loadBunqueue();\n await mkdir(dirname(this.options.path), { recursive: true });\n const queue = new bunqueue.Queue<JobsEnvelope>(queueName, {\n embedded: true,\n dataPath: this.options.path,\n defaultJobOptions: {\n durable: this.options.durable,\n },\n });\n\n await queue.waitUntilReady();\n this.queueRuntimes.set(queueName, { queue, cronsSynced: false });\n return queue;\n }\n\n private async getAllQueueNames(): Promise<string[]> {\n return Array.from(\n new Set([\n ...this.registeredJobs.keys(),\n ...this.registeredCrons.keys(),\n ...this.queueRuntimes.keys(),\n ]),\n );\n }\n\n private markQueueCronsDirty(queueName: string): void {\n const runtime = this.queueRuntimes.get(queueName);\n if (runtime) runtime.cronsSynced = false;\n }\n\n private async syncCronSchedulers(queueName: string): Promise<void> {\n const runtime = this.queueRuntimes.get(queueName);\n if (!runtime || runtime.cronsSynced) return;\n\n const cronDefinitions = this.registeredCrons.get(queueName) ?? new Map();\n const existing = await runtime.queue.getJobSchedulers(0, 10_000);\n const existingIds = new Set(existing.map((scheduler) => scheduler.id));\n\n for (const [cronName, definition] of cronDefinitions.entries()) {\n await runtime.queue.upsertJobScheduler(\n cronName,\n {\n pattern: definition.cron,\n limit: definition.maxExecutions,\n timezone: definition.tz,\n },\n {\n name: cronName,\n data: this.createEnvelope(\n undefined,\n undefined,\n undefined,\n definition,\n ),\n opts: { durable: this.options.durable },\n },\n );\n existingIds.delete(cronName);\n }\n\n for (const schedulerId of existingIds) {\n await runtime.queue.removeJobScheduler(schedulerId);\n }\n\n runtime.cronsSynced = true;\n }\n\n private createEnvelope(\n input?: unknown,\n metadata?: Record<string, unknown>,\n scope?: IgniterJobsScopeEntry,\n scheduleSource?:\n | IgniterJobsAdapterScheduleParams\n | IgniterCronDefinition<any, any>,\n ): JobsEnvelope {\n return {\n __igniterJobs: true,\n input,\n metadata,\n scope,\n schedule: scheduleSource\n ? {\n skipWeekends: scheduleSource.skipWeekends,\n onlyBusinessHours: scheduleSource.onlyBusinessHours,\n businessHours: scheduleSource.businessHours,\n onlyWeekdays: scheduleSource.onlyWeekdays,\n skipDates: scheduleSource.skipDates?.map((value) =>\n value instanceof Date ? value.toISOString() : value,\n ),\n }\n : undefined,\n };\n }\n\n private toJobOptions(\n params: IgniterJobsAdapterDispatchParams | IgniterJobsAdapterScheduleParams,\n overrides?: Partial<BunqueueJobOptions>,\n ): BunqueueJobOptions {\n return {\n jobId: params.jobId,\n priority: params.priority,\n delay: params.delay,\n attempts: params.attempts,\n removeOnComplete: params.removeOnComplete,\n removeOnFail: params.removeOnFail,\n durable: this.options.durable,\n ...overrides,\n };\n }\n\n private async processJob(\n workerState: WorkerState,\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n ): Promise<unknown> {\n const envelope = this.normalizeEnvelope(job.data);\n\n if (!this.shouldExecuteScheduledJob(envelope.schedule, new Date())) {\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n \"Scheduled run skipped by adapter rules.\",\n );\n return { skipped: true };\n }\n\n const registeredJob = this.registeredJobs.get(queueName)?.get(job.name);\n if (registeredJob) {\n return this.processRegisteredDefinition(\n workerState,\n queueName,\n job,\n envelope,\n registeredJob,\n );\n }\n\n const registeredCron = this.registeredCrons.get(queueName)?.get(job.name);\n if (registeredCron) {\n return this.processRegisteredCron(\n queueName,\n job,\n envelope,\n registeredCron,\n );\n }\n\n throw new IgniterJobsError({\n code: \"JOBS_NOT_REGISTERED\",\n message: `Job \"${job.name}\" is not registered for queue \"${queueName}\".`,\n });\n }\n\n private async processRegisteredDefinition(\n workerState: WorkerState,\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n envelope: JobsEnvelope,\n definition: IgniterJobDefinition<any, any, any>,\n ): Promise<unknown> {\n const baseContext = this.createExecutionContext(\n queueName,\n job,\n envelope,\n definition,\n );\n const startedAt = new Date();\n\n await this.writeLog(queueName, job.id, \"info\", \"Job started.\");\n await this.invokeHook(() =>\n definition.onStart?.({ ...baseContext, startedAt } as never),\n );\n\n try {\n const result = await definition.handler(baseContext as never);\n const duration = Date.now() - startedAt.getTime();\n workerState.metrics.processed += 1;\n workerState.metrics.totalDuration += duration;\n\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n `Job completed in ${duration}ms.`,\n );\n await this.invokeHook(() =>\n definition.onSuccess?.({\n ...baseContext,\n startedAt,\n duration,\n result,\n } as never),\n );\n\n return result;\n } catch (error) {\n const runtimeError =\n error instanceof Error ? error : new Error(String(error));\n const duration = Date.now() - startedAt.getTime();\n const maxAttempts = definition.attempts ?? job.opts.attempts ?? 1;\n const isFinalAttempt = job.attemptsMade >= maxAttempts;\n workerState.metrics.failed += 1;\n\n await this.writeLog(queueName, job.id, \"error\", runtimeError.message);\n await this.invokeHook(() =>\n definition.onFailure?.({\n ...baseContext,\n startedAt,\n duration,\n error: runtimeError,\n isFinalAttempt,\n } as never),\n );\n\n throw runtimeError;\n }\n }\n\n private async processRegisteredCron(\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n envelope: JobsEnvelope,\n definition: IgniterCronDefinition<any, any>,\n ): Promise<unknown> {\n await this.writeLog(queueName, job.id, \"info\", \"Cron execution started.\");\n\n try {\n const result = await definition.handler({\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: queueName,\n attemptsMade: job.attemptsMade,\n createdAt: new Date(job.timestamp),\n metadata: envelope.metadata,\n },\n scope: envelope.scope,\n } as never);\n\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n \"Cron execution completed.\",\n );\n return result;\n } catch (error) {\n const runtimeError =\n error instanceof Error ? error : new Error(String(error));\n await this.writeLog(queueName, job.id, \"error\", runtimeError.message);\n throw runtimeError;\n }\n }\n\n private createExecutionContext(\n queueName: string,\n job: BunqueueJob<JobsEnvelope>,\n envelope: JobsEnvelope,\n definition: IgniterJobDefinition<any, any, any>,\n ) {\n const baseContext = {\n input: envelope.input,\n context: {},\n job: {\n id: job.id,\n name: job.name,\n queue: queueName,\n attemptsMade: job.attemptsMade,\n createdAt: new Date(job.timestamp),\n metadata: envelope.metadata,\n updateProgress: async (progress: number, message?: string) => {\n await job.updateProgress(progress, message);\n await this.writeLog(\n queueName,\n job.id,\n \"info\",\n `Progress updated to ${progress}%.`,\n );\n await this.invokeHook(() =>\n definition.onProgress?.({\n ...baseContext,\n progress,\n message,\n } as never),\n );\n },\n },\n scope: envelope.scope,\n };\n\n return baseContext;\n }\n\n private attachWorkerEvents(\n workerState: WorkerState,\n queueName: string,\n worker: BunqueueWorker<JobsEnvelope, unknown>,\n ): void {\n worker.on(\"active\", async (job) => {\n workerState.activeJobs.add(job.id);\n await this.invokeHandler(() =>\n workerState.handlers?.onActive?.({\n job: this.mapJobSync(job, queueName),\n }),\n );\n });\n\n worker.on(\"completed\", async (job, result) => {\n workerState.activeJobs.delete(job.id);\n await this.invokeHandler(() =>\n workerState.handlers?.onSuccess?.({\n job: this.mapJobSync(job, queueName, \"completed\"),\n result,\n }),\n );\n });\n\n worker.on(\"failed\", async (job, error) => {\n workerState.activeJobs.delete(job.id);\n await this.invokeHandler(() =>\n workerState.handlers?.onFailure?.({\n job: this.mapJobSync(job, queueName, \"failed\"),\n error,\n }),\n );\n });\n\n worker.on(\"drained\", async () => {\n if (workerState.activeJobs.size === 0) {\n await this.invokeHandler(() => workerState.handlers?.onIdle?.());\n }\n });\n\n worker.on(\"error\", async (error) => {\n await this.writeQueueLog(\n queueName,\n \"error\",\n `Worker error: ${error.message}`,\n );\n });\n }\n\n private toWorkerHandle(worker: WorkerState): IgniterJobsWorkerHandle {\n return {\n id: worker.id,\n queues: [...worker.queues],\n pause: async () => {\n worker.paused = true;\n for (const runtime of worker.workers.values()) runtime.pause();\n },\n resume: async () => {\n worker.paused = false;\n for (const runtime of worker.workers.values()) runtime.resume();\n },\n close: async () => {\n await this.closeWorkerState(worker);\n },\n isRunning: () => !worker.closed && !worker.paused,\n isPaused: () => worker.paused,\n isClosed: () => worker.closed,\n getMetrics: async () => this.buildWorkerMetrics(worker),\n };\n }\n\n private buildWorkerMetrics(worker: WorkerState): IgniterJobsWorkerMetrics {\n return {\n processed: worker.metrics.processed,\n failed: worker.metrics.failed,\n avgDuration:\n worker.metrics.processed > 0\n ? worker.metrics.totalDuration / worker.metrics.processed\n : 0,\n concurrency: worker.concurrency,\n uptime: Date.now() - worker.startedAt.getTime(),\n };\n }\n\n private async closeWorkerState(worker: WorkerState): Promise<void> {\n worker.closed = true;\n await Promise.all(\n Array.from(worker.workers.values()).map((runtime) => runtime.close()),\n );\n worker.workers.clear();\n }\n\n private async requireJob(\n jobId: string,\n queue?: string,\n ): Promise<BunqueueJob<JobsEnvelope>> {\n const queueName = queue ?? (await this.findQueueByJobId(jobId));\n if (!queueName) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found.`,\n });\n }\n\n const job = await this.getQueue(queueName).then((queueClient) =>\n queueClient.getJob(jobId),\n );\n if (!job) {\n throw new IgniterJobsError({\n code: \"JOBS_NOT_FOUND\",\n message: `Job \"${jobId}\" not found${queue ? ` in queue \"${queue}\"` : \"\"}.`,\n });\n }\n\n return job;\n }\n\n private async findQueueByJobId(jobId: string): Promise<string | null> {\n for (const queueName of await this.getAllQueueNames()) {\n const job = await this.getQueue(queueName).then((queueClient) =>\n queueClient.getJob(jobId),\n );\n if (job) return queueName;\n }\n return null;\n }\n\n private getStreamKey(queue: string, jobId: string): string {\n return `${queue}:${jobId}`;\n }\n\n private mapStreamRow(row: {\n id: number;\n type: string;\n data: string;\n timestamp: string;\n job_id: string;\n job_name: string;\n queue: string;\n scope: string | null;\n }): IgniterJobsJobStreamEvent<string, unknown> {\n return {\n id: String(row.id),\n type: row.type,\n data: JSON.parse(row.data),\n timestamp: new Date(row.timestamp),\n jobId: row.job_id,\n jobName: row.job_name,\n queue: row.queue,\n scope: row.scope ? JSON.parse(row.scope) : undefined,\n };\n }\n\n private async mapJob(\n job: BunqueueJob<JobsEnvelope>,\n queueName: string,\n forcedState?: IgniterJobStatus,\n ): Promise<IgniterJobSearchResult> {\n const queue = await this.getQueue(queueName);\n const rawState = await job.getState();\n return this.mapJobSync(\n job,\n queueName,\n forcedState ?? this.toPublicStatus(rawState, queue.isPaused()),\n );\n }\n\n private mapJobSync(\n job: BunqueueJob<JobsEnvelope>,\n queueName: string,\n status?: IgniterJobStatus,\n ): IgniterJobSearchResult {\n const envelope = this.normalizeEnvelope(job.data);\n\n return {\n id: job.id,\n name: job.name,\n queue: queueName,\n status: status ?? this.toPublicStatus(\"waiting\", false),\n input: envelope.input,\n result: job.returnvalue,\n error: job.failedReason ?? undefined,\n progress: typeof job.progress === \"number\" ? job.progress : 0,\n attemptsMade: job.attemptsMade,\n priority: job.priority ?? 0,\n createdAt: new Date(job.timestamp),\n startedAt: job.processedOn ? new Date(job.processedOn) : undefined,\n completedAt: job.finishedOn ? new Date(job.finishedOn) : undefined,\n metadata: envelope.metadata,\n scope: envelope.scope,\n };\n }\n\n private normalizeEnvelope(data: JobsEnvelope | unknown): JobsEnvelope {\n if (\n data &&\n typeof data === \"object\" &&\n (data as JobsEnvelope).__igniterJobs === true\n ) {\n return data as JobsEnvelope;\n }\n\n return {\n __igniterJobs: true,\n input: data,\n };\n }\n\n private toPublicStatus(\n rawState: string,\n isQueuePaused: boolean,\n ): IgniterJobStatus {\n if (\n (rawState === \"waiting\" || rawState === \"prioritized\") &&\n isQueuePaused\n ) {\n return \"paused\";\n }\n\n switch (rawState) {\n case \"prioritized\":\n case \"waiting-children\":\n return \"waiting\";\n case \"waiting\":\n case \"active\":\n case \"completed\":\n case \"failed\":\n case \"delayed\":\n case \"paused\":\n return rawState;\n default:\n return \"waiting\";\n }\n }\n\n private toBunqueueStatus(status: IgniterJobStatus): string {\n switch (status) {\n case \"waiting\":\n return \"waiting\";\n default:\n return status;\n }\n }\n\n private toBunqueueStates(status: IgniterJobStatus): string[] {\n switch (status) {\n case \"waiting\":\n return [\"waiting\", \"prioritized\"];\n case \"paused\":\n return [\"paused\"];\n default:\n return [status];\n }\n }\n\n private distributeConcurrency(\n total: number,\n queues: string[],\n ): Map<string, number> {\n const result = new Map<string, number>();\n if (queues.length === 0) return result;\n\n const base = Math.max(1, Math.floor(total / queues.length));\n let remainder = Math.max(0, total - base * queues.length);\n\n for (const queue of queues) {\n const value = base + (remainder > 0 ? 1 : 0);\n result.set(queue, value);\n remainder = Math.max(0, remainder - 1);\n }\n\n return result;\n }\n\n private shouldExecuteScheduledJob(\n schedule: JobsEnvelope[\"schedule\"],\n now: Date,\n ): boolean {\n if (!schedule) return true;\n const day = now.getDay();\n const isoDate = now.toISOString().slice(0, 10);\n\n if (schedule.skipWeekends && (day === 0 || day === 6)) return false;\n if (schedule.onlyWeekdays?.length && !schedule.onlyWeekdays.includes(day))\n return false;\n if (schedule.skipDates?.some((value) => value.slice(0, 10) === isoDate))\n return false;\n\n if (schedule.onlyBusinessHours && schedule.businessHours) {\n const hour = now.getHours();\n return (\n hour >= schedule.businessHours.start &&\n hour < schedule.businessHours.end\n );\n }\n\n return true;\n }\n\n private parseLogEntry(entry: string): IgniterJobsJobLog {\n try {\n const parsed = JSON.parse(entry) as StructuredLog;\n if (\n parsed &&\n typeof parsed.message === \"string\" &&\n typeof parsed.timestamp === \"string\" &&\n (parsed.level === \"info\" ||\n parsed.level === \"warn\" ||\n parsed.level === \"error\")\n ) {\n return {\n timestamp: new Date(parsed.timestamp),\n level: parsed.level,\n message: parsed.message,\n };\n }\n } catch {\n // fall back to plain string\n }\n\n return {\n timestamp: new Date(),\n level: \"info\",\n message: entry,\n };\n }\n\n private async writeLog(\n queueName: string,\n jobId: string,\n level: \"info\" | \"warn\" | \"error\",\n message: string,\n ): Promise<void> {\n const queue = await this.getQueue(queueName);\n await queue.addJobLog(\n jobId,\n JSON.stringify({ timestamp: new Date().toISOString(), level, message }),\n );\n }\n\n private async writeQueueLog(\n queueName: string,\n level: \"info\" | \"warn\" | \"error\",\n message: string,\n ): Promise<void> {\n void queueName;\n void level;\n void message;\n }\n\n private async invokeHook(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch {\n // Hooks must not break worker state transitions.\n }\n }\n\n private async invokeHandler(fn: () => Promise<void> | void): Promise<void> {\n try {\n await fn();\n } catch {\n // Worker observers are isolated from backend processing.\n }\n }\n}\n\nexport type { IgniterJobsBunSQLiteAdapterOptions };\n"]}
@@ -1,4 +1,4 @@
1
- import { a as IgniterJobsAdapter, H as IgniterJobsQueueManager, c as IgniterJobDefinition, q as IgniterCronDefinition, v as IgniterJobsAdapterDispatchParams, w as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, m as IgniterJobStatus, F as IgniterJobsJobLog, h as IgniterJobsQueueInfo, u as IgniterJobCounts, l as IgniterJobsQueueCleanOptions, i as IgniterJobsWorkerHandle, d as IgniterJobsWorkerBuilderConfig, f as IgniterJobsEventHandler } from '../adapter-Cax_40HW.mjs';
1
+ import { a as IgniterJobsAdapter, X as IgniterJobsQueueManager, c as IgniterJobDefinition, r as IgniterCronDefinition, x as IgniterJobsAdapterDispatchParams, B as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, m as IgniterJobStatus, Q as IgniterJobsJobLog, h as IgniterJobsQueueInfo, w as IgniterJobCounts, l as IgniterJobsQueueCleanOptions, i as IgniterJobsWorkerHandle, d as IgniterJobsWorkerBuilderConfig, f as IgniterJobsEventHandler, A as IgniterJobsAdapterJobStreamWriteParams, y as IgniterJobsAdapterJobStreamReadParams, V as IgniterJobsJobStreamReadResult, S as IgniterJobsJobStreamEvent, z as IgniterJobsAdapterJobStreamSubscribeParams } from '../adapter-DDyMVche.mjs';
2
2
  import 'ioredis';
3
3
  import '@igniter-js/common';
4
4
 
@@ -21,6 +21,8 @@ declare class IgniterJobsMemoryAdapter implements IgniterJobsAdapter {
21
21
  private readonly registeredJobs;
22
22
  private readonly registeredCrons;
23
23
  private readonly workers;
24
+ private readonly streamRecords;
25
+ private readonly streamSubscribers;
24
26
  private readonly subscribers;
25
27
  readonly queues: IgniterJobsQueueManager;
26
28
  private readonly pausedQueues;
@@ -57,8 +59,12 @@ declare class IgniterJobsMemoryAdapter implements IgniterJobsAdapter {
57
59
  getWorkers(): Map<string, IgniterJobsWorkerHandle>;
58
60
  publishEvent(channel: string, payload: unknown): Promise<void>;
59
61
  subscribeEvent(channel: string, handler: IgniterJobsEventHandler): Promise<() => Promise<void>>;
62
+ writeJobStreamEvent(params: IgniterJobsAdapterJobStreamWriteParams): Promise<string>;
63
+ readJobStream(params: IgniterJobsAdapterJobStreamReadParams): Promise<IgniterJobsJobStreamReadResult<IgniterJobsJobStreamEvent<string, unknown>>>;
64
+ subscribeJobStream(params: IgniterJobsAdapterJobStreamSubscribeParams): Promise<() => Promise<void>>;
60
65
  shutdown(): Promise<void>;
61
66
  private toSearchResult;
67
+ private getStreamKey;
62
68
  private toWorkerHandle;
63
69
  private toWorkerMetrics;
64
70
  private kickWorkers;
@@ -1,4 +1,4 @@
1
- import { a as IgniterJobsAdapter, H as IgniterJobsQueueManager, c as IgniterJobDefinition, q as IgniterCronDefinition, v as IgniterJobsAdapterDispatchParams, w as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, m as IgniterJobStatus, F as IgniterJobsJobLog, h as IgniterJobsQueueInfo, u as IgniterJobCounts, l as IgniterJobsQueueCleanOptions, i as IgniterJobsWorkerHandle, d as IgniterJobsWorkerBuilderConfig, f as IgniterJobsEventHandler } from '../adapter-Cax_40HW.js';
1
+ import { a as IgniterJobsAdapter, X as IgniterJobsQueueManager, c as IgniterJobDefinition, r as IgniterCronDefinition, x as IgniterJobsAdapterDispatchParams, B as IgniterJobsAdapterScheduleParams, g as IgniterJobSearchResult, m as IgniterJobStatus, Q as IgniterJobsJobLog, h as IgniterJobsQueueInfo, w as IgniterJobCounts, l as IgniterJobsQueueCleanOptions, i as IgniterJobsWorkerHandle, d as IgniterJobsWorkerBuilderConfig, f as IgniterJobsEventHandler, A as IgniterJobsAdapterJobStreamWriteParams, y as IgniterJobsAdapterJobStreamReadParams, V as IgniterJobsJobStreamReadResult, S as IgniterJobsJobStreamEvent, z as IgniterJobsAdapterJobStreamSubscribeParams } from '../adapter-DDyMVche.js';
2
2
  import 'ioredis';
3
3
  import '@igniter-js/common';
4
4
 
@@ -21,6 +21,8 @@ declare class IgniterJobsMemoryAdapter implements IgniterJobsAdapter {
21
21
  private readonly registeredJobs;
22
22
  private readonly registeredCrons;
23
23
  private readonly workers;
24
+ private readonly streamRecords;
25
+ private readonly streamSubscribers;
24
26
  private readonly subscribers;
25
27
  readonly queues: IgniterJobsQueueManager;
26
28
  private readonly pausedQueues;
@@ -57,8 +59,12 @@ declare class IgniterJobsMemoryAdapter implements IgniterJobsAdapter {
57
59
  getWorkers(): Map<string, IgniterJobsWorkerHandle>;
58
60
  publishEvent(channel: string, payload: unknown): Promise<void>;
59
61
  subscribeEvent(channel: string, handler: IgniterJobsEventHandler): Promise<() => Promise<void>>;
62
+ writeJobStreamEvent(params: IgniterJobsAdapterJobStreamWriteParams): Promise<string>;
63
+ readJobStream(params: IgniterJobsAdapterJobStreamReadParams): Promise<IgniterJobsJobStreamReadResult<IgniterJobsJobStreamEvent<string, unknown>>>;
64
+ subscribeJobStream(params: IgniterJobsAdapterJobStreamSubscribeParams): Promise<() => Promise<void>>;
60
65
  shutdown(): Promise<void>;
61
66
  private toSearchResult;
67
+ private getStreamKey;
62
68
  private toWorkerHandle;
63
69
  private toWorkerMetrics;
64
70
  private kickWorkers;