The TypeScript runtime announces what it serves too, in the same services format (hq ADR 0197)

The per-module containers still run this runtime; their tools and the seats they hold (the store's,
the catalogue's) must be found by the console the same way as the node runtime's. It answers
$SRV.PING, $SRV.INFO and $SRV.STATS with one service per process, one endpoint per tool per subject
and per seat verb served, the metadata as the Go runtime writes it.
This commit is contained in:
jochen
2026-10-03 22:15:48 +02:00
parent 7722668220
commit 66e8be0e31
4 changed files with 247 additions and 4 deletions
+20
View File
@@ -97,6 +97,13 @@ export interface RuntimeBroker extends Broker {
serving(): string[];
/** The module this connection is: what its credential named, and what a bare key serves as. */
readonly module: string;
/** Where a served module's tool is answered right now (ADR 0197: what it serves, it announces). */
servedOn?(module: string, tool: string): { subject: string; queue?: string }[];
/** Answer a subject in a format of its own, not a tool's reply envelope — the NATS services
* protocol's discovery (novox/hq ADR 0197). An undefined answer is no reply. */
raw?(subject: string, answer: (subject: string, data: Uint8Array) => Uint8Array | undefined): () => void;
/** The machine this connection serves on, when its credential names one. */
readonly node?: string;
}
/**
@@ -348,6 +355,19 @@ export async function connectNats(
},
module: self,
node,
servedOn,
raw(subject: string, answer: (subject: string, data: Uint8Array) => Uint8Array | undefined): () => void {
const sub = conn.subscribe(subject);
subs.push(sub);
void (async () => {
for await (const msg of sub) {
const body = answer(msg.subject, msg.data);
if (body) msg.respond(body);
}
})();
return () => sub.unsubscribe();
},
follow,
serving: () => [...issued.keys()],
membership: (module?: string) => issued.get(module ?? self),