@asenajs/asena 0.7.1 → 0.8.1
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.md +2 -2
- package/dist/lib/adapter/AsenaAdapter.d.ts +2 -2
- package/dist/lib/adapter/AsenaAdapter.js.map +1 -1
- package/dist/lib/adapter/types/ServeOptions.d.ts +16 -0
- package/dist/lib/adapter/types/ValidationError.d.ts +53 -0
- package/dist/lib/adapter/types/ValidationError.js +24 -0
- package/dist/lib/adapter/types/ValidationError.js.map +1 -0
- package/dist/lib/adapter/types/index.d.ts +1 -0
- package/dist/lib/adapter/types/index.js +1 -0
- package/dist/lib/adapter/types/index.js.map +1 -1
- package/dist/lib/ioc/Container.d.ts +25 -0
- package/dist/lib/ioc/Container.js +47 -0
- package/dist/lib/ioc/Container.js.map +1 -1
- package/dist/lib/ioc/CoreContainer.d.ts +5 -3
- package/dist/lib/ioc/CoreContainer.js +9 -3
- package/dist/lib/ioc/CoreContainer.js.map +1 -1
- package/dist/lib/ioc/IocEngine.d.ts +50 -4
- package/dist/lib/ioc/IocEngine.js +138 -12
- package/dist/lib/ioc/IocEngine.js.map +1 -1
- package/dist/lib/ioc/component/componentRegistry.d.ts +22 -0
- package/dist/lib/ioc/component/componentRegistry.js +119 -0
- package/dist/lib/ioc/component/componentRegistry.js.map +1 -0
- package/dist/lib/ioc/component/componentUtils.js +4 -0
- package/dist/lib/ioc/component/componentUtils.js.map +1 -1
- package/dist/lib/ioc/component/decorators/Inject.js +16 -0
- package/dist/lib/ioc/component/decorators/Inject.js.map +1 -1
- package/dist/lib/ioc/component/index.d.ts +1 -0
- package/dist/lib/ioc/component/index.js +1 -0
- package/dist/lib/ioc/component/index.js.map +1 -1
- package/dist/lib/ioc/constants/ComponentConstants.d.ts +4 -0
- package/dist/lib/ioc/constants/ComponentConstants.js +5 -0
- package/dist/lib/ioc/constants/ComponentConstants.js.map +1 -1
- package/dist/lib/ioc/helper/fileHelper.d.ts +9 -0
- package/dist/lib/ioc/helper/fileHelper.js +41 -11
- package/dist/lib/ioc/helper/fileHelper.js.map +1 -1
- package/dist/lib/ioc/types/ICoreServiceNamesType.d.ts +1 -0
- package/dist/lib/ioc/types/ICoreServiceNamesType.js +1 -0
- package/dist/lib/ioc/types/ICoreServiceNamesType.js.map +1 -1
- package/dist/lib/ioc/types/InjectableComponent.d.ts +10 -0
- package/dist/lib/ioc/types/IocConfig.d.ts +7 -0
- package/dist/lib/ioc/types/decorators/ComponentType.d.ts +2 -1
- package/dist/lib/ioc/types/decorators/ComponentType.js +1 -0
- package/dist/lib/ioc/types/decorators/ComponentType.js.map +1 -1
- package/dist/lib/server/AsenaServer.d.ts +47 -3
- package/dist/lib/server/AsenaServer.js +167 -28
- package/dist/lib/server/AsenaServer.js.map +1 -1
- package/dist/lib/server/AsenaServerFactory.d.ts +38 -3
- package/dist/lib/server/AsenaServerFactory.js +21 -2
- package/dist/lib/server/AsenaServerFactory.js.map +1 -1
- package/dist/lib/server/config/AsenaConfig.d.ts +82 -4
- package/dist/lib/server/config/AsenaConfig.js +39 -1
- package/dist/lib/server/config/AsenaConfig.js.map +1 -1
- package/dist/lib/server/decorators/components/MessageController.d.ts +49 -0
- package/dist/lib/server/decorators/components/MessageController.js +62 -0
- package/dist/lib/server/decorators/components/MessageController.js.map +1 -0
- package/dist/lib/server/decorators/components/index.d.ts +1 -0
- package/dist/lib/server/decorators/components/index.js +1 -0
- package/dist/lib/server/decorators/components/index.js.map +1 -1
- package/dist/lib/server/event/EventDispatchService.d.ts +3 -7
- package/dist/lib/server/event/EventDispatchService.js +9 -40
- package/dist/lib/server/event/EventDispatchService.js.map +1 -1
- package/dist/lib/server/event/PatternHandlerIndex.d.ts +53 -0
- package/dist/lib/server/event/PatternHandlerIndex.js +100 -0
- package/dist/lib/server/event/PatternHandlerIndex.js.map +1 -0
- package/dist/lib/server/event/decorators/On.d.ts +4 -0
- package/dist/lib/server/event/decorators/On.js +6 -0
- package/dist/lib/server/event/decorators/On.js.map +1 -1
- package/dist/lib/server/event/index.d.ts +1 -0
- package/dist/lib/server/event/index.js +2 -0
- package/dist/lib/server/event/index.js.map +1 -1
- package/dist/lib/server/event/types.d.ts +12 -0
- package/dist/lib/server/health/HealthServer.d.ts +26 -0
- package/dist/lib/server/health/HealthServer.js +63 -0
- package/dist/lib/server/health/HealthServer.js.map +1 -0
- package/dist/lib/server/health/index.d.ts +1 -0
- package/dist/lib/server/health/index.js +2 -0
- package/dist/lib/server/health/index.js.map +1 -0
- package/dist/lib/server/messaging/Ulak.d.ts +156 -0
- package/dist/lib/server/messaging/Ulak.js +174 -0
- package/dist/lib/server/messaging/Ulak.js.map +1 -1
- package/dist/lib/server/messaging/types.d.ts +5 -1
- package/dist/lib/server/messaging/types.js +5 -0
- package/dist/lib/server/messaging/types.js.map +1 -1
- package/dist/lib/server/microservice/InMemoryTransport.d.ts +45 -0
- package/dist/lib/server/microservice/InMemoryTransport.js +124 -0
- package/dist/lib/server/microservice/InMemoryTransport.js.map +1 -0
- package/dist/lib/server/microservice/MicroserviceTransport.d.ts +132 -0
- package/dist/lib/server/microservice/MicroserviceTransport.js +2 -0
- package/dist/lib/server/microservice/MicroserviceTransport.js.map +1 -0
- package/dist/lib/server/microservice/decorators/EventPattern.d.ts +38 -0
- package/dist/lib/server/microservice/decorators/EventPattern.js +59 -0
- package/dist/lib/server/microservice/decorators/EventPattern.js.map +1 -0
- package/dist/lib/server/microservice/decorators/MessagePattern.d.ts +31 -0
- package/dist/lib/server/microservice/decorators/MessagePattern.js +55 -0
- package/dist/lib/server/microservice/decorators/MessagePattern.js.map +1 -0
- package/dist/lib/server/microservice/decorators/index.d.ts +2 -0
- package/dist/lib/server/microservice/decorators/index.js +3 -0
- package/dist/lib/server/microservice/decorators/index.js.map +1 -0
- package/dist/lib/server/microservice/index.d.ts +5 -0
- package/dist/lib/server/microservice/index.js +11 -0
- package/dist/lib/server/microservice/index.js.map +1 -0
- package/dist/lib/server/microservice/interceptorChain.d.ts +20 -0
- package/dist/lib/server/microservice/interceptorChain.js +39 -0
- package/dist/lib/server/microservice/interceptorChain.js.map +1 -0
- package/dist/lib/server/microservice/types.d.ts +142 -0
- package/dist/lib/server/microservice/types.js +5 -0
- package/dist/lib/server/microservice/types.js.map +1 -0
- package/dist/lib/server/src/services/PrepareEventService.d.ts +4 -1
- package/dist/lib/server/src/services/PrepareEventService.js +10 -3
- package/dist/lib/server/src/services/PrepareEventService.js.map +1 -1
- package/dist/lib/server/src/services/PrepareMicroserviceService.d.ts +66 -0
- package/dist/lib/server/src/services/PrepareMicroserviceService.js +193 -0
- package/dist/lib/server/src/services/PrepareMicroserviceService.js.map +1 -0
- package/dist/lib/test/factory/deepMock.d.ts +25 -0
- package/dist/lib/test/factory/deepMock.js +105 -0
- package/dist/lib/test/factory/deepMock.js.map +1 -0
- package/dist/lib/test/factory/ulakStub.d.ts +44 -0
- package/dist/lib/test/factory/ulakStub.js +40 -0
- package/dist/lib/test/factory/ulakStub.js.map +1 -0
- package/dist/lib/test/harness/createTestApp.d.ts +33 -0
- package/dist/lib/test/harness/createTestApp.js +105 -0
- package/dist/lib/test/harness/createTestApp.js.map +1 -0
- package/dist/lib/test/harness/createWebTest.d.ts +28 -0
- package/dist/lib/test/harness/createWebTest.js +127 -0
- package/dist/lib/test/harness/createWebTest.js.map +1 -0
- package/dist/lib/test/harness/silentLogger.d.ts +27 -0
- package/dist/lib/test/harness/silentLogger.js +54 -0
- package/dist/lib/test/harness/silentLogger.js.map +1 -0
- package/dist/lib/test/harness/types.d.ts +147 -0
- package/dist/lib/test/harness/types.js +2 -0
- package/dist/lib/test/harness/types.js.map +1 -0
- package/dist/lib/test/http/TestHttpCall.d.ts +78 -0
- package/dist/lib/test/http/TestHttpCall.js +149 -0
- package/dist/lib/test/http/TestHttpCall.js.map +1 -0
- package/dist/lib/test/http/TestHttpResponse.d.ts +46 -0
- package/dist/lib/test/http/TestHttpResponse.js +70 -0
- package/dist/lib/test/http/TestHttpResponse.js.map +1 -0
- package/dist/lib/test/index.d.ts +9 -0
- package/dist/lib/test/index.js +8 -0
- package/dist/lib/test/index.js.map +1 -1
- package/dist/lib/test/metadata/discovery.d.ts +21 -0
- package/dist/lib/test/metadata/discovery.js +37 -8
- package/dist/lib/test/metadata/discovery.js.map +1 -1
- package/dist/lib/test/mockComponent.d.ts +25 -0
- package/dist/lib/test/mockComponent.js +39 -6
- package/dist/lib/test/mockComponent.js.map +1 -1
- package/dist/lib/test/types.d.ts +13 -0
- package/package.json +11 -7
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { matchesEventPattern } from './eventPatternMatcher';
|
|
2
|
+
/**
|
|
3
|
+
* @description Shared pattern → handler index with the hybrid lookup strategy
|
|
4
|
+
* used across Asena's event and messaging systems:
|
|
5
|
+
*
|
|
6
|
+
* - Exact patterns → Map (O(1) lookup on collect)
|
|
7
|
+
* - Wildcard patterns → Array (O(n) matchesEventPattern check, smaller n)
|
|
8
|
+
*
|
|
9
|
+
* Consumers: EventDispatchService (in-process events), InMemoryTransport and
|
|
10
|
+
* RedisMicroserviceTransport (microservice event handlers). The generic type T
|
|
11
|
+
* lets each consumer store what it needs (a bare handler or a subscription object).
|
|
12
|
+
*
|
|
13
|
+
* Collection order: exact matches first (registration order), then wildcard
|
|
14
|
+
* matches (registration order).
|
|
15
|
+
*/
|
|
16
|
+
export class PatternHandlerIndex {
|
|
17
|
+
/**
|
|
18
|
+
* Exact pattern → entries (O(1) fast path)
|
|
19
|
+
*/
|
|
20
|
+
exact = new Map();
|
|
21
|
+
/**
|
|
22
|
+
* Wildcard patterns, matched with matchesEventPattern on collect
|
|
23
|
+
*/
|
|
24
|
+
wildcard = [];
|
|
25
|
+
/**
|
|
26
|
+
* Register an entry under a pattern
|
|
27
|
+
*/
|
|
28
|
+
add(pattern, entry) {
|
|
29
|
+
if (pattern.includes('*')) {
|
|
30
|
+
this.wildcard.push({ pattern, entry });
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const entries = this.exact.get(pattern) || [];
|
|
34
|
+
entries.push(entry);
|
|
35
|
+
this.exact.set(pattern, entries);
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Remove a specific entry registered under a pattern (identity comparison)
|
|
39
|
+
*
|
|
40
|
+
* @returns true if the entry was found and removed
|
|
41
|
+
*/
|
|
42
|
+
remove(pattern, entry) {
|
|
43
|
+
if (pattern.includes('*')) {
|
|
44
|
+
const index = this.wildcard.findIndex((item) => item.pattern === pattern && item.entry === entry);
|
|
45
|
+
if (index !== -1) {
|
|
46
|
+
this.wildcard.splice(index, 1);
|
|
47
|
+
return true;
|
|
48
|
+
}
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const entries = this.exact.get(pattern);
|
|
52
|
+
if (!entries) {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
const index = entries.indexOf(entry);
|
|
56
|
+
if (index === -1) {
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
entries.splice(index, 1);
|
|
60
|
+
if (!entries.length) {
|
|
61
|
+
this.exact.delete(pattern);
|
|
62
|
+
}
|
|
63
|
+
return true;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Collect all entries whose pattern matches the given event name
|
|
67
|
+
*/
|
|
68
|
+
collect(eventName) {
|
|
69
|
+
const result = [...(this.exact.get(eventName) || [])];
|
|
70
|
+
for (const item of this.wildcard) {
|
|
71
|
+
if (matchesEventPattern(eventName, item.pattern)) {
|
|
72
|
+
result.push(item.entry);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* All registered patterns - exact first (registration order), then wildcard
|
|
79
|
+
*
|
|
80
|
+
* Diagnostics only: consumers use it to explain why an expected source
|
|
81
|
+
* matched no handler (e.g. the Kafka transport's external-topic hint).
|
|
82
|
+
*/
|
|
83
|
+
patterns() {
|
|
84
|
+
return [...this.exact.keys(), ...this.wildcard.map((item) => item.pattern)];
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Whether the index holds no entries at all
|
|
88
|
+
*/
|
|
89
|
+
get isEmpty() {
|
|
90
|
+
return this.exact.size === 0 && this.wildcard.length === 0;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Remove all entries
|
|
94
|
+
*/
|
|
95
|
+
clear() {
|
|
96
|
+
this.exact.clear();
|
|
97
|
+
this.wildcard = [];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
//# sourceMappingURL=PatternHandlerIndex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PatternHandlerIndex.js","sourceRoot":"","sources":["../../../../lib/server/event/PatternHandlerIndex.ts"],"names":[],"mappings":"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"}
|
|
@@ -20,6 +20,10 @@ import type { OnParams } from '../types';
|
|
|
20
20
|
*
|
|
21
21
|
* @On({ event: 'deleted', skip: true }) // Temporarily disabled
|
|
22
22
|
* handleDeleted(eventName: string, data: any) { }
|
|
23
|
+
*
|
|
24
|
+
* // Absolute - opts out of the 'user' prefix
|
|
25
|
+
* @On({ event: 'payment.completed', prefix: false })
|
|
26
|
+
* handlePayment(eventName: string, data: any) { }
|
|
23
27
|
* }
|
|
24
28
|
*
|
|
25
29
|
* @example
|
|
@@ -21,6 +21,10 @@ import { defineTypedMetadata, getOwnTypedMetadata } from '../../../utils';
|
|
|
21
21
|
*
|
|
22
22
|
* @On({ event: 'deleted', skip: true }) // Temporarily disabled
|
|
23
23
|
* handleDeleted(eventName: string, data: any) { }
|
|
24
|
+
*
|
|
25
|
+
* // Absolute - opts out of the 'user' prefix
|
|
26
|
+
* @On({ event: 'payment.completed', prefix: false })
|
|
27
|
+
* handlePayment(eventName: string, data: any) { }
|
|
24
28
|
* }
|
|
25
29
|
*
|
|
26
30
|
* @example
|
|
@@ -46,6 +50,8 @@ export function On(params) {
|
|
|
46
50
|
handlers[propertyKey.toString()] = {
|
|
47
51
|
pattern: _params.event,
|
|
48
52
|
methodName: propertyKey.toString(),
|
|
53
|
+
// `!== false` covers the string shorthand and objects that omit the flag
|
|
54
|
+
prefix: _params.prefix !== false,
|
|
49
55
|
skip: _params.skip || false,
|
|
50
56
|
};
|
|
51
57
|
// Store updated metadata
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"On.js","sourceRoot":"","sources":["../../../../../lib/server/event/decorators/On.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1E
|
|
1
|
+
{"version":3,"file":"On.js","sourceRoot":"","sources":["../../../../../lib/server/event/decorators/On.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAG1E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,UAAU,EAAE,CAAC,MAAyB;IAC1C,oDAAoD;IACpD,MAAM,OAAO,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;IAErF,OAAO,UAAU,MAAc,EAAE,WAA4B,EAAE,UAA8B;QAC3F,qDAAqD;QACrD,MAAM,QAAQ,GACZ,mBAAmB,CACjB,kBAAkB,CAAC,gBAAgB,EACnC,MAAM,CAAC,WAAW,CACnB,IAAI,EAAE,CAAC;QAEV,8BAA8B;QAC9B,QAAQ,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC,GAAG;YACjC,OAAO,EAAE,OAAO,CAAC,KAAK;YACtB,UAAU,EAAE,WAAW,CAAC,QAAQ,EAAE;YAClC,yEAAyE;YACzE,MAAM,EAAE,OAAO,CAAC,MAAM,KAAK,KAAK;YAChC,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK;SAC5B,CAAC;QAEF,yBAAyB;QACzB,mBAAmB,CAAC,kBAAkB,CAAC,gBAAgB,EAAE,QAAQ,EAAE,MAAM,CAAC,WAAW,CAAC,CAAC;QAEvF,OAAO,UAAU,CAAC;IACpB,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { EventEmitter } from './EventEmitter';
|
|
2
2
|
export { EventDispatchService } from './EventDispatchService';
|
|
3
3
|
export { matchesEventPattern } from './eventPatternMatcher';
|
|
4
|
+
export { PatternHandlerIndex } from './PatternHandlerIndex';
|
|
4
5
|
export { emitter } from './emitter';
|
|
5
6
|
export * from './types';
|
|
6
7
|
export * from './decorators';
|
|
@@ -3,6 +3,8 @@ export { EventEmitter } from './EventEmitter';
|
|
|
3
3
|
export { EventDispatchService } from './EventDispatchService';
|
|
4
4
|
// Pattern matcher (utility)
|
|
5
5
|
export { matchesEventPattern } from './eventPatternMatcher';
|
|
6
|
+
// Shared pattern → handler index (hybrid exact/wildcard lookup)
|
|
7
|
+
export { PatternHandlerIndex } from './PatternHandlerIndex';
|
|
6
8
|
// Injection utility
|
|
7
9
|
export { emitter } from './emitter';
|
|
8
10
|
// Types
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/server/event/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,4BAA4B;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,oBAAoB;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,QAAQ;AACR,cAAc,SAAS,CAAC;AAExB,aAAa;AACb,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/server/event/index.ts"],"names":[],"mappings":"AAAA,oBAAoB;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAE9D,4BAA4B;AAC5B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,gEAAgE;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D,oBAAoB;AACpB,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,QAAQ;AACR,cAAc,SAAS,CAAC;AAExB,aAAa;AACb,cAAc,cAAc,CAAC"}
|
|
@@ -21,6 +21,13 @@ export interface OnParams {
|
|
|
21
21
|
* @example 'download.complete' or 'download.*'
|
|
22
22
|
*/
|
|
23
23
|
event: string;
|
|
24
|
+
/**
|
|
25
|
+
* Join the @EventService prefix onto `event`.
|
|
26
|
+
* Set false to listen on an absolute pattern — another domain's event
|
|
27
|
+
* vocabulary, or a global catch-all ('*').
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
prefix?: boolean;
|
|
24
31
|
/**
|
|
25
32
|
* Skip this handler (useful for temporarily disabling handlers)
|
|
26
33
|
* @default false
|
|
@@ -40,6 +47,11 @@ export interface EventHandlerMetadata {
|
|
|
40
47
|
* Method name to call when event is emitted
|
|
41
48
|
*/
|
|
42
49
|
methodName: string;
|
|
50
|
+
/**
|
|
51
|
+
* Whether the @EventService prefix is joined onto `pattern`.
|
|
52
|
+
* Normalized at decoration time (`prefix: false` opt-out → false).
|
|
53
|
+
*/
|
|
54
|
+
prefix: boolean;
|
|
43
55
|
/**
|
|
44
56
|
* Whether this handler should be skipped
|
|
45
57
|
*/
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type ServerLogger } from '../../logger';
|
|
2
|
+
import type { HealthOptions } from '../AsenaServerFactory';
|
|
3
|
+
import type { Ulak } from '../messaging/Ulak';
|
|
4
|
+
/**
|
|
5
|
+
* @description Minimal zero-dependency health endpoint for headless/hybrid deployments.
|
|
6
|
+
*
|
|
7
|
+
* Serves a single endpoint (default GET /healthz) reporting process liveness and
|
|
8
|
+
* per-microservice-transport connection state - built for Kubernetes probes on
|
|
9
|
+
* headless services that have no HTTP adapter.
|
|
10
|
+
*
|
|
11
|
+
* Responses:
|
|
12
|
+
* - No microservice transports configured → 200 { status: 'up', uptime }
|
|
13
|
+
* - All transports connected → 200 { status: 'up', uptime, transports: { name: 'connected' } }
|
|
14
|
+
* - Any transport disconnected → 503 { status: 'degraded', ... }
|
|
15
|
+
*/
|
|
16
|
+
export declare class HealthServer {
|
|
17
|
+
private readonly options;
|
|
18
|
+
private readonly ulak;
|
|
19
|
+
private readonly logger;
|
|
20
|
+
private server?;
|
|
21
|
+
private startedAt;
|
|
22
|
+
constructor(options: HealthOptions, ulak: Ulak, logger: ServerLogger);
|
|
23
|
+
start(): void;
|
|
24
|
+
stop(): void;
|
|
25
|
+
private buildHealthResponse;
|
|
26
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as bun from 'bun';
|
|
2
|
+
import { blue } from '../../logger';
|
|
3
|
+
/**
|
|
4
|
+
* @description Minimal zero-dependency health endpoint for headless/hybrid deployments.
|
|
5
|
+
*
|
|
6
|
+
* Serves a single endpoint (default GET /healthz) reporting process liveness and
|
|
7
|
+
* per-microservice-transport connection state - built for Kubernetes probes on
|
|
8
|
+
* headless services that have no HTTP adapter.
|
|
9
|
+
*
|
|
10
|
+
* Responses:
|
|
11
|
+
* - No microservice transports configured → 200 { status: 'up', uptime }
|
|
12
|
+
* - All transports connected → 200 { status: 'up', uptime, transports: { name: 'connected' } }
|
|
13
|
+
* - Any transport disconnected → 503 { status: 'degraded', ... }
|
|
14
|
+
*/
|
|
15
|
+
export class HealthServer {
|
|
16
|
+
options;
|
|
17
|
+
ulak;
|
|
18
|
+
logger;
|
|
19
|
+
server;
|
|
20
|
+
startedAt = 0;
|
|
21
|
+
constructor(options, ulak, logger) {
|
|
22
|
+
this.options = options;
|
|
23
|
+
this.ulak = ulak;
|
|
24
|
+
this.logger = logger;
|
|
25
|
+
}
|
|
26
|
+
start() {
|
|
27
|
+
const path = this.options.path || '/healthz';
|
|
28
|
+
this.startedAt = Date.now();
|
|
29
|
+
this.server = bun.serve({
|
|
30
|
+
port: this.options.port,
|
|
31
|
+
fetch: (request) => {
|
|
32
|
+
const url = new URL(request.url);
|
|
33
|
+
if (url.pathname !== path) {
|
|
34
|
+
return new Response('Not Found', { status: 404 });
|
|
35
|
+
}
|
|
36
|
+
return this.buildHealthResponse();
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
this.logger.info(`${blue('[Health]')} Health endpoint ready at :${this.options.port}${path}`);
|
|
40
|
+
}
|
|
41
|
+
stop() {
|
|
42
|
+
void this.server?.stop(true);
|
|
43
|
+
this.server = undefined;
|
|
44
|
+
}
|
|
45
|
+
buildHealthResponse() {
|
|
46
|
+
const transports = this.ulak.getMicroserviceTransports();
|
|
47
|
+
const uptime = Math.round((Date.now() - this.startedAt) / 1000);
|
|
48
|
+
if (transports.size === 0) {
|
|
49
|
+
return Response.json({ status: 'up', uptime });
|
|
50
|
+
}
|
|
51
|
+
const states = {};
|
|
52
|
+
let degraded = false;
|
|
53
|
+
for (const [name, transport] of transports) {
|
|
54
|
+
const connected = transport.isConnected;
|
|
55
|
+
states[name] = connected ? 'connected' : 'disconnected';
|
|
56
|
+
if (!connected) {
|
|
57
|
+
degraded = true;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return Response.json({ status: degraded ? 'degraded' : 'up', uptime, transports: states }, { status: degraded ? 503 : 200 });
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=HealthServer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HealthServer.js","sourceRoot":"","sources":["../../../../lib/server/health/HealthServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,GAAG,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,IAAI,EAAqB,MAAM,cAAc,CAAC;AAIvD;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,YAAY;IAMJ;IACA;IACA;IAPX,MAAM,CAAmB;IAEzB,SAAS,GAAG,CAAC,CAAC;IAEtB,YACmB,OAAsB,EACtB,IAAU,EACV,MAAoB;QAFpB,YAAO,GAAP,OAAO,CAAe;QACtB,SAAI,GAAJ,IAAI,CAAM;QACV,WAAM,GAAN,MAAM,CAAc;IACpC,CAAC;IAEG,KAAK;QACV,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,UAAU,CAAC;QAE7C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE5B,IAAI,CAAC,MAAM,GAAG,GAAG,CAAC,KAAK,CAAC;YACtB,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI;YACvB,KAAK,EAAE,CAAC,OAAgB,EAAE,EAAE;gBAC1B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAEjC,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;oBAC1B,OAAO,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC;gBACpD,CAAC;gBAED,OAAO,IAAI,CAAC,mBAAmB,EAAE,CAAC;YACpC,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,UAAU,CAAC,8BAA8B,IAAI,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,EAAE,CAAC,CAAC;IAChG,CAAC;IAEM,IAAI;QACT,KAAK,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC;IAC1B,CAAC;IAEO,mBAAmB;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,yBAAyB,EAAE,CAAC;QAEzD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC,CAAC;QAEhE,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACjD,CAAC;QAED,MAAM,MAAM,GAAiD,EAAE,CAAC;QAChE,IAAI,QAAQ,GAAG,KAAK,CAAC;QAErB,KAAK,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,IAAI,UAAU,EAAE,CAAC;YAC3C,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC;YAExC,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,cAAc,CAAC;YAExD,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,QAAQ,GAAG,IAAI,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC,IAAI,CAClB,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EACpE,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CACjC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './HealthServer';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../lib/server/health/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
|
|
@@ -1,6 +1,28 @@
|
|
|
1
1
|
import type { AsenaWebSocketService } from '../web/websocket';
|
|
2
2
|
import { type ICoreService, ICoreServiceNames } from '../../ioc';
|
|
3
3
|
import { type BulkOperation, type BulkResult } from './types';
|
|
4
|
+
import type { MessagingInterceptor } from '../microservice/types';
|
|
5
|
+
import type { EmitOptions, MicroserviceTransport, SendOptions } from '../microservice/MicroserviceTransport';
|
|
6
|
+
/**
|
|
7
|
+
* @description Options for Ulak microservice sends - adds named transport selection
|
|
8
|
+
*/
|
|
9
|
+
export interface UlakSendOptions extends SendOptions {
|
|
10
|
+
/**
|
|
11
|
+
* Named microservice transport to use (multi-broker projects)
|
|
12
|
+
* @default 'default'
|
|
13
|
+
*/
|
|
14
|
+
transport?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* @description Options for Ulak microservice emits - adds named transport selection
|
|
18
|
+
*/
|
|
19
|
+
export interface UlakEmitOptions extends EmitOptions {
|
|
20
|
+
/**
|
|
21
|
+
* Named microservice transport to use (multi-broker projects)
|
|
22
|
+
* @default 'default'
|
|
23
|
+
*/
|
|
24
|
+
transport?: string;
|
|
25
|
+
}
|
|
4
26
|
/**
|
|
5
27
|
* Central WebSocket message broker for Asena.js
|
|
6
28
|
*
|
|
@@ -32,6 +54,14 @@ export declare class Ulak implements ICoreService {
|
|
|
32
54
|
* Map of namespace path to WebSocket service instance
|
|
33
55
|
*/
|
|
34
56
|
private namespaces;
|
|
57
|
+
/**
|
|
58
|
+
* Named microservice transports (set during bootstrap by PrepareMicroserviceService)
|
|
59
|
+
*/
|
|
60
|
+
private microserviceTransports;
|
|
61
|
+
/**
|
|
62
|
+
* Messaging interceptors applied to all outgoing send/emit calls
|
|
63
|
+
*/
|
|
64
|
+
private microserviceInterceptors;
|
|
35
65
|
/**
|
|
36
66
|
* Initialize Ulak messaging system
|
|
37
67
|
* Called after dependency injection is complete
|
|
@@ -133,6 +163,62 @@ export declare class Ulak implements ICoreService {
|
|
|
133
163
|
* @returns Number of active sockets
|
|
134
164
|
*/
|
|
135
165
|
getSocketCount(namespace: string): number;
|
|
166
|
+
/**
|
|
167
|
+
* Wire the microservice transports into Ulak
|
|
168
|
+
* Called during bootstrap by PrepareMicroserviceService - not intended for user code
|
|
169
|
+
*
|
|
170
|
+
* @param transports - Named transports ('default' for the single-transport form)
|
|
171
|
+
* @param interceptors - Interceptors applied to all outgoing send/emit calls
|
|
172
|
+
*/
|
|
173
|
+
setMicroserviceTransports(transports: Map<string, MicroserviceTransport>, interceptors?: MessagingInterceptor[]): void;
|
|
174
|
+
/**
|
|
175
|
+
* Check if a microservice transport is configured and connected
|
|
176
|
+
*
|
|
177
|
+
* @param transport - Named transport to check
|
|
178
|
+
* @returns True when the transport exists and reports a live connection
|
|
179
|
+
*/
|
|
180
|
+
isMicroserviceConnected(transport?: string): boolean;
|
|
181
|
+
/**
|
|
182
|
+
* Get all configured microservice transports (read-only)
|
|
183
|
+
* Used by the health endpoint to report per-transport status
|
|
184
|
+
*/
|
|
185
|
+
getMicroserviceTransports(): ReadonlyMap<string, MicroserviceTransport>;
|
|
186
|
+
/**
|
|
187
|
+
* Send a request to another service and await its reply (request/response)
|
|
188
|
+
*
|
|
189
|
+
* @param pattern - Full request pattern (e.g. 'order.create')
|
|
190
|
+
* @param data - Request payload
|
|
191
|
+
* @param options - Timeout, headers and named transport selection
|
|
192
|
+
* @returns The reply produced by the remote @MessagePattern handler
|
|
193
|
+
* @throws {UlakError} NO_TRANSPORT / TRANSPORT_NOT_FOUND / TIMEOUT / REMOTE_ERROR
|
|
194
|
+
*/
|
|
195
|
+
send<T = unknown>(pattern: string, data?: unknown, options?: UlakSendOptions): Promise<T>;
|
|
196
|
+
/**
|
|
197
|
+
* Emit a fire-and-forget event to other services
|
|
198
|
+
*
|
|
199
|
+
* @param pattern - Full event pattern (e.g. 'order.created')
|
|
200
|
+
* @param data - Event payload
|
|
201
|
+
* @param options - Headers and named transport selection
|
|
202
|
+
* @throws {UlakError} NO_TRANSPORT / TRANSPORT_NOT_FOUND
|
|
203
|
+
*/
|
|
204
|
+
emit(pattern: string, data?: unknown, options?: UlakEmitOptions): Promise<void>;
|
|
205
|
+
/**
|
|
206
|
+
* Select a pattern-scoped microservice messaging view
|
|
207
|
+
* Patterns passed to the returned view are joined with the prefix ('order' + 'create' → 'order.create')
|
|
208
|
+
*
|
|
209
|
+
* @param prefix - Pattern prefix (empty for absolute patterns)
|
|
210
|
+
* @param options - Named transport selection
|
|
211
|
+
* @returns Scoped messages instance
|
|
212
|
+
*
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* const orders = ulak.messages('order');
|
|
216
|
+
* const res = await orders.send('create', dto); // sends 'order.create'
|
|
217
|
+
* ```
|
|
218
|
+
*/
|
|
219
|
+
messages<T extends string = ''>(prefix?: T, options?: {
|
|
220
|
+
transport?: string;
|
|
221
|
+
}): Ulak.Messages<T>;
|
|
136
222
|
/**
|
|
137
223
|
* Dispose of all resources and stop background tasks
|
|
138
224
|
* Should be called during application shutdown
|
|
@@ -146,6 +232,13 @@ export declare class Ulak implements ICoreService {
|
|
|
146
232
|
* @throws {UlakError} If namespace not found
|
|
147
233
|
*/
|
|
148
234
|
private getNamespaceService;
|
|
235
|
+
/**
|
|
236
|
+
* Get a named microservice transport or throw
|
|
237
|
+
*
|
|
238
|
+
* @param name - Named transport (defaults to 'default')
|
|
239
|
+
* @throws {UlakError} NO_TRANSPORT when none configured, TRANSPORT_NOT_FOUND for unknown names
|
|
240
|
+
*/
|
|
241
|
+
private getMicroserviceTransport;
|
|
149
242
|
}
|
|
150
243
|
/**
|
|
151
244
|
* Scoped namespace interface
|
|
@@ -191,6 +284,34 @@ export declare namespace Ulak {
|
|
|
191
284
|
*/
|
|
192
285
|
getSocketCount(): number;
|
|
193
286
|
}
|
|
287
|
+
/**
|
|
288
|
+
* Pattern-scoped microservice messaging view
|
|
289
|
+
* Provides ergonomic API without repeating the pattern prefix
|
|
290
|
+
*/
|
|
291
|
+
interface Messages<P extends string = string> {
|
|
292
|
+
/**
|
|
293
|
+
* The pattern prefix ('' for absolute patterns)
|
|
294
|
+
*/
|
|
295
|
+
readonly prefix: P;
|
|
296
|
+
/**
|
|
297
|
+
* Send a request and await its reply (request/response)
|
|
298
|
+
* The pattern is joined with the prefix ('create' → 'order.create')
|
|
299
|
+
*
|
|
300
|
+
* @param pattern - Request pattern relative to the prefix
|
|
301
|
+
* @param data - Request payload
|
|
302
|
+
* @param options - Timeout and headers
|
|
303
|
+
*/
|
|
304
|
+
send<T = unknown>(pattern: string, data?: unknown, options?: SendOptions): Promise<T>;
|
|
305
|
+
/**
|
|
306
|
+
* Emit a fire-and-forget event
|
|
307
|
+
* The pattern is joined with the prefix ('created' → 'order.created')
|
|
308
|
+
*
|
|
309
|
+
* @param pattern - Event pattern relative to the prefix
|
|
310
|
+
* @param data - Event payload
|
|
311
|
+
* @param options - Headers
|
|
312
|
+
*/
|
|
313
|
+
emit(pattern: string, data?: unknown, options?: EmitOptions): Promise<void>;
|
|
314
|
+
}
|
|
194
315
|
}
|
|
195
316
|
/**
|
|
196
317
|
* Helper function for injecting scoped Ulak namespace
|
|
@@ -222,3 +343,38 @@ export declare namespace Ulak {
|
|
|
222
343
|
* ```
|
|
223
344
|
*/
|
|
224
345
|
export declare function ulak<T extends string>(namespace: T): readonly [ICoreServiceNames.__ULAK__, (ulak: Ulak) => Ulak.NameSpace<T>];
|
|
346
|
+
/**
|
|
347
|
+
* Helper functions for injecting microservice messaging views from Ulak
|
|
348
|
+
* Declaration merging keeps the single `ulak` entry point:
|
|
349
|
+
* `ulak('/chat')` → WebSocket namespace, `ulak.messages('order')` → microservice messaging
|
|
350
|
+
*/
|
|
351
|
+
export declare namespace ulak {
|
|
352
|
+
/**
|
|
353
|
+
* Inject a pattern-scoped microservice messaging view
|
|
354
|
+
*
|
|
355
|
+
* @param prefix - Pattern prefix joined to every send/emit ('' for absolute patterns)
|
|
356
|
+
* @param options - Named transport selection (multi-broker projects)
|
|
357
|
+
* @returns A tuple of [serviceName, expression] for @Inject decorator
|
|
358
|
+
*
|
|
359
|
+
* @example
|
|
360
|
+
* ```typescript
|
|
361
|
+
* @Service('CheckoutService')
|
|
362
|
+
* export class CheckoutService {
|
|
363
|
+
* @Inject(ulak.messages('order'))
|
|
364
|
+
* private orders: Ulak.Messages<'order'>;
|
|
365
|
+
*
|
|
366
|
+
* async checkout(dto: CheckoutDto) {
|
|
367
|
+
* const res = await this.orders.send('create', dto); // sends 'order.create'
|
|
368
|
+
* await this.orders.emit('created', { id: res.id }); // emits 'order.created'
|
|
369
|
+
* }
|
|
370
|
+
* }
|
|
371
|
+
*
|
|
372
|
+
* // Named transport (multi-broker projects)
|
|
373
|
+
* @Inject(ulak.messages('metrics', { transport: 'analytics' }))
|
|
374
|
+
* private metrics: Ulak.Messages<'metrics'>;
|
|
375
|
+
* ```
|
|
376
|
+
*/
|
|
377
|
+
function messages<P extends string = ''>(prefix?: P, options?: {
|
|
378
|
+
transport?: string;
|
|
379
|
+
}): readonly [ICoreServiceNames.__ULAK__, (u: Ulak) => Ulak.Messages<P>];
|
|
380
|
+
}
|