From 830c0d49ad415df746cd3947a1a06e2b25be873b Mon Sep 17 00:00:00 2001 From: Max Date: Mon, 11 Dec 2023 14:51:49 +0100 Subject: [PATCH] fix(sync): keep queue around during reconnects When yjs does not receive awareness updates it will close and reopen the websocket. Keep the content of the queue, i.e. the outgoing steps so they can be send out once the connection is back. --- cypress/e2e/api/SyncServiceProvider.spec.js | 2 ++ src/components/Editor.vue | 2 ++ src/services/SyncServiceProvider.js | 5 +++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cypress/e2e/api/SyncServiceProvider.spec.js b/cypress/e2e/api/SyncServiceProvider.spec.js index aae87849b4e..2d0e940fb8f 100644 --- a/cypress/e2e/api/SyncServiceProvider.spec.js +++ b/cypress/e2e/api/SyncServiceProvider.spec.js @@ -60,6 +60,7 @@ describe('Sync service provider', function() { * @param {object} ydoc Yjs document */ function createProvider(ydoc) { + const queue = [] const syncService = new SyncService({ serialize: () => 'Serialized', getDocumentState: () => null, @@ -70,6 +71,7 @@ describe('Sync service provider', function() { syncService, fileId, initialSession: null, + queue, disableBc: true, }) } diff --git a/src/components/Editor.vue b/src/components/Editor.vue index 407004d9992..6b4cce51790 100644 --- a/src/components/Editor.vue +++ b/src/components/Editor.vue @@ -329,6 +329,7 @@ export default { }, created() { this.$ydoc = new Doc() + this.$queue = [] // The following can be useful for debugging ydoc updates // this.$ydoc.on('update', function(update, origin, doc, tr) { // console.debug('ydoc update', update, origin, doc, tr) @@ -381,6 +382,7 @@ export default { ydoc: this.$ydoc, syncService: this.$syncService, fileId: this.fileId, + queue: this.$queue, initialSession: this.initialSession, }) this.$providers.push(syncServiceProvider) diff --git a/src/services/SyncServiceProvider.js b/src/services/SyncServiceProvider.js index dc015304f97..8dff59e4e6c 100644 --- a/src/services/SyncServiceProvider.js +++ b/src/services/SyncServiceProvider.js @@ -30,15 +30,16 @@ import { logger } from '../helpers/logger.js' * @param {object} options.ydoc - the Ydoc * @param {object} options.syncService - sync service to build upon * @param {number} options.fileId - file id of the file to open + * @param {number} options.queue - queue for outgoing steps * @param {object} options.initialSession - initialSession to start from * @param {boolean} options.disableBc - disable broadcast channel synchronization (default: disabled in debug mode, enabled otherwise) */ -export default function createSyncServiceProvider({ ydoc, syncService, fileId, initialSession, disableBc }) { +export default function createSyncServiceProvider({ ydoc, syncService, fileId, initialSession, queue, disableBc }) { if (!fileId) { // We need a file id as a unique identifier for y.js as otherwise state might leak between different files throw new Error('fileId is required') } - const WebSocketPolyfill = initWebSocketPolyfill(syncService, fileId, initialSession) + const WebSocketPolyfill = initWebSocketPolyfill(syncService, fileId, initialSession, queue) disableBc = disableBc ?? !!window?._oc_debug const websocketProvider = new WebsocketProvider( 'ws://localhost:1234',