Hi, I am trying to work up a basic usage of the sync protocol based on y-protocol and y-websocket, but I am missing something as I can’t get 2 documents to sync and I am not sure.
Here are the basics of what I am trying to do:
- create a “Peer” class that handles initiating a peer, sharing updates, and receiving messages:
import * as syncProtocol from "y-protocols/sync";
import * as encoding from "lib0/encoding";
import * as decoding from "lib0/decoding";
export class Peer {
constructor(sendMsg, peerId) {
this._sendMsg = sendMsg;
this.peerId = peerId;
}
// Call this in response to message
applyMessage(msg, doc) {
const decoder = decoding.createDecoder(new Uint8Array(msg));
const encoder = encoding.createEncoder();
const syncMessageType = syncProtocol.readSyncMessage(
decoder,
encoder,
doc,
this.peerId
);
// Send response if we have one
if (encoding.length(encoder) > 0) {
this._sendMsg(encoding.toUint8Array(encoder));
}
}
// Call this on updates
notify(update) {
const encoder = encoding.createEncoder();
syncProtocol.writeUpdate(encoder, update);
const msg = encoding.toUint8Array(encoder);
this._sendMsg(msg);
}
// Call this when peer connects first time
init(doc) {
const encoder = encoding.createEncoder();
syncProtocol.writeSyncStep1(encoder, doc);
const msg = encoding.toUint8Array(encoder);
this._sendMsg(msg);
}
}
- Do a simple test to see if I can sync 2 yjs docs this way:
import * as Y from "yjs";
import { Peer } from "./src/peer.js";
// Create 2 docs
const doc = new Y.Doc();
const doc2 = new Y.Doc();
// Create 2 peers
let peer;
let peer2;
peer = new Peer((msg) => {
peer2.applyMessage(msg, doc2);
}, "A");
peer2 = new Peer((msg) => {
peer.applyMessage(msg, doc);
}, "B");
// When the docs are updated, notify
doc.on("update", (update) => {
peer.notify(update);
});
doc2.on("update", (update) => {
peer2.notify(update);
});
// Initialize both peers
peer.init(doc);
peer2.init(doc2);
// Make a change to 1 doc
doc.getArray("foo").insert(0, ["Hello world"]);
// See if the docs are any different
console.log("DOC", doc.toJSON());
console.log("DOC2", doc2.toJSON());
However, when I run that test the docs seem to only partially sync. I get the following logged out:
DOC { foo: [ 'Hello world' ] }
DOC2 { foo: undefined }
What am I missing here? From poking around, it seems like I am not getting SyncStep2 messages generated even though I thought syncProtocol.readSyncMessage would create them in response to receiving a SyncStep1 message
EDIT: OK I realize now that the code above is working, just my test to compare the docs wasn’t. If I add doc2.getArray("foo").get(0)
, I can then see that doc2 does have the data expected.
That leaves me with a new question: How do you inspect an entire doc in JSON, or check equality between 2 docs? I’m interested in the latter for unit testing purposes