From 4e533affca2e81024c808cbeb3dbb866a01401d5 Mon Sep 17 00:00:00 2001 From: Max Date: Thu, 18 Jan 2024 12:14:40 +0100 Subject: [PATCH] fix(sync): yjs messages are Uint8Arrays in the queue Remove duplicate encoding for updateMessage Signed-off-by: Max Signed-off-by: Jonas --- cypress/component/helpers/yjs.cy.js | 2 +- src/helpers/yjs.js | 26 +++++++++++++++++++------- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/cypress/component/helpers/yjs.cy.js b/cypress/component/helpers/yjs.cy.js index 6f4d261383f..7472e28adc8 100644 --- a/cypress/component/helpers/yjs.cy.js +++ b/cypress/component/helpers/yjs.cy.js @@ -70,7 +70,7 @@ describe('Yjs base64 wrapped with our helpers', function() { const stateA = getDocumentState(source) const update0A = getUpdateMessage(source, state0) const updateAA = getUpdateMessage(source, stateA) - expect(update0A.length).to.be.eq(40) + expect(update0A.length).to.be.eq(29) expect(updateAA).to.be.eq(undefined) }) diff --git a/src/helpers/yjs.js b/src/helpers/yjs.js index 6ed897eff76..01d4af2df03 100644 --- a/src/helpers/yjs.js +++ b/src/helpers/yjs.js @@ -21,7 +21,11 @@ */ import { encodeArrayBuffer, decodeArrayBuffer } from '../helpers/base64.js' -import { Doc, encodeStateAsUpdate, applyUpdate } from 'yjs' +import * as Y from 'yjs' +import * as decoding from 'lib0/decoding.js' +import * as encoding from 'lib0/encoding.js' +import * as syncProtocol from 'y-protocols/sync' +import { messageSync } from 'y-websocket' /** * Get Document state encode as base64. @@ -51,7 +55,7 @@ export function applyDocumentState(ydoc, documentState, origin) { * * @param {Y.Doc} ydoc - encode state of this doc * @param {string} encodedBaseUpdate - base64 encoded doc update to build upon - * @return {string|undefined} + * @return {Uint8Array|undefined} */ export function getUpdateMessage(ydoc, encodedBaseUpdate) { const baseUpdate = decodeArrayBuffer(encodedBaseUpdate) @@ -65,8 +69,7 @@ export function getUpdateMessage(ydoc, encodedBaseUpdate) { encoding.writeVarUint(encoder, messageSync) const update = Y.encodeStateAsUpdate(ydoc, baseStateVector) syncProtocol.writeUpdate(encoder, update) - const buf = encoding.toUint8Array(encoder) - return encodeArrayBuffer(buf) + return encoding.toUint8Array(encoder) } /** @@ -74,12 +77,11 @@ export function getUpdateMessage(ydoc, encodedBaseUpdate) { * * Only used in tests right now. * @param {Y.Doc} ydoc - encode state of this doc - * @param {string} updateMessage - base64 encoded y-websocket sync message with update + * @param {Uint8Array} updateMessage - y-websocket sync message with update * @param {object} origin - initiator object e.g. WebsocketProvider */ export function applyUpdateMessage(ydoc, updateMessage, origin = 'origin') { - const updateBuffer = decodeArrayBuffer(updateMessage) - const decoder = decoding.createDecoder(updateBuffer) + const decoder = decoding.createDecoder(updateMessage) const messageType = decoding.readVarUint(decoder) if (messageType !== messageSync) { console.error('y.js update message with invalid type', messageType) @@ -94,3 +96,13 @@ export function applyUpdateMessage(ydoc, updateMessage, origin = 'origin') { origin, ) } + +/** + * Helper function to check if two state vectors have the same state + * @param {Array} arr - state vector to compare + * @param {Array} other - state vector to compare against + */ +function sameState(arr, other) { + return arr.length === other.length + && arr.every((value, index) => other[index] === value) +}