@fluojs/cqrs 2.0.0 → 3.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.
Files changed (45) hide show
  1. package/README.ko.md +25 -5
  2. package/README.md +25 -5
  3. package/dist/buses/command-bus.d.ts +10 -0
  4. package/dist/buses/command-bus.d.ts.map +1 -1
  5. package/dist/buses/command-bus.js +14 -0
  6. package/dist/buses/event-bus.d.ts +11 -2
  7. package/dist/buses/event-bus.d.ts.map +1 -1
  8. package/dist/buses/event-bus.js +40 -8
  9. package/dist/buses/publish-drain-tracker.d.ts.map +1 -1
  10. package/dist/buses/publish-drain-tracker.js +3 -0
  11. package/dist/buses/query-bus.d.ts +10 -0
  12. package/dist/buses/query-bus.d.ts.map +1 -1
  13. package/dist/buses/query-bus.js +14 -0
  14. package/dist/buses/saga-bus.d.ts +15 -2
  15. package/dist/buses/saga-bus.d.ts.map +1 -1
  16. package/dist/buses/saga-bus.js +87 -27
  17. package/dist/buses/saga-continuation.d.ts +14 -0
  18. package/dist/buses/saga-continuation.d.ts.map +1 -0
  19. package/dist/buses/saga-continuation.js +24 -0
  20. package/dist/buses/saga-topology.d.ts +4 -1
  21. package/dist/buses/saga-topology.d.ts.map +1 -1
  22. package/dist/buses/saga-topology.js +9 -2
  23. package/dist/buses/shutdown-deadline.d.ts +23 -0
  24. package/dist/buses/shutdown-deadline.d.ts.map +1 -0
  25. package/dist/buses/shutdown-deadline.js +31 -0
  26. package/dist/decorators.d.ts.map +1 -1
  27. package/dist/decorators.js +15 -1
  28. package/dist/discovery.d.ts +2 -0
  29. package/dist/discovery.d.ts.map +1 -1
  30. package/dist/discovery.js +80 -4
  31. package/dist/dispatch-context.d.ts +2 -0
  32. package/dist/dispatch-context.d.ts.map +1 -1
  33. package/dist/dispatch-context.js +1 -0
  34. package/dist/errors.d.ts +4 -2
  35. package/dist/errors.d.ts.map +1 -1
  36. package/dist/errors.js +4 -2
  37. package/dist/module.d.ts +4 -1
  38. package/dist/module.d.ts.map +1 -1
  39. package/dist/module.js +17 -4
  40. package/dist/status.d.ts +4 -0
  41. package/dist/status.d.ts.map +1 -1
  42. package/dist/status.js +10 -6
  43. package/dist/types.d.ts +2 -0
  44. package/dist/types.d.ts.map +1 -1
  45. package/package.json +7 -7
package/README.ko.md CHANGED
@@ -24,6 +24,10 @@ fluo 애플리케이션을 위한 CQRS 패키지입니다. 부트스트랩 시
24
24
  npm install @fluojs/cqrs
25
25
  ```
26
26
 
27
+ ### Node.js 지원
28
+
29
+ `@fluojs/cqrs`는 패키지 자체의 지원 계약으로 Node.js `>=24.0.0 <27`을 지원합니다. Node.js 24 미만과 Node.js 27+는 지원하지 않습니다.
30
+
27
31
  ## 사용 시점
28
32
 
29
33
  - "의도"(Command/Query)와 "실행"(Handler)을 분리하고 싶을 때 사용합니다.
@@ -168,19 +172,19 @@ class UserSaga implements ISaga<UserCreatedEvent> {
168
172
  }
169
173
  ```
170
174
 
171
- Saga 실행은 같은 프로세스 안에서 동일 provider-token/event route 순환 재진입하거나 중첩 hop 수가 32넘으면 `SagaTopologyError`로 즉시 실패합니다. 같은 decorated saga class사용하는 서로 다른 singleton token은 별도의 fan-out route로 유지됩니다. 서로 다른 이벤트 단계를 순차 처리하는 multi-stage saga는 계속 허용되지만, in-process saga graph 전체는 비순환(acyclic) 구조를 유지해야 하며, 의도적인 순환/피드백 루프나 더 긴 체인은 외부 transport, scheduler, 또는 다른 bounded boundary 뒤로 이동해야 합니다.
175
+ Saga 실행은 singleton provider token마다 하나의 활성 `handle(...)` 호출만 유지합니다. Saga가 동일 token이 소유한 다른 event route publish하면 CQRS는 이를 token의 전역 FIFO execution chain에 serialized continuation으로 기록하고, 현재 `handle(...)` 호출을 끝낸 뒤 enqueue 순서대로 queued work실행합니다. 이 공유 순서는 nested continuation, 외부 publication, awaited delegated `@OnEvent(...)` subscriber에서 발생한 publication에 모두 적용되므로 기본 `waitForHandlers` 재진입이 deadlock하지 않고 이미 token에 enqueue된 work추월하지 않습니다. 따라서 nested `publish(...)`는 막힌 token을 기다리지 않고 resolve되며, 바깥 publicationcontinuation과 위임 event publication이 settle될 때까지 계속 기다립니다. 이미 활성 상태인 provider-token/event route로 다시 진입하면 여전히 `SagaTopologyError`로 즉시 실패하고, 중첩 hop 수가 32를 넘어도 실패합니다. 의도적인 순환/피드백 루프나 더 긴 chain은 외부 transport, scheduler, 또는 다른 bounded boundary 뒤로 이동해야 합니다.
172
176
 
173
177
  Saga, command handler, query handler, event handler 안에서 다시 CQRS `execute(...)`, `publish(...)`, `publishAll(...)`를 호출할 때는 optional `CqrsDispatchContext` 인자를 그대로 전달하세요. CQRS는 이 명시적인 runtime-agnostic context로 Node.js async-local API에 의존하지 않고 nested dispatch 전반의 saga topology check를 유지합니다. 이 context는 opaque, frozen fieldless pass-through value이며, 신뢰하는 topology와 shutdown-drain state는 CQRS 내부에 비공개로 유지됩니다. Caller-shaped object와 복사된 값은 신뢰된 runtime state를 운반하지 않으므로 context를 직접 생성, 복제, 검사, mutate하지 마세요.
174
178
 
175
179
  ### Event 발행 계약
176
180
 
