Merge pull request 'mesh-tools run: a one-shot entrypoint invocation (ADR 0052 runtime side)' (#5) from feat/run-once-entry into main
This commit was merged in pull request #5.
This commit is contained in:
+30
-1
@@ -1,10 +1,17 @@
|
|||||||
// The runnable entrypoint. Two modes:
|
// The runnable entrypoint. Three modes:
|
||||||
//
|
//
|
||||||
// mesh-tools serve — bind the broker and serve the assigned modules until
|
// mesh-tools serve — bind the broker and serve the assigned modules until
|
||||||
// stopped. A module entrypoint that subscribes to events (on("#"))
|
// stopped. A module entrypoint that subscribes to events (on("#"))
|
||||||
// starts consuming as it is imported, so this also runs consumers.
|
// starts consuming as it is imported, so this also runs consumers.
|
||||||
// mesh-tools emit TYPE [JSON] emit one event onto the mesh and exit — an operable primitive,
|
// mesh-tools emit TYPE [JSON] emit one event onto the mesh and exit — an operable primitive,
|
||||||
// and what an events test uses to put a message on the wire.
|
// and what an events test uses to put a message on the wire.
|
||||||
|
// mesh-tools run ENTRYPOINT run one compiled module entrypoint to completion and exit — the
|
||||||
|
// runtime side of a run-once step (novox/hq ADR 0052). It imports
|
||||||
|
// the given entrypoint, whose top-level code does its work — seed a
|
||||||
|
// store, migrate, health-gate — and awaits it. It does NOT connect
|
||||||
|
// to the broker: a first-boot step runs offline, before the module
|
||||||
|
// has anything to talk to, and the host gates the container that
|
||||||
|
// depends on it on this process exiting 0.
|
||||||
//
|
//
|
||||||
// The broker, in order of preference:
|
// The broker, in order of preference:
|
||||||
// MESH_BROKER_FILE a sealed {url, fingerprint} the mesh delivered (novox/hq ADR 0043) — an
|
// MESH_BROKER_FILE a sealed {url, fingerprint} the mesh delivered (novox/hq ADR 0043) — an
|
||||||
@@ -14,6 +21,7 @@
|
|||||||
// MESH_MODULE / MESH_NODE the identity stamped onto emitted events (ADR 0042)
|
// MESH_MODULE / MESH_NODE the identity stamped onto emitted events (ADR 0042)
|
||||||
|
|
||||||
import { readFileSync } from "node:fs";
|
import { readFileSync } from "node:fs";
|
||||||
|
import { pathToFileURL } from "node:url";
|
||||||
import { connectAmqp } from "./broker-amqp.js";
|
import { connectAmqp } from "./broker-amqp.js";
|
||||||
import type { Credential } from "./broker-amqp.js";
|
import type { Credential } from "./broker-amqp.js";
|
||||||
import { runTools } from "./runtime.js";
|
import { runTools } from "./runtime.js";
|
||||||
@@ -109,8 +117,29 @@ async function invokeOnce(module: string, tool: string, argsJson: string): Promi
|
|||||||
await broker.close();
|
await broker.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run one compiled module entrypoint to completion — the runtime side of a run-once step
|
||||||
|
* (novox/hq ADR 0052). Importing it runs its top-level code and awaits any top-level await, so this
|
||||||
|
* returns only once the step's own code has finished; a step that throws rejects here and the
|
||||||
|
* process exits non-zero, which is how the host knows the step did not complete and must not start
|
||||||
|
* the container it gates. No broker is connected — a first-boot seed or migration runs offline.
|
||||||
|
*/
|
||||||
|
async function runEntry(entrypoint: string): Promise<void> {
|
||||||
|
if (!entrypoint) {
|
||||||
|
console.error("mesh-tools run <entrypoint> — a compiled module entrypoint path is required");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
// A file URL, not a bare path: dynamic import of an absolute path is not portable, and the
|
||||||
|
// entrypoint the manifest names is an absolute path inside the image.
|
||||||
|
await import(pathToFileURL(entrypoint).href);
|
||||||
|
}
|
||||||
|
|
||||||
async function main(): Promise<void> {
|
async function main(): Promise<void> {
|
||||||
const [command, ...rest] = process.argv.slice(2);
|
const [command, ...rest] = process.argv.slice(2);
|
||||||
|
if (command === "run") {
|
||||||
|
await runEntry(rest[0] ?? "");
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (command === "invoke") {
|
if (command === "invoke") {
|
||||||
const [module, tool] = rest;
|
const [module, tool] = rest;
|
||||||
if (!module || !tool) {
|
if (!module || !tool) {
|
||||||
|
|||||||
Reference in New Issue
Block a user