That’s fair. I just wanted to give this one last shot.
I just realized that the example in your blog post shows that positions in OT also don’t always converge. This was surprising to me. I’m currently educating people using y-prosemirror not to use the default position mapping because they don’t work in peer-to-peer scenarios. If this is the expected behavior for CodeMirror & ProseMirror, I can be more lenient to the fact they they also don’t converge
with Yjs.
Although, I still think that in some cases this behavior is not acceptable. For example when implementing a shared-cursor plugin, or when implementing a commenting plugin.
The idea is to find the position in the old CRDT state and then map that position to the new CRDT state.
I would implement this by associating every CodeMirror State object to a Yjs Snapshot. A snapshot is a view on the Yjs document that reflects the old state. A position mapping from one state to another would basically find the position in the old state (extracting the unique character id) and map that position to the new state (by computing the offset of the unique character id).
If it was possible to hijack the position mapping and provide a custom mapping based on the CRDT model, it would be possible to have positions converge. This will be helpful for plugins that mark text and rely on positions to converge.
I’m currently struggling to find more good examples when positions must converge. Maybe you are right and having diverging positions are an acceptable tradeoff for simpler position representation. It would still be nice to have positions converge when using Yjs.