Y-prosemirror & tui.editor3 & Vuejs3 [solved]

Hi,

I’m currently developing a document generator with go and vue3. I’m adding yjs in it. I have already a POC where I have synced a ytext between 2 clients.
As tui.editor’s Markdown editor is based on prosemirror-view, I started to work with y-prosemirror.
But there is something I don’t understand.
I can’t have your websocket server due to end-to-end encryption requirement.
I only store encrypted update in server memory which is cleared when there is no client.

Here are my steps when a client wants modify a markdown string :
(1st client)

  1. open websocket
  2. server asks for initial state
  3. editor is intialized with ysyncplugin
  4. current markdown value is loaded in editor
  5. so the ydoc is updated -> its state (Y.encodeStateAsUpdate) is send to server
  6. server say ok
    7a. on user input, ydoc is updated -> the update is sent to the server
    7b. on websocket message -> the update is applied on ydoc

(2nd+ client(s))

  1. open websocket
  2. server sends all updates in memory -> there are not applied on ydoc
  3. editor is intialized with ysyncplugin
  4. state and update are applied on ydoc (the view is well updated)
    5a. on user input, ydoc is updated -> the update is sent to the server
    5b. on websocket message -> the update is applied on ydoc

It’s working very well for the ydoc which is identical between client (console.log it with toJson).
But the view isn’t correctly synchronized.
I this type of error
Uncaught RangeError: Position 315 out of range
resolve resolvedpos.js:230
resolveCached resolvedpos.js:251
resolve2 node.js:221
create5 selection.js:285
restoreRelativeSelection sync-plugin.js:166
_typeChanged sync-plugin.js:355
createMutex mutex.js:35
_typeChanged sync-plugin.js:343
callAll function.js:19
callEventHandlerListeners EventHandler.js:87
cleanupTransactions Transaction.js:292
callAll function.js:19
cleanupTransactions Transaction.js:298
transact Transaction.js:402
readUpdateV2 encoding.js:382
applyUpdateV2 encoding.js:475
applyUpdate encoding.js:489

When I try to load the state and updates (for 2nd+ clients) before the editor initialization, I have this type of error :
n._item is null
absolutePositionToRelativePosition lib.js:96
getRelativeSelection sync-plugin.js:172
beforeAllTransactions sync-plugin.js:206
emit observable.js:73
emit observable.js:73
transact Transaction.js:386
toDelta YText.js:981

I have tried to follow the demo and the code of the y-websocket and y-prosemirror but I can’t figure if i have to init the doc before or after the editor due to the JS asynchronous.

I use only ysyncplugin.

For example, on an empty markdown with 2 clients. The 1st write “Test”.
The second received this :

cws.updateYDocHandler
cws.updateDoc
Uint8Array(53) [ 1, 3, 212, 204, 137, 142, 6, 0, 7, 1, … ]
T
cws.readUpdate
cws.updateYDocHandler
cws.updateDoc
Uint8Array(18) [ 1, 1, 212, 204, 137, 142, 6, 3, 132, 212, … ]
Te
cws.readUpdate
cws.updateYDocHandler
cws.updateDoc
Uint8Array(18) [ 1, 1, 212, 204, 137, 142, 6, 4, 132, 212, … ]
Tes
cws.readUpdate
cws.updateYDocHandler
cws.updateDoc
Uint8Array(18) [ 1, 1, 212, 204, 137, 142, 6, 5, 132, 212, … ]
Test

But only the “T” is added to the view.
maybe the behavior comes from the schema of the prosemirror-view used by tui.editor ?

I found the guilty ! The proxy added by Vuejs on ref object !
Without it, it works like a charm with tui.editor 3 !

And for “I have tried to follow the demo and the code of the y-websocket and y-prosemirror but I can’t figure if i have to init the doc before or after the editor due to the JS asynchronous.” -> we can init when we want.

Well, thanks a lot for listenning :smiley: and for your work which is really impressive !

1 Like

Hey @Titanexx,

Happy you found a solution by yourself!

I needed some time out from the discussion boards and chats and will slowly come back. Just wanted you to know that I wasn’t ignoring you specifically.

Cheers,
Kevin