Skip to content

Commit 44779a6

Browse files
committed
add hocuspocus server
1 parent 47efd75 commit 44779a6

File tree

11 files changed

+486
-421
lines changed

11 files changed

+486
-421
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env node
2+
3+
/**
4+
* Hocuspocus (Yjs WebSocket) Server for ChatBox v2
5+
*
6+
* Provides real-time shared state via Yjs documents served over WebSocket.
7+
* Each application room maps to a Yjs document. Presence is handled through
8+
* Hocuspocus awareness on the client side.
9+
*
10+
* Env vars:
11+
* PORT - HTTP/WebSocket port (default 3006)
12+
* HOST - Bind address (default 0.0.0.0)
13+
* HOCUSPOCUS_SECRET - Optional shared secret for token auth
14+
*
15+
* Usage: node hocuspocus-server.js
16+
*/
17+
18+
import { Server } from "@hocuspocus/server";
19+
20+
const PORT = parseInt(process.env.PORT || "3006", 10);
21+
const HOST = process.env.HOST || "0.0.0.0";
22+
const SECRET = process.env.HOCUSPOCUS_SECRET || "";
23+
24+
function writeJson(response, statusCode, payload) {
25+
response.writeHead(statusCode, { "Content-Type": "application/json" });
26+
response.end(JSON.stringify(payload));
27+
}
28+
29+
const server = new Server({
30+
name: "lowcoder-hocuspocus",
31+
quiet: true,
32+
address: HOST,
33+
port: PORT,
34+
35+
async onListen() {
36+
console.log(`[hocuspocus] listening on ws://${HOST}:${PORT}`);
37+
},
38+
39+
async onRequest({ request, response }) {
40+
if (request.url === "/health") {
41+
writeJson(response, 200, {
42+
status: "ok",
43+
host: HOST,
44+
port: PORT,
45+
auth: SECRET ? "enabled" : "disabled",
46+
});
47+
return;
48+
}
49+
50+
if (request.url === "/") {
51+
writeJson(response, 200, {
52+
name: "lowcoder-hocuspocus",
53+
websocket: `ws://${HOST}:${PORT}`,
54+
health: "/health",
55+
});
56+
}
57+
},
58+
59+
async onAuthenticate({ token, documentName }) {
60+
if (!SECRET) {
61+
return;
62+
}
63+
64+
if (token !== SECRET) {
65+
console.warn(`[hocuspocus] rejected connection for ${documentName}: invalid token`);
66+
throw new Error("Unauthorized");
67+
}
68+
},
69+
70+
async onConnect({ documentName, socketId }) {
71+
console.log(`[hocuspocus] connect socket=${socketId} document=${documentName}`);
72+
},
73+
74+
async onDisconnect({ documentName, socketId }) {
75+
console.log(`[hocuspocus] disconnect socket=${socketId} document=${documentName}`);
76+
},
77+
});
78+
79+
try {
80+
await server.listen();
81+
} catch (error) {
82+
console.error("[hocuspocus] failed to start", error);
83+
process.exit(1);
84+
}

client/packages/lowcoder/package.json

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,14 +30,11 @@
3030
"@fortawesome/free-regular-svg-icons": "^6.5.1",
3131
"@fortawesome/free-solid-svg-icons": "^6.5.1",
3232
"@fortawesome/react-fontawesome": "latest",
33+
"@hocuspocus/provider": "^3.4.4",
34+
"@hocuspocus/server": "^3.4.4",
3335
"@jsonforms/core": "^3.5.1",
3436
"@lottiefiles/dotlottie-react": "^0.13.0",
3537
"@manaflair/redux-batch": "^1.0.0",
36-
"@pluv/client": "^4.0.1",
37-
"@pluv/crdt-yjs": "^4.0.1",
38-
"@pluv/io": "^4.0.1",
39-
"@pluv/platform-pluv": "^4.0.1",
40-
"@pluv/react": "^4.0.1",
4138
"@radix-ui/react-avatar": "^1.1.10",
4239
"@radix-ui/react-dialog": "^1.1.14",
4340
"@radix-ui/react-slot": "^1.2.3",
@@ -141,7 +138,6 @@
141138
"scripts": {
142139
"supportedBrowsers": "yarn dlx browserslist-useragent-regexp --allowHigherVersions '>0.2%,not dead,not op_mini all,chrome >=69'",
143140
"start": "REACT_APP_LOG_LEVEL=debug REACT_APP_ENV=local vite",
144-
"start:pluv": "node pluv-server.js",
145141
"build": "vite build && cp ../../VERSION ./build/VERSION",
146142
"preview": "vite preview",
147143
"prepare": "husky install"

client/packages/lowcoder/pluv-server.js

Lines changed: 0 additions & 152 deletions
This file was deleted.

client/packages/lowcoder/src/comps/comps/chatBoxComponentv2/chatBoxComp.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -259,8 +259,6 @@ let ChatBoxV2Tmp = (function () {
259259
const typingUsers = Array.isArray(props.typingUsers) ? props.typingUsers : [];
260260
const onlineUsers = Array.isArray(props.onlineUsers) ? props.onlineUsers : [];
261261
const isAiThinking = Boolean(props.isAiThinking);
262-
// DEBUG: Log onlineUsers to verify data flow from ChatController
263-
console.log("[ChatBox] onlineUsers prop:", onlineUsers.length, onlineUsers.map((u: any) => u.userId));
264262
const pendingInvites = (Array.isArray(props.pendingInvites)
265263
? props.pendingInvites
266264
: []) as unknown as PendingRoomInvite[];

0 commit comments

Comments
 (0)