nandi/frqpublic Fork 0
2e24e647a7766c822d13d253777204c3bf92fb7a
Commits
Clone
git clone https://git.rickub.com/nandi/frq.git
git clone ssh://git@rickub.com/nandi/frq.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

README.md · 80 lines · 3.5 KBmarkdown Blame HistoryRaw
Six verbs, and the last of the nix 2e24e64 nandi 17h ago1# `web`
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago2
Six verbs, and the last of the nix 2e24e64 nandi 17h ago3 modal run .modal/web/container.py
4 just modal web
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago5
Six verbs, and the last of the nix 2e24e64 nandi 17h ago6Defined by `container.toml`; `../_loader.py` is what reads it, and
7its comments are the spec.
Three tarballs where a devShell was 5ce66d5 nandi yesterday8Built on `debian:13-slim`.
9
10No nix, and that is the point of this container rather than an
11incidental fact about it. The build is `tools/build-web.sh`, which
12gets its Flutter, its JDK and its Clojure CLI from
13`tools/toolchain.sh` -- three tarballs pinned by sha256 and unpacked
14into a directory. So the image build is one `apt-get install` of
15curl, git, rsync, tar and the two unarchivers, and everything that
16used to happen before a line of Dart was compiled -- warming a
17devShell, printing its environment, caching that against flake.lock,
18copying a nix closure back to a volume afterwards -- does not happen
19at all. The toolchain lands on the volume and the second run finds
20it there.
21
Six verbs, and the last of the nix 2e24e64 nandi 17h ago22The `dev` container beside it works the same way now, and so does a
23laptop: one script, one pinned set of tarballs, and whatever the
24host has to bring for a given target -- GTK and a C++ toolchain for
25the desktop build, Google's command-line tools for the APK.
Three tarballs where a devShell was 5ce66d5 nandi yesterday26
27Same incremental shape as before -- the working tree, the generated
28Dart under `flutter/lib/cljd-out` and Flutter's caches live on the
Six verbs, and the last of the nix 2e24e64 nandi 17h ago29`devshell` volume, under `frq-web/` so the desktop
Three tarballs where a devShell was 5ce66d5 nandi yesterday30container's directory beside it is untouched. None of them is copied
31in from the laptop: a checkout's copy of the compiler's output is
32not this container's, and overwriting the volume's with it is how an
33incremental build stops being one.
34
35One build mode, not two. A `fast` mode (dart2js -O1, no icon
36tree-shaking, no service worker) measured 52.5s against the release
37build's 49.8s on the same source change, so what it bought was a
38bigger bundle. `--no-wasm-dry-run` is the flag that did pay, and it
39is in the one build there is.
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago40
41Runs as a Sandbox on a real VM (kernel 6.x, not gVisor). The command
42is the sandbox's own process, so it dies when the command exits.
43
44To look at what it built, ask for the serve action -- `[network]
45ports` tunnels 8080 out, and the URL is printed once the sandbox is
46scheduled:
47
Six verbs, and the last of the nix 2e24e64 nandi 17h ago48 modal run .modal/web/container.py \
49 --command 'cd /devshell/frq-web && tools/build-web.sh serve 8080'
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago50
51That blocks until you Ctrl-C it, and it bills until you do.
52
53## It compiles; it does not start
54
55dart2js links the whole app -- `main.dart.js` is 3.6MB and has
56`frq`, `irc`, `atproto` and `handshake` all through it, so the
57`dart:io` imports under `flutter/src` are not the wall they look
58like. What stops it is the first line of `main`:
59`getApplicationDocumentsDirectory` is a platform channel, path_provider
60ships no web implementation, and the channel with no handler behind it
61throws `MissingPluginException`. `main` awaits that before installing
62`frq.io.dart`, so no widget is ever built and the page stays white.
63
64That is the seam doing its job rather than a build problem. The fix is
65a `frq.io.web` behind `frq.io` -- the browser's answer for a private
66file is IndexedDB or localStorage, not a directory -- and `main`
67choosing it the way `flutter/src/frq/main.cljd` chooses the Dart one
68now. `frq.net.web` is the next one after it, for the same reason: a
69browser has no raw socket, so the IRC connection wants a WebSocket.
70
71## Serving it
72
73`serve.py` is the other half: a Function that mounts the same volume
74and hands out `flutter/build/web`, so a rebuild in the Sandbox is
75picked up by the next cold start with nothing redeployed.
76
Six verbs, and the last of the nix 2e24e64 nandi 17h ago77 modal deploy .modal/web/serve.py
A third target, and the seam that was already waiting for it f54ca45 nandi 2d ago78
79`[network] ports` tunnels 8080 out of the Sandbox as well, for the
80case where you want the build and the server to be one process.