Tooling
How the project is built, understood, and maintained — the meta-layer around the app itself.
This site (Design)
Design is a set of standalone, text-first HTML pages served at
/design (and openable straight from disk). Its own direction,
conventions, and open questions live in the
Design roadmap.
GraphEditor
A standalone tool that renders the codebase as an interactive dependency
graph — each file a node, each import an edge — to make the shape of the
code legible. Currently its own project under GraphEditor/; a
candidate to fold in here later so documentation flows into visualising.
Opening it from the docs
A documentation page can name the code files it covers, and Design will
show a graph icon by the relevant heading. Clicking it opens GraphEditor in
a third column, filtered to just those files. Design names the set after
the heading it came from (e.g. "Encryption & authorship"); GraphEditor
adds it to its own legend as an ordinary "custom" category — same swatch,
same toggle, no special styling or fixed position — so it can be switched
on/off, or other categories re-enabled alongside it, exactly like any
built-in one. Closing the column returns to the two-column layout.
GraphEditor stays independent — Design drives it purely through a small
postMessage API on the embedded iframe
(showNodes with the file list and a display name /
clearFilter), so the tool still runs on its own.
The file list is hidden data-files metadata holding
GraphEditor node ids (repo paths under the analysed root, e.g.
js/peer/mesh.js; a leading app/ is tolerated). A
short page carries one list on its <main> (the icon sits
by the <h1>); a long page can instead put a list on each
root-level <h2>.
Most pages carry it now; a page without it simply shows no icon.
Build & runtime
How source becomes the files a browser runs — the per-file esbuild step
into app/dist/, the TypeScript-where-it-pays policy, the
service worker that makes Tally installable and offline-capable, and how a
running install picks up a new version.
Dev & test
Three seeded identities — Alice, Bob and Carol, with fixed keypairs so they can genuinely connect — make local multi-user work possible without hand-building state. Alice starts with Bob accepted and Carol pending; the others mirror that.
- Seeding —
?seed=aliceon an empty IndexedDB;/?removeUserfirst to start over. - Peer helper (
npm run peer) — drives a headless second user through one action (change name, accept a friend request, send a payment request) so you can watch the first user's UI react. - Two-client E2E (
tests/two-client-e2e/) — two full browsers against a dedicated test server, for friend requests, reconnection, and relay queue delivery.
Performance notes, chiefly the cost of secp256k1 in JavaScript: Performance.