@bymax-one/nest-queue 1.0.11 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,37 @@ versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.2.0] — 2026-08-10
11
+
12
+ **Breaking, shipped as a minor by choice.** The peer ranges move to the next major of each
13
+ Redis/BullMQ package and the `'paused'` job state is removed from the public status surface —
14
+ changes that would normally warrant a major. They ship under a minor because the package has no
15
+ downstream consumer yet; every breaking detail is called out below so a first adopter sees it.
16
+
17
+ ### Changed
18
+
19
+ - **Peer dependencies migrated to the next major:** `bullmq` `^5` → `^6`, `bullmq-otel` `^1` →
20
+ `^2`, and `ioredis` `^5` → `^6`. A consumer must upgrade all three together. `ioredis` 6 keeps
21
+ `'legacy'` reply mapping by default, so BullMQ's reply-shape assumptions are unaffected; it does
22
+ require Node.js ≥ 20, already covered by this package's `engines`.
23
+
24
+ ### Removed
25
+
26
+ - **`'paused'` is no longer a job status.** BullMQ 6 dropped `'paused'` from its job-state set —
27
+ jobs on a paused queue now live in `'wait'`. It is therefore removed from the `JobStatus` union,
28
+ from the `JOB_STATUS` constant (`JOB_STATUS.PAUSED` no longer exists), and from the
29
+ `getMetrics().counts` shape, which now reports the five remaining statuses (`waiting`, `active`,
30
+ `completed`, `failed`, `delayed`). The queue-lifecycle `'paused'`/`'resumed'` **events**
31
+ (`@OnQueueEvent`) and the `pauseQueue`/`resumeQueue` methods are unchanged — those describe the
32
+ queue, not a job.
33
+
34
+ ### Internal
35
+
36
+ - Dev-tooling bumps: `eslint` `^10`, `typescript` `^6`, `@types/node` `^26`, plus `@eslint/js`
37
+ `^10`. These do not ship and do not change `dist/`. The package's `engines` stays at Node ≥ 24.
38
+ - Mutation gate tightened: Stryker `break`/`high` raised from 95/99 → **100** (the run is at 100%,
39
+ 0 survivors).
40
+
10
41
  ## [1.0.11] — 2026-08-10
11
42
 
12
43
  **Documentation only.** The shipped declaration comments change (`dts` preserves them); no runtime
@@ -456,6 +487,7 @@ v6 peer range.
456
487
 
457
488
  ---
458
489
 
490
+ [1.2.0]: https://github.com/bymaxone/nest-queue/compare/v1.0.11...v1.2.0
459
491
  [1.0.11]: https://github.com/bymaxone/nest-queue/compare/v1.0.10...v1.0.11
460
492
  [1.0.10]: https://github.com/bymaxone/nest-queue/compare/v1.0.9...v1.0.10
461
493
  [1.0.9]: https://github.com/bymaxone/nest-queue/compare/v1.0.8...v1.0.9
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
 
7
7
  <p align="center">
8
8
  <strong>Typed BullMQ queues for NestJS</strong><br />
9
- <sub>BullMQ 5 · Workers · Flows · Job Schedulers · Deduplication · OpenTelemetry · Graceful Shutdown · Zero Runtime Dependencies</sub>
9
+ <sub>BullMQ 6 · Workers · Flows · Job Schedulers · Deduplication · OpenTelemetry · Graceful Shutdown · Zero Runtime Dependencies</sub>
10
10
  </p>
11
11
 
12
12
  <p align="center">
@@ -33,7 +33,7 @@
33
33
 
34
34
  ## ✨ Overview
35
35
 
36
- `@bymax-one/nest-queue` is a NestJS dynamic module that wraps **BullMQ 5** behind a typed,
36
+ `@bymax-one/nest-queue` is a NestJS dynamic module that wraps **BullMQ 6** behind a typed,
37
37
  opinionated surface. Instead of wiring `ioredis` connections, per-queue registration, and
38
38
  `maxRetriesPerRequest` policy by hand, you install one library and get typed producers,
39
39
  decorator-based workers, flows, recurring **Job Schedulers**, native deduplication,
