Hi @dmonad, thanks for the yjs library. I’m trying to build a collaborative editor with yjs-websocket (codemirror binding) and create-react-app with node.js in the back-end. Whenever I try to run, the sync stops after sometime. Please have a look:
The code is quite simple
This is my front-end
import React, { useEffect, useRef, useState } from "react";
import * as Y from "yjs";
import { WebsocketProvider } from "y-websocket";
import { CodemirrorBinding } from "y-codemirror";
import { Controlled as CodeMirror } from "react-codemirror2";
import { useParams } from "react-router-dom";
const CodeMirrorEditor = ({ userName }) => {
const [codeMirrorText, setCodeMirrorText] = useState("");
const codeMirrorRef = useRef();
const { roomId } = useParams();
const handleChange = (value) => {
setCodeMirrorText(value);
};
useEffect(() => {
if (!codeMirrorRef.current) return;
const ydoc = new Y.Doc({
meta: {
cellId: roomId,
},
});
const wsProvider = new WebsocketProvider(
"ws://localhost:1234",
roomId,
ydoc
);
const yText = ydoc.getText(`codemirror`);
wsProvider.awareness.setLocalStateField("user", {
name: userName,
color: "#ffaabb",
});
const _codemirrorBinding = new CodemirrorBinding(
yText,
codeMirrorRef.current,
wsProvider.awareness
);
return () => {
_codemirrorBinding.destroy();
wsProvider.destroy();
};
}, [roomId, userName]);
return (
<CodeMirror
editorDidMount={(editor) => {
codeMirrorRef.current = editor;
}}
value={codeMirrorText}
onBeforeChange={(_editor, _data, value) => {
handleChange(value);
}}
/>
);
};
export default CodeMirrorEditor;
Backend:
import pkg from "ws";
import { setupWSConnection, setPersistence } from "y-websocket/bin/utils.js";
import * as Y from "yjs";
import express from "express";
const { Server: WsServer } = pkg;
const app = express();
app.use(express.json());
const notes = {
1: `# Welcome to Live Collab`,
};
const port = process.env.PORT || 1234;
const wss = new WsServer({ noServer: true });
setPersistence({
bindState: async (id, doc) => {
const foundNote = notes.hasOwnProperty(id);
const foundSourceCode = foundNote ? notes[id] : "";
const yText = doc.getText("codemirror");
yText.insert(0, foundSourceCode);
const ecodedState = Y.encodeStateAsUpdate(doc);
doc.on("update", (update) => {
Y.applyUpdate(doc, update);
});
return Y.applyUpdate(doc, ecodedState);
},
writeState: (_identifier, _doc) => {
delete notes[_identifier];
return new Promise((resolve) => {
resolve();
});
},
});
wss.on("connection", setupWSConnection);
const server = app.listen(port, () => {
console.log(`Server listening at http://localhost:${port}`);
});
server.on("upgrade", (request, socket, head) => {
const handleAuth = (ws) => {
wss.emit("connection", ws, request);
};
wss.handleUpgrade(request, socket, head, handleAuth);
});
app.post("/:id", (req, res) => {
const { id } = req.params;
notes[id] = req.body.content;
});
Please have a look when you get time. Is there anything that I’ve done wrong? Please let me know. Thanks