Make local graph execution optional across composed packages

This commit is contained in:
Timothy J. Aveni
2026-09-28 21:05:42 -07:00
parent 1e72713ae2
commit e9c15fe40f
87 changed files with 3703 additions and 3400 deletions
+19 -14
View File
@@ -1,3 +1,4 @@
import { standardNativeBackends, type NativeExecutionBackend } from "./native-backends.js";
import type {
WorkspaceRevision,
ExecutionContract,
@@ -45,7 +46,7 @@ export interface PlannedOperation {
operationId: string;
scope: "object" | "class";
execution: ExecutionContract;
/** Installed implementation closure; the public execution contract above remains required. */
/** Targets available for this complete installed implementation/dependency closure. */
availableTargets: string[];
input: ValueType;
output: ValueType;
@@ -171,7 +172,10 @@ function checkValue(type: ValueType, path: string, allowChange = false): void {
}
/** Compile declarations into a closed dispatch/dependency graph before artifact selection. */
export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
export function compileExecutionPlan(
input: WorkspaceRevision,
backends: readonly NativeExecutionBackend[] = standardNativeBackends,
): ExecutionPlan {
const workspace = structuredClone(input);
const issues = validateWorkspaceRevision(workspace);
if (issues.length)
@@ -311,13 +315,6 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
path.join(" -> "),
"Execution effect is not allowed by the root contract",
);
for (const target of requested.targets)
if (!node.execution.targets.includes(target))
throw new ExecutionPlanError(
"MISSING_EXECUTION_TARGET",
path.join(" -> "),
`Dependency does not provide ${target}`,
);
for (const dependency of node.dependencies) {
if (dependency.kind === "operation")
walk(dependency.operation, [...path, dependency.port, dependency.operation]);
@@ -352,9 +349,10 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
const provider =
binding.kind === "package"
? packages.get(binding.packageRevisionId)!.exports.find((entry) => entry.id === binding.exportId)!.execution
: binding.kind === "lifecycle" || (binding.kind === "subscription" && binding.primitive !== "status")
? { kind: "transaction" as const, targets: ["server" as const] }
: { kind: node.execution.kind, targets: ["browser" as const, "server" as const] };
: {
kind: node.execution.kind,
targets: backends.filter((backend) => backend.supports(binding)).map((backend) => backend.target),
};
if (provider && provider.kind !== "remote") node.availableTargets = [...provider.targets].sort();
}
let targetsChanged = true;
@@ -382,6 +380,13 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
}
}
}
for (const node of operationMap.values())
if (node.execution.kind !== "remote" && !node.availableTargets.includes("server"))
throw new ExecutionPlanError(
"MISSING_SERVER_IMPLEMENTATION",
node.key,
"Every graph operation requires an authoritative implementation across its dependency closure",
);
const plannedQueries: PlannedQuery[] = queries.map((query) => ({
id: queryKey(query.packageRevisionId, query.checked.declaration.id),
query,
@@ -515,11 +520,11 @@ export function compileExecutionPlan(input: WorkspaceRevision): ExecutionPlan {
source.admittedOperations.push(...query.operations);
for (const operation of query.operations) {
const node = operationMap.get(operation)!;
if (node.execution.kind !== "snapshot" || !node.execution.targets.includes("browser"))
if (node.execution.kind !== "snapshot" || !node.availableTargets.some((target) => target !== "server"))
throw new ExecutionPlanError(
"NONPORTABLE_QUERY_FIELD",
`${query.id}/${operation}`,
"Local query getter must provide browser snapshot execution",
"Local query getter needs an installed local snapshot implementation",
);
}
}