/
effective_wiki
/
backend
Обзор
Документация
Войти
/
effective_wiki
/
backend
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
master
hocuspocus-server/server.js
162 строки
4 KB
Max-Sam231
feat: add new server
17 дек 2025, 13:40
17 дек 2025, 13:40
ff1b6f6
Код
Авторство
О чём код?
import { Server } from "@hocuspocus/server"; import dotenv from "dotenv"; dotenv.config(); const PORT = Number(process.env.HOCUSPOCUS_PORT) || 1234; const GO_BACKEND_URL = process.env.GO_BACKEND_URL; /* Environment setup (.env): HOCUSPOCUS_PORT=1234 # optional, defaults to 1234 GO_BACKEND_URL=http://host:8080 Run server: npm install npm run dev */ const server = Server.configure({ port: PORT, debounce: 5000, // Загрузка документа при подключении async onLoadDocument(data) { const pageId = data.document.name; console.log(`📥 Loading document: ${pageId}`); try { const response = await fetch(`${GO_BACKEND_URL}/api/pages/${pageId}`, { method: "GET", headers: { "Content-Type": "application/json", }, }); if (response.ok) { const page = await response.json(); // загружаем контент if (page?.content) { const yContent = data.document.getArray("content"); if (Array.isArray(page.content.content)) { yContent.delete(0, yContent.length); yContent.insert(0, [page.content]); console.log(`✅ Document loaded: ${pageId}`); } else { const yMap = data.document.getMap("shared"); yMap.set("content", page.content); console.log(`✅ Document loaded (as Map): ${pageId}`); } } else { console.log(`⚠️ Document ${pageId} has no content, starting empty`); } } else { console.warn(`⚠️ Failed to load ${pageId}: ${response.status}`); } } catch (error) { console.error(`❌ Error loading ${pageId}:`, error.message); // Продолжаем работу даже если ошибка загрузки } }, // Сохранение документа после изменений async onStoreDocument(data) { const pageId = data.document.name; try { let content = null; const yArray = data.document.getArray("content"); if (yArray && yArray.length > 0) { content = yArray.toArray()[0]; } if (!content) { const yMap = data.document.getMap("shared"); content = yMap.get("content"); } if (!content) { const yText = data.document.getText("shared"); const fullText = yText.toString(); try { content = JSON.parse(fullText); } catch { content = fullText; } } console.log( `💾 Storing document: ${pageId}`, JSON.stringify(content).substring(0, 100) ); // 🟢 ОТПРАВЛЯЕМ В GO-СЕРВЕР const response = await fetch(`${GO_BACKEND_URL}/api/pages/${pageId}`, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ content: content, updatedBy: "hocuspocus-server", timestamp: new Date().toISOString(), }), }); if (response.ok) { console.log(`✅ Saved: ${pageId}`); } else { const errorText = await response.text(); console.error( `❌ Failed to save ${pageId}: ${response.status} - ${errorText}` ); } } catch (error) { console.error(`❌ Error saving ${pageId}:`, error.message); } }, // При подключении пользователя onConnect(data) { console.log(`✅ User connected to: ${data.documentName}`); console.log(` Socket ID: ${data.socketId}`); }, // При отключении пользователя onDisconnect(data) { console.log(`❌ User disconnected from: ${data.documentName}`); console.log(` Remaining connections: ${data.clientsCount}`); }, // Обработка ошибок onError(data) { console.error(`❌ Server error:`, data.error); }, }); // Запускаем сервер server .listen() .then(() => { console.log("✅ Hocuspocus server started successfully"); console.log(`🚀 Server running on ws://localhost:${PORT}`); console.log(`📡 Backend URL: ${GO_BACKEND_URL}`); }) .catch((error) => { console.error("❌ Failed to start server:", error); process.exit(1); }); process.on("SIGINT", () => { console.log("\n🛑 Shutting down server…"); server.destroy(); process.exit(0); }); process.on("unhandledRejection", (error) => { console.error("❌ Unhandled rejection:", error); });