nandi/frqpublic Fork 0
562900f7846ea707ed5bd6b41e783a2e83999c70
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.

A third target, and the seam that was already waiting for it f54ca45 · on 562900f7846ea707ed5bd6b41e783a2e83999c70 · nandi · 2d ago
README.md · 55 lines · 2.4 KBmarkdown
Blame HistoryOpen raw

flutter-web

modal run .modal/flutter-web/container.py
just modal flutter-web

Defined by container.toml; see ../spec.md for the keys.
Built on the published arch-nix image.

flutter-dev with the Linux target swapped for the web one: the same
clojure -M:cljd compile over the same flutter/src and common/,
then dart2js instead of CMake and Ninja. Same incremental shape --
the working tree and Flutter's caches live on the devshell volume,
under frq-flutter-web/ so the desktop container's directory beside
it is untouched.

Runs as a Sandbox on a real VM (kernel 6.x, not gVisor). The command
is the sandbox's own process, so it dies when the command exits.

To look at what it built, ask for the serve action -- [network] ports tunnels 8080 out, and the URL is printed once the sandbox is
scheduled:

modal run .modal/flutter-web/container.py \
  --command 'cd /devshell/frq-flutter-web && nix develop /app#flutter-web --command just -f /devshell/frq-flutter-web/justfile flutter-web serve'

That blocks until you Ctrl-C it, and it bills until you do.

It compiles; it does not start

dart2js links the whole app -- main.dart.js is 3.6MB and has
frq, irc, atproto and handshake all through it, so the
dart:io imports under flutter/src are not the wall they look
like. What stops it is the first line of main:
getApplicationDocumentsDirectory is a platform channel, path_provider
ships no web implementation, and the channel with no handler behind it
throws MissingPluginException. main awaits that before installing
frq.io.dart, so no widget is ever built and the page stays white.

That is the seam doing its job rather than a build problem. The fix is
a frq.io.web behind frq.io -- the browser's answer for a private
file is IndexedDB or localStorage, not a directory -- and main
choosing it the way flutter/src/frq/main.cljd chooses the Dart one
now. frq.net.web is the next one after it, for the same reason: a
browser has no raw socket, so the IRC connection wants a WebSocket.

Serving it

serve.py is the other half: a Function that mounts the same volume
and hands out flutter/build/web, so a rebuild in the Sandbox is
picked up by the next cold start with nothing redeployed.

modal deploy .modal/flutter-web/serve.py

[network] ports tunnels 8080 out of the Sandbox as well, for the
case where you want the build and the server to be one process.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# `flutter-web`

    modal run .modal/flutter-web/container.py
    just modal flutter-web

Defined by `container.toml`; see `../spec.md` for the keys.
Built on the published `arch-nix` image.

`flutter-dev` with the Linux target swapped for the web one: the same
`clojure -M:cljd compile` over the same `flutter/src` and `common/`,
then dart2js instead of CMake and Ninja. Same incremental shape --
the working tree and Flutter's caches live on the `devshell` volume,
under `frq-flutter-web/` so the desktop container's directory beside
it is untouched.

Runs as a Sandbox on a real VM (kernel 6.x, not gVisor). The command
is the sandbox's own process, so it dies when the command exits.

To look at what it built, ask for the serve action -- `[network]
ports` tunnels 8080 out, and the URL is printed once the sandbox is
scheduled:

    modal run .modal/flutter-web/container.py \
      --command 'cd /devshell/frq-flutter-web && nix develop /app#flutter-web --command just -f /devshell/frq-flutter-web/justfile flutter-web serve'

That blocks until you Ctrl-C it, and it bills until you do.

## It compiles; it does not start

dart2js links the whole app -- `main.dart.js` is 3.6MB and has
`frq`, `irc`, `atproto` and `handshake` all through it, so the
`dart:io` imports under `flutter/src` are not the wall they look
like. What stops it is the first line of `main`:
`getApplicationDocumentsDirectory` is a platform channel, path_provider
ships no web implementation, and the channel with no handler behind it
throws `MissingPluginException`. `main` awaits that before installing
`frq.io.dart`, so no widget is ever built and the page stays white.

That is the seam doing its job rather than a build problem. The fix is
a `frq.io.web` behind `frq.io` -- the browser's answer for a private
file is IndexedDB or localStorage, not a directory -- and `main`
choosing it the way `flutter/src/frq/main.cljd` chooses the Dart one
now. `frq.net.web` is the next one after it, for the same reason: a
browser has no raw socket, so the IRC connection wants a WebSocket.

## Serving it

`serve.py` is the other half: a Function that mounts the same volume
and hands out `flutter/build/web`, so a rebuild in the Sandbox is
picked up by the next cold start with nothing redeployed.

    modal deploy .modal/flutter-web/serve.py

`[network] ports` tunnels 8080 out of the Sandbox as well, for the
case where you want the build and the server to be one process.