When we use the Y.Doc, when receive message from server side, the doc update will trigger the observer that binded before. here we receive the server side message:
messageHandlers[SyncMessageType.MessageSync] = (
encoder: any,
decoder: any,
provider: SocketIOClientProvider,
emitSynced: any,
messageType: any
) => {
writeVarUint(encoder, SyncMessageType.MessageSync);
const syncMessageType = syncProtocol.readSyncMessage(
decoder,
encoder,
provider.doc,
provider
);
if (
emitSynced &&
syncMessageType === syncProtocol.messageYjsSyncStep2 &&
!provider.synced
) {
provider.synced = true;
}
};
then it will trigger the oberser and update the doc in codemirror:
this._observer = (event, tr) => {
console.log("triggering observer");
if (tr.origin !== this.conf) {
const delta = event.delta
const changes = []
let pos = 0
for (let i = 0; i < delta.length; i++) {
const d = delta[i]
if (d.insert != null) {
changes.push({ from: pos, to: pos, insert: d.insert })
} else if (d.delete != null) {
changes.push({ from: pos, to: pos + d.delete, insert: '' })
pos += d.delete
} else {
pos += d.retain
}
}
view.dispatch({ changes, annotations: [ySyncAnnotation.of(this.conf)] })
}
}
but when I update the subdocument, seems the chain could not work. what should I do to fixed it? This is the subdocument receive message code look like:
messageHandlers[SyncMessageType.SubDocMessageSync] = (
encoder: any,
decoder: any,
provider: SocketIOClientProvider,
emitSynced: boolean = true,
messageType: any
) => {
const docGuid = decoding.readVarString(decoder);
const doc = provider.getDoc(docGuid);
if (!doc) {
console.error("doc not found with id: ", docGuid);
return;
}
encoding.writeVarUint(encoder, SyncMessageType.SubDocMessageSync);
// convert to the legacy message without doc guid
encoding.writeVarString(encoder, docGuid);
const syncMessageType = syncProtocol.readSyncMessage(
decoder,
encoder,
doc,
provider
);
// main doc synced
if (
emitSynced &&
docGuid === provider.roomname &&
syncMessageType === syncProtocol.messageYjsSyncStep2 &&
!provider.synced
) {
provider.synced = true;
}
// sub doc synced
if (
emitSynced &&
docGuid !== provider.roomname &&
syncMessageType === syncProtocol.messageYjsSyncStep2 &&
!provider.syncedStatus.get(docGuid)
) {
console.info("sub doc synced, docGuid:" + docGuid);
provider.updateSyncedStatus(docGuid, true);
}
};
I have tried like this:
rootYdoc.on("subdocs", (props: SubDocEventProps) => {
console.warn("trigger sub docs");
props.loaded.forEach((subdoc: Y.Doc) => {
console.warn("add sub docs:" + subdoc.guid);
wsProvider.addSubdoc(subdoc);
const subDocText = subdoc.getText();
subDocText.observe((event, tr) => {
console.log("subdocument observed:" + subDocText.toString());
let conf = editorView.state.facet(ySyncFacet)
if (tr.origin !== conf) {
const delta = event.delta
const changes = []
let pos = 0
for (let i = 0; i < delta.length; i++) {
const d = delta[i]
if (d.insert != null) {
changes.push({ from: pos, to: pos, insert: d.insert })
} else if (d.delete != null) {
changes.push({ from: pos, to: pos + d.delete, insert: '' })
pos += d.delete
} else {
pos += d.retain!;
}
}
// @ts-ignore
editorView.dispatch({ changes, annotations: [ySyncAnnotation.of(conf)] })
}
});
});
});
the observe has no data.