@bymax-one/nest-queue 1.0.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 +123 -0
- package/LICENSE +21 -0
- package/README.md +858 -0
- package/dist/server/index.cjs +1518 -0
- package/dist/server/index.d.cts +1386 -0
- package/dist/server/index.d.ts +1386 -0
- package/dist/server/index.mjs +1500 -0
- package/dist/shared/index.cjs +32 -0
- package/dist/shared/index.d.cts +132 -0
- package/dist/shared/index.d.ts +132 -0
- package/dist/shared/index.mjs +29 -0
- package/package.json +153 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to `@bymax-one/nest-queue` are documented in this file.
|
|
4
|
+
|
|
5
|
+
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.0.0/);
|
|
6
|
+
versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
## [1.0.0] — 2026-07-30
|
|
11
|
+
|
|
12
|
+
First public release. The library is feature-complete for the surface described
|
|
13
|
+
in `docs/technical_specification.md`, holds 100% line/branch/function/statement
|
|
14
|
+
coverage, and ships with zero runtime dependencies.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- `BymaxQueueModule.forRoot()` and `.forRootAsync()` dynamic module (built on
|
|
19
|
+
`ConfigurableModuleBuilder`; `isGlobal` mapped to `DynamicModule.global` via `setExtras`)
|
|
20
|
+
- `QueueService` with typed `enqueue` (native `deduplication` options), `enqueueBulk`,
|
|
21
|
+
`getJob`, `getJobs`, `getMetrics`, `pauseQueue`/`resumeQueue`/`cleanQueue`, and Job
|
|
22
|
+
Schedulers `upsertJobScheduler`/`removeJobScheduler`/`getJobSchedulers`
|
|
23
|
+
- `@Processor`, `@Process`, `@OnWorkerEvent` (worker-local, full `Job`), `@OnQueueEvent`
|
|
24
|
+
(global) decorators plus automatic discovery via `DiscoveryService`; `job.updateProgress()`
|
|
25
|
+
and progress event support
|
|
26
|
+
- `WorkerRegistry` programmatic API, including `registerSandboxed` for file-based
|
|
27
|
+
out-of-process processors
|
|
28
|
+
- `FlowService` (opt-in via `options.flows.enabled`)
|
|
29
|
+
- `MetricsService` with TTL cache (opt-in via `options.metrics.enabled`)
|
|
30
|
+
- Optional OpenTelemetry `telemetry` passthrough (via `bullmq-otel`, an optional peer dep)
|
|
31
|
+
- `QueueLifecycle` bounded graceful-shutdown protocol (bounded drain via `Promise.race` +
|
|
32
|
+
`worker.close(true)`, optional drain, Redis disconnect on Mode B); at-least-once semantics
|
|
33
|
+
documented
|
|
34
|
+
- Dual-mode connection (Mode A: bring-your-own ioredis / Mode B: lib-owned), with per-role
|
|
35
|
+
`maxRetriesPerRequest` policy applied automatically
|
|
36
|
+
- Subpaths: `.` (server), `./shared` (zero-dep types and constants)
|
|
37
|
+
- `'error'` as a subscribable `@OnQueueEvent` name. It carries a real `Error`
|
|
38
|
+
instance rather than the serialized payload every other queue event delivers,
|
|
39
|
+
because it reports a connection fault rather than a job transition
|
|
40
|
+
- Peer deps: `@nestjs/common ^11`, `@nestjs/core ^11`, `bullmq ^5.16`, `ioredis ^5`,
|
|
41
|
+
`reflect-metadata ^0.2`; optional `bullmq-otel ^1`
|
|
42
|
+
- E2E tests with Testcontainers Redis
|
|
43
|
+
|
|
44
|
+
### Fixed
|
|
45
|
+
|
|
46
|
+
- **The configured `prefix` now reaches every BullMQ object.** Only the producer
|
|
47
|
+
`Queue` received `options.prefix`; the `Worker`, `QueueEvents` and `FlowProducer`
|
|
48
|
+
were constructed without it and fell back to BullMQ's default `bull` prefix. With
|
|
49
|
+
any non-default prefix, producers and consumers diverged onto separate keyspaces —
|
|
50
|
+
workers never consumed jobs, event listeners never fired, and flow jobs were
|
|
51
|
+
enqueued where no worker polled. Nothing threw.
|
|
52
|
+
- **Explicit `@Inject` on every injectable constructor parameter.** The package
|
|
53
|
+
ships as a tsup/esbuild bundle, and esbuild does not emit
|
|
54
|
+
`emitDecoratorMetadata`. Providers resolved purely by reflected type metadata
|
|
55
|
+
(`QueueService`, `WorkerRegistry`, `QueueEventsRegistry`,
|
|
56
|
+
`ProcessorDiscoveryService`, `QueueLifecycle`) could not be instantiated from
|
|
57
|
+
the built `dist` by a consumer's Nest container.
|
|
58
|
+
- **The `exports` map hands CommonJS consumers CommonJS declarations.** With
|
|
59
|
+
`"type": "module"`, TypeScript reads a bare `.d.ts` as ESM, so a `require()`
|
|
60
|
+
consumer landed on ESM declarations. `types` is now declared per condition,
|
|
61
|
+
`main`/`module`/`types` are present for legacy resolution, `./package.json` is
|
|
62
|
+
exported, and the package passes `attw` at the strict profile.
|
|
63
|
+
|
|
64
|
+
- **Every BullMQ emitter the library creates carries a fallback `error` listener.**
|
|
65
|
+
`Queue`, `Worker`, `QueueEvents` and `FlowProducer` extend Node's `EventEmitter`,
|
|
66
|
+
where emitting `'error'` with no listener **throws** rather than being delivered.
|
|
67
|
+
The library constructs all four on the consumer's behalf, so a transient Redis
|
|
68
|
+
fault surfaced as an uncaught exception in an application that never asked for
|
|
69
|
+
the emitter. The fallback logs and does not consume the event — an
|
|
70
|
+
`@OnWorkerEvent('error')` or `@OnQueueEvent('error')` handler still runs.
|
|
71
|
+
- **One owner for shutdown.** `QueueService`, `FlowService` and `ConnectionResolver`
|
|
72
|
+
each exposed `onModuleDestroy`, and NestJS binds lifecycle hooks by method name,
|
|
73
|
+
so Nest invoked them on its own schedule while `QueueLifecycle` also called two
|
|
74
|
+
of them inside its ordered sequence: the flow producer closed twice, and queues
|
|
75
|
+
could close before the bounded drain finished with them. They now expose plain
|
|
76
|
+
methods — `QueueService.closeAll()`, `FlowService.close()`,
|
|
77
|
+
`ConnectionResolver.teardown()` — and `QueueLifecycle` is the only lifecycle hook.
|
|
78
|
+
- **Operational failures no longer masquerade as a bad cron.** `upsertJobScheduler`
|
|
79
|
+
wrapped every failure in `INVALID_REPEAT_OPTIONS` with HTTP 400 and "pattern must
|
|
80
|
+
be a valid cron expression", so an unreachable Redis was reported as a client
|
|
81
|
+
mistake — with a status telling the caller not to retry. Faults carrying a string
|
|
82
|
+
`code` now propagate untouched.
|
|
83
|
+
- **A malformed `repeat` raises the documented error instead of a `TypeError`.**
|
|
84
|
+
The union forbids it for a TypeScript caller, but plain JavaScript and any
|
|
85
|
+
payload cast from `unknown` reached the `in` operator unchecked. `null`,
|
|
86
|
+
`undefined`, strings, numbers and arrays are rejected as
|
|
87
|
+
`INVALID_REPEAT_OPTIONS`, as is a blank `pattern`.
|
|
88
|
+
- **`QueueEventsRegistry.getConnections()` returns a copy.** `ReadonlyMap` is a
|
|
89
|
+
compile-time claim only; the live registry could be cast and mutated.
|
|
90
|
+
|
|
91
|
+
### Security
|
|
92
|
+
|
|
93
|
+
- Release pipeline gated behind a manual-approval environment, with SHA-pinned
|
|
94
|
+
actions, tag/version verification, and OIDC provenance from the second release
|
|
95
|
+
onward.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## BullMQ version policy
|
|
100
|
+
|
|
101
|
+
### 1.x — floor `bullmq ^5.16.0`
|
|
102
|
+
|
|
103
|
+
The `1.x` series floors `peerDependencies.bullmq` at `^5.16.0`, the release that
|
|
104
|
+
introduced the Job Schedulers API (`upsertJobScheduler`/`removeJobScheduler`/`getJobSchedulers`).
|
|
105
|
+
Current recommended peer: `5.79.1`.
|
|
106
|
+
|
|
107
|
+
### Forward compatibility with BullMQ v6
|
|
108
|
+
|
|
109
|
+
This library is **forward-compatible with BullMQ v6 by design**. It exclusively uses
|
|
110
|
+
Job Schedulers for recurring jobs and never calls the removed `addRepeatable`/`removeRepeatable`
|
|
111
|
+
API, so no public-API break is expected on promotion to v6.
|
|
112
|
+
|
|
113
|
+
**Promotion trigger.** When the E2E suite is green on both the v5 and v6 matrix, the peer
|
|
114
|
+
range will be widened to `^5.16.0 || ^6.0.0` in a minor release. No adapter is needed because
|
|
115
|
+
the recurring-jobs surface is unchanged.
|
|
116
|
+
|
|
117
|
+
**Fallback.** If another API used by the library breaks in BullMQ v6 without a trivial adapter,
|
|
118
|
+
a parallel branch will keep the `1.x` line on `^5.16` only, and a `2.x` series will track the
|
|
119
|
+
v6 peer range.
|
|
120
|
+
|
|
121
|
+
---
|
|
122
|
+
|
|
123
|
+
[1.0.0]: https://github.com/bymaxone/nest-queue/releases/tag/v1.0.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bymax One
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|