Expose closed module types and define stable presentation occurrences
This commit is contained in:
@@ -7,6 +7,7 @@ import type {
|
||||
import { canonicalJson } from "../capability-model/evolution.js";
|
||||
import { portableValueSchema, tsType } from "../bindings/portable.js";
|
||||
import { type ExecutionPlan, resolvePlannedOperation, hexDigest, ExecutionPlanError } from "./plan.js";
|
||||
import { moduleTypeContext } from "./module-contracts.js";
|
||||
|
||||
/** Public shape only: no slot inventory, implementation binding, or workspace identity. */
|
||||
export interface PublicOperationContract {
|
||||
@@ -111,7 +112,7 @@ export function generateInterfaceClientBindings(
|
||||
const members = iface.members.map((member) => {
|
||||
if (member.kind === "module" && member.subject?.kind === "interface") {
|
||||
const subject = member.subject.interfaceRevisionId;
|
||||
return `${JSON.stringify(member.displayName)}: defineModuleMember<${JSON.stringify(subject)}, ${moduleProps?.(iface.revisionId, member.id) ?? "{}"}>(${JSON.stringify({ interface: iface.revisionId, member: member.id, subject, contract: member.contract })})`;
|
||||
return `${JSON.stringify(member.displayName)}: defineModuleMember<${JSON.stringify(subject)}, ${moduleProps?.(iface.revisionId, member.id) ?? "{}"}>(${JSON.stringify({ interface: iface.revisionId, member: member.id, subject, contract: member.contract, ...moduleTypeContext(iface) })})`;
|
||||
}
|
||||
const operations = member.operations
|
||||
.filter((op) => op.mode === "call")
|
||||
|
||||
@@ -128,6 +128,8 @@ export interface InstalledComponent {
|
||||
readonly member: string;
|
||||
readonly subject: string;
|
||||
readonly contract: string;
|
||||
readonly typeArguments?: readonly unknown[];
|
||||
readonly requiredInterfaces?: readonly string[];
|
||||
};
|
||||
readonly packageRevision: string;
|
||||
readonly id: string;
|
||||
@@ -215,6 +217,8 @@ function assembleExecutionInstallation(
|
||||
member: module.memberId,
|
||||
subject: component.subject,
|
||||
contract: module.contract,
|
||||
...(module.typeArguments ? { typeArguments: module.typeArguments } : {}),
|
||||
...(module.requiredInterfaces ? { requiredInterfaces: module.requiredInterfaces } : {}),
|
||||
};
|
||||
})(),
|
||||
packageRevision: revision,
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { InterfaceRevision } from "../capability-model/types.js";
|
||||
|
||||
/** Public, checked type information for artifact consumers. It describes the
|
||||
* nominal role, without exposing implementations or synthesizing any storage. */
|
||||
export function moduleTypeContext(iface: InterfaceRevision): {
|
||||
typeArguments?: readonly unknown[];
|
||||
requiredInterfaces?: readonly string[];
|
||||
} {
|
||||
return {
|
||||
...(iface.application?.arguments.length
|
||||
? {
|
||||
typeArguments: structuredClone(iface.application.arguments),
|
||||
}
|
||||
: {}),
|
||||
...(iface.requiredInterfaces?.length ? { requiredInterfaces: [...iface.requiredInterfaces].sort() } : {}),
|
||||
};
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import { resolveForwardedBinding } from "../capability-model/forwarding.js";
|
||||
import { linkQueries, type LinkedQuery } from "../query/link.js";
|
||||
import { type BindingSchema } from "../bindings/index.js";
|
||||
import { unsupportedQueryOperator } from "./query-operators.js";
|
||||
import { moduleTypeContext } from "./module-contracts.js";
|
||||
|
||||
export class ExecutionPlanError extends Error {
|
||||
constructor(
|
||||
@@ -62,6 +63,8 @@ export interface PlanPackage {
|
||||
modules?: (NonNullable<WorkspaceRevision["packageImports"][number]["modules"]>[number] & {
|
||||
contract: string;
|
||||
subject?: import("../capability-model/types.js").ObjectExpectation;
|
||||
typeArguments?: readonly unknown[];
|
||||
requiredInterfaces?: readonly string[];
|
||||
})[];
|
||||
controllers?: NonNullable<WorkspaceRevision["packageImports"][number]["controllers"]>;
|
||||
components?: { id: string; displayName: string; subject: InterfaceRevisionId; runtime: "react" }[];
|
||||
@@ -504,6 +507,9 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
|
||||
...module,
|
||||
contract: contract.contract,
|
||||
...(contract.subject ? { subject: contract.subject } : {}),
|
||||
...moduleTypeContext(
|
||||
workspace.interfaceImports.find((iface) => iface.revisionId === module.interfaceRevisionId)!,
|
||||
),
|
||||
};
|
||||
}),
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user