Text edits a string field as a sequence of characters. Assigning a string replaces it, so of two concurrent assignments
one wins. An edit with Text inserts and deletes characters, so two people typing in the same field both keep their
work. Changes and branches shows what merges and how.
Perform mutations on an echo object within a controlled context.
All mutations within the callback are batched and trigger a single notification
when the callback completes. Direct mutations outside of Obj.update will throw
an error for echo objects.
This function also works with nested objects within echo objects (e.g., Template structs)
that are reactive at runtime.
@param ― obj - The echo object to mutate. Use Relation.update for relations.
@param ― callback - The callback that performs mutations on the object.
@example
const person = Obj.make(Person, { name: 'John', age: 25 });
Splice the string CRDT value at path by character index, mirroring Array.prototype.splice:
remove deleteCount characters at start and insert insert. Returns the removed substring.
Must be called inside Obj.update(obj, () => { ... }).
Replace the string CRDT value at path with newText.
For database-backed objects the change is applied as a minimal Automerge diff (preserving cursors,
anchors, and merging cleanly with concurrent edits); for in-memory objects it is a plain assignment.
Must be called inside Obj.update(obj, () => { ... }).
@performance ― O(text length) diff, so concurrent edits merge minimally.
s to the string value at path, returning the resulting
full string. Implemented on top of
splice
so it works for both backends.
An edit with a missing or empty oldString appends its newString. A non-replaceAll edit whose
oldString is not found throws
Error.TextEditNotFoundError
.
Must be called inside Obj.update(obj, () => { ... }).
@performance ― O(N) per edit plus O(M · N) for replaceAll (N = text length, M = matches): it re-reads and searches the
whole string after every splice, so one replaceAll edit can be O(N²).
A text field bound to an ECHO string, such as a <textarea> whose value is the field, loses its caret when a peer’s
edit arrives, because React sets the whole value again. Save the selection before the remote change renders, and move it
by the number of characters the change inserted or removed before it. Write each local keystroke with Text.update, so
it merges with what the peer typed.