Files
dynamic-sites-simple/server/src/live-reload.ts
2026-04-23 08:34:47 -05:00

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);
}
}
}