BitPhinix / slate-yjs

Yjs binding for Slate
https://docs.slate-yjs.dev
MIT License
514 stars 73 forks source link

Content duplication in Slate-Yjs offline syncing #382

Open Maryam-Yumna opened 1 year ago

Maryam-Yumna commented 1 year ago

We were working on a collaborative editing project with Plate and YJs. We used the slate-yjs library, and we did the editor initialization as follows:

const sharedType = doc.getArray(“content”); const editor = useMemo(() => { const editor: any = withCursor( withYjs( withReact(withHistory(createPlateEditor({ plugins: plugins }))), sharedType ), provider.awareness ); return editor; }, [sharedType, provider, dbProvider]);

Everything is working well so far, but we are having an issue with the offline syncing, where the content gets duplicated when there is a concurrent change.

example:

  1. content before offline sync

Global warming is the long-term warming of the planet’s overall temperature. Though this warming trend has been going on for a long time, its pace has significantly increased in the last hundred years due to the burning of fossil fuels.

  1. when two users make concurrent changes to content

(If one user goes offline and changes the word “Though” to “Even though” and another user changes the word “Though” to “Although”, the whole content that is after that word is duplicated when the document gets synced.) Global warming is the long-term warming of the planet’s overall temperature. Even though this warming trend has been going on for a long time, its pace has significantly increased in the last hundred years due to the burning of fossil fuels. Although this warming trend has been going on for a long time, its pace has significantly increased in the last hundred years due to the burning of fossil fuels.

Is there any particular reason for this issue and Is there a way to fix the issue?

beeant0512 commented 4 months ago

i am using hocuspocus as backend server, and here is my solution to fix the issue

    async onLoadDocument(data) {
        if (data.document.isEmpty('content')) {
            const result = await selectYjsDocument(data.documentName);
            if (result) {
                Y.applyUpdate(
                    data.document,
                    fromBase64(result),
                    'snapshot-patch'
                );
            }
        }
        return data.document;
    }