Skip to content

Commit

Permalink
fix(sync): yjs messages are Uint8Arrays in the queue
Browse files Browse the repository at this point in the history
Remove duplicate encoding for updateMessage

Signed-off-by: Max <max@nextcloud.com>
Signed-off-by: Jonas <jonas@freesources.org>
  • Loading branch information
max-nextcloud authored and mejo- committed Jan 29, 2024
1 parent 66e5128 commit da3fcaf
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 8 deletions.
2 changes: 1 addition & 1 deletion cypress/component/helpers/yjs.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})

Expand Down
26 changes: 19 additions & 7 deletions src/helpers/yjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand All @@ -65,21 +69,19 @@ 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)
}

/**
* Apply an updated message to the ydoc.
*
* 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)
Expand All @@ -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)
}

0 comments on commit da3fcaf

Please sign in to comment.