@zlink-systems/nestjs 0.10.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/LICENSE +105 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/auto-discovery-marker.d.ts +3 -0
- package/dist/auto-discovery-marker.js +12 -0
- package/dist/contracts.d.ts +229 -0
- package/dist/contracts.js +4 -0
- package/dist/decorators.d.ts +16 -0
- package/dist/decorators.js +174 -0
- package/dist/dispatch-scope.d.ts +5 -0
- package/dist/dispatch-scope.js +19 -0
- package/dist/drain-health-indicator.d.ts +9 -0
- package/dist/drain-health-indicator.js +32 -0
- package/dist/framework-integration-contracts.d.ts +368 -0
- package/dist/framework-integration-contracts.js +2 -0
- package/dist/framework-loader.d.ts +50 -0
- package/dist/framework-loader.js +16 -0
- package/dist/handler-adapters.d.ts +13 -0
- package/dist/handler-adapters.js +155 -0
- package/dist/handler-metadata.d.ts +55 -0
- package/dist/handler-metadata.js +84 -0
- package/dist/http-client-module.d.ts +28 -0
- package/dist/http-client-module.js +96 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +27 -0
- package/dist/internal-tokens.d.ts +2 -0
- package/dist/internal-tokens.js +5 -0
- package/dist/module.d.ts +11 -0
- package/dist/module.js +203 -0
- package/dist/options-builder.d.ts +2 -0
- package/dist/options-builder.js +973 -0
- package/dist/provider-discovery.d.ts +36 -0
- package/dist/provider-discovery.js +186 -0
- package/dist/providers.d.ts +16 -0
- package/dist/providers.js +426 -0
- package/dist/registration-composer.d.ts +7 -0
- package/dist/registration-composer.js +310 -0
- package/dist/spot-node-handler-registry.d.ts +24 -0
- package/dist/spot-node-handler-registry.js +105 -0
- package/dist/tokens.d.ts +19 -0
- package/dist/tokens.js +22 -0
- package/package.json +26 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { InjectionToken } from '@nestjs/common';
|
|
2
|
+
import type { DiscoveryService, ModuleRef } from '@nestjs/core';
|
|
3
|
+
import type { Type } from '@zlink-systems/framework';
|
|
4
|
+
import { type ZLinkNestHandlerMetadata, type ZLinkNestSpotActorHandlerMetadata, type ZLinkNestSpotHandlerMetadata, type ZLinkNestSpotTimerHandlerMetadata } from './handler-metadata';
|
|
5
|
+
export interface DiscoveredNestProvider {
|
|
6
|
+
readonly handlerKey: InjectionToken;
|
|
7
|
+
readonly handlerName: string;
|
|
8
|
+
readonly token: InjectionToken;
|
|
9
|
+
readonly metadata: ZLinkNestHandlerMetadata;
|
|
10
|
+
}
|
|
11
|
+
export interface DiscoveredNestSpotActorProvider {
|
|
12
|
+
readonly handlerKey: Type;
|
|
13
|
+
readonly handlerName: string;
|
|
14
|
+
readonly token: InjectionToken;
|
|
15
|
+
readonly metadata: ZLinkNestSpotActorHandlerMetadata;
|
|
16
|
+
}
|
|
17
|
+
export interface DiscoveredNestSpotProvider {
|
|
18
|
+
readonly handlerKey: Type;
|
|
19
|
+
readonly handlerName: string;
|
|
20
|
+
readonly token: InjectionToken;
|
|
21
|
+
readonly metadata: ZLinkNestSpotHandlerMetadata;
|
|
22
|
+
}
|
|
23
|
+
export interface DiscoveredNestSpotTimerProvider {
|
|
24
|
+
readonly handlerKey: Type;
|
|
25
|
+
readonly handlerName: string;
|
|
26
|
+
readonly token: InjectionToken;
|
|
27
|
+
readonly metadata: ZLinkNestSpotTimerHandlerMetadata;
|
|
28
|
+
}
|
|
29
|
+
export interface DiscoveredNestSessionProvider {
|
|
30
|
+
readonly handlerKey: Type;
|
|
31
|
+
}
|
|
32
|
+
export declare function discoverSessionProviderRefs(discovery: DiscoveryService, moduleRef: ModuleRef): DiscoveredNestSessionProvider[];
|
|
33
|
+
export declare function discoverProviderRefs(discovery: DiscoveryService, moduleRef: ModuleRef): DiscoveredNestProvider[];
|
|
34
|
+
export declare function discoverSpotProviderRefs(discovery: DiscoveryService, moduleRef: ModuleRef): DiscoveredNestSpotProvider[];
|
|
35
|
+
export declare function discoverSpotActorProviderRefs(discovery: DiscoveryService, moduleRef: ModuleRef): DiscoveredNestSpotActorProvider[];
|
|
36
|
+
export declare function discoverSpotTimerProviderRefs(discovery: DiscoveryService, moduleRef: ModuleRef): DiscoveredNestSpotTimerProvider[];
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.discoverSessionProviderRefs = discoverSessionProviderRefs;
|
|
4
|
+
exports.discoverProviderRefs = discoverProviderRefs;
|
|
5
|
+
exports.discoverSpotProviderRefs = discoverSpotProviderRefs;
|
|
6
|
+
exports.discoverSpotActorProviderRefs = discoverSpotActorProviderRefs;
|
|
7
|
+
exports.discoverSpotTimerProviderRefs = discoverSpotTimerProviderRefs;
|
|
8
|
+
const framework_loader_1 = require("./framework-loader");
|
|
9
|
+
const auto_discovery_marker_1 = require("./auto-discovery-marker");
|
|
10
|
+
const handler_metadata_1 = require("./handler-metadata");
|
|
11
|
+
function discoverSessionProviderRefs(discovery, moduleRef) {
|
|
12
|
+
const refs = [];
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
const metadataSymbol = Symbol.for('@zlink-systems/framework:decorator');
|
|
15
|
+
for (const wrapper of discovery.getProviders()) {
|
|
16
|
+
const handlerType = wrapper.metatype;
|
|
17
|
+
if (typeof handlerType !== 'function'
|
|
18
|
+
|| seen.has(handlerType)
|
|
19
|
+
|| !(0, auto_discovery_marker_1.isAutoDiscoveredProvider)(handlerType)) {
|
|
20
|
+
continue;
|
|
21
|
+
}
|
|
22
|
+
// The symbol is only present on decorated handlers, so the lookup has to
|
|
23
|
+
// admit undefined for the fallback to mean anything.
|
|
24
|
+
const metadata = handlerType[metadataSymbol] ?? [];
|
|
25
|
+
if (metadata.some((entry) => entry.kind === 'packet')
|
|
26
|
+
&& typeof handlerType.prototype?.handle === 'function'
|
|
27
|
+
&& tryGetProviderInstance(moduleRef, handlerType) !== undefined) {
|
|
28
|
+
seen.add(handlerType);
|
|
29
|
+
refs.push({ handlerKey: handlerType });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return refs;
|
|
33
|
+
}
|
|
34
|
+
function discoverProviderRefs(discovery, moduleRef) {
|
|
35
|
+
return discoverDecoratedProviderRefs({
|
|
36
|
+
discovery,
|
|
37
|
+
moduleRef,
|
|
38
|
+
metadataEntries: (0, handler_metadata_1.nestHandlerMetadataEntries)(),
|
|
39
|
+
readMetadata: handler_metadata_1.readNestHandlerMetadata,
|
|
40
|
+
metadataKey: (metadata) => `${metadata.groupName}:${metadata.kind}:${metadata.packetName}`,
|
|
41
|
+
createRef: ({ handlerKey, handlerName, token, metadata }) => ({
|
|
42
|
+
handlerKey,
|
|
43
|
+
handlerName,
|
|
44
|
+
token,
|
|
45
|
+
metadata
|
|
46
|
+
})
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
function discoverSpotProviderRefs(discovery, moduleRef) {
|
|
50
|
+
return discoverDecoratedClassProviderRefs({
|
|
51
|
+
discovery,
|
|
52
|
+
moduleRef,
|
|
53
|
+
metadataEntries: (0, handler_metadata_1.nestSpotHandlerMetadataEntries)(),
|
|
54
|
+
readMetadata: handler_metadata_1.readNestSpotHandlerMetadata,
|
|
55
|
+
metadataKey: (metadata) => `${metadata.kind}:${metadata.packetName ?? metadata.topic ?? ''}`,
|
|
56
|
+
invalidClassMessage: 'ZLink SPOT handler decorators must be applied to class providers.',
|
|
57
|
+
createRef: ({ handlerKey, handlerName, token, metadata }) => ({
|
|
58
|
+
handlerKey,
|
|
59
|
+
handlerName,
|
|
60
|
+
token,
|
|
61
|
+
metadata
|
|
62
|
+
})
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function discoverSpotActorProviderRefs(discovery, moduleRef) {
|
|
66
|
+
return discoverDecoratedClassProviderRefs({
|
|
67
|
+
discovery,
|
|
68
|
+
moduleRef,
|
|
69
|
+
metadataEntries: (0, handler_metadata_1.nestSpotActorHandlerMetadataEntries)(),
|
|
70
|
+
readMetadata: handler_metadata_1.readNestSpotActorHandlerMetadata,
|
|
71
|
+
metadataKey: (metadata) => `${metadata.kind}:${metadata.packetName}`,
|
|
72
|
+
invalidClassMessage: 'ZLink SPOT actor handler decorators must be applied to class providers.',
|
|
73
|
+
createRef: ({ handlerKey, handlerName, token, metadata }) => ({
|
|
74
|
+
handlerKey,
|
|
75
|
+
handlerName,
|
|
76
|
+
token,
|
|
77
|
+
metadata
|
|
78
|
+
})
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
function discoverSpotTimerProviderRefs(discovery, moduleRef) {
|
|
82
|
+
return discoverDecoratedClassProviderRefs({
|
|
83
|
+
discovery,
|
|
84
|
+
moduleRef,
|
|
85
|
+
metadataEntries: (0, handler_metadata_1.nestSpotTimerHandlerMetadataEntries)(),
|
|
86
|
+
readMetadata: handler_metadata_1.readNestSpotTimerHandlerMetadata,
|
|
87
|
+
metadataKey: (metadata) => metadata.name,
|
|
88
|
+
invalidClassMessage: 'ZLink SPOT timer handler decorators must be applied to class providers.',
|
|
89
|
+
createRef: ({ handlerKey, handlerName, token, metadata }) => ({
|
|
90
|
+
handlerKey,
|
|
91
|
+
handlerName,
|
|
92
|
+
token,
|
|
93
|
+
metadata
|
|
94
|
+
})
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
function discoverDecoratedProviderRefs(options) {
|
|
98
|
+
const refs = [];
|
|
99
|
+
const seen = new Set();
|
|
100
|
+
for (const wrapper of options.discovery.getProviders()) {
|
|
101
|
+
const token = wrapper.token;
|
|
102
|
+
if (token === undefined) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
const instance = wrapper.instance === undefined ? undefined : wrapper.instance;
|
|
106
|
+
for (const handlerKey of providerMetadataCandidateTokens(wrapper.metatype, instance, token)) {
|
|
107
|
+
appendDiscoveredProviderRefs(refs, seen, {
|
|
108
|
+
handlerKey,
|
|
109
|
+
token,
|
|
110
|
+
instance,
|
|
111
|
+
metadataList: options.readMetadata(handlerKey),
|
|
112
|
+
metadataKey: options.metadataKey,
|
|
113
|
+
createRef: options.createRef
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
for (const [handlerKey, metadataList] of options.metadataEntries) {
|
|
118
|
+
const instance = tryGetProviderInstance(options.moduleRef, handlerKey);
|
|
119
|
+
if (instance === undefined) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
appendDiscoveredProviderRefs(refs, seen, {
|
|
123
|
+
handlerKey,
|
|
124
|
+
token: handlerKey,
|
|
125
|
+
instance,
|
|
126
|
+
metadataList,
|
|
127
|
+
metadataKey: options.metadataKey,
|
|
128
|
+
createRef: options.createRef
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
return refs;
|
|
132
|
+
}
|
|
133
|
+
function discoverDecoratedClassProviderRefs(options) {
|
|
134
|
+
return discoverDecoratedProviderRefs({
|
|
135
|
+
...options,
|
|
136
|
+
createRef: (input) => {
|
|
137
|
+
if (typeof input.handlerKey !== 'function') {
|
|
138
|
+
throw new framework_loader_1.framework.ZLinkConfigurationException(options.invalidClassMessage);
|
|
139
|
+
}
|
|
140
|
+
return options.createRef({
|
|
141
|
+
...input,
|
|
142
|
+
handlerKey: input.handlerKey
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
function appendDiscoveredProviderRefs(refs, seen, options) {
|
|
148
|
+
const handlerName = handlerKeyName(options.handlerKey);
|
|
149
|
+
for (const metadata of options.metadataList) {
|
|
150
|
+
const key = `${String(options.token)}:${handlerName}:${options.metadataKey(metadata)}`;
|
|
151
|
+
if (seen.has(key)) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
seen.add(key);
|
|
155
|
+
refs.push(options.createRef({
|
|
156
|
+
handlerKey: options.handlerKey,
|
|
157
|
+
handlerName,
|
|
158
|
+
token: options.token,
|
|
159
|
+
instance: options.instance,
|
|
160
|
+
metadata
|
|
161
|
+
}));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
function providerMetadataCandidateTokens(metatype, instance, token) {
|
|
165
|
+
return [...new Set([metatype, instance?.constructor, token].filter(isInjectionToken))];
|
|
166
|
+
}
|
|
167
|
+
function isInjectionToken(value) {
|
|
168
|
+
return typeof value === 'function' || typeof value === 'string' || typeof value === 'symbol';
|
|
169
|
+
}
|
|
170
|
+
function tryGetProviderInstance(moduleRef, token) {
|
|
171
|
+
try {
|
|
172
|
+
return moduleRef.get(token, { strict: false });
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
return undefined;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
function handlerKeyName(handlerKey) {
|
|
179
|
+
if (typeof handlerKey === 'function') {
|
|
180
|
+
return handlerKey.name;
|
|
181
|
+
}
|
|
182
|
+
if (typeof handlerKey === 'symbol') {
|
|
183
|
+
return handlerKey.description ?? handlerKey.toString();
|
|
184
|
+
}
|
|
185
|
+
return handlerKey;
|
|
186
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { InjectionToken, OnModuleDestroy, OnModuleInit, Provider } from '@nestjs/common';
|
|
2
|
+
import { DiscoveryService, ModuleRef } from '@nestjs/core';
|
|
3
|
+
import type { Type } from '@zlink-systems/framework';
|
|
4
|
+
import type { ZLinkFrameworkRegistration } from './framework-integration-contracts';
|
|
5
|
+
import { type FrameworkRuntimeHost } from './framework-loader';
|
|
6
|
+
type RuntimeHostWithNestLifecycle = FrameworkRuntimeHost & OnModuleInit & OnModuleDestroy;
|
|
7
|
+
export declare function alwaysAvailableClientProviders(registration?: ZLinkFrameworkRegistration): Provider[];
|
|
8
|
+
export declare function alwaysAvailableClientTokens(): InjectionToken[];
|
|
9
|
+
export declare function conditionalClientProviders(registration: ZLinkFrameworkRegistration): Provider[];
|
|
10
|
+
export declare function conditionalClientProvidersForFactory(): Provider[];
|
|
11
|
+
export declare function conditionalClientTokens(): InjectionToken[];
|
|
12
|
+
export declare function createRuntimeHost(registration: ZLinkFrameworkRegistration, moduleRef: ModuleRef, discovery: DiscoveryService): RuntimeHostWithNestLifecycle;
|
|
13
|
+
export declare function disposeNestOwnedHandler(instance: unknown): Promise<void>;
|
|
14
|
+
export declare function createNestHandlerInstance<T>(moduleRef: ModuleRef, contextId: import('@nestjs/core').ContextId, dependencies: Map<unknown, Promise<unknown>>, type: Type<T>): Promise<T>;
|
|
15
|
+
export declare function providerToken(provider: Provider): InjectionToken;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.alwaysAvailableClientProviders = alwaysAvailableClientProviders;
|
|
4
|
+
exports.alwaysAvailableClientTokens = alwaysAvailableClientTokens;
|
|
5
|
+
exports.conditionalClientProviders = conditionalClientProviders;
|
|
6
|
+
exports.conditionalClientProvidersForFactory = conditionalClientProvidersForFactory;
|
|
7
|
+
exports.conditionalClientTokens = conditionalClientTokens;
|
|
8
|
+
exports.createRuntimeHost = createRuntimeHost;
|
|
9
|
+
exports.disposeNestOwnedHandler = disposeNestOwnedHandler;
|
|
10
|
+
exports.createNestHandlerInstance = createNestHandlerInstance;
|
|
11
|
+
exports.providerToken = providerToken;
|
|
12
|
+
const constants_1 = require("@nestjs/common/constants");
|
|
13
|
+
const core_1 = require("@nestjs/core");
|
|
14
|
+
const tokens_1 = require("./tokens");
|
|
15
|
+
const internal_tokens_1 = require("./internal-tokens");
|
|
16
|
+
const framework_loader_1 = require("./framework-loader");
|
|
17
|
+
const dispatch_scope_1 = require("./dispatch-scope");
|
|
18
|
+
const ALWAYS_AVAILABLE_CLIENT_PROVIDER_SPECS = [
|
|
19
|
+
{
|
|
20
|
+
token: tokens_1.ZLINK_CHANNEL_CLIENT,
|
|
21
|
+
create: (registration, runtime) => framework_loader_1.framework.createIntegrationChannelClient(registration, runtime)
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
token: tokens_1.ZLINK_CHANNEL_RUNTIME_OPTIONS,
|
|
25
|
+
create: (_registration, runtime) => runtime.channelRuntimeOptions
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
token: tokens_1.ZLINK_FANOUT_CLIENT,
|
|
29
|
+
create: (registration, runtime) => framework_loader_1.framework.createIntegrationFanoutClient(registration, runtime)
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
token: tokens_1.ZLINK_ROUTE_CLIENT,
|
|
33
|
+
create: (registration, runtime) => framework_loader_1.framework.createIntegrationRouteClient(registration, runtime)
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
token: tokens_1.ZLINK_BOUND_SESSION_FACTORY,
|
|
37
|
+
create: (_registration, runtime) => runtime.boundSessionFactory
|
|
38
|
+
}
|
|
39
|
+
];
|
|
40
|
+
function alwaysAvailableClientProviders(registration) {
|
|
41
|
+
return [
|
|
42
|
+
...ALWAYS_AVAILABLE_CLIENT_PROVIDER_SPECS.map((spec) => createAlwaysAvailableClientProvider(spec, registration)),
|
|
43
|
+
{ provide: tokens_1.ZLINK_MESSAGE_METADATA_POLICY, useValue: Object.freeze({ forward: true }) }
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
function createAlwaysAvailableClientProvider(spec, registration) {
|
|
47
|
+
if (registration !== undefined) {
|
|
48
|
+
return {
|
|
49
|
+
provide: spec.token,
|
|
50
|
+
inject: [tokens_1.ZLINK_FRAMEWORK_RUNTIME],
|
|
51
|
+
useFactory: (runtime) => spec.create(registration, runtime)
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
return {
|
|
55
|
+
provide: spec.token,
|
|
56
|
+
inject: [tokens_1.ZLINK_FRAMEWORK_REGISTRATION, tokens_1.ZLINK_FRAMEWORK_RUNTIME],
|
|
57
|
+
useFactory: (resolved, runtime) => spec.create(resolved, runtime)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function alwaysAvailableClientTokens() {
|
|
61
|
+
return [
|
|
62
|
+
tokens_1.ZLINK_CHANNEL_CLIENT,
|
|
63
|
+
tokens_1.ZLINK_ROUTE_CLIENT,
|
|
64
|
+
tokens_1.ZLINK_FANOUT_CLIENT,
|
|
65
|
+
tokens_1.ZLINK_BOUND_SESSION_FACTORY,
|
|
66
|
+
tokens_1.ZLINK_MESSAGE_METADATA_POLICY,
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
function conditionalClientProviders(registration) {
|
|
70
|
+
return CONDITIONAL_CLIENT_PROVIDER_SPECS
|
|
71
|
+
.filter((spec) => spec.isEnabled(registration))
|
|
72
|
+
.map((spec) => createConditionalClientProvider(spec, registration));
|
|
73
|
+
}
|
|
74
|
+
const CONDITIONAL_CLIENT_PROVIDER_SPECS = [
|
|
75
|
+
{
|
|
76
|
+
token: tokens_1.ZLINK_CLIENT_SERVER_RUNTIME,
|
|
77
|
+
requiresRuntime: true,
|
|
78
|
+
isEnabled: (registration) => [...registration.channels.values()]
|
|
79
|
+
.some(channel => channel.client !== undefined || channel.server !== undefined),
|
|
80
|
+
create: (_registration, runtime) => requireRuntime(runtime).clientServerRuntime
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
token: tokens_1.ZLINK_FANOUT_RUNTIME,
|
|
84
|
+
requiresRuntime: true,
|
|
85
|
+
isEnabled: (registration) => [...registration.channels.values()]
|
|
86
|
+
.some(channel => channel.subscriber !== undefined
|
|
87
|
+
&& (channel.subscriber.manualConnections?.length ?? 0) === 0),
|
|
88
|
+
create: (_registration, runtime) => requireRuntime(runtime).fanoutRuntime
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
token: tokens_1.ZLINK_ROUTE_MESH_RUNTIME_OPTIONS,
|
|
92
|
+
requiresRuntime: true,
|
|
93
|
+
isEnabled: (registration) => registration.spotNodes.size > 0,
|
|
94
|
+
create: (_registration, runtime) => requireRuntime(runtime).routeMeshRuntimeOptions
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
token: tokens_1.ZLINK_ROUTE_MESH_RUNTIME,
|
|
98
|
+
requiresRuntime: true,
|
|
99
|
+
isEnabled: (registration) => registration.spotNodes.size > 0,
|
|
100
|
+
create: (_registration, runtime) => requireRuntime(runtime).routeMeshRuntime
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
token: tokens_1.ZLINK_SPOT_MANAGER,
|
|
104
|
+
requiresRuntime: true,
|
|
105
|
+
isEnabled: (registration) => framework_loader_1.framework.hasSpotNode(registration) && hasLocationStores(registration),
|
|
106
|
+
create: (registration, runtime, moduleRef, discovery) => createSpotManager(registration, requireRuntime(runtime), moduleRef, discovery)
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
token: tokens_1.ZLINK_SPOT_OUTBOUND,
|
|
110
|
+
requiresRuntime: true,
|
|
111
|
+
isEnabled: (registration) => framework_loader_1.framework.hasSpotNode(registration),
|
|
112
|
+
create: (registration, runtime, moduleRef, discovery) => createSpotOutbound(registration, requireRuntime(runtime), moduleRef, discovery)
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
token: tokens_1.ZLINK_SPOT_PUBLISHER_CLIENT,
|
|
116
|
+
requiresRuntime: true,
|
|
117
|
+
isEnabled: (registration) => framework_loader_1.framework.hasSpotPublisherClient(registration),
|
|
118
|
+
create: (registration, runtime) => framework_loader_1.framework.createIntegrationSpotPublisherClient(registration, requireRuntime(runtime))
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
token: tokens_1.ZLINK_ACTOR_CLIENT,
|
|
122
|
+
requiresRuntime: true,
|
|
123
|
+
isEnabled: (registration) => framework_loader_1.framework.hasSpotNode(registration) && hasLocationStores(registration),
|
|
124
|
+
create: (_registration, runtime) => framework_loader_1.framework.createIntegrationActorClient(requireRuntime(runtime))
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
token: tokens_1.ZLINK_ACTOR_MANAGER,
|
|
128
|
+
requiresRuntime: true,
|
|
129
|
+
isEnabled: (registration) => framework_loader_1.framework.hasActorManager(registration),
|
|
130
|
+
create: async (registration, runtime, moduleRef, discovery) => {
|
|
131
|
+
const host = requireRuntime(runtime);
|
|
132
|
+
return framework_loader_1.framework.createIntegrationActorManager(registration, host, moduleRef === undefined ? undefined : createProviderResolver(moduleRef, discovery));
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
{
|
|
136
|
+
token: tokens_1.ZLINK_LOCATION_RUNTIME_QUERY,
|
|
137
|
+
requiresRuntime: true,
|
|
138
|
+
isEnabled: (registration) => hasLocationStores(registration),
|
|
139
|
+
create: (_registration, runtime) => {
|
|
140
|
+
const query = requireRuntime(runtime).locationRuntimeQuery;
|
|
141
|
+
if (query === undefined) {
|
|
142
|
+
throw new framework_loader_1.framework.ZLinkConfigurationException('Location runtime query requires location stores.');
|
|
143
|
+
}
|
|
144
|
+
return query;
|
|
145
|
+
}
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
token: internal_tokens_1.ZLINK_SPOT_HANDLE_RESOLVER,
|
|
149
|
+
requiresRuntime: true,
|
|
150
|
+
isEnabled: (registration) => hasLocationStores(registration),
|
|
151
|
+
create: (_registration, runtime) => {
|
|
152
|
+
const resolver = requireRuntime(runtime).createLocationHandleResolver();
|
|
153
|
+
if (resolver === undefined) {
|
|
154
|
+
throw new framework_loader_1.framework.ZLinkConfigurationException('SpotHandle resolver requires location stores.');
|
|
155
|
+
}
|
|
156
|
+
return resolver;
|
|
157
|
+
}
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
token: internal_tokens_1.ZLINK_ACTOR_SPOT_HANDLE_RESOLVER,
|
|
161
|
+
requiresRuntime: true,
|
|
162
|
+
isEnabled: (registration) => hasLocationStores(registration),
|
|
163
|
+
create: (_registration, runtime) => {
|
|
164
|
+
const resolver = requireRuntime(runtime).createLocationHandleResolver();
|
|
165
|
+
if (resolver === undefined) {
|
|
166
|
+
throw new framework_loader_1.framework.ZLinkConfigurationException('Actor SpotHandle resolver requires location stores.');
|
|
167
|
+
}
|
|
168
|
+
return resolver;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
];
|
|
172
|
+
function conditionalClientProvidersForFactory() {
|
|
173
|
+
return CONDITIONAL_CLIENT_PROVIDER_SPECS.map(createConditionalClientProviderForFactory);
|
|
174
|
+
}
|
|
175
|
+
function createConditionalClientProviderForFactory(spec) {
|
|
176
|
+
return createConditionalClientProviderFromSpec(spec, { checkEnabled: true });
|
|
177
|
+
}
|
|
178
|
+
function createConditionalClientProvider(spec, registration) {
|
|
179
|
+
return createConditionalClientProviderFromSpec(spec, { registration, checkEnabled: false });
|
|
180
|
+
}
|
|
181
|
+
function createConditionalClientProviderFromSpec(spec, options) {
|
|
182
|
+
return {
|
|
183
|
+
provide: spec.token,
|
|
184
|
+
inject: conditionalClientProviderInject(spec, options),
|
|
185
|
+
useFactory: (...args) => {
|
|
186
|
+
const { registration, runtime, moduleRef, discovery } = conditionalClientProviderArgs(spec, options, args);
|
|
187
|
+
if (options.checkEnabled && !spec.isEnabled(registration)) {
|
|
188
|
+
return null;
|
|
189
|
+
}
|
|
190
|
+
return spec.create(registration, runtime, moduleRef, discovery);
|
|
191
|
+
}
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
function conditionalClientProviderInject(spec, options) {
|
|
195
|
+
return [
|
|
196
|
+
...(options.registration === undefined ? [tokens_1.ZLINK_FRAMEWORK_REGISTRATION] : []),
|
|
197
|
+
...(spec.requiresRuntime ? [tokens_1.ZLINK_FRAMEWORK_RUNTIME] : []),
|
|
198
|
+
core_1.ModuleRef,
|
|
199
|
+
core_1.DiscoveryService
|
|
200
|
+
];
|
|
201
|
+
}
|
|
202
|
+
function conditionalClientProviderArgs(spec, options, args) {
|
|
203
|
+
let index = 0;
|
|
204
|
+
const registration = options.registration ?? args[index++];
|
|
205
|
+
const runtime = spec.requiresRuntime ? args[index++] : undefined;
|
|
206
|
+
const moduleRef = args[index++];
|
|
207
|
+
const discovery = args[index++];
|
|
208
|
+
return { registration, runtime, moduleRef, discovery };
|
|
209
|
+
}
|
|
210
|
+
function requireRuntime(runtime) {
|
|
211
|
+
if (runtime === undefined) {
|
|
212
|
+
throw new framework_loader_1.framework.ZLinkConfigurationException('ZLink runtime host is not available.');
|
|
213
|
+
}
|
|
214
|
+
return runtime;
|
|
215
|
+
}
|
|
216
|
+
function conditionalClientTokens() {
|
|
217
|
+
return [
|
|
218
|
+
tokens_1.ZLINK_CLIENT_SERVER_RUNTIME,
|
|
219
|
+
tokens_1.ZLINK_FANOUT_RUNTIME,
|
|
220
|
+
tokens_1.ZLINK_ROUTE_MESH_RUNTIME_OPTIONS,
|
|
221
|
+
tokens_1.ZLINK_ROUTE_MESH_RUNTIME,
|
|
222
|
+
tokens_1.ZLINK_SPOT_MANAGER,
|
|
223
|
+
tokens_1.ZLINK_SPOT_OUTBOUND,
|
|
224
|
+
tokens_1.ZLINK_SPOT_PUBLISHER_CLIENT,
|
|
225
|
+
tokens_1.ZLINK_ACTOR_CLIENT,
|
|
226
|
+
tokens_1.ZLINK_ACTOR_MANAGER,
|
|
227
|
+
tokens_1.ZLINK_LOCATION_RUNTIME_QUERY
|
|
228
|
+
];
|
|
229
|
+
}
|
|
230
|
+
function hasLocationStores(registration) {
|
|
231
|
+
return registration.locations.useInMemoryStores
|
|
232
|
+
|| registration.locations.storeInstance !== undefined;
|
|
233
|
+
}
|
|
234
|
+
function createRuntimeHost(registration, moduleRef, discovery) {
|
|
235
|
+
const runtime = framework_loader_1.framework.createIntegrationRuntimeHost(registration, createProviderResolver(moduleRef, discovery));
|
|
236
|
+
runtime.onModuleInit = async () => {
|
|
237
|
+
await runtime.start();
|
|
238
|
+
};
|
|
239
|
+
runtime.onModuleDestroy = async () => {
|
|
240
|
+
await runtime.shutdown();
|
|
241
|
+
};
|
|
242
|
+
runtime.onApplicationBootstrap = async () => { };
|
|
243
|
+
return runtime;
|
|
244
|
+
}
|
|
245
|
+
function createProviderResolver(moduleRef, discovery) {
|
|
246
|
+
const resolver = {
|
|
247
|
+
get(type) {
|
|
248
|
+
const discovered = findDiscoveredProviderInstance(discovery, type);
|
|
249
|
+
if (discovered !== undefined) {
|
|
250
|
+
return discovered;
|
|
251
|
+
}
|
|
252
|
+
try {
|
|
253
|
+
return moduleRef.get(type, { strict: false });
|
|
254
|
+
}
|
|
255
|
+
catch {
|
|
256
|
+
return undefined;
|
|
257
|
+
}
|
|
258
|
+
},
|
|
259
|
+
async create(type) {
|
|
260
|
+
try {
|
|
261
|
+
// Spot and actor lifecycles request a fresh application object for
|
|
262
|
+
// each activation. ModuleRef.resolve() returns the registered
|
|
263
|
+
// singleton when the application also lists that class as a Nest
|
|
264
|
+
// provider, which would make later Spot contexts overwrite earlier
|
|
265
|
+
// activations. ModuleRef.create() preserves dependency injection
|
|
266
|
+
// while creating an independent object.
|
|
267
|
+
return await moduleRef.create(type);
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
// Fall back to direct construction through Nest for classes that are
|
|
271
|
+
// not registered as providers.
|
|
272
|
+
}
|
|
273
|
+
return await moduleRef.resolve(type, undefined, { strict: false });
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
Object.defineProperty(resolver, Symbol.for('@zlink-systems/framework.handler-instance-scope-factory'), {
|
|
277
|
+
value: {
|
|
278
|
+
create(context) {
|
|
279
|
+
const currentContextId = (0, dispatch_scope_1.currentNestDispatchContext)();
|
|
280
|
+
const contextId = currentContextId ?? core_1.ContextIdFactory.create();
|
|
281
|
+
if (context !== undefined && currentContextId === undefined) {
|
|
282
|
+
moduleRef.registerRequestByContextId({ zlinkContext: context }, contextId);
|
|
283
|
+
}
|
|
284
|
+
const instances = new Map();
|
|
285
|
+
const dependencies = new Map();
|
|
286
|
+
const owned = [];
|
|
287
|
+
let disposed = false;
|
|
288
|
+
return {
|
|
289
|
+
async resolve(type) {
|
|
290
|
+
if (disposed) {
|
|
291
|
+
throw new Error('Handler instance scope is already disposed.');
|
|
292
|
+
}
|
|
293
|
+
let instance = instances.get(type);
|
|
294
|
+
if (instance === undefined) {
|
|
295
|
+
instance = createNestHandlerInstance(moduleRef, contextId, dependencies, type)
|
|
296
|
+
.then(async (created) => {
|
|
297
|
+
if (disposed) {
|
|
298
|
+
await disposeNestOwnedHandler(created);
|
|
299
|
+
throw new Error('Handler instance scope was disposed during activation.');
|
|
300
|
+
}
|
|
301
|
+
owned.push(created);
|
|
302
|
+
return created;
|
|
303
|
+
});
|
|
304
|
+
instances.set(type, instance);
|
|
305
|
+
}
|
|
306
|
+
return await instance;
|
|
307
|
+
},
|
|
308
|
+
async dispose() {
|
|
309
|
+
if (disposed)
|
|
310
|
+
return;
|
|
311
|
+
disposed = true;
|
|
312
|
+
const pending = [...instances.values()];
|
|
313
|
+
await Promise.allSettled(pending);
|
|
314
|
+
for (let index = owned.length - 1; index >= 0; index -= 1) {
|
|
315
|
+
await disposeNestOwnedHandler(owned[index]);
|
|
316
|
+
}
|
|
317
|
+
owned.length = 0;
|
|
318
|
+
instances.clear();
|
|
319
|
+
dependencies.clear();
|
|
320
|
+
}
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
},
|
|
324
|
+
enumerable: false
|
|
325
|
+
});
|
|
326
|
+
framework_loader_1.framework.registerIntegrationHandlerFilterScope(resolver, (context, callback) => (0, dispatch_scope_1.runInNestDispatchScope)(moduleRef, context, async () => {
|
|
327
|
+
const contextId = (0, dispatch_scope_1.currentNestDispatchContext)();
|
|
328
|
+
const dependencies = new Map();
|
|
329
|
+
const owned = [];
|
|
330
|
+
try {
|
|
331
|
+
return await callback({
|
|
332
|
+
async resolve(type) {
|
|
333
|
+
const instance = await createNestHandlerInstance(moduleRef, contextId, dependencies, type);
|
|
334
|
+
owned.push(instance);
|
|
335
|
+
return instance;
|
|
336
|
+
}
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
finally {
|
|
340
|
+
for (let index = owned.length - 1; index >= 0; index -= 1) {
|
|
341
|
+
await disposeNestOwnedHandler(owned[index]);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}));
|
|
345
|
+
return resolver;
|
|
346
|
+
}
|
|
347
|
+
async function disposeNestOwnedHandler(instance) {
|
|
348
|
+
if (instance === null || instance === undefined)
|
|
349
|
+
return;
|
|
350
|
+
const value = instance;
|
|
351
|
+
if (typeof value.dispose === 'function') {
|
|
352
|
+
await value.dispose();
|
|
353
|
+
}
|
|
354
|
+
else if (typeof value.close === 'function') {
|
|
355
|
+
await value.close();
|
|
356
|
+
}
|
|
357
|
+
else if (typeof value.onModuleDestroy === 'function') {
|
|
358
|
+
await value.onModuleDestroy();
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
async function createNestHandlerInstance(moduleRef, contextId, dependencies, type) {
|
|
362
|
+
const reflected = [
|
|
363
|
+
...(Reflect.getMetadata(constants_1.PARAMTYPES_METADATA, type) ?? [])
|
|
364
|
+
];
|
|
365
|
+
const declared = Reflect.getMetadata(constants_1.SELF_DECLARED_DEPS_METADATA, type);
|
|
366
|
+
for (const dependency of declared ?? []) {
|
|
367
|
+
reflected[dependency.index] = dependency.param;
|
|
368
|
+
}
|
|
369
|
+
const optional = new Set(Reflect.getMetadata(constants_1.OPTIONAL_DEPS_METADATA, type) ?? []);
|
|
370
|
+
const parameters = await Promise.all(reflected.map((token, index) => resolveNestHandlerDependency(moduleRef, contextId, dependencies, token, optional.has(index))));
|
|
371
|
+
const instance = new type(...parameters);
|
|
372
|
+
const properties = Reflect.getMetadata(constants_1.PROPERTY_DEPS_METADATA, type);
|
|
373
|
+
const optionalProperties = new Set(Reflect.getMetadata(constants_1.OPTIONAL_PROPERTY_DEPS_METADATA, type) ?? []);
|
|
374
|
+
for (const property of properties ?? []) {
|
|
375
|
+
const dependency = await resolveNestHandlerDependency(moduleRef, contextId, dependencies, property.type, optionalProperties.has(property.key));
|
|
376
|
+
if (dependency !== undefined) {
|
|
377
|
+
instance[property.key] = dependency;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
return instance;
|
|
381
|
+
}
|
|
382
|
+
async function resolveNestHandlerDependency(moduleRef, contextId, dependencies, token, optional) {
|
|
383
|
+
const forwardReference = typeof token === 'object'
|
|
384
|
+
&& token !== null
|
|
385
|
+
&& 'forwardRef' in token
|
|
386
|
+
? token
|
|
387
|
+
: undefined;
|
|
388
|
+
const resolvedToken = typeof forwardReference?.forwardRef === 'function'
|
|
389
|
+
? forwardReference.forwardRef()
|
|
390
|
+
: token;
|
|
391
|
+
let dependency = dependencies.get(resolvedToken);
|
|
392
|
+
if (dependency === undefined) {
|
|
393
|
+
dependency = moduleRef.resolve(resolvedToken, contextId, { strict: false });
|
|
394
|
+
dependencies.set(resolvedToken, dependency);
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
return await dependency;
|
|
398
|
+
}
|
|
399
|
+
catch (error) {
|
|
400
|
+
dependencies.delete(resolvedToken);
|
|
401
|
+
if (optional)
|
|
402
|
+
return undefined;
|
|
403
|
+
throw error;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
function findDiscoveredProviderInstance(discovery, type) {
|
|
407
|
+
for (const wrapper of discovery?.getProviders() ?? []) {
|
|
408
|
+
if (wrapper.instance !== undefined
|
|
409
|
+
&& wrapper.instance !== null
|
|
410
|
+
&& (wrapper.token === type
|
|
411
|
+
|| wrapper.metatype === type
|
|
412
|
+
|| wrapper.instance.constructor === type)) {
|
|
413
|
+
return wrapper.instance;
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return undefined;
|
|
417
|
+
}
|
|
418
|
+
function providerToken(provider) {
|
|
419
|
+
return typeof provider === 'function' ? provider : provider.provide;
|
|
420
|
+
}
|
|
421
|
+
async function createSpotManager(registration, runtime, moduleRef, discovery) {
|
|
422
|
+
return framework_loader_1.framework.createIntegrationSpotManager(registration, runtime, moduleRef === undefined ? undefined : createProviderResolver(moduleRef, discovery));
|
|
423
|
+
}
|
|
424
|
+
async function createSpotOutbound(_registration, runtime, _moduleRef, _discovery) {
|
|
425
|
+
return framework_loader_1.framework.createIntegrationSpotOutbound(runtime);
|
|
426
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { DiscoveryService, ModuleRef } from '@nestjs/core';
|
|
2
|
+
import type { ZLinkFrameworkRegistrationOptions } from './framework-integration-contracts';
|
|
3
|
+
import { type ZLinkModuleOptions, type ZLinkNestModuleRegistrationOptions } from './contracts';
|
|
4
|
+
export declare function hasNestHandlerDiscovery(options: ZLinkNestModuleRegistrationOptions): boolean;
|
|
5
|
+
export declare function createDiscoveredOptions(options: ZLinkNestModuleRegistrationOptions, discovery: DiscoveryService, moduleRef: ModuleRef): ZLinkFrameworkRegistrationOptions;
|
|
6
|
+
export declare function createRegistrationOptions(options: ZLinkNestModuleRegistrationOptions): ZLinkFrameworkRegistrationOptions;
|
|
7
|
+
export declare function assertBuiltModuleOptions(options: ZLinkModuleOptions): ZLinkNestModuleRegistrationOptions;
|