@zlink-systems/nestjs 0.21.0 → 0.23.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/dist/.tsbuildinfo +1 -1
- package/dist/contracts.d.ts +4 -0
- package/dist/decorators.js +1 -3
- package/dist/framework-integration-contracts.d.ts +2 -0
- package/dist/handler-adapters.js +4 -2
- package/dist/handler-metadata.js +3 -3
- package/dist/http-client-module.js +3 -1
- package/dist/module.js +9 -14
- package/dist/options-builder.js +59 -37
- package/dist/provider-discovery.js +7 -6
- package/dist/providers.js +17 -24
- package/dist/registration-composer.js +36 -19
- package/dist/spot-node-handler-registry.js +15 -9
- package/package.json +3 -3
package/dist/contracts.d.ts
CHANGED
|
@@ -25,8 +25,10 @@ export type Mutable<T> = {
|
|
|
25
25
|
export interface InternalZLinkNestFanoutChannelOptions extends ZLinkNestHandlerDiscoveryOptions {
|
|
26
26
|
readonly routingId?: string;
|
|
27
27
|
readonly routingIdPrefix?: string;
|
|
28
|
+
readonly noDrop?: boolean;
|
|
28
29
|
readonly publisher?: ZLinkPublisherCapabilityOptions;
|
|
29
30
|
readonly subscriber?: ZLinkClientCapabilityOptions;
|
|
31
|
+
readonly subscriptions?: readonly string[];
|
|
30
32
|
readonly publishHandlers?: readonly ZLinkChannelPublishHandlerRegistration[];
|
|
31
33
|
readonly publishHandlerTypes?: readonly ZLinkNestManualHandlerOptions[];
|
|
32
34
|
}
|
|
@@ -154,7 +156,9 @@ export interface ZLinkNestFanoutChannelBuilder extends ZLinkNestFrameworkOptions
|
|
|
154
156
|
setAdvertiseHost(advertiseHost: string): this;
|
|
155
157
|
routingId(routingId: string | undefined): this;
|
|
156
158
|
setRoutingIdPrefix(prefix: string): this;
|
|
159
|
+
setNoDrop(noDrop?: boolean): this;
|
|
157
160
|
enableSubscriber(endpoint?: string | readonly string[]): this;
|
|
161
|
+
subscribe(topic: string): this;
|
|
158
162
|
addPublishHandler(packetName: string, handlerType: Type): this;
|
|
159
163
|
addHandlerGroup(groupName: string): this;
|
|
160
164
|
}
|
package/dist/decorators.js
CHANGED
|
@@ -164,9 +164,7 @@ function inferPacketName(handlerType, handlerToken) {
|
|
|
164
164
|
? handlerType.name.slice(0, -'Handler'.length)
|
|
165
165
|
: handlerType.name;
|
|
166
166
|
}
|
|
167
|
-
const tokenName = typeof handlerToken === 'symbol'
|
|
168
|
-
? handlerToken.description
|
|
169
|
-
: String(handlerToken);
|
|
167
|
+
const tokenName = typeof handlerToken === 'symbol' ? handlerToken.description : String(handlerToken);
|
|
170
168
|
if (tokenName === undefined || tokenName.trim() === '') {
|
|
171
169
|
throw new framework_loader_1.framework.ZLinkConfigurationException('ZLink handler packetName is required for anonymous provider tokens.');
|
|
172
170
|
}
|
|
@@ -109,11 +109,13 @@ export interface ZLinkFrameworkRegistrationOptions {
|
|
|
109
109
|
export interface ZLinkChannelOptions {
|
|
110
110
|
readonly routingId?: string;
|
|
111
111
|
readonly routingIdPrefix?: string;
|
|
112
|
+
readonly noDrop?: boolean;
|
|
112
113
|
readonly requestTimeoutMs?: number;
|
|
113
114
|
readonly client?: ZLinkClientCapabilityOptions;
|
|
114
115
|
readonly publisher?: ZLinkPublisherCapabilityOptions;
|
|
115
116
|
readonly routeMesh?: ZLinkRouteMeshChannelOptions;
|
|
116
117
|
readonly publishHandlers?: readonly ZLinkChannelPublishHandlerRegistration[];
|
|
118
|
+
readonly subscriptions?: readonly string[];
|
|
117
119
|
readonly requestHandlers?: readonly ZLinkChannelRequestHandlerRegistration[];
|
|
118
120
|
readonly sendHandlers?: readonly ZLinkChannelSendHandlerRegistration[];
|
|
119
121
|
readonly server?: {
|
package/dist/handler-adapters.js
CHANGED
|
@@ -17,7 +17,9 @@ function createDiscoveredRequestHandlers(providerRefs, handlerGroups, moduleRef)
|
|
|
17
17
|
return createDiscoveredHandlerRegistrations(providerRefs, handlerGroups, 'request', (ref, metadata) => ({
|
|
18
18
|
async handle(payload, context) {
|
|
19
19
|
const result = await invokeDiscoveredHandler(moduleRef, ref, metadata, payload, context);
|
|
20
|
-
return metadata.encodeResult === undefined
|
|
20
|
+
return metadata.encodeResult === undefined
|
|
21
|
+
? result
|
|
22
|
+
: metadata.encodeResult(result, context);
|
|
21
23
|
}
|
|
22
24
|
}));
|
|
23
25
|
}
|
|
@@ -131,7 +133,7 @@ async function resolveHandlerInstance(moduleRef, handlerType, context) {
|
|
|
131
133
|
if (currentContextId === undefined) {
|
|
132
134
|
moduleRef.registerRequestByContextId({ zlinkContext: context }, contextId);
|
|
133
135
|
}
|
|
134
|
-
return await (0, providers_1.createNestHandlerInstance)(moduleRef, contextId, new Map(), handlerType);
|
|
136
|
+
return (await (0, providers_1.createNestHandlerInstance)(moduleRef, contextId, new Map(), handlerType));
|
|
135
137
|
}
|
|
136
138
|
function decodePayload(metadata, payload, context) {
|
|
137
139
|
if (Buffer.isBuffer(payload) || payload instanceof Uint8Array) {
|
package/dist/handler-metadata.js
CHANGED
|
@@ -48,14 +48,14 @@ function appendNestSpotActorHandlerMetadata(handlerToken, metadata) {
|
|
|
48
48
|
spotActorHandlerMetadata.set(handlerToken, [...current, metadata]);
|
|
49
49
|
}
|
|
50
50
|
function readNestSpotActorHandlerMetadata(handlerToken) {
|
|
51
|
-
return handlerToken === undefined ? [] : spotActorHandlerMetadata.get(handlerToken) ?? [];
|
|
51
|
+
return handlerToken === undefined ? [] : (spotActorHandlerMetadata.get(handlerToken) ?? []);
|
|
52
52
|
}
|
|
53
53
|
function appendNestSpotHandlerMetadata(handlerToken, metadata) {
|
|
54
54
|
const current = readNestSpotHandlerMetadata(handlerToken);
|
|
55
55
|
spotHandlerMetadata.set(handlerToken, [...current, metadata]);
|
|
56
56
|
}
|
|
57
57
|
function readNestSpotHandlerMetadata(handlerToken) {
|
|
58
|
-
return handlerToken === undefined ? [] : spotHandlerMetadata.get(handlerToken) ?? [];
|
|
58
|
+
return handlerToken === undefined ? [] : (spotHandlerMetadata.get(handlerToken) ?? []);
|
|
59
59
|
}
|
|
60
60
|
function markNestSpotTimerHandler(handlerToken) {
|
|
61
61
|
spotTimerHandlerTokens.add(handlerToken);
|
|
@@ -65,7 +65,7 @@ function appendNestSpotTimerHandlerMetadata(handlerToken, metadata) {
|
|
|
65
65
|
spotTimerHandlerMetadata.set(handlerToken, [...current, metadata]);
|
|
66
66
|
}
|
|
67
67
|
function readNestSpotTimerHandlerMetadata(handlerToken) {
|
|
68
|
-
return handlerToken === undefined ? [] : spotTimerHandlerMetadata.get(handlerToken) ?? [];
|
|
68
|
+
return handlerToken === undefined ? [] : (spotTimerHandlerMetadata.get(handlerToken) ?? []);
|
|
69
69
|
}
|
|
70
70
|
function hasNestSpotTimerHandlerMetadata(handlerToken) {
|
|
71
71
|
return handlerToken !== undefined && spotTimerHandlerTokens.has(handlerToken);
|
|
@@ -27,7 +27,9 @@ class ZLinkHttpClientRegistry {
|
|
|
27
27
|
constructor(registrations, moduleRef) {
|
|
28
28
|
const runtime = new Proxy({}, {
|
|
29
29
|
get: (_target, property) => {
|
|
30
|
-
const current = moduleRef.get(tokens_1.ZLINK_FRAMEWORK_RUNTIME, {
|
|
30
|
+
const current = moduleRef.get(tokens_1.ZLINK_FRAMEWORK_RUNTIME, {
|
|
31
|
+
strict: false
|
|
32
|
+
});
|
|
31
33
|
return Reflect.get(current, property);
|
|
32
34
|
}
|
|
33
35
|
});
|
package/dist/module.js
CHANGED
|
@@ -40,10 +40,7 @@ function zlinkModule(metadataOrRoleRoot, metadata) {
|
|
|
40
40
|
: createProviderDiscoveryProviders(providerDiscovery);
|
|
41
41
|
return (0, common_1.Module)({
|
|
42
42
|
...rest,
|
|
43
|
-
providers: [
|
|
44
|
-
...(providers ?? []),
|
|
45
|
-
...discoveredProviders
|
|
46
|
-
]
|
|
43
|
+
providers: [...(providers ?? []), ...discoveredProviders]
|
|
47
44
|
});
|
|
48
45
|
}
|
|
49
46
|
function loadDecoratedProviderModules(rootDir, options) {
|
|
@@ -85,13 +82,13 @@ function addDecoratedProviderModuleExports(providers, filePath) {
|
|
|
85
82
|
const frameworkMetadata = typeof value === 'function'
|
|
86
83
|
? (value[Symbol.for('@zlink-systems/framework:decorator')] ?? [])
|
|
87
84
|
: [];
|
|
88
|
-
if (typeof value === 'function'
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
85
|
+
if (typeof value === 'function' &&
|
|
86
|
+
((0, handler_metadata_1.readNestHandlerMetadata)(value).length > 0 ||
|
|
87
|
+
(0, handler_metadata_1.readNestSpotActorHandlerMetadata)(value).length > 0 ||
|
|
88
|
+
(0, handler_metadata_1.readNestSpotHandlerMetadata)(value).length > 0 ||
|
|
89
|
+
(0, handler_metadata_1.hasNestSpotTimerHandlerMetadata)(value) ||
|
|
90
|
+
(frameworkMetadata.some((entry) => entry.kind === 'packet') &&
|
|
91
|
+
typeof value.prototype?.handle === 'function'))) {
|
|
95
92
|
providers.add((0, auto_discovery_marker_1.markAutoDiscoveredProvider)(value));
|
|
96
93
|
}
|
|
97
94
|
}
|
|
@@ -197,7 +194,5 @@ function createDefaultProviderDiscoveryProviders(roleRoot) {
|
|
|
197
194
|
return createProviderDiscoveryProviders(defaultProviderDiscoveryRoots(roleRoot));
|
|
198
195
|
}
|
|
199
196
|
function defaultProviderDiscoveryRoots(roleRoot) {
|
|
200
|
-
return node_fs_1.default.existsSync(roleRoot)
|
|
201
|
-
? [{ rootDir: roleRoot, options: { recursive: true } }]
|
|
202
|
-
: [];
|
|
197
|
+
return node_fs_1.default.existsSync(roleRoot) ? [{ rootDir: roleRoot, options: { recursive: true } }] : [];
|
|
203
198
|
}
|
package/dist/options-builder.js
CHANGED
|
@@ -32,8 +32,8 @@ function ensureChannelAvailable(state, name) {
|
|
|
32
32
|
if (name.trim().length === 0 || name.trim() !== name) {
|
|
33
33
|
throw new framework_loader_1.framework.ZLinkConfigurationException('Channel name must not be empty or padded.');
|
|
34
34
|
}
|
|
35
|
-
if (Object.prototype.hasOwnProperty.call(state.fanoutChannels, name)
|
|
36
|
-
|
|
35
|
+
if (Object.prototype.hasOwnProperty.call(state.fanoutChannels, name) ||
|
|
36
|
+
Object.prototype.hasOwnProperty.call(state.clientServerChannels, name)) {
|
|
37
37
|
throw new framework_loader_1.framework.ZLinkConfigurationException(`Duplicate channel '${name}'.`);
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -141,7 +141,10 @@ class ZLinkNestOptionsBuilder {
|
|
|
141
141
|
}
|
|
142
142
|
configureStreamCompression() {
|
|
143
143
|
const compression = { ...(this.state.additionalOptions.streamCompression ?? {}) };
|
|
144
|
-
this.state.additionalOptions = {
|
|
144
|
+
this.state.additionalOptions = {
|
|
145
|
+
...this.state.additionalOptions,
|
|
146
|
+
streamCompression: compression
|
|
147
|
+
};
|
|
145
148
|
return framework_loader_1.framework.createIntegrationStreamCompressionBuilder(compression);
|
|
146
149
|
}
|
|
147
150
|
configureLocations() {
|
|
@@ -243,9 +246,10 @@ class DefaultZLinkNestFanoutChannelBuilder extends ZLinkNestOptionsBuilder {
|
|
|
243
246
|
this.channelOptions = channelOptions;
|
|
244
247
|
}
|
|
245
248
|
enablePublisher(endpointOrPort) {
|
|
246
|
-
this.channelOptions.publisher =
|
|
247
|
-
|
|
248
|
-
|
|
249
|
+
this.channelOptions.publisher =
|
|
250
|
+
typeof endpointOrPort === 'string'
|
|
251
|
+
? { bind: endpointOrPort }
|
|
252
|
+
: { port: requireListenerPort(endpointOrPort, `Fanout channel '${this.name}' publisher`) };
|
|
249
253
|
return this;
|
|
250
254
|
}
|
|
251
255
|
setBindHost(bindHost) {
|
|
@@ -268,13 +272,22 @@ class DefaultZLinkNestFanoutChannelBuilder extends ZLinkNestOptionsBuilder {
|
|
|
268
272
|
this.channelOptions.routingIdPrefix = framework_loader_1.framework.validateRoutingIdPrefix(prefix);
|
|
269
273
|
return this;
|
|
270
274
|
}
|
|
275
|
+
setNoDrop(noDrop) {
|
|
276
|
+
this.channelOptions.noDrop = noDrop;
|
|
277
|
+
return this;
|
|
278
|
+
}
|
|
271
279
|
enableSubscriber(endpoint) {
|
|
272
280
|
const mode = endpoint === undefined ? 'automatic' : 'manual';
|
|
273
281
|
if (this.subscriberMode !== undefined && this.subscriberMode !== mode) {
|
|
274
282
|
throw new framework_loader_1.framework.ZLinkConfigurationException(`Fanout channel '${this.name}' cannot combine automatic and manual subscriber sources.`);
|
|
275
283
|
}
|
|
276
284
|
this.subscriberMode = mode;
|
|
277
|
-
this.channelOptions.subscriber =
|
|
285
|
+
this.channelOptions.subscriber =
|
|
286
|
+
endpoint === undefined ? {} : { manualConnections: endpointList(endpoint) };
|
|
287
|
+
return this;
|
|
288
|
+
}
|
|
289
|
+
subscribe(topic) {
|
|
290
|
+
this.channelOptions.subscriptions = [...(this.channelOptions.subscriptions ?? []), topic];
|
|
278
291
|
return this;
|
|
279
292
|
}
|
|
280
293
|
addHandlerGroup(groupName) {
|
|
@@ -282,7 +295,10 @@ class DefaultZLinkNestFanoutChannelBuilder extends ZLinkNestOptionsBuilder {
|
|
|
282
295
|
return this;
|
|
283
296
|
}
|
|
284
297
|
addPublishHandler(packetName, handlerType) {
|
|
285
|
-
this.channelOptions.publishHandlerTypes = [
|
|
298
|
+
this.channelOptions.publishHandlerTypes = [
|
|
299
|
+
...(this.channelOptions.publishHandlerTypes ?? []),
|
|
300
|
+
{ packetName, handlerType }
|
|
301
|
+
];
|
|
286
302
|
return this;
|
|
287
303
|
}
|
|
288
304
|
updatePublisher(values) {
|
|
@@ -504,13 +520,14 @@ class DefaultZLinkNestMeshNodeBuilder extends ZLinkNestOptionsBuilder {
|
|
|
504
520
|
return new DefaultZLinkNestMeshChannelBuilder(this.state, channels[name]);
|
|
505
521
|
}
|
|
506
522
|
listen(endpointOrPort) {
|
|
507
|
-
this.spotOptions.router =
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
523
|
+
this.spotOptions.router =
|
|
524
|
+
typeof endpointOrPort === 'string'
|
|
525
|
+
? { ...(this.spotOptions.router ?? {}), bind: endpointOrPort, port: undefined }
|
|
526
|
+
: {
|
|
527
|
+
...(this.spotOptions.router ?? {}),
|
|
528
|
+
bind: undefined,
|
|
529
|
+
port: requireListenerPort(endpointOrPort, `RouteMesh '${this.name}' listener`)
|
|
530
|
+
};
|
|
514
531
|
return this;
|
|
515
532
|
}
|
|
516
533
|
setBindHost(bindHost) {
|
|
@@ -527,10 +544,12 @@ class DefaultZLinkNestMeshNodeBuilder extends ZLinkNestOptionsBuilder {
|
|
|
527
544
|
rejectGeneratedRoutingId(this.spotOptions.routingIdPrefix, this.name);
|
|
528
545
|
this.spotOptions.routingId = routingId;
|
|
529
546
|
if (this.spotOptions.router !== undefined) {
|
|
530
|
-
this.spotOptions.router.routingId =
|
|
547
|
+
this.spotOptions.router.routingId =
|
|
548
|
+
routingId;
|
|
531
549
|
}
|
|
532
550
|
if (this.spotOptions.pubSub !== undefined) {
|
|
533
|
-
this.spotOptions.pubSub.routingId =
|
|
551
|
+
this.spotOptions.pubSub.routingId =
|
|
552
|
+
routingId;
|
|
534
553
|
}
|
|
535
554
|
return this;
|
|
536
555
|
}
|
|
@@ -699,8 +718,8 @@ class DefaultZLinkNestUserSpotFactoryBuilder extends DefaultZLinkNestFactoryBuil
|
|
|
699
718
|
relocationCoordinationMode: this.relocationCoordinationModeValue
|
|
700
719
|
};
|
|
701
720
|
validateUserSpotFactoryConfiguration(options);
|
|
702
|
-
if (options.executionMode === framework_1.ZLinkUserSpotExecutionMode.PerActor
|
|
703
|
-
|
|
721
|
+
if (options.executionMode === framework_1.ZLinkUserSpotExecutionMode.PerActor &&
|
|
722
|
+
relocation.kind !== 'recreate') {
|
|
704
723
|
throw new framework_loader_1.framework.ZLinkConfigurationException('PerActor User Spots require RecreateOnRelocation.');
|
|
705
724
|
}
|
|
706
725
|
return { options, relocation };
|
|
@@ -829,10 +848,10 @@ class DefaultZLinkNestMeshObjectServerBuilder extends ZLinkNestOptionsBuilder {
|
|
|
829
848
|
}
|
|
830
849
|
}
|
|
831
850
|
function validateObjectFactory(stableType, label) {
|
|
832
|
-
if (typeof stableType !== 'string'
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
851
|
+
if (typeof stableType !== 'string' ||
|
|
852
|
+
Buffer.byteLength(stableType) < 1 ||
|
|
853
|
+
Buffer.byteLength(stableType) > 255 ||
|
|
854
|
+
stableType.includes('\0')) {
|
|
836
855
|
throw new framework_loader_1.framework.ZLinkConfigurationException(`${label} must contain 1..255 UTF-8 bytes and no NUL.`);
|
|
837
856
|
}
|
|
838
857
|
return stableType;
|
|
@@ -846,22 +865,21 @@ function validateUserSpotFactoryConfiguration(options) {
|
|
|
846
865
|
validateStableTypeLimit(options.stableTypeLimit);
|
|
847
866
|
const executionMode = options.executionMode;
|
|
848
867
|
const relocationCoordinationMode = options.relocationCoordinationMode;
|
|
849
|
-
if (executionMode !== framework_1.ZLinkUserSpotExecutionMode.SpotWide
|
|
850
|
-
|
|
868
|
+
if (executionMode !== framework_1.ZLinkUserSpotExecutionMode.SpotWide &&
|
|
869
|
+
executionMode !== framework_1.ZLinkUserSpotExecutionMode.PerActor) {
|
|
851
870
|
throw new framework_loader_1.framework.ZLinkConfigurationException('User Spot executionMode is invalid.');
|
|
852
871
|
}
|
|
853
|
-
if (relocationCoordinationMode !== framework_1.ZLinkSpotRelocationCoordinationMode.FrameworkManaged
|
|
854
|
-
|
|
872
|
+
if (relocationCoordinationMode !== framework_1.ZLinkSpotRelocationCoordinationMode.FrameworkManaged &&
|
|
873
|
+
relocationCoordinationMode !== framework_1.ZLinkSpotRelocationCoordinationMode.ApplicationSignaled) {
|
|
855
874
|
throw new framework_loader_1.framework.ZLinkConfigurationException('User Spot relocationCoordinationMode is invalid.');
|
|
856
875
|
}
|
|
857
|
-
if (options.executionMode === framework_1.ZLinkUserSpotExecutionMode.PerActor
|
|
858
|
-
|
|
876
|
+
if (options.executionMode === framework_1.ZLinkUserSpotExecutionMode.PerActor &&
|
|
877
|
+
options.relocationCoordinationMode === framework_1.ZLinkSpotRelocationCoordinationMode.ApplicationSignaled) {
|
|
859
878
|
throw new framework_loader_1.framework.ZLinkConfigurationException('ApplicationSignaled relocation coordination mode is valid only for SpotWide User Spots.');
|
|
860
879
|
}
|
|
861
880
|
}
|
|
862
881
|
function validateStableTypeLimit(value) {
|
|
863
|
-
if (value !== undefined
|
|
864
|
-
&& (!Number.isInteger(value) || value < 0 || value > 2_147_483_647)) {
|
|
882
|
+
if (value !== undefined && (!Number.isInteger(value) || value < 0 || value > 2_147_483_647)) {
|
|
865
883
|
throw new framework_loader_1.framework.ZLinkConfigurationException('stableTypeLimit must be an integer from 0 through 2147483647.');
|
|
866
884
|
}
|
|
867
885
|
}
|
|
@@ -926,7 +944,10 @@ class DefaultZLinkNestMeshChannelServerBuilder extends ZLinkNestOptionsBuilder {
|
|
|
926
944
|
return this;
|
|
927
945
|
}
|
|
928
946
|
addRequestHandler(packetName, handlerType) {
|
|
929
|
-
this.channel.requestHandlers = [
|
|
947
|
+
this.channel.requestHandlers = [
|
|
948
|
+
...(this.channel.requestHandlers ?? []),
|
|
949
|
+
{ packetName, handlerType }
|
|
950
|
+
];
|
|
930
951
|
return this;
|
|
931
952
|
}
|
|
932
953
|
addHandlerGroup(groupName) {
|
|
@@ -941,7 +962,10 @@ class DefaultZLinkNestMeshPeerConnections {
|
|
|
941
962
|
}
|
|
942
963
|
connect(expectedRoutingIdOrEndpoint, endpoint) {
|
|
943
964
|
if (endpoint === undefined) {
|
|
944
|
-
this.router.manualConnections = [
|
|
965
|
+
this.router.manualConnections = [
|
|
966
|
+
...(this.router.manualConnections ?? []),
|
|
967
|
+
expectedRoutingIdOrEndpoint
|
|
968
|
+
];
|
|
945
969
|
return;
|
|
946
970
|
}
|
|
947
971
|
this.router.manualPeerConnections = [
|
|
@@ -950,10 +974,8 @@ class DefaultZLinkNestMeshPeerConnections {
|
|
|
950
974
|
];
|
|
951
975
|
}
|
|
952
976
|
disconnect(endpoint) {
|
|
953
|
-
this.router.manualConnections = (this.router.manualConnections ?? [])
|
|
954
|
-
|
|
955
|
-
this.router.manualPeerConnections = (this.router.manualPeerConnections ?? [])
|
|
956
|
-
.filter((value) => value.endpoint !== endpoint);
|
|
977
|
+
this.router.manualConnections = (this.router.manualConnections ?? []).filter((value) => value !== endpoint);
|
|
978
|
+
this.router.manualPeerConnections = (this.router.manualPeerConnections ?? []).filter((value) => value.endpoint !== endpoint);
|
|
957
979
|
}
|
|
958
980
|
listConnections() {
|
|
959
981
|
return [
|
|
@@ -14,17 +14,18 @@ function discoverSessionProviderRefs(discovery, moduleRef) {
|
|
|
14
14
|
const metadataSymbol = Symbol.for('@zlink-systems/framework:decorator');
|
|
15
15
|
for (const wrapper of discovery.getProviders()) {
|
|
16
16
|
const handlerType = wrapper.metatype;
|
|
17
|
-
if (typeof handlerType !== 'function'
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
if (typeof handlerType !== 'function' ||
|
|
18
|
+
seen.has(handlerType) ||
|
|
19
|
+
!(0, auto_discovery_marker_1.isAutoDiscoveredProvider)(handlerType)) {
|
|
20
20
|
continue;
|
|
21
21
|
}
|
|
22
22
|
// The symbol is only present on decorated handlers, so the lookup has to
|
|
23
23
|
// admit undefined for the fallback to mean anything.
|
|
24
24
|
const metadata = handlerType[metadataSymbol] ?? [];
|
|
25
|
-
if (metadata.some((entry) => entry.kind === 'packet')
|
|
26
|
-
|
|
27
|
-
|
|
25
|
+
if (metadata.some((entry) => entry.kind === 'packet') &&
|
|
26
|
+
typeof handlerType.prototype?.handle ===
|
|
27
|
+
'function' &&
|
|
28
|
+
tryGetProviderInstance(moduleRef, handlerType) !== undefined) {
|
|
28
29
|
seen.add(handlerType);
|
|
29
30
|
refs.push({ handlerKey: handlerType });
|
|
30
31
|
}
|
package/dist/providers.js
CHANGED
|
@@ -63,28 +63,24 @@ function alwaysAvailableClientTokens() {
|
|
|
63
63
|
tokens_1.ZLINK_ROUTE_CLIENT,
|
|
64
64
|
tokens_1.ZLINK_FANOUT_CLIENT,
|
|
65
65
|
tokens_1.ZLINK_BOUND_SESSION_FACTORY,
|
|
66
|
-
tokens_1.ZLINK_MESSAGE_METADATA_POLICY
|
|
66
|
+
tokens_1.ZLINK_MESSAGE_METADATA_POLICY
|
|
67
67
|
];
|
|
68
68
|
}
|
|
69
69
|
function conditionalClientProviders(registration) {
|
|
70
|
-
return CONDITIONAL_CLIENT_PROVIDER_SPECS
|
|
71
|
-
.filter((spec) => spec.isEnabled(registration))
|
|
72
|
-
.map((spec) => createConditionalClientProvider(spec, registration));
|
|
70
|
+
return CONDITIONAL_CLIENT_PROVIDER_SPECS.filter((spec) => spec.isEnabled(registration)).map((spec) => createConditionalClientProvider(spec, registration));
|
|
73
71
|
}
|
|
74
72
|
const CONDITIONAL_CLIENT_PROVIDER_SPECS = [
|
|
75
73
|
{
|
|
76
74
|
token: tokens_1.ZLINK_CLIENT_SERVER_RUNTIME,
|
|
77
75
|
requiresRuntime: true,
|
|
78
|
-
isEnabled: (registration) => [...registration.channels.values()]
|
|
79
|
-
.some(channel => channel.client !== undefined || channel.server !== undefined),
|
|
76
|
+
isEnabled: (registration) => [...registration.channels.values()].some((channel) => channel.client !== undefined || channel.server !== undefined),
|
|
80
77
|
create: (_registration, runtime) => requireRuntime(runtime).clientServerRuntime
|
|
81
78
|
},
|
|
82
79
|
{
|
|
83
80
|
token: tokens_1.ZLINK_FANOUT_RUNTIME,
|
|
84
81
|
requiresRuntime: true,
|
|
85
|
-
isEnabled: (registration) => [...registration.channels.values()]
|
|
86
|
-
|
|
87
|
-
&& (channel.subscriber.manualConnections?.length ?? 0) === 0),
|
|
82
|
+
isEnabled: (registration) => [...registration.channels.values()].some((channel) => channel.subscriber !== undefined &&
|
|
83
|
+
(channel.subscriber.manualConnections?.length ?? 0) === 0),
|
|
88
84
|
create: (_registration, runtime) => requireRuntime(runtime).fanoutRuntime
|
|
89
85
|
},
|
|
90
86
|
{
|
|
@@ -228,8 +224,7 @@ function conditionalClientTokens() {
|
|
|
228
224
|
];
|
|
229
225
|
}
|
|
230
226
|
function hasLocationStores(registration) {
|
|
231
|
-
return registration.locations.useInMemoryStores
|
|
232
|
-
|| registration.locations.storeInstance !== undefined;
|
|
227
|
+
return (registration.locations.useInMemoryStores || registration.locations.storeInstance !== undefined);
|
|
233
228
|
}
|
|
234
229
|
function createRuntimeHost(registration, moduleRef, discovery) {
|
|
235
230
|
const runtime = framework_loader_1.framework.createIntegrationRuntimeHost(registration, createProviderResolver(moduleRef, discovery));
|
|
@@ -292,8 +287,7 @@ function createProviderResolver(moduleRef, discovery) {
|
|
|
292
287
|
}
|
|
293
288
|
let instance = instances.get(type);
|
|
294
289
|
if (instance === undefined) {
|
|
295
|
-
instance = createNestHandlerInstance(moduleRef, contextId, dependencies, type)
|
|
296
|
-
.then(async (created) => {
|
|
290
|
+
instance = createNestHandlerInstance(moduleRef, contextId, dependencies, type).then(async (created) => {
|
|
297
291
|
if (disposed) {
|
|
298
292
|
await disposeNestOwnedHandler(created);
|
|
299
293
|
throw new Error('Handler instance scope was disposed during activation.');
|
|
@@ -303,7 +297,7 @@ function createProviderResolver(moduleRef, discovery) {
|
|
|
303
297
|
});
|
|
304
298
|
instances.set(type, instance);
|
|
305
299
|
}
|
|
306
|
-
return await instance;
|
|
300
|
+
return (await instance);
|
|
307
301
|
},
|
|
308
302
|
async dispose() {
|
|
309
303
|
if (disposed)
|
|
@@ -360,7 +354,8 @@ async function disposeNestOwnedHandler(instance) {
|
|
|
360
354
|
}
|
|
361
355
|
async function createNestHandlerInstance(moduleRef, contextId, dependencies, type) {
|
|
362
356
|
const reflected = [
|
|
363
|
-
...(Reflect.getMetadata(constants_1.PARAMTYPES_METADATA, type) ??
|
|
357
|
+
...(Reflect.getMetadata(constants_1.PARAMTYPES_METADATA, type) ??
|
|
358
|
+
[])
|
|
364
359
|
];
|
|
365
360
|
const declared = Reflect.getMetadata(constants_1.SELF_DECLARED_DEPS_METADATA, type);
|
|
366
361
|
for (const dependency of declared ?? []) {
|
|
@@ -380,9 +375,7 @@ async function createNestHandlerInstance(moduleRef, contextId, dependencies, typ
|
|
|
380
375
|
return instance;
|
|
381
376
|
}
|
|
382
377
|
async function resolveNestHandlerDependency(moduleRef, contextId, dependencies, token, optional) {
|
|
383
|
-
const forwardReference = typeof token === 'object'
|
|
384
|
-
&& token !== null
|
|
385
|
-
&& 'forwardRef' in token
|
|
378
|
+
const forwardReference = typeof token === 'object' && token !== null && 'forwardRef' in token
|
|
386
379
|
? token
|
|
387
380
|
: undefined;
|
|
388
381
|
const resolvedToken = typeof forwardReference?.forwardRef === 'function'
|
|
@@ -390,7 +383,9 @@ async function resolveNestHandlerDependency(moduleRef, contextId, dependencies,
|
|
|
390
383
|
: token;
|
|
391
384
|
let dependency = dependencies.get(resolvedToken);
|
|
392
385
|
if (dependency === undefined) {
|
|
393
|
-
dependency = moduleRef.resolve(resolvedToken, contextId, {
|
|
386
|
+
dependency = moduleRef.resolve(resolvedToken, contextId, {
|
|
387
|
+
strict: false
|
|
388
|
+
});
|
|
394
389
|
dependencies.set(resolvedToken, dependency);
|
|
395
390
|
}
|
|
396
391
|
try {
|
|
@@ -405,11 +400,9 @@ async function resolveNestHandlerDependency(moduleRef, contextId, dependencies,
|
|
|
405
400
|
}
|
|
406
401
|
function findDiscoveredProviderInstance(discovery, type) {
|
|
407
402
|
for (const wrapper of discovery?.getProviders() ?? []) {
|
|
408
|
-
if (wrapper.instance !== undefined
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|| wrapper.metatype === type
|
|
412
|
-
|| wrapper.instance.constructor === type)) {
|
|
403
|
+
if (wrapper.instance !== undefined &&
|
|
404
|
+
wrapper.instance !== null &&
|
|
405
|
+
(wrapper.token === type || wrapper.metatype === type || wrapper.instance.constructor === type)) {
|
|
413
406
|
return wrapper.instance;
|
|
414
407
|
}
|
|
415
408
|
}
|
|
@@ -10,12 +10,11 @@ const handler_adapters_1 = require("./handler-adapters");
|
|
|
10
10
|
const framework_loader_1 = require("./framework-loader");
|
|
11
11
|
const spot_node_handler_registry_1 = require("./spot-node-handler-registry");
|
|
12
12
|
function hasNestHandlerDiscovery(options) {
|
|
13
|
-
return hasConfiguredSpotNodes(options.spotNodes)
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|| (channel.publishHandlerTypes ?? []).length > 0);
|
|
13
|
+
return (hasConfiguredSpotNodes(options.spotNodes) ||
|
|
14
|
+
Object.values(options.clientServerChannels ?? {}).some((channel) => (channel.handlerGroups ?? []).length > 0 ||
|
|
15
|
+
(channel.requestHandlerTypes ?? []).length > 0 ||
|
|
16
|
+
(channel.sendHandlerTypes ?? []).length > 0) ||
|
|
17
|
+
Object.values(options.fanoutChannels ?? {}).some((channel) => (channel.handlerGroups ?? []).length > 0 || (channel.publishHandlerTypes ?? []).length > 0));
|
|
19
18
|
}
|
|
20
19
|
function hasConfiguredSpotNodes(value) {
|
|
21
20
|
if (value === undefined) {
|
|
@@ -28,10 +27,18 @@ function createDiscoveredOptions(options, discovery, moduleRef) {
|
|
|
28
27
|
const channels = { ...(registrationOptions.channels ?? {}) };
|
|
29
28
|
const useImplicitHandlers = options.implicitHandlerAutoRegistration !== false;
|
|
30
29
|
const providerRefs = useImplicitHandlers ? (0, provider_discovery_1.discoverProviderRefs)(discovery, moduleRef) : [];
|
|
31
|
-
const spotActorProviderRefs = useImplicitHandlers
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
const
|
|
30
|
+
const spotActorProviderRefs = useImplicitHandlers
|
|
31
|
+
? (0, provider_discovery_1.discoverSpotActorProviderRefs)(discovery, moduleRef)
|
|
32
|
+
: [];
|
|
33
|
+
const spotProviderRefs = useImplicitHandlers
|
|
34
|
+
? (0, provider_discovery_1.discoverSpotProviderRefs)(discovery, moduleRef)
|
|
35
|
+
: [];
|
|
36
|
+
const spotTimerProviderRefs = useImplicitHandlers
|
|
37
|
+
? (0, provider_discovery_1.discoverSpotTimerProviderRefs)(discovery, moduleRef)
|
|
38
|
+
: [];
|
|
39
|
+
const sessionProviderRefs = useImplicitHandlers
|
|
40
|
+
? (0, provider_discovery_1.discoverSessionProviderRefs)(discovery, moduleRef)
|
|
41
|
+
: [];
|
|
35
42
|
const spotNodes = createDiscoveredMeshChannelOptions(createDiscoveredSpotNodeOptions(registrationOptions.spotNodes, spotActorProviderRefs, spotProviderRefs, spotTimerProviderRefs), providerRefs, moduleRef);
|
|
36
43
|
for (const [channelName, channel] of Object.entries(options.fanoutChannels ?? {})) {
|
|
37
44
|
const existingChannel = channels[channelName];
|
|
@@ -84,11 +91,15 @@ function createDiscoveredMeshChannelOptions(value, providerRefs, moduleRef) {
|
|
|
84
91
|
if (value === undefined || Array.isArray(value)) {
|
|
85
92
|
return value;
|
|
86
93
|
}
|
|
87
|
-
return Object.fromEntries(Object.entries(value).map(([meshName, mesh]) => [
|
|
94
|
+
return Object.fromEntries(Object.entries(value).map(([meshName, mesh]) => [
|
|
95
|
+
meshName,
|
|
96
|
+
{
|
|
88
97
|
...mesh,
|
|
89
98
|
meshChannels: mesh.meshChannels === undefined
|
|
90
99
|
? undefined
|
|
91
|
-
: Object.fromEntries(Object.entries(mesh.meshChannels).map(([channelName, channel]) => [
|
|
100
|
+
: Object.fromEntries(Object.entries(mesh.meshChannels).map(([channelName, channel]) => [
|
|
101
|
+
channelName,
|
|
102
|
+
{
|
|
92
103
|
...channel,
|
|
93
104
|
requestHandlers: [
|
|
94
105
|
...(0, handler_adapters_1.createManualRequestHandlers)(channel.requestHandlers, moduleRef),
|
|
@@ -98,8 +109,10 @@ function createDiscoveredMeshChannelOptions(value, providerRefs, moduleRef) {
|
|
|
98
109
|
...(0, handler_adapters_1.createManualSendHandlers)(channel.sendHandlers, moduleRef),
|
|
99
110
|
...(0, handler_adapters_1.createDiscoveredSendHandlers)(providerRefs, channel.handlerGroups, moduleRef)
|
|
100
111
|
]
|
|
101
|
-
}
|
|
102
|
-
|
|
112
|
+
}
|
|
113
|
+
]))
|
|
114
|
+
}
|
|
115
|
+
]));
|
|
103
116
|
}
|
|
104
117
|
function createDiscoveredSpotNodeOptions(value, refs, spotRefs = [], timerRefs = []) {
|
|
105
118
|
if (refs.length === 0 && spotRefs.length === 0 && timerRefs.length === 0) {
|
|
@@ -190,7 +203,8 @@ function addDiscoveredSpotHandlers(registry, spotRefs) {
|
|
|
190
203
|
}
|
|
191
204
|
function addDiscoveredSpotActorHandlers(registry, refs) {
|
|
192
205
|
for (const ref of refs) {
|
|
193
|
-
if (ref.metadata.kind === 'entrySpotActorSend' ||
|
|
206
|
+
if (ref.metadata.kind === 'entrySpotActorSend' ||
|
|
207
|
+
ref.metadata.kind === 'entrySpotActorRequest') {
|
|
194
208
|
const entrySpotType = resolveNestType(ref.metadata.entrySpot, 'entrySpot');
|
|
195
209
|
const actorType = resolveNestType(ref.metadata.actor, 'actor');
|
|
196
210
|
const targets = registry.entrySpotTargets(entrySpotType, `ZLink Entry Spot actor handler '${ref.handlerName}' targets an Entry Spot that is not registered on any SpotNode.`);
|
|
@@ -263,9 +277,11 @@ function createRegistrationOptions(options) {
|
|
|
263
277
|
channels[name] = {
|
|
264
278
|
routingId: channel.routingId,
|
|
265
279
|
routingIdPrefix: channel.routingIdPrefix,
|
|
280
|
+
noDrop: channel.noDrop,
|
|
266
281
|
publishHandlers: channel.publishHandlers,
|
|
267
282
|
publisher: channel.publisher,
|
|
268
|
-
subscriber: channel.subscriber
|
|
283
|
+
subscriber: channel.subscriber,
|
|
284
|
+
subscriptions: channel.subscriptions
|
|
269
285
|
};
|
|
270
286
|
}
|
|
271
287
|
return {
|
|
@@ -304,7 +320,8 @@ function assertBuiltModuleOptions(options) {
|
|
|
304
320
|
return options;
|
|
305
321
|
}
|
|
306
322
|
function isBuiltModuleOptions(options) {
|
|
307
|
-
return typeof options === 'object'
|
|
308
|
-
|
|
309
|
-
|
|
323
|
+
return (typeof options === 'object' &&
|
|
324
|
+
options !== null &&
|
|
325
|
+
options[contracts_1.ZLINK_MODULE_OPTIONS_BRAND] ===
|
|
326
|
+
true);
|
|
310
327
|
}
|
|
@@ -32,8 +32,8 @@ class SpotNodeHandlerRegistry {
|
|
|
32
32
|
return this.requireTargets((node) => node.entrySpotType === entrySpotType, missingMessage);
|
|
33
33
|
}
|
|
34
34
|
spotTargets(spotType, missingMessage) {
|
|
35
|
-
return this.requireTargets((node) => (node.spotFactories ?? []).includes(spotType)
|
|
36
|
-
|
|
35
|
+
return this.requireTargets((node) => (node.spotFactories ?? []).includes(spotType) ||
|
|
36
|
+
Object.values(node.instanceSpotFactories ?? {}).includes(spotType), missingMessage);
|
|
37
37
|
}
|
|
38
38
|
addEntrySpotTimer(node, registration) {
|
|
39
39
|
node.entrySpotTimerHandlers = [...(node.entrySpotTimerHandlers ?? []), registration];
|
|
@@ -49,8 +49,12 @@ class SpotNodeHandlerRegistry {
|
|
|
49
49
|
}
|
|
50
50
|
addEntrySpotSubscription(node, registration) {
|
|
51
51
|
this.assertUnique(node.entrySpotSubscriptionHandlers, (existing) => existing.entrySpotType === registration.entrySpotType &&
|
|
52
|
-
existing.channelName === registration.channelName &&
|
|
53
|
-
|
|
52
|
+
existing.channelName === registration.channelName &&
|
|
53
|
+
existing.topic === registration.topic, `Duplicate Entry Spot subscription handler '${registration.entrySpotType.name}:${registration.channelName}:${registration.topic}'.`);
|
|
54
|
+
node.entrySpotSubscriptionHandlers = [
|
|
55
|
+
...(node.entrySpotSubscriptionHandlers ?? []),
|
|
56
|
+
registration
|
|
57
|
+
];
|
|
54
58
|
}
|
|
55
59
|
addSpotPacket(node, registration) {
|
|
56
60
|
const packetName = registration.packetName ?? registration.handlerType.name;
|
|
@@ -60,13 +64,12 @@ class SpotNodeHandlerRegistry {
|
|
|
60
64
|
}
|
|
61
65
|
addSpotSubscription(node, registration) {
|
|
62
66
|
this.assertUnique(node.spotSubscriptionHandlers, (existing) => existing.spotType === registration.spotType &&
|
|
63
|
-
existing.channelName === registration.channelName &&
|
|
67
|
+
existing.channelName === registration.channelName &&
|
|
68
|
+
existing.topic === registration.topic, `Duplicate SPOT subscription handler '${registration.spotType.name}:${registration.channelName}:${registration.topic}'.`);
|
|
64
69
|
node.spotSubscriptionHandlers = [...(node.spotSubscriptionHandlers ?? []), registration];
|
|
65
70
|
}
|
|
66
71
|
addEntrySpotActor(node, kind, registration) {
|
|
67
|
-
const existing = kind === 'send'
|
|
68
|
-
? node.entrySpotActorSendHandlers
|
|
69
|
-
: node.entrySpotActorRequestHandlers;
|
|
72
|
+
const existing = kind === 'send' ? node.entrySpotActorSendHandlers : node.entrySpotActorRequestHandlers;
|
|
70
73
|
this.assertUnique(existing, (handler) => handler.entrySpotType === registration.entrySpotType &&
|
|
71
74
|
handler.actorType === registration.actorType &&
|
|
72
75
|
handler.packetName === registration.packetName, `Duplicate Entry Spot actor handler '${registration.entrySpotType.name}:${registration.actorType.name}:${registration.packetName}'.`);
|
|
@@ -74,7 +77,10 @@ class SpotNodeHandlerRegistry {
|
|
|
74
77
|
node.entrySpotActorSendHandlers = [...(node.entrySpotActorSendHandlers ?? []), registration];
|
|
75
78
|
}
|
|
76
79
|
else {
|
|
77
|
-
node.entrySpotActorRequestHandlers = [
|
|
80
|
+
node.entrySpotActorRequestHandlers = [
|
|
81
|
+
...(node.entrySpotActorRequestHandlers ?? []),
|
|
82
|
+
registration
|
|
83
|
+
];
|
|
78
84
|
}
|
|
79
85
|
}
|
|
80
86
|
addSpotActor(node, kind, registration) {
|