Collaborative editing and the central authority

Hi. I’m making collaborative editing, now my code is working, it looks like this:

Client

dispatchTransaction(transaction: Transaction): void {
  const newState: EditorState = this.state.apply(transaction);

  view.updateState(newState);

  const sendable = sendableSteps(state);

  if (sendable) {
    this.socket.emit('update', sendable);
  }
}

this.socket.socket.on('updated', (data): void => {
  view.updateState(
    view.state.apply(
      receiveTransaction(
        view.state,
        data.steps.map((step: JSON): Step => Step.fromJSON(view.state.schema, step)),
        data.clientIDs,
      ),
    ),
  ),
});

Server
public async onNewMessage(@MessageBody() data): Promise<void> {
  const steps = data.steps.forEach((json: JSON): void => {
    this.document = Step.fromJSON(schema, json).apply(this.document).doc;
  });

  this.server.emit('updated', {
    version: data.version + steps.length,
    steps,
    clientIDs: data.steps.map(() => data.clientID),
  });
}

Everything works fine as long as editing happens “calmly”. When I start typing very fast, something strange happens to the document of the recipient of the changes, not the same as in the original document. And at some point my server crashes with the error: “Position X out of range”

I have a concrete example with socket events when this happened:

From the sender’s side:

image

From the recipient’s side:

image

What should I change? :face_with_peeking_eye: :melting_face: