Write showcase's tools and provisioner against the SDK's registerModuleTools and runProvisioner, so it type-checks (issue 894)
mesh/merge-gate head afd002a9004a merged into trunk 1a2c917abfdb — fail: builds adwaita, asus-zephyrus-g14, build-agent, ca-trust, clipmenu, docker, dunst,…
mesh/repo-check head afd002a9004a merged into trunk 1a2c917abfdb — pass: [release feat/57-config-and-provisioning, judged by its controller 6a6628a76961] T…
mesh/delivery superseded: a newer head of the same pull request
mesh/merge-gate head afd002a9004a merged into trunk 1a2c917abfdb — fail: builds adwaita, asus-zephyrus-g14, build-agent, ca-trust, clipmenu, docker, dunst,…
mesh/repo-check head afd002a9004a merged into trunk 1a2c917abfdb — pass: [release feat/57-config-and-provisioning, judged by its controller 6a6628a76961] T…
mesh/delivery superseded: a newer head of the same pull request
This commit is contained in:
@@ -1,20 +1,19 @@
|
|||||||
// showcase's provisioner — how a consumer is given an instance of what this module provides.
|
// showcase's provisioner — how a consumer is given an instance of what this module provides.
|
||||||
//
|
//
|
||||||
// **A provider ships the provisioner that creates instances of the resource it offers** (ADR
|
// **A provider ships the provisioner that creates instances of the resource it offers** (ADR
|
||||||
// 0040). The mesh asks; this adapts that request to whatever the software actually needs, and
|
// 0040). The mesh asks; this adapts that request to whatever the software actually needs. The
|
||||||
// hands back what the consumer is given.
|
// reconcile loop is the sdk's (`runProvisioner`); this writes only the per-service half.
|
||||||
import { provisioner } from "@novox/mesh-sdk/provisioner";
|
import { runProvisioner, type Provision } from "@novox/mesh-sdk/provisioner";
|
||||||
|
|
||||||
await provisioner({
|
runProvisioner("greeting", {
|
||||||
provision: "greeting",
|
async create(p: Provision): Promise<void> {
|
||||||
async create({ consumer }: { consumer: string }) {
|
|
||||||
// A real provider would create something here — a database, a vhost, an account. This one has
|
// A real provider would create something here — a database, a vhost, an account. This one has
|
||||||
// nothing to create, so it returns what a consumer is told, which is the half that matters:
|
// nothing to create: what a consumer is told is the manifest's `serves` block, which the mesh
|
||||||
// the mesh seals it and delivers it, and the consumer never sees this code.
|
// fills for this consumer, seals and delivers (ADR 0048), so the consumer never sees this code.
|
||||||
return { serves: { greeting: `hello ${consumer}` } };
|
console.log(`[showcase] greeting ready for ${p.consumer ?? p.as}`);
|
||||||
},
|
},
|
||||||
async remove() {
|
async remove(): Promise<void> {
|
||||||
// Removal is not optional. A provider that cannot take an instance back leaves the mesh unable
|
// Removal is not optional. A provider that cannot take an instance back leaves the mesh unable
|
||||||
// to unassign a consumer without leaking whatever it was given.
|
// to unassign a consumer without leaking whatever it was given. Nothing was made, so nothing goes.
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,25 +1,31 @@
|
|||||||
// showcase's tools — its operator-facing surface, served over the broker.
|
// showcase's tools — its operator-facing surface, served over the broker.
|
||||||
//
|
//
|
||||||
// Two of them, because one tool proves a tool can exist and two prove a module can have a surface.
|
// Two of them, because one tool proves a tool can exist and two prove a module can have a surface.
|
||||||
import { tool } from "@novox/mesh-sdk/tools";
|
import { registerModuleTools, type ToolDefinition } from "@novox/mesh-sdk/tools";
|
||||||
|
|
||||||
tool({
|
export function getShowcaseTools(env: NodeJS.ProcessEnv = process.env): ToolDefinition[] {
|
||||||
name: "showcase_greet",
|
return [
|
||||||
description: "Greet somebody, and say which machine did it.",
|
{
|
||||||
input: { type: "object", properties: { who: { type: "string" } } },
|
name: "showcase_greet",
|
||||||
async run({ who }: { who?: string }) {
|
description: "Greet somebody, and say which machine did it.",
|
||||||
return { greeting: `hello ${who ?? "world"}`, from: process.env.MESH_NODE ?? "somewhere" };
|
input: { type: "object", properties: { who: { type: "string" } } },
|
||||||
},
|
async run(args: Readonly<Record<string, unknown>>) {
|
||||||
});
|
const who = typeof args.who === "string" && args.who !== "" ? args.who : "world";
|
||||||
|
return { greeting: `hello ${who}`, from: env.MESH_NODE ?? "somewhere" };
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "showcase_state",
|
||||||
|
description: "What this module was configured with, so a test can read it back.",
|
||||||
|
input: { type: "object", properties: {} },
|
||||||
|
async run() {
|
||||||
|
return {
|
||||||
|
greeting: env.SHOWCASE_GREETING ?? "",
|
||||||
|
database: env.SHOWCASE_DATABASE ?? "",
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
tool({
|
registerModuleTools("showcase", (env) => getShowcaseTools(env));
|
||||||
name: "showcase_state",
|
|
||||||
description: "What this module was configured with, so a test can read it back.",
|
|
||||||
input: { type: "object", properties: {} },
|
|
||||||
async run() {
|
|
||||||
return {
|
|
||||||
greeting: process.env.SHOWCASE_GREETING ?? "",
|
|
||||||
database: process.env.SHOWCASE_DATABASE ?? "",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|||||||
Reference in New Issue
Block a user