Add checked query composition foundations for prepared presentations

Move React navigation query generation behind an explicit build frontend. Add checked result-dependent query bindings and pure composition evaluation, including one-snapshot server execution. Preserve the existing rendering path while the React manifest, worker preparation, and replica admission integration remain pending; see docs/PREPARED_PRESENTATIONS_PROGRESS.md.
This commit is contained in:
Timothy J. Aveni
2026-09-27 16:28:33 -07:00
parent ad64ba532f
commit fdb7cd3f6f
14 changed files with 595 additions and 23 deletions
+32
View File
@@ -3,6 +3,7 @@ import { compileInspectionTemplates } from "./inspection.js";
import { portableValueSchema } from "../bindings/portable.js";
import { ExecutionPlanError, hexDigest, type ExecutionPlan } from "./plan.js";
import type { ValueType } from "../capability-model/types.js";
import { compileQueryComposition } from "../query/composition.js";
const lowerTypes = (value: unknown): unknown =>
JSON.parse(
@@ -25,9 +26,40 @@ export function compileQueryProgram(plan: ExecutionPlan): unknown {
if (hexDigest(plan.definition) !== plan.digest)
throw new ExecutionPlanError("INVALID_PLAN", "queries", "Plan digest mismatch");
const interfaces = plan.definition.workspace.interfaceImports;
const allQueries = new Map(plan.definition.queries.map(({ id, query }) => [id, query.checked]));
const compositions = plan.definition.workspace.packageImports.flatMap((pkg) =>
(pkg.queryCompositions ?? []).map((composition) => {
const scoped = new Map(allQueries);
for (const query of pkg.checkedQueries ?? []) scoped.set(query.declaration.id, query);
const checked = compileQueryComposition(
{
id: composition.id,
input: composition.input,
steps: composition.steps,
maxQueries: composition.maxQueries,
},
scoped,
);
if (checked.definitionDigest !== composition.definitionDigest)
throw new ExecutionPlanError("INVALID_QUERY_COMPOSITION", composition.id, "Checked dependencies changed");
return {
id: JSON.stringify([pkg.revisionId, composition.id]),
input: portableValueSchema(checked.input),
output: portableValueSchema(checked.output),
maxQueries: checked.maxQueries,
steps: checked.steps.map((step) => ({
...step,
query: (pkg.checkedQueries ?? []).some((query) => query.declaration.id === step.query)
? JSON.stringify([pkg.revisionId, step.query])
: step.query,
})),
};
}),
);
return {
codec: "camino-query-program-v1",
plan: (compileKernelProgram(plan) as { plan: string }).plan,
...(compositions.length ? { compositions } : {}),
queries: [
...compileInspectionTemplates(plan).queries,
...plan.definition.queries.map(({ id, query, admittedOperations }) => {