@dudousxd/nestjs-diagnostics 0.8.1 → 0.9.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 +16 -0
- package/README.md +29 -0
- package/dist/channel.d.ts +1 -1
- package/dist/channel.d.ts.map +1 -1
- package/dist/channel.js +3 -1
- package/dist/channel.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/nestjs/delivery.d.ts +92 -0
- package/dist/nestjs/delivery.d.ts.map +1 -0
- package/dist/nestjs/delivery.js +2 -0
- package/dist/nestjs/delivery.js.map +1 -0
- package/dist/nestjs/diagnostics.explorer.d.ts +51 -11
- package/dist/nestjs/diagnostics.explorer.d.ts.map +1 -1
- package/dist/nestjs/diagnostics.explorer.js +209 -53
- package/dist/nestjs/diagnostics.explorer.js.map +1 -1
- package/dist/nestjs/diagnostics.module.d.ts +9 -2
- package/dist/nestjs/diagnostics.module.d.ts.map +1 -1
- package/dist/nestjs/diagnostics.module.js +23 -3
- package/dist/nestjs/diagnostics.module.js.map +1 -1
- package/dist/nestjs/diagnostics.options.d.ts +31 -0
- package/dist/nestjs/diagnostics.options.d.ts.map +1 -0
- package/dist/nestjs/diagnostics.options.js +3 -0
- package/dist/nestjs/diagnostics.options.js.map +1 -0
- package/dist/nestjs/index.d.ts +6 -3
- package/dist/nestjs/index.d.ts.map +1 -1
- package/dist/nestjs/index.js +4 -2
- package/dist/nestjs/index.js.map +1 -1
- package/dist/nestjs/on-diagnostic.decorator.d.ts +33 -7
- package/dist/nestjs/on-diagnostic.decorator.d.ts.map +1 -1
- package/dist/nestjs/on-diagnostic.decorator.js +0 -9
- package/dist/nestjs/on-diagnostic.decorator.js.map +1 -1
- package/dist/nestjs/queue-transport.d.ts +47 -0
- package/dist/nestjs/queue-transport.d.ts.map +1 -0
- package/dist/nestjs/queue-transport.js +45 -0
- package/dist/nestjs/queue-transport.js.map +1 -0
- package/dist/nestjs/role.d.ts +13 -0
- package/dist/nestjs/role.d.ts.map +1 -0
- package/dist/nestjs/role.js +13 -0
- package/dist/nestjs/role.js.map +1 -0
- package/dist/nestjs/transports.d.ts +125 -0
- package/dist/nestjs/transports.d.ts.map +1 -0
- package/dist/nestjs/transports.js +127 -0
- package/dist/nestjs/transports.js.map +1 -0
- package/dist/redis-relay.d.ts +60 -0
- package/dist/redis-relay.d.ts.map +1 -0
- package/dist/redis-relay.js +170 -0
- package/dist/redis-relay.js.map +1 -0
- package/dist/relayed.d.ts +8 -0
- package/dist/relayed.d.ts.map +1 -0
- package/dist/relayed.js +31 -0
- package/dist/relayed.js.map +1 -0
- package/dist/trace.d.ts.map +1 -1
- package/dist/trace.js +2 -0
- package/dist/trace.js.map +1 -1
- package/dist/types.d.ts +9 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +14 -6
- package/skills/emit-diagnostics/SKILL.md +5 -2
- package/skills/react-with-on-diagnostic/SKILL.md +41 -13
- package/skills/trace-spans/SKILL.md +2 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: react-with-on-diagnostic
|
|
3
|
-
description: React to diagnostics events inside a NestJS app with @OnDiagnostic(lib, event?) from @dudousxd/nestjs-diagnostics/nestjs, wired by DiagnosticsModule.forRoot(). Decorate provider methods to handle one exact aviary:<lib>:<event> channel or every aviary:<lib>:* channel (current and future). Handlers run on the DI-resolved instance; sync throws and async rejections are logged and swallowed
|
|
3
|
+
description: React to diagnostics events inside a NestJS app with @OnDiagnostic(lib, event?) from @dudousxd/nestjs-diagnostics/nestjs, wired by DiagnosticsModule.forRoot()/forRootAsync({ default, transports, role, nodeId }). Decorate provider methods to handle one exact aviary:<lib>:<event> channel, a RegExp match, or every aviary:<lib>:* channel (current and future). The handler parameter is checked against the ChannelRegistry payload for registered channels; each listener has a stable <ClassName>#<method> id. Handlers run on the DI-resolved instance; without a delivering transport sync throws and async rejections are logged and swallowed, while queue/durable transports propagate the handler error for retry with delivery once from the emitting process. role 'api' never consumes or runs listeners.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
6
|
type: core
|
|
@@ -44,21 +44,37 @@ export class Reactions {
|
|
|
44
44
|
@OnDiagnostic('resilience', 'circuit-opened') // one exact channel
|
|
45
45
|
onCircuitOpen(e: DiagnosticEvent) { /* … */ }
|
|
46
46
|
|
|
47
|
+
@OnDiagnostic('durable', /^run\./) // every event of the lib whose name matches
|
|
48
|
+
onRun(e: DiagnosticEvent) { /* … */ }
|
|
49
|
+
|
|
47
50
|
@OnDiagnostic('resilience') // every aviary:resilience:* channel
|
|
48
51
|
onAnyResilience(e: DiagnosticEvent) { /* … */ }
|
|
49
52
|
}
|
|
50
53
|
```
|
|
51
54
|
|
|
55
|
+
For a channel declared in the `ChannelRegistry`, the handler's parameter is
|
|
56
|
+
checked against the declared payload (see `DiagnosticEventOf`); untyped
|
|
57
|
+
channels accept any annotation. Each listener has a stable id,
|
|
58
|
+
`<ClassName>#<method>`; two listener classes with the same name fail the
|
|
59
|
+
bootstrap. To run listeners across processes, pass
|
|
60
|
+
`{ default, transports, role, nodeId }` to `forRoot()` (or `forRootAsync()`):
|
|
61
|
+
`transports.redis()`, `transports.queue()`, or `transports.durable()` select
|
|
62
|
+
the delivery, and `role: 'api'` emits and hands work to the transport but
|
|
63
|
+
never consumes or runs listeners (`'api'`/`'worker'` without a `default`
|
|
64
|
+
transport fail the bootstrap).
|
|
65
|
+
|
|
52
66
|
Source: `packages/core/src/nestjs/diagnostics.module.ts`,
|
|
53
67
|
`packages/core/src/nestjs/on-diagnostic.decorator.ts`,
|
|
54
68
|
`packages/core/src/nestjs/diagnostics.explorer.ts`.
|
|
55
69
|
|
|
56
70
|
## Core patterns
|
|
57
71
|
|
|
58
|
-
### 1. Exact channel
|
|
72
|
+
### 1. Exact channel, RegExp match, or library wildcard
|
|
59
73
|
|
|
60
74
|
- `@OnDiagnostic('resilience', 'circuit-opened')` subscribes to the exact
|
|
61
75
|
`aviary:resilience:circuit-opened` channel.
|
|
76
|
+
- `@OnDiagnostic('durable', /^run\./)` subscribes to every
|
|
77
|
+
`aviary:durable:*` channel whose event name matches the `RegExp`.
|
|
62
78
|
- `@OnDiagnostic('resilience')` (no `event`) subscribes to **every**
|
|
63
79
|
`aviary:resilience:*` channel — both those already registered at bootstrap and
|
|
64
80
|
any that appear later (a library's first `emit('resilience', 'newevent', …)`).
|
|
@@ -69,6 +85,12 @@ automatically.
|
|
|
69
85
|
|
|
70
86
|
Source: `packages/core/src/nestjs/diagnostics.explorer.ts` (`onApplicationBootstrap`).
|
|
71
87
|
|
|
88
|
+
Each discovered method gets a stable listener id, `<ClassName>#<method>`,
|
|
89
|
+
which delivering transports (`queue`, `durable`) use to route work; keep it
|
|
90
|
+
stable while deliveries may be pending. Two listener classes with the same
|
|
91
|
+
name fail the bootstrap. `role: 'api'` never consumes or runs listeners —
|
|
92
|
+
it emits and hands work to the transport.
|
|
93
|
+
|
|
72
94
|
### 2. Handlers run on the DI-resolved instance
|
|
73
95
|
|
|
74
96
|
The decorated method is invoked on the real provider instance, so injected
|
|
@@ -86,17 +108,21 @@ export class AlertReactions {
|
|
|
86
108
|
}
|
|
87
109
|
```
|
|
88
110
|
|
|
89
|
-
Source: `packages/core/src/nestjs/diagnostics.explorer.ts` (`
|
|
111
|
+
Source: `packages/core/src/nestjs/diagnostics.explorer.ts` (`invoke` calls `fn.call(instance, event)`).
|
|
90
112
|
|
|
91
|
-
### 3. Never-throw isolation
|
|
113
|
+
### 3. Never-throw isolation without a delivering transport
|
|
92
114
|
|
|
93
115
|
`diagnostics_channel.publish` is **synchronous**, so a subscriber that throws
|
|
94
|
-
would propagate into the emitter's call stack.
|
|
116
|
+
would propagate into the emitter's call stack. Without a delivering transport,
|
|
117
|
+
the explorer's `invoke` path
|
|
95
118
|
catches synchronous throws and attaches a `.catch` to rejected promises, logging
|
|
96
119
|
both — a reaction can never break the `emit()` that triggered it. Async handlers
|
|
97
|
-
are therefore fire-and-forget (publish cannot await).
|
|
120
|
+
are therefore fire-and-forget (publish cannot await). With a delivering
|
|
121
|
+
transport (`queue`, `durable`), delivery happens once, from the emitting
|
|
122
|
+
process, and the handler's error rejects `invoke` so the transport can retry
|
|
123
|
+
instead of being swallowed.
|
|
98
124
|
|
|
99
|
-
Source: `packages/core/src/nestjs/diagnostics.explorer.ts` (`
|
|
125
|
+
Source: `packages/core/src/nestjs/diagnostics.explorer.ts` (`invoke`, `onEvent`, `deliver`).
|
|
100
126
|
|
|
101
127
|
## Common mistakes
|
|
102
128
|
|
|
@@ -143,21 +169,23 @@ Source: `packages/core/src/nestjs/diagnostics.explorer.ts` (`discovery.getProvid
|
|
|
143
169
|
### Throwing in a handler expecting the framework to retry
|
|
144
170
|
|
|
145
171
|
```ts
|
|
146
|
-
// Wrong — assuming a throw bubbles up or triggers a retry.
|
|
172
|
+
// Wrong — assuming a throw bubbles up or triggers a retry (without a delivering transport it will NOT — it is logged and swallowed).
|
|
147
173
|
@OnDiagnostic('billing', 'invoice-paid')
|
|
148
174
|
onPaid(e: DiagnosticEvent) {
|
|
149
|
-
throw new Error('will be retried'); //
|
|
175
|
+
throw new Error('will be retried'); // only retried with transports.queue()/durable()
|
|
150
176
|
}
|
|
151
177
|
```
|
|
152
178
|
|
|
153
179
|
```ts
|
|
154
|
-
// Correct — handle failures inside the reaction; it is fire-and-forget.
|
|
180
|
+
// Correct — handle failures inside the reaction when running without a delivering transport; it is fire-and-forget.
|
|
155
181
|
@OnDiagnostic('billing', 'invoice-paid')
|
|
156
182
|
async onPaid(e: DiagnosticEvent) {
|
|
157
183
|
try { await this.work(e); } catch (err) { this.logger.warn(err); }
|
|
158
184
|
}
|
|
159
185
|
```
|
|
160
186
|
|
|
161
|
-
|
|
162
|
-
is no delivery guarantee, retry, or replay.
|
|
163
|
-
|
|
187
|
+
Without a delivering transport, the explorer swallows throws/rejections by design, so emission stays safe — there
|
|
188
|
+
is no delivery guarantee, retry, or replay. With `transports.queue()` or
|
|
189
|
+
`transports.durable()`, the handler error propagates to the transport and is
|
|
190
|
+
retried (delivery happens once, from the emitting process).
|
|
191
|
+
Source: `packages/core/src/nestjs/diagnostics.explorer.ts` (`invoke`, `onEvent`).
|
|
@@ -42,7 +42,8 @@ export class AuthzService {
|
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
Span events ride `aviary:<lib>:<event>:<phase>`; the base `aviary:<lib>:<event>`
|
|
45
|
-
name is what gets registered for discovery. A `SpanEvent` carries `v`,
|
|
45
|
+
name is what gets registered for discovery. A `SpanEvent` carries `v`, a unique
|
|
46
|
+
`id` (a UUID stamped by `trace`; correlate phases with `spanId`), `ts`,
|
|
46
47
|
`lib`, `event`, `phase`, a per-span `spanId`, optional `traceId`, and
|
|
47
48
|
`payload` / `result` / `error` / `durationMs` depending on the phase.
|
|
48
49
|
|