66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
|
|
/**
|
||
|
|
* WebSocket manager for hot reload
|
||
|
|
* Generates a unique instance ID on startup and broadcasts it to connected clients.
|
||
|
|
* When the server restarts, clients detect the new ID and reload the page.
|
||
|
|
*/
|
||
|
|
export class ReloadSocketManager {
|
||
|
|
private instanceId: string;
|
||
|
|
private clients: Set<WebSocket> = new Set();
|
||
|
|
|
||
|
|
constructor() {
|
||
|
|
this.instanceId = crypto.randomUUID();
|
||
|
|
console.log(`[ReloadSocket] Instance ID: ${this.instanceId}`);
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the current instance ID
|
||
|
|
*/
|
||
|
|
getInstanceId(): string {
|
||
|
|
return this.instanceId;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Handle WebSocket upgrade request
|
||
|
|
*/
|
||
|
|
handleUpgrade(request: Request): Response {
|
||
|
|
const { socket, response } = Deno.upgradeWebSocket(request);
|
||
|
|
|
||
|
|
socket.onopen = () => {
|
||
|
|
this.clients.add(socket);
|
||
|
|
console.log(`[ReloadSocket] Client connected (${this.clients.size} total)`);
|
||
|
|
// Send instance ID immediately
|
||
|
|
socket.send(JSON.stringify({ type: 'instance', id: this.instanceId }));
|
||
|
|
};
|
||
|
|
|
||
|
|
socket.onclose = () => {
|
||
|
|
this.clients.delete(socket);
|
||
|
|
console.log(`[ReloadSocket] Client disconnected (${this.clients.size} remaining)`);
|
||
|
|
};
|
||
|
|
|
||
|
|
socket.onerror = (error) => {
|
||
|
|
console.error('[ReloadSocket] WebSocket error:', error);
|
||
|
|
};
|
||
|
|
|
||
|
|
return response;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Broadcast a message to all connected clients
|
||
|
|
*/
|
||
|
|
broadcast(message: object): void {
|
||
|
|
const msg = JSON.stringify(message);
|
||
|
|
for (const client of this.clients) {
|
||
|
|
if (client.readyState === WebSocket.OPEN) {
|
||
|
|
client.send(msg);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Get the number of connected clients
|
||
|
|
*/
|
||
|
|
getClientCount(): number {
|
||
|
|
return this.clients.size;
|
||
|
|
}
|
||
|
|
}
|