How is UndoManager being used?

I curious about how the yjs UndoManager is actually being used. I am puzzled because the undo stack is shared among all clients. So, for example, if user A inserts ‘X’; then user B inserts ‘Y’; and then user ‘A’ pops an item off the undo stack, the effect is that ‘Y’, not ‘X’ is removed. But this is unlikely to feel natural to users. When User A presses the undo button (or whatever the UI provides to pop an item off the undo stack) they almost certainly intend to undo their own action, not user Y’s action. If they wanted to get rid of Y, they would, I feel, be much more likely to use a ‘delete’ command.

Do you know of a use case in which a shared undo stack is appropriate?

I did a quick check and, for instance, Google Docs and tldraw both implement per-user undo stacks rather than one shared stack.

If you have implemented a per-user (i.e. per client) undo stack, how did you do it? How did you achieve persistence (i.e. the stack remains even if the user exits and resumes)? Do you care about dependencies e.g. User A inserts ‘CAT’, User B modifies it to ‘DOG’, User A tries to undo their action - with what result? Is DOG deleted (it is a modified version of User A’s inserted CAT) or does the undo fail (that is what happens with Google Doc - the undo silently fails).

Any thoughts or examples very welcome…

Thank you for expressing your doubts about UndoManager in the community.

I went to check the relevant code logic and found that UndoManager project does share the stack internally.

The reference code is as follows:

However, if you want to achieve localization (client/user level) stack, I think that you can refer to trackedOrigins

Thanks for confirming that the UndoManager is shared. While trackedOrigins may be useful for some applications, it is not clear to me how it could be used to implement a per-user undo stack. Can you explain?

hi,@micrology

UndoManager records changes based on transaction , when we mark transaction through origins, only transaction with the same mark will be recorded, so as to achieve the purpose of localization.

more detail please see here: