Build checked portable package artifacts and shared runtime assets

This commit is contained in:
Timothy J. Aveni
2026-09-20 00:42:19 -07:00
parent 60b1bdb39f
commit ab41e67dc5
8 changed files with 216 additions and 2 deletions
+28
View File
@@ -10,6 +10,7 @@ import {
loadArtifactWorld,
BrowserArtifactGateway,
implementationDigest,
contentArtifactUrl,
} from "../src/execution-world/index.js";
import { loadReaderWorkspace } from "./reader-fixture.js";
import { buildArtifactFixture } from "./artifact-fixture.js";
@@ -52,6 +53,8 @@ test("gateway serves only declared browser assets with correct Wasm MIME and con
digest: createHash("sha256").update(wasm).digest("hex"),
mediaType: "application/wasm",
});
const shared = { ...browser.files[0]!, path: "share/quixos/shared/core.mjs" };
browser.files.push(shared);
const { contentDigest, ...body } = browser;
browser.contentDigest = implementationDigest(body);
for (const implementation of fixture.manifest.implementations)
@@ -65,6 +68,7 @@ test("gateway serves only declared browser assets with correct Wasm MIME and con
const loaded = await loadArtifactWorld(plan, { [fixture.manifest.packageRevisionId]: root });
const gateway = new BrowserArtifactGateway(loaded);
assert.equal(gateway.entries.length, 1);
assert.deepEqual((await gateway.response(contentArtifactUrl(shared)))?.body, Buffer.from(fixture.bytes));
const entry = gateway.entries[0]!;
const response = await gateway.response(entry.url);
assert.equal(response?.status, 200);
@@ -86,3 +90,27 @@ test("gateway serves only declared browser assets with correct Wasm MIME and con
await rm(root, { recursive: true, force: true });
}
});
test("checked receipts bind regenerated code, generator identity and manifests", async () => {
const { expectedArtifactReceipt, checkArtifactReceipt } = await import("../src/execution-world/receipts.js");
const plan = compileExecutionPlan(await loadReaderWorkspace());
const fixture = buildArtifactFixture(plan);
const generator = "a".repeat(64);
const { receipt, sources } = expectedArtifactReceipt(plan, fixture.manifest, generator);
const read = async (_revision: string, file: string) => sources.get(file)!;
await checkArtifactReceipt(plan, fixture.manifest, receipt, generator, read);
await assert.rejects(
checkArtifactReceipt(plan, fixture.manifest, { ...receipt, generatorDigest: "b".repeat(64) }, generator, read),
/trusted compiler/,
);
await assert.rejects(
checkArtifactReceipt(plan, fixture.manifest, { ...receipt, manifestDigest: "b".repeat(64) }, generator, read),
/trusted compiler/,
);
await assert.rejects(
checkArtifactReceipt(plan, fixture.manifest, receipt, generator, async () =>
new TextEncoder().encode("substituted"),
),
/replaced or omitted/,
);
});
+20
View File
@@ -11,3 +11,23 @@ for (const target of ["browser", "server"])
generatePortableTypeScriptBindings(plan.definition.bindingSchema, "package:reader-runtime@1", { target }),
);
await writeFile("dist/portable-reader/plan.json", JSON.stringify(plan));
const serviceWorkspace = structuredClone(plan.definition.workspace);
serviceWorkspace.atoms = [];
serviceWorkspace.conformances = [];
serviceWorkspace.constructors = [];
serviceWorkspace.interfaceImports = [];
serviceWorkspace.sharedAttachments = [];
serviceWorkspace.packageImports[0]!.queries = [];
serviceWorkspace.packageImports[0]!.checkedQueries = [];
const original = serviceWorkspace.packageImports[0]!.exports.find((e) => e.kind === "function")!;
serviceWorkspace.packageImports[0]!.exports = [
{
...original,
kind: "function",
execution: { kind: "remote" },
inputType: { kind: "scalar", name: "string" },
outputType: { kind: "scalar", name: "string" },
dependencyPorts: [],
},
];
await writeFile("dist/portable-reader/service-plan.json", JSON.stringify(compileExecutionPlan(serviceWorkspace)));