Zum Inhalt springen
Anjunar/ DOCS

Dokumentmodell

Ein Dokument ist ein unveränderlicher Baum. Knoten referenzieren ihre Kinder per ID; eine Änderung tief im Baum kostet ein paar Einträge statt einer Kopie aller Vorfahren.

Baum

Knoten, IDs und Typen

Jeder Knoten hat eine stabile NodeId und einen Typ aus dem Schema. Elementknoten listen ihre Kinder als IDs; Textläufe tragen Text und Marks.

Der Baum hinter dem Text

Bearbeite das Dokument und beobachte den Baum: Tippen ändert einen Textlauf, Formatieren teilt Läufe, Enter fügt einen Absatz hinzu.

A small document

A paragraph with strong and emphasized text, a link and inline code.

  1. First item

  2. Second item

20 Wörter · 21 Knoten
ember.core.root/1 [document] ember.rich-text.heading/1 [document2] ember.core.text/1 [document1] "A small document" ember.rich-text.paragraph/1 [document13] ember.core.text/1 [document3] "A paragraph with " ember.core.text/1 [document4] "strong" ember.core.text/1 [document5] " and " ember.core.text/1 [document6] "emphasized" ember.core.text/1 [document7] " text, a " ember.link.link/1 [document9] ember.core.text/1 [document8] "link" ember.core.text/1 [document10] " and " ember.core.text/1 [document11] "inline code" ember.core.text/1 [document12] "." ember.list.list/1 [document20] ember.list.item/1 [document16] ember.rich-text.paragraph/1 [document15] ember.core.text/1 [document14] "First item" ember.list.item/1 [document19] ember.rich-text.paragraph/1 [document18] ember.core.text/1 [document17] "Second item"
Bauen

Gültig durch Konstruktion

Document.build prüft fünf Stufen der Reihe nach: Identität, Referenzen, Zyklen, Erreichbarkeit und Schema. Es stoppt bei der ersten fehlerhaften Stufe, damit eine hängende Referenz nicht in Folgefehlern untergeht.

scala
val root = NodeId("root") Document.build(schema, root, Vector(RootNode(root, Vector(NodeId("ghost"))))) // Left(Vector(Violation(...)))
Ausgabe
<root>#root.children[0]: `root` references the unknown node `ghost` at position 0.
Operationen

Sieben Primitive

Insert, Remove, Move, Replace, SpliceText, SplitText und MergeText. Jede liefert neues Dokument, ChangeSet und PositionMapping gemeinsam, damit sie nie auseinanderlaufen. Bei einem Fehler bleibt das Ausgangsdokument unverändert.

scala
document.applyOperation(Operation.SpliceText(NodeId("t1"), 5, 0, "!")) // Either[OperationError, OperationResult]
Positionen überstehen Änderungen

Eine PositionMapping trägt einen Punkt über eine Änderung und sagt, ob er erhalten oder verdrängt wurde. Ein Upload-Lesezeichen, dessen Text verschwand, gilt als verdrängt und wird nie stillschweigend woandershin verschoben.