Skip to content

feat(frontend): save the installer in browsers without a file picker - #2

Merged
dangreen merged 1 commit into
mainfrom
feat/download-without-picker
Oct 20, 2026
Merged

dangreen merged 1 commit into
mainfrom
feat/download-without-picker

Conversation

@dangreen

Copy link
Copy Markdown
Member

Why

Firefox, Safari and Brave have no showSaveFilePicker (Brave switches it off), so the page stopped at "This browser is not supported". SPEC §8 gave the reason as a Blob capped at ~1-2 GB, but that cap is about a Blob built from bytes in memory. The .run is the header, meta and the archive byte for byte, and a Blob keeps a File among its parts as a reference to the disk: the download reads the archive from disk as it goes and never holds it in memory.

What

  • Without the picker, Build$ puts the header, meta and the archive File into one Blob (runBlob in services/bundle) and hands it to the browser through a link with download (startDownload in the new services/download).
  • Chrome and Edge keep the picker: it can put the file straight onto a USB stick or another drive, so the system disk needs no room for a second copy, and the page follows the progress and shows a write error itself.
  • The address of the Blob is let go at the next build or when the archive changes, not right after the click. A download already under way goes on without it.
  • Without the picker the build panel shows no progress bar, since the browser shows the progress, and leads into the steps with "The browser is downloading need-for-speed.run. Once it is done, copy the file to SteamOS, then, in Desktop Mode:". A Downloading story shows it.
  • The "This browser is not supported" callout on the home page goes away, with its tests and the UnsupportedBrowser story.
  • The warning about free space is asked for only where the picker is: elsewhere navigator.storage.estimate() is the quota of the site, which Firefox 157 put at 7.4 GiB on a disk with 51 GB free.
  • CanSaveFiles$ becomes HasSavePicker$: every browser can save now, and the token says how.
  • SPEC (§6, 6.2, 6.3, 8), README and the comments no longer say Chromium only.

Notes

  • Checked on the production build in Playwright with a 5 GiB Zip64 archive. Firefox 157: the download started 0.3 s after the click and took 27 s, the browser grew by 54 MiB with three such downloads running at once, GNU dd and tar read meta out of the .run by its own header, and the archive in it matched the original byte for byte. Chromium 156 with the picker removed, as in Brave, did the same in 15 s.
  • Building again while a download runs lets the old address go, and the old download still completes, in both browsers. Revoking the address right after the click did not break a download in either of them; keeping it until the next build covers the browsers that were not checked.
  • Safari is not verified: WebKit does not start in the container the checks ran in.
  • In Firefox 157 the page looks as it does in Chromium, in both colour schemes.
  • Lint, types, 616 unit tests of the frontend and the 56 checks of the installer pass. editorconfig-checker v4.0.2 finds no errors.

Firefox, Safari and Brave have no showSaveFilePicker, so the page stopped at "This browser is not supported". There the .run now goes out as an ordinary download: header, meta and the archive in one Blob, the archive as the File itself, which a Blob keeps as a reference to the disk, so it is never read into memory. Chrome and Edge keep the picker: it puts the file straight onto a USB stick or another drive, and the page follows the progress.

Verified on the built site with a 5 GiB Zip64 archive: Firefox 157 downloaded it in 27 s and grew by 54 MiB with three such downloads at once, and Chromium 156 without the picker, as in Brave, took 15 s. GNU dd and tar read meta out of the .run, and the archive in it matched the original byte for byte. Safari is not verified.

Without the picker the build panel shows no progress, since the browser does, and says the browser is downloading the file. The warning about free space is shown only where the picker is: elsewhere navigator.storage.estimate() is the quota of the site, which Firefox 157 put at 7.4 GiB on a disk with 51 GB free. CanSaveFiles$ becomes HasSavePicker$, and the download itself is the new download service.
@dangreen
dangreen merged commit 742a684 into main Oct 20, 2026
6 checks passed
@dangreen
dangreen deleted the feat/download-without-picker branch October 20, 2026 15:28
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