-
-
Notifications
You must be signed in to change notification settings - Fork 42
Description
Please save me some time and use the following template. In 90% of all issues I can't reproduce the problem because I don't know what exactly you are doing, in which environment, or which y-* version is responsible. Just use the following template even if you think the problem is obvious.
Checklist
- Are you reporting a bug? Use github issues for bug reports and feature requests. For general questions, please use https://discuss.yjs.dev/
- Try to report your issue in the correct repository. Yjs consists of many modules. When in doubt, report it to https://github.com/yjs/yjs/issues/
Describe the bug
The project I'm working on has multiple codemirror states that represent different tabs in an editor, and uses a single codemirror view that can switch to render multiple codemirror states. If a doc that is in a background tab is modified by a remote peer, it becomes out of sync when it switches to the front.
const state1 = EditorState.create({
doc: "doc1",
extensions: [yCollabPlugin1],
})
const state2 = EditorState.create({
doc: "doc2",
extensions: [],
})
const view = new EditorView({
state: state1,
parent: document.body
})
// when switching tabs
view.setState(state2)
// when switching back
view.setState(state1)
In other words, when yCollab is installed on a codemirror state that goes offscreen (i.e. the view/editor switches to another state), the editor becomes out of sync and can't recover.
Expected behavior
I would expect the when the view plugin is destroyed changes will be queued up, and when the view is remounted, the changes are applied at once (with a warning if the resulting codemirror doc diverges from the yjs doc).
Environment Information
- Chrome: 132.0.6834.160
- y-codemirror.next: 0.3.5,
- y-webrtc: 10.3.0,
- yjs: 13.6.23
Additional context
Add any other context about the problem here.
One solution I was experimenting with is to create a simple diff and patch algorithm that was triggered when the doc was remounted, but I was wondering if there was a more official way of doing this or if this might be useful to include in this library?
import { diff } from 'fast-myers-diff'
const syncPlugin = (ytext: Y.Text) =>
ViewPlugin.fromClass(
class {
constructor(public view: EditorView) {
if (view.state.doc.toString() != ytext.toString()) {
const ystr = ytext.toString()
const mydiff = diff(view.state.doc.toString(), ystr)
const changes: ChangeSpec[] = []
for (const [sx, ex, sy, ey] of mydiff) {
changes.push({
from: sx,
to: ex,
insert: ystr.slice(sy, ey),
})
}
queueMicrotask(() => {
view.dispatch({
changes: changes,
annotations: [ySyncAnnotation.of(view.plugin(ySync)!.conf)]
})
})
}
}
},
)
- I'm a sponsor 💖
- This issue is a blocker for my project.