Skip to content

wasm: ship the user library with the build#2145

Open
jcelerier wants to merge 1 commit into
masterfrom
wasm-library
Open

wasm: ship the user library with the build#2145
jcelerier wants to merge 1 commit into
masterfrom
wasm-library

Conversation

@jcelerier

Copy link
Copy Markdown
Member

wasm builds shipped with no library at all — no shaders, no presets, no device templates.

The runtime download cannot work in a browser: PluginSettingsModel::firstTimeLibraryDownload() fetches github.com/ossia/score-user-library/archive/master.zip, and codeload sends no CORS headers. So there is nowhere to get the library from at runtime.

This bakes it into the MEMFS image at link time instead, mounted at the path Library::Settings::Model already computes for the default package — so the existing scanning code finds a populated directory with no runtime change.

Cost

payload 62.5 MB, 5816 files (CI clones at depth 1 and drops .git, which is a third of the checkout)
ossia-score.data 62.5 MB — ~32 MB if the host negotiates gzip/brotli
ossia-score.js 607 KB → 1.69 MB (the file index)

--use-preload-cache keeps the package in IndexedDB, so only the first visit pays for the download. The .js growth is a per-load cost that the cache does not remove.

It compresses about 2×, not more, because roughly a third is already-compressed or binary: Presets/Faust/SAM/SHARC is 17.1 MB on its own, PNG+JPG another 11.3 MB. Trimming SHARC and bela/ReadMe.pdf alone would save ~19 MB with no shader loss, if the size ever becomes a problem.

Opt-in via SCORE_WASM_PRELOAD_LIBRARY, so a build that does not set it is unchanged.

Also

ci/wasm.deploy.sh tested for the .data file with [ -f … ] && mv …. Under set -e that aborts the whole deploy when the file is absent, rather than skipping the move. Now an if.

Verification

Automated, in headless Chrome against the built artifact:

  • FS.readdir at /home/web_user/Documents/ossia/score/packages/default returns all 5816 files, with the expected top-level entries.
  • The User Library panel lists default and expands to Cues / Devices / Media / Presets / Scripts / Skins / Util / LICENSE / package.json / README.md — i.e. score's own scanner walks it, not just files present in the filesystem.
  • Boot is clean; the only console output is the pre-existing QWebSocketServer: WebSocket servers are not supported by Qt for WebAssembly.

The mount path was confirmed against the SDK rather than assumed: emscripten sets HOME=/home/web_user, and libQt6Core.a carries /home/web_user and /Documents as literals, so QStandardPaths::DocumentsLocation resolves as expected.

The library cannot be fetched at runtime in the browser: score downloads it
from github's codeload, which sends no CORS headers, so
PluginSettingsModel::firstTimeLibraryDownload() can only ever fail there. That
left wasm builds with no shaders, presets or device templates at all.

Preload it into the MEMFS image instead, at the path
Library::Settings::Model computes for the default package, so the existing
scanning path finds it with no runtime change. CI clones score-user-library at
depth 1 and drops the .git directory, which is a third of the checkout.

This is roughly 76MB of mostly text, and it is a deliberate trade: the first
visit downloads it, --use-preload-cache then keeps the package in IndexedDB so
later visits do not. Opt-in through SCORE_WASM_PRELOAD_LIBRARY, so a build that
does not set it is unchanged.

Also stop the deploy script from testing for the .data file with an `&&`
one-liner: under `set -e` the whole statement fails when the file is absent,
which would abort the deploy rather than skip the move.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019oPj1zRcxSQX7FNni7EHM6
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