sse => ws

This commit is contained in:
Darius
2026-02-06 11:08:26 +01:00
parent 60bcd23f5b
commit ad9cf36e98
14 changed files with 136 additions and 555 deletions

View File

@@ -2,7 +2,6 @@ export * from "./fastify.js";
export * from "./homeassistant.js";
export * from "./homepage.js";
export * from "./logger.js";
export * from "./sse.js";
export * from "./ws.js";
export * from "./tidal.js";
export * from "./timehelper.js";

View File

@@ -1,75 +0,0 @@
import { UUID } from "crypto";
import { logInfo } from "./logger.js";
export type SseClient = {
id: UUID;
send: (data: SseEvent) => void;
};
export type SseEvent = {
type: string;
data?: unknown;
message?: string;
};
export type SseClientChangeEvent = {
type: "add" | "remove";
clientId: string;
clientCount: number;
};
export type SseClientChangeCallback = (event: SseClientChangeEvent) => void;
export class SseService {
private clients: Map<string, SseClient> = new Map();
private clientChangeCallbacks: SseClientChangeCallback[] = [];
onClientChange(callback: SseClientChangeCallback): () => void {
this.clientChangeCallbacks.push(callback);
return () => {
this.clientChangeCallbacks = this.clientChangeCallbacks.filter(
(cb) => cb !== callback,
);
};
}
private emitClientChange(event: SseClientChangeEvent): void {
for (const callback of this.clientChangeCallbacks) {
callback(event);
}
}
addClient(client: SseClient): void {
this.clients.set(client.id, client);
logInfo(
`SSE client connected: ${client.id}. Total clients: ${this.clients.size}`,
);
this.emitClientChange({
type: "add",
clientId: client.id,
clientCount: this.clients.size,
});
}
removeClient(clientId: string): void {
this.clients.delete(clientId);
logInfo(
`SSE client disconnected: ${clientId}. Total clients: ${this.clients.size}`,
);
this.emitClientChange({
type: "remove",
clientId,
clientCount: this.clients.size,
});
}
notifyClients(event: SseEvent): void {
for (const client of this.clients.values()) {
client.send(event);
}
}
getClientCount(): number {
return this.clients.size;
}
}

48
src/ws.ts Normal file
View File

@@ -0,0 +1,48 @@
import { logInfo } from "./logger.js";
export type WsEvent = {
type: string;
data?: unknown;
};
export type WsClientChangeCallback = (clients: number) => void;
export class WsService {
private clients: Set<WebSocket> = new Set();
private listeners: WsClientChangeCallback[] = [];
onClientChange(callback: WsClientChangeCallback): () => void {
this.listeners.push(callback);
return () => {
this.listeners = this.listeners.filter((cb) => cb !== callback);
};
}
private emitClientChange(): void {
for (const callback of this.listeners) {
callback(this.clients.size);
}
}
addClient(ws: WebSocket): void {
this.clients.add(ws);
logInfo(`Socket connected. Total clients: ${this.clients.size}`);
this.emitClientChange();
}
removeClient(ws: WebSocket): void {
this.clients.delete(ws);
logInfo(`Socket disconnected. Total clients: ${this.clients.size}`);
this.emitClientChange();
}
broadcast(message: WsEvent): void {
this.clients.forEach((socket) => {
socket.send(JSON.stringify(message));
});
}
getClientCount(): number {
return this.clients.size;
}
}