import type { ChannelWebSocket } from "./types";
/**
* Store clients by channel
*/
const channels = new Map<string, Set<ChannelWebSocket>>();
/**
* Get or create a channel
*/
export function getChannel(channelName: string): Set<ChannelWebSocket> {
const existing = channels.get(channelName);
if (existing) return existing;
const newChannel = new Set<ChannelWebSocket>();
channels.set(channelName, newChannel);
return newChannel;
}
/**
* Add a client to a channel
*/
export function joinChannel(ws: ChannelWebSocket, channelName: string): number {
const channel = getChannel(channelName);
channel.add(ws);
return channel.size;
}
/**
* Remove a client from a channel
*/
export function leaveChannel(ws: ChannelWebSocket, channelName: string): void {
const channel = channels.get(channelName);
if (channel) {
channel.delete(ws);
// Clean up empty channels
if (channel.size === 0) {
channels.delete(channelName);
}
}
}
/**
* Remove a client from all channels
*/
export function leaveAllChannels(ws: ChannelWebSocket): void {
for (const [channelName, clients] of channels.entries()) {
if (clients.has(ws)) {
clients.delete(ws);
// Clean up empty channels
if (clients.size === 0) {
channels.delete(channelName);
}
}
}
}
/**
* Check if a client is in a channel
*/
export function isInChannel(
ws: ChannelWebSocket,
channelName: string,
): boolean {
const channel = channels.get(channelName);
return channel ? channel.has(ws) : false;
}
/**
* Get all clients in a channel except the sender
*/
export function getOtherClientsInChannel(
ws: ChannelWebSocket,
channelName: string,
): ChannelWebSocket[] {
const channel = channels.get(channelName);
if (!channel) return [];
return Array.from(channel).filter((client) => client !== ws);
}
/**
* Get the number of clients in a channel
*/
export function getChannelSize(channelName: string): number {
const channel = channels.get(channelName);
return channel ? channel.size : 0;
}
/**
* Broadcast a message to all other clients in a channel
*/
export function broadcastToChannel(
ws: ChannelWebSocket,
channelName: string,
message: string,
): number {
const others = getOtherClientsInChannel(ws, channelName);
let count = 0;
for (const client of others) {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
count++;
}
}
return count;
}