95 lines
4.0 KiB
TypeScript
95 lines
4.0 KiB
TypeScript
import { compileInspectionTemplates, type InspectionKernel } from "./inspection.js";
|
|
import { hexDigestAsync, type ExecutionPlan } from "./plan.js";
|
|
import type { ClientContractCatalog } from "./installation.js";
|
|
import { publicOperationContract, publicQueryContract } from "./client-contracts.js";
|
|
|
|
/** Explicit public projection of checked inputs. Never serialize conformance
|
|
* storage or package ports, or recompile a historical Candidate at runtime.
|
|
* The caller supplies that Candidate's checked, cached public catalog. */
|
|
export async function publicDefinitionSnapshot(
|
|
plan: ExecutionPlan,
|
|
kernel: InspectionKernel,
|
|
catalog: ClientContractCatalog,
|
|
) {
|
|
const workspace = plan.definition.workspace;
|
|
const rows = {
|
|
atoms: workspace.atoms.map((atom) => ({ id: atom.id, name: atom.displayName, documentation: atom.documentation })),
|
|
interfaces: workspace.interfaceImports.map((iface) => ({
|
|
id: iface.revisionId,
|
|
interface: iface.interfaceId,
|
|
name: iface.displayName,
|
|
source: iface.source,
|
|
template: iface.template,
|
|
application: iface.application,
|
|
requiredInterfaces: iface.requiredInterfaces ?? [],
|
|
argumentRequirements: iface.argumentRequirements ?? [],
|
|
members: iface.members.map((member) => ({
|
|
...member,
|
|
operations: member.operations.map((operation) => ({
|
|
...operation,
|
|
...(operation.mode === "call" && !iface.template
|
|
? { descriptor: publicOperationContract(iface, operation) }
|
|
: {}),
|
|
})),
|
|
})),
|
|
})),
|
|
conformances: workspace.conformances.map((c) => ({
|
|
id: JSON.stringify([c.atomId, c.interfaceRevisionId]),
|
|
atom: c.atomId,
|
|
interface: c.interfaceRevisionId,
|
|
semanticMajor: c.semanticMajor ?? 0,
|
|
operations: (
|
|
workspace.interfaceImports.find((iface) => iface.revisionId === c.interfaceRevisionId)?.members ?? []
|
|
).flatMap((member) =>
|
|
member.operations.map((operation) => {
|
|
const installed = kernel.operations.find(
|
|
(op) => op.atom === c.atomId && op.interface === c.interfaceRevisionId && op.operation === operation.id,
|
|
);
|
|
return {
|
|
operation: operation.id,
|
|
available: !!installed && !installed.unsupported,
|
|
unavailable: installed?.unsupported ?? (installed ? null : "NOT_CALLABLE"),
|
|
execution: installed ? { kind: installed.effect, targets: installed.targets } : null,
|
|
};
|
|
}),
|
|
),
|
|
modules: catalog.moduleBindings.filter(
|
|
(binding) => binding.atom === c.atomId && binding.interface === c.interfaceRevisionId,
|
|
),
|
|
})),
|
|
queries: [
|
|
...compileInspectionTemplates(plan, kernel).contracts.map((descriptor) => ({
|
|
id: JSON.stringify([descriptor.package, descriptor.query]),
|
|
name: "Public inspection",
|
|
package: descriptor.package,
|
|
descriptor,
|
|
system: true,
|
|
})),
|
|
...workspace.packageImports.flatMap((pkg) =>
|
|
(pkg.checkedQueries ?? []).map((query) => ({
|
|
id: JSON.stringify([pkg.revisionId, query.declaration.id]),
|
|
name: query.declaration.displayName,
|
|
package: pkg.revisionId,
|
|
descriptor: publicQueryContract(pkg, query.declaration.id),
|
|
fragment: query.declaration.fragment,
|
|
limits: query.declaration.budgets,
|
|
watch: query.declaration.watch,
|
|
})),
|
|
),
|
|
],
|
|
presentations: catalog.components.map((component) => ({
|
|
id: JSON.stringify([component.packageRevision, component.id]),
|
|
component,
|
|
registrations: catalog.presentations.filter(
|
|
(p) => p.packageRevision === component.packageRevision && p.component === component.id,
|
|
),
|
|
})),
|
|
};
|
|
const publicRows = JSON.parse(JSON.stringify(rows)) as Record<
|
|
keyof typeof rows,
|
|
{ id: string; [key: string]: unknown }[]
|
|
>;
|
|
for (const entries of Object.values(publicRows)) entries.sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0));
|
|
return { codec: "camino-definitions-v1" as const, id: await hexDigestAsync(publicRows), rows: publicRows };
|
|
}
|