nandi/frqpublic Fork 0
284b59c6810a1b2abace25c071e9d166cd0dafc9
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 · 84 lines · 4.0 KBmarkdown Blame HistoryRaw
One frontend where there were three, and a core that is not Clojure 438b247 nandi 20h ago1# The Nim core
2
The last of the Clojure 284b59c nandi 9h ago3The program. It owns the state, the screens, the IRC connection and the
4message signing; Flutter is a renderer over the widget tree it emits, and
5`dart/frq_core` is the FFI binding between them.
One frontend where there were three, and a core that is not Clojure 438b247 nandi 20h ago6
7```
8src/frq_core.nim the C ABI: every exported symbol, and nothing else
The last of the Clojure 284b59c nandi 9h ago9src/frq/ui.nim the widget tree, in the screens' own tag vocabulary
10src/frq/cells.nim every piece of state the screens read
11src/frq/reducer.nim every event they can send, and what it does
12src/frq/model.nim what a message and a room are
13src/frq/rooms.nim the list, the overview, and the read marker
14src/frq/members.nim who is in a channel, and what the server says of them
15src/frq/conn.nim the socket, the TLS, the line framing
One frontend where there were three, and a core that is not Clojure 438b247 nandi 20h ago16src/frq/ircparse.nim the IRC wire format
The last of the Clojure 284b59c nandi 9h ago17src/frq/handshake.nim CAP and the SASL exchange inside it
18src/frq/atproto.nim handle → DID → PDS → session
19src/frq/crypto.nim OpenSSL, bound: SHA-256 and Ed25519
20src/frq/msgsig.nim signing a mutation so freeq will accept it
21src/frq/emoji.nim 1,884 emoji — generated, see below
22src/frq/glyphs.nim a line split into words and pictures
23src/frq/clock.nim server time in the reader's own zone
24src/frq/store.nim what survives a restart
25src/frq/screens/ connect, chats, chat, discover, settings
One frontend where there were three, and a core that is not Clojure 438b247 nandi 20h ago26```
27
28## The ABI
29
The last of the Clojure 284b59c nandi 9h ago30Strings in, strings out, and JSON where the answer is not a single string —
31deliberately, against a struct-based ABI: a struct means both sides agreeing
32on a memory layout, and a field added later is a version skew that segfaults
33instead of failing.
34
35Two rules, both of which cost a segfault to rediscover:
36
37* Every string the core returns is the **caller's** to free, with `frq_free`.
38 Nim's allocator is not Dart's.
39* `frq_init` exists and does nothing. It used to call `NimMain`, and on Linux
40 `--app:lib` already runs the module initialisers from a library constructor
41 — so calling it again ran every module's top-level code a second time, which
42 for `conn.nim` meant `open()` on channels that were already open.
43
44## Things that will bite
45
46* **Nothing is shared with the socket threads.** There are two — one reader,
47 one writer — and they speak only in channels. `recvLine(timeout)` does not
48 time out on a TLS socket, so a single thread cannot both wait for the server
49 and notice what the client wants to say.
50* **`--mm:orc`, not refc.** refc gives each thread its own GC heap, so the
51 `Socket` the two threads share is a ref from another heap and dereferencing
52 it segfaults.
53* **Every intra-package import says `frq/…`.** `import conn` and
54 `import frq/conn` name the same file by two paths and Nim compiles it twice,
55 giving two sets of globals and two states.
56* **`emoji.nim` is generated.** It was `tools/emoji2nim.py` reading the
57 ClojureDart catalogue, which is gone; regenerating it now means going back to
58 Unicode's `emoji-test.txt` and filtering to what the Twemoji pack draws.
59* **The crypto is bindings, not implementations.** `crypto.nim` is OpenSSL
60 through EVP. The RFC 8032 vectors in `tests/tcrypto.nim` check that this
61 drives it correctly — the seed in the right place, the one-shot signing form,
62 the bytes out in the right order — and not that Ed25519 is implemented
63 correctly, which is OpenSSL's problem.
A message in #test, from Nim 35994d4 nandi 19h ago64
65```bash
The last of the Clojure 284b59c nandi 9h ago66just test nim # the whole suite
67just test nim tircparse # one file
68just build lib # libfrqcore.so into build/nim
Delete the spike that owned the screens 1bb3f77 nandi 19h ago69```
The window connects 1d62d1a nandi 19h ago70
The last of the Clojure 284b59c nandi 9h ago71## What is not here
One frontend where there were three, and a core that is not Clojure 438b247 nandi 20h ago72
The last of the Clojure 284b59c nandi 9h ago73`frq.profile` and `frq.replies` were never ported and went with the
74ClojureDart rather than moving: a Bluesky profile behind a nick, and asking
75freeq what a collapsed msgid was. Neither had a screen in this app to appear
76on.
One frontend where there were three, and a core that is not Clojure 438b247 nandi 20h ago77
The last of the Clojure 284b59c nandi 9h ago78The emoji picker, the overview strip, the lightbox and the profile card are
79state without a screen: the reducer moves them and nothing renders them, so
80those buttons change colour and do nothing.
One frontend where there were three, and a core that is not Clojure 438b247 nandi 20h ago81
The last of the Clojure 284b59c nandi 9h ago82Untested against a real account: nobody has watched freeq accept a SASL
83challenge response or a signature. The shapes are checked and the curve is
84OpenSSL's, but the server has not said yes.