@bymax-one/nest-queue 1.0.5 → 1.0.7
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 +60 -0
- package/README.md +24 -1
- package/dist/server/index.cjs +8 -1
- package/dist/server/index.d.cts +0 -3
- package/dist/server/index.d.ts +0 -3
- package/dist/server/index.mjs +8 -1
- package/package.json +27 -24
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,64 @@ versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
+
## [1.0.7] — 2026-08-04
|
|
11
|
+
|
|
12
|
+
**Runtime change.** `dist/` differs from `1.0.6`: the four decorators no longer carry
|
|
13
|
+
a `reflect-metadata` side-effect import, so the built bundle no longer references the
|
|
14
|
+
package at all.
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **The application owns the `reflect-metadata` polyfill.** `@Processor`, `@Process`,
|
|
19
|
+
`@OnWorkerEvent` and `@OnQueueEvent` each imported it for its side effect. None of
|
|
20
|
+
the other eight `@bymax-one` libraries does — the polyfill is global state the
|
|
21
|
+
application initialises once in `main.ts`, and NestJS pulls it in regardless:
|
|
22
|
+
importing `@nestjs/common` alone takes `Reflect.defineMetadata` from `undefined` to
|
|
23
|
+
`function`. Nothing here needed to load it.
|
|
24
|
+
|
|
25
|
+
Carrying it also contradicted this package's own `"sideEffects": false`, which
|
|
26
|
+
asserts that no module has a side effect while importing something whose entire
|
|
27
|
+
purpose is one.
|
|
28
|
+
|
|
29
|
+
The cost was measurable in a consumer's bundle: with the import present, esbuild
|
|
30
|
+
inlines the polyfill, taking a minimal bundle from **53 kB to 95 kB** even when the
|
|
31
|
+
application had already loaded it.
|
|
32
|
+
|
|
33
|
+
Nothing changes for a correctly wired application. The decorators are reachable
|
|
34
|
+
only through the `.` subpath, whose bundle imports `@nestjs/common` on its first
|
|
35
|
+
line — so the polyfill is present before any decorator body runs, which the tests
|
|
36
|
+
and a real consumer both confirm.
|
|
37
|
+
|
|
38
|
+
### Changed
|
|
39
|
+
|
|
40
|
+
- **The Quick Start shows the `main.ts` entry point**, with `import 'reflect-metadata'`
|
|
41
|
+
as its first line, and the peer matrix states plainly that the polyfill belongs to
|
|
42
|
+
the application. Previously the README named `reflect-metadata` only as a peer, which
|
|
43
|
+
was survivable while the library loaded it and is not now.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## [1.0.6] — 2026-08-02
|
|
48
|
+
|
|
49
|
+
Metadata only. `dist/` is byte-identical to `1.0.5` — verified by diffing a fresh
|
|
50
|
+
build against the published tarball — so there is no runtime change.
|
|
51
|
+
|
|
52
|
+
### Fixed
|
|
53
|
+
|
|
54
|
+
- **The npm package page showed no documentation.** `1.0.5` reached the registry
|
|
55
|
+
with an empty `readme` field, so the page rendered nothing, even though
|
|
56
|
+
`README.md` was in the tarball all along. Publishing goes through the npm CLI
|
|
57
|
+
now instead of `pnpm publish`, and this release is what carries the README to
|
|
58
|
+
the registry.
|
|
59
|
+
|
|
60
|
+
The cause is measurable: across the five published `@bymax-one/*` libraries,
|
|
61
|
+
every package released under pnpm 11 landed with an empty `readme` and no
|
|
62
|
+
`_npmVersion`, while every one released under pnpm 10 — which delegated to the
|
|
63
|
+
npm CLI — carries both. `nest-realtime@1.0.1` confirmed it, restoring both
|
|
64
|
+
fields in a single release by switching the command.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
10
68
|
## [1.0.5] — 2026-08-01
|
|
11
69
|
|
|
12
70
|
Documentation only. `dist/` is byte-identical to `1.0.4` — verified by diffing a
|
|
@@ -311,6 +369,8 @@ v6 peer range.
|
|
|
311
369
|
|
|
312
370
|
---
|
|
313
371
|
|
|
372
|
+
[1.0.7]: https://github.com/bymaxone/nest-queue/compare/v1.0.6...v1.0.7
|
|
373
|
+
[1.0.6]: https://github.com/bymaxone/nest-queue/releases/tag/v1.0.6
|
|
314
374
|
[1.0.5]: https://github.com/bymaxone/nest-queue/releases/tag/v1.0.5
|
|
315
375
|
[1.0.4]: https://github.com/bymaxone/nest-queue/releases/tag/v1.0.4
|
|
316
376
|
[1.0.3]: https://github.com/bymaxone/nest-queue/releases/tag/v1.0.3
|
package/README.md
CHANGED
|
@@ -120,6 +120,12 @@ Both subpaths ship ESM **and** CommonJS with declarations for each format, so a
|
|
|
120
120
|
| `./shared` | None |
|
|
121
121
|
| Optional | `bullmq-otel ^1` (OpenTelemetry) |
|
|
122
122
|
|
|
123
|
+
> [!IMPORTANT]
|
|
124
|
+
> `reflect-metadata` is a **global polyfill the application owns** — import it once at
|
|
125
|
+
> the top of `main.ts`. This library never imports it, so it cannot be shipped twice
|
|
126
|
+
> into your bundle; NestJS pulls it in as well, which is why a correctly wired
|
|
127
|
+
> application already has it before a decorator runs.
|
|
128
|
+
|
|
123
129
|
---
|
|
124
130
|
|
|
125
131
|
> [!TIP]
|
|
@@ -137,7 +143,24 @@ Both subpaths ship ESM **and** CommonJS with declarations for each format, so a
|
|
|
137
143
|
## 🚀 Quick Start
|
|
138
144
|
|
|
139
145
|
```bash
|
|
140
|
-
pnpm add @bymax-one/nest-queue bullmq ioredis
|
|
146
|
+
pnpm add @bymax-one/nest-queue bullmq ioredis reflect-metadata
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`reflect-metadata` is loaded **once by your application**, before anything else — this
|
|
150
|
+
is the standard NestJS entry point and the decorators in this library depend on it:
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// main.ts
|
|
154
|
+
import 'reflect-metadata'
|
|
155
|
+
import { NestFactory } from '@nestjs/core'
|
|
156
|
+
import { AppModule } from './app.module'
|
|
157
|
+
|
|
158
|
+
async function bootstrap(): Promise<void> {
|
|
159
|
+
const app = await NestFactory.create(AppModule)
|
|
160
|
+
await app.listen(3000)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
void bootstrap()
|
|
141
164
|
```
|
|
142
165
|
|
|
143
166
|
Wire the module in your root `AppModule`:
|
package/dist/server/index.cjs
CHANGED
|
@@ -5,7 +5,6 @@ var core = require('@nestjs/core');
|
|
|
5
5
|
var ioredis = require('ioredis');
|
|
6
6
|
var bullmq = require('bullmq');
|
|
7
7
|
var path = require('path');
|
|
8
|
-
require('reflect-metadata');
|
|
9
8
|
|
|
10
9
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
11
10
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -1440,6 +1439,8 @@ exports.BymaxQueueModule = class BymaxQueueModule extends ConfigurableModuleClas
|
|
|
1440
1439
|
exports.BymaxQueueModule = __decorateClass([
|
|
1441
1440
|
common.Module({})
|
|
1442
1441
|
], exports.BymaxQueueModule);
|
|
1442
|
+
|
|
1443
|
+
// src/server/decorators/processor.decorator.ts
|
|
1443
1444
|
function Processor(queueName, options) {
|
|
1444
1445
|
return (target) => {
|
|
1445
1446
|
const concurrencyOmitted = options?.concurrency === void 0;
|
|
@@ -1455,6 +1456,8 @@ function Processor(queueName, options) {
|
|
|
1455
1456
|
Reflect.defineMetadata(PROCESSOR_METADATA_KEY, metadata, target);
|
|
1456
1457
|
};
|
|
1457
1458
|
}
|
|
1459
|
+
|
|
1460
|
+
// src/server/decorators/process.decorator.ts
|
|
1458
1461
|
function Process(jobName) {
|
|
1459
1462
|
return (target, propertyKey) => {
|
|
1460
1463
|
const existing = Reflect.getOwnMetadata(PROCESS_HANDLERS_METADATA_KEY, target.constructor) ?? [];
|
|
@@ -1462,6 +1465,8 @@ function Process(jobName) {
|
|
|
1462
1465
|
Reflect.defineMetadata(PROCESS_HANDLERS_METADATA_KEY, [...existing, entry], target.constructor);
|
|
1463
1466
|
};
|
|
1464
1467
|
}
|
|
1468
|
+
|
|
1469
|
+
// src/server/decorators/on-worker-event.decorator.ts
|
|
1465
1470
|
function OnWorkerEvent(eventName) {
|
|
1466
1471
|
return (target, propertyKey) => {
|
|
1467
1472
|
const existing = Reflect.getOwnMetadata(
|
|
@@ -1475,6 +1480,8 @@ function OnWorkerEvent(eventName) {
|
|
|
1475
1480
|
);
|
|
1476
1481
|
};
|
|
1477
1482
|
}
|
|
1483
|
+
|
|
1484
|
+
// src/server/decorators/on-queue-event.decorator.ts
|
|
1478
1485
|
function OnQueueEvent(eventName) {
|
|
1479
1486
|
return (target, propertyKey) => {
|
|
1480
1487
|
const existing = Reflect.getOwnMetadata(
|
package/dist/server/index.d.cts
CHANGED
|
@@ -1102,7 +1102,6 @@ declare function Processor(queueName: string, options?: WorkerOptions): ClassDec
|
|
|
1102
1102
|
* class coexist without overwriting each other.
|
|
1103
1103
|
* @layer server/decorators
|
|
1104
1104
|
*/
|
|
1105
|
-
|
|
1106
1105
|
/**
|
|
1107
1106
|
* Marks a method as a job processor. If `jobName` is supplied the method is
|
|
1108
1107
|
* only invoked for jobs whose `name` matches; if omitted the method acts as a
|
|
@@ -1135,7 +1134,6 @@ declare function Process(jobName?: string): MethodDecorator;
|
|
|
1135
1134
|
* and timing fields. Use `'progress'` to observe `job.updateProgress()`.
|
|
1136
1135
|
* @layer server/decorators
|
|
1137
1136
|
*/
|
|
1138
|
-
|
|
1139
1137
|
/**
|
|
1140
1138
|
* Union of BullMQ `Worker` event names surfaced by this library. Handlers
|
|
1141
1139
|
* registered with `@OnWorkerEvent` receive the **full** `Job` instance for
|
|
@@ -1195,7 +1193,6 @@ declare function OnWorkerEvent(eventName: WorkerEventName): MethodDecorator;
|
|
|
1195
1193
|
* To inspect the full `Job`, call `QueueService.getJob(jobId)`.
|
|
1196
1194
|
* @layer server/decorators
|
|
1197
1195
|
*/
|
|
1198
|
-
|
|
1199
1196
|
/**
|
|
1200
1197
|
* Union of BullMQ `QueueEvents` event names surfaced by this library. Listeners
|
|
1201
1198
|
* registered with `@OnQueueEvent` receive a serialized event payload, NOT the
|
package/dist/server/index.d.ts
CHANGED
|
@@ -1102,7 +1102,6 @@ declare function Processor(queueName: string, options?: WorkerOptions): ClassDec
|
|
|
1102
1102
|
* class coexist without overwriting each other.
|
|
1103
1103
|
* @layer server/decorators
|
|
1104
1104
|
*/
|
|
1105
|
-
|
|
1106
1105
|
/**
|
|
1107
1106
|
* Marks a method as a job processor. If `jobName` is supplied the method is
|
|
1108
1107
|
* only invoked for jobs whose `name` matches; if omitted the method acts as a
|
|
@@ -1135,7 +1134,6 @@ declare function Process(jobName?: string): MethodDecorator;
|
|
|
1135
1134
|
* and timing fields. Use `'progress'` to observe `job.updateProgress()`.
|
|
1136
1135
|
* @layer server/decorators
|
|
1137
1136
|
*/
|
|
1138
|
-
|
|
1139
1137
|
/**
|
|
1140
1138
|
* Union of BullMQ `Worker` event names surfaced by this library. Handlers
|
|
1141
1139
|
* registered with `@OnWorkerEvent` receive the **full** `Job` instance for
|
|
@@ -1195,7 +1193,6 @@ declare function OnWorkerEvent(eventName: WorkerEventName): MethodDecorator;
|
|
|
1195
1193
|
* To inspect the full `Job`, call `QueueService.getJob(jobId)`.
|
|
1196
1194
|
* @layer server/decorators
|
|
1197
1195
|
*/
|
|
1198
|
-
|
|
1199
1196
|
/**
|
|
1200
1197
|
* Union of BullMQ `QueueEvents` event names surfaced by this library. Listeners
|
|
1201
1198
|
* registered with `@OnQueueEvent` receive a serialized event payload, NOT the
|
package/dist/server/index.mjs
CHANGED
|
@@ -3,7 +3,6 @@ import { DiscoveryService, DiscoveryModule } from '@nestjs/core';
|
|
|
3
3
|
import { Redis } from 'ioredis';
|
|
4
4
|
import { Worker, QueueEvents, Queue, FlowProducer } from 'bullmq';
|
|
5
5
|
import { isAbsolute, extname } from 'path';
|
|
6
|
-
import 'reflect-metadata';
|
|
7
6
|
|
|
8
7
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
9
8
|
var __decorateClass = (decorators, target, key, kind) => {
|
|
@@ -1438,6 +1437,8 @@ var BymaxQueueModule = class extends ConfigurableModuleClass {
|
|
|
1438
1437
|
BymaxQueueModule = __decorateClass([
|
|
1439
1438
|
Module({})
|
|
1440
1439
|
], BymaxQueueModule);
|
|
1440
|
+
|
|
1441
|
+
// src/server/decorators/processor.decorator.ts
|
|
1441
1442
|
function Processor(queueName, options) {
|
|
1442
1443
|
return (target) => {
|
|
1443
1444
|
const concurrencyOmitted = options?.concurrency === void 0;
|
|
@@ -1453,6 +1454,8 @@ function Processor(queueName, options) {
|
|
|
1453
1454
|
Reflect.defineMetadata(PROCESSOR_METADATA_KEY, metadata, target);
|
|
1454
1455
|
};
|
|
1455
1456
|
}
|
|
1457
|
+
|
|
1458
|
+
// src/server/decorators/process.decorator.ts
|
|
1456
1459
|
function Process(jobName) {
|
|
1457
1460
|
return (target, propertyKey) => {
|
|
1458
1461
|
const existing = Reflect.getOwnMetadata(PROCESS_HANDLERS_METADATA_KEY, target.constructor) ?? [];
|
|
@@ -1460,6 +1463,8 @@ function Process(jobName) {
|
|
|
1460
1463
|
Reflect.defineMetadata(PROCESS_HANDLERS_METADATA_KEY, [...existing, entry], target.constructor);
|
|
1461
1464
|
};
|
|
1462
1465
|
}
|
|
1466
|
+
|
|
1467
|
+
// src/server/decorators/on-worker-event.decorator.ts
|
|
1463
1468
|
function OnWorkerEvent(eventName) {
|
|
1464
1469
|
return (target, propertyKey) => {
|
|
1465
1470
|
const existing = Reflect.getOwnMetadata(
|
|
@@ -1473,6 +1478,8 @@ function OnWorkerEvent(eventName) {
|
|
|
1473
1478
|
);
|
|
1474
1479
|
};
|
|
1475
1480
|
}
|
|
1481
|
+
|
|
1482
|
+
// src/server/decorators/on-queue-event.decorator.ts
|
|
1476
1483
|
function OnQueueEvent(eventName) {
|
|
1477
1484
|
return (target, propertyKey) => {
|
|
1478
1485
|
const existing = Reflect.getOwnMetadata(
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bymax-one/nest-queue",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
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",
|
|
@@ -53,6 +53,30 @@
|
|
|
53
53
|
]
|
|
54
54
|
}
|
|
55
55
|
},
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "pnpm clean && tsup",
|
|
58
|
+
"check:exports": "attw --pack .",
|
|
59
|
+
"check:published": "node scripts/check-published-surface.mjs",
|
|
60
|
+
"clean": "rm -rf dist coverage",
|
|
61
|
+
"lint": "eslint src scripts test",
|
|
62
|
+
"lint:fix": "eslint src scripts test --fix",
|
|
63
|
+
"mutation": "stryker run",
|
|
64
|
+
"mutation:dry-run": "stryker run --dryRunOnly",
|
|
65
|
+
"mutation:incremental": "stryker run --incremental",
|
|
66
|
+
"prepare": "husky",
|
|
67
|
+
"prepublishOnly": "pnpm clean && pnpm typecheck && pnpm test:types && pnpm lint && pnpm test:cov:all && pnpm build && pnpm check:published",
|
|
68
|
+
"release": "npm publish --provenance --access public",
|
|
69
|
+
"size": "node scripts/check-size.mjs",
|
|
70
|
+
"smoke": "node scripts/dogfood-smoke-test.mjs",
|
|
71
|
+
"test": "jest",
|
|
72
|
+
"test:all": "pnpm test && pnpm test:e2e",
|
|
73
|
+
"test:cov": "jest --coverage",
|
|
74
|
+
"test:cov:all": "jest --config jest.coverage.config.ts --coverage",
|
|
75
|
+
"test:e2e": "jest --config jest.e2e.config.ts",
|
|
76
|
+
"test:types": "tsc --noEmit -p tsconfig.typetest.json",
|
|
77
|
+
"test:watch": "jest --watch",
|
|
78
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.server.json"
|
|
79
|
+
},
|
|
56
80
|
"dependencies": {},
|
|
57
81
|
"peerDependencies": {
|
|
58
82
|
"@nestjs/common": "^11.0.16",
|
|
@@ -122,33 +146,12 @@
|
|
|
122
146
|
"prettier --write"
|
|
123
147
|
]
|
|
124
148
|
},
|
|
149
|
+
"packageManager": "pnpm@11.0.0",
|
|
125
150
|
"engines": {
|
|
126
151
|
"node": ">=24.0.0"
|
|
127
152
|
},
|
|
128
153
|
"publishConfig": {
|
|
129
154
|
"access": "public",
|
|
130
155
|
"registry": "https://registry.npmjs.org/"
|
|
131
|
-
},
|
|
132
|
-
"scripts": {
|
|
133
|
-
"build": "pnpm clean && tsup",
|
|
134
|
-
"check:exports": "attw --pack .",
|
|
135
|
-
"check:published": "node scripts/check-published-surface.mjs",
|
|
136
|
-
"clean": "rm -rf dist coverage",
|
|
137
|
-
"lint": "eslint src scripts test",
|
|
138
|
-
"lint:fix": "eslint src scripts test --fix",
|
|
139
|
-
"mutation": "stryker run",
|
|
140
|
-
"mutation:dry-run": "stryker run --dryRunOnly",
|
|
141
|
-
"mutation:incremental": "stryker run --incremental",
|
|
142
|
-
"release": "pnpm publish --provenance",
|
|
143
|
-
"size": "node scripts/check-size.mjs",
|
|
144
|
-
"smoke": "node scripts/dogfood-smoke-test.mjs",
|
|
145
|
-
"test": "jest",
|
|
146
|
-
"test:all": "pnpm test && pnpm test:e2e",
|
|
147
|
-
"test:cov": "jest --coverage",
|
|
148
|
-
"test:cov:all": "jest --config jest.coverage.config.ts --coverage",
|
|
149
|
-
"test:e2e": "jest --config jest.e2e.config.ts",
|
|
150
|
-
"test:types": "tsc --noEmit -p tsconfig.typetest.json",
|
|
151
|
-
"test:watch": "jest --watch",
|
|
152
|
-
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.server.json"
|
|
153
156
|
}
|
|
154
|
-
}
|
|
157
|
+
}
|