import { randomUUID } from 'node:crypto' export type LiveChatMessage = { id: string username: string text: string createdAt: number } type LiveChatRoom = { messages: LiveChatMessage[] sockets: Set } const MAX_MESSAGES_PER_ROOM = 100 export class LiveChatStore { private readonly rooms = new Map() joinRoom (streamKey: string, socketId: string) { const room = this.getOrCreateRoom(streamKey) room.sockets.add(socketId) return room } leaveRoom (streamKey: string, socketId: string) { const room = this.rooms.get(streamKey) if (!room) return room.sockets.delete(socketId) if (room.sockets.size === 0 && room.messages.length === 0) { this.rooms.delete(streamKey) } } addMessage (streamKey: string, username: string, text: string) { const room = this.getOrCreateRoom(streamKey) const message: LiveChatMessage = { id: randomUUID(), username, text, createdAt: Date.now() } room.messages.push(message) if (room.messages.length > MAX_MESSAGES_PER_ROOM) { room.messages.splice(0, room.messages.length - MAX_MESSAGES_PER_ROOM) } return message } getRecentMessages (streamKey: string) { return [ ...(this.rooms.get(streamKey)?.messages || []) ] } getPresenceCount (streamKey: string) { return this.rooms.get(streamKey)?.sockets.size || 0 } deleteRoom (streamKey: string) { return this.rooms.delete(streamKey) } private getOrCreateRoom (streamKey: string) { let room = this.rooms.get(streamKey) if (!room) { room = { messages: [], sockets: new Set() } this.rooms.set(streamKey, room) } return room } }