@znight/core 0.4.0 → 0.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@znight/core",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Znight core runtime: compile-time DI container, lifecycle, plugins and marker decorators",
5
5
  "license": "MIT",
6
6
  "author": "Ugho STEPHAN",
package/src/errors.ts CHANGED
@@ -7,7 +7,7 @@
7
7
  * messaging, config, observability).
8
8
  * - From `ZNIGHT030`, each first-party package reserves a block of ten: `ZNIGHT030`–`039`
9
9
  * `@znight/openapi`, `ZNIGHT040`–`049` `@znight/schedule`, `ZNIGHT050`–`059` `@znight/websocket`
10
- * (reserved), `ZNIGHT060`–`069` `@znight/graphql`.
10
+ * (reserved), `ZNIGHT060`–`069` `@znight/graphql`, `ZNIGHT070`–`079` `@znight/events`.
11
11
  *
12
12
  * Within a range, codes are allocated in order without gaps. A package uses its block for its own
13
13
  * failure modes, with one catch-all code for invalid usage and options, and reuses a lower code
@@ -138,6 +138,14 @@ export const ErrorCode = {
138
138
  * type or argument the SDL does not declare, a signature that does not conform to the SDL types.
139
139
  */
140
140
  GraphQLSchemaMismatch: 'ZNIGHT068',
141
+
142
+ // ZNIGHT070–079: @znight/events (RFC 0011)
143
+ /**
144
+ * Invalid event listener: an `@OnEvent` method whose parameter is not a class (or a union of
145
+ * classes), a generic or optional event, an event class the generated module cannot import, invalid
146
+ * options, the NestJS string form, a detached listener depending on a request-scoped external.
147
+ */
148
+ InvalidEventListener: 'ZNIGHT070',
141
149
  } as const
142
150
 
143
151
  export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode]
@@ -189,6 +197,7 @@ export const ERROR_DESCRIPTIONS: Readonly<Record<ErrorCode, string>> = {
189
197
  ZNIGHT066: 'Invalid GraphQL setup: metadata, schema, GraphQLPlugin options, driver or HttpPlugin missing',
190
198
  ZNIGHT067: 'Invalid GraphQL SDL: the schema-first .graphql files cannot be read, parsed or validated',
191
199
  ZNIGHT068: 'GraphQL schema mismatch: schema-first resolvers do not cover or conform to the SDL',
200
+ ZNIGHT070: 'Invalid event listener: an @OnEvent method does not listen to a class, or its options are invalid',
192
201
  }
193
202
 
194
203
  export interface ZnightErrorOptions extends ErrorOptions {
package/src/hooks.ts CHANGED
@@ -33,6 +33,17 @@ export interface ZnightHooks {
33
33
  * emitted when listeners exist.
34
34
  */
35
35
  'graphql:operation': GraphQLOperationEvent
36
+ /**
37
+ * One publication of `@znight/events` (`EventPublisher.publish()` or `emit()`) that matched at least
38
+ * one listener (RFC 0011): wraps the inline phase with `hooks.run` when wrappers exist, then is
39
+ * emitted when listeners exist. A publication without listener produces nothing.
40
+ */
41
+ 'events:publish': EventPublishEvent
42
+ /**
43
+ * One listener invocation of `@znight/events` (RFC 0011), inline or detached: wrapped with
44
+ * `hooks.run` when wrappers exist, then emitted when listeners exist.
45
+ */
46
+ 'events:listener': EventListenerEvent
36
47
  }
37
48
 
38
49
  /**
@@ -227,6 +238,52 @@ export interface GraphQLOperationEvent {
227
238
  errors?: readonly GraphQLOperationError[]
228
239
  }
229
240
 
241
+ /** How an application event was published (`EventPublishEvent.mode`). */
242
+ export type EventPublishMode = 'publish' | 'emit'
243
+
244
+ /**
245
+ * Instrumentation event of the `events:publish` hook, produced by `@znight/events` (RFC 0011) for a
246
+ * publication that matched at least one listener. The wrappers surround the inline phase (the
247
+ * detached listeners are scheduled after it succeeded); `error` and `failedListener` are set before
248
+ * `next()` rejects.
249
+ */
250
+ export interface EventPublishEvent {
251
+ /** Class name of the event (`UserCreated`). */
252
+ readonly event: string
253
+ /** The published object. */
254
+ readonly payload: object
255
+ readonly mode: EventPublishMode
256
+ /** Number of inline listeners matched. */
257
+ readonly inline: number
258
+ /** Number of detached listeners matched. */
259
+ readonly detached: number
260
+ /** `performance.now()` when the publication started. */
261
+ readonly startTime: number
262
+ /** First inline error, set before `next()` rejects in the wrappers. */
263
+ error?: unknown
264
+ /** `Class.method` of the inline listener that failed. */
265
+ failedListener?: string
266
+ }
267
+
268
+ /**
269
+ * Instrumentation event of the `events:listener` hook, produced by `@znight/events` (RFC 0011) for
270
+ * every listener invocation. Inline listeners run in the publisher's async context, detached ones in
271
+ * a fresh scope of their own; `error` is set before `next()` rejects.
272
+ */
273
+ export interface EventListenerEvent {
274
+ /** Class name of the event. */
275
+ readonly event: string
276
+ /** The published object. */
277
+ readonly payload: object
278
+ /** `Class.method` of the listener (`WelcomeMail.send`). */
279
+ readonly listener: string
280
+ readonly detached: boolean
281
+ /** `performance.now()` when the invocation started. */
282
+ readonly startTime: number
283
+ /** What the listener threw or rejected with. */
284
+ error?: unknown
285
+ }
286
+
230
287
  /** Name of a declared hook. */
231
288
  export type HookName = keyof ZnightHooks
232
289
 
package/src/index.ts CHANGED
@@ -38,6 +38,9 @@ export {
38
38
  export { isProviderDefinition } from './definition.ts'
39
39
  export * from './errors.ts'
40
40
  export {
41
+ type EventListenerEvent,
42
+ type EventPublishEvent,
43
+ type EventPublishMode,
41
44
  type GraphQLOperationError,
42
45
  type GraphQLOperationEvent,
43
46
  type GraphQLOperationOutcome,