@NataliaMolchanova - I will share our found and solution here for anyone who needs it:
Real user update:
You can extract the clientID from the result of Y.decodeUpdate(update)
(ideally your server can store the map of this yjs clientID to the real user in your application)
Sync/update events when the first time load data from LevelDB
The problem(we use LevelDB to persist the updates data):
-
- When the first user access a ydoc that the ydoc data haven’t loaded yet from LevelDB.
-
- The Server(i.e. bindState) will try to load the ydoc data from LevelDB Asynchronously
-
- The Server will send this ydoc data to the client as an initial step which client code will not treat as a user update.
(See more details about sync steps here https://github.com/yjs/y-protocols/blob/ba21a9c92990743554e47223c49513630b7eadda/sync.js#L15)
- The Server will send this ydoc data to the client as an initial step which client code will not treat as a user update.
The problem is on the #3 step, as the above #2 loading step is asynchronous process, so when running #3 step, the #2 ydoc data is not ready yet and finally client initialize with emtpty ydoc, later #2 data is loaded and send to client treat as a normal user update, this will trigger client update event, then finally send to the server again, so this is why we see server ydoc update events during the initial sync, eve user didn’t change any content.
Solution:
We did some changes to the utils.js
and client y-websocket.js
,
When the “messageYjsSyncStep1” message(in messageListener
) from the client triggers the bindState method to load data from the LevelDB, we will just store this connection and data #1 first, then waiting read LevelDB to finish, then send all the data to the client at #2, we defined new message type to do this.
I know maybe this is hard to understand the whole thing, and I am not sure how to explain all the details as I can’t simply share the entire code.