feat(registry): Add hot-reload websocket, embedded UI bundling, and multi-platform Deno build tasks

Introduce a ReloadSocketManager and client ReloadService for automatic page reloads when the server restarts. Serve UI assets from an embedded generated file and add Deno tasks to bundle the UI and compile native binaries for multiple platforms. Also update dev watch workflow and ignore generated embedded UI file.
This commit is contained in:
2025-11-28 12:35:59 +00:00
parent 45114f89d4
commit 5d9cd3ad85
13 changed files with 794 additions and 47 deletions

65
ts/reload-socket.ts Normal file
View File

@@ -0,0 +1,65 @@
/**
* 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;
}
}