Make local graph execution optional across composed packages
This commit is contained in:
@@ -17,23 +17,63 @@ import {
|
||||
|
||||
import { buildArtifactFixture as buildFixture } from "./artifact-fixture.js";
|
||||
import { compileKernelProgram } from "../src/execution-world/kernel.js";
|
||||
import { loadCompositeWorkspace } from "./composite-fixture.js";
|
||||
import { standardNativeBackends } from "../src/execution-world/native-backends.js";
|
||||
|
||||
test("optional targets close over calls into another package", async () => {
|
||||
const workspace = await loadCompositeWorkspace();
|
||||
const before = compileExecutionPlan(workspace).definition.operations.find(
|
||||
(op) => op.operationId === "document:annotate:call",
|
||||
)!;
|
||||
assert.ok(before, "fixture exposes the composed add-highlight operation");
|
||||
assert.equal(before.availableTargets.length, 2);
|
||||
workspace.packageImports.find((pkg) => pkg.revisionId === "package:comment-runtime@1")!.exports[0]!.execution = {
|
||||
kind: "transaction",
|
||||
targets: ["server"],
|
||||
};
|
||||
const after = compileExecutionPlan(workspace).definition.operations.find((op) => op.key === before.key)!;
|
||||
assert.deepEqual(after.availableTargets, ["server"]);
|
||||
assert.deepEqual(after.execution, before.execution);
|
||||
});
|
||||
|
||||
test("native support can be supplied for a nominal device target without platform syntax", async () => {
|
||||
const workspace = await loadReaderWorkspace();
|
||||
const target = "interface:example.esp32@1";
|
||||
for (const pkg of workspace.packageImports)
|
||||
for (const entry of pkg.exports) {
|
||||
if (entry.execution && entry.execution.kind !== "remote") entry.execution.targets.push(target);
|
||||
}
|
||||
const plan = compileExecutionPlan(workspace, [
|
||||
...standardNativeBackends,
|
||||
{ target, supports: (binding) => binding.kind === "state" || binding.kind === "edge" },
|
||||
]);
|
||||
assert.ok(
|
||||
plan.definition.operations
|
||||
.filter((op) => op.binding.kind === "state")
|
||||
.every((op) => op.availableTargets.includes(target)),
|
||||
);
|
||||
assert.ok(
|
||||
plan.definition.operations.some((op) => op.binding.kind === "package" && op.availableTargets.includes(target)),
|
||||
);
|
||||
});
|
||||
const resign = (implementation: ArtifactImplementation) => {
|
||||
const { contentDigest, ...body } = implementation;
|
||||
implementation.contentDigest = implementationDigest(body);
|
||||
};
|
||||
|
||||
test("installed targets can exceed the public requirement without changing that contract", async () => {
|
||||
const workspace = await loadReaderWorkspace((name, text) =>
|
||||
name === "DocumentFactory.qx" ? text.replaceAll("targets [browser, server]", "targets [server]") : text,
|
||||
);
|
||||
test("installed targets are implementation properties; authoritative fallback preserves the interface", async () => {
|
||||
const workspace = await loadReaderWorkspace();
|
||||
const plan = compileExecutionPlan(workspace);
|
||||
const factory = plan.definition.operations.find(
|
||||
(op) => op.binding.kind === "package" && op.binding.exportId === "reader:create-document",
|
||||
)!;
|
||||
assert.deepEqual(factory.execution, { kind: "transaction", targets: ["server"] });
|
||||
assert.deepEqual(factory.availableTargets, ["browser", "server"]);
|
||||
assert.deepEqual(factory.availableTargets, ["server", "target:org.quixos.execution.javascript@1"]);
|
||||
const kernel = compileKernelProgram(plan) as { operations: { key: string; targets: string[] }[] };
|
||||
assert.deepEqual(kernel.operations.find((op) => op.key === factory.key)!.targets, ["browser", "server"]);
|
||||
assert.deepEqual(kernel.operations.find((op) => op.key === factory.key)!.targets, [
|
||||
"server",
|
||||
"target:org.quixos.execution.javascript@1",
|
||||
]);
|
||||
|
||||
const provider = workspace.packageImports
|
||||
.flatMap((pkg) => pkg.exports)
|
||||
@@ -102,8 +142,8 @@ test("artifact closure checks bytes, exact source/schema, ABI, exports and targe
|
||||
(m.versions as unknown as Record<string, string>).value = "v2";
|
||||
}, /Incompatible runtime codecs/);
|
||||
await negative((m) => {
|
||||
m.implementations = m.implementations.filter((i) => i.target !== "browser");
|
||||
}, /Missing browser implementation/);
|
||||
m.implementations = m.implementations.filter((i) => i.target !== "target:org.quixos.execution.javascript@1");
|
||||
}, /Missing target:org.quixos.execution.javascript@1 implementation/);
|
||||
await negative((m) => {
|
||||
m.implementations = m.implementations.filter((i) => i.compatibility !== "quixos-service-v1");
|
||||
}, /Missing service fallback/);
|
||||
@@ -211,7 +251,7 @@ test("closed generic applications retain distinct identities and codec shapes",
|
||||
const source = { repository: "https://example.test/generic.git", commit: "a".repeat(40) };
|
||||
const definition = compileCapabilityResourceSource(
|
||||
`interface Cell<value V : storable> id "cell" revision "cell@1" {
|
||||
value content id "value" : V { get id "get" execution snapshot targets [browser, server]; }
|
||||
value content id "value" : V { get id "get" execution snapshot; }
|
||||
}`,
|
||||
{ source },
|
||||
);
|
||||
@@ -269,11 +309,10 @@ test("query dependencies propagate target requirements through selected getters"
|
||||
binding: { kind: "query", packageRevisionId: pkg.revisionId, queryId: query.id, scope: "workspace" },
|
||||
});
|
||||
compileExecutionPlan(workspace);
|
||||
const field = workspace.interfaceImports
|
||||
.find((i) => i.displayName === "HighlightData")!
|
||||
.members.find((m) => m.displayName === "color")!;
|
||||
field.operations.find((o) => o.displayName === "get")!.execution = { kind: "snapshot", targets: ["browser"] };
|
||||
assert.throws(() => compileExecutionPlan(workspace), /MISSING_EXECUTION_TARGET.*test:selector-query.*server/);
|
||||
// Package artifact support is checked over the composed graph; an interface
|
||||
// declaration cannot manufacture an authoritative implementation.
|
||||
entry.execution = { kind: "snapshot", targets: ["target:org.quixos.execution.javascript@1"] };
|
||||
assert.throws(() => compileExecutionPlan(workspace), /MISSING_SERVER_IMPLEMENTATION/);
|
||||
});
|
||||
|
||||
test("implementation selection is explicit, target checked and independent of manifest order", async () => {
|
||||
@@ -281,7 +320,7 @@ test("implementation selection is explicit, target checked and independent of ma
|
||||
const plan = compileExecutionPlan(await loadReaderWorkspace());
|
||||
const { manifest, read } = buildFixture(plan);
|
||||
const selection = {
|
||||
target: "browser",
|
||||
target: "target:org.quixos.execution.javascript@1",
|
||||
compatibility: "quixos-js-module-v1" as const,
|
||||
exports: [manifest.implementations[0]!.exports[0]!],
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user