Advanced apologies if this question was addressed before.
How is Yjs integrated with editors (say SlateJS) to enable collaborative editing?
I assume the desired approach is to make Yjs the “system of record” and editors act as UI clients that accept input from local users. Specifically, if there are two nodes, the editor of the first node will be connected to one instance of Yjs doc, and the editor of the second node to the second instance of Yjs doc. Local operations will be accepted by each editor and conveyed to its connected Yjs doc. Remote operations received by the Yjs doc are conveyed back to the editor.
Assuming the above setup is right, how is an editor and its corresponding Yjs doc kept in sync at all times? It is conceivable for a (human) user to be inserting characters into the editor at a certain position in the sequence while its Yjs doc is receiving concurrent operations from a remote node that affect the position where the new characters are being inserted. In other words, the editor also becomes a source of concurrent operations.
I can imagine a few solutions:
Pause merges of remote operations at Yjs doc when local operations are flowing in. This will prioritize local operations, but other than occasional jitteriness, positions implied in local operations are always meaningful because all remote operations seen by Yjs doc are also seen by the editor (and therefore the human user). I believe this approach is the most practical, and one could pause merges by “going offline” or find a way to somehow tell Yjs to not accept remote operations temporarily.
Replace the editor’s internal data model with Yjs doc’s data model. This way, both user inputs and remote operations are changing the Yjs doc directly. And Yjs is already capable of handling concurrent operations. However, it is usually impractical to replace editor’s data model unless we have access to and willing to change the editor’s source code.
Allow users to enter characters via the editor, but intercept those events and send them directly to Yjs doc instead of to editor’s internal data model. The output from the Yjs doc is what is fed to the editor model for purposes of displaying the text back to the user. This approach can be implemented in two ways and both seem farfetched. One implementation is to update the whole text in the editor by reading back the full string from Yjs doc for each character change. The other implementation is to calculate the positions where text got affected from the recent local/remote operations at Yjs doc, and transform those Yjs operations into editor-specific operations and apply them on the editor. The second implementation sounds a lot like a mini-OT solution, which is not preferable.
How is the solution implemented in practice? I appreciate your thoughts.