@@ -114,11 +114,11 @@ Both subpaths ship ESM **and** CommonJS with declarations for each format, so a
114
114
 
115
115
  ### Peer dependency matrix
116
116
 
117
- | Subpath | Required peers |
118
- | ------------ | --------------------------------------------------------------------------------------------------------- |
119
- | `.` (server) | `@nestjs/common ^11.0.16`, `@nestjs/core ^11.1.18`, `bullmq ^5.16`, `ioredis ^5`, `reflect-metadata ^0.2` |
120
- | `./shared` | None |
121
- | Optional | `bullmq-otel ^1` (OpenTelemetry) |
117
+ | Subpath | Required peers |
118
+ | ------------ | ---------------------------------------------------------------------------------------------------------- |
119
+ | `.` (server) | `@nestjs/common ^11.0.16`, `@nestjs/core ^11.1.18`, `bullmq ^6.0`, `ioredis ^6.0`, `reflect-metadata ^0.2` |
120
+ | `./shared` | None |
121
+ | Optional | `bullmq-otel ^2` (OpenTelemetry) |
122
122
 
123
123
  > [!IMPORTANT]
124
124
  > `reflect-metadata` is a **global polyfill the application owns** — import it once at
@@ -785,11 +785,11 @@ key will do it twice at some point.
785
785
 
786
786
  - **Runtime:** Node.js 24+
787
787
  - **Framework:** NestJS 11 (`ConfigurableModuleBuilder` + `setExtras`)
788
- - **Queue engine:** BullMQ `^5.16` (peer) over `ioredis ^5` (peer)
789
- - **Telemetry:** `bullmq-otel ^1` (optional peer)
788
+ - **Queue engine:** BullMQ `^6.0` (peer) over `ioredis ^6.0` (peer)
789
+ - **Telemetry:** `bullmq-otel ^2` (optional peer)
790
790
  - **Build:** tsup — ESM + CJS per subpath, with `.d.ts` _and_ `.d.cts` declarations
791
791
  - **Tests:** Jest + `@testcontainers/redis` (E2E) + Stryker (mutation)
792
- - **TypeScript:** 5.x strict (`noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`), zero `any`
792
+ - **TypeScript:** 6.x strict (`noUncheckedIndexedAccess`, `exactOptionalPropertyTypes`), zero `any`
793
793
 
794
794
  ---
795
795
 
@@ -884,9 +884,9 @@ do not pick them up:
884
884
 
885
885
  - **NestJS only** — does not work with plain Express, standalone Fastify, or other frameworks.
886
886
  - **Node.js only** — Deno and Bun are not supported.
887
- - **BullMQ `^5.16` (1.x floor)** — v6 promotion is planned once the E2E suite is
888
- green on the v5 + v6 matrix; see the BullMQ version policy in
889
- [`CHANGELOG.md`](CHANGELOG.md).
887
+ - **BullMQ `^6.0` only** — the library targets BullMQ 6 (with `bullmq-otel ^2` for telemetry)
888
+ and does not support BullMQ 5; the `'paused'` job state that v6 removed is no longer exposed.
889
+ See the BullMQ version policy in [`CHANGELOG.md`](CHANGELOG.md).
890
890
  - **No Redis Cluster sharding** — BullMQ's cluster support is not exercised by this library.
891
891
  - **No built-in DLQ helper** — use the `@OnWorkerEvent('failed')` pattern above.
892
892
  - **No Prometheus metrics export** — `getMetrics()` returns snapshots; publish them
@@ -198,11 +198,22 @@ exports.ConnectionResolver = class ConnectionResolver {
198
198
  return;
199
199
  }
200
200
  this.mode = "mode-b-owned";
201
- __privateSet(this, _client, "url" in cfg ? new ioredis.Redis(cfg.url, { ...cfg.options ?? {}, lazyConnect: false }) : new ioredis.Redis({ ...cfg.options, lazyConnect: false }));
201
+ __privateSet(this, _client, "url" in cfg ? new ioredis.Redis(cfg.url, this.ownedOptions(cfg.options)) : new ioredis.Redis(this.ownedOptions(cfg.options)));
202
202
  await this.waitReady(
203
203
  __privateGet(this, _options).connectionReadyTimeoutMs ?? DEFAULT_CONNECTION_READY_TIMEOUT_MS
204
204
  );
