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:
@@ -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 }) => {
|
||||
|
||||
Reference in New Issue
Block a user