177
- `CqrsEventBusService.publish(event)`는 CQRS event pipeline을 고정된 순서로 실행합니다. 먼저 일치하는 `@EventHandler(...)` provider를 실행하고, 그다음 일치하는 `@Saga(...)` provider를 실행한 뒤, 마지막으로 `@fluojs/event-bus`로 위임 발행합니다. `publishAll(events)`는 각 event의 CQRS handler, saga, 위임 발행 호출을 기다린 뒤 다음 event를 발행하므로 입력 순서를 보존합니다. 애플리케이션 shutdown 중에는 CQRS event bus가 진행 중인 `publish(...)` pipeline, `publishAll(...)` sequence, saga execution chain이 settle될 때까지 기다린 뒤 stopped 상태로 전환합니다. Command bus와 query bus는 shutdown이 시작되면 새로운 `execute(...)` 호출을 거부하고 shutdown 중 preload된 handler cache를 정리하므로, close 이후 dispatch가 오래된 provider instance를 재사용할 수 없습니다. Shutdown이 시작되면 brand-new external `publish(...)`, `publishAll(...)`, direct saga dispatch 호출은 거부됩니다. 이미 활성화된 handler나 saga에서 호출되는 nested `publish(...)` 또는 `publishAll(...)`은 CQRS가 제공한 `CqrsDispatchContext`를 그대로 전달할 때만 계속 진행할 수 있습니다. 이렇게 하면 drain 작업은 활성 pipeline 안에 머무르고 관련 없는 caller는 계속 거부됩니다. 이미 진행 중인 publish와 saga 작업은 bounded shutdown window 안에서 계속 drain됩니다. Shutdown drain은 기본값이 5000ms인 `CqrsModule.forRoot({ shutdown: { drainTimeoutMs } })`로 제한됩니다. CQRS handler, saga 또는 위임 publish chain이 이 bound 이후에도 멈춰 있으면 CQRS는 degraded status diagnostic을 기록하고 경고를 남긴 뒤 애플리케이션 close를 무기한 hang시키지 않고 계속 진행합니다. `CqrsModule.forRoot({ eventBus: { publish: { waitForHandlers: false } } })`로 설정한 경우 위임 발행 호출은 일치하는 `@OnEvent(...)` subscriber가 완료되기 전에 resolve될 수 있으므로, 이 모드에서 `publish(...)`, `publishAll(...)`, shutdown drain 완료는 subscriber 완료를 의미하지 않습니다.
181
+ `CqrsEventBusService.publish(event)`는 CQRS event pipeline을 고정된 순서로 실행합니다. 먼저 일치하는 `@EventHandler(...)` provider를 실행하고, 그다음 일치하는 `@Saga(...)` provider를 실행한 뒤, 마지막으로 `@fluojs/event-bus`로 위임 발행합니다. `publishAll(events)`는 각 event의 CQRS handler, saga, 위임 발행 호출을 기다린 뒤 다음 event를 발행하므로 입력 순서를 보존합니다. 애플리케이션 shutdown 중에는 CQRS event bus가 진행 중인 `publish(...)` pipeline, `publishAll(...)` sequence, saga execution chain이 settle될 때까지 기다린 뒤 stopped 상태로 전환합니다. Command bus와 query bus는 shutdown이 시작되면 새로운 `execute(...)` 호출을 거부하고 shutdown 중 preload된 handler cache를 정리하므로, close 이후 dispatch가 오래된 provider instance를 재사용할 수 없습니다. Shutdown이 시작되면 brand-new external `publish(...)`, `publishAll(...)`, direct saga dispatch 호출은 거부됩니다. 이미 활성화된 handler나 saga에서 호출되는 nested `publish(...)` 또는 `publishAll(...)`은 CQRS가 제공한 `CqrsDispatchContext`를 그대로 전달할 때만 계속 진행할 수 있습니다. 이렇게 하면 drain 작업은 활성 pipeline 안에 머무르고 관련 없는 caller는 계속 거부됩니다. 이미 진행 중인 publish와 saga 작업은 하나의 absolute shutdown window 안에서 drain됩니다. `CqrsModule.forRoot({ shutdown: { drainTimeoutMs } })`는 기본값 5000ms의 CQRS 전체 bound를 설정하며, 위임 `@fluojs/event-bus` shutdown은 항상 남은 budget을 상속합니다. 명시적인 `eventBus.shutdown.drainTimeoutMs`는 이 cap을 더 줄일 수만 있고 공유 CQRS deadline을 연장할 수 없습니다. CQRS handler, saga 또는 위임 publish chain이 이 bound 만료된 뒤에도 멈춰 있으면 CQRS는 degraded status diagnostic을 기록하고 경고를 남긴 뒤 애플리케이션 close를 무기한 hang시키지 않고 계속 진행합니다. `CqrsModule.forRoot({ eventBus: { publish: { waitForHandlers: false } } })`로 설정한 경우 위임 발행 호출은 일치하는 `@OnEvent(...)` subscriber가 완료되기 전에 resolve될 수 있으므로, 이 모드에서 `publish(...)`, `publishAll(...)`, shutdown drain 완료는 subscriber 완료를 의미하지 않습니다.
178
182
 
179
183
  각 CQRS event handler와 saga는 매칭된 event prototype이 복원된 격리 event 복사본을 받습니다. 이 복사본을 mutate해도 변경은 현재 handler 또는 saga route 안에만 머물며, 다른 CQRS handler, saga, 원본 event 객체, 또는 위임된 `@fluojs/event-bus` subscriber에는 보이지 않습니다. 위임된 event-bus 발행은 CQRS side effect가 끝난 뒤 원본 event를 받으므로, `@OnEvent(...)` projection과 transport는 CQRS handler가 mutate한 복사본이 아니라 호출자가 소유한 payload를 관찰합니다.
180
184
 
181
185
  Event class는 payload state를 clone 가능하고 enumerable하게 유지해야 합니다. 문자열 key와 symbol key를 가진 enumerable payload field는 shared core clone fallback으로 보존되지만, 열린 socket, function, process-local handle처럼 의도적으로 clone할 수 없는 resource는 발행 전에 ID나 다른 serializable boundary로 표현해야 합니다.
182
186
 
183
- CQRS handler, event handler, saga는 singleton provider에서만 discovery됩니다. Non-singleton registration은 경고와 함께 건너뜁니다. Event handler와 saga fan-out은 singleton provider token으로 구분되므로 같은 decorated class를 사용해도 서로 다른 token은 별도 route로 유지됩니다.
187
+ CQRS handler, event handler, saga는 singleton provider에서만 discovery됩니다. Discovery는 direct class와 `useClass` provider, class token이 CQRS metadata를 가진 `useFactory` provider, instance constructor가 CQRS metadata를 가진 `useValue` provider를 지원합니다. Non-singleton registration은 경고와 함께 건너뜁니다. Event handler와 saga fan-out은 singleton provider token으로 구분되므로 같은 decorated class를 사용해도 서로 다른 token은 별도 route로 유지됩니다.
184
188
 
185
189
  ### 심볼 토큰
186
190
 
