And you're right. You don't want undo/redo only in multi-user apps. You want to have each user have their own local undo/redo events that they can apply and unapply from the shared state which has its own events apart from each user.
Everyone involved needs to keep track of what events they have created forever and always for things to work correctly. This is exactly what ES, OT, and CRDT patterns do, CRDT being the most recent and most capable.
https://github.com/yjs/yjs
And you're right. You don't want undo/redo only in multi-user apps. You want to have each user have their own local undo/redo events that they can apply and unapply from the shared state which has its own events apart from each user.
Everyone involved needs to keep track of what events they have created forever and always for things to work correctly. This is exactly what ES, OT, and CRDT patterns do, CRDT being the most recent and most capable.