I am using Lexical editor based on this documentation: React | Lexical
In my custom y-websocket server I store updated in db using y-mongodb.
export default function setupWSConnection(conn: WebSocket, req: http.IncomingMessage) {
...
const [doc, isNew] = getYDoc(docName);
doc.conns.set(conn, new Set());
// listen and reply to events
conn.on('message', (message: ArrayBuffer) => messageListener(conn, doc, new Uint8Array(message)));
if (isNew) {
doc.on('update', async (update: Uint8Array) => {
await mongoDbPersistence.storeUpdate(docName, update);
});
}
Meanwhile, on the client side, I store the editor state from Lexical in another collection.
On last disconnect I remove everything from DB
export const closeConn = (doc: WSSharedDoc, conn: WebSocket): void => {
const controlledIds = doc.conns.get(conn);
if (controlledIds) {
doc.conns.delete(conn);
awarenessProtocol.removeAwarenessStates(doc.awareness, Array.from(controlledIds), null);
if (doc.conns.size === 0) {
doc.destroy();
docs.delete(doc.name);
// remove from db, if the init from client works we will remove mongodb persistence
mongoDbPersistence.clearDocument(doc.name).catch(e => {
logger.error(e, `Cannot remove doc: ${doc.name} from db %e`, e);
});
}
}
conn.close();
};
I do this to know if I should bootstrap the Lexical editor with the initial editor state which comes from another collection and is the source of truth. If there are no yjs transactions in DB then the editor should bootstrap, else just initialize and get the state from YDoc.
This approach works ok on one container.
But when users connect from different containers, there are 2 instances of YDoc.
When one user from Container A refreshed the page on one instance of WebSocket server the doc.conns.size === 0
and it removes the yjs-transactions from DB. After page loads the DB is empty and the editor bootstraps the YDoc with it’s state from another collection.
How do I make sure that connections are shared across several instances of YDoc on separate WebSocket containers?