nandi/frqpublic Fork 0
98d613511f9664af4d9779a07baf26ecb2feaeea
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 · 89 lines · 4.3 KBmarkdown Blame HistoryRaw
One frontend where there were three, and a core that is not Clojure 438b247 nandi yesterday1# The Nim core
2
The last of the Clojure 284b59c nandi yesterday3The 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 yesterday6
7```
8src/frq_core.nim the C ABI: every exported symbol, and nothing else
The last of the Clojure 284b59c nandi yesterday9src/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 yesterday16src/frq/ircparse.nim the IRC wire format
The last of the Clojure 284b59c nandi yesterday17src/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 yesterday26```
27
28## The ABI
29
The last of the Clojure 284b59c nandi yesterday30Strings 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 yesterday64
65```bash
The last of the Clojure 284b59c nandi yesterday66just 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 yesterday69```
The window connects 1d62d1a nandi yesterday70
The last of the Clojure 284b59c nandi yesterday71## What is not here
One frontend where there were three, and a core that is not Clojure 438b247 nandi yesterday72
The last of the Clojure 284b59c nandi yesterday73`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 yesterday77
Three buttons that did nothing now do what they say 98d6135 nandi yesterday78The profile card is state without a screen: `profileViewing` is moved by
79nothing and rendered by nothing, and `frq.profile` was never ported.
80
81The emoji picker, the overview strip and the lightbox used to be in that list.
82They have screens now — the picker under the message it is for, the overview
83as a pane above the compose bar, the lightbox as a panel over the
84conversation — so the 🙂 chip, the Overview toggle and clicking a picture all
85do what they look like they do.
One frontend where there were three, and a core that is not Clojure 438b247 nandi yesterday86
The last of the Clojure 284b59c nandi yesterday87Untested against a real account: nobody has watched freeq accept a SASL
88challenge response or a signature. The shapes are checked and the curve is
89OpenSSL's, but the server has not said yes.