Package ordinary PresentationMount contracts and typed React hosting

This commit is contained in:
Timothy J. Aveni
2026-09-25 12:26:34 -07:00
parent e7778b3518
commit c482a99aca
4 changed files with 19 additions and 6 deletions
+14 -1
View File
@@ -211,6 +211,19 @@ export function generateComponentClientBindings(plan: ExecutionPlan, packageRevi
const subjects = Object.fromEntries(components.map((component) => [component.displayName, find(component.subject)]));
const props = (iface: string, member: string) =>
`ExtraModuleProps<${JSON.stringify(JSON.stringify([iface, member]))}>`;
// Preserve closed type arguments for the artifact consumer. Interpretation of
// a particular module contract belongs to that consumer, not this compiler.
const moduleArguments = (iface: InterfaceRevision) => `[${(iface.application?.arguments ?? []).map(argument => {
if (argument.kind === "value") return tsType(argument.type);
const target = argument.target;
const reference = target.kind === "atom" ? `ManagedReference<"atom", ${JSON.stringify(target.atomId)}>` : `ManagedReference<"interface", ${JSON.stringify(target.interfaceRevisionId)}>`;
const fields = target.kind === "interface" ? find(target.interfaceRevisionId).members.flatMap(member => {
if ((member.kind !== "value" && member.kind !== "relationship") || !member.queryRead) return [];
const getter = member.operations.find(operation => operation.displayName === (member.kind === "value" ? "get" : "resolve"));
return getter ? [`readonly ${JSON.stringify(member.displayName)}: ${tsType(getter.outputType)}`] : [];
}) : [];
return `{readonly reference: ${reference}; readonly values: {${fields.join(";")}}}`;
}).join(",")}]`;
const interfaces = generateInterfaceClientBindings(imports, "@quixos/camino-react", props);
const subjectBindings = generateInterfaceClientBindings(subjects, "@quixos/camino-react", props)
.split("\n")
@@ -248,7 +261,7 @@ export function generateComponentClientBindings(plan: ExecutionPlan, packageRevi
.map((component) => {
const module = modules.find((module) => module.id === component.id)!;
const key = JSON.stringify([module.interfaceRevisionId, module.memberId]);
return `${JSON.stringify(component.displayName)}: ComponentType<ComponentProps<${JSON.stringify(component.subject)}> & ExtraModuleProps<${JSON.stringify(key)}>>;`;
return `${JSON.stringify(component.displayName)}: ComponentType<ComponentProps<${JSON.stringify(component.subject)}, ${JSON.stringify(module.contract)}, ${moduleArguments(find(module.interfaceRevisionId))}> & ExtraModuleProps<${JSON.stringify(key)}>>;`;
})
.join("\n") +
"\n}\n"