Implement Studio root and placement capabilities on the replica graph (WI-10)
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
import { portableReflectionType } from "../execution-world/reflection.js";
|
||||
import type { BindingSchema } from "./index.js";
|
||||
import type {
|
||||
ValueType,
|
||||
@@ -98,7 +99,7 @@ interface Method {
|
||||
name: string;
|
||||
portId: string;
|
||||
portName: string;
|
||||
action: { kind: string; primitive?: string; operationId?: string };
|
||||
action: { kind: string; primitive?: string; operationId?: string; selector?: string };
|
||||
input: ValueType;
|
||||
output: ValueType;
|
||||
keyed: boolean;
|
||||
@@ -126,6 +127,15 @@ function methods(
|
||||
throw new PortableBindingError(path, "Snapshot context cannot expose mutation ports");
|
||||
};
|
||||
switch (req.kind) {
|
||||
case "reflection":
|
||||
if (remote)
|
||||
throw new PortableBindingError(
|
||||
path,
|
||||
"Use an ordinary portable snapshot capability to read installation metadata",
|
||||
);
|
||||
return req.selectors.map((selector) =>
|
||||
method(selector, { kind: "reflection", selector }, unit, portableReflectionType(selector)),
|
||||
);
|
||||
case "creation":
|
||||
writable();
|
||||
return [
|
||||
@@ -301,5 +311,27 @@ function generateBindings(
|
||||
methods: all.map((m) => ({ ...m, input: portableValueSchema(m.input), output: portableValueSchema(m.output) })),
|
||||
});
|
||||
}
|
||||
return `// Generated ${remote ? "remote" : "portable"} bindings. Regenerate from the checked capability schema; do not edit.\nimport { define${mode}Registry, type ${mode}Export, type PreparedChange, type ManagedReference, type ExactReference, type ${remote ? "ServerMutationOptions" : "MutationKey"} } from ${q(options.runtimeModule ?? "@quixos/camino-replica-core")};\nexport const target = ${q(options.target)};\nexport type Contexts = { ${contexts.join(";\n")} };\nexport type ${mode}Implementation = { ${implementations.join(";\n")} };\nexport const declarations = ${JSON.stringify(descriptors, null, 2)} as const satisfies readonly ${mode}Export[];\nexport function createRegistry(handlers: ${mode}Implementation) { const installed = { ...handlers }; return define${mode}Registry(declarations, { ${adapters.join(",\n")} }); }\n`;
|
||||
const groups = new Map<string, typeof entries>();
|
||||
for (const entry of entries) {
|
||||
if (!entry.application) continue;
|
||||
const template = pkg.genericExports?.find((item) => item.id === entry.application!.exportId);
|
||||
if (!template) throw new PortableBindingError(entry.id, "Missing generic export template");
|
||||
groups.set(template.displayName, [...(groups.get(template.displayName) ?? []), entry]);
|
||||
}
|
||||
const generic = [...groups].map(([name, applications]) => {
|
||||
contexts.push(
|
||||
`readonly ${q(name)}: ${applications.map((entry) => `Contexts[${q(entry.displayName)}]`).join(" | ")}`,
|
||||
);
|
||||
const type = applications
|
||||
.map(
|
||||
(entry) =>
|
||||
`((context: Contexts[${q(entry.displayName)}]) => ${tsType(entry.outputType)} | Promise<${tsType(entry.outputType)}>)`,
|
||||
)
|
||||
.join(" & ");
|
||||
const handlers = applications
|
||||
.map((entry) => `${q(entry.displayName)}: (context: Contexts[${q(entry.displayName)}]) => handler(context)`)
|
||||
.join(",");
|
||||
return `${q(name)}: (handler: ${type}) => ({${handlers}})`;
|
||||
});
|
||||
return `// Generated ${remote ? "remote" : "portable"} bindings. Regenerate from the checked capability schema; do not edit.\nimport { define${mode}Registry, type ${mode}Export, type PreparedChange, type ManagedReference, type ExactReference, type ${remote ? "ServerMutationOptions" : "MutationKey"} } from ${q(options.runtimeModule ?? "@quixos/camino-replica-core")};\nexport const target = ${q(options.target)};\nexport type Contexts = { ${contexts.join(";\n")} };\nexport type ${mode}Implementation = { ${implementations.join(";\n")} };\nexport const declarations = ${JSON.stringify(descriptors, null, 2)} as const satisfies readonly ${mode}Export[];\nexport const generic = { ${generic.join(",\n")} };\nexport function createRegistry(handlers: ${mode}Implementation) { const installed = { ...handlers }; return define${mode}Registry(declarations, { ${adapters.join(",\n")} }); }\n`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user