@fluojs/event-bus 1.0.1 → 2.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.
- package/README.ko.md +6 -4
- package/README.md +7 -5
- package/dist/service.d.ts +2 -0
- package/dist/service.d.ts.map +1 -1
- package/dist/service.js +76 -11
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +4 -4
package/README.ko.md
CHANGED
|
@@ -52,7 +52,7 @@ export class NotificationService {
|
|
|
52
52
|
|
|
53
53
|
`EventBusModule`을 등록하고 `EventBusLifecycleService`를 주입받아 이벤트를 발행합니다.
|
|
54
54
|
|
|
55
|
-
인프로세스 이벤트 버스 등록은 `EventBusModule.forRoot(...)`로 구성합니다.
|
|
55
|
+
인프로세스 이벤트 버스 등록은 `EventBusModule.forRoot(...)`로 구성합니다. Event-bus provider는 기본적으로 global(`global: true`)이므로 root graph를 import하는 모듈에서 `EventBusLifecycleService`와 `EVENT_BUS` 호환성 토큰을 사용할 수 있습니다. 모듈-local visibility가 필요하면 `EventBusModule.forRoot({ global: false })`를 전달하세요.
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
58
|
import { Module, Inject } from '@fluojs/core';
|
|
@@ -75,7 +75,9 @@ export class UserService {
|
|
|
75
75
|
export class AppModule {}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
`publish(event, options?)`는 `signal`, `timeoutMs`, `waitForHandlers`를 지원합니다. `waitForHandlers`의 기본값은 `true`이며, 기다리는 로컬 핸들러와 기다리는 트랜스포트 publish는 동일한 timeout 및 cancellation bound를 공유합니다. 이러한 bound가 실제 handler 또는 transport 작업이 끝나기 전에 호출자에게 반환되는 publish promise를 settle하더라도, shutdown은 해당 underlying awaited work가 settle되거나 shutdown drain bound가 만료될 때까지 계속 추적합니다. `waitForHandlers`를 `false`로 설정하면 publish가 즉시 반환되고 timeout bound를 적용하지
|
|
78
|
+
`publish(event, options?)`는 `signal`, `timeoutMs`, `waitForHandlers`를 지원합니다. `waitForHandlers`의 기본값은 `true`이며, 기다리는 로컬 핸들러와 기다리는 트랜스포트 publish는 동일한 timeout 및 cancellation bound를 공유합니다. 이러한 bound가 실제 handler 또는 transport 작업이 끝나기 전에 호출자에게 반환되는 publish promise를 settle하더라도, shutdown은 해당 underlying awaited work가 settle되거나 shutdown drain bound가 만료될 때까지 계속 추적합니다. `waitForHandlers`를 `false`로 설정하면 publish가 즉시 반환되고 timeout bound를 적용하지 않지만, handler와 transport 작업은 background에서 계속 실행되며 shutdown drain 추적 대상에 남습니다. Shutdown 중에는 이벤트 버스가 진행 중인 awaited/background publish 및 inbound transport handler 작업을 drain한 뒤 트랜스포트를 닫고, lifecycle이 stopping에 진입한 뒤의 새 publish 호출과 shutdown 시작 뒤 도착한 inbound transport callback은 무시합니다. Shutdown drain은 기본값이 5000ms인 `EventBusModule.forRoot({ shutdown: { drainTimeoutMs } })`로 제한됩니다. 활성 dispatch 작업이 이 bound 이후에도 멈춰 있으면 bus는 degraded status diagnostic을 기록하고 경고를 남긴 뒤, 애플리케이션 close를 무기한 hang시키지 않고 transport cleanup을 계속합니다.
|
|
79
|
+
|
|
80
|
+
**마이그레이션 참고:** `waitForHandlers: false`를 사용하는 애플리케이션은 이제 background handler 및 transport 작업을 위해 `app.close()`가 최대 `shutdown.drainTimeoutMs`까지 기다린 뒤 transport cleanup을 계속할 수 있음을 shutdown budget에 반영해야 합니다. 해당 작업을 bounded하게 유지하거나 애플리케이션에 적절한 drain budget을 구성하세요.
|
|
79
81
|
|
|
80
82
|
## 일반적인 패턴
|
|
81
83
|
|
|
@@ -144,12 +146,12 @@ class UserRegisteredEvent {
|
|
|
144
146
|
}
|
|
145
147
|
```
|
|
146
148
|
|
|
147
|
-
핸들러는 imported module의 singleton provider와 controller에서 발견됩니다. Discovery는 여러 provider가 같은 구현 class를 공유하더라도 서로 다른 singleton provider identity를 유지하며, 같은 provider token과 handler method가 중복 등록된 경우에는 한 번만 호출합니다. 각 핸들러는 격리된 clone payload를 받으며, class inheritance는 `instanceof` 매칭으로 지원됩니다. 외부 트랜스포트를 구성하면 subclass event publish는 publisher process에 해당 타입의 local handler가 없더라도 subclass channel과 prototype chain의 모든 inherited event channel로 fan-out됩니다. Subclass가 직접 `static eventKey`를 선언한 경우에만 그 값을 사용하며, 그렇지 않으면 subclass channel은 class name을 유지하고 base class는 자신의 stable key를 유지합니다.
|
|
149
|
+
핸들러는 imported module의 singleton provider와 controller에서 발견됩니다. Discovery는 여러 provider가 같은 구현 class를 공유하더라도 서로 다른 singleton provider identity를 유지하며, 같은 provider token과 handler method가 중복 등록된 경우에는 한 번만 호출합니다. Event-bus bootstrap은 ready 상태를 보고하기 전에 발견된 모든 handler target을 resolve하며, 실제 handler target resolution이 실패하면 handler를 조용히 건너뛰고 ready를 보고하는 대신 bootstrap을 실패시킵니다. Discovery는 이미 handler metadata를 가진 singleton `useValue` instance와 provider token 자체가 `@OnEvent(...)` metadata를 가진 handler class인 singleton `useFactory` provider만 검사하므로, event-bus bootstrap 중 관련 없는 factory provider는 호출되지 않습니다. 각 핸들러는 격리된 clone payload를 받으며, class inheritance는 `instanceof` 매칭으로 지원됩니다. 외부 트랜스포트를 구성하면 subclass event publish는 publisher process에 해당 타입의 local handler가 없더라도 subclass channel과 prototype chain의 모든 inherited event channel로 fan-out됩니다. Subclass가 직접 `static eventKey`를 선언한 경우에만 그 값을 사용하며, 그렇지 않으면 subclass channel은 class name을 유지하고 base class는 자신의 stable key를 유지합니다.
|
|
148
150
|
|
|
149
151
|
## 공개 API 개요
|
|
150
152
|
|
|
151
153
|
### 핵심 구성 요소
|
|
152
|
-
- `EventBusModule.forRoot(
|
|
154
|
+
- `EventBusModule.forRoot({ global?, publish?, shutdown?, transport? })`: 이벤트 버스 등록을 위한 기본 진입점입니다. `global`의 기본값은 `true`이며, event-bus provider를 event-bus 모듈을 import한 모듈을 통해서만 보이게 하려면 `global: false`를 설정하세요.
|
|
153
155
|
- `EventBusLifecycleService`: 이벤트 발행(`publish(event, options?)`)과 platform status snapshot 생성을 위한 기본 서비스입니다.
|
|
154
156
|
- `@OnEvent(EventClass)`: 특정 메서드를 이벤트 핸들러로 지정하는 데코레이터입니다.
|
|
155
157
|
- `EVENT_BUS`: 발행 facade를 위한 호환성 주입 토큰입니다.
|
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ In-process event publishing and subscription for fluo. It features decorator-bas
|
|
|
10
10
|
- [When to use](#when-to-use)
|
|
11
11
|
- [Quick Start](#quick-start)
|
|
12
12
|
- [Common Patterns](#common-patterns)
|
|
13
|
-
- [Public API](#public-api)
|
|
13
|
+
- [Public API Overview](#public-api-overview)
|
|
14
14
|
- [Runtime-Specific and Integration Subpaths](#runtime-specific-and-integration-subpaths)
|
|
15
15
|
- [Related Packages](#related-packages)
|
|
16
16
|
- [Example Sources](#example-sources)
|
|
@@ -52,7 +52,7 @@ export class NotificationService {
|
|
|
52
52
|
|
|
53
53
|
Import `EventBusModule` and inject `EventBusLifecycleService` to publish events.
|
|
54
54
|
|
|
55
|
-
Use `EventBusModule.forRoot(...)` to wire the in-process event bus.
|
|
55
|
+
Use `EventBusModule.forRoot(...)` to wire the in-process event bus. Event-bus providers are global by default (`global: true`), so `EventBusLifecycleService` and the `EVENT_BUS` compatibility token are visible to modules that import the root graph. Pass `EventBusModule.forRoot({ global: false })` when you need module-local visibility instead.
|
|
56
56
|
|
|
57
57
|
```typescript
|
|
58
58
|
import { Module, Inject } from '@fluojs/core';
|
|
@@ -75,7 +75,9 @@ export class UserService {
|
|
|
75
75
|
export class AppModule {}
|
|
76
76
|
```
|
|
77
77
|
|
|
78
|
-
`publish(event, options?)` supports `signal`, `timeoutMs`, and `waitForHandlers`. `waitForHandlers` defaults to `true`; awaited local handlers and awaited transport publishes share the same timeout and cancellation bounds. When those bounds settle the caller-facing publish promise before the underlying handler or transport work finishes, shutdown still tracks that underlying awaited work until it settles or the shutdown drain bound expires. When `waitForHandlers` is set to `false`, publishing returns immediately and skips timeout bounds. During shutdown, the event bus drains in-flight awaited publish
|
|
78
|
+
`publish(event, options?)` supports `signal`, `timeoutMs`, and `waitForHandlers`. `waitForHandlers` defaults to `true`; awaited local handlers and awaited transport publishes share the same timeout and cancellation bounds. When those bounds settle the caller-facing publish promise before the underlying handler or transport work finishes, shutdown still tracks that underlying awaited work until it settles or the shutdown drain bound expires. When `waitForHandlers` is set to `false`, publishing returns immediately and skips timeout bounds, while the handler and transport work continue in the background and remain part of shutdown drain tracking. During shutdown, the event bus drains in-flight awaited and background publish work plus inbound transport handler work before closing the transport, ignores new publish calls after the lifecycle has started stopping, and ignores inbound transport callbacks that arrive after shutdown begins. Shutdown drain is bounded by `EventBusModule.forRoot({ shutdown: { drainTimeoutMs } })`, which defaults to 5000ms; if active dispatch work is still stuck after the bound, the bus records a degraded status diagnostic, logs a warning, and continues transport cleanup instead of hanging application close indefinitely.
|
|
79
|
+
|
|
80
|
+
**Migration note:** applications that use `waitForHandlers: false` should now budget for `app.close()` to wait up to `shutdown.drainTimeoutMs` for background handler and transport work before transport cleanup continues. Keep that work bounded or configure a drain budget appropriate for the application.
|
|
79
81
|
|
|
80
82
|
## Common Patterns
|
|
81
83
|
|
|
@@ -144,12 +146,12 @@ class UserRegisteredEvent {
|
|
|
144
146
|
}
|
|
145
147
|
```
|
|
146
148
|
|
|
147
|
-
Handlers are discovered from singleton providers and controllers across imported modules. Discovery keeps distinct singleton provider identities even when multiple providers share the same implementation class; duplicate registration of the same provider token and handler method is invoked only once. Each handler receives an isolated cloned payload, and class inheritance is supported through `instanceof` matching. With an external transport configured, publishing a subclass event fans out to the subclass channel and every inherited event channel in its prototype chain, even when the publisher process has no matching local handlers for those types. A subclass uses its own `static eventKey` only when it declares one directly; otherwise its class name remains the subclass channel while base classes keep their own stable keys.
|
|
149
|
+
Handlers are discovered from singleton providers and controllers across imported modules. Discovery keeps distinct singleton provider identities even when multiple providers share the same implementation class; duplicate registration of the same provider token and handler method is invoked only once. Event-bus bootstrap resolves every discovered handler target before reporting ready, and a real handler target resolution failure fails bootstrap instead of silently reporting ready with skipped handlers. Discovery inspects singleton `useValue` instances that already carry handler metadata and singleton `useFactory` providers only when their provider token is the handler class with `@OnEvent(...)` metadata, so unrelated factory providers are not invoked during event-bus bootstrap. Each handler receives an isolated cloned payload, and class inheritance is supported through `instanceof` matching. With an external transport configured, publishing a subclass event fans out to the subclass channel and every inherited event channel in its prototype chain, even when the publisher process has no matching local handlers for those types. A subclass uses its own `static eventKey` only when it declares one directly; otherwise its class name remains the subclass channel while base classes keep their own stable keys.
|
|
148
150
|
|
|
149
151
|
## Public API Overview
|
|
150
152
|
|
|
151
153
|
### Core
|
|
152
|
-
- `EventBusModule.forRoot(
|
|
154
|
+
- `EventBusModule.forRoot({ global?, publish?, shutdown?, transport? })`: Main entry point for event bus registration. `global` defaults to `true`; set `global: false` to keep event-bus providers visible only through the module that imports the event-bus module.
|
|
153
155
|
- `EventBusLifecycleService`: Primary service for publishing events (`publish(event, options?)`) and creating platform status snapshots.
|
|
154
156
|
- `@OnEvent(EventClass)`: Decorator to mark a method as an event handler.
|
|
155
157
|
- `EVENT_BUS`: Compatibility injection token for the publish facade.
|
package/dist/service.d.ts
CHANGED
|
@@ -84,6 +84,8 @@ export declare class EventBusLifecycleService implements EventBus, OnApplication
|
|
|
84
84
|
private isDuplicateHandlerRegistration;
|
|
85
85
|
private createHandlerDescriptor;
|
|
86
86
|
private discoveryCandidates;
|
|
87
|
+
private resolveProviderDiscoveryCandidate;
|
|
88
|
+
private createUnresolvedProviderDiscoveryCandidate;
|
|
87
89
|
private invokeHandler;
|
|
88
90
|
private resolveHandlerInstance;
|
|
89
91
|
}
|
package/dist/service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAMxH,OAAO,KAAK,EACV,QAAQ,EACR,qBAAqB,EAGrB,mBAAmB,EAEpB,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAY,MAAM,YAAY,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,cAAc,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAMxH,OAAO,KAAK,EACV,QAAQ,EACR,qBAAqB,EAGrB,mBAAmB,EAEpB,MAAM,YAAY,CAAC;AA6EpB;;;;;GAKG;AACH,qBACa,wBAAyB,YAAW,QAAQ,EAAE,sBAAsB,EAAE,qBAAqB;IAgBpG,OAAO,CAAC,QAAQ,CAAC,gBAAgB;IACjC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,aAAa;IAlBhC,OAAO,CAAC,WAAW,CAAgC;IACnD,OAAO,CAAC,gBAAgB,CAA4B;IACpD,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,cAAc,CAAsF;IAC5G,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAsC;IACvE,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAqB;IACxD,OAAO,CAAC,sBAAsB,CAAK;IACnC,OAAO,CAAC,wBAAwB,CAAK;IACrC,OAAO,CAAC,0BAA0B,CAAK;IACvC,OAAO,CAAC,qBAAqB,CAAK;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAA4B;IAC7D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgC;IAC1D,OAAO,CAAC,eAAe,CAAS;gBAGb,gBAAgB,EAAE,SAAS,EAC3B,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,qBAAqB;IAKjD,sBAAsB,IAAI,OAAO,CAAC,IAAI,CAAC;IAavC,qBAAqB,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB5C;;;;OAIG;IACH,4BAA4B;IAe5B;;;;;;OAMG;IACG,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC;YAY5D,cAAc;IA+B5B,OAAO,CAAC,4BAA4B;YAItB,qBAAqB;YAcrB,mBAAmB;IAUjC,OAAO,CAAC,uBAAuB;YAajB,kBAAkB;IAiBhC,OAAO,CAAC,6BAA6B;IAIrC,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,qBAAqB;IAW7B,OAAO,CAAC,+BAA+B;IAWvC,OAAO,CAAC,8BAA8B;YAMxB,yBAAyB;YAazB,gBAAgB;IAqB9B,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,kBAAkB;YAQZ,gBAAgB;IAW9B,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,2BAA2B;IAkBnC,OAAO,CAAC,gBAAgB;YAiBV,kBAAkB;IAgChC,OAAO,CAAC,0CAA0C;IAOlD,OAAO,CAAC,+BAA+B;YAwBzB,0BAA0B;YAwB1B,mDAAmD;YAInD,6BAA6B;YAa7B,cAAc;YAYd,yBAAyB;IAiCvC,OAAO,CAAC,mCAAmC;YAI7B,gCAAgC;YAmBhC,uBAAuB;YAUvB,uBAAuB;IAmBrC,OAAO,CAAC,iCAAiC;IAOzC,OAAO,CAAC,yBAAyB;YAwBnB,qBAAqB;IAuBnC,OAAO,CAAC,sBAAsB;IAqB9B,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,gBAAgB;YAmBV,0BAA0B;IAyBxC,OAAO,CAAC,+BAA+B;IAevC,OAAO,CAAC,8BAA8B;IA4BtC,OAAO,CAAC,uBAAuB;YAejB,mBAAmB;IAoDjC,OAAO,CAAC,iCAAiC;IA+CzC,OAAO,CAAC,0CAA0C;YAmBpC,aAAa;YAwBb,sBAAsB;CAsBrC"}
|
package/dist/service.js
CHANGED
|
@@ -44,6 +44,12 @@ function methodKeyToName(methodKey) {
|
|
|
44
44
|
function isClassProvider(provider) {
|
|
45
45
|
return typeof provider === 'object' && provider !== null && 'useClass' in provider;
|
|
46
46
|
}
|
|
47
|
+
function isFactoryOrValueProvider(provider) {
|
|
48
|
+
return typeof provider === 'object' && provider !== null && ('useFactory' in provider || 'useValue' in provider);
|
|
49
|
+
}
|
|
50
|
+
function hasEventHandlerMetadata(targetType) {
|
|
51
|
+
return getEventHandlerMetadataEntries(targetType.prototype).length > 0;
|
|
52
|
+
}
|
|
47
53
|
|
|
48
54
|
/**
|
|
49
55
|
* Lifecycle-managed in-process event bus with optional external transport fan-out.
|
|
@@ -219,7 +225,7 @@ class EventBusLifecycleService {
|
|
|
219
225
|
}
|
|
220
226
|
runInvocationTasksInBackground(invocationTasks) {
|
|
221
227
|
for (const task of invocationTasks) {
|
|
222
|
-
void task;
|
|
228
|
+
void this.trackActiveDispatchWork(task);
|
|
223
229
|
}
|
|
224
230
|
}
|
|
225
231
|
async invokeHandlerInBackground(descriptor, event, signal) {
|
|
@@ -261,7 +267,7 @@ class EventBusLifecycleService {
|
|
|
261
267
|
}
|
|
262
268
|
async discoverHandlers() {
|
|
263
269
|
try {
|
|
264
|
-
this.descriptors = this.discoverHandlerDescriptors();
|
|
270
|
+
this.descriptors = await this.discoverHandlerDescriptors();
|
|
265
271
|
this.handlerInstances.clear();
|
|
266
272
|
await this.preloadHandlerInstances(this.descriptors);
|
|
267
273
|
this.discovered = true;
|
|
@@ -316,8 +322,8 @@ class EventBusLifecycleService {
|
|
|
316
322
|
}
|
|
317
323
|
try {
|
|
318
324
|
const publishWork = this.transport.publish(channel, payload);
|
|
319
|
-
const
|
|
320
|
-
await this.awaitInvocationBounds(
|
|
325
|
+
const trackedPublishWork = this.trackActiveDispatchWork(publishWork);
|
|
326
|
+
await this.awaitInvocationBounds(trackedPublishWork, publishOptions);
|
|
321
327
|
} catch (error) {
|
|
322
328
|
this.transportPublishFailures += 1;
|
|
323
329
|
this.logBoundedTransportPublishError(channel, error);
|
|
@@ -508,10 +514,10 @@ class EventBusLifecycleService {
|
|
|
508
514
|
})
|
|
509
515
|
};
|
|
510
516
|
}
|
|
511
|
-
discoverHandlerDescriptors() {
|
|
517
|
+
async discoverHandlerDescriptors() {
|
|
512
518
|
const seen = new Map();
|
|
513
519
|
const descriptors = [];
|
|
514
|
-
for (const candidate of this.discoveryCandidates()) {
|
|
520
|
+
for (const candidate of await this.discoveryCandidates()) {
|
|
515
521
|
const entries = getEventHandlerMetadataEntries(candidate.targetType.prototype);
|
|
516
522
|
if (this.shouldSkipNonSingletonCandidate(candidate, entries.length)) {
|
|
517
523
|
continue;
|
|
@@ -562,8 +568,9 @@ class EventBusLifecycleService {
|
|
|
562
568
|
token: candidate.token
|
|
563
569
|
};
|
|
564
570
|
}
|
|
565
|
-
discoveryCandidates() {
|
|
571
|
+
async discoveryCandidates() {
|
|
566
572
|
const candidates = [];
|
|
573
|
+
const providerCandidates = [];
|
|
567
574
|
for (const compiledModule of this.compiledModules) {
|
|
568
575
|
for (const provider of compiledModule.definition.providers ?? []) {
|
|
569
576
|
if (typeof provider === 'function') {
|
|
@@ -582,6 +589,13 @@ class EventBusLifecycleService {
|
|
|
582
589
|
targetType: provider.useClass,
|
|
583
590
|
token: provider.provide
|
|
584
591
|
});
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
if (isFactoryOrValueProvider(provider)) {
|
|
595
|
+
providerCandidates.push({
|
|
596
|
+
moduleName: compiledModule.type.name,
|
|
597
|
+
provider
|
|
598
|
+
});
|
|
585
599
|
}
|
|
586
600
|
}
|
|
587
601
|
for (const controller of compiledModule.definition.controllers ?? []) {
|
|
@@ -593,13 +607,64 @@ class EventBusLifecycleService {
|
|
|
593
607
|
});
|
|
594
608
|
}
|
|
595
609
|
}
|
|
610
|
+
for (const candidate of providerCandidates) {
|
|
611
|
+
const resolvedCandidate = await this.resolveProviderDiscoveryCandidate(candidate);
|
|
612
|
+
if (resolvedCandidate) {
|
|
613
|
+
candidates.push(resolvedCandidate);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
596
616
|
return candidates;
|
|
597
617
|
}
|
|
618
|
+
resolveProviderDiscoveryCandidate(candidate) {
|
|
619
|
+
const provider = candidate.provider;
|
|
620
|
+
if (!('provide' in provider)) {
|
|
621
|
+
return undefined;
|
|
622
|
+
}
|
|
623
|
+
const scope = scopeFromProvider(provider);
|
|
624
|
+
const token = provider.provide;
|
|
625
|
+
if (scope !== 'singleton') {
|
|
626
|
+
return this.createUnresolvedProviderDiscoveryCandidate(candidate.moduleName, token, scope);
|
|
627
|
+
}
|
|
628
|
+
if ('useValue' in provider) {
|
|
629
|
+
const instance = provider.useValue;
|
|
630
|
+
if (typeof instance !== 'object' || instance === null) {
|
|
631
|
+
return undefined;
|
|
632
|
+
}
|
|
633
|
+
const targetType = instance.constructor;
|
|
634
|
+
if (typeof targetType !== 'function' || !hasEventHandlerMetadata(targetType)) {
|
|
635
|
+
return undefined;
|
|
636
|
+
}
|
|
637
|
+
return {
|
|
638
|
+
moduleName: candidate.moduleName,
|
|
639
|
+
scope,
|
|
640
|
+
targetType,
|
|
641
|
+
token
|
|
642
|
+
};
|
|
643
|
+
}
|
|
644
|
+
if (typeof token !== 'function' || !hasEventHandlerMetadata(token)) {
|
|
645
|
+
return undefined;
|
|
646
|
+
}
|
|
647
|
+
return {
|
|
648
|
+
moduleName: candidate.moduleName,
|
|
649
|
+
scope,
|
|
650
|
+
targetType: token,
|
|
651
|
+
token
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
createUnresolvedProviderDiscoveryCandidate(moduleName, token, scope) {
|
|
655
|
+
const tokenType = typeof token === 'function' ? token : undefined;
|
|
656
|
+
if (!tokenType) {
|
|
657
|
+
return undefined;
|
|
658
|
+
}
|
|
659
|
+
return {
|
|
660
|
+
moduleName,
|
|
661
|
+
scope,
|
|
662
|
+
targetType: tokenType,
|
|
663
|
+
token
|
|
664
|
+
};
|
|
665
|
+
}
|
|
598
666
|
async invokeHandler(descriptor, event) {
|
|
599
667
|
const instance = await this.resolveHandlerInstance(descriptor);
|
|
600
|
-
if (instance === undefined) {
|
|
601
|
-
return;
|
|
602
|
-
}
|
|
603
668
|
const value = instance[descriptor.methodKey];
|
|
604
669
|
if (typeof value !== 'function') {
|
|
605
670
|
this.logger.warn(`Event handler ${descriptor.targetName}.${descriptor.methodName} is not callable and was skipped.`, 'EventBusLifecycleService');
|
|
@@ -623,7 +688,7 @@ class EventBusLifecycleService {
|
|
|
623
688
|
} catch (error) {
|
|
624
689
|
this.handlerInstances.delete(descriptor.token);
|
|
625
690
|
this.logger.error(`Failed to resolve event handler target ${descriptor.targetName} from module ${descriptor.moduleName}.`, error, 'EventBusLifecycleService');
|
|
626
|
-
|
|
691
|
+
throw error;
|
|
627
692
|
}
|
|
628
693
|
}
|
|
629
694
|
static {
|
package/dist/types.d.ts
CHANGED
|
@@ -27,7 +27,8 @@ export interface EventPublishOptions {
|
|
|
27
27
|
export interface EventBusTransport {
|
|
28
28
|
/**
|
|
29
29
|
* Publish an event payload to the external transport under the given channel name.
|
|
30
|
-
* Called
|
|
30
|
+
* Called for each selected transport channel when a transport is configured; one local
|
|
31
|
+
* `publish()` invocation can fan out to multiple inherited event channels.
|
|
31
32
|
*/
|
|
32
33
|
publish(channel: string, payload: unknown): Promise<void>;
|
|
33
34
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE/D,qGAAqG;AACrG,MAAM,WAAW,SAAS,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IACvD,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IAChC
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE/D,qGAAqG;AACrG,MAAM,WAAW,SAAS,CAAC,MAAM,SAAS,MAAM,GAAG,MAAM;IACvD,KAAK,GAAG,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,0CAA0C;AAC1C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,kEAAkE;AAClE,MAAM,WAAW,sBAAsB;IACrC,SAAS,EAAE,SAAS,CAAC;IACrB,SAAS,EAAE,mBAAmB,CAAC;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;CACd;AAED,8EAA8E;AAC9E,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,kGAAkG;AAClG,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE1D;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExF;;OAEG;IACH,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,sFAAsF;AACtF,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE;QACR,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,eAAe,CAAC,EAAE,OAAO,CAAC;KAC3B,CAAC;IACF,kEAAkE;IAClE,QAAQ,CAAC,EAAE;QACT,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF;;;;OAIG;IACH,SAAS,CAAC,EAAE,iBAAiB,CAAC;CAC/B;AAED,+DAA+D;AAC/D,MAAM,WAAW,QAAQ;IACvB;;;;;;OAMG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACtE"}
|
package/package.json
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
"pubsub",
|
|
9
9
|
"in-process"
|
|
10
10
|
],
|
|
11
|
-
"version": "
|
|
11
|
+
"version": "2.0.0",
|
|
12
12
|
"private": false,
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"repository": {
|
|
@@ -39,9 +39,9 @@
|
|
|
39
39
|
"dist"
|
|
40
40
|
],
|
|
41
41
|
"dependencies": {
|
|
42
|
-
"@fluojs/core": "^1.0
|
|
43
|
-
"@fluojs/di": "^
|
|
44
|
-
"@fluojs/runtime": "^
|
|
42
|
+
"@fluojs/core": "^1.1.0",
|
|
43
|
+
"@fluojs/di": "^2.0.0",
|
|
44
|
+
"@fluojs/runtime": "^2.0.1"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
47
|
"ioredis": "^5.0.0"
|