@bymax-one/nest-queue 1.0.2 → 1.0.4

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,92 @@ versioning follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ---
9
9
 
10
+ ## [1.0.4] — 2026-08-01
11
+
12
+ ### Fixed
13
+
14
+ - **`BymaxQueueModuleAsyncOptions.useFactory` rejected the factory this library
15
+ documents.** It was declared `(...args: unknown[]) => …`, and a parameter typed
16
+ `unknown` accepts no narrower parameter under `strictFunctionTypes`. So the
17
+ shape shown in the README and in `BymaxQueueModule`'s own `@example`:
18
+
19
+ ```ts
20
+ useFactory: (client: Redis) => ({ connection: { client } })
21
+ ```
22
+
23
+ failed to typecheck **against the exported interface**:
24
+
25
+ ```
26
+ TS2322: Type '(client: Redis) => …' is not assignable to
27
+ type '(...args: unknown[]) => …'
28
+ ```
29
+
30
+ Scope, precisely: `forRootAsync` is typed by NestJS's `ASYNC_OPTIONS_TYPE`, not
31
+ by this interface, so passing the object **inline** always compiled. Only a
32
+ consumer who annotated it — extracting the options into a
33
+ `const opts: BymaxQueueModuleAsyncOptions = { … }` — hit the error. The
34
+ interface was stricter than the module it describes.
35
+
36
+ It is now declared with **method syntax**. `strictFunctionTypes` makes
37
+ parameters contravariant for function-typed _properties_ but leaves method
38
+ parameters bivariant, so the interface accepts a factory that names its
39
+ injected types. This **widens** what is accepted: every factory that compiled
40
+ before still does, the variadic `(...args: unknown[])` form included. Nothing
41
+ needs changing in consumer code.
42
+
43
+ Method syntax rather than a looser parameter type, because the factory has to
44
+ stay **callable**: NestJS invokes it with the values `inject` resolves, and a
45
+ consumer may call it directly in a unit test. A `never[]` rest parameter would
46
+ have bought the same assignability and silently cost that —
47
+ `options.useFactory(client)` fails with `TS2345: Argument of type 'Redis' is
48
+ not assignable to parameter of type 'never'`.
49
+
50
+ Pinned by seven cases in `test/types/public-api.test-d.ts` — typed parameter,
51
+ async, several parameters, zero parameters, the pre-1.0.4 variadic form, and
52
+ two for callability — where `useFactory` was previously pinned by nothing,
53
+ which is why this went unnoticed. Red-checked against **both** rejected
54
+ signatures: the original property form fails the assignability cases, and
55
+ `never[]` fails the callability ones.
56
+
57
+ No runtime change, verified rather than asserted: diffed against the published
58
+ `1.0.3` tarball, all four emitted runtime files (`server` and `shared`, `.mjs`
59
+ and `.cjs`) are byte-identical, and only `dist/server/index.d.ts` / `.d.cts`
60
+ differ. The altered source declares types only, so it produces no Stryker
61
+ mutants and the 99.06% score stands.
62
+
63
+ ---
64
+
65
+ ## [1.0.3] — 2026-08-01
66
+
67
+ Documentation only. `dist/` is byte-identical to `1.0.2` — verified by unpacking
68
+ the published tarball and diffing it against a fresh build — so there is no
69
+ runtime change of any kind for consumers.
70
+
71
+ ### Fixed
72
+
73
+ - **The "Example App" link in the README pointed at a path that no longer
74
+ exists.** It resolved to
75
+ `github.com/bymaxone/nest-queue/tree/main/examples/nest-queue-example`, a
76
+ directory that was renamed to `test/consumer-app` in this repository. The link
77
+ returned **404** for anyone reading the package page on npm, which is where a
78
+ README link matters most and where a broken one is least visible to us.
79
+
80
+ It now points at [`bymaxone/nest-queue-example`](https://github.com/bymaxone/nest-queue-example),
81
+ the actual reference application.
82
+
83
+ ### Changed
84
+
85
+ - **The README no longer implies that `test/consumer-app` is a demo.** The two
86
+ artifacts had been sharing one name, and only one of them is something to copy
87
+ from:
88
+
89
+ | | What it is |
90
+ | ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
91
+ | `bymaxone/nest-queue-example` | The reference application — an API and a web console exercising every public export against a real Redis. **Start here.** |
92
+ | `test/consumer-app` (this repo) | A typecheck fixture. CI compiles it against the freshly built library on every pull request to catch an ergonomic break in the decorator API that a signature test cannot see. Not published, not a demo. |
93
+
94
+ ---
95
+
10
96
  ## [1.0.2] — 2026-07-30
11
97
 
12
98
  ### Security
package/README.md CHANGED
@@ -26,7 +26,7 @@
26
26
  <a href="https://github.com/bymaxone/nest-queue/issues">Issues</a> ·
27
27
  <a href="#-quick-start">Quick Start</a> ·
28
28
  <a href="#-api-reference">API Reference</a> ·
29
- <a href="https://github.com/bymaxone/nest-queue/tree/main/examples/nest-queue-example">Example App</a>
29
+ <a href="https://github.com/bymaxone/nest-queue-example">Example App</a>
30
30
  </p>
31
31
 
32
32
  ---
@@ -123,10 +123,14 @@ Both subpaths ship ESM **and** CommonJS with declarations for each format, so a
123
123
  ---
124
124
 
125
125
  > [!TIP]
126
- > A runnable reference application lives in
127
- > [`examples/nest-queue-example`](https://github.com/bymaxone/nest-queue/tree/main/examples/nest-queue-example) —
128
- > a NestJS app that consumes this library and exercises producers, decorated
129
- > processors, and a health endpoint against a real Redis.
126
+ > A full reference application lives in
127
+ > [`bymaxone/nest-queue-example`](https://github.com/bymaxone/nest-queue-example) —
128
+ > an API and a web console exercising every public export against a real Redis.
129
+ >
130
+ > The `test/consumer-app` directory in this repository is **not** that. It is a
131
+ > typecheck fixture: a few hundred lines of application-shaped code that CI
132
+ > compiles against the freshly built library on every pull request, to catch an
133
+ > ergonomic break in the decorator API that a signature test cannot see.
130
134
 
131
135
  ---
132
136
 
@@ -97,8 +97,29 @@ interface BymaxQueueOptionsFactory {
97
97
  }
98
98
  /** Asynchronous configuration mirroring the NestJS async dynamic-module pattern. */
99
99
  interface BymaxQueueModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
100
- /** Factory returning the module options. */
101
- useFactory?: (...args: unknown[]) => Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
100
+ /**
101
+ * Factory returning the module options. Its parameters are whatever `inject`
102
+ * resolves to, so declare them with the types you expect:
103
+ *
104
+ * ```ts
105
+ * useFactory: (client: Redis) => ({ connection: { client } })
106
+ * ```
107
+ *
108
+ * Declared with **method syntax** on purpose. `strictFunctionTypes` makes
109
+ * parameters contravariant for function-typed *properties* but leaves method
110
+ * parameters bivariant, so this accepts a factory that names its injected
111
+ * types — which a property typed `(...args: unknown[]) => …` rejects, since
112
+ * `unknown` is assignable from no narrower parameter. That rejection is what
113
+ * made the form above fail against this interface while compiling when passed
114
+ * inline to `forRootAsync`.
115
+ *
116
+ * Bivariance is the right trade here rather than a looser parameter type:
117
+ * NestJS resolves these arguments from `inject` at runtime, so no signature
118
+ * can make them statically safe, and method syntax keeps the factory
119
+ * **callable** — `options.useFactory(client)` typechecks, which a
120
+ * `never[]` rest parameter would have broken.
121
+ */
122
+ useFactory?(...args: unknown[]): Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
102
123
  /** Class implementing the options factory. */
103
124
  useClass?: Type<BymaxQueueOptionsFactory>;
104
125
  /** Existing provider implementing the options factory. */
@@ -97,8 +97,29 @@ interface BymaxQueueOptionsFactory {
97
97
  }
98
98
  /** Asynchronous configuration mirroring the NestJS async dynamic-module pattern. */
99
99
  interface BymaxQueueModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {
100
- /** Factory returning the module options. */
101
- useFactory?: (...args: unknown[]) => Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
100
+ /**
101
+ * Factory returning the module options. Its parameters are whatever `inject`
102
+ * resolves to, so declare them with the types you expect:
103
+ *
104
+ * ```ts
105
+ * useFactory: (client: Redis) => ({ connection: { client } })
106
+ * ```
107
+ *
108
+ * Declared with **method syntax** on purpose. `strictFunctionTypes` makes
109
+ * parameters contravariant for function-typed *properties* but leaves method
110
+ * parameters bivariant, so this accepts a factory that names its injected
111
+ * types — which a property typed `(...args: unknown[]) => …` rejects, since
112
+ * `unknown` is assignable from no narrower parameter. That rejection is what
113
+ * made the form above fail against this interface while compiling when passed
114
+ * inline to `forRootAsync`.
115
+ *
116
+ * Bivariance is the right trade here rather than a looser parameter type:
117
+ * NestJS resolves these arguments from `inject` at runtime, so no signature
118
+ * can make them statically safe, and method syntax keeps the factory
119
+ * **callable** — `options.useFactory(client)` typechecks, which a
120
+ * `never[]` rest parameter would have broken.
121
+ */
122
+ useFactory?(...args: unknown[]): Promise<BymaxQueueModuleOptions> | BymaxQueueModuleOptions;
102
123
  /** Class implementing the options factory. */
103
124
  useClass?: Type<BymaxQueueOptionsFactory>;
104
125
  /** Existing provider implementing the options factory. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bymax-one/nest-queue",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
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",