Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,18 @@ jobs:
# default job-id key component (and the `key` input): without
# it this job looked up "...-e2e-..." while Pages saved
# "...-build-...", so every E2E run was a cold cargo build.
shared-key: demo-${{ hashFiles('scripts/setup.sh', '**/rust-toolchain.toml') }}
#
# The key hashes ONLY the toolchain file of a cached workspace.
# It used to glob `**/rust-toolchain.toml`, which also matched
# every spikes/*/rust-toolchain.toml — none of which this job
# builds — so an edit to a spike's toolchain threw away the
# demo's cache. That is what happened at #143: every E2E run
# after it built the engine composite cold, and the suite went
# from ~20 consecutive first-attempt passes to one pass in seven
# attempts (browser-process crashes and store/sync timeouts, the
# shape of a runner under load). The spike workspaces the Pages
# job additionally caches carry no toolchain file of their own.
shared-key: demo-${{ hashFiles('scripts/setup.sh', 'engine/rust-toolchain.toml') }}
# Never saves: the Pages workflow builds the same workspaces on
# main and owns the entry; this job only restores it.
save-if: false
Expand Down
28 changes: 24 additions & 4 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ jobs:
examples/todomvc/guest
providers/s3/panel
providers/dropbox/panel
spikes/todomvc/guest
spikes/todomvc/guest-dioxus
spikes/todomvc/lab
# No registry pruning: the sibling workspace sits outside the
# repo, and its deps must survive the post-job save.
cache-all-crates: true
Expand All @@ -84,9 +87,14 @@ jobs:
# cold cargo build every time.
#
# Sibling pins and tool versions live in setup.sh, the pinned
# compilers in rust-toolchain.toml; bumping either must rotate
# the key or stale target dirs get restored forever.
shared-key: demo-${{ hashFiles('scripts/setup.sh', '**/rust-toolchain.toml') }}
# compiler in engine/rust-toolchain.toml; bumping either must
# rotate the key or stale target dirs get restored forever.
# ONLY engine's toolchain file, not `**/rust-toolchain.toml`:
# the glob also matched every spike's, and a spike toolchain edit
# (#143) rotated the demo's cache for nothing — see e2e.yml's
# note on what that did to the suite. The spike workspaces listed
# above carry no toolchain file of their own.
shared-key: demo-${{ hashFiles('scripts/setup.sh', 'engine/rust-toolchain.toml') }}
# Save only on main: PR jobs restore but never save, so PR
# branches don't churn the cache entries every run depends on.
save-if: ${{ github.ref == 'refs/heads/main' }}
Expand All @@ -107,14 +115,26 @@ jobs:
working-directory: demo
run: just pages

- name: Build the TodoMVC spike
# Writes into ../../docs/spike-todomvc (spikes/todomvc/justfile's
# `out`) — gitignored, generated fresh here same as docs/demo.
working-directory: spikes/todomvc
run: just build

- name: Assemble the site
# docs/ is the site root: docs/index.html is the only committed
# build; docs/demo is the one this workflow rebuilds.
# build; docs/demo and docs/spike-todomvc are the two this
# workflow rebuilds.
run: |
test -f docs/demo/engine.component.wasm
test -f docs/demo/panel-dropbox.component.wasm
test -f docs/demo/solo.html
test -f docs/demo/solo-worker.js
test -f docs/spike-todomvc/index.html
test -f docs/spike-todomvc/frame-dioxus.html
test -f docs/spike-todomvc/frame.js
test -f docs/spike-todomvc/todomvc-dioxus.component.wasm
test -f docs/spike-todomvc/todomvc-dioxus.plan.json
test -f docs/index.html
du -sh docs

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/soak.yml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ jobs:
# MUST MATCH pages.yml and e2e.yml exactly — see e2e.yml's
# comment on this key: the Pages build owns the entry and
# everyone else restores it.
shared-key: demo-${{ hashFiles('scripts/setup.sh', '**/rust-toolchain.toml') }}
shared-key: demo-${{ hashFiles('scripts/setup.sh', 'engine/rust-toolchain.toml') }}
save-if: false

