Collaborative undo
Undo that reverses your own last action and leaves everyone else's work alone - which is what users expect, and what a naïve "restore the previous state" undo gets badly wrong in a shared document.
Two replicas, two undo stacks
Each replica has its own undo stack, tracking only its own edits.
Opening two replicas…
Undo mine, not yours
Undo in a single-user editor means "put the document back how it was". In a collaborative document that would be a disaster: restoring an earlier state would throw away everything your collaborators did in the meantime, and they would watch their work vanish because somebody else pressed a key.
What users actually expect is selective undo - reverse my last action, leave everybody else's alone - and that is what these two replicas implement.
Note also that consecutive keystrokes collapse into one undo step, so undo removes a word or a phrase rather than a single character. A remote edit arriving between two of your keystrokes ends the current step, which is what keeps the boundaries sensible when several people are working at once.
Why this is not a rewind
An undo here does not restore a previous state. It creates new operations that delete what the action inserted and re-insert what it deleted, and those operations travel to peers exactly like a keystroke. That is why the effect appears on the other replica, why it merges rather than clobbering, and why it can itself be undone.
It is also why an undo can survive a disconnection: take a replica offline, undo something, bring it back, and the undo reaches its peer whenever the connection returns.
// One stack per editing surface, scoped to the text it edits. var undo = new BcrdtUndoManager(document.Text("body"), new BcrdtUndoManagerOptions { // Adds to the default set, which already tracks untagged (null-origin) edits. TrackedOrigins = { typeof(BcrdtTextArea) }, }); undo.Undo(); // removes what I did, not what they did undo.Redo();