open-standards/joule-code/joule-code-rs/crates/joule-moq-web/web/compose/index.html
Transaction Science 52c00f6847 joule-moq-web: receipts a subscription did not deliver are fetched; the e2e package lock
An object whose receipts-track object reached the relay just before the receipts
subscription did never gets it live; after a second its group of the receipts track is
fetched (moq-streaming-format §4.1). e2e/package-lock.json pins the automation package
by integrity (playwright 1.60.0 and playwright-core, Apache-2.0; fsevents, MIT, optional,
its install script never run: npm ci --ignore-scripts).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-18 13:53:25 -04:00

63 lines
3.3 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Composition conformance</title>
<link rel="icon" href="data:,">
<style>
:root { --bg: #f6f7f9; --fg: #15171a; --muted: #5d6470; }
@media (prefers-color-scheme: dark) { :root { --bg: #111317; --fg: #e8eaee; --muted: #9aa2ae; } }
body { margin: 0; padding: 16px; background: var(--bg); color: var(--fg); font: 14px/1.45 system-ui, sans-serif; }
pre { white-space: pre-wrap; overflow-wrap: anywhere; font: 12px ui-monospace, monospace; color: var(--muted); }
</style>
</head>
<body>
<h1 style="font-size:16px">live-conformance/compose in the browser</h1>
<pre id="out">running</pre>
<script type="module">
// Every case of live-conformance/compose given its outcome by wai-live-web's wasm build:
// the layout and mix cases through the functions a page lays out and mixes with, the
// compositions through the room replay a page composes with, and wai-rs's own corpus
// check run in the page. The corpus states the outcome the native build reaches, so a
// case that holds here gives the native build's rectangles and samples.
import init, * as wai from "../pkg/wai_live_web.js";
const out = document.getElementById("out");
const differ = (c, got) => Object.keys(got).filter((k) => JSON.stringify(c[k]) !== JSON.stringify(got[k]));
async function run() {
await init();
const text = await (await fetch(new URLSearchParams(location.search).get("corpus") || "../vectors/compose.json")).text();
const doc = JSON.parse(text);
const r = { layouts: 0, mixes: 0, compositions: 0, descriptors: 0, failures: [] };
for (const c of doc.layouts) {
r.layouts++;
const got = JSON.parse(wai.layoutCase(JSON.stringify(c.params), JSON.stringify(c.entrants)));
for (const k of differ(c, got)) r.failures.push(`layout ${c.name}: ${k}`);
}
for (const c of doc.mixes) {
r.mixes++;
const got = JSON.parse(wai.mixCase(c.channels, c.frames, JSON.stringify(c.inputs)));
for (const k of differ(c, got)) r.failures.push(`mix ${c.name}: ${k}`);
}
const unhex = (h) => new Uint8Array((h.match(/../g) || []).map((x) => parseInt(x, 16)));
for (const c of doc.compositions) {
r.compositions++;
const got = JSON.parse(wai.compositionCase(JSON.stringify(doc.rooms[c.room]), unhex(c.descriptor), JSON.stringify(c.instants)));
for (const k of differ(c, got)) r.failures.push(`composition ${c.name}: ${k}`);
}
for (const c of doc.descriptors) {
r.descriptors++;
const got = JSON.parse(wai.composeDescriptor(unhex(c.bytes)));
const want = c.outcome === "read" ? { outcome: "read", digest: c.digest } : { outcome: "refuse", reason: c.reason };
const g = c.outcome === "read" ? { outcome: got.outcome, digest: got.digest } : { outcome: got.outcome, reason: got.reason };
if (JSON.stringify(g) !== JSON.stringify(want)) r.failures.push(`descriptor ${c.name}`);
}
r.corpus_verify = wai.corpusVerify(text);
r.tiles = doc.layouts.reduce((n, c) => n + (c.tiles ? c.tiles.length : 0), 0) + doc.compositions.reduce((n, c) => n + (c.frames || []).reduce((k, f) => k + f.tiles.length, 0), 0);
window.composeTest = r;
out.textContent = JSON.stringify(r, null, 2);
}
run().catch((e) => { window.composeTest = { error: String(e.stack || e) }; out.textContent = String(e.stack || e); });
</script>
</body>
</html>