62 lines
1.9 KiB
JavaScript
62 lines
1.9 KiB
JavaScript
/**
|
|
* Tracks which socket.io connection ids are subscribed to each logical channel.
|
|
* Keys: "patch:<patchId>", "waterTank", "power", "wateringSessions", "waterSchedules"
|
|
*/
|
|
export class SubscriptionRegistry {
|
|
constructor() {
|
|
/** @type {Map<string, Set<string>>} */
|
|
this._keyToSockets = new Map();
|
|
/** @type {Map<string, Set<string>>} */
|
|
this._socketToKeys = new Map();
|
|
}
|
|
|
|
static channelKey(resource, id) {
|
|
if (resource === "patch") {
|
|
if (id == null || id === "") return null;
|
|
return `patch:${id}`;
|
|
}
|
|
if (resource === "waterTank") return "waterTank";
|
|
if (resource === "power") return "power";
|
|
if (resource === "wateringSessions") return "wateringSessions";
|
|
if (resource === "waterSchedules") return "waterSchedules";
|
|
return null;
|
|
}
|
|
|
|
subscribe(socketId, key) {
|
|
if (!key) return;
|
|
if (!this._keyToSockets.has(key)) this._keyToSockets.set(key, new Set());
|
|
this._keyToSockets.get(key).add(socketId);
|
|
if (!this._socketToKeys.has(socketId)) this._socketToKeys.set(socketId, new Set());
|
|
this._socketToKeys.get(socketId).add(key);
|
|
}
|
|
|
|
unsubscribe(socketId, key) {
|
|
if (!key) return;
|
|
this._keyToSockets.get(key)?.delete(socketId);
|
|
if (this._keyToSockets.get(key)?.size === 0) {
|
|
this._keyToSockets.delete(key);
|
|
}
|
|
this._socketToKeys.get(socketId)?.delete(key);
|
|
if (this._socketToKeys.get(socketId)?.size === 0) {
|
|
this._socketToKeys.delete(socketId);
|
|
}
|
|
}
|
|
|
|
removeSocket(socketId) {
|
|
const keys = this._socketToKeys.get(socketId);
|
|
if (!keys) return;
|
|
for (const key of keys) {
|
|
this._keyToSockets.get(key)?.delete(socketId);
|
|
if (this._keyToSockets.get(key)?.size === 0) {
|
|
this._keyToSockets.delete(key);
|
|
}
|
|
}
|
|
this._socketToKeys.delete(socketId);
|
|
}
|
|
|
|
/** @returns {Iterable<string>} */
|
|
getSubscriberIds(key) {
|
|
return this._keyToSockets.get(key) ?? [];
|
|
}
|
|
}
|