The ClojureDart half
Nothing here builds yet. This is the boundary, drawn before the port rather
than after it, so that the question "can this file go on the phone?" has a
filesystem answer.
The three trees
common/ .cljc both compilers. No jolt, no glimmer, no dart.
src/ .clj jolt: glimmer, jolt.ffi, the cosmic and tui backends.
flutter/ .cljd ClojureDart: Flutter widgets, dart:io, dart:ffi.
The extension is the boundary and the compilers enforce it. ClojureDart reads
.cljd and .cljc and never .clj, so a namespace that reaches for
jolt.host cannot accidentally end up in the APK — it is a .clj and the Dart
compiler cannot see it. jolt reads all three, which is why common/ works at
all: one copy of frq.clock, compiled twice.
Where both need a namespace but the answer differs, .cljd wins over .cljc
in ClojureDart's own resolution, so a file here shadows a shared one without
either side knowing. Reader conditionals work too, with one trap from
ClojureDart's FAQ: the :clj feature is always on under cljd, so :clj goes
last in a conditional, and macro code that wants the Clojure path during
host evaluation asks for :cljd/clj-host.
What has crossed
frq.io is the seam — the host's job named once, with frq.io.jolt answering
it on the desktop and frq.io.dart here. It carries the filesystem, the
environment, the config directory and the clock.
Moved to common/ and running under jolt today:
| namespace | lines | note |
|---|---|---|
frq.emoji |
1,914 | data; nothing to port |
frq.glyphs |
84 | data |
frq.av.dial |
117 | already touched neither jolt nor glimmer |
frq.clock |
93 | zone-hunting moved into the backends |
frq.store |
122 | install -m 600 became write-private-file! |
frq.clock is the shape the rest should follow. It used to open with four
guesses at the reader's zone — TZ, the target of /etc/localtime, the file
itself by path, then Android's persist.sys.timezone — and then convert days
to a date by printing one with jolt.time.local and taking a subs of the
result. Both are gone: the guessing is a libc question and lives in
frq.io.jolt, where Dart answers it in one call instead; the conversion is
eleven lines of Hinnant's algorithm, checked against java.time.LocalDate for
every day from 1901 to 2052.
What has not
Roughly 4,000 lines are portable in substance and still .clj because the seam
does not reach far enough yet. In the order worth doing them:
frq.wire,frq.msgsig— need a crypto seam beside the io one.frq.irc(433) — the parser is pure; the reader is a blocking thread in
afuture, and Dart has no threads. It becomes aStreamover
SecureSocket, which is also what makes TLS work on the phone at all.frq.atproto(209),frq.oauth(182) — hand-rolled HTTPS over
jolt.mvn-http's OpenSSL bindings, which is why sign-in is desktop-only
today.dart:iohas TLS in the runtime; this is the single biggest thing
the port buys.frq.state(1,930) — mostly portable logic, but its ratoms are
glimmer's. Needs the reactive layer decided first.frq.app(1,834) — not a port. Flutter brings its own reconciler, so
the screens are rewritten againstcljd.flutter.
Not coming: frq.tui (no terminal Flutter), frq.cosmic (libcosmic is
desktop-only), and the media plane — moq/, codec/, capture/, av/, about
3,800 lines of FFI against C libraries that do not exist on Android either way.
dart:ffi does not conjure V4L2; that half wants Flutter's camera and audio
plugins and is its own project.
To make this real
- Pin
tensegritics/clojuredartindeps.edn— it saysPIN-ME. - Get a Flutter SDK and the cljd toolchain into the flake. Neither is there.
clj -M:cljd init, thenclj -M:cljd flutter. (There is norelease
subcommand — a release build isclj -M:cljd compilefollowed by
flutter build.)frq.io.dartis written from the docs and has never been compiled. Expect
its interop to be wrong in detail.
There is no other APK to fall back on. The jolt one — nix/android.nix, the
android/ manifest and Java glue, the .#apk outputs and just apk — is
gone, along with the jvui and Vidya backends it painted through. Until step 2
exists, frq has no Android build at all, and that is the honest state.
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 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
|