feat(dart): build the web target's assets instead of scripting them - #60
Conversation
A Flutter web application needs the WebAssembly module and its glue, which the native library is not a variant of. Both are cut from one pinned source now, so the Dart package can never talk to bindings from another revision. Collects everything vodozemac under nix/dart/vodozemac/ on the way. Signed-off-by: Niklas Zender <n.zender@famedly.com> Co-authored-by: Cursor <cursoragent@cursor.com>
A Flutter project depends on flutter_vodozemac, not on the plain package, and the hook then found no constraint at all and failed every commit. Both names are cut from the tag the bindings are built from. Signed-off-by: Niklas Zender <n.zender@famedly.com> Co-authored-by: Cursor <cursoragent@cursor.com>
The vodozemac module and LiveKit's encryption worker are compiled artefacts of dependencies that a web build expects in web/, and a repository that carried them would carry copies that silently age. The worker is compiled from the package the project already resolved, so it follows pubspec.lock instead of a second clone pinned by hand. One script does both, and the devshell carries it: an asset only CI can produce is one a developer cannot reproduce when the site misbehaves in the browser. Signed-off-by: Niklas Zender <n.zender@famedly.com> Co-authored-by: Cursor <cursoragent@cursor.com>
`./pkg/` is the default `wasmPath` of both the plugin and the plain package, so an application that gets the module from us now needs to pass nothing at all. An application that passes a path of its own has to drop it. Signed-off-by: Niklas Zender <n.zender@famedly.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 897a0c9. Configure here.
| ++ lib.optional projectConfig.web.livekitE2eeWorker.enable '' | ||
| # The worker's own imports resolve through the project's package | ||
| # config, which is also where the package it lives in is recorded. | ||
| [ -f .dart_tool/package_config.json ] || flutter pub get |
There was a problem hiding this comment.
Pub get pulls example deps
Medium Severity
Issue: When package_config.json is missing, the LiveKit asset step runs flutter pub get without --no-example, so CI also resolves a project's example/ pubspec. That can fail or drift the lockfile on apps that ship an example, and it contradicts the checks workflow which already avoids this.
Fix: Use flutter pub get --no-example.
Reviewed by Cursor Bugbot for commit 897a0c9. Configure here.


A Flutter web application needs two compiled artefacts in
web/that norepository should carry: the vodozemac WebAssembly module with its glue, and
LiveKit's frame-encryption worker.
famedly/callproduces them with aprepare-web.shthat clones two repositories,cargo installs a codegenerator and pins the worker to a branch name by hand. This replaces that.
module are the same crate compiled twice, so both now come from one pinned
source and the Dart package can never talk to bindings from another revision.
Everything vodozemac moves under
nix/dart/vodozemac/on the way.location comes out of
.dart_tool/package_config.json, so it followspubspec.lockand needs no pin of its own.how to produce is one a developer cannot reproduce when the site misbehaves in
the browser.
wasm-packruns directly rather than throughflutter_rust_bridge_codegen build-web, which is a Dart program that only shells out to it — that keeps aDart toolchain and a pub cache out of the build. The price is that the flags
live here, and
flutter_rust_bridgehas changed them between versions, so thebuild fails with an explanation if the crate stops pinning the version those
flags were read off.
Stacked on #56, whose
build.nixthis extends.Test plan
nix flake check --all-systemsnix build .#famedly-vodozemac-web: the module carries the threadinginstructions the browser needs, and the two files match byte for byte what
prepare-web.shproduces todayfamedly/call: both assets land where they are looked for, theworktree stays clean, under two seconds
flutter build webMade with Cursor