const { WebSocketServer, WebSocket } = require('ws'); const http = require('http'); const PORT = process.env.PORT || 8080; const server = http.createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('SyncWatch server running\n'); }); const wss = new WebSocketServer({ server }); // Map> const rooms = new Map(); function generateCode() { let code; do { code = Math.floor(100000 + Math.random() * 900000).toString(); } while (rooms.has(code)); return code; } function broadcast(room, message, exclude) { const data = JSON.stringify(message); for (const client of room) { if (client !== exclude && client.readyState === WebSocket.OPEN) { client.send(data); } } } wss.on('connection', (ws) => { ws.roomCode = null; ws.on('message', (raw) => { let msg; try { msg = JSON.parse(raw); } catch { return; } switch (msg.type) { case 'create': { if (ws.roomCode) return; const code = generateCode(); rooms.set(code, new Set([ws])); ws.roomCode = code; ws.send(JSON.stringify({ type: 'created', code })); break; } case 'join': { if (ws.roomCode) return; const code = String(msg.code || ''); const room = rooms.get(code); if (!room) { ws.send(JSON.stringify({ type: 'error', message: 'Room not found' })); return; } if (room.size >= 2) { ws.send(JSON.stringify({ type: 'error', message: 'Room is full' })); return; } room.add(ws); ws.roomCode = code; ws.send(JSON.stringify({ type: 'joined', code, memberCount: room.size })); broadcast(room, { type: 'peer_joined' }, ws); break; } case 'sync': { if (!ws.roomCode) return; const room = rooms.get(ws.roomCode); if (!room) return; broadcast(room, { type: 'sync', action: msg.action, time: msg.time }, ws); break; } case 'ping': ws.send(JSON.stringify({ type: 'pong' })); break; } }); ws.on('close', () => { if (!ws.roomCode) return; const room = rooms.get(ws.roomCode); if (!room) return; room.delete(ws); if (room.size === 0) { rooms.delete(ws.roomCode); } else { broadcast(room, { type: 'peer_left' }, null); } }); }); server.listen(PORT, () => { console.log(`SyncWatch server listening on port ${PORT}`); });