65 lines
1.7 KiB
TypeScript
65 lines
1.7 KiB
TypeScript
import type http from 'node:http';
|
|
import { WebSocketServer, type WebSocket } from 'ws';
|
|
import { logger } from './logger.js';
|
|
|
|
let wss: WebSocketServer | null = null;
|
|
|
|
export function initLiveReload(server: http.Server): void {
|
|
if (wss) return;
|
|
|
|
const enabled = process.env.LIVE_RELOAD_WS_ENABLED === 'true';
|
|
if (!enabled) {
|
|
logger.info({ event: 'live_reload.disabled' }, 'Live reload websocket disabled');
|
|
return;
|
|
}
|
|
|
|
const wsPath = process.env.LIVE_RELOAD_WS_PATH || '/__live_reload';
|
|
|
|
wss = new WebSocketServer({ server, path: wsPath });
|
|
wss.on('connection', (socket: WebSocket) => {
|
|
logger.info({ event: 'live_reload.connected' }, 'Live reload client connected');
|
|
socket.on('close', () => {
|
|
logger.info({ event: 'live_reload.disconnected' }, 'Live reload client disconnected');
|
|
});
|
|
});
|
|
|
|
logger.info({ event: 'live_reload.started', path: wsPath }, 'Live reload websocket started');
|
|
}
|
|
|
|
export function broadcastReload(reason: string, data?: Record<string, unknown>): void {
|
|
if (!wss) return;
|
|
|
|
const payload = JSON.stringify({
|
|
type: 'reload',
|
|
ts: Date.now(),
|
|
reason,
|
|
...data,
|
|
});
|
|
|
|
for (const client of wss.clients) {
|
|
if (client.readyState === client.OPEN) {
|
|
client.send(payload);
|
|
}
|
|
}
|
|
}
|
|
|
|
export type UpdateStatusPhase = 'request_received' | 'update_started' | 'update_done';
|
|
|
|
export function broadcastUpdateStatus(phase: UpdateStatusPhase, data?: Record<string, unknown>): void {
|
|
if (!wss) return;
|
|
|
|
const payload = JSON.stringify({
|
|
type: 'update_status',
|
|
ts: Date.now(),
|
|
phase,
|
|
...data,
|
|
});
|
|
|
|
for (const client of wss.clients) {
|
|
if (client.readyState === client.OPEN) {
|
|
client.send(payload);
|
|
}
|
|
}
|
|
}
|
|
|