@@ -221,12 +225,28 @@ class TokenInjectedService {
221
225
  - `DuplicateCommandHandlerError`, `DuplicateQueryHandlerError`: 서로 다른 singleton provider가 같은 command 또는 query type을 claim할 때 발생합니다.
222
226
  - `DuplicateEventHandlerError`: 호환성을 위해서만 export가 유지되며, event-handler discovery는 이 오류를 throw하거나 중복 registration을 failure로 취급하지 않습니다. 같은 provider token과 event route가 반복 discovery되면 조용히 deduplicate하고, 서로 다른 singleton provider token은 discovery 순서대로 fan-out되는 유효한 route로 유지합니다.
223
227
  - `SagaExecutionError`: 예상하지 못한 non-Fluo saga 실패를 감쌉니다.
224
- - `SagaTopologyError`: 자기 트리거, 순환, 또는 과도하게 깊은 in-process saga graph를 감지했을 때 발생합니다.
228
+ - `SagaTopologyError`: 활성 provider-token/event-route cycle 또는 과도하게 깊은 in-process saga graph를 감지했을 때 발생합니다.
225
229
 
226
230
  ### status와 metadata
227
- - `createCqrsPlatformStatusSnapshot(...)`: diagnostics와 health surface를 위한 CQRS status snapshot을 생성합니다.
231
+ - `createCqrsPlatformStatusSnapshot(...)`: diagnostics와 health surface를 위한 CQRS status snapshot을 생성합니다. Snapshot `details`는 Command, Query, Event handler, saga의 탐색된 개수와 각 lifecycle summary를 보고합니다. Command와 Query adapter input은 호환성을 위해 optional로 유지하며, 생략하면 탐색된 handler 수는 0이고 lifecycle은 CQRS event lifecycle을 사용합니다.
232
+ - `CqrsEventBusService.createPlatformStatusSnapshot()`: live bus state에서 Command와 Query discovery summary를 채웁니다. Snapshot details는 handler descriptor, provider token, saga topology를 절대 노출하지 않으며 Command와 Query summary는 기존 event/saga readiness 또는 health semantics를 바꾸지 않습니다.
228
233
  - command, query, event, saga registration을 검사해야 하는 framework package를 위해 metadata helper와 symbol이 export됩니다.
229
234
 
235
+ #### Status snapshot field
236
+
237
+ 모든 CQRS snapshot은 `readiness`, `health`, `ownership`, `details`를 가집니다. `ownership`은 항상 `externallyManaged: false`, `ownsResources: false`를 보고합니다. CQRS는 자체 in-process lifecycle을 관찰하며 caller-owned external resource를 소유한다고 주장하지 않습니다.
238
+
239
+ | `details` field | 의미 |
240
+ | --- | --- |
241
+ | `dependencies` | 위임된 event-bus dependency를 나타내는 항상 `['event-bus.default']` 값입니다. |
242
+ | `commandHandlersDiscovered`, `queryHandlersDiscovered`, `eventHandlersDiscovered`, `sagasDiscovered` | 현재 탐색된 singleton handler 또는 saga의 개수입니다. Command/Query adapter input을 생략하면 `0`을 사용하며, shutdown 후 live-bus count는 `0`입니다. |
243
+ | `commandLifecycleState`, `queryLifecycleState`, `lifecycleState`, `sagaLifecycleState` | Command, Query, event-pipeline, saga runtime의 lifecycle state입니다. Command/Query adapter input을 생략하면 `lifecycleState`로 fallback합니다. |
244
+ | `inFlightSagaExecutions` | 현재 runtime이 소유한 saga execution 수입니다. |
245
+ | `shutdownDrainTimeoutMs` | 설정된 bounded shutdown-drain window입니다. |
246
+ | `shutdownDrainTimeouts`, `sagaShutdownDrainTimeouts` | event pipeline과 saga runtime에서 기록된 bounded drain timeout입니다. |
247
+
248
+ 유효한 lifecycle state는 `created`, `discovering`, `ready`, `stopping`, `stopped`, `failed`입니다. Readiness는 event와 saga state를 다음 순서로 평가합니다. 둘 다 `ready`이면 `ready`, 그 외에는 하나라도 `discovering`이면 `degraded`, 그 외에는 하나라도 `stopping`이면 `not-ready`, 그 외에는 하나라도 `stopped` 또는 `failed`이면 `not-ready`, `created`를 포함한 나머지 조합은 `not-ready`입니다. Health는 다음 순서로 평가합니다. 0이 아닌 drain-timeout counter가 하나라도 있으면 `degraded`, 그 외에는 하나라도 `stopped` 또는 `failed`이면 `unhealthy`, 그 외에는 하나라도 `discovering` 또는 `stopping`이면 `degraded`, 나머지 조합은 `healthy`입니다. Command와 Query lifecycle field는 diagnostic 전용이며 기존 event/saga readiness 또는 health rule을 바꾸지 않습니다.
249
+
230
250
  ## 관련 패키지
231
251
 
232
252
  - `@fluojs/event-bus`: `CqrsEventBusService`에서 사용하는 하위 이벤트 분산 패키지입니다.
package/README.md CHANGED
@@ -24,6 +24,10 @@ CQRS primitives for fluo applications with bootstrap-time handler discovery, com
24
24
  npm install @fluojs/cqrs
25
25
  ```
26
26
 
27
+ ### Node.js Support
28
+
29
+ `@fluojs/cqrs` supports Node.js `>=24.0.0 <27` as its package-owned support contract. Node.js versions below 24 and Node.js 27+ are not supported.
30
+
27
31
  ## When to Use
28
32
 
29
33
  - When you want to decouple the "intent" (Commands/Queries) from the "execution" (Handlers).
@@ -168,19 +172,19 @@ class UserSaga implements ISaga<UserCreatedEvent> {
168
172
  }
169
173
  ```
170
174
 
171
- Saga execution fails fast with `SagaTopologyError` when an in-process publish chain re-enters the same provider-token/event route cyclically or exceeds 32 nested saga hops. Distinct singleton tokens that use the same decorated saga class remain distinct fan-out routes. Multi-stage sagas may still react to different event types in sequence, but in-process saga graphs must stay acyclic overall; move intentionally cyclic or long-running feedback loops behind an external transport, scheduler, or other bounded boundary.
175
+ Saga execution keeps one active `handle(...)` call per singleton provider token. When a saga publishes a different event route owned by that same token, CQRS records a serialized continuation on the token's global FIFO execution chain, lets the current `handle(...)` call finish, and then runs queued work in enqueue order. This shared ordering covers nested continuations, external publications, and publications from awaited delegated `@OnEvent(...)` subscribers, so default `waitForHandlers` re-entry does not deadlock and work already enqueued for the token is not overtaken. The nested `publish(...)` resolves without awaiting the blocked token, while the outer publication still waits for the continuation and delegated event publication to settle. Re-entering an already active provider-token/event route still fails fast with `SagaTopologyError`, as does exceeding 32 nested saga hops. Move intentionally cyclic or long-running feedback loops behind an external transport, scheduler, or other bounded boundary.
172
176
 
173
177
  When a saga, command handler, query handler, or event handler performs another CQRS `execute(...)`, `publish(...)`, or `publishAll(...)` call, pass the optional `CqrsDispatchContext` argument through unchanged. CQRS uses this explicit runtime-agnostic context to keep saga topology checks intact across nested dispatch without relying on Node.js async-local APIs. The context is an opaque, frozen fieldless pass-through value; trusted topology and shutdown-drain state remains private to CQRS. Do not construct, clone, inspect, or mutate it because caller-shaped objects and copied values do not carry trusted runtime state.
174
178
 
175
179
  ### Event Publishing Contracts
176
180
 
177
- `CqrsEventBusService.publish(event)` runs the CQRS event pipeline in a fixed order: matching `@EventHandler(...)` providers first, matching `@Saga(...)` providers second, and delegated `@fluojs/event-bus` publication last. `publishAll(events)` preserves the input order by awaiting each event's CQRS handlers, sagas, and delegated publication call before publishing the next event. During application shutdown, the CQRS event bus waits for active `publish(...)` pipelines, `publishAll(...)` sequences, and saga execution chains to settle before marking itself stopped. Command and query buses reject new `execute(...)` calls once shutdown starts and clear their preloaded handler caches during shutdown, so post-close dispatch cannot reuse stale provider instances. Once shutdown starts, brand-new external `publish(...)`, `publishAll(...)`, and direct saga dispatch calls are rejected. A nested `publish(...)` or `publishAll(...)` invoked from an already active handler or saga may continue only when it passes through the CQRS-provided `CqrsDispatchContext`; this keeps drain work inside the active pipeline while still rejecting unrelated callers. Already active publish and saga work continues draining inside the bounded shutdown window. Shutdown drain is bounded by `CqrsModule.forRoot({ shutdown: { drainTimeoutMs } })`, which defaults to 5000ms; if a CQRS handler, saga, or delegated publish chain is still stuck after the bound, CQRS records degraded status diagnostics, logs a warning, and lets application close continue instead of hanging indefinitely. When `CqrsModule.forRoot({ eventBus: { publish: { waitForHandlers: false } } })` is configured, the delegated publication call can resolve before matching `@OnEvent(...)` subscribers finish, so `publish(...)`, `publishAll(...)`, and shutdown drain completion do not imply subscriber completion in that mode.
181
+ `CqrsEventBusService.publish(event)` runs the CQRS event pipeline in a fixed order: matching `@EventHandler(...)` providers first, matching `@Saga(...)` providers second, and delegated `@fluojs/event-bus` publication last. `publishAll(events)` preserves the input order by awaiting each event's CQRS handlers, sagas, and delegated publication call before publishing the next event. During application shutdown, the CQRS event bus waits for active `publish(...)` pipelines, `publishAll(...)` sequences, and saga execution chains to settle before marking itself stopped. Command and query buses reject new `execute(...)` calls once shutdown starts and clear their preloaded handler caches during shutdown, so post-close dispatch cannot reuse stale provider instances. Once shutdown starts, brand-new external `publish(...)`, `publishAll(...)`, and direct saga dispatch calls are rejected. A nested `publish(...)` or `publishAll(...)` invoked from an already active handler or saga may continue only when it passes through the CQRS-provided `CqrsDispatchContext`; this keeps drain work inside the active pipeline while still rejecting unrelated callers. Already active publish and saga work drains inside one absolute shutdown window. `CqrsModule.forRoot({ shutdown: { drainTimeoutMs } })` sets that CQRS-wide bound and defaults to 5000ms; delegated `@fluojs/event-bus` shutdown always inherits its remaining budget. An explicit `eventBus.shutdown.drainTimeoutMs` may tighten that cap, but never extend the shared CQRS deadline. If a CQRS handler, saga, or delegated publish chain is still stuck when that bound expires, CQRS records degraded status diagnostics, logs a warning, and lets application close continue instead of hanging indefinitely. When `CqrsModule.forRoot({ eventBus: { publish: { waitForHandlers: false } } })` is configured, the delegated publication call can resolve before matching `@OnEvent(...)` subscribers finish, so `publish(...)`, `publishAll(...)`, and shutdown drain completion do not imply subscriber completion in that mode.
178
182
 
179
183
  Each CQRS event handler and saga receives an isolated event copy with the matched event prototype restored. Mutating that copy is local to the current handler or saga route; those mutations are not visible to other CQRS handlers, sagas, the original event object, or delegated `@fluojs/event-bus` subscribers. The delegated event-bus publication receives the original event after CQRS side effects complete, so `@OnEvent(...)` projections and transports observe the caller-owned payload rather than a CQRS handler's mutated copy.
180
184
 
181
185
  Event classes should keep their payload state cloneable and enumerable. String-keyed and symbol-keyed enumerable payload fields are preserved by the shared core clone fallback, while intentionally non-cloneable resources such as open sockets, functions, or process-local handles should be represented by IDs or other serializable boundaries before publishing.
182
186
 
183
- CQRS handlers, event handlers, and sagas are discovered only on singleton providers. Non-singleton registrations are skipped with warnings. Event-handler and saga fan-out is keyed by singleton provider token, so distinct tokens remain distinct routes even when they use the same decorated class.
187
+ CQRS handlers, event handlers, and sagas are discovered only on singleton providers. Discovery supports direct class and `useClass` providers, `useFactory` providers whose class token carries CQRS metadata, and `useValue` providers whose instance constructor carries CQRS metadata. Non-singleton registrations are skipped with warnings. Event-handler and saga fan-out is keyed by singleton provider token, so distinct tokens remain distinct routes even when they use the same decorated class.
184
188
 
185
189
  ### Symbol Tokens
186
190
 
@@ -221,12 +225,28 @@ class TokenInjectedService {
221
225
  - `DuplicateCommandHandlerError`, `DuplicateQueryHandlerError`: Raised when different singleton providers claim the same command or query type.
222
226
  - `DuplicateEventHandlerError`: Retained only as a compatibility export; event-handler discovery does not throw it or treat duplicate registrations as failures. Repeated discovery of the same provider token and event route is silently deduplicated, while distinct singleton provider tokens remain valid fan-out routes in discovery order.
223
227
  - `SagaExecutionError`: Wraps unexpected non-Fluo saga failures.
224
- - `SagaTopologyError`: Raised when saga orchestration detects a self-triggering, cyclic, or over-deep in-process saga graph.
228
+ - `SagaTopologyError`: Raised when saga orchestration detects an active provider-token/event-route cycle or an over-deep in-process saga graph.
225
229
 
226
230
  ### Status and metadata
227
- - `createCqrsPlatformStatusSnapshot(...)`: Creates CQRS status snapshots for diagnostics and health surfaces.
231
+ - `createCqrsPlatformStatusSnapshot(...)`: Creates CQRS status snapshots for diagnostics and health surfaces. Command and query adapter inputs remain optional for compatibility and default to zero discovered handlers plus the CQRS event lifecycle when omitted.
232
+ - `CqrsEventBusService.createPlatformStatusSnapshot()`: Populates all discovery and lifecycle summaries from live bus state. Snapshot details never expose handler descriptors, provider tokens, or saga topology; command and query summaries do not change the existing event/saga readiness or health semantics.
228
233
  - Metadata helpers and symbols are exported for framework packages that need to inspect command, query, event, or saga registrations.
229
234
 
235
+ #### Status snapshot fields
236
+
237
+ Every CQRS snapshot has `readiness`, `health`, `ownership`, and `details`. `ownership` always reports `externallyManaged: false` and `ownsResources: false`: CQRS observes its own in-process lifecycle and does not claim a caller-owned external resource.
238
+
239
+ | `details` field | Meaning |
240
+ | --- | --- |
241
+ | `dependencies` | Always `['event-bus.default']`, identifying the delegated event-bus dependency. |
242
+ | `commandHandlersDiscovered`, `queryHandlersDiscovered`, `eventHandlersDiscovered`, `sagasDiscovered` | The currently discovered singleton handler or saga counts. Command/query adapter inputs default to `0` when omitted; after shutdown, live-bus counts are `0`. |
243
+ | `commandLifecycleState`, `queryLifecycleState`, `lifecycleState`, `sagaLifecycleState` | The command, query, event-pipeline, and saga runtime states. When command/query adapter inputs are omitted, their states fall back to `lifecycleState`. |
244
+ | `inFlightSagaExecutions` | Saga executions currently owned by the runtime. |
245
+ | `shutdownDrainTimeoutMs` | The configured bounded shutdown-drain window. |
246
+ | `shutdownDrainTimeouts`, `sagaShutdownDrainTimeouts` | Recorded bounded drain timeouts for the event pipeline and saga runtime. |
247
+
248
+ The lifecycle states are `created`, `discovering`, `ready`, `stopping`, `stopped`, and `failed`. Readiness evaluates event and saga state in this order: both `ready` reports `ready`; otherwise any `discovering` reports `degraded`; otherwise any `stopping` reports `not-ready`; otherwise any `stopped` or `failed` reports `not-ready`; every remaining combination, including `created`, reports `not-ready`. Health evaluates in this order: any nonzero drain-timeout counter reports `degraded`; otherwise any `stopped` or `failed` reports `unhealthy`; otherwise any `discovering` or `stopping` reports `degraded`; every remaining combination reports `healthy`. Command and query lifecycle fields remain diagnostic only and do not alter these event/saga readiness or health rules.
249
+
230
250
  ## Related Packages
231
251
 
232
252
  - `@fluojs/event-bus`: Underlying event distribution used by `CqrsEventBusService`.
@@ -17,6 +17,16 @@ export declare class CommandBusLifecycleService extends CqrsBusBase implements C
17
17
  constructor(runtimeContainer: Container, compiledModules: readonly CompiledModule[], logger: ApplicationLogger, registerRuntimeCleanup?: RuntimeCleanupRegistration);
18
18
  onApplicationBootstrap(): Promise<void>;
19
19
  onApplicationShutdown(): Promise<void>;
20
+ /**
21
+ * Returns command-handler discovery and lifecycle state for CQRS diagnostics.
22
+ *
23
+ * @returns Current discovery state, lifecycle state, and discovered command-handler count.
24
+ */
25
+ getRuntimeSnapshot(): {
26
+ discovered: boolean;
27
+ commandHandlersDiscovered: number;
28
+ lifecycleState: 'created' | 'discovering' | 'ready' | 'stopping' | 'stopped' | 'failed';
29
+ };
20
30
  /**
21
31
  * Executes one command by dispatching it to the discovered handler for its constructor.
22
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"command-bus.d.ts","sourceRoot":"","sources":["../../src/buses/command-bus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAEpJ,OAAO,EAAE,WAAW,EAA4D,MAAM,iBAAiB,CAAC;AAGxG,OAAO,KAAK,EACV,UAAU,EAGV,mBAAmB,EACnB,QAAQ,EAET,MAAM,aAAa,CAAC;AAUrB;;;;;GAKG;AACH,qBACa,0BAA2B,SAAQ,WAAY,YAAW,UAAU,EAAE,sBAAsB,EAAE,qBAAqB;IAC9H,OAAO,CAAC,WAAW,CAAoD;IACvE,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,8BAA8B,CAA2B;gBAG/D,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,sBAAsB,GAAE,0BAAkD;IAStE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;;;;;;OASG;IACG,OAAO,CAAC,QAAQ,SAAS,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoB5H,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,8BAA8B;YAMxB,gBAAgB;YAchB,gBAAgB;IAe9B,OAAO,CAAC,0BAA0B;CA2CnC"}
1
+ {"version":3,"file":"command-bus.d.ts","sourceRoot":"","sources":["../../src/buses/command-bus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAEpJ,OAAO,EAAE,WAAW,EAA4D,MAAM,iBAAiB,CAAC;AAGxG,OAAO,KAAK,EACV,UAAU,EAGV,mBAAmB,EACnB,QAAQ,EAET,MAAM,aAAa,CAAC;AAUrB;;;;;GAKG;AACH,qBACa,0BAA2B,SAAQ,WAAY,YAAW,UAAU,EAAE,sBAAsB,EAAE,qBAAqB;IAC9H,OAAO,CAAC,WAAW,CAAoD;IACvE,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,8BAA8B,CAA2B;gBAG/D,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,sBAAsB,GAAE,0BAAkD;IAStE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;OAIG;IACH,kBAAkB,IAAI;QACpB,UAAU,EAAE,OAAO,CAAC;QACpB,yBAAyB,EAAE,MAAM,CAAC;QAClC,cAAc,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;KACzF;IAUD;;;;;;;;;OASG;IACG,OAAO,CAAC,QAAQ,SAAS,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoB5H,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,8BAA8B;YAMxB,gBAAgB;YAchB,gBAAgB;IAe9B,OAAO,CAAC,0BAA0B;CA2CnC"}
@@ -59,6 +59,20 @@ class CommandBusLifecycleService extends CqrsBusBase {
59
59
  this.lifecycleState = 'stopped';
60
60
  }
61
61
 
62
+ /**
63
+ * Returns command-handler discovery and lifecycle state for CQRS diagnostics.
64
+ *
65
+ * @returns Current discovery state, lifecycle state, and discovered command-handler count.
66
+ */
67
+ getRuntimeSnapshot() {
68
+ const stopped = this.lifecycleState === 'stopped';
69
+ return {
70
+ commandHandlersDiscovered: stopped ? 0 : this.descriptors.size,
71
+ discovered: stopped ? false : this.discovered,
72
+ lifecycleState: this.lifecycleState
73
+ };
74
+ }
75
+
62
76
  /**
63
77
  * Executes one command by dispatching it to the discovered handler for its constructor.
64
78
  *
@@ -1,9 +1,12 @@
1
- import { type EventBus } from '@fluojs/event-bus';
1
+ import { type EventBus, EventBusLifecycleService } from '@fluojs/event-bus';
2
2
  import type { OnApplicationBootstrap, OnApplicationShutdown, RuntimeCleanupRegistration } from '@fluojs/runtime';
3
3
  import { CqrsBusBase } from '../discovery.js';
4
4
  import type { CqrsModuleOptions } from '../module.js';
5
5
  import type { CqrsDispatchContext, CqrsEventBus, IEvent } from '../types.js';
6
6
  import { CqrsSagaLifecycleService } from './saga-bus.js';
7
+ import { CqrsShutdownDeadline } from './shutdown-deadline.js';
8
+ import { CommandBusLifecycleService } from './command-bus.js';
9
+ import { QueryBusLifecycleService } from './query-bus.js';
7
10
  /**
8
11
  * CQRS-facing event bus that dispatches local event handlers, sagas, and the shared event transport.
9
12
  *
@@ -14,13 +17,17 @@ export declare class CqrsEventBusService extends CqrsBusBase implements CqrsEven
14
17
  private readonly eventBus;
15
18
  private readonly sagaService;
16
19
  private readonly moduleOptions;
20
+ private readonly delegatedEventBus;
21
+ private readonly shutdownDeadline;
22
+ private readonly commandService;
23
+ private readonly queryService;
17
24
  private descriptors;
18
25
  private discoveryPromise;
19
26
  private discovered;
20
27
  private readonly publishDrainTracker;
21
28
  private lifecycleState;
22
29
  private unregisterShutdownStartCleanup;
23
- constructor(eventBus: EventBus, sagaService: CqrsSagaLifecycleService, runtimeContainer: ConstructorParameters<typeof CqrsBusBase>[0], compiledModules: ConstructorParameters<typeof CqrsBusBase>[1], logger: ConstructorParameters<typeof CqrsBusBase>[2], moduleOptions?: CqrsModuleOptions, registerRuntimeCleanup?: RuntimeCleanupRegistration);
30
+ constructor(eventBus: EventBus, sagaService: CqrsSagaLifecycleService, runtimeContainer: ConstructorParameters<typeof CqrsBusBase>[0], compiledModules: ConstructorParameters<typeof CqrsBusBase>[1], logger: ConstructorParameters<typeof CqrsBusBase>[2], moduleOptions?: CqrsModuleOptions, registerRuntimeCleanup?: RuntimeCleanupRegistration, delegatedEventBus?: EventBusLifecycleService | undefined, shutdownDeadline?: CqrsShutdownDeadline, commandService?: CommandBusLifecycleService | undefined, queryService?: QueryBusLifecycleService | undefined);
24
31
  onApplicationBootstrap(): Promise<void>;
25
32
  onApplicationShutdown(): Promise<void>;
26
33
  /**
@@ -49,10 +56,12 @@ export declare class CqrsEventBusService extends CqrsBusBase implements CqrsEven
49
56
  publishAll<TEvent extends IEvent>(events: readonly TEvent[], context?: CqrsDispatchContext): Promise<void>;
50
57
  private runPublishPipeline;
51
58
  private runPublishAllPipeline;
59
+ private trackPublishPipeline;
52
60
  private assertAcceptingNewWork;
53
61
  private markApplicationShutdownStarted;
54
62
  private createPublishContext;
55
63
  private resolveShutdownDrainTimeoutMs;
64
+ private resolveRemainingShutdownDrainTimeoutMs;
56
65
  private matchEventDescriptors;
57
66
  private ensureDiscovered;
58
67
  private discoverHandlers;
@@ -1 +1 @@
1
- {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/buses/event-bus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAA+B,MAAM,mBAAmB,CAAC;AAC/E,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAGjH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAM9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAyC,MAAM,EAAiB,MAAM,aAAa,CAAC;AAGnI,OAAO,EAAiC,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAiBxF;;;;;GAKG;AACH,qBASa,mBAAoB,SAAQ,WAAY,YAAW,YAAY,EAAE,sBAAsB,EAAE,qBAAqB;IASvH,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAI5B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAbhC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0B;IAC9D,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,8BAA8B,CAA2B;gBAG9C,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,wBAAwB,EACtD,gBAAgB,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC9D,eAAe,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC7D,MAAM,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EACnC,aAAa,GAAE,iBAAsB,EACtD,sBAAsB,GAAE,0BAAkD;IAUtE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5C;;;;OAIG;IACH,4BAA4B;IAe5B;;;;;;;;OAQG;IACG,OAAO,CAAC,MAAM,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IASjG;;;;;;OAMG;IACG,UAAU,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;YASlG,kBAAkB;YAiBlB,qBAAqB;IAMnC,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,8BAA8B;IAMtC,OAAO,CAAC,oBAAoB;IAiB5B,OAAO,CAAC,6BAA6B;IAUrC,OAAO,CAAC,qBAAqB;YAIf,gBAAgB;YAchB,gBAAgB;IAe9B,OAAO,CAAC,wBAAwB;CAGjC"}
1
+ {"version":3,"file":"event-bus.d.ts","sourceRoot":"","sources":["../../src/buses/event-bus.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,QAAQ,EAAE,wBAAwB,EAA+B,MAAM,mBAAmB,CAAC;AACzG,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAGjH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAM9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGtD,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAyC,MAAM,EAAiB,MAAM,aAAa,CAAC;AAGnI,OAAO,EAAiC,wBAAwB,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,0BAA0B,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAiB1D;;;;;GAKG;AACH,qBAaa,mBAAoB,SAAQ,WAAY,YAAW,YAAY,EAAE,sBAAsB,EAAE,qBAAqB;IASvH,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,WAAW;IAI5B,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,iBAAiB;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,cAAc;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAlB/B,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAA0B;IAC9D,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,8BAA8B,CAA2B;gBAG9C,QAAQ,EAAE,QAAQ,EAClB,WAAW,EAAE,wBAAwB,EACtD,gBAAgB,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC9D,eAAe,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC7D,MAAM,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EACnC,aAAa,GAAE,iBAAsB,EACtD,sBAAsB,GAAE,0BAAkD,EACzD,iBAAiB,GAAE,wBAAwB,GAAG,SAAqB,EACnE,gBAAgB,GAAE,oBAAiD,EACnE,cAAc,GAAE,0BAA0B,GAAG,SAAqB,EAClE,YAAY,GAAE,wBAAwB,GAAG,SAAqB;IAU3E,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAY5C;;;;OAIG;IACH,4BAA4B;IAqB5B;;;;;;;;OAQG;IACG,OAAO,CAAC,MAAM,SAAS,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;IASjG;;;;;;OAMG;IACG,UAAU,CAAC,MAAM,SAAS,MAAM,EAAE,MAAM,EAAE,SAAS,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;YASlG,kBAAkB;YAuBlB,qBAAqB;YAMrB,oBAAoB;IAUlC,OAAO,CAAC,sBAAsB;IAc9B,OAAO,CAAC,8BAA8B;IAatC,OAAO,CAAC,oBAAoB;IAkB5B,OAAO,CAAC,6BAA6B;IAUrC,OAAO,CAAC,sCAAsC;IAI9C,OAAO,CAAC,qBAAqB;YAIf,gBAAgB;YAchB,gBAAgB;IAe9B,OAAO,CAAC,wBAAwB;CAGjC"}
@@ -5,7 +5,7 @@ function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e =
5
5
  function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
6
6
  function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
7
7
  import { Inject, InvariantError } from '@fluojs/core';
8
- import { EVENT_BUS as FLUO_EVENT_BUS } from '@fluojs/event-bus';
8
+ import { EventBusLifecycleService, EVENT_BUS as FLUO_EVENT_BUS } from '@fluojs/event-bus';
9
9
  import { APPLICATION_LOGGER, COMPILED_MODULES, RUNTIME_CLEANUP_REGISTRATION, RUNTIME_CONTAINER } from '@fluojs/runtime/internal';
10
10
  import { CqrsBusBase } from '../discovery.js';
11
11
  import { createInternalCqrsDispatchContext, getInternalCqrsDispatchContextState } from '../dispatch-context.js';
@@ -15,6 +15,9 @@ import { CQRS_MODULE_OPTIONS } from '../tokens.js';
15
15
  import { discoverEventHandlerDescriptors } from './event-handler-discovery.js';
16
16
  import { CqrsPublishDrainTracker } from './publish-drain-tracker.js';
17
17
  import { CQRS_SAGA_DRAIN_AUTHORIZATION, CqrsSagaLifecycleService } from './saga-bus.js';
18
+ import { CqrsShutdownDeadline } from './shutdown-deadline.js';
19
+ import { CommandBusLifecycleService } from './command-bus.js';
20
+ import { QueryBusLifecycleService } from './query-bus.js';
18
21
  const DEFAULT_SHUTDOWN_DRAIN_TIMEOUT_MS = 5000;
19
22
  function isEventHandler(value) {
20
23
  if (typeof value !== 'object' || value === null) {
@@ -32,7 +35,7 @@ function isEventHandler(value) {
32
35
  let _CqrsEventBusService;
33
36
  class CqrsEventBusService extends CqrsBusBase {
34
37
  static {
35
- [_CqrsEventBusService, _initClass] = _applyDecs(this, [Inject(FLUO_EVENT_BUS, CqrsSagaLifecycleService, RUNTIME_CONTAINER, COMPILED_MODULES, APPLICATION_LOGGER, CQRS_MODULE_OPTIONS, RUNTIME_CLEANUP_REGISTRATION)], [], 0, void 0, CqrsBusBase).c;
38
+ [_CqrsEventBusService, _initClass] = _applyDecs(this, [Inject(FLUO_EVENT_BUS, CqrsSagaLifecycleService, RUNTIME_CONTAINER, COMPILED_MODULES, APPLICATION_LOGGER, CQRS_MODULE_OPTIONS, RUNTIME_CLEANUP_REGISTRATION, EventBusLifecycleService, CqrsShutdownDeadline, CommandBusLifecycleService, QueryBusLifecycleService)], [], 0, void 0, CqrsBusBase).c;
36
39
  }
37
40
  descriptors = [];
38
41
  discoveryPromise;
@@ -40,11 +43,15 @@ class CqrsEventBusService extends CqrsBusBase {
40
43
  publishDrainTracker;
41
44
  lifecycleState = 'created';
42
45
  unregisterShutdownStartCleanup;
43
- constructor(eventBus, sagaService, runtimeContainer, compiledModules, logger, moduleOptions = {}, registerRuntimeCleanup = () => () => undefined) {
46
+ constructor(eventBus, sagaService, runtimeContainer, compiledModules, logger, moduleOptions = {}, registerRuntimeCleanup = () => () => undefined, delegatedEventBus = undefined, shutdownDeadline = new CqrsShutdownDeadline(), commandService = undefined, queryService = undefined) {
44
47
  super(runtimeContainer, compiledModules, logger);
45
48
  this.eventBus = eventBus;
46
49
  this.sagaService = sagaService;
47
50
  this.moduleOptions = moduleOptions;
51
+ this.delegatedEventBus = delegatedEventBus;
52
+ this.shutdownDeadline = shutdownDeadline;
53
+ this.commandService = commandService;
54
+ this.queryService = queryService;
48
55
  this.publishDrainTracker = new CqrsPublishDrainTracker(logger);
49
56
  this.unregisterShutdownStartCleanup = registerRuntimeCleanup(() => {
50
57
  this.markApplicationShutdownStarted();
@@ -65,7 +72,7 @@ class CqrsEventBusService extends CqrsBusBase {
65
72
  this.unregisterShutdownStartCleanup?.();
66
73
  this.unregisterShutdownStartCleanup = undefined;
67
74
  if (this.publishDrainTracker.hasActivePipelines) {
68
- await this.publishDrainTracker.drain(this.resolveShutdownDrainTimeoutMs());
75
+ await this.publishDrainTracker.drain(this.resolveRemainingShutdownDrainTimeoutMs());
69
76
  }
70
77
  this.lifecycleState = 'stopped';
71
78
  }
@@ -76,11 +83,17 @@ class CqrsEventBusService extends CqrsBusBase {
76
83
  * @returns A structured snapshot describing CQRS event-handler discovery and saga lifecycle state.
77
84
  */
78
85
  createPlatformStatusSnapshot() {
86
+ const commandSnapshot = this.commandService?.getRuntimeSnapshot();
87
+ const querySnapshot = this.queryService?.getRuntimeSnapshot();
79
88
  const sagaSnapshot = this.sagaService.getRuntimeSnapshot();
80
89
  return createCqrsPlatformStatusSnapshot({
90
+ commandHandlersDiscovered: commandSnapshot?.commandHandlersDiscovered,
91
+ commandLifecycleState: commandSnapshot?.lifecycleState,
81
92
  eventHandlersDiscovered: this.descriptors.length,
82
93
  inFlightSagaExecutions: sagaSnapshot.inFlightSagaExecutions,
83
94
  lifecycleState: this.lifecycleState,
95
+ queryHandlersDiscovered: querySnapshot?.queryHandlersDiscovered,
96
+ queryLifecycleState: querySnapshot?.lifecycleState,
84
97
  sagaLifecycleState: sagaSnapshot.lifecycleState,
85
98
  sagaShutdownDrainTimeouts: sagaSnapshot.shutdownDrainTimeouts,
86
99
  sagasDiscovered: sagaSnapshot.sagasDiscovered,
@@ -101,7 +114,7 @@ class CqrsEventBusService extends CqrsBusBase {
101
114
  async publish(event, context) {
102
115
  this.assertAcceptingNewWork('publish', context);
103
116
  const publishContext = this.createPublishContext(context);
104
- await this.publishDrainTracker.track(this.runPublishPipeline(event, publishContext.context), publishContext.drainToken);
117
+ await this.trackPublishPipeline(publishContext, this.runPublishPipeline(event, publishContext.context));
105
118
  }
106
119
 
107
120
  /**
@@ -114,7 +127,7 @@ class CqrsEventBusService extends CqrsBusBase {
114
127
  async publishAll(events, context) {
115
128
  this.assertAcceptingNewWork('publishAll', context);
116
129
  const publishContext = this.createPublishContext(context);
117
- await this.publishDrainTracker.track(this.runPublishAllPipeline(events, publishContext.context), publishContext.drainToken);
130
+ await this.trackPublishPipeline(publishContext, this.runPublishAllPipeline(events, publishContext.context));
118
131
  }
119
132
  async runPublishPipeline(event, context) {
120
133
  await this.ensureDiscovered();
@@ -125,14 +138,24 @@ class CqrsEventBusService extends CqrsBusBase {
125
138
  }
126
139
  await instance.handle(createIsolatedEvent(descriptor.eventType, event), context);
127
140
  }
128
- await this.sagaService.dispatch(event, context, CQRS_SAGA_DRAIN_AUTHORIZATION);
129
- await this.eventBus.publish(event);
141
+ await this.sagaService.dispatch(event, context, {
142
+ afterSagas: async () => this.eventBus.publish(event),
143
+ drainAuthorization: CQRS_SAGA_DRAIN_AUTHORIZATION
144
+ });
130
145
  }
131
146
  async runPublishAllPipeline(events, context) {
132
147
  for (const event of events) {
133
148
  await this.runPublishPipeline(event, context);
134
149
  }
135
150
  }
151
+ async trackPublishPipeline(publishContext, pipeline) {
152
+ const releaseSagaGraph = this.sagaService.acquireAuthorizedPipelineLease();
153
+ try {
154
+ await this.publishDrainTracker.track(pipeline, publishContext.drainToken);
155
+ } finally {
156
+ releaseSagaGraph();
157
+ }
158
+ }
136
159
  assertAcceptingNewWork(operation, context) {
137
160
  if (this.lifecycleState === 'stopped') {
138
161
  throw new InvariantError(`CQRS event bus cannot ${operation} after shutdown has started.`);
@@ -145,6 +168,11 @@ class CqrsEventBusService extends CqrsBusBase {
145
168
  }
146
169
  }
147
170
  markApplicationShutdownStarted() {
171
+ this.shutdownDeadline.start(this.resolveShutdownDrainTimeoutMs());
172
+ const deadlineAtMs = this.shutdownDeadline.deadlineAtMs();
173
+ if (deadlineAtMs !== undefined && this.delegatedEventBus) {
174
+ this.delegatedEventBus.adoptShutdownDeadline(deadlineAtMs);
175
+ }
148
176
  if (this.lifecycleState !== 'stopped') {
149
177
  this.lifecycleState = 'stopping';
150
178
  }
@@ -161,6 +189,7 @@ class CqrsEventBusService extends CqrsBusBase {
161
189
  return {
162
190
  context: createInternalCqrsDispatchContext({
163
191
  publishDrainToken: drainToken,
192
+ sagaContinuationScope: internalState?.sagaContinuationScope,
164
193
  sagaTopology: internalState?.sagaTopology
165
194
  }),
166
195
  drainToken
@@ -173,6 +202,9 @@ class CqrsEventBusService extends CqrsBusBase {
173
202
  }
174
203
  return Math.floor(timeoutMs);
175
204
  }
205
+ resolveRemainingShutdownDrainTimeoutMs() {
206
+ return this.shutdownDeadline.remainingTimeoutMs() ?? this.resolveShutdownDrainTimeoutMs();
207
+ }
176
208
  matchEventDescriptors(event) {
177
209
  return this.descriptors.filter(descriptor => event instanceof descriptor.eventType);
178
210
  }
@@ -1 +1 @@
1
- {"version":3,"file":"publish-drain-tracker.d.ts","sourceRoot":"","sources":["../../src/buses/publish-drain-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,kFAAkF;AAClF,qBAAa,uBAAuB;IAKtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4B;IAC5D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,aAAa,CAAK;gBAEG,MAAM,EAAE,iBAAiB;IAEtD,wDAAwD;IACxD,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED,4DAA4D;IAC5D,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhC;;;;;;OAMG;IACG,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlE;;;;;OAKG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAc/B,UAAU;YAgBV,iBAAiB;CAKhC"}
1
+ {"version":3,"file":"publish-drain-tracker.d.ts","sourceRoot":"","sources":["../../src/buses/publish-drain-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,kFAAkF;AAClF,qBAAa,uBAAuB;IAKtB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAJnC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAA4B;IAC5D,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,OAAO,CAAC,aAAa,CAAK;gBAEG,MAAM,EAAE,iBAAiB;IAEtD,wDAAwD;IACxD,IAAI,qBAAqB,IAAI,MAAM,CAElC;IAED,4DAA4D;IAC5D,IAAI,kBAAkB,IAAI,OAAO,CAEhC;IAED;;;;;OAKG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIhC;;;;;;OAMG;IACG,KAAK,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkBlE;;;;;OAKG;IACG,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;YAc/B,UAAU;YAoBV,iBAAiB;CAKhC"}
@@ -65,6 +65,9 @@ export class CqrsPublishDrainTracker {
65
65
  this.logger.warn(`CQRS event shutdown drain exceeded ${String(timeoutMs)}ms with ${String(this.activePipelines.size)} active publish pipeline(s); continuing shutdown.`, 'CqrsEventBusService');
66
66
  }
67
67
  async awaitDrain(timeoutMs) {
68
+ if (timeoutMs <= 0) {
69
+ return false;
70
+ }
68
71
  let timeoutId;
69
72
  const timeout = new Promise(resolve => {
70
73
  timeoutId = setTimeout(() => resolve(false), timeoutMs);
@@ -17,6 +17,16 @@ export declare class QueryBusLifecycleService extends CqrsBusBase implements Que
17
17
  constructor(runtimeContainer: Container, compiledModules: readonly CompiledModule[], logger: ApplicationLogger, registerRuntimeCleanup?: RuntimeCleanupRegistration);
18
18
  onApplicationBootstrap(): Promise<void>;
19
19
  onApplicationShutdown(): Promise<void>;
20
+ /**
21
+ * Returns query-handler discovery and lifecycle state for CQRS diagnostics.
22
+ *
23
+ * @returns Current discovery state, lifecycle state, and discovered query-handler count.
24
+ */
25
+ getRuntimeSnapshot(): {
26
+ discovered: boolean;
27
+ lifecycleState: 'created' | 'discovering' | 'ready' | 'stopping' | 'stopped' | 'failed';
28
+ queryHandlersDiscovered: number;
29
+ };
20
30
  /**
21
31
  * Executes one query by dispatching it to the discovered handler for its constructor.
22
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"query-bus.d.ts","sourceRoot":"","sources":["../../src/buses/query-bus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAA4D,MAAM,iBAAiB,CAAC;AAGxG,OAAO,KAAK,EACV,mBAAmB,EACnB,MAAM,EAEN,QAAQ,EAGT,MAAM,aAAa,CAAC;AAUrB;;;;;GAKG;AACH,qBACa,wBAAyB,SAAQ,WAAY,YAAW,QAAQ,EAAE,sBAAsB,EAAE,qBAAqB;IAC1H,OAAO,CAAC,WAAW,CAAgD;IACnE,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,8BAA8B,CAA2B;gBAG/D,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,sBAAsB,GAAE,0BAAkD;IAStE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;;;;;;OASG;IACG,OAAO,CAAC,MAAM,SAAS,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBhI,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,8BAA8B;YAMxB,gBAAgB;YAchB,gBAAgB;IAe9B,OAAO,CAAC,wBAAwB;CA2CjC"}
1
+ {"version":3,"file":"query-bus.d.ts","sourceRoot":"","sources":["../../src/buses/query-bus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EACV,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,0BAA0B,EAC3B,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAA4D,MAAM,iBAAiB,CAAC;AAGxG,OAAO,KAAK,EACV,mBAAmB,EACnB,MAAM,EAEN,QAAQ,EAGT,MAAM,aAAa,CAAC;AAUrB;;;;;GAKG;AACH,qBACa,wBAAyB,SAAQ,WAAY,YAAW,QAAQ,EAAE,sBAAsB,EAAE,qBAAqB;IAC1H,OAAO,CAAC,WAAW,CAAgD;IACnE,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,8BAA8B,CAA2B;gBAG/D,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,sBAAsB,GAAE,0BAAkD;IAStE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;OAIG;IACH,kBAAkB,IAAI;QACpB,UAAU,EAAE,OAAO,CAAC;QACpB,cAAc,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;QACxF,uBAAuB,EAAE,MAAM,CAAC;KACjC;IAUD;;;;;;;;;OASG;IACG,OAAO,CAAC,MAAM,SAAS,MAAM,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;IAoBhI,OAAO,CAAC,sBAAsB;IAM9B,OAAO,CAAC,8BAA8B;YAMxB,gBAAgB;YAchB,gBAAgB;IAe9B,OAAO,CAAC,wBAAwB;CA2CjC"}
@@ -59,6 +59,20 @@ class QueryBusLifecycleService extends CqrsBusBase {
59
59
  this.lifecycleState = 'stopped';
60
60
  }
61
61
 
62
+ /**
63
+ * Returns query-handler discovery and lifecycle state for CQRS diagnostics.
64
+ *
65
+ * @returns Current discovery state, lifecycle state, and discovered query-handler count.
66
+ */
67
+ getRuntimeSnapshot() {
68
+ const stopped = this.lifecycleState === 'stopped';
69
+ return {
70
+ discovered: stopped ? false : this.discovered,
71
+ lifecycleState: this.lifecycleState,
72
+ queryHandlersDiscovered: stopped ? 0 : this.descriptors.size
73
+ };
74
+ }
75
+
62
76
  /**
63
77
  * Executes one query by dispatching it to the discovered handler for its constructor.
64
78
  *
@@ -2,6 +2,8 @@ import type { OnApplicationBootstrap, OnApplicationShutdown, RuntimeCleanupRegis
2
2
  import { CqrsBusBase } from '../discovery.js';
3
3
  import type { CqrsModuleOptions } from '../module.js';
4
4
  import type { CqrsDispatchContext, IEvent } from '../types.js';
5
+ import { type SagaDispatchOptions } from './saga-continuation.js';
6
+ import { CqrsShutdownDeadline } from './shutdown-deadline.js';
5
7
  /** Private capability authorizing saga dispatch from an already active publish drain. */
6
8
  export declare const CQRS_SAGA_DRAIN_AUTHORIZATION: unique symbol;
7
9
  /**
@@ -12,15 +14,17 @@ export declare const CQRS_SAGA_DRAIN_AUTHORIZATION: unique symbol;
12
14
  */
13
15
  export declare class CqrsSagaLifecycleService extends CqrsBusBase implements OnApplicationBootstrap, OnApplicationShutdown {
14
16
  private readonly moduleOptions;
17
+ private readonly shutdownDeadline;
15
18
  private descriptorsByEvent;
16
19
  private discoveryPromise;
17
20
  private discovered;
18
21
  private readonly executionChains;
19
22
  private lifecycleState;
20
23
  private readonly pendingDispatches;
24
+ private authorizedPipelineLeaseCount;
21
25
  private shutdownDrainTimeouts;
22
26
  private unregisterShutdownStartCleanup;
23
- constructor(runtimeContainer: ConstructorParameters<typeof CqrsBusBase>[0], compiledModules: ConstructorParameters<typeof CqrsBusBase>[1], logger: ConstructorParameters<typeof CqrsBusBase>[2], moduleOptions?: CqrsModuleOptions, registerRuntimeCleanup?: RuntimeCleanupRegistration);
27
+ constructor(runtimeContainer: ConstructorParameters<typeof CqrsBusBase>[0], compiledModules: ConstructorParameters<typeof CqrsBusBase>[1], logger: ConstructorParameters<typeof CqrsBusBase>[2], moduleOptions?: CqrsModuleOptions, registerRuntimeCleanup?: RuntimeCleanupRegistration, shutdownDeadline?: CqrsShutdownDeadline);
24
28
  onApplicationBootstrap(): Promise<void>;
25
29
  onApplicationShutdown(): Promise<void>;
26
30
  /**
@@ -41,11 +45,20 @@ export declare class CqrsSagaLifecycleService extends CqrsBusBase implements OnA
41
45
  * @param event Event instance that may trigger one or more sagas.
42
46
  * @returns A promise that resolves once all matching saga chains for the event complete.
43
47
  */
44
- dispatch<TEvent extends IEvent>(event: TEvent, context?: CqrsDispatchContext, drainAuthorization?: typeof CQRS_SAGA_DRAIN_AUTHORIZATION): Promise<void>;
48
+ dispatch<TEvent extends IEvent>(event: TEvent, context?: CqrsDispatchContext, options?: SagaDispatchOptions<typeof CQRS_SAGA_DRAIN_AUTHORIZATION>): Promise<void>;
49
+ /**
50
+ * Retains the discovered saga graph for one active CQRS publish pipeline.
51
+ *
52
+ * @returns A release function that must run after the authorized pipeline settles.
53
+ */
54
+ acquireAuthorizedPipelineLease(): () => void;
55
+ private runDispatch;
45
56
  private assertAcceptingNewWork;
46
57
  private markApplicationShutdownStarted;
47
58
  private matchSagaDescriptors;
48
59
  private dispatchWithOrdering;
60
+ private trackPendingDispatch;
61
+ private clearStoppedSagaGraphIfQuiescent;
49
62
  private drainActiveSagaWork;
50
63
  private reportShutdownDrainTimeout;
51
64
  private resolveShutdownDrainTimeoutMs;
@@ -1 +1 @@
1
- {"version":3,"file":"saga-bus.d.ts","sourceRoot":"","sources":["../../src/buses/saga-bus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAGjH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,KAAK,EAAE,mBAAmB,EAAiB,MAAM,EAAyB,MAAM,aAAa,CAAC;AAOrG,yFAAyF;AACzF,eAAO,MAAM,6BAA6B,EAAE,OAAO,MAAmD,CAAC;AAkBvG;;;;;GAKG;AACH,qBACa,wBAAyB,SAAQ,WAAY,YAAW,sBAAsB,EAAE,qBAAqB;IAc9G,OAAO,CAAC,QAAQ,CAAC,aAAa;IAbhC,OAAO,CAAC,kBAAkB,CAA8C;IACxE,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4B;IAC9D,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,8BAA8B,CAA2B;gBAG/D,gBAAgB,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC9D,eAAe,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC7D,MAAM,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EACnC,aAAa,GAAE,iBAAsB,EACtD,sBAAsB,GAAE,0BAAkD;IAStE,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAe5C;;;;OAIG;IACH,kBAAkB,IAAI;QACpB,UAAU,EAAE,OAAO,CAAC;QACpB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,cAAc,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;QACxF,eAAe,EAAE,MAAM,CAAC;QACxB,qBAAqB,EAAE,MAAM,CAAC;KAC/B;IAUD;;;;;OAKG;IACG,QAAQ,CAAC,MAAM,SAAS,MAAM,EAClC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,mBAAmB,EAC7B,kBAAkB,CAAC,EAAE,OAAO,6BAA6B,GACxD,OAAO,CAAC,IAAI,CAAC;IAahB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,8BAA8B;IAMtC,OAAO,CAAC,oBAAoB;YAYd,oBAAoB;YAuBpB,mBAAmB;IAUjC,OAAO,CAAC,0BAA0B;IAQlC,OAAO,CAAC,6BAA6B;YAUvB,UAAU;YAoBV,gBAAgB;YAchB,gBAAgB;IAiB9B,OAAO,CAAC,uBAAuB;CAGhC"}
1
+ {"version":3,"file":"saga-bus.d.ts","sourceRoot":"","sources":["../../src/buses/saga-bus.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAC;AAGjH,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEtD,OAAO,KAAK,EAAE,mBAAmB,EAAiB,MAAM,EAAyB,MAAM,aAAa,CAAC;AACrG,OAAO,EAA8D,KAAK,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAG9H,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAK9D,yFAAyF;AACzF,eAAO,MAAM,6BAA6B,EAAE,OAAO,MAAmD,CAAC;AAkBvG;;;;;GAKG;AACH,qBAQa,wBAAyB,SAAQ,WAAY,YAAW,sBAAsB,EAAE,qBAAqB;IAe9G,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IAhBnC,OAAO,CAAC,kBAAkB,CAA8C;IACxE,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAmC;IACnE,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAA4B;IAC9D,OAAO,CAAC,4BAA4B,CAAK;IACzC,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,8BAA8B,CAA2B;gBAG/D,gBAAgB,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC9D,eAAe,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EAC7D,MAAM,EAAE,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,EACnC,aAAa,GAAE,iBAAsB,EACtD,sBAAsB,GAAE,0BAAkD,EACzD,gBAAgB,GAAE,oBAAiD;IAShF,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAYvC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAW5C;;;;OAIG;IACH,kBAAkB,IAAI;QACpB,UAAU,EAAE,OAAO,CAAC;QACpB,sBAAsB,EAAE,MAAM,CAAC;QAC/B,cAAc,EAAE,SAAS,GAAG,aAAa,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;QACxF,eAAe,EAAE,MAAM,CAAC;QACxB,qBAAqB,EAAE,MAAM,CAAC;KAC/B;IAcD;;;;;OAKG;IACG,QAAQ,CAAC,MAAM,SAAS,MAAM,EAClC,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,mBAAmB,EAC7B,OAAO,GAAE,mBAAmB,CAAC,OAAO,6BAA6B,CAAM,GACtE,OAAO,CAAC,IAAI,CAAC;IAKhB;;;;OAIG;IACH,8BAA8B,IAAI,MAAM,IAAI;YAe9B,WAAW;IA2CzB,OAAO,CAAC,sBAAsB;IAS9B,OAAO,CAAC,8BAA8B;IAQtC,OAAO,CAAC,oBAAoB;YAYd,oBAAoB;YAwBpB,oBAAoB;IAWlC,OAAO,CAAC,gCAAgC;YAgB1B,mBAAmB;IAUjC,OAAO,CAAC,0BAA0B;IAQlC,OAAO,CAAC,6BAA6B;YAUvB,UAAU;YAoBV,gBAAgB;YAchB,gBAAgB;IAiB9B,OAAO,CAAC,uBAAuB;CAGhC"}