diff --git a/experiments/iroh-blobs/host/browser-entry.ts b/experiments/iroh-blobs/host/browser-entry.ts index 535db5b..141c892 100644 --- a/experiments/iroh-blobs/host/browser-entry.ts +++ b/experiments/iroh-blobs/host/browser-entry.ts @@ -3,31 +3,34 @@ // (browser-test.mjs) to await and assert on. // // Bundled by browser-test.mjs with `deno bundle --platform browser` into -// dist/browser-entry.js; the page passes the translator-shim URL as the -// `translator` query parameter and the guest component is fetched -// relative to this experiment. +// dist/browser-entry.js; the harness pre-translates the guest with +// translate.ts (embedder-api A4), so the page fetches the component plus +// its envelope and no translator ships to the browser. import { stats } from "./sockets.ts"; import { bridgeStats } from "./bridge.ts"; import { webrtcStats } from "./webrtc-bridge.ts"; -import { guestImports, runGuest } from "../../iroh-relay-ws/host/harness.ts"; +import { artifactsFrom, guestImports, runGuest } from "../../iroh-relay-ws/host/harness.ts"; const logEl = document.getElementById("log")!; const t0 = performance.now(); try { - const params = new URLSearchParams(location.search); - const translatorUrl = params.get("translator"); - if (!translatorUrl) throw new Error("missing ?translator= (see browser-test.mjs)"); const fetchBytes = async (url: string): Promise => { const resp = await fetch(url); if (!resp.ok) throw new Error(`GET ${url}: ${resp.status}`); return new Uint8Array(await resp.arrayBuffer()); }; - const [translator, componentBytes] = await Promise.all([ - fetchBytes(translatorUrl), + const fetchText = async (url: string): Promise => { + const resp = await fetch(url); + if (!resp.ok) throw new Error(`GET ${url}: ${resp.status}`); + return resp.text(); + }; + const [componentBytes, envelope] = await Promise.all([ fetchBytes("../guest/target/wasm32-wasip2/release/iroh-blobs-guest.wasm"), + fetchText("./dist/iroh-blobs-guest.plan.json"), ]); + const artifacts = artifactsFrom(envelope, componentBytes); console.log(`[driver] loaded in ${(performance.now() - t0).toFixed(1)}ms`); const env: Record = {}; @@ -39,7 +42,7 @@ try { if (relay) env.RELAY = relay; await runGuest( - { componentBytes, translator }, + artifacts, guestImports({ args: ["iroh-blobs-guest"], env }), ); const summary = diff --git a/experiments/iroh-blobs/host/browser-test.mjs b/experiments/iroh-blobs/host/browser-test.mjs index b750a7e..11f75fc 100644 --- a/experiments/iroh-blobs/host/browser-test.mjs +++ b/experiments/iroh-blobs/host/browser-test.mjs @@ -2,9 +2,10 @@ // live relay→webrtc migration + blob transfer happened. Companion to // run.ts (Deno path). // -// - fetches the pinned deltic translator shim (host-deltic/fetch-translator.ts) -// and bundles the page driver with `deno bundle --platform browser`, -// - serves the repository root over HTTP (the guest and translator fetches +// - pre-translates the guest (translate.ts, embedder-api A4 envelope) and +// bundles the page driver with `deno bundle --platform browser` — the +// page fetches component + envelope; no translator ships to the browser, +// - serves the repository root over HTTP (the guest and envelope fetches // resolve there, and COOP/COEP headers buy 5us timers for the guest's // RTT measurements), // - reuses a running iroh-relay on 127.0.0.1:3340 or starts one, @@ -19,13 +20,17 @@ import { readFile } from "node:fs/promises"; import { spawn } from "node:child_process"; import { execFile } from "node:child_process"; import { promisify } from "node:util"; -import { extname, join, normalize, relative } from "node:path"; +import { extname, join, normalize } from "node:path"; import { fileURLToPath } from "node:url"; import { chromium } from "playwright"; const HOST_DIR = fileURLToPath(new URL(".", import.meta.url)); const ROOT = fileURLToPath(new URL("../../..", import.meta.url)); const PAGE_PATH = "/experiments/iroh-blobs/host/browser.html"; +const GUEST_WASM = join( + HOST_DIR, + "../guest/target/wasm32-wasip2/release/iroh-blobs-guest.wasm", +); const RELAY_BIN = join(ROOT, ".deps/iroh/target/release/iroh-relay"); const TIMEOUT_MS = 90_000; @@ -39,20 +44,19 @@ const MIME = { const run = promisify(execFile); -/** Fetch (cached) the pinned translator shim; return its URL path under ROOT. */ -async function fetchTranslator() { - const { stdout } = await run("deno", [ +/** Pre-translate the guest (A4): the page fetches this envelope. */ +async function translateGuest() { + await run("deno", [ "run", "--config", - join(ROOT, "host-deltic/deno.json"), + join(HOST_DIR, "../../iroh-relay-ws/host/deno.json"), "--frozen", `--allow-read=${ROOT}`, - `--allow-write=${join(ROOT, "target/deltic")}`, - "--allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com", - join(ROOT, "host-deltic/fetch-translator.ts"), - ]); - const path = stdout.trim(); - return `/${relative(ROOT, path).split("\\").join("/")}`; + `--allow-write=${join(HOST_DIR, "dist")}`, + join(HOST_DIR, "../../iroh-relay-ws/host/translate.ts"), + GUEST_WASM, + join(HOST_DIR, "dist/iroh-blobs-guest.plan.json"), + ], { cwd: HOST_DIR }); } async function bundleEntry() { @@ -133,14 +137,12 @@ async function runPage(browser, url, lines) { } const headed = process.argv.includes("--headed"); -console.log("[harness] fetching translator + bundling the page driver"); -const translatorPath = await fetchTranslator(); +console.log("[harness] translating the guest + bundling the page driver"); +await translateGuest(); await bundleEntry(); const relay = await ensureRelay(); const server = await serveRoot(); -const url = `http://127.0.0.1:${server.address().port}${PAGE_PATH}?translator=${ - encodeURIComponent(translatorPath) -}`; +const url = `http://127.0.0.1:${server.address().port}${PAGE_PATH}`; console.log(`[harness] serving ${url}`); const lines = []; diff --git a/experiments/iroh-blobs/host/run.ts b/experiments/iroh-blobs/host/run.ts index 01b038d..44478ae 100644 --- a/experiments/iroh-blobs/host/run.ts +++ b/experiments/iroh-blobs/host/run.ts @@ -3,9 +3,10 @@ // WebRTC). The guest prints its own results; this driver adds a // watchdog and the shim/bridge counters. // -// Runs on stock Deno: run.sh fetches the pinned translator shim and -// exports its path as DELTIC_TRANSLATOR. +// Runs on stock Deno; the translator is `@deltic/translator`'s packaged +// asset, loaded through the module graph. +import { defaultTranslator } from "@deltic/translator"; import { stats } from "./sockets.ts"; import { bridgeStats } from "./bridge.ts"; import { webrtcStats } from "./webrtc-bridge.ts"; @@ -28,19 +29,10 @@ const watchdog = setTimeout(() => { Deno.exit(1); }, WATCHDOG_MS); -const shimPath = Deno.env.get("DELTIC_TRANSLATOR"); -if (!shimPath) { - console.error( - "[driver] DELTIC_TRANSLATOR is unset — run this through run.sh, which " + - "fetches the pinned translator shim (host-deltic/fetch-translator.ts).", - ); - Deno.exit(2); -} - const t0 = performance.now(); const artifacts = { componentBytes: await Deno.readFile(GUEST_WASM), - translator: await Deno.readFile(shimPath), + translator: await defaultTranslator(), }; console.log(`[driver] loaded in ${(performance.now() - t0).toFixed(1)}ms`); diff --git a/experiments/iroh-blobs/run.sh b/experiments/iroh-blobs/run.sh index 58f265d..802897a 100755 --- a/experiments/iroh-blobs/run.sh +++ b/experiments/iroh-blobs/run.sh @@ -1,7 +1,8 @@ #!/usr/bin/env bash # Runs the iroh-blobs spike end to end: a stock iroh-relay server (from # .deps/iroh, built by the just recipe), then the deltic host on stock -# Deno driving the wasip2 guest — runtime-linked, no transpile step. +# Deno driving the wasip2 guest — runtime-linked, no transpile step; the +# translator ships inside the pinned @deltic/translator package. # Reuses an already-running relay on 127.0.0.1:3340; kills only what it # started. set -euo pipefail @@ -20,14 +21,4 @@ if ! curl -s -m 2 http://127.0.0.1:3340 >/dev/null 2>&1; then done fi -# The sha256-pinned translator shim, cached under target/deltic/ (the pin -# and the cache live with host-deltic; the deltic tag in -# ../iroh-relay-ws/host/deno.json — the shared config for every -# experiment — matches it). -shim=$(deno run --config ../../host-deltic/deno.json --frozen \ - --allow-read=../.. --allow-write=../../target/deltic \ - --allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com \ - ../../host-deltic/fetch-translator.ts) - -DELTIC_TRANSLATOR="$shim" timeout 120 \ - deno run -A --config ../iroh-relay-ws/host/deno.json --frozen host/run.ts +timeout 120 deno run -A --config ../iroh-relay-ws/host/deno.json --frozen host/run.ts diff --git a/experiments/iroh-relay-ws/host/browser-entry.ts b/experiments/iroh-relay-ws/host/browser-entry.ts index 1f45dbb..874ce4a 100644 --- a/experiments/iroh-relay-ws/host/browser-entry.ts +++ b/experiments/iroh-relay-ws/host/browser-entry.ts @@ -3,31 +3,34 @@ // (browser-test.mjs) to await and assert on. // // Bundled by browser-test.mjs with `deno bundle --platform browser` into -// dist/browser-entry.js; the page passes the translator-shim URL as the -// `translator` query parameter and the guest component is fetched -// relative to this experiment. +// dist/browser-entry.js; the harness pre-translates the guest with +// translate.ts (embedder-api A4), so the page fetches the component plus +// its envelope and no translator ships to the browser. import { stats } from "./sockets.ts"; import { bridgeStats } from "./bridge.ts"; import { webrtcStats } from "./webrtc-bridge.ts"; -import { guestImports, runGuest } from "./harness.ts"; +import { artifactsFrom, guestImports, runGuest } from "./harness.ts"; const logEl = document.getElementById("log")!; const t0 = performance.now(); try { - const params = new URLSearchParams(location.search); - const translatorUrl = params.get("translator"); - if (!translatorUrl) throw new Error("missing ?translator= (see browser-test.mjs)"); const fetchBytes = async (url: string): Promise => { const resp = await fetch(url); if (!resp.ok) throw new Error(`GET ${url}: ${resp.status}`); return new Uint8Array(await resp.arrayBuffer()); }; - const [translator, componentBytes] = await Promise.all([ - fetchBytes(translatorUrl), + const fetchText = async (url: string): Promise => { + const resp = await fetch(url); + if (!resp.ok) throw new Error(`GET ${url}: ${resp.status}`); + return resp.text(); + }; + const [componentBytes, envelope] = await Promise.all([ fetchBytes("../guest/target/wasm32-wasip2/release/iroh-relay-ws-guest.wasm"), + fetchText("./dist/iroh-relay-ws-guest.plan.json"), ]); + const artifacts = artifactsFrom(envelope, componentBytes); console.log(`[driver] loaded in ${(performance.now() - t0).toFixed(1)}ms`); const env: Record = {}; @@ -35,7 +38,7 @@ try { if (rustLog) env.RUST_LOG = rustLog; await runGuest( - { componentBytes, translator }, + artifacts, guestImports({ args: ["iroh-relay-ws-guest"], env }), ); const summary = diff --git a/experiments/iroh-relay-ws/host/browser-test.mjs b/experiments/iroh-relay-ws/host/browser-test.mjs index d2ee792..fa001fe 100644 --- a/experiments/iroh-relay-ws/host/browser-test.mjs +++ b/experiments/iroh-relay-ws/host/browser-test.mjs @@ -1,9 +1,10 @@ // Playwright harness: runs the spike in a real Chromium and asserts the // live relay→webrtc migration happened. Companion to run.ts (Deno path). // -// - fetches the pinned deltic translator shim (host-deltic/fetch-translator.ts) -// and bundles the page driver with `deno bundle --platform browser`, -// - serves the repository root over HTTP (the guest/translator fetches +// - pre-translates the guest (translate.ts, embedder-api A4 envelope) and +// bundles the page driver with `deno bundle --platform browser` — the +// page fetches component + envelope; no translator ships to the browser, +// - serves the repository root over HTTP (the guest/envelope fetches // resolve there, and COOP/COEP headers buy 5us timers for the guest's // RTT measurements), // - reuses a running iroh-relay on 127.0.0.1:3340 or starts one, @@ -18,13 +19,17 @@ import { readFile } from "node:fs/promises"; import { spawn } from "node:child_process"; import { execFile } from "node:child_process"; import { promisify } from "node:util"; -import { extname, join, normalize, relative } from "node:path"; +import { extname, join, normalize } from "node:path"; import { fileURLToPath } from "node:url"; import { chromium } from "playwright"; const HOST_DIR = fileURLToPath(new URL(".", import.meta.url)); const ROOT = fileURLToPath(new URL("../../..", import.meta.url)); const PAGE_PATH = "/experiments/iroh-relay-ws/host/browser.html"; +const GUEST_WASM = join( + HOST_DIR, + "../guest/target/wasm32-wasip2/release/iroh-relay-ws-guest.wasm", +); const RELAY_BIN = join(ROOT, ".deps/iroh/target/release/iroh-relay"); const TIMEOUT_MS = 90_000; @@ -38,20 +43,19 @@ const MIME = { const run = promisify(execFile); -/** Fetch (cached) the pinned translator shim; return its URL path under ROOT. */ -async function fetchTranslator() { - const { stdout } = await run("deno", [ +/** Pre-translate the guest (A4): the page fetches this envelope. */ +async function translateGuest() { + await run("deno", [ "run", "--config", - join(ROOT, "host-deltic/deno.json"), + join(HOST_DIR, "deno.json"), "--frozen", `--allow-read=${ROOT}`, - `--allow-write=${join(ROOT, "target/deltic")}`, - "--allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com", - join(ROOT, "host-deltic/fetch-translator.ts"), - ]); - const path = stdout.trim(); - return `/${relative(ROOT, path).split("\\").join("/")}`; + `--allow-write=${join(HOST_DIR, "dist")}`, + join(HOST_DIR, "translate.ts"), + GUEST_WASM, + join(HOST_DIR, "dist/iroh-relay-ws-guest.plan.json"), + ], { cwd: HOST_DIR }); } async function bundleEntry() { @@ -130,14 +134,12 @@ async function runPage(browser, url, lines) { } const headed = process.argv.includes("--headed"); -console.log("[harness] fetching translator + bundling the page driver"); -const translatorPath = await fetchTranslator(); +console.log("[harness] translating the guest + bundling the page driver"); +await translateGuest(); await bundleEntry(); const relay = await ensureRelay(); const server = await serveRoot(); -const url = `http://127.0.0.1:${server.address().port}${PAGE_PATH}?translator=${ - encodeURIComponent(translatorPath) -}`; +const url = `http://127.0.0.1:${server.address().port}${PAGE_PATH}`; console.log(`[harness] serving ${url}`); const lines = []; diff --git a/experiments/iroh-relay-ws/host/browser.html b/experiments/iroh-relay-ws/host/browser.html index 44d34e8..30818f1 100644 --- a/experiments/iroh-relay-ws/host/browser.html +++ b/experiments/iroh-relay-ws/host/browser.html @@ -1,8 +1,8 @@ diff --git a/experiments/iroh-relay-ws/host/deno.json b/experiments/iroh-relay-ws/host/deno.json index a36afa9..16374b7 100644 --- a/experiments/iroh-relay-ws/host/deno.json +++ b/experiments/iroh-relay-ws/host/deno.json @@ -1,14 +1,18 @@ { - "//": "MODULE-IDENTITY CONSTRAINT: deltic's wasi-shims and the sibling deltic host modules (.deps/{websocket,webrtc}) import @deltic/runtime/embedder by bare specifier internally; this file maps that specifier ONCE for the whole module graph, so `instanceof WitError` holds across every boundary. This is the ONE deno config for all three experiments (iroh-relay-ws, iroh-blobs, ping-demo): the others pass --config pointing here, so the deltic pin below is written once. The tag matches host-deltic/deno.json and host-deltic/fetch-translator.ts's TAG (the pin gate there checks all of them; see host-deltic/README.md, 'The pin'). @deltic/runtime/plan serves the translate CLI's envelope self-check (ping-demo/build.sh). The npm mappings serve the webrtc module's bare specifiers under Deno; a browser build resolves the RTCPeerConnection global instead. compilerOptions.lib carries dom next to deno.ns so the browser entries (browser-entry.ts, ping-demo's demo.ts/overlay.ts) type-check in the same graph as the Deno drivers (needs polymorph-websocket >= #44's dom-lib fix).", + "//": "MODULE-IDENTITY CONSTRAINT: deltic's wasi-shims and the sibling deltic host modules (.deps/{websocket,webrtc}) import @deltic/runtime/embedder by bare specifier internally; this file maps that specifier ONCE for the whole module graph, so `instanceof WitError` holds across every boundary. This is the ONE deno config for all three experiments (iroh-relay-ws, iroh-blobs, ping-demo): the others pass --config pointing here. deltic arrives as exactly-pinned JSR prereleases (0.1.0-pre.g names one upstream commit; @deltic/translator ships the translator wasm for the SAME commit); the version matches host-deltic/deno.json by repo convention (exam-deltic asserts it; see host-deltic/README.md, 'The pin'). minimumDependencyAge keeps Deno's default supply-chain gate for everything else while letting same-day @deltic prereleases resolve. The npm mappings serve the webrtc module's bare specifiers under Deno; a browser build resolves the RTCPeerConnection global instead. compilerOptions.lib carries dom next to deno.ns so the browser entries (browser-entry.ts, ping-demo's demo.ts/overlay.ts) type-check in the same graph as the Deno drivers.", "nodeModulesDir": "auto", + "minimumDependencyAge": { + "age": "P1D", + "exclude": ["jsr:@deltic/*"] + }, "compilerOptions": { "lib": ["dom", "dom.iterable", "dom.asynciterable", "deno.ns"] }, "imports": { - "@deltic/runtime/embedder": "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/mod.ts", - "@deltic/runtime/plan": "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/plan/mod.ts", - "@deltic/runtime/shim": "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/shim/mod.ts", - "@deltic/wasi-shims": "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/mod.ts", + "@deltic/runtime/embedder": "jsr:@deltic/runtime@0.1.0-pre.ga67ee83/embedder", + "@deltic/runtime/shim": "jsr:@deltic/runtime@0.1.0-pre.ga67ee83/shim", + "@deltic/translator": "jsr:@deltic/translator@0.1.0-pre.ga67ee83", + "@deltic/wasi-shims": "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83", "node-datachannel": "npm:node-datachannel@0.32.3", "node-datachannel/polyfill": "npm:node-datachannel@0.32.3/polyfill", "werift": "npm:werift@0.22.2" diff --git a/experiments/iroh-relay-ws/host/deno.lock b/experiments/iroh-relay-ws/host/deno.lock index 0120a0b..7ee9e88 100644 --- a/experiments/iroh-relay-ws/host/deno.lock +++ b/experiments/iroh-relay-ws/host/deno.lock @@ -1,10 +1,31 @@ { "version": "5", "specifiers": { + "jsr:@deltic/runtime@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", + "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", + "jsr:@deltic/translator@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", + "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", "npm:node-datachannel@0.32.3": "0.32.3", "npm:playwright@^1.62.1": "1.62.1", "npm:werift@0.22.2": "0.22.2" }, + "jsr": { + "@deltic/runtime@0.1.0-pre.ga67ee83": { + "integrity": "2a2b0949031747a2340dc186299e654ea9f361ae39ac6bd633019940682db4ed" + }, + "@deltic/translator@0.1.0-pre.ga67ee83": { + "integrity": "e4f1bb219e56b62262b0c9665e3f6646aa13883b2cfbb9d6306f69d19974d412", + "dependencies": [ + "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83" + ] + }, + "@deltic/wasi-shims@0.1.0-pre.ga67ee83": { + "integrity": "a5754e65d50873e675695a51279989e22b3771e31f16a84a09feb15905c574a7", + "dependencies": [ + "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83" + ] + } + }, "npm": { "@fidm/asn1@1.0.4": { "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==" @@ -590,69 +611,11 @@ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" } }, - "remote": { - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/async_values.ts": "af1279d4e4db5b756268979aeff5b27c1cf6c0f021213655676ade90472f282b", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/context.ts": "b4b60891ef9d9e72b208636f6ba37f0b9b6962d307af6156ad3b5ad59a626902", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/flatten.ts": "6c980fe38d7adce349d5e028b819eb0ffbb92714f958c1d5daae8da3e7ed3889", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/float.ts": "0483e8c1aa8786eee4c6f6357fee6738555e4310650c474aba6cd811a80d7d36", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/handles.ts": "30510750261499f48a812bb8c349a8f88a3bb7239175e6f1d4e6d10c38571e5d", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/layout.ts": "8122141b39f4d8189c13d91fc1b37825ceead86988f879f3fa9351bbef96f8f2", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/lift.ts": "e4475a44a5618114f288025601b535bc04b97e9a37b3be21f51d3be092d419c8", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/load.ts": "c1d8ddb1b3b3c59afe30710a97ad6dd7ae1ecd59aa1d427a5eaf4552d3b1ea01", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/lower.ts": "916ef7476dc583783770f4c42de7a655350531b3763c81a92249cca96f5e4d80", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/memory.ts": "09728360d6413fb30a5a7bff1ba6abec1ac6474ff150d45f093b8ebe5e65cd51", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/mod.ts": "b79cf9e2bab2e837fee76fa61dc18bff66d941e08597f1b76de93811bd6d6008", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/store.ts": "ab3c1475ddce5aef1c7feb77933c19b48ab8bd54634c22a5397c9e734cfd5183", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/strings.ts": "9589dda3857725792ae15ef6888449b48e973b9eb0f3058ed64e10bf4d39b793", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/trap.ts": "307d8b48806eeba30400b3d7db9370cee70a12298851c1c19053dd8ca0013e1c", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/types.ts": "d0392e8cdf2990a76c8a1f9b85795d3b7c19b8eb006c2b159b671d08c39b9535", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/values.ts": "9e6ddcc4192d05897b2cbea250db3fef0ad9bf6548ba87aff378ee14b7ab7022", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/casing.ts": "1e9083becfc08107c09015ce3db79c304b05c40085a3c899ea1c8ebe25fcd45f", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/errors.ts": "fe1b220c22facf37948d444f97d7c8083da41c8496e6ce23b27c820ca0c2c7d7", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/imports.ts": "98cca003e4a1131c35854c91b458f109d6761a3e8f67c23730f7e9bc28bbad88", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/instantiate.ts": "1c50c17d72bca15738b161b99aa5c406ce87486110b50d09f116aa49a05c215c", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/mod.ts": "3d0be7e5d2fc784725c7ec5ddb1add5120c4f7a2c39be3d4aa3368f27834ed87", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/resources.ts": "d209e5f13545b9c0c095ac4e188b72370d97c9bd394ba7c8793ddd74f436b1ef", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/streams.ts": "f3f3374faf54bc412954692c4df7446d711fe4b6c7712b29e2cea289fcabe5a5", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/values.ts": "ed876f9103f4a4f34e8eb475934091156bee1447f5a029ea300644b8f3ee71eb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/version.ts": "b1c589988e5fb88dce3a014846c9253399e286f12afb5fd92509c8d6090ad4bb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/boundary.ts": "3467d40646a21af853cfdf511fa1acdc9a28122c09e09dcfe124af8ce769b3d2", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/executor.ts": "5d0a5b90886a79ca7c774c8ed612d8aead1acf06433406702ce97ddcf2968be1", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/host_streams.ts": "38e4d6a89169616a18a1369dd6220cfbc11f2ec3d4f85ab10b5933eed76b36cb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/mod.ts": "a46320977ece14342bcb72c9c9e36d65a1cd09d789591d0909d7d1185264010b", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/async_builtins.ts": "526795358da8908d54a483bb47eebc43e0a1ea59e69ece94d0c6890ad0fa8784", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/context.ts": "be93b23d127ff71d5c372781f89d1c3746c5d32a44e67ebbcd91f2b0f0807e93", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/errors.ts": "9d09fc1818b4dc98b238aa69008a9110d9d305b6a8e806604f3bd48fca1eebcb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/fact_calls.ts": "c28a9e07699045800105b8f8c3eb086f5550f118b1de852de72d25814ee17068", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/mod.ts": "f9c095e561f5fbb51f70693b21f272f66241f2e8ff2e1a83cd4176bcd0104eb9", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/stream_builtins.ts": "bbc1e1ea0e4616026a46d790a68695aa70589a88b08a6275acdb525f0ab531ec", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/transcode.ts": "e3fcaeb7a60b6cbad999d9389d4bce59e305e6f54e035ba791f909e10d1f82c7", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/bridge.ts": "28cb5681d63408cca14a9e307065f50188b25aa15ebe5be159ed32dc5f96f002", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/mechanics.ts": "621eb66135f516cdb488ef6388607772175ec1ef005a70f67e86d1c31f84e4db", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/mod.ts": "672aae180ad752ce07cfd83b006d24058f3aa4952a75d9a1fd256b7f804cd46a", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/suspending.ts": "8d24327f6452cf47197e01f2b5224d03fe9270968254fcaa4e8a927ea1b19041", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/types.ts": "102430fa9386026d0429d42a5365dcc2ed557af536138328325e4cd56f8ddce0", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/plan/format.ts": "90e31bbc7137c2f80c0782e1431afb6f81827aab8d38dba1178b8761f1b3ea0a", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/plan/loader.ts": "107db77e724a7f74f161a5fd20e7110a6e6f182c46f18282eba650bc887dc876", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/plan/mod.ts": "4ad969fc0760e52650dbcd299b859e79e91c6366402c2986d75d26939c2e4abc", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/shim/mod.ts": "34af2240dfd0be720def487db2db34eaad6ba9178003f20e2193d03a0632779b", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/shim/translator.ts": "9b8c558179acbf7b467db3437be71837db44cecbcc52f45e913b210b3a059dab", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/mod.ts": "42d2a2620eba5651016a16c16f47ec0524be525e56f78dec4956c1767b4d2002", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/scheduler.ts": "b6f3ecf8a3b8e51862cc60a51907009ee3cc5ba9f21a6e4dc49d54f595c04e70", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/streams.ts": "59e3b9b5ededc2b191b8de0728b105f8459e113e1b869b7e418150aaea869029", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/subtask.ts": "750b13a1318f62836bfd149f1b9144de5b017fd7a84adc8e2fb2151e63130fbc", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/thread.ts": "9f19995d3b0cdbd491d9a8176151f1ceea1ffdd10af837777b9ed4071b99218f", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/waitable.ts": "5e1fc092e3d8f1fb4429d6a91d8886b3e474aa9ac6254e7924fd896c4929e1f9", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/tools/translate/main.ts": "d9c8d1d478378e26d1c3ef82892268447cb715cd01809c66053e9ff8fd1bb3e9", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/cli.ts": "d1617e12dc2569f4ee107f8b92488797daf431d14b8a86a1ab10750a28757394", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/clocks.ts": "1ce4e2beb07231c7e284e3feb9d6a5bb25d16627e1104d8d51a9d016d17fa457", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/filesystem.ts": "6dcead5346d78084c3923410e44875e678f3b58db0c2d59513339b428596ec25", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/io.ts": "797828af58cf820250b5d8f174a451fbe525a33f82353eac4c50ff55610d47af", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/mod.ts": "1748985cf851252e1755aafd9ebb9c7ae96003ec41322d9524a952062d2b8570", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/random.ts": "bdd9b3c87c16588a8b176b9e4fbd4f9900a78a3a3a545a5559c51272e1780647" - }, "workspace": { "dependencies": [ + "jsr:@deltic/runtime@0.1.0-pre.ga67ee83", + "jsr:@deltic/translator@0.1.0-pre.ga67ee83", + "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83", "npm:node-datachannel@0.32.3", "npm:werift@0.22.2" ], diff --git a/experiments/iroh-relay-ws/host/harness.ts b/experiments/iroh-relay-ws/host/harness.ts index 4f0adb0..1693f3d 100644 --- a/experiments/iroh-relay-ws/host/harness.ts +++ b/experiments/iroh-relay-ws/host/harness.ts @@ -14,6 +14,7 @@ import type { ComponentArtifacts } from "@deltic/runtime/embedder"; import { artifactsFromEnvelope, instantiate } from "@deltic/runtime/embedder"; +import type { Translator } from "@deltic/runtime/shim"; import { OutputStream, wasiShims } from "@deltic/wasi-shims"; import { syntheticNetImports } from "./sockets.ts"; @@ -69,13 +70,14 @@ export function guestImports(options: GuestOptions): Record { * * `artifacts` is anything `instantiate` accepts (embedder-api A3): the * translated `ComponentArtifacts`, or `{ componentBytes, translator }` - * for in-process translation. jspi mode is selected by wasi-shims' own - * `suspending()` markers (the A5 kernel); no explicit option is needed. + * with `@deltic/translator`'s instance for in-process translation. jspi + * mode is selected by wasi-shims' own `suspending()` markers (the A5 + * kernel); no explicit option is needed. */ export async function runGuest( artifacts: ComponentArtifacts | { componentBytes: Uint8Array; - translator: Uint8Array; + translator: Uint8Array | Translator; }, imports: Record, ): Promise { diff --git a/experiments/iroh-relay-ws/host/run.ts b/experiments/iroh-relay-ws/host/run.ts index ba7f210..fc57ee1 100644 --- a/experiments/iroh-relay-ws/host/run.ts +++ b/experiments/iroh-relay-ws/host/run.ts @@ -2,9 +2,10 @@ // two-endpoint relay echo + WebRTC migration. The guest prints its own // results; this driver adds a watchdog and the shim/bridge counters. // -// Runs on stock Deno: `run.sh` fetches the pinned translator shim and -// exports its path as DELTIC_TRANSLATOR. +// Runs on stock Deno; the translator is `@deltic/translator`'s packaged +// asset, loaded through the module graph. +import { defaultTranslator } from "@deltic/translator"; import { stats } from "./sockets.ts"; import { bridgeStats } from "./bridge.ts"; import { webrtcStats } from "./webrtc-bridge.ts"; @@ -23,19 +24,10 @@ const watchdog = setTimeout(() => { Deno.exit(1); }, WATCHDOG_MS); -const shimPath = Deno.env.get("DELTIC_TRANSLATOR"); -if (!shimPath) { - console.error( - "[driver] DELTIC_TRANSLATOR is unset — run this through run.sh, which " + - "fetches the pinned translator shim (host-deltic/fetch-translator.ts).", - ); - Deno.exit(2); -} - const t0 = performance.now(); const artifacts = { componentBytes: await Deno.readFile(GUEST_WASM), - translator: await Deno.readFile(shimPath), + translator: await defaultTranslator(), }; console.log(`[driver] loaded in ${(performance.now() - t0).toFixed(1)}ms`); diff --git a/experiments/iroh-relay-ws/host/translate.ts b/experiments/iroh-relay-ws/host/translate.ts new file mode 100644 index 0000000..718ce4e --- /dev/null +++ b/experiments/iroh-relay-ws/host/translate.ts @@ -0,0 +1,27 @@ +// Build-time translation (deltic embedder-api A4): component in, envelope +// out. The translator is `@deltic/translator`'s packaged asset — the same +// pinned release as the runtime, so the envelope's plan format matches +// what the pages' `artifactsFromEnvelope` expects by construction. +// +// Used by ping-demo's build.sh and the spikes' browser harnesses (their +// pages fetch component + envelope; no translator ships to a browser). +// +// deno run --allow-read --allow-write --config /deno.json \ +// translate.ts + +import { dirname } from "node:path"; +import { defaultTranslator } from "@deltic/translator"; + +const [input, output] = Deno.args; +if (!input || !output) { + console.error("usage: translate.ts "); + Deno.exit(2); +} +const translator = await defaultTranslator(); +const envelope = translator.translateRaw(await Deno.readFile(input)); +// The output dir may not exist yet: the browser harnesses write the +// envelope into gitignored dist/ BEFORE `deno bundle` (the other dist/ +// writer) runs, so on a fresh checkout this is the first creator. +await Deno.mkdir(dirname(output), { recursive: true }); +await Deno.writeTextFile(output, envelope); +console.error(`translated ${input} -> ${output} (${envelope.length} bytes)`); diff --git a/experiments/iroh-relay-ws/run.sh b/experiments/iroh-relay-ws/run.sh index 37c7b0b..3d215e0 100755 --- a/experiments/iroh-relay-ws/run.sh +++ b/experiments/iroh-relay-ws/run.sh @@ -1,9 +1,9 @@ #!/usr/bin/env bash # Runs the iroh-relay-ws spike end to end: a stock iroh-relay server (from # .deps/iroh, built by the just recipe), then the deltic host on stock -# Deno driving the wasip2 guest — runtime-linked, no transpile step. -# Reuses an already-running relay on 127.0.0.1:3340; kills only what it -# started. +# Deno driving the wasip2 guest — runtime-linked, no transpile step; the +# translator ships inside the pinned @deltic/translator package. Reuses an +# already-running relay on 127.0.0.1:3340; kills only what it started. set -euo pipefail cd "$(dirname "$0")" @@ -20,13 +20,4 @@ if ! curl -s -m 2 http://127.0.0.1:3340 >/dev/null 2>&1; then done fi -# The sha256-pinned translator shim, cached under target/deltic/ (the pin -# and the cache live with host-deltic; the deltic tag in host/deno.json -# matches it). -shim=$(deno run --config ../../host-deltic/deno.json --frozen \ - --allow-read=../.. --allow-write=../../target/deltic \ - --allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com \ - ../../host-deltic/fetch-translator.ts) - -DELTIC_TRANSLATOR="$shim" timeout 120 \ - deno run -A --config host/deno.json --frozen host/run.ts +timeout 120 deno run -A --config host/deno.json --frozen host/run.ts diff --git a/experiments/ping-demo/build.sh b/experiments/ping-demo/build.sh index b89fb02..c9d8977 100755 --- a/experiments/ping-demo/build.sh +++ b/experiments/ping-demo/build.sh @@ -17,24 +17,13 @@ GUEST_WASM=guest/target/wasm32-wasip2/release/ping-demo-guest.wasm rm -rf "$SITE" mkdir -p "$SITE" -# The sha256-pinned translator shim, cached under target/deltic/ (the pin -# and the cache live with host-deltic; the deltic tag in -# ../iroh-relay-ws/host/deno.json matches it). build.sh's cwd is -# experiments/ping-demo, two levels below repo root — see -# ../iroh-relay-ws/run.sh for the sibling invocation this mirrors. -shim=$(deno run --config ../../host-deltic/deno.json --frozen \ - --allow-read=../.. --allow-write=../../target/deltic \ - --allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com \ - ../../host-deltic/fetch-translator.ts) - # Build-time translation (deltic embedder-api A4): produces the -# component-plus-plan envelope the page fetches at runtime. The shared -# experiments config maps the CLI's @deltic/runtime/* imports at the -# repo's pinned tag; the raw URL below must carry the same tag (the pin -# gate in host-deltic/fetch-translator.ts checks it). -deno run --config "$SPIKE_HOST/deno.json" --allow-read --allow-write \ - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/tools/translate/main.ts" \ - "$GUEST_WASM" -o "$SITE/ping-demo.plan.json" --shim "$shim" +# component-plus-plan envelope the page fetches at runtime. The +# translator is @deltic/translator's packaged asset at the same pinned +# release as the runtime the bundle carries, so the envelope's plan +# format matches by construction. +deno run --config "$SPIKE_HOST/deno.json" --frozen --allow-read --allow-write \ + "$SPIKE_HOST/translate.ts" "$GUEST_WASM" "$SITE/ping-demo.plan.json" cp "$GUEST_WASM" "$SITE/ping-demo.component.wasm" diff --git a/host-deltic/README.md b/host-deltic/README.md index b1ec100..5b8fd3a 100644 --- a/host-deltic/README.md +++ b/host-deltic/README.md @@ -53,29 +53,31 @@ guest's and is latent on every host. ## The pin -deltic is pinned to ONE release tag repo-wide, cross-checked at run time -by `fetch-translator.ts`: +deltic arrives as exactly-pinned JSR prereleases: +`jsr:@deltic/{runtime,wasi-shims,translator}@0.1.0-pre.g`, +where the short hash names one upstream commit (the same hash as the +corresponding GitHub `pre-` release). `@deltic/translator` +ships the translator wasm for that same commit, so the plan-format +coupling between runtime and translator is self-consistent inside each +graph by construction — there is no separate asset pin and no fetch +step. -- `deno.json` — import-map URLs - (`raw.githubusercontent.com/lann/deltic//…`) for - `@deltic/runtime/{embedder,shim}` and `@deltic/wasi-shims`; - `deno.lock` carries integrity hashes, enforced with `--frozen`. The - sibling host modules map to their `.deps` checkouts (pinned by - `scripts/setup.sh`), and the npm mappings (`node-datachannel`, - `werift`) serve the webrtc module's bare specifiers, which resolve - against this config as the entry import map. -- `fetch-translator.ts` — `TAG` + `TRANSLATOR_SHA256` for the - `deltic-translator-shim.wasm` release asset (cached under - `target/deltic//`). -- `experiments/iroh-relay-ws/host/deno.json` — the upstream-iroh spikes' - shared config (one import map for all three experiments), plus the - translate-CLI URL in `experiments/ping-demo/build.sh`; both must carry - the same tag, and `fetch-translator.ts` refuses to run on drift. +- `deno.json` — the versions in the import map; `deno.lock` carries + integrity, enforced with `--frozen`. The sibling host modules map to + their `.deps` checkouts (pinned by `scripts/setup.sh`), and the npm + mappings (`node-datachannel`, `werift`) serve the webrtc module's + bare specifiers, which resolve against this config as the entry + import map. `minimumDependencyAge` exempts `jsr:@deltic/*` from + Deno's default 24-hour supply-chain gate so same-day prereleases + resolve; everything else keeps the default. +- `experiments/iroh-relay-ws/host/deno.json` — the upstream-iroh + spikes' shared config, same versions by repo convention; the + `exam-deltic` recipe asserts the two configs agree before running. -To bump: update the tag in all of the above and the sha256 from the -release's `SHA256SUMS`, delete both `deno.lock` files, re-run -`just deltic-setup` and `deno install --allow-scripts=npm:node-datachannel` -in `experiments/iroh-relay-ws/host/` to regenerate them, and commit the +To bump: update the versions in both configs, delete both `deno.lock` +files, re-run `just deltic-setup` and +`deno install --allow-scripts=npm:node-datachannel` in +`experiments/iroh-relay-ws/host/` to regenerate them, and commit the diff. ## Module identity diff --git a/host-deltic/deno.json b/host-deltic/deno.json index 4fc4295..7ce4d0c 100644 --- a/host-deltic/deno.json +++ b/host-deltic/deno.json @@ -1,17 +1,21 @@ { - "//": "MODULE-IDENTITY CONSTRAINT: deltic's wasi-shims and the sibling deltic host modules (.deps/{websocket,webrtc,webcrypto}) import @deltic/runtime/embedder by bare specifier internally; this file maps that specifier ONCE for the whole module graph, so `instanceof WitError` holds across every boundary. The npm mappings serve the webrtc module's bare `node-datachannel`/`werift` specifiers, which resolve against THIS config when run-endpoint.ts is the entry module.", + "//": "MODULE-IDENTITY CONSTRAINT: deltic's wasi-shims and the sibling deltic host modules (.deps/{websocket,webrtc,webcrypto}) import @deltic/runtime/embedder by bare specifier internally; this file maps that specifier ONCE for the whole module graph, so `instanceof WitError` holds across every boundary. deltic arrives as exactly-pinned JSR prereleases (0.1.0-pre.g names one upstream commit; @deltic/translator ships the translator wasm for the SAME commit, so the plan-format coupling is self-consistent per graph); deno.lock carries integrity, enforced with --frozen. The version matches experiments/iroh-relay-ws/host/deno.json by repo convention (see README.md, 'The pin'; exam-deltic asserts it). minimumDependencyAge keeps Deno's default supply-chain gate for everything else while letting same-day @deltic prereleases resolve. The npm mappings serve the webrtc module's bare specifiers, which resolve against this config as the entry import map.", "nodeModulesDir": "auto", + "minimumDependencyAge": { + "age": "P1D", + "exclude": ["jsr:@deltic/*"] + }, "imports": { - "@deltic/runtime/embedder": "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/mod.ts", - "@deltic/runtime/shim": "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/shim/mod.ts", - "@deltic/wasi-shims": "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/mod.ts", + "@deltic/runtime/embedder": "jsr:@deltic/runtime@0.1.0-pre.ga67ee83/embedder", + "@deltic/translator": "jsr:@deltic/translator@0.1.0-pre.ga67ee83", + "@deltic/wasi-shims": "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83", "@polymorph/webcrypto-deltic": "../.deps/webcrypto/js/deltic/src/mod.ts", "node-datachannel": "npm:node-datachannel@0.32.3", "node-datachannel/polyfill": "npm:node-datachannel@0.32.3/polyfill", "werift": "npm:werift@0.22.2" }, "tasks": { - "check": "deno check src fetch-translator.ts", + "check": "deno check src", "exam": "deno run -A src/run-endpoint.ts" } } diff --git a/host-deltic/deno.lock b/host-deltic/deno.lock index 9084b43..37c8f41 100644 --- a/host-deltic/deno.lock +++ b/host-deltic/deno.lock @@ -1,9 +1,30 @@ { "version": "5", "specifiers": { + "jsr:@deltic/runtime@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", + "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", + "jsr:@deltic/translator@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", + "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83": "0.1.0-pre.ga67ee83", "npm:node-datachannel@0.32.3": "0.32.3", "npm:werift@0.22.2": "0.22.2" }, + "jsr": { + "@deltic/runtime@0.1.0-pre.ga67ee83": { + "integrity": "2a2b0949031747a2340dc186299e654ea9f361ae39ac6bd633019940682db4ed" + }, + "@deltic/translator@0.1.0-pre.ga67ee83": { + "integrity": "e4f1bb219e56b62262b0c9665e3f6646aa13883b2cfbb9d6306f69d19974d412", + "dependencies": [ + "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83" + ] + }, + "@deltic/wasi-shims@0.1.0-pre.ga67ee83": { + "integrity": "a5754e65d50873e675695a51279989e22b3771e31f16a84a09feb15905c574a7", + "dependencies": [ + "jsr:@deltic/runtime@~0.1.0-pre.ga67ee83" + ] + } + }, "npm": { "@fidm/asn1@1.0.4": { "integrity": "sha512-esd1jyNvRb2HVaQGq2Gg8Z0kbQPXzV9Tq5Z14KNIov6KfFD6PTaRIO8UpcsYiTNzOqJpmyzWgVTrUwFV3UF4TQ==" @@ -618,67 +639,13 @@ "https://raw.githubusercontent.com/lann/deltic/pre-58b2404/runtime/src/task/streams.ts": "83b522a6393ba06fbdb87881bc6761f3fce9c03b85e9eda03d3befe7d2605a60", "https://raw.githubusercontent.com/lann/deltic/pre-58b2404/runtime/src/task/subtask.ts": "750b13a1318f62836bfd149f1b9144de5b017fd7a84adc8e2fb2151e63130fbc", "https://raw.githubusercontent.com/lann/deltic/pre-58b2404/runtime/src/task/thread.ts": "81fe38b37a1ec130803b478a24e428b19ee4e1ef8c0bae741395cd8d52751580", - "https://raw.githubusercontent.com/lann/deltic/pre-58b2404/runtime/src/task/waitable.ts": "5e1fc092e3d8f1fb4429d6a91d8886b3e474aa9ac6254e7924fd896c4929e1f9", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/async_values.ts": "af1279d4e4db5b756268979aeff5b27c1cf6c0f021213655676ade90472f282b", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/context.ts": "b4b60891ef9d9e72b208636f6ba37f0b9b6962d307af6156ad3b5ad59a626902", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/flatten.ts": "6c980fe38d7adce349d5e028b819eb0ffbb92714f958c1d5daae8da3e7ed3889", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/float.ts": "0483e8c1aa8786eee4c6f6357fee6738555e4310650c474aba6cd811a80d7d36", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/handles.ts": "30510750261499f48a812bb8c349a8f88a3bb7239175e6f1d4e6d10c38571e5d", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/layout.ts": "8122141b39f4d8189c13d91fc1b37825ceead86988f879f3fa9351bbef96f8f2", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/lift.ts": "e4475a44a5618114f288025601b535bc04b97e9a37b3be21f51d3be092d419c8", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/load.ts": "c1d8ddb1b3b3c59afe30710a97ad6dd7ae1ecd59aa1d427a5eaf4552d3b1ea01", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/lower.ts": "916ef7476dc583783770f4c42de7a655350531b3763c81a92249cca96f5e4d80", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/memory.ts": "09728360d6413fb30a5a7bff1ba6abec1ac6474ff150d45f093b8ebe5e65cd51", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/mod.ts": "b79cf9e2bab2e837fee76fa61dc18bff66d941e08597f1b76de93811bd6d6008", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/store.ts": "ab3c1475ddce5aef1c7feb77933c19b48ab8bd54634c22a5397c9e734cfd5183", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/strings.ts": "9589dda3857725792ae15ef6888449b48e973b9eb0f3058ed64e10bf4d39b793", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/trap.ts": "307d8b48806eeba30400b3d7db9370cee70a12298851c1c19053dd8ca0013e1c", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/types.ts": "d0392e8cdf2990a76c8a1f9b85795d3b7c19b8eb006c2b159b671d08c39b9535", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/cabi/values.ts": "9e6ddcc4192d05897b2cbea250db3fef0ad9bf6548ba87aff378ee14b7ab7022", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/casing.ts": "1e9083becfc08107c09015ce3db79c304b05c40085a3c899ea1c8ebe25fcd45f", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/errors.ts": "fe1b220c22facf37948d444f97d7c8083da41c8496e6ce23b27c820ca0c2c7d7", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/imports.ts": "98cca003e4a1131c35854c91b458f109d6761a3e8f67c23730f7e9bc28bbad88", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/instantiate.ts": "1c50c17d72bca15738b161b99aa5c406ce87486110b50d09f116aa49a05c215c", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/mod.ts": "3d0be7e5d2fc784725c7ec5ddb1add5120c4f7a2c39be3d4aa3368f27834ed87", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/resources.ts": "d209e5f13545b9c0c095ac4e188b72370d97c9bd394ba7c8793ddd74f436b1ef", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/streams.ts": "f3f3374faf54bc412954692c4df7446d711fe4b6c7712b29e2cea289fcabe5a5", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/values.ts": "ed876f9103f4a4f34e8eb475934091156bee1447f5a029ea300644b8f3ee71eb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/embedder/version.ts": "b1c589988e5fb88dce3a014846c9253399e286f12afb5fd92509c8d6090ad4bb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/boundary.ts": "3467d40646a21af853cfdf511fa1acdc9a28122c09e09dcfe124af8ce769b3d2", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/executor.ts": "5d0a5b90886a79ca7c774c8ed612d8aead1acf06433406702ce97ddcf2968be1", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/host_streams.ts": "38e4d6a89169616a18a1369dd6220cfbc11f2ec3d4f85ab10b5933eed76b36cb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/exec/mod.ts": "a46320977ece14342bcb72c9c9e36d65a1cd09d789591d0909d7d1185264010b", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/async_builtins.ts": "526795358da8908d54a483bb47eebc43e0a1ea59e69ece94d0c6890ad0fa8784", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/context.ts": "be93b23d127ff71d5c372781f89d1c3746c5d32a44e67ebbcd91f2b0f0807e93", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/errors.ts": "9d09fc1818b4dc98b238aa69008a9110d9d305b6a8e806604f3bd48fca1eebcb", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/fact_calls.ts": "c28a9e07699045800105b8f8c3eb086f5550f118b1de852de72d25814ee17068", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/mod.ts": "f9c095e561f5fbb51f70693b21f272f66241f2e8ff2e1a83cd4176bcd0104eb9", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/stream_builtins.ts": "bbc1e1ea0e4616026a46d790a68695aa70589a88b08a6275acdb525f0ab531ec", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/intrinsics/transcode.ts": "e3fcaeb7a60b6cbad999d9389d4bce59e305e6f54e035ba791f909e10d1f82c7", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/bridge.ts": "28cb5681d63408cca14a9e307065f50188b25aa15ebe5be159ed32dc5f96f002", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/mechanics.ts": "621eb66135f516cdb488ef6388607772175ec1ef005a70f67e86d1c31f84e4db", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/mod.ts": "672aae180ad752ce07cfd83b006d24058f3aa4952a75d9a1fd256b7f804cd46a", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/suspending.ts": "8d24327f6452cf47197e01f2b5224d03fe9270968254fcaa4e8a927ea1b19041", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/jspi/types.ts": "102430fa9386026d0429d42a5365dcc2ed557af536138328325e4cd56f8ddce0", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/plan/format.ts": "90e31bbc7137c2f80c0782e1431afb6f81827aab8d38dba1178b8761f1b3ea0a", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/plan/loader.ts": "107db77e724a7f74f161a5fd20e7110a6e6f182c46f18282eba650bc887dc876", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/shim/mod.ts": "34af2240dfd0be720def487db2db34eaad6ba9178003f20e2193d03a0632779b", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/shim/translator.ts": "9b8c558179acbf7b467db3437be71837db44cecbcc52f45e913b210b3a059dab", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/mod.ts": "42d2a2620eba5651016a16c16f47ec0524be525e56f78dec4956c1767b4d2002", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/scheduler.ts": "b6f3ecf8a3b8e51862cc60a51907009ee3cc5ba9f21a6e4dc49d54f595c04e70", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/streams.ts": "59e3b9b5ededc2b191b8de0728b105f8459e113e1b869b7e418150aaea869029", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/subtask.ts": "750b13a1318f62836bfd149f1b9144de5b017fd7a84adc8e2fb2151e63130fbc", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/thread.ts": "9f19995d3b0cdbd491d9a8176151f1ceea1ffdd10af837777b9ed4071b99218f", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/runtime/src/task/waitable.ts": "5e1fc092e3d8f1fb4429d6a91d8886b3e474aa9ac6254e7924fd896c4929e1f9", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/cli.ts": "d1617e12dc2569f4ee107f8b92488797daf431d14b8a86a1ab10750a28757394", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/clocks.ts": "1ce4e2beb07231c7e284e3feb9d6a5bb25d16627e1104d8d51a9d016d17fa457", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/filesystem.ts": "6dcead5346d78084c3923410e44875e678f3b58db0c2d59513339b428596ec25", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/io.ts": "797828af58cf820250b5d8f174a451fbe525a33f82353eac4c50ff55610d47af", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/mod.ts": "1748985cf851252e1755aafd9ebb9c7ae96003ec41322d9524a952062d2b8570", - "https://raw.githubusercontent.com/lann/deltic/pre-a67ee83/wasi-shims/src/random.ts": "bdd9b3c87c16588a8b176b9e4fbd4f9900a78a3a3a545a5559c51272e1780647" + "https://raw.githubusercontent.com/lann/deltic/pre-58b2404/runtime/src/task/waitable.ts": "5e1fc092e3d8f1fb4429d6a91d8886b3e474aa9ac6254e7924fd896c4929e1f9" }, "workspace": { "dependencies": [ + "jsr:@deltic/runtime@0.1.0-pre.ga67ee83", + "jsr:@deltic/translator@0.1.0-pre.ga67ee83", + "jsr:@deltic/wasi-shims@0.1.0-pre.ga67ee83", "npm:node-datachannel@0.32.3", "npm:werift@0.22.2" ], diff --git a/host-deltic/fetch-translator.ts b/host-deltic/fetch-translator.ts deleted file mode 100644 index db4d241..0000000 --- a/host-deltic/fetch-translator.ts +++ /dev/null @@ -1,101 +0,0 @@ -// Fetch (and cache) the deltic translator-shim wasm for the pinned release. -// -// deltic is a runtime linker: components are translated by a wasm build of -// its translator, shipped as a release asset so consumers need no extra -// Rust build. This script downloads that asset once into target/deltic/, -// verifies it against the pinned sha256, and prints the cached path on -// stdout (the `exam-deltic` recipe captures it and exports it as -// `DELTIC_TRANSLATOR`). -// -// THE PIN lives here (TAG + TRANSLATOR_SHA256) and in the sibling -// deno.json's import-map URLs. `assertPinConsistency` checks the latter -// against TAG and fails loud on drift. -// -// Bumping: update TAG here and in deno.json, update TRANSLATOR_SHA256 from -// the release's SHA256SUMS, delete deno.lock, and re-run -// `deno install --allow-scripts=npm:node-datachannel` in this directory to -// regenerate it (commit the diff). - -const TAG = "pre-a67ee83"; -const TRANSLATOR_SHA256 = - "2a2c9bbd3dfc009f301bdce9101116b237593bd8e17a06f412b000e2d4d4c220"; -const ASSET = "deltic-translator-shim.wasm"; - -const HERE = new URL(".", import.meta.url); -const REPO_ROOT = new URL("../", HERE); -const CACHE_DIR = new URL(`target/deltic/${TAG}/`, REPO_ROOT); -const CACHED = new URL(ASSET, CACHE_DIR); -const RELEASE_URL = - `https://github.com/lann/deltic/releases/download/${TAG}/${ASSET}`; - -async function sha256Hex(bytes: Uint8Array): Promise { - const digest = await crypto.subtle.digest( - "SHA-256", - bytes as BufferSource, - ); - return Array.from(new Uint8Array(digest)) - .map((b) => b.toString(16).padStart(2, "0")) - .join(""); -} - -/** The one-pin-everywhere gate: every raw.githubusercontent deltic URL in - * the sibling import map — and in the experiments' shared config and the - * ping demo's build-time translate step, which ride the same release — - * must reference TAG. */ -async function assertPinConsistency(): Promise { - const pinned = [ - new URL("deno.json", HERE), - new URL("../experiments/iroh-relay-ws/host/deno.json", HERE), - new URL("../experiments/ping-demo/build.sh", HERE), - ]; - for (const fileUrl of pinned) { - const text = await Deno.readTextFile(fileUrl); - const urls = text.match( - /https:\/\/raw\.githubusercontent\.com\/lann\/deltic[^"\s]+/g, - ) ?? []; - if (fileUrl.pathname.endsWith("deno.json") && urls.length === 0) { - throw new Error(`${fileUrl.pathname}: no pinned deltic URLs found`); - } - for (const url of urls) { - if (!url.includes(`/lann/deltic/${TAG}/`)) { - throw new Error( - `pin drift: ${fileUrl.pathname} pins ${url}\n` + - `but fetch-translator.ts pins ${TAG}`, - ); - } - } - } -} - -async function main() { - await assertPinConsistency(); - - try { - const cached = await Deno.readFile(CACHED); - if (await sha256Hex(cached) === TRANSLATOR_SHA256) { - console.log(CACHED.pathname); - return; - } - console.error(`cached ${ASSET} has a stale digest; re-fetching`); - } catch { - // not cached yet - } - - console.error(`fetching ${RELEASE_URL} …`); - const resp = await fetch(RELEASE_URL); - if (!resp.ok) { - throw new Error(`GET ${RELEASE_URL}: ${resp.status} ${resp.statusText}`); - } - const bytes = new Uint8Array(await resp.arrayBuffer()); - const got = await sha256Hex(bytes); - if (got !== TRANSLATOR_SHA256) { - throw new Error( - `sha256 mismatch for ${ASSET}@${TAG}:\n want ${TRANSLATOR_SHA256}\n got ${got}`, - ); - } - await Deno.mkdir(CACHE_DIR, { recursive: true }); - await Deno.writeFile(CACHED, bytes); - console.log(CACHED.pathname); -} - -await main(); diff --git a/host-deltic/src/harness.ts b/host-deltic/src/harness.ts index 9c34d27..236e9e7 100644 --- a/host-deltic/src/harness.ts +++ b/host-deltic/src/harness.ts @@ -12,7 +12,7 @@ // graph, so there is exactly one `WitError`/`Stream` module instance and // `instanceof` holds across every boundary. -import { Translator } from "@deltic/runtime/shim"; +import { defaultTranslator } from "@deltic/translator"; import type { ComponentArtifacts } from "@deltic/runtime/embedder"; import { instantiate, WitError } from "@deltic/runtime/embedder"; import { wasiShims } from "@deltic/wasi-shims"; @@ -62,20 +62,13 @@ async function exists(path: string): Promise { * across every `instantiate` in the run: two endpoint *instances* are two * separate component instances over the same immutable artifacts. * - * The translator shim arrives through `DELTIC_TRANSLATOR`; the - * `exam-deltic` justfile recipe fetches the sha256-pinned release asset - * with `fetch-translator.ts` and exports the path. + * The translator is `@deltic/translator`'s packaged asset — the same + * pinned release as the runtime, loaded through the module graph + * (permission-free on Deno), so there is no fetch step and no + * plan-format skew to guard against. */ export async function loadArtifacts(): Promise { if (cachedArtifacts) return cachedArtifacts; - const shim = Deno.env.get("DELTIC_TRANSLATOR"); - if (!shim) { - throw new Error( - "DELTIC_TRANSLATOR is unset — fetch the pinned translator shim with " + - "host-deltic/fetch-translator.ts and export its path (the " + - "`just exam-deltic` recipe does both).", - ); - } if (!await exists(ENDPOINT_WASM)) { throw new Error( `endpoint component not found at ${ENDPOINT_WASM} — build it with ` + @@ -83,7 +76,7 @@ export async function loadArtifacts(): Promise { ); } const bytes = await Deno.readFile(ENDPOINT_WASM); - const translator = await Translator.create(await Deno.readFile(shim)); + const translator = await defaultTranslator(); const { plan, adapters } = translator.translate(bytes); cachedArtifacts = { plan, componentBytes: bytes, adapters }; return cachedArtifacts; diff --git a/justfile b/justfile index 558b7ef..707c28e 100644 --- a/justfile +++ b/justfile @@ -69,11 +69,19 @@ deltic-setup: exam-deltic: build-components relay-build deltic-setup #!/usr/bin/env bash set -euo pipefail - shim=$(deno run --config host-deltic/deno.json --frozen \ - --allow-read=. --allow-write=target/deltic \ - --allow-net=github.com,objects.githubusercontent.com,release-assets.githubusercontent.com \ - host-deltic/fetch-translator.ts) - DELTIC_TRANSLATOR="$shim" timeout 600 deno run -A --config host-deltic/deno.json --frozen \ + # One deltic version repo-wide (host-deltic/README.md "The pin"): the + # exam is the natural fail-loud point, replacing the retired + # fetch-translator gate. Every jsr:@deltic/* pin in both configs must + # name the SAME prerelease — a translator/runtime split is exactly the + # plan-format skew (or double-runtime WitError identity break) the + # packaged translator exists to rule out. + v=$(grep -ho 'jsr:@deltic/[a-z-]*@[^/"]*' host-deltic/deno.json \ + experiments/iroh-relay-ws/host/deno.json | sed 's/.*@//' | sort -u) + if [ "$(printf '%s\n' "$v" | wc -l)" != 1 ]; then + echo "deltic pin drift across deno.jsons: $v" >&2 + exit 1 + fi + timeout 600 deno run -A --config host-deltic/deno.json --frozen \ host-deltic/src/run-endpoint.ts # The measured-claims gate: per-wire latency/throughput medians,