I’m experimenting with a system that should enable users to play changes back and forth in a document, similar to the time slider feature available in etherpad (example with a slider at the top of the page: https://etherpad.net/p/yolo/timeslider).
What I am currently doing is the following:
With each new step that gets applied, I save the step and an inverted version of the step. Using this data I can easily go back and forth in a document’s history, which is already working nicely.
Now I’m facing a few problems with this approach:
When going through history, the user should not be able to see intermediary steps of a single transform. An example would be selecting multiple paragraphs and wrapping them in a list (Ctrl+Shift+8). An action like this should appear as a single change to the user when going through history. This makes sense as from the user’s perspective only a single action was performed. The undo/redo behaves the same way.
The easiest way to solve this problem would probably be to save groups of steps, which each represent a transform. That way the groups of steps could atomically be applied when going through history. The problem with this solution is that the current protocol for collaboration does not contain any information about the transforms/groups and only contains a flat array of steps.
Handling and persisting the history separated from the normal document collaboration doesn’t sound like a good idea, as all of the syncing logic would need to be performed twice and additionally one would need to ensure that the history is consistent with the current document version (in case of timeouts, errors, etc.).
One idea to allow this kind of functionality would be to transmit an array of arrays of steps in the remote protocol instead of only an array of steps. Each array would then represent a transform, which would enable the server to use this additional information. Maybe there are also other use cases which would profit from this additional information of grouped steps.
Would be great to get some input on this. Maybe there are alternative approaches to this challenge?