Skip to content

Adopt @statewalker/webrun-http-browser 0.5.0; mountEdge relies on its uncontrolled-page recovery - #6

Merged
mkotelnikov merged 2 commits into
mainfrom
chore/http-browser-0.5
Sep 18, 2026
Merged

mkotelnikov merged 2 commits into
mainfrom
chore/http-browser-0.5

Conversation

@mkotelnikov

Copy link
Copy Markdown
Contributor

What

  • Bump @statewalker/webrun-http-browser to ^0.5.0 (webrun-wire feat!: the membership token travels in x-httpeers-token, never Authorization #9, merge 485ad21) in httpeers-member (peer + dev), httpeers-browser-conformance, demos and llm-chat. A caret on 0.x pins the minor, so ^0.4.x would never have picked it up. The standalone lockfile changes only those edges.
  • mountEdge relies on the library. 0.5's SwHttpAdapter.start() sends a CLAIM request that the stock sw-worker (every app's /sw.js) answers with clients.claim(), bounds every wait by timeout, and rejects with ServiceWorkerControlError. So the page-side pre-check and reload guard from fix(member): mountEdge recovers a page its ServiceWorker does not control (hard reload hang) #5 go; a hard-reloaded page is now taken over in place, with no navigation.
  • edge-control.ts is now just edgeStartError: ServiceWorkerControlError (matched on name/reason, since every bundle carries its own copy of the class) → UncontrolledPageError ("close the tab and reopen it") for uncontrolled, the existing actionable Error for activation-timeout / unresponsive, anything else unchanged. The library error is kept as cause.
  • reloadIfUncontrolled: true stays, as the last resort. It covers a worker that does not answer CLAIM: a pre-0.5 /sw.js still installed in a returning visitor's browser, or a custom serviceWorkerUrl. It costs nothing when the claim works, and the library guards it with sessionStorage so it can't loop. The catch is that such a worker keeps the page waiting for the whole controlTimeoutMs (30 s) before the reload.
  • Public exports (mountEdge, UncontrolledPageError, DEFAULT_CONTROL_TIMEOUT_MS, controlTimeoutMs) are unchanged.
  • No demos asset workaround exists on main (it lives only in unmerged Session origins: {name}.p.httpeers.net shell, demo, infra #3), so there is nothing to remove. The apps copy webrun-http-browser/sw-worker to sw.js at build time, so a rebuild ships the CLAIM handler.

Tests

  • Standalone, as CI runs it: pnpm install --frozen-lockfile, lint:check, build, typecheck and test all pass (member 116, llm-chat 119, hub 125, access 185, …).
  • In the llm-chat assembly (webrun-wire at main, every webrun-http-browser edge link:): the same suite passes.
  • test:reload (Playwright, Chromium + Firefox), both linked and against the published 0.5.0 tarball:
    • first visit, normal reload, and a second tab (plus the first tab after it) all pass;
    • hard reload recovers in place: controlledAtLoad=false, one load, 1 navigation;
    • on a second origin whose worker ignores CLAIM: a hard reload does the one fallback reload (2 loads, 2 navigations, controlled). With the guard already spent it shows "close the tab and reopen it", with no reload. The normal reload after that recovers.
  • test:browser: 11/11 (Chromium).

🤖 Generated with Claude Code

mkotelnikov and others added 2 commits September 18, 2026 17:14
A caret on 0.x pins the minor, so ^0.4.x would never pick up 0.5.0. Moves
httpeers-member (peer and dev), httpeers-browser-conformance, demos and
llm-chat to ^0.5.0; the standalone lockfile changes only those edges.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… page

0.5's SwHttpAdapter.start() asks an active worker to claim an uncontrolled
page (CLAIM, answered by the stock sw-worker every app ships as /sw.js),
bounds every wait by `timeout`, and can reload once, guarded, when the
claim does not take. mountEdge now relies on that instead of its own
pre-check and reload guard: a hard reload recovers in place, with no
navigation.

- edge-control.ts shrinks to edgeStartError: ServiceWorkerControlError,
  matched by name/reason, becomes UncontrolledPageError ("close the tab and
  reopen it") for `uncontrolled`, and the existing actionable Error for
  `activation-timeout` / `unresponsive`; anything else passes through.
- reloadIfUncontrolled stays on as the last resort, for a worker that does
  not answer CLAIM (a pre-0.5 /sw.js in a returning visitor's browser, a
  custom serviceWorkerUrl). It costs nothing when the claim works.
- controlTimeoutMs is passed as the adapter's timeout; public exports
  (mountEdge, UncontrolledPageError, DEFAULT_CONTROL_TIMEOUT_MS) unchanged.
- edge-reload.mjs: a hard reload must now recover with one load and one
  navigation; a second origin serves a worker that ignores CLAIM to cover
  the fallback reload and the spent guard. Chromium and Firefox pass.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@mkotelnikov
mkotelnikov merged commit 018d5ef into main Sep 18, 2026
3 checks passed
@mkotelnikov
mkotelnikov deleted the chore/http-browser-0.5 branch September 20, 2026 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant