diff --git a/src/services/WebSocketPolyfill.ts b/src/services/WebSocketPolyfill.ts index 7f2aa517bd7..aa6bfbf53d1 100644 --- a/src/services/WebSocketPolyfill.ts +++ b/src/services/WebSocketPolyfill.ts @@ -3,7 +3,7 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { decodeArrayBuffer } from '../helpers/base64.js' +import { decodeArrayBuffer, encodeArrayBuffer } from '../helpers/base64.js' import { logger } from '../helpers/logger.js' import getNotifyBus from './NotifyService' import type { Step, SyncService } from './SyncService.js' @@ -78,16 +78,24 @@ export default function initWebSocketPolyfill( send(step: Uint8Array) { // Useful for debugging what steps are sent and how they were initiated // logStep(step) - if (this.#processingVersion) { - // this is a direct response while processing the step - console.error(`Failed to process step ${this.#processingVersion}.`, { - lastSuccessfullyProcessed: syncService.version, - sendingSyncStep1: step, - }) - // Do not increase the syncService.version for the current steps - // as we failed to process them. - this.#processingVersion = 0 + + const encoded = encodeArrayBuffer(step) + const isSyncStep1 = encoded < 'AAE' + if (!this.#processingVersion || !isSyncStep1) { + syncService.sendStep(step) + return } + + // If `this.#processingVersion` is set, we're in the middle of applying steps of one version. + // If `isSyncStep1`, Yjs failed to integrate a message due to pending structs. + // Log and ask for recovery due to a not applied/missing step. + console.error(`Failed to process step ${this.#processingVersion}.`, { + lastSuccessfullyProcessed: syncService.version, + sendingSyncStep1: step, + }) + // Do not increase the syncService.version for the current steps + // as we failed to process them. + this.#processingVersion = 0 syncService.sendRecoveryStep(step) }