Alex Severyanov  ·  2026-03-25

vite-ws-plugin.ts

 1import type { Plugin } from 'vite';
 2import { createServer } from 'http';
 3
 4export function terminalWebSocket(): Plugin {
 5	let wsServer: ReturnType<typeof createServer> | null = null;
 6
 7	return {
 8		name: 'terminal-websocket',
 9		configureServer(server) {
10			server.httpServer?.once('listening', () => {
11				const addr = server.httpServer?.address();
12				const vitePort = typeof addr === 'object' && addr ? addr.port : 5173;
13				const wsPort = parseInt(process.env.VITE_LCR_WS_PORT || String(vitePort + 1000), 10);
14
15				wsServer = createServer();
16
17				import('./ws-handler.ts').then(({ attachWebSocket }) => {
18					attachWebSocket(wsServer!, vitePort);
19					wsServer!.listen(wsPort, '127.0.0.1', () => {
20						console.log(`  Terminal WebSocket on ws://localhost:${wsPort}/ws/terminal`);
21					});
22					wsServer!.on('error', (err: any) => {
23						if (err.code === 'EADDRINUSE') {
24							console.error(`  Terminal WebSocket port ${wsPort} in use. Set LCR_WS_PORT to a different port.`);
25						}
26					});
27				}).catch((err) => {
28					console.error('Failed to attach terminal WebSocket:', err);
29				});
30			});
31		},
32		closeBundle() {
33			wsServer?.close();
34		}
35	};
36}