205
205
  }
206
+ /**
207
+ * Merge the consumer's options with the owned-connection policy
208
+ * (`lazyConnect: false`, so the client connects eagerly and `init` can wait
209
+ * for `ready`) and narrow the result to the shape ioredis 6's constructor
210
+ * accepts. The runtime object is unchanged — the cast only drops the
211
+ * `undefined` that `RedisOptions.replyMapping` carries and the constructor
212
+ * rejects.
213
+ */
214
+ ownedOptions(options) {
215
+ return { ...options ?? {}, lazyConnect: false };
216
+ }
206
217
  /** The resolved Queue-role client. */
207
218
  getClient() {
208
219
  if (!__privateGet(this, _client)) {
@@ -471,8 +482,7 @@ exports.QueueService = class QueueService {
471
482
  "active",
472
483
  "completed",
473
484
  "failed",
474
- "delayed",
475
- "paused"
485
+ "delayed"
476
486
  );
477
487
  return {
478
488
  queue: queueName,
@@ -1341,9 +1351,9 @@ QueueLifecycle = __decorateClass([
1341
1351
 
1342
1352
  // src/server/bymax-queue.module.ts
1343
1353
  var { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = (
1344
- // The `moduleName` shapes the generated token's description only — a label read in Nest's DI
1345
- // error output, never compared against anything. Mutation testing reports it as surviving for
1346
- // that reason; no Stryker directive attaches inside this builder chain, so the note lives here.
1354
+ // The `moduleName` shapes the generated option token's identifier — `BYMAX_QUEUE_MODULE_OPTIONS`,
1355
+ // which the module spec asserts by value; emptying the name would degrade it to an opaque
1356
+ // `CONFIGURABLE_MODULE_OPTIONS[<hash>]`, so the argument is a caught regression, not a free label.
1347
1357
  new common.ConfigurableModuleBuilder({ moduleName: "BymaxQueue" }).setClassMethodName("forRoot").setFactoryMethodName("createQueueOptions").setExtras({ isGlobal: true }, (definition, extras) => ({
1348
1358
  ...definition,
1349
1359
  global: extras.isGlobal
@@ -1548,8 +1558,7 @@ var JOB_STATUS = {
1548
1558
  ACTIVE: "active",
1549
1559
  COMPLETED: "completed",
1550
1560
  FAILED: "failed",
1551
- DELAYED: "delayed",
1552
- PAUSED: "paused"
1561
+ DELAYED: "delayed"
1553
1562
  };
1554
1563
 
1555
1564
  exports.BYMAX_QUEUE_CONNECTION_MODE = BYMAX_QUEUE_CONNECTION_MODE;
@@ -269,7 +269,7 @@ interface BulkJob<TData = unknown> {
269
269
  * @example
270
270
  * const status: JobStatus = 'waiting'
271
271
  */
272
- type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'paused';
272
+ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed';
273
273
 
274
274
  /**
275
275
  * @fileoverview Instantaneous queue metrics snapshot type.
@@ -282,14 +282,14 @@ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'pa
282
282
  * @example
283
283
  * const metrics: QueueMetrics = {
284
284
  * queue: 'email',
285
- * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0, paused: 0 },
285
+ * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0 },
286
286
  * collectedAt: '2026-06-26T12:00:00.000Z',
287
287
  * }
288
288
  */
289
289
  interface QueueMetrics {
290
290
  /** Queue name the snapshot was taken from. */
291
291
  queue: string;
292
- /** Number of jobs in each of the six BullMQ statuses. */
292
+ /** Number of jobs in each of the five BullMQ statuses. */
293
293
  counts: Record<JobStatus, number>;
294
294
  /** ISO 8601 UTC timestamp when the snapshot was collected. */
295
295
  collectedAt: string;
@@ -359,6 +359,15 @@ declare class ConnectionResolver {
359
359
  constructor(options: BymaxQueueModuleOptions);
360
360
  /** Resolve and validate the connection. Call once during module bootstrap. */
361
361
  init(): Promise<void>;
362
+ /**
363
+ * Merge the consumer's options with the owned-connection policy
364
+ * (`lazyConnect: false`, so the client connects eagerly and `init` can wait
365
+ * for `ready`) and narrow the result to the shape ioredis 6's constructor
366
+ * accepts. The runtime object is unchanged — the cast only drops the
367
+ * `undefined` that `RedisOptions.replyMapping` carries and the constructor
368
+ * rejects.
369
+ */
370
+ private ownedOptions;
362
371
  /** The resolved Queue-role client. */
363
372
  getClient(): Redis;
364
373
  /** The resolved connection mode. */
@@ -1402,7 +1411,6 @@ declare const JOB_STATUS: {
1402
1411
  readonly COMPLETED: "completed";
1403
1412
  readonly FAILED: "failed";
1404
1413
  readonly DELAYED: "delayed";
1405
- readonly PAUSED: "paused";
1406
1414
  };
1407
1415
 
1408
1416
  export { BYMAX_QUEUE_CONNECTION_MODE, BYMAX_QUEUE_OPTIONS, BYMAX_QUEUE_REDIS_CLIENT, BYMAX_QUEUE_RESOLVED_OPTIONS, type BulkJob, BymaxQueueModule, type BymaxQueueModuleAsyncOptions, type BymaxQueueModuleOptions, type BymaxQueueOptionsFactory, ConnectionResolver, DEFAULT_JOB_OPTIONS, DEFAULT_METRICS_CACHE_TTL_MS, DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS, DEFAULT_WORKER_CONCURRENCY, FlowService, JOB_STATUS, type JobSchedulerRepeatOptions, type JobStatus, MAX_WORKER_CONCURRENCY, MetricsService, OnQueueEvent, OnWorkerEvent, Process, type ProcessHandlerMetadata, Processor, type ProcessorMetadata, type ProgrammaticWorkerConfig, QUEUE_ERROR_CODES, QUEUE_ERROR_MESSAGES, type QueueConnectionConfig, type QueueConnectionMode, type QueueErrorCode, type QueueEventListenerMetadata, type QueueEventName, QueueEventsRegistry, QueueException, QueueLifecycle, type QueueMetrics, QueueService, type SandboxedWorkerConfig, type WorkerEventName, type WorkerOptions, WorkerRegistry };
@@ -269,7 +269,7 @@ interface BulkJob<TData = unknown> {
269
269
  * @example
270
270
  * const status: JobStatus = 'waiting'
271
271
  */
272
- type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'paused';
272
+ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed';
273
273
 
274
274
  /**
275
275
  * @fileoverview Instantaneous queue metrics snapshot type.
@@ -282,14 +282,14 @@ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'pa
282
282
  * @example
283
283
  * const metrics: QueueMetrics = {
284
284
  * queue: 'email',
285
- * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0, paused: 0 },
285
+ * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0 },
286
286
  * collectedAt: '2026-06-26T12:00:00.000Z',
287
287
  * }
288
288
  */
289
289
  interface QueueMetrics {
290
290
  /** Queue name the snapshot was taken from. */
291
291
  queue: string;
292
- /** Number of jobs in each of the six BullMQ statuses. */
292
+ /** Number of jobs in each of the five BullMQ statuses. */
293
293
  counts: Record<JobStatus, number>;
294
294
  /** ISO 8601 UTC timestamp when the snapshot was collected. */
295
295
  collectedAt: string;
@@ -359,6 +359,15 @@ declare class ConnectionResolver {
359
359
  constructor(options: BymaxQueueModuleOptions);
360
360
  /** Resolve and validate the connection. Call once during module bootstrap. */
361
361
  init(): Promise<void>;
362
+ /**
363
+ * Merge the consumer's options with the owned-connection policy
364
+ * (`lazyConnect: false`, so the client connects eagerly and `init` can wait
365
+ * for `ready`) and narrow the result to the shape ioredis 6's constructor
366
+ * accepts. The runtime object is unchanged — the cast only drops the
367
+ * `undefined` that `RedisOptions.replyMapping` carries and the constructor
368
+ * rejects.
369
+ */
370
+ private ownedOptions;
362
371
  /** The resolved Queue-role client. */
363
372
  getClient(): Redis;
364
373
  /** The resolved connection mode. */
@@ -1402,7 +1411,6 @@ declare const JOB_STATUS: {
1402
1411
  readonly COMPLETED: "completed";
1403
1412
  readonly FAILED: "failed";
1404
1413
  readonly DELAYED: "delayed";
1405
- readonly PAUSED: "paused";
1406
1414
  };
1407
1415
 
1408
1416
  export { BYMAX_QUEUE_CONNECTION_MODE, BYMAX_QUEUE_OPTIONS, BYMAX_QUEUE_REDIS_CLIENT, BYMAX_QUEUE_RESOLVED_OPTIONS, type BulkJob, BymaxQueueModule, type BymaxQueueModuleAsyncOptions, type BymaxQueueModuleOptions, type BymaxQueueOptionsFactory, ConnectionResolver, DEFAULT_JOB_OPTIONS, DEFAULT_METRICS_CACHE_TTL_MS, DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS, DEFAULT_WORKER_CONCURRENCY, FlowService, JOB_STATUS, type JobSchedulerRepeatOptions, type JobStatus, MAX_WORKER_CONCURRENCY, MetricsService, OnQueueEvent, OnWorkerEvent, Process, type ProcessHandlerMetadata, Processor, type ProcessorMetadata, type ProgrammaticWorkerConfig, QUEUE_ERROR_CODES, QUEUE_ERROR_MESSAGES, type QueueConnectionConfig, type QueueConnectionMode, type QueueErrorCode, type QueueEventListenerMetadata, type QueueEventName, QueueEventsRegistry, QueueException, QueueLifecycle, type QueueMetrics, QueueService, type SandboxedWorkerConfig, type WorkerEventName, type WorkerOptions, WorkerRegistry };
@@ -196,11 +196,22 @@ var ConnectionResolver = class {
196
196
  return;
197
197
  }
198
198
  this.mode = "mode-b-owned";
199
- __privateSet(this, _client, "url" in cfg ? new Redis(cfg.url, { ...cfg.options ?? {}, lazyConnect: false }) : new Redis({ ...cfg.options, lazyConnect: false }));
199
+ __privateSet(this, _client, "url" in cfg ? new Redis(cfg.url, this.ownedOptions(cfg.options)) : new Redis(this.ownedOptions(cfg.options)));
200
200
  await this.waitReady(
201
201
  __privateGet(this, _options).connectionReadyTimeoutMs ?? DEFAULT_CONNECTION_READY_TIMEOUT_MS
202
202
  );
203
203
  }
204
+ /**
205
+ * Merge the consumer's options with the owned-connection policy
206
+ * (`lazyConnect: false`, so the client connects eagerly and `init` can wait
207
+ * for `ready`) and narrow the result to the shape ioredis 6's constructor
208
+ * accepts. The runtime object is unchanged — the cast only drops the
209
+ * `undefined` that `RedisOptions.replyMapping` carries and the constructor
210
+ * rejects.
211
+ */
212
+ ownedOptions(options) {
213
+ return { ...options ?? {}, lazyConnect: false };
214
+ }
204
215
  /** The resolved Queue-role client. */
205
216
  getClient() {
206
217
  if (!__privateGet(this, _client)) {
@@ -469,8 +480,7 @@ var QueueService = class {
469
480
  "active",
470
481
  "completed",
471
482
  "failed",
472
- "delayed",
473
- "paused"
483
+ "delayed"
474
484
  );
475
485
  return {
476
486
  queue: queueName,
@@ -1339,9 +1349,9 @@ QueueLifecycle = __decorateClass([
1339
1349
 
1340
1350
  // src/server/bymax-queue.module.ts
1341
1351
  var { ConfigurableModuleClass, MODULE_OPTIONS_TOKEN, OPTIONS_TYPE, ASYNC_OPTIONS_TYPE } = (
1342
- // The `moduleName` shapes the generated token's description only — a label read in Nest's DI
1343
- // error output, never compared against anything. Mutation testing reports it as surviving for
1344
- // that reason; no Stryker directive attaches inside this builder chain, so the note lives here.
1352
+ // The `moduleName` shapes the generated option token's identifier — `BYMAX_QUEUE_MODULE_OPTIONS`,
1353
+ // which the module spec asserts by value; emptying the name would degrade it to an opaque
1354
+ // `CONFIGURABLE_MODULE_OPTIONS[<hash>]`, so the argument is a caught regression, not a free label.
1345
1355
  new ConfigurableModuleBuilder({ moduleName: "BymaxQueue" }).setClassMethodName("forRoot").setFactoryMethodName("createQueueOptions").setExtras({ isGlobal: true }, (definition, extras) => ({
1346
1356
  ...definition,
1347
1357
  global: extras.isGlobal
@@ -1546,8 +1556,7 @@ var JOB_STATUS = {
1546
1556
  ACTIVE: "active",
1547
1557
  COMPLETED: "completed",
1548
1558
  FAILED: "failed",
1549
- DELAYED: "delayed",
1550
- PAUSED: "paused"
1559
+ DELAYED: "delayed"
1551
1560
  };
1552
1561
 
1553
1562
  export { BYMAX_QUEUE_CONNECTION_MODE, BYMAX_QUEUE_OPTIONS, BYMAX_QUEUE_REDIS_CLIENT, BYMAX_QUEUE_RESOLVED_OPTIONS, BymaxQueueModule, ConnectionResolver, DEFAULT_JOB_OPTIONS, DEFAULT_METRICS_CACHE_TTL_MS, DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS, DEFAULT_WORKER_CONCURRENCY, FlowService, JOB_STATUS, MAX_WORKER_CONCURRENCY, MetricsService, OnQueueEvent, OnWorkerEvent, Process, Processor, QUEUE_ERROR_CODES, QUEUE_ERROR_MESSAGES, QueueEventsRegistry, QueueException, QueueService, WorkerRegistry };
@@ -6,8 +6,7 @@ var JOB_STATUS = {
6
6
  ACTIVE: "active",
7
7
  COMPLETED: "completed",
8
8
  FAILED: "failed",
9
- DELAYED: "delayed",
10
- PAUSED: "paused"
9
+ DELAYED: "delayed"
11
10
  };
12
11
 
13
12
  // src/shared/constants/error-codes.ts
@@ -9,7 +9,7 @@
9
9
  * @example
10
10
  * const status: JobStatus = 'waiting'
11
11
  */
12
- type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'paused';
12
+ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed';
13
13
 
14
14
  /**
15
15
  * @fileoverview Instantaneous queue metrics snapshot type.
@@ -22,14 +22,14 @@ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'pa
22
22
  * @example
23
23
  * const metrics: QueueMetrics = {
24
24
  * queue: 'email',
25
- * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0, paused: 0 },
25
+ * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0 },
26
26
  * collectedAt: '2026-06-26T12:00:00.000Z',
27
27
  * }
28
28
  */
29
29
  interface QueueMetrics {
30
30
  /** Queue name the snapshot was taken from. */
31
31
  queue: string;
32
- /** Number of jobs in each of the six BullMQ statuses. */
32
+ /** Number of jobs in each of the five BullMQ statuses. */
33
33
  counts: Record<JobStatus, number>;
34
34
  /** ISO 8601 UTC timestamp when the snapshot was collected. */
35
35
  collectedAt: string;
@@ -94,7 +94,6 @@ declare const JOB_STATUS: {
94
94
  readonly COMPLETED: "completed";
95
95
  readonly FAILED: "failed";
96
96
  readonly DELAYED: "delayed";
97
- readonly PAUSED: "paused";
98
97
  };
99
98
 
100
99
  /**
@@ -9,7 +9,7 @@
9
9
  * @example
10
10
  * const status: JobStatus = 'waiting'
11
11
  */
12
- type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'paused';
12
+ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed';
13
13
 
14
14
  /**
15
15
  * @fileoverview Instantaneous queue metrics snapshot type.
@@ -22,14 +22,14 @@ type JobStatus = 'waiting' | 'active' | 'completed' | 'failed' | 'delayed' | 'pa
22
22
  * @example
23
23
  * const metrics: QueueMetrics = {
24
24
  * queue: 'email',
25
- * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0, paused: 0 },
25
+ * counts: { waiting: 3, active: 1, completed: 120, failed: 2, delayed: 0 },
26
26
  * collectedAt: '2026-06-26T12:00:00.000Z',
27
27
  * }
28
28
  */
29
29
  interface QueueMetrics {
30
30
  /** Queue name the snapshot was taken from. */
31
31
  queue: string;
32
- /** Number of jobs in each of the six BullMQ statuses. */
32
+ /** Number of jobs in each of the five BullMQ statuses. */
33
33
  counts: Record<JobStatus, number>;
34
34
  /** ISO 8601 UTC timestamp when the snapshot was collected. */
35
35
  collectedAt: string;
@@ -94,7 +94,6 @@ declare const JOB_STATUS: {
94
94
  readonly COMPLETED: "completed";
95
95
  readonly FAILED: "failed";
96
96
  readonly DELAYED: "delayed";
97
- readonly PAUSED: "paused";
98
97
  };
99
98
 
100
99
  /**
@@ -4,8 +4,7 @@ var JOB_STATUS = {
4
4
  ACTIVE: "active",
5
5
  COMPLETED: "completed",
6
6
  FAILED: "failed",
7
- DELAYED: "delayed",
8
- PAUSED: "paused"
7
+ DELAYED: "delayed"
9
8
  };
10
9
 
11
10
  // src/shared/constants/error-codes.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-queue",
3
- "version": "1.0.11",
3
+ "version": "1.2.0",
4
4
  "description": "NestJS dynamic module wrapping BullMQ — typed jobs, flows, job schedulers, deduplication, OpenTelemetry, graceful shutdown",
5
5
  "author": "Bymax One <support@bymax.one>",
6
6
  "license": "MIT",
@@ -82,9 +82,9 @@
82
82
  "peerDependencies": {
83
83
  "@nestjs/common": "^11.0.16",
84
84
  "@nestjs/core": "^11.1.18",
85
- "bullmq": "^5.16.0",
86
- "bullmq-otel": "^1.0.0",
87
- "ioredis": "^5.0.0",
85
+ "bullmq": "^6.0.0",
86
+ "bullmq-otel": "^2.0.0",
87
+ "ioredis": "^6.0.0",
88
88
  "reflect-metadata": "^0.2.0"
89
89
  },
90
90
  "peerDependenciesMeta": {
@@ -96,20 +96,19 @@
96
96
  "@arethetypeswrong/cli": "^0.18.5",
97
97
  "@commitlint/cli": "^21.2.1",
98
98
  "@commitlint/config-conventional": "^21.2.0",
99
- "@eslint/js": "^9.39.5",
99
+ "@eslint/js": "^10.0.1",
100
100
  "@nestjs/common": "^11.1.28",
101
101
  "@nestjs/core": "^11.1.28",
102
102
  "@nestjs/testing": "^11.1.28",
103
103
  "@stryker-mutator/core": "^9.6.1",
104
104
  "@stryker-mutator/jest-runner": "^9.6.1",
105
105
  "@types/jest": "^30.0.0",
106
- "@types/node": "^24.13.3",
107
- "bullmq": "^5.81.2",
108
- "eslint": "^9.39.5",
106
+ "@types/node": "^26.2.0",
107
+ "bullmq": "^6.0.0",
108
+ "eslint": "^10.8.1",
109
109
  "eslint-config-prettier": "^10.1.8",
110
110
  "husky": "^9.1.7",
111
- "ioredis": "5.11.1",
112
- "ioredis-mock": "^8.9.0",
111
+ "ioredis": "^6.0.0",
113
112
  "jest": "^30.0.0",
114
113
  "jest-environment-node": "^30.4.1",
115
114
  "lint-staged": "^17.2.0",
@@ -119,7 +118,7 @@
119
118
  "testcontainers": "^12.0.4",
120
119
  "ts-jest": "^29.4.12",
121
120
  "tsup": "^8.3.0",
122
- "typescript": "^5.6.0",
121
+ "typescript": "^6.0.3",
123
122
  "typescript-eslint": "^8.65.0"
124
123
  },
125
124
  "keywords": [