- name: Set up tools and the endpoint component
Expand Down
59 changes: 59 additions & 0 deletions scripts/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,15 @@ JUST_VERSION="${JUST_VERSION:-1.54.0}"
WEBRTC_REPO=https://github.com/polymorph-components/polymorph-webrtc-datachannels.git
WEBRTC_PIN=db187f4b7d9d72bdc673ddb91c3170f0d9c7e325 # v0.5.0 — A22-clean: no runtime pin of its own, couples to @polyengine/protocol; the 0.5.1 bump needs it

# spikes/todomvc's guest-dioxus is `polyengine-dioxus = { path =
# "../../../../polyengine-dioxus" }` (see that Cargo.toml's comment) — a
# sibling PATH dependency, not a git rev, because the spike builds against
# the sibling's own crate source directly (mirrors spikes/visor-dioxus's
# identical arrangement). The pin below is the commit the spike's guest and
# deno.json (@deltic/* import map) were last verified against.
DIOXUS_REPO=https://github.com/lannbot/polyengine-dioxus.git
DIOXUS_PIN=fdc0d52adef7a301aa38030ab49b12af3284fb33 # spikes/todomvc's guest-dioxus + translate step

log() { printf '\n==> %s\n' "$1"; }

pin_repo() { # url pin dir
Expand All @@ -64,6 +73,33 @@ pin_repo() { # url pin dir

mkdir -p "$SIBLINGS_DIR"
pin_repo "$WEBRTC_REPO" "$WEBRTC_PIN" "$SIBLINGS_DIR/polymorph-webrtc-datachannels"
pin_repo "$DIOXUS_REPO" "$DIOXUS_PIN" "$SIBLINGS_DIR/polyengine-dioxus"

# The sibling has its own sibling: `.deps/polyengine` (the runtime +
# translator spikes/todomvc's deno.json and justfile build-time-translate
# step both reach through, per its README/`just deps`). Cloned here (blob-
# less, same as the pins above); the cargo build of its translator shim is
# cargo work and belongs in the tools phase below, past the
# SIBLINGS_ONLY gate. POLYENGINE_REV is read from the pinned sibling's own
# justfile rather than duplicated here, so bumping the sibling pin above
# carries its polyengine pin forward automatically.
DIOXUS_DIR="$SIBLINGS_DIR/polyengine-dioxus"
POLYENGINE_REPO=https://github.com/polymorph-components/polyengine.git
POLYENGINE_REV="$(sed -n 's/^POLYENGINE_REV := "\(.*\)"$/\1/p' "$DIOXUS_DIR/justfile")"
if [ -z "$POLYENGINE_REV" ]; then
echo "setup: could not read POLYENGINE_REV from $DIOXUS_DIR/justfile" >&2
exit 1
fi
if [ ! -d "$DIOXUS_DIR/.deps/polyengine/.git" ]; then
log "Cloning polyengine-dioxus's polyengine dependency"
mkdir -p "$DIOXUS_DIR/.deps"
git clone --filter=blob:none "$POLYENGINE_REPO" "$DIOXUS_DIR/.deps/polyengine"
fi
if ! git -C "$DIOXUS_DIR/.deps/polyengine" cat-file -e "$POLYENGINE_REV^{commit}" 2>/dev/null; then
git -C "$DIOXUS_DIR/.deps/polyengine" fetch --filter=blob:none origin
fi
log "Pinning polyengine-dioxus's polyengine at ${POLYENGINE_REV}"
git -C "$DIOXUS_DIR/.deps/polyengine" checkout --quiet --detach "$POLYENGINE_REV"

if [ "${SIBLINGS_ONLY:-0}" = "1" ]; then
log "Siblings pinned (SIBLINGS_ONLY=1); stopping before tools and builds"
Expand Down Expand Up @@ -188,6 +224,29 @@ EOF
else
binstall "wac-cli@${WAC_VERSION}"
fi

# The translator shim spikes/todomvc's build-time translate step needs
# (deno.json's @deltic/translator resolves into this same checkout).
# Cargo work, so it lives here rather than in the siblings phase above;
# mirrors polyengine-dioxus/justfile's `deps` recipe exactly (same env,
# same target, same output path) so a future upstream change is a diff
# against that recipe, not a divergent reimplementation. wasm32-unknown-
# unknown was already added above; polyengine carries no rust-toolchain
# of its own, so the shim builds with whatever toolchain is active here.
SHIM="$SIBLINGS_DIR/polyengine-dioxus/.deps/polyengine/translator/translator_shim.wasm"
log "Ensuring polyengine-dioxus's translator shim is built"
if [ -f "$SHIM" ]; then
echo "translator_shim.wasm already present: $SHIM"
else
(cd "$SIBLINGS_DIR/polyengine-dioxus/.deps/polyengine" && \
CARGO_PROFILE_RELEASE_OPT_LEVEL=z \
CARGO_PROFILE_RELEASE_LTO=fat \
CARGO_PROFILE_RELEASE_CODEGEN_UNITS=1 \
CARGO_PROFILE_RELEASE_PANIC=abort \
CARGO_PROFILE_RELEASE_STRIP=symbols \
cargo build -p translator-shim --target wasm32-unknown-unknown --release && \
cp target/wasm32-unknown-unknown/release/translator_shim.wasm translator/translator_shim.wasm)
fi
fi

log "Setup complete. Siblings in $SIBLINGS_DIR"
15 changes: 10 additions & 5 deletions spikes/todomvc/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,20 @@ conversion-checkpoint artifact for [#16] (app execution model: no app JS),
under the shape rules of [#15], running on [deltic].

**Live demo (mobile-friendly):**
https://polymorph-components.github.io/polymorph-apps/spike-todomvc/
https://polymorph-components.github.io/polyvisor/spike-todomvc/
([`?guest=dioxus`](https://polymorph-components.github.io/polyvisor/spike-todomvc/?guest=dioxus)
for the re-targeted dioxus guest; its sandboxed frame document is served
standalone at
[`frame-dioxus.html`](https://polymorph-components.github.io/polyvisor/spike-todomvc/frame-dioxus.html)).

**Scope.** Validates the wasm→DOM plumbing only: the WIT surface, the
validated op protocol, and the event-record path. The permission linker and
asset pipeline are deliberately left as seams; the worker/frame split is no
longer one (both surfaces mount into a real sandboxed frame). Quarantined
and delete-at-will, but no longer gate-less: see [Gates](#gates), two
Playwright suites, both green. The built demo is committed at
`docs/spike-todomvc/` (the repo's Pages root).
Playwright suites, both green. The site is built by `.github/workflows/
pages.yml` on every push to `main` (`cd spikes/todomvc && just build`,
same as `docs/demo`) — nothing under `docs/spike-todomvc/` is committed.

[#16]: https://github.com/polymorph-components/polyvisor/issues/16
[#15]: https://github.com/polymorph-components/polyvisor/issues/15
Expand Down Expand Up @@ -84,7 +89,7 @@ Phase C). **These four are the `polyvisor:surface` guests' backends only**
— the dioxus guest is a different world with one transport; see
[Two surfaces, four guests](#two-surfaces-four-guests).

**The equivalence harness** ([harness.html](https://polymorph-components.github.io/polymorph-apps/spike-todomvc/harness.html))
**The equivalence harness** ([harness.html](https://polymorph-components.github.io/polyvisor/spike-todomvc/harness.html))
makes "semantically equivalent" a checked property: the same guests run the
same scripts on every backend — 15 TodoMVC steps (synthetic event records
plus real DOM clicks) with full-DOM serialization compared stepwise
Expand All @@ -107,7 +112,7 @@ renders the same app — is covered by the demo spike's e2e suite
(`spikes/demo/e2e`'s `frameProbe` and boot scenarios), not by this
same-realm harness.

**The churn bench** ([bench.html](https://polymorph-components.github.io/polymorph-apps/spike-todomvc/bench.html),
**The churn bench** ([bench.html](https://polymorph-components.github.io/polyvisor/spike-todomvc/bench.html),
`?n=` rows; li+span per row ≈ 6 surface calls) — Chromium, aarch64 linux,
2026-08-16, n=5000 (30k surface calls in one invocation):

Expand Down
2 changes: 1 addition & 1 deletion spikes/todomvc/justfile
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ guests:
cd guest && cargo build --release --target wasm32-unknown-unknown
cd lab && cargo build --release --target wasm32-unknown-unknown
cd guest-dioxus && cargo build --release --target wasm32-wasip2
cd guest-preact && npm run build
cd guest-preact && npm ci && npm run build

# Report the dioxus component's size, raw and gzipped (README's table).
size:
Expand Down
Loading