Recently I have added subdocument for my project, I am using the subdocument observe to update the codemirror like this:
// Add observer for future changes
subDocText.observe((event: Y.YTextEvent, tr: Y.Transaction) => {
console.log("Subdoc text changed:", {
docId: subdoc.guid,
delta: event.delta,
currentText: subDocTextString,
});
updateEditor(editorView, tr, event, subdoc);
});
this is the update logic:
export const updateEditor = (
editorView: EditorView | undefined,
tr: Y.Transaction,
event: Y.YTextEvent,
doc: Y.Doc
) => {
console.log("subdocument observed:", doc.guid);
if (!editorView) {
console.error("EditorView is null:");
return;
}
let conf = editorView.state.facet(ySyncFacet);
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!;
}
}
if (changes.length === 0) {
console.warn("No changes found in the delta.");
return
}
editorView.dispatch({
// @ts-ignore
changes,
annotations: [ySyncAnnotation.of(conf)],
});
};
I found the delta was array and has no content to update, and I still did not found the observe in codemirror.next plugin:
constructor (view) {
this.view = view
this.conf = view.state.facet(ySyncFacet)
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)] })
}
}
this._ytext = this.conf.ytext
this._ytext.observe(this._observer)
}
this is the function handle the subdocument message:
messageHandlers[SyncMessageType.SubDocMessageSync] = (
encoder: any,
decoder: any,
provider: SocketIOClientProvider,
emitSynced: boolean = true,
messageType: any
) => {
console.info("doc map: ", JSON.stringify(provider.docs));
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 hasContent = decoding.hasContent(decoder);
if (!hasContent) {
console.error("sub doc message sync has no content");
}
console.warn("sub doc message sync with content,docGuid:", docGuid);
let copiedDecoder = decoding.clone(decoder);
if (!enableTracing()) {
logYjsUnwrapMsg(copiedDecoder);
}
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);
}
};
how does the yjs trigger codemirror update?