At the beginning of a session, you are not synced. After a time, the clients will sync with each other and you will see the latest value. Hence, it is important that you don’t overwrite content before you synced with the other clients.
const ymap = ydoc.getMap('my map')
doesn’t write any content to a Yjs document (hence the get
keyword). Only when calling something like ymap.set('value', someValue)
you will write content. Adding event listeners also doesn’t manipulate a Yjs document.
There is a possibility that your code populates the ymap
accidentally with initial content of the slider. At the beginning of a session, the client would set the value of the slider to value X, which will trigger an event listener that updates the value of the ymap
. This change can potentially overwrite the content from remote clients (in case of a conflict there is a 50/50 chance that the new client overwrites the existing content).
A collaborative slider could be implemented safely, without overwriting remote content like this:
const ymap = ydoc.getMap('slider')
ymap.observe(event => {
slider.setVal(ymap.get('value'))
})
/**
* Set the default value before you add the slider.on('change', ..) event listener.
* Otherwise every new clients set the value of ymap reverting it to the old state.
*/
slider.setVal(0)
slider.on('change', newVal => {
// only set the new ymap value when the user actively changes the default-state to a new value
ymap.set('value', newVal)
})
// This is an alternative (overoptimized) version that ensures that no value is written at the beginning of a session:
slider.on('change', newVal => {
if (newVal !== 0) {
ymap.set('value', newVal)
} else {
ymap.delete('value') // nothing will happen at the beginning of a session,
}
ymap.set('value', newVal)
})
This is just a suggestion. There are probably other ways from preventing clients from accidentally overwriting content at the beginning of a session.
Alternatively, when using y-websocket, you could also just listen to the synced
event so your new clients don’t have to populate the content of the ymap before you received the remote content. However, I highly recommend making your code independent from specific providers - the above code is more idiomatic.
websocketProvider.on('synced', () => {..})