@fluojs/microservices 1.0.0-beta.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/LICENSE +21 -0
- package/README.ko.md +182 -0
- package/README.md +179 -0
- package/dist/decorators.d.ts +51 -0
- package/dist/decorators.d.ts.map +1 -0
- package/dist/decorators.js +106 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/metadata.d.ts +9 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +48 -0
- package/dist/module.d.ts +23 -0
- package/dist/module.d.ts.map +1 -0
- package/dist/module.js +55 -0
- package/dist/service.d.ts +116 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +550 -0
- package/dist/status.d.ts +30 -0
- package/dist/status.d.ts.map +1 -0
- package/dist/status.js +79 -0
- package/dist/tokens.d.ts +7 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +4 -0
- package/dist/transports/event-handler-logger.d.ts +3 -0
- package/dist/transports/event-handler-logger.d.ts.map +1 -0
- package/dist/transports/event-handler-logger.js +3 -0
- package/dist/transports/grpc-transport.d.ts +193 -0
- package/dist/transports/grpc-transport.d.ts.map +1 -0
- package/dist/transports/grpc-transport.js +1035 -0
- package/dist/transports/kafka-transport.d.ts +77 -0
- package/dist/transports/kafka-transport.d.ts.map +1 -0
- package/dist/transports/kafka-transport.js +289 -0
- package/dist/transports/mqtt-transport.d.ts +124 -0
- package/dist/transports/mqtt-transport.d.ts.map +1 -0
- package/dist/transports/mqtt-transport.js +460 -0
- package/dist/transports/nats-transport.d.ts +92 -0
- package/dist/transports/nats-transport.d.ts.map +1 -0
- package/dist/transports/nats-transport.js +218 -0
- package/dist/transports/rabbitmq-transport.d.ts +77 -0
- package/dist/transports/rabbitmq-transport.d.ts.map +1 -0
- package/dist/transports/rabbitmq-transport.js +263 -0
- package/dist/transports/redis-streams-transport.d.ts +136 -0
- package/dist/transports/redis-streams-transport.d.ts.map +1 -0
- package/dist/transports/redis-streams-transport.js +482 -0
- package/dist/transports/redis-transport.d.ts +73 -0
- package/dist/transports/redis-transport.d.ts.map +1 -0
- package/dist/transports/redis-transport.js +152 -0
- package/dist/transports/tcp-transport.d.ts +66 -0
- package/dist/transports/tcp-transport.d.ts.map +1 -0
- package/dist/transports/tcp-transport.js +283 -0
- package/dist/types.d.ts +105 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +105 -0
package/dist/service.js
ADDED
|
@@ -0,0 +1,550 @@
|
|
|
1
|
+
let _initClass;
|
|
2
|
+
function _applyDecs(e, t, n, r, o, i) { var a, c, u, s, f, l, p, d = Symbol.metadata || Symbol.for("Symbol.metadata"), m = Object.defineProperty, h = Object.create, y = [h(null), h(null)], v = t.length; function g(t, n, r) { return function (o, i) { n && (i = o, o = e); for (var a = 0; a < t.length; a++) i = t[a].apply(o, r ? [i] : []); return r ? i : o; }; } function b(e, t, n, r) { if ("function" != typeof e && (r || void 0 !== e)) throw new TypeError(t + " must " + (n || "be") + " a function" + (r ? "" : " or undefined")); return e; } function applyDec(e, t, n, r, o, i, u, s, f, l, p) { function d(e) { if (!p(e)) throw new TypeError("Attempted to access private element on non-instance"); } var h = [].concat(t[0]), v = t[3], w = !u, D = 1 === o, S = 3 === o, j = 4 === o, E = 2 === o; function I(t, n, r) { return function (o, i) { return n && (i = o, o = e), r && r(o), P[t].call(o, i); }; } if (!w) { var P = {}, k = [], F = S ? "get" : j || D ? "set" : "value"; if (f ? (l || D ? P = { get: _setFunctionName(function () { return v(this); }, r, "get"), set: function (e) { t[4](this, e); } } : P[F] = v, l || _setFunctionName(P[F], r, E ? "" : F)) : l || (P = Object.getOwnPropertyDescriptor(e, r)), !l && !f) { if ((c = y[+s][r]) && 7 !== (c ^ o)) throw Error("Decorating two elements with the same name (" + P[F].name + ") is not supported yet"); y[+s][r] = o < 3 ? 1 : o; } } for (var N = e, O = h.length - 1; O >= 0; O -= n ? 2 : 1) { var T = b(h[O], "A decorator", "be", !0), z = n ? h[O - 1] : void 0, A = {}, H = { kind: ["field", "accessor", "method", "getter", "setter", "class"][o], name: r, metadata: a, addInitializer: function (e, t) { if (e.v) throw new TypeError("attempted to call addInitializer after decoration was finished"); b(t, "An initializer", "be", !0), i.push(t); }.bind(null, A) }; if (w) c = T.call(z, N, H), A.v = 1, b(c, "class decorators", "return") && (N = c);else if (H.static = s, H.private = f, c = H.access = { has: f ? p.bind() : function (e) { return r in e; } }, j || (c.get = f ? E ? function (e) { return d(e), P.value; } : I("get", 0, d) : function (e) { return e[r]; }), E || S || (c.set = f ? I("set", 0, d) : function (e, t) { e[r] = t; }), N = T.call(z, D ? { get: P.get, set: P.set } : P[F], H), A.v = 1, D) { if ("object" == typeof N && N) (c = b(N.get, "accessor.get")) && (P.get = c), (c = b(N.set, "accessor.set")) && (P.set = c), (c = b(N.init, "accessor.init")) && k.unshift(c);else if (void 0 !== N) throw new TypeError("accessor decorators must return an object with get, set, or init properties or undefined"); } else b(N, (l ? "field" : "method") + " decorators", "return") && (l ? k.unshift(N) : P[F] = N); } return o < 2 && u.push(g(k, s, 1), g(i, s, 0)), l || w || (f ? D ? u.splice(-1, 0, I("get", s), I("set", s)) : u.push(E ? P[F] : b.call.bind(P[F])) : m(e, r, P)), N; } function w(e) { return m(e, d, { configurable: !0, enumerable: !0, value: a }); } return void 0 !== i && (a = i[d]), a = h(null == a ? null : a), f = [], l = function (e) { e && f.push(g(e)); }, p = function (t, r) { for (var i = 0; i < n.length; i++) { var a = n[i], c = a[1], l = 7 & c; if ((8 & c) == t && !l == r) { var p = a[2], d = !!a[3], m = 16 & c; applyDec(t ? e : e.prototype, a, m, d ? "#" + p : _toPropertyKey(p), l, l < 2 ? [] : t ? s = s || [] : u = u || [], f, !!t, d, r, t && d ? function (t) { return _checkInRHS(t) === e; } : o); } } }, p(8, 0), p(0, 0), p(8, 1), p(0, 1), l(u), l(s), c = f, v || w(e), { e: c, get c() { var n = []; return v && [w(e = applyDec(e, [t], r, e.name, 5, n)), g(n, 1)]; } }; }
|
|
3
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
4
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
5
|
+
function _setFunctionName(e, t, n) { "symbol" == typeof t && (t = (t = t.description) ? "[" + t + "]" : ""); try { Object.defineProperty(e, "name", { configurable: !0, value: n ? n + " " + t : t }); } catch (e) {} return e; }
|
|
6
|
+
function _checkInRHS(e) { if (Object(e) !== e) throw TypeError("right-hand side of 'in' should be an object, got " + (null !== e ? typeof e : "null")); return e; }
|
|
7
|
+
import { Inject } from '@fluojs/core';
|
|
8
|
+
import { cloneWithFallback, getClassDiMetadata } from '@fluojs/core/internal';
|
|
9
|
+
import { APPLICATION_LOGGER, COMPILED_MODULES, RUNTIME_CONTAINER } from '@fluojs/runtime/internal';
|
|
10
|
+
import { getHandlerMetadataEntries } from './metadata.js';
|
|
11
|
+
import { createMicroservicePlatformStatusSnapshot } from './status.js';
|
|
12
|
+
import { MICROSERVICE_OPTIONS } from './tokens.js';
|
|
13
|
+
function methodKeyToName(methodKey) {
|
|
14
|
+
return typeof methodKey === 'symbol' ? methodKey.toString() : methodKey;
|
|
15
|
+
}
|
|
16
|
+
function scopeFromProvider(provider) {
|
|
17
|
+
if (typeof provider === 'function') {
|
|
18
|
+
return getClassDiMetadata(provider)?.scope ?? 'singleton';
|
|
19
|
+
}
|
|
20
|
+
if ('useClass' in provider) {
|
|
21
|
+
return provider.scope ?? getClassDiMetadata(provider.useClass)?.scope ?? 'singleton';
|
|
22
|
+
}
|
|
23
|
+
return 'scope' in provider ? provider.scope ?? 'singleton' : 'singleton';
|
|
24
|
+
}
|
|
25
|
+
function isClassProvider(provider) {
|
|
26
|
+
return typeof provider === 'object' && provider !== null && 'useClass' in provider;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Lifecycle-managed microservice runtime that discovers pattern handlers and binds them to a transport.
|
|
31
|
+
*
|
|
32
|
+
* The service resolves singleton or request-scoped handlers, exposes programmatic
|
|
33
|
+
* send/emit/stream APIs, and delegates transport-specific I/O to the configured adapter.
|
|
34
|
+
*/
|
|
35
|
+
let _MicroserviceLifecycl;
|
|
36
|
+
class MicroserviceLifecycleService {
|
|
37
|
+
static {
|
|
38
|
+
[_MicroserviceLifecycl, _initClass] = _applyDecs(this, [Inject(RUNTIME_CONTAINER, COMPILED_MODULES, APPLICATION_LOGGER, MICROSERVICE_OPTIONS)], []).c;
|
|
39
|
+
}
|
|
40
|
+
descriptors = [];
|
|
41
|
+
handlerInstances = new Map();
|
|
42
|
+
lifecycleState = 'created';
|
|
43
|
+
lastListenError;
|
|
44
|
+
listening = false;
|
|
45
|
+
listenPromise;
|
|
46
|
+
constructor(runtimeContainer, compiledModules, logger, moduleOptions) {
|
|
47
|
+
this.runtimeContainer = runtimeContainer;
|
|
48
|
+
this.compiledModules = compiledModules;
|
|
49
|
+
this.logger = logger;
|
|
50
|
+
this.moduleOptions = moduleOptions;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Starts transport listeners and discovers decorated handlers.
|
|
55
|
+
*
|
|
56
|
+
* @returns A promise that resolves once the configured transport is ready to accept traffic.
|
|
57
|
+
*/
|
|
58
|
+
async listen() {
|
|
59
|
+
if (this.listening) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (this.listenPromise) {
|
|
63
|
+
await this.listenPromise;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.listenPromise = (async () => {
|
|
67
|
+
this.lifecycleState = 'starting';
|
|
68
|
+
this.lastListenError = undefined;
|
|
69
|
+
this.descriptors.length = 0;
|
|
70
|
+
this.descriptors.push(...this.discoverHandlerDescriptors());
|
|
71
|
+
const transport = this.moduleOptions.transport;
|
|
72
|
+
transport.setLogger?.(this.logger);
|
|
73
|
+
if (transport.listenServerStreaming) {
|
|
74
|
+
transport.listenServerStreaming(async (pattern, payload, writer) => {
|
|
75
|
+
await this.dispatchServerStream(pattern, cloneWithFallback(payload), writer);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
if (transport.listenClientStreaming) {
|
|
79
|
+
transport.listenClientStreaming(async (pattern, reader) => {
|
|
80
|
+
return await this.dispatchClientStream(pattern, reader);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
if (transport.listenBidiStreaming) {
|
|
84
|
+
transport.listenBidiStreaming(async (pattern, reader, writer) => {
|
|
85
|
+
await this.dispatchBidiStream(pattern, reader, writer);
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
await transport.listen(async packet => this.dispatchPacket(packet));
|
|
89
|
+
this.listening = true;
|
|
90
|
+
this.lifecycleState = 'ready';
|
|
91
|
+
})();
|
|
92
|
+
try {
|
|
93
|
+
await this.listenPromise;
|
|
94
|
+
} catch (error) {
|
|
95
|
+
this.lifecycleState = 'failed';
|
|
96
|
+
this.lastListenError = error instanceof Error ? error.message : String(error);
|
|
97
|
+
throw error;
|
|
98
|
+
} finally {
|
|
99
|
+
this.listenPromise = undefined;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Closes the configured transport and stops accepting microservice traffic.
|
|
105
|
+
*
|
|
106
|
+
* @returns A promise that resolves once shutdown completes.
|
|
107
|
+
*/
|
|
108
|
+
async close() {
|
|
109
|
+
if (this.listenPromise) {
|
|
110
|
+
await this.listenPromise;
|
|
111
|
+
}
|
|
112
|
+
this.lifecycleState = 'stopping';
|
|
113
|
+
try {
|
|
114
|
+
await this.moduleOptions.transport.close();
|
|
115
|
+
this.listening = false;
|
|
116
|
+
this.lifecycleState = 'stopped';
|
|
117
|
+
} catch (error) {
|
|
118
|
+
this.lifecycleState = 'failed';
|
|
119
|
+
this.lastListenError = error instanceof Error ? error.message : String(error);
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async onApplicationShutdown() {
|
|
124
|
+
await this.close();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Creates a platform status snapshot for health checks and diagnostics.
|
|
129
|
+
*
|
|
130
|
+
* @returns A structured snapshot describing handler counts, transport capabilities, and lifecycle state.
|
|
131
|
+
*/
|
|
132
|
+
createPlatformStatusSnapshot() {
|
|
133
|
+
return createMicroservicePlatformStatusSnapshot({
|
|
134
|
+
handlerCounts: {
|
|
135
|
+
'bidi-stream': this.descriptors.filter(descriptor => descriptor.kind === 'bidi-stream').length,
|
|
136
|
+
'client-stream': this.descriptors.filter(descriptor => descriptor.kind === 'client-stream').length,
|
|
137
|
+
event: this.descriptors.filter(descriptor => descriptor.kind === 'event').length,
|
|
138
|
+
message: this.descriptors.filter(descriptor => descriptor.kind === 'message').length,
|
|
139
|
+
'server-stream': this.descriptors.filter(descriptor => descriptor.kind === 'server-stream').length
|
|
140
|
+
},
|
|
141
|
+
lastListenError: this.lastListenError,
|
|
142
|
+
lifecycleState: this.lifecycleState,
|
|
143
|
+
transportCapabilities: {
|
|
144
|
+
bidiStream: typeof this.moduleOptions.transport.bidiStream === 'function',
|
|
145
|
+
clientStream: typeof this.moduleOptions.transport.clientStream === 'function',
|
|
146
|
+
emit: typeof this.moduleOptions.transport.emit === 'function',
|
|
147
|
+
send: typeof this.moduleOptions.transport.send === 'function',
|
|
148
|
+
serverStream: typeof this.moduleOptions.transport.serverStream === 'function'
|
|
149
|
+
}
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Sends one request-response message through the configured transport.
|
|
155
|
+
*
|
|
156
|
+
* @param pattern Pattern identifying the remote handler.
|
|
157
|
+
* @param payload Serializable payload forwarded to the transport.
|
|
158
|
+
* @param signal Optional abort signal passed to the transport.
|
|
159
|
+
* @returns The transport response payload.
|
|
160
|
+
*/
|
|
161
|
+
async send(pattern, payload, signal) {
|
|
162
|
+
return this.moduleOptions.transport.send(pattern, cloneWithFallback(payload), signal);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/**
|
|
166
|
+
* Emits one fire-and-forget event through the configured transport.
|
|
167
|
+
*
|
|
168
|
+
* @param pattern Pattern identifying the remote event channel.
|
|
169
|
+
* @param payload Serializable payload forwarded to the transport.
|
|
170
|
+
* @returns A promise that resolves once the transport accepts the event.
|
|
171
|
+
*/
|
|
172
|
+
async emit(pattern, payload) {
|
|
173
|
+
await this.moduleOptions.transport.emit(pattern, cloneWithFallback(payload));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Opens a server-streaming request through the configured transport.
|
|
178
|
+
*
|
|
179
|
+
* @param pattern Pattern identifying the remote server-stream handler.
|
|
180
|
+
* @param payload Serializable request payload forwarded to the transport.
|
|
181
|
+
* @param signal Optional abort signal passed to the transport.
|
|
182
|
+
* @returns An async iterable of stream messages.
|
|
183
|
+
*
|
|
184
|
+
* @throws {Error} When the configured transport does not implement `serverStream()`.
|
|
185
|
+
*/
|
|
186
|
+
serverStream(pattern, payload, signal) {
|
|
187
|
+
const transport = this.moduleOptions.transport;
|
|
188
|
+
if (!transport.serverStream) {
|
|
189
|
+
throw new Error('The configured transport does not support server streaming. Use a transport that implements serverStream().');
|
|
190
|
+
}
|
|
191
|
+
return transport.serverStream(pattern, cloneWithFallback(payload), signal);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/**
|
|
195
|
+
* Opens a client-streaming request through the configured transport.
|
|
196
|
+
*
|
|
197
|
+
* @param pattern Pattern identifying the remote client-stream handler.
|
|
198
|
+
* @param signal Optional abort signal passed to the transport.
|
|
199
|
+
* @returns A writer for request chunks plus a promise for the final response.
|
|
200
|
+
*
|
|
201
|
+
* @throws {Error} When the configured transport does not implement `clientStream()`.
|
|
202
|
+
*/
|
|
203
|
+
clientStream(pattern, signal) {
|
|
204
|
+
const transport = this.moduleOptions.transport;
|
|
205
|
+
if (!transport.clientStream) {
|
|
206
|
+
throw new Error('The configured transport does not support client streaming. Use a transport that implements clientStream().');
|
|
207
|
+
}
|
|
208
|
+
return transport.clientStream(pattern, signal);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Opens a bidirectional stream through the configured transport.
|
|
213
|
+
*
|
|
214
|
+
* @param pattern Pattern identifying the remote bidi-stream handler.
|
|
215
|
+
* @param signal Optional abort signal passed to the transport.
|
|
216
|
+
* @returns A reader for response chunks and a writer for outbound chunks.
|
|
217
|
+
*
|
|
218
|
+
* @throws {Error} When the configured transport does not implement `bidiStream()`.
|
|
219
|
+
*/
|
|
220
|
+
bidiStream(pattern, signal) {
|
|
221
|
+
const transport = this.moduleOptions.transport;
|
|
222
|
+
if (!transport.bidiStream) {
|
|
223
|
+
throw new Error('The configured transport does not support bidirectional streaming. Use a transport that implements bidiStream().');
|
|
224
|
+
}
|
|
225
|
+
return transport.bidiStream(pattern, signal);
|
|
226
|
+
}
|
|
227
|
+
async dispatchPacket(packet) {
|
|
228
|
+
const matches = this.descriptors.filter(descriptor => descriptor.kind === packet.kind && this.matchesPattern(descriptor.pattern, packet.pattern));
|
|
229
|
+
if (packet.kind === 'message') {
|
|
230
|
+
if (matches.length > 1) {
|
|
231
|
+
throw new Error(`Multiple message handlers matched pattern "${packet.pattern}": ${matches.map(descriptor => `${descriptor.targetName}.${descriptor.methodName}`).join(', ')}.`);
|
|
232
|
+
}
|
|
233
|
+
const first = matches[0];
|
|
234
|
+
if (!first) {
|
|
235
|
+
throw new Error(`No message handler registered for pattern "${packet.pattern}".`);
|
|
236
|
+
}
|
|
237
|
+
return await this.invokeHandler(first, cloneWithFallback(packet.payload));
|
|
238
|
+
}
|
|
239
|
+
return await this.dispatchEventHandlers(matches, cloneWithFallback(packet.payload));
|
|
240
|
+
}
|
|
241
|
+
async dispatchServerStream(pattern, payload, writer) {
|
|
242
|
+
const matches = this.descriptors.filter(descriptor => descriptor.kind === 'server-stream' && this.matchesPattern(descriptor.pattern, pattern));
|
|
243
|
+
if (matches.length > 1) {
|
|
244
|
+
const errorMsg = `Multiple server-stream handlers matched pattern "${pattern}": ${matches.map(descriptor => `${descriptor.targetName}.${descriptor.methodName}`).join(', ')}.`;
|
|
245
|
+
writer.error(new Error(errorMsg));
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
const first = matches[0];
|
|
249
|
+
if (!first) {
|
|
250
|
+
writer.error(new Error(`No server-stream handler registered for pattern "${pattern}".`));
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
await this.invokeServerStreamHandler(first, payload, writer);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
this.logger.error(`Server-stream handler ${first.targetName}.${first.methodName} failed.`, error, 'MicroserviceLifecycleService');
|
|
257
|
+
writer.error(error instanceof Error ? error : new Error('Server-stream handler failed.'));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async invokeServerStreamHandler(descriptor, payload, writer) {
|
|
261
|
+
if (descriptor.scope === 'singleton') {
|
|
262
|
+
return await this.invokeResolvedServerStreamHandler(await this.resolveSingletonHandlerInstance(descriptor), descriptor, payload, writer);
|
|
263
|
+
}
|
|
264
|
+
const streamScope = this.runtimeContainer.createRequestScope();
|
|
265
|
+
try {
|
|
266
|
+
const instance = await streamScope.resolve(descriptor.token);
|
|
267
|
+
await this.invokeResolvedServerStreamHandler(instance, descriptor, payload, writer);
|
|
268
|
+
} finally {
|
|
269
|
+
try {
|
|
270
|
+
await streamScope.dispose();
|
|
271
|
+
} catch (error) {
|
|
272
|
+
this.logger.error(`Failed to dispose microservice server-stream scope for ${descriptor.targetName}.${descriptor.methodName}.`, error, 'MicroserviceLifecycleService');
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
async invokeResolvedServerStreamHandler(instance, descriptor, payload, writer) {
|
|
277
|
+
if (!instance) {
|
|
278
|
+
throw new Error(`Failed to resolve microservice target ${descriptor.targetName} from module ${descriptor.moduleName}.`);
|
|
279
|
+
}
|
|
280
|
+
const value = instance[descriptor.methodKey];
|
|
281
|
+
if (typeof value !== 'function') {
|
|
282
|
+
throw new Error(`Microservice handler ${descriptor.targetName}.${descriptor.methodName} must be a callable function.`);
|
|
283
|
+
}
|
|
284
|
+
await Promise.resolve(value.call(instance, payload, writer));
|
|
285
|
+
}
|
|
286
|
+
async dispatchClientStream(pattern, reader) {
|
|
287
|
+
const matches = this.descriptors.filter(descriptor => descriptor.kind === 'client-stream' && this.matchesPattern(descriptor.pattern, pattern));
|
|
288
|
+
if (matches.length > 1) {
|
|
289
|
+
throw new Error(`Multiple client-stream handlers matched pattern "${pattern}": ${matches.map(descriptor => `${descriptor.targetName}.${descriptor.methodName}`).join(', ')}.`);
|
|
290
|
+
}
|
|
291
|
+
const first = matches[0];
|
|
292
|
+
if (!first) {
|
|
293
|
+
throw new Error(`No client-stream handler registered for pattern "${pattern}".`);
|
|
294
|
+
}
|
|
295
|
+
try {
|
|
296
|
+
return await this.invokeClientStreamHandler(first, reader);
|
|
297
|
+
} catch (error) {
|
|
298
|
+
this.logger.error(`Client-stream handler ${first.targetName}.${first.methodName} failed.`, error, 'MicroserviceLifecycleService');
|
|
299
|
+
throw error;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
async invokeClientStreamHandler(descriptor, reader) {
|
|
303
|
+
if (descriptor.scope === 'singleton') {
|
|
304
|
+
return await this.invokeResolvedClientStreamHandler(await this.resolveSingletonHandlerInstance(descriptor), descriptor, reader);
|
|
305
|
+
}
|
|
306
|
+
const streamScope = this.runtimeContainer.createRequestScope();
|
|
307
|
+
try {
|
|
308
|
+
const instance = await streamScope.resolve(descriptor.token);
|
|
309
|
+
return await this.invokeResolvedClientStreamHandler(instance, descriptor, reader);
|
|
310
|
+
} finally {
|
|
311
|
+
try {
|
|
312
|
+
await streamScope.dispose();
|
|
313
|
+
} catch (error) {
|
|
314
|
+
this.logger.error(`Failed to dispose microservice client-stream scope for ${descriptor.targetName}.${descriptor.methodName}.`, error, 'MicroserviceLifecycleService');
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
async invokeResolvedClientStreamHandler(instance, descriptor, reader) {
|
|
319
|
+
if (!instance) {
|
|
320
|
+
throw new Error(`Failed to resolve microservice target ${descriptor.targetName} from module ${descriptor.moduleName}.`);
|
|
321
|
+
}
|
|
322
|
+
const value = instance[descriptor.methodKey];
|
|
323
|
+
if (typeof value !== 'function') {
|
|
324
|
+
throw new Error(`Microservice handler ${descriptor.targetName}.${descriptor.methodName} must be a callable function.`);
|
|
325
|
+
}
|
|
326
|
+
return await Promise.resolve(value.call(instance, reader));
|
|
327
|
+
}
|
|
328
|
+
async dispatchBidiStream(pattern, reader, writer) {
|
|
329
|
+
const matches = this.descriptors.filter(descriptor => descriptor.kind === 'bidi-stream' && this.matchesPattern(descriptor.pattern, pattern));
|
|
330
|
+
if (matches.length > 1) {
|
|
331
|
+
const errorMsg = `Multiple bidi-stream handlers matched pattern "${pattern}": ${matches.map(descriptor => `${descriptor.targetName}.${descriptor.methodName}`).join(', ')}.`;
|
|
332
|
+
writer.error(new Error(errorMsg));
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
const first = matches[0];
|
|
336
|
+
if (!first) {
|
|
337
|
+
writer.error(new Error(`No bidi-stream handler registered for pattern "${pattern}".`));
|
|
338
|
+
return;
|
|
339
|
+
}
|
|
340
|
+
try {
|
|
341
|
+
await this.invokeBidiStreamHandler(first, reader, writer);
|
|
342
|
+
} catch (error) {
|
|
343
|
+
this.logger.error(`Bidi-stream handler ${first.targetName}.${first.methodName} failed.`, error, 'MicroserviceLifecycleService');
|
|
344
|
+
writer.error(error instanceof Error ? error : new Error('Bidi-stream handler failed.'));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
async invokeBidiStreamHandler(descriptor, reader, writer) {
|
|
348
|
+
if (descriptor.scope === 'singleton') {
|
|
349
|
+
return await this.invokeResolvedBidiStreamHandler(await this.resolveSingletonHandlerInstance(descriptor), descriptor, reader, writer);
|
|
350
|
+
}
|
|
351
|
+
const streamScope = this.runtimeContainer.createRequestScope();
|
|
352
|
+
try {
|
|
353
|
+
const instance = await streamScope.resolve(descriptor.token);
|
|
354
|
+
await this.invokeResolvedBidiStreamHandler(instance, descriptor, reader, writer);
|
|
355
|
+
} finally {
|
|
356
|
+
try {
|
|
357
|
+
await streamScope.dispose();
|
|
358
|
+
} catch (error) {
|
|
359
|
+
this.logger.error(`Failed to dispose microservice bidi-stream scope for ${descriptor.targetName}.${descriptor.methodName}.`, error, 'MicroserviceLifecycleService');
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
async invokeResolvedBidiStreamHandler(instance, descriptor, reader, writer) {
|
|
364
|
+
if (!instance) {
|
|
365
|
+
throw new Error(`Failed to resolve microservice target ${descriptor.targetName} from module ${descriptor.moduleName}.`);
|
|
366
|
+
}
|
|
367
|
+
const value = instance[descriptor.methodKey];
|
|
368
|
+
if (typeof value !== 'function') {
|
|
369
|
+
throw new Error(`Microservice handler ${descriptor.targetName}.${descriptor.methodName} must be a callable function.`);
|
|
370
|
+
}
|
|
371
|
+
await Promise.resolve(value.call(instance, reader, writer));
|
|
372
|
+
}
|
|
373
|
+
async dispatchEventHandlers(descriptors, payload) {
|
|
374
|
+
const singletonDescriptors = descriptors.filter(descriptor => descriptor.scope === 'singleton');
|
|
375
|
+
const scopedDescriptors = descriptors.filter(descriptor => descriptor.scope !== 'singleton');
|
|
376
|
+
const singletonResults = await Promise.allSettled(singletonDescriptors.map(descriptor => this.invokeHandler(descriptor, cloneWithFallback(payload))));
|
|
377
|
+
for (const result of singletonResults) {
|
|
378
|
+
if (result.status === 'rejected') {
|
|
379
|
+
this.logger.error('Event handler failed during singleton dispatch.', result.reason, 'MicroserviceLifecycleService');
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
if (scopedDescriptors.length === 0) {
|
|
383
|
+
return undefined;
|
|
384
|
+
}
|
|
385
|
+
const perEventScope = this.runtimeContainer.createRequestScope();
|
|
386
|
+
const scopeErrors = [];
|
|
387
|
+
try {
|
|
388
|
+
const scopedResults = await Promise.allSettled(scopedDescriptors.map(descriptor => this.invokeResolvedHandlerInScope(perEventScope, descriptor, cloneWithFallback(payload))));
|
|
389
|
+
for (const result of scopedResults) {
|
|
390
|
+
if (result.status === 'rejected') {
|
|
391
|
+
scopeErrors.push(result.reason instanceof Error ? result.reason : new Error(String(result.reason)));
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
} finally {
|
|
395
|
+
try {
|
|
396
|
+
await perEventScope.dispose();
|
|
397
|
+
} catch (disposeError) {
|
|
398
|
+
this.logger.error('Failed to dispose per-event scope.', disposeError, 'MicroserviceLifecycleService');
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
if (scopeErrors.length > 0) {
|
|
402
|
+
for (const error of scopeErrors) {
|
|
403
|
+
this.logger.error('Scoped event handler failed.', error, 'MicroserviceLifecycleService');
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
return undefined;
|
|
407
|
+
}
|
|
408
|
+
async invokeResolvedHandlerInScope(scope, descriptor, payload) {
|
|
409
|
+
const instance = await scope.resolve(descriptor.token);
|
|
410
|
+
return await this.invokeResolvedHandler(instance, descriptor, payload);
|
|
411
|
+
}
|
|
412
|
+
matchesPattern(pattern, input) {
|
|
413
|
+
if (pattern instanceof RegExp) {
|
|
414
|
+
pattern.lastIndex = 0;
|
|
415
|
+
return pattern.test(input);
|
|
416
|
+
}
|
|
417
|
+
return pattern === input;
|
|
418
|
+
}
|
|
419
|
+
discoverHandlerDescriptors() {
|
|
420
|
+
const seen = new WeakMap();
|
|
421
|
+
const descriptors = [];
|
|
422
|
+
for (const candidate of this.discoveryCandidates()) {
|
|
423
|
+
const entries = getHandlerMetadataEntries(candidate.targetType.prototype);
|
|
424
|
+
for (const entry of entries) {
|
|
425
|
+
const dedupeKey = this.dedupeKey(entry.metadata.kind, entry.metadata.pattern);
|
|
426
|
+
if (this.isDuplicate(seen, candidate.targetType, entry.propertyKey, dedupeKey)) {
|
|
427
|
+
this.logger.warn(`Duplicate microservice handler registration for ${dedupeKey} on ${candidate.targetType.name}.${methodKeyToName(entry.propertyKey)} was ignored.`, 'MicroserviceLifecycleService');
|
|
428
|
+
continue;
|
|
429
|
+
}
|
|
430
|
+
descriptors.push({
|
|
431
|
+
kind: entry.metadata.kind,
|
|
432
|
+
methodKey: entry.propertyKey,
|
|
433
|
+
methodName: methodKeyToName(entry.propertyKey),
|
|
434
|
+
moduleName: candidate.moduleName,
|
|
435
|
+
pattern: entry.metadata.pattern,
|
|
436
|
+
scope: candidate.scope,
|
|
437
|
+
targetName: candidate.targetType.name,
|
|
438
|
+
token: candidate.token
|
|
439
|
+
});
|
|
440
|
+
}
|
|
441
|
+
}
|
|
442
|
+
return descriptors;
|
|
443
|
+
}
|
|
444
|
+
dedupeKey(kind, pattern) {
|
|
445
|
+
if (pattern instanceof RegExp) {
|
|
446
|
+
return `${kind}:/${pattern.source}/${pattern.flags}`;
|
|
447
|
+
}
|
|
448
|
+
return `${kind}:${pattern}`;
|
|
449
|
+
}
|
|
450
|
+
isDuplicate(seen, targetType, methodKey, dedupeKey) {
|
|
451
|
+
let methodsByKey = seen.get(targetType);
|
|
452
|
+
if (!methodsByKey) {
|
|
453
|
+
methodsByKey = new Map();
|
|
454
|
+
seen.set(targetType, methodsByKey);
|
|
455
|
+
}
|
|
456
|
+
let seenPatterns = methodsByKey.get(methodKey);
|
|
457
|
+
if (!seenPatterns) {
|
|
458
|
+
seenPatterns = new Set();
|
|
459
|
+
methodsByKey.set(methodKey, seenPatterns);
|
|
460
|
+
}
|
|
461
|
+
if (seenPatterns.has(dedupeKey)) {
|
|
462
|
+
return true;
|
|
463
|
+
}
|
|
464
|
+
seenPatterns.add(dedupeKey);
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
discoveryCandidates() {
|
|
468
|
+
const candidates = [];
|
|
469
|
+
for (const compiledModule of this.compiledModules) {
|
|
470
|
+
for (const provider of compiledModule.definition.providers ?? []) {
|
|
471
|
+
if (typeof provider === 'function') {
|
|
472
|
+
candidates.push({
|
|
473
|
+
moduleName: compiledModule.type.name,
|
|
474
|
+
scope: scopeFromProvider(provider),
|
|
475
|
+
targetType: provider,
|
|
476
|
+
token: provider
|
|
477
|
+
});
|
|
478
|
+
continue;
|
|
479
|
+
}
|
|
480
|
+
if (isClassProvider(provider)) {
|
|
481
|
+
candidates.push({
|
|
482
|
+
moduleName: compiledModule.type.name,
|
|
483
|
+
scope: scopeFromProvider(provider),
|
|
484
|
+
targetType: provider.useClass,
|
|
485
|
+
token: provider.provide
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
for (const controller of compiledModule.definition.controllers ?? []) {
|
|
490
|
+
candidates.push({
|
|
491
|
+
moduleName: compiledModule.type.name,
|
|
492
|
+
scope: scopeFromProvider(controller),
|
|
493
|
+
targetType: controller,
|
|
494
|
+
token: controller
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
return candidates;
|
|
499
|
+
}
|
|
500
|
+
async invokeHandler(descriptor, payload) {
|
|
501
|
+
if (descriptor.scope === 'singleton') {
|
|
502
|
+
return await this.invokeResolvedHandler(await this.resolveSingletonHandlerInstance(descriptor), descriptor, payload);
|
|
503
|
+
}
|
|
504
|
+
const messageScope = this.runtimeContainer.createRequestScope();
|
|
505
|
+
try {
|
|
506
|
+
const instance = await messageScope.resolve(descriptor.token);
|
|
507
|
+
return await this.invokeResolvedHandler(instance, descriptor, payload);
|
|
508
|
+
} finally {
|
|
509
|
+
try {
|
|
510
|
+
await messageScope.dispose();
|
|
511
|
+
} catch (error) {
|
|
512
|
+
this.logger.error(`Failed to dispose microservice request scope for ${descriptor.targetName}.${descriptor.methodName}.`, error, 'MicroserviceLifecycleService');
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
async invokeResolvedHandler(instance, descriptor, payload) {
|
|
517
|
+
if (!instance) {
|
|
518
|
+
throw new Error(`Failed to resolve microservice target ${descriptor.targetName} from module ${descriptor.moduleName}.`);
|
|
519
|
+
}
|
|
520
|
+
const value = instance[descriptor.methodKey];
|
|
521
|
+
if (typeof value !== 'function') {
|
|
522
|
+
throw new Error(`Microservice handler ${descriptor.targetName}.${descriptor.methodName} must be a callable function.`);
|
|
523
|
+
}
|
|
524
|
+
try {
|
|
525
|
+
return await Promise.resolve(value.call(instance, payload));
|
|
526
|
+
} catch (error) {
|
|
527
|
+
this.logger.error(`Microservice handler ${descriptor.targetName}.${descriptor.methodName} failed.`, error, 'MicroserviceLifecycleService');
|
|
528
|
+
throw error;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
async resolveSingletonHandlerInstance(descriptor) {
|
|
532
|
+
const cached = this.handlerInstances.get(descriptor.token);
|
|
533
|
+
if (cached) {
|
|
534
|
+
return await cached;
|
|
535
|
+
}
|
|
536
|
+
const resolving = this.runtimeContainer.resolve(descriptor.token);
|
|
537
|
+
this.handlerInstances.set(descriptor.token, resolving);
|
|
538
|
+
try {
|
|
539
|
+
return await resolving;
|
|
540
|
+
} catch (error) {
|
|
541
|
+
this.handlerInstances.delete(descriptor.token);
|
|
542
|
+
this.logger.error(`Failed to resolve microservice target ${descriptor.targetName} from module ${descriptor.moduleName}.`, error, 'MicroserviceLifecycleService');
|
|
543
|
+
throw error;
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
static {
|
|
547
|
+
_initClass();
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
export { _MicroserviceLifecycl as MicroserviceLifecycleService };
|
package/dist/status.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { PlatformHealthReport, PlatformReadinessReport, PlatformSnapshot } from '@fluojs/runtime';
|
|
2
|
+
export type MicroserviceLifecycleState = 'created' | 'starting' | 'ready' | 'stopping' | 'stopped' | 'failed';
|
|
3
|
+
export interface MicroserviceHandlerCounts {
|
|
4
|
+
'bidi-stream': number;
|
|
5
|
+
'client-stream': number;
|
|
6
|
+
event: number;
|
|
7
|
+
message: number;
|
|
8
|
+
'server-stream': number;
|
|
9
|
+
}
|
|
10
|
+
export interface MicroserviceTransportCapabilities {
|
|
11
|
+
bidiStream: boolean;
|
|
12
|
+
clientStream: boolean;
|
|
13
|
+
emit: boolean;
|
|
14
|
+
send: boolean;
|
|
15
|
+
serverStream: boolean;
|
|
16
|
+
}
|
|
17
|
+
export interface MicroserviceStatusAdapterInput {
|
|
18
|
+
handlerCounts: MicroserviceHandlerCounts;
|
|
19
|
+
lastListenError?: string;
|
|
20
|
+
lifecycleState: MicroserviceLifecycleState;
|
|
21
|
+
transportCapabilities: MicroserviceTransportCapabilities;
|
|
22
|
+
}
|
|
23
|
+
export interface MicroservicePlatformStatusSnapshot {
|
|
24
|
+
readiness: PlatformReadinessReport;
|
|
25
|
+
health: PlatformHealthReport;
|
|
26
|
+
ownership: PlatformSnapshot['ownership'];
|
|
27
|
+
details: Record<string, unknown>;
|
|
28
|
+
}
|
|
29
|
+
export declare function createMicroservicePlatformStatusSnapshot(input: MicroserviceStatusAdapterInput): MicroservicePlatformStatusSnapshot;
|
|
30
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../src/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEvG,MAAM,MAAM,0BAA0B,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE9G,MAAM,WAAW,yBAAyB;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,iCAAiC;IAChD,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,OAAO,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,8BAA8B;IAC7C,aAAa,EAAE,yBAAyB,CAAC;IACzC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,0BAA0B,CAAC;IAC3C,qBAAqB,EAAE,iCAAiC,CAAC;CAC1D;AAED,MAAM,WAAW,kCAAkC;IACjD,SAAS,EAAE,uBAAuB,CAAC;IACnC,MAAM,EAAE,oBAAoB,CAAC;IAC7B,SAAS,EAAE,gBAAgB,CAAC,WAAW,CAAC,CAAC;IACzC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAqED,wBAAgB,wCAAwC,CACtD,KAAK,EAAE,8BAA8B,GACpC,kCAAkC,CAoBpC"}
|
package/dist/status.js
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
function createReadiness(input) {
|
|
2
|
+
if (input.lifecycleState === 'ready') {
|
|
3
|
+
return {
|
|
4
|
+
critical: true,
|
|
5
|
+
status: 'ready'
|
|
6
|
+
};
|
|
7
|
+
}
|
|
8
|
+
if (input.lifecycleState === 'starting') {
|
|
9
|
+
return {
|
|
10
|
+
critical: true,
|
|
11
|
+
reason: 'Microservice transport listener is still starting.',
|
|
12
|
+
status: 'degraded'
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
if (input.lifecycleState === 'failed') {
|
|
16
|
+
return {
|
|
17
|
+
critical: true,
|
|
18
|
+
reason: input.lastListenError ?? 'Microservice transport listener failed to start.',
|
|
19
|
+
status: 'not-ready'
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (input.lifecycleState === 'stopping') {
|
|
23
|
+
return {
|
|
24
|
+
critical: true,
|
|
25
|
+
reason: 'Microservice transport listener is shutting down.',
|
|
26
|
+
status: 'not-ready'
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
if (input.lifecycleState === 'stopped') {
|
|
30
|
+
return {
|
|
31
|
+
critical: true,
|
|
32
|
+
reason: 'Microservice transport listener is stopped.',
|
|
33
|
+
status: 'not-ready'
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
critical: true,
|
|
38
|
+
reason: 'Microservice transport listener has not started yet.',
|
|
39
|
+
status: 'not-ready'
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
function createHealth(input) {
|
|
43
|
+
if (input.lifecycleState === 'failed' || input.lifecycleState === 'stopped') {
|
|
44
|
+
return {
|
|
45
|
+
reason: input.lastListenError ?? 'Microservice transport listener is unavailable.',
|
|
46
|
+
status: 'unhealthy'
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (input.lifecycleState === 'starting' || input.lifecycleState === 'stopping') {
|
|
50
|
+
return {
|
|
51
|
+
reason: 'Microservice transport listener is transitioning lifecycle state.',
|
|
52
|
+
status: 'degraded'
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
status: 'healthy'
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export function createMicroservicePlatformStatusSnapshot(input) {
|
|
60
|
+
return {
|
|
61
|
+
details: {
|
|
62
|
+
dependencies: ['transport.external'],
|
|
63
|
+
handlerCounts: {
|
|
64
|
+
...input.handlerCounts
|
|
65
|
+
},
|
|
66
|
+
lastListenError: input.lastListenError,
|
|
67
|
+
lifecycleState: input.lifecycleState,
|
|
68
|
+
transportCapabilities: {
|
|
69
|
+
...input.transportCapabilities
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
health: createHealth(input),
|
|
73
|
+
ownership: {
|
|
74
|
+
externallyManaged: true,
|
|
75
|
+
ownsResources: false
|
|
76
|
+
},
|
|
77
|
+
readiness: createReadiness(input)
|
|
78
|
+
};
|
|
79
|
+
}
|
package/dist/tokens.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Token } from '@fluojs/core';
|
|
2
|
+
import type { Microservice, MicroserviceModuleOptions } from './types.js';
|
|
3
|
+
/** Compatibility injection token for the programmatic microservice facade. */
|
|
4
|
+
export declare const MICROSERVICE: Token<Microservice>;
|
|
5
|
+
/** Injection token for the configured transport and runtime module options. */
|
|
6
|
+
export declare const MICROSERVICE_OPTIONS: Token<MicroserviceModuleOptions>;
|
|
7
|
+
//# sourceMappingURL=tokens.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,KAAK,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAE1E,8EAA8E;AAC9E,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,YAAY,CAA4C,CAAC;AAC1F,+EAA+E;AAC/E,eAAO,MAAM,oBAAoB,EAAE,KAAK,CAAC,yBAAyB,CAA4C,CAAC"}
|