This repository has been archived on 2026-10-08. You can view files and clone it, but cannot push or open issues or pull requests.
allotment/packages/server/socket/SocketManager.js

88 lines
2.2 KiB
JavaScript

import { SocketClient } from "./SocketClient.js";
import { SubscriptionRegistry } from "./SubscriptionRegistry.js";
export class SocketManager {
/**
* @param {import("socket.io").Server} io
* @param {object} [options]
* @param {SubscriptionRegistry} [options.subscriptionRegistry]
*/
constructor(io, options = {}) {
this.io = io;
this.subscriptionRegistry =
options.subscriptionRegistry ?? new SubscriptionRegistry();
this.clients = new Map();
/** @type {((socket: import("socket.io").Socket, client: SocketClient) => void) | null} */
this.registerSocketApi = null;
this.setup();
}
setup() {
this.io.on("connection", (socket) => this.handleConnection(socket));
}
handleConnection(socket) {
const client = new SocketClient(socket);
client.onDisconnect = (c) => {
this.subscriptionRegistry.removeSocket(c.id);
this.clients.delete(c.id);
};
client.setupListeners();
if (this.registerSocketApi) {
this.registerSocketApi(socket, client);
}
this.clients.set(socket.id, client);
}
/**
* Broadcast { type, payload } to all clients (legacy / non-subscription paths).
*/
broadcast(data) {
if (data && data.type !== undefined) {
this.io.emit(data.type, data.payload);
} else {
this.io.emit("message", data);
}
}
emitToSubscribers(channelKey, event, payload) {
const ids = this.subscriptionRegistry.getSubscriberIds(channelKey);
for (const socketId of ids) {
this.io.to(socketId).emit(event, payload);
}
}
emitPatchUpdated(patch) {
if (!patch?.id) return;
this.emitToSubscribers(`patch:${patch.id}`, "patchUpdated", { patch });
}
emitWaterTankUpdated(payload) {
this.emitToSubscribers("waterTank", "waterTankUpdated", payload);
}
emitPowerUpdated(payload) {
this.emitToSubscribers("power", "powerUpdated", payload);
}
emitWateringSessionsUpdated(payload) {
this.emitToSubscribers(
"wateringSessions",
"wateringSessionsUpdated",
payload,
);
}
emitWaterSchedulesUpdated(payload) {
this.emitToSubscribers(
"waterSchedules",
"waterSchedulesUpdated",
payload,
);
}
getClient(id) {
return this.clients.get(id);
}
}