Hi! In continuation of my previous topic [Solved] Steps and collaborative editing.
I’m implementing collaborative editing, and now I have the following problem: when I edit a document in the first window, it’s updated in the second, but when after that I try to make changes in the second, an error occurs in the first.
Here’s how I send and receive changes:
// Send
this.view = new EditorView(target, {
state,
dispatchTransaction(transaction) {
const newState = this.state.apply(transaction);
this.updateState(newState);
const sendable = collab.sendableSteps(newState);
if (sendable) {
socket.emit('update',
sendable.version,
sendable.steps,
sendable.clientID,
);
}
},
});
// Receive
socket.on('updated', ([version, stepsJSON, clientID])=> {
if (clientID == userId) return false;
const steps = stepsJSON
.slice(collab.getVersion(this.view.state))
.map((json) => Step.fromJSON(this.view.state.schema, json));
const transaction: Transaction = collab.receiveTransaction(
this.view.state,
steps,
clientID,
{ mapSelectionBackward: true },
);
this.view.dispatch(transaction);
})
Initially, I have an empty document opened in two windows. My actions:
- I enter “1” in the first window. In the second I get:
And my code works! The editor accepts the update!
- I enter “2” in the second window. In the first I get:

Which is strange, if I do the same thing, but with a longer text, I get a different error already: “RangeError: Position X out of range”.
What am I missing? 
I understood that when I start typing, the cyclic dependence starts to occur, events begin to follow each other endlessly. I think that I’m missing something conceptual, but can’t understand what. I have read documentation and the source files of the example, but cannot see where my problem might be. In fact, I believe that it’s related to versions of documents that I should be controlling… Or maybe not…
My code hasn’t changed, now it looks like this:
const view = new EditorView(target, {
state,
dispatchTransaction(transaction) {
const newState = this.state.apply(transaction);
view.updateState(newState);
const sendable = sendableSteps(newState);
if (sendable) {
socket.emit('update', sendable);
}
}
});
socket.on('updated', ({ version, steps, clientId }) => {
if (clientId == userId) return false;
const transaction = receiveTransaction(
view.state,
steps
.slice(getVersion(view.state))
.map((json) => Step.fromJSON(view.state.schema, json)),
clientId ?? 0,
);
view.dispatch(transaction);
});
This is all! When I make changes to the document, my socket-events start causing each other endlessly. What logic should I add to avoid this?
@marijn sorry to bother you, perhaps your eyes will immediately see the cause of my problem
I changed the way I applied the changes from another window:
socket.on('updated', ({ version, steps, clientID }) => {
if (clientID == userId) return false;
const transaction = receiveTransaction(
view.state,
steps
.slice(getVersion(view.state))
.map(json => Step.fromJSON(view.state.schema, json)),
clientID,
);
view.updateState(view.state.apply(transaction));
});
But I can still edit the document only from one window, the second one gets the changes, but when it initiates the changes itself, I get the error again: Uncaught (in promise) RangeError: Position X out of range

Can anyone see what I’m doing wrong?
Closed. I’ve made some nonsense here.