diff --git a/server/core/collaboration.mjs b/server/core/collaboration.mjs index 4722ea98..1dc476f6 100644 --- a/server/core/collaboration.mjs +++ b/server/core/collaboration.mjs @@ -1,16 +1,17 @@ -import { Server as HocuspocusServer } from '@hocuspocus/server' +import { Hocuspocus } from '@hocuspocus/server' import { Database } from '@hocuspocus/extension-database' -import * as Y from 'yjs' +import { WebSocketServer } from 'ws' export default { server: null, + wss: null, async init(httpServer) { - this.server = HocuspocusServer.configure({ + this.server = new Hocuspocus({ + port: null, quiet: true, async onAuthenticate({ token }) { - // Allow all authenticated users (token is passed from frontend) if (!token || token === 'anonymous') { throw new Error('Not authenticated') } @@ -20,30 +21,27 @@ export default { extensions: [ new Database({ async fetch({ documentName }) { - try { - WIKI.logger.debug(`Collab: fetching document ${documentName}`) - return null // Let Hocuspocus create fresh doc, editor loads content from store - } catch (err) { - WIKI.logger.warn(`Collab fetch error: ${err.message}`) - return null - } + WIKI.logger.debug(`Collab: fetch doc ${documentName}`) + return null }, async store({ documentName, state }) { - try { - WIKI.logger.debug(`Collab: storing state for ${documentName}`) - } catch (err) { - WIKI.logger.warn(`Collab store error: ${err.message}`) - } + WIKI.logger.debug(`Collab: store doc ${documentName}`) } }) ] }) - // Attach to HTTP server for WebSocket upgrade + // Create a WebSocket server without its own HTTP server + this.wss = new WebSocketServer({ noServer: true }) + + // Handle upgrade on the main HTTP server if (httpServer) { httpServer.on('upgrade', (request, socket, head) => { if (request.url && request.url.startsWith('/_collab')) { - this.server.handleUpgrade(request, socket, head) + this.wss.handleUpgrade(request, socket, head, (ws) => { + WIKI.logger.info(`Collab: WebSocket client connected for ${request.url}`) + this.server.handleConnection(ws, request) + }) } }) } diff --git a/server/package.json b/server/package.json index 5a0c0aa2..a86b2003 100644 --- a/server/package.json +++ b/server/package.json @@ -175,6 +175,7 @@ "uuid": "11.1.0", "validate.js": "0.13.1", "vue": "3.5.18", + "ws": "8.20.0", "xss": "1.0.15", "yjs": "13.6.30" }, diff --git a/server/pnpm-lock.yaml b/server/pnpm-lock.yaml index 69ba5a11..8740e406 100644 --- a/server/pnpm-lock.yaml +++ b/server/pnpm-lock.yaml @@ -425,6 +425,9 @@ importers: vue: specifier: 3.5.18 version: 3.5.18(typescript@5.6.3) + ws: + specifier: 8.20.0 + version: 8.20.0 xss: specifier: 1.0.15 version: 1.0.15 @@ -5136,8 +5139,8 @@ packages: utf-8-validate: optional: true - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + ws@8.20.0: + resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -5656,7 +5659,7 @@ snapshots: async-mutex: 0.5.0 kleur: 4.1.5 lib0: 0.2.117 - ws: 8.18.3 + ws: 8.20.0 y-protocols: 1.0.7(yjs@13.6.30) yjs: 13.6.30 transitivePeerDependencies: @@ -8597,7 +8600,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.18.3 + ws: 8.20.0 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -8624,7 +8627,7 @@ snapshots: whatwg-encoding: 3.1.1 whatwg-mimetype: 4.0.0 whatwg-url: 14.2.0 - ws: 8.18.3 + ws: 8.20.0 xml-name-validator: 5.0.0 transitivePeerDependencies: - bufferutil @@ -9527,7 +9530,7 @@ snapshots: debug: 4.4.1(supports-color@5.5.0) devtools-protocol: 0.0.1464554 typed-query-selector: 2.12.0 - ws: 8.18.3 + ws: 8.20.0 transitivePeerDependencies: - bare-buffer - bufferutil @@ -10588,7 +10591,7 @@ snapshots: ws@8.17.1: {} - ws@8.18.3: {} + ws@8.20.0: {} xml-crypto@6.1.2: dependencies: