Fix batching of events
Instead of delaying edits to the Y.Doc, make all edits immediately. But combine the resulting updates into a single update before sending it to the other doc.
This commit is contained in:
+25
-17
@@ -19,7 +19,7 @@ const ta2 = document.getElementById('ta2') as HTMLTextAreaElement;
|
|||||||
function bind(text: Y.Text, el: HTMLTextAreaElement) {
|
function bind(text: Y.Text, el: HTMLTextAreaElement) {
|
||||||
el.value = text.toString();
|
el.value = text.toString();
|
||||||
|
|
||||||
const handle = _.debounce(() => {
|
const handle = () => {
|
||||||
let prev = text.toString();
|
let prev = text.toString();
|
||||||
let curr = el.value;
|
let curr = el.value;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
@@ -40,11 +40,32 @@ function bind(text: Y.Text, el: HTMLTextAreaElement) {
|
|||||||
text.delete(offset, prev.length);
|
text.delete(offset, prev.length);
|
||||||
text.insert(offset, curr);
|
text.insert(offset, curr);
|
||||||
});
|
});
|
||||||
}, 500);
|
};
|
||||||
|
|
||||||
el.addEventListener('input', (_ev) => {
|
el.addEventListener('input', (_ev) => {
|
||||||
handle();
|
handle();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
text.doc!.on('update', () => {
|
||||||
|
el.value = text.toString();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function pipe(src: Y.Doc, dest: Y.Doc) {
|
||||||
|
let prevStateVector = Y.encodeStateVector(src);
|
||||||
|
|
||||||
|
const flush = _.debounce(
|
||||||
|
() => {
|
||||||
|
const update = Y.encodeStateAsUpdate(src, prevStateVector);
|
||||||
|
prevStateVector = Y.encodeStateVector(src);
|
||||||
|
setTimeout(() => Y.applyUpdate(dest, update), _.random(2500, 5000));
|
||||||
|
},
|
||||||
|
1000,
|
||||||
|
{
|
||||||
|
maxWait: 2000,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
src.on('update', flush);
|
||||||
}
|
}
|
||||||
|
|
||||||
const doc1 = new Y.Doc();
|
const doc1 = new Y.Doc();
|
||||||
@@ -52,22 +73,9 @@ bind(doc1.getText(), ta1);
|
|||||||
const doc2 = new Y.Doc();
|
const doc2 = new Y.Doc();
|
||||||
bind(doc2.getText(), ta2);
|
bind(doc2.getText(), ta2);
|
||||||
|
|
||||||
doc1.on('update', async (update) => {
|
pipe(doc1, doc2);
|
||||||
await new Promise((res, _rej) =>
|
pipe(doc2, doc1);
|
||||||
setTimeout(res, 3000 * Math.random() + 2000)
|
|
||||||
);
|
|
||||||
Y.applyUpdate(doc2, update);
|
|
||||||
ta2.value = doc2.getText().toString();
|
|
||||||
});
|
|
||||||
doc2.on('update', async (update) => {
|
|
||||||
await new Promise((res, _rej) =>
|
|
||||||
setTimeout(res, 3000 * Math.random() + 2000)
|
|
||||||
);
|
|
||||||
Y.applyUpdate(doc1, update);
|
|
||||||
ta1.value = doc1.getText().toString();
|
|
||||||
});
|
|
||||||
|
|
||||||
doc1.getText().insert(0, 'foo bar baz');
|
doc1.getText().insert(0, 'foo bar baz');
|
||||||
ta1.value = doc1.getText().toString();
|
|
||||||
|
|
||||||
(window as any).Y = Y;
|
(window as any).Y = Y;
|
||||||
|
|||||||
Reference in New Issue
Block a user