Skip to content

feat(site): make the explorer an installable offline app - #37

Merged
Mearman merged 4 commits into
mainfrom
feat/site-pwa
Oct 30, 2026
Merged

Mearman merged 4 commits into
mainfrom
feat/site-pwa

Conversation

@Mearman

@Mearman Mearman commented Oct 30, 2026 •

Copy link
Copy Markdown
Member

Makes the explorer installable and usable offline, shows which release or commit the page was built from, and prompts when a newer build is available. Everything is in the site scope, so this releases nothing.

The service worker comes from vite-plugin-pwa (generateSW, prompt mode), with icons produced from one SVG at build time. Nothing generated is committed. The page registers the worker itself through workbox-window, so the update prompt is ordinary markup and the update logic is a small function over a worker, a view and the page, unit-tested with fakes. A waiting build is only activated when the user presses Update, then the page reloads; the model lives in the address bar, so the reload keeps it. The page checks for a newer build each time it becomes visible again.

The footer link uses @exadev/build-identity, as the other apps do: a release if a release tag is on the built commit, the predicted version (linking to the commit) if the commit will release, otherwise the short hash. The prediction needed the site scope rule passed through, which build-identity now accepts (ExaDev/build-identity#14, released as 3.1.0). Reading the history needs tags, so the Browser and Pages jobs check out with full depth.

A deploy of the commit that triggers a release runs before its tag exists, so it can only show the commit. The release job now records whether it cut a release, and a new redeploy-site job, run only then, starts the Pages workflow again from the tagged commit. I used a dispatch from the workflow rather than a tag trigger because the release commit is [skip ci], which also skips workflows triggered by pushing its tag.

The browser tests serve the built site from a small server of their own and stop it to go offline, because Playwright's setOffline makes navigations fail before the service worker can answer them. They cover the manifest and icons, the footer link, opening, counting and opening a share link with no network, the gist failure message, and the update prompt (the served worker script changes between loads, as a new deployment would). I checked that each test can fail: not registering the worker fails 5, listing the manifest twice in the precache fails 3 (that one makes Workbox throw while setting up, so the worker installs and caches nothing), and not activating the waiting worker fails the update test.

The Browser job fetched its base commit at depth one, which made its full checkout shallow again and broke the site build, so that fetch now takes the commit whole. The Typecheck job also built the site, a second build of the same sources that the Browser job makes on any change that could break it, so I removed that one and added release.config.ts (the rules the label is predicted from) to the Browser job's trigger. Pages gets full depth too.

…lease

The explorer's footer names the release or the commit it was built
from, and the version a commit will release as is read from the
history since the last release tag, so the Browser and Pages jobs
check out every commit and tag.

A deploy of the commit that triggers a release runs before its tag
exists and shows the commit. The release job now records whether it
cut a release, and a job started only by that starts the Pages
workflow again from the tagged commit.
The explorer has a web app manifest and install icons made from one
SVG at build time, and a service worker that precaches the built site,
the engine worker's chunk included, so every operation, a saved model
and a share link work with no network. A gist load says it cannot be
reached instead of failing silently.

A newer build is installed in the background and offered in a prompt;
only the user's choice lets it take over and reloads the page, which
keeps its model in the address bar. The page looks for a newer build
each time it becomes visible again.

The footer links to the release the page was built from, to the commit
it will release from when it is not one yet, or to the commit.
The Browser job fetched its base commit at depth one, which made the
full checkout shallow again, so the site build could not read the last
release tag. It now fetches the commit whole.

The Typecheck job built the site as well, a second build of the same
sources that the Browser job already makes on any change that could
break it, and it too lacked the history. The Browser job's trigger now
also covers the release rules the version label is predicted from.
@Mearman
Mearman marked this pull request as ready for review October 30, 2026 04:54
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
🔒 Security Review ⚠️ Failed 2026-10-30T04:54:54.862839Z
We couldn’t complete this review. Comment @codex security review to try again.
e0039c8 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector

Copy link
Copy Markdown

This security review couldn’t start because the paying account has exhausted its Codex allowance and has insufficient available credits. The payer can check their balance and add credits in the Codex usage dashboard, then try again. If you do not manage the paying account, contact this repository's admins.

@Mearman
Mearman merged commit 7bc9261 into main Oct 30, 2026
12 checks passed
@Mearman
Mearman deleted the feat/site-pwa branch October 30, 2026 04:55
@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.1.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant