This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2024-01-22
Channels
- # announcements (18)
- # babashka (9)
- # beginners (22)
- # biff (2)
- # calva (17)
- # clj-kondo (5)
- # clojure (9)
- # clojure-europe (25)
- # clojure-nl (1)
- # clojure-norway (3)
- # clojure-uk (7)
- # clojuredesign-podcast (6)
- # clojurescript (61)
- # cursive (11)
- # data-science (1)
- # datahike (3)
- # datomic (2)
- # humbleui (2)
- # hyperfiddle (7)
- # jobs (1)
- # jobs-discuss (4)
- # joyride (1)
- # overtone (7)
- # re-frame (2)
- # reitit (9)
- # releases (2)
- # remote-jobs (8)
- # scittle (1)
- # shadow-cljs (48)
- # squint (8)
This is a spike/prototype/pre-alpha rich text editor, written from scratch using Electric, Automerge, and Rama.
I built it to prove (to myself) that:
• Automerge’s capabilities are complete enough that I should be able to express a rich text editor entirely in terms of transformations on an Automerge document. I.e., there’s no intermediary state other than that which the AM document holds, and the editor can be expressed with view=f(data)
, where the automerge document is the data
part. This turned out partly true, because in the end I didn’t want to serialize the cursor positions into the document, so they are side-channeled.
• Electric is capable of being the f
part in the same equation, producing the correct event ordering, semantics, etc. necessary in order to keep the view updated a) fast enough, and b) consistent enough that there are no glitches with cursors, selections, etc., even when absolutely hammering the keyboard like a squirrel on acid (and also when being a collaborator on the receiving end of the output of aforementioned squirrel).
• Rama can act as a document repository (something that otherwise requires specialized infrastructure, and has certain problems, such as with scaling); receiving a stream of changes and (exactly once, in the correct order) batch those changes and atomically update a document stored on disk, replicate to n
nodes, and keep m
clients up-to-date.
Additionally,
• There should be a way to render “local-only” objects in the editor (menus, input-boxes, whatever).
• There should be a way to express simple and complex object-like things (images, tables, etc.), in the editor and document state.
I’ve made no consideration of performance other than in the “big O” sense. I.e., rendering latency should not exceed linearity to the size of the content visible on screen.
The footprint of the codebase turned out like this:
• Code for turning an AM document into renderable data structures, ~200 lines of code.
• Code for rendering DOM elements and translating DOM actions into appropriate actions on the Automerge document, ~300 lines of code total.
• Rama module for updating documents, 60 lines of code plus another 50 various helper functions.
• Code for syncing cursors and document content (client/server), ~100 lines or so.
This is not including another ~250 lines of code for just exposing a Clojure CLJC for Automerge that was symmetrical for both backend and frontend. I’m probably not accounting for helpers that have been in the codebase forever, and that I take for granted.
I can’t say much about how long time this took, since I wrote 90% of it during Christmas vacations as a fun way of torturing myself, and then stalled on some misunderstandings and bits I was missing in the Automerge API (which they very promptly took on board and amended, or otherwise helped me along).
Note: this is feature-incomplete, lacks tests, rigour, consistency and conciseness, but at least satisfies the goals I set out for it.
I’m looking forward to seeing how my thinking around this changes with the forthcoming differential Electric (it’s already changed a bit).
thanks for consistently pushing the envelope forward - i've learned a lot from reading your code
Thanks! I wouldn’t say “plans” as much as “thoughts”. It’s nowhere near a releasable state by any measure, and certainly not to the standards I would expect from a Clojure library.
a library would be amazing, but it could be a valuable reference project even in its current state
Sorry, but no. In its current state, it’s not representative of something I want to put into the world.