Sitzungen und Befehle
Eine EditorSession besitzt den aktuellen Zustand. Jede Änderung läuft über update oder dispatch und endet in einem Commit oder in einem Wert, der sagt, warum nicht.
Transaktionen
Ein privater Entwurf
update gibt dir eine Transaktion. Sie hält ihren ersten Fehler fest und lehnt alles danach ab, und ihr Handle gilt nur innerhalb der Closure.
scala
session.update { tx =>
tx.spliceText(NodeId("t1"), 5, 0, "!")
tx.select(RangeSelection.caret(Point.textAfter(NodeId("t1"), 6)))
} // Either[UpdateError, Commit]
Befehle
Absicht mit typisiertem Payload
Ein Befehl ist ein EditorCommand[A], gefunden über die Referenz, nie über einen String. Handler laufen von Critical bis Fallback; der erste, der ihn behandelt, beendet die Kette.
scala
session.dispatch(RichText.InsertText, "Hello")
session.dispatch(RichText.InsertParagraph)
session.dispatch(RichText.ToggleMark, StandardMarks.Strong)
session.dispatch(RichText.SetHeading, Some(HeadingLevel.H2))
Commits
Zwei Revisionen
revision wächst mit jeder Veröffentlichung, documentRevision nur, wenn sich das Dokument geändert hat. Code, der speichert, vergleicht die zweite; ein bewegter Cursor löst so nie ein Schreiben aus.
scala
var saved = session.state.documentRevision
val subscription = session.onCommit { commit =>
if commit.current.documentRevision != saved then
save(commit.current.document)
saved = commit.current.documentRevision
}
Regeln der Grenze
Ein Commit ist kein Rendern: Ob eine Ansicht ihn zeigt, beantwortet DocumentView.onProjected.
update innerhalb von update liefert UpdateError.NestedUpdate; nutze in Listenern enqueueUpdate.
Erwartete Fehler sind Either-Werte; Fehlgebrauch wie ein abgelaufenes Transaktions-Handle wirft.
Der Reducer eines State-Felds darf einen Commit ablehnen, bevor er passiert.