import BinaryEncoder from '../Util/Binary/Encoder.js' import { readStateSet, writeStateSet } from './stateSet.js' import { writeDeleteSet } from './deleteSet.js' import ID from '../Util/ID/ID.js' import { RootFakeUserID } from '../Util/ID/RootID.js' export function stringifySyncStep1 (y, decoder, strBuilder) { let auth = decoder.readVarString() let protocolVersion = decoder.readVarUint() strBuilder.push(` - auth: "${auth}"`) strBuilder.push(` - protocolVersion: ${protocolVersion}`) // write SS let ssBuilder = [] let len = decoder.readUint32() for (let i = 0; i < len; i++) { let user = decoder.readVarUint() let clock = decoder.readVarUint() ssBuilder.push(`(${user}:${clock})`) } strBuilder.push(' == SS: ' + ssBuilder.join(',')) } export function sendSyncStep1 (connector, syncUser) { let encoder = new BinaryEncoder() encoder.writeVarString(connector.y.room) encoder.writeVarString('sync step 1') encoder.writeVarString(connector.authInfo || '') encoder.writeVarUint(connector.protocolVersion) writeStateSet(connector.y, encoder) connector.send(syncUser, encoder.createBuffer()) } /** * @private * Write all Items that are not not included in ss to * the encoder object. */ export function writeStructs (y, encoder, ss) { const lenPos = encoder.pos encoder.writeUint32(0) let len = 0 for (let user of y.ss.state.keys()) { let clock = ss.get(user) || 0 if (user !== RootFakeUserID) { const minBound = new ID(user, clock) const overlappingLeft = y.os.findPrev(minBound) const rightID = overlappingLeft === null ? null : overlappingLeft._id if (rightID !== null && rightID.user === user && rightID.clock + overlappingLeft._length > clock) { const struct = overlappingLeft._clonePartial(clock - rightID.clock) struct._toBinary(encoder) len++ } y.os.iterate(minBound, new ID(user, Number.MAX_VALUE), function (struct) { struct._toBinary(encoder) len++ }) } } encoder.setUint32(lenPos, len) } export function readSyncStep1 (decoder, encoder, y, senderConn, sender) { let protocolVersion = decoder.readVarUint() // check protocol version if (protocolVersion !== y.connector.protocolVersion) { console.warn( `You tried to sync with a Yjs instance that has a different protocol version (You: ${protocolVersion}, Client: ${protocolVersion}). `) y.destroy() } // write sync step 2 encoder.writeVarString('sync step 2') encoder.writeVarString(y.connector.authInfo || '') const ss = readStateSet(decoder) writeStructs(y, encoder, ss) writeDeleteSet(y, encoder) y.connector.send(senderConn.uid, encoder.createBuffer()) senderConn.receivedSyncStep2 = true if (y.connector.role === 'slave') { sendSyncStep1(y.connector, sender) } }