/** * Reusable Room/Session helper functions * These are application-agnostic and work with any Room/Session implementation */ import type { BaseSession, Participant, Session, Room } from './types'; /** * Get participant list for a room * Returns minimal session information suitable for client-side participant lists */ export function getParticipants( sessions: Record> ): Participant[] { const participants: Participant[] = []; for (const id in sessions) { const session = sessions[id]; if (!session) continue; participants.push({ name: session.name, session_id: session.id, live: session.live, protected: session.protected || false, has_media: session.has_media, bot_run_id: session.bot_run_id || null, bot_provider_id: session.bot_provider_id || null, bot_instance_id: session.bot_instance_id || null, muted: false, // TODO: Track mute state separately video_on: true, // TODO: Track video state separately }); } return participants; } /** * Get a session by ID */ export function getSession( sessions: Record>, sessionId: string ): Session | undefined { return sessions[sessionId]; } /** * Create a new base session */ export function createBaseSession(sessionId: string, name: string | null = null): BaseSession { return { id: sessionId, name, live: false, connected: false, lastActive: Date.now(), has_media: true, // Default to true _initialSnapshotSent: false, }; } /** * Update session activity timestamp */ export function updateSessionActivity( session: Session ): void { session.lastActive = Date.now(); session.live = true; } /** * Check if a session is active */ export function isSessionActive( session: Session, timeoutMs: number = 60000 ): boolean { if (!session.live) return false; return Date.now() - session.lastActive < timeoutMs; } /** * Get the display name for a session */ export function getSessionName( session: Session | undefined ): string { if (!session) return 'Unknown'; return session.name || session.id; } /** * Filter active sessions */ export function getActiveSessions( sessions: Record> ): Session[] { return Object.values(sessions).filter(s => s && isSessionActive(s)); } /** * Count active sessions */ export function countActiveSessions( sessions: Record> ): number { return getActiveSessions(sessions).length; } /** * Remove inactive sessions */ export function cleanupInactiveSessions( sessions: Record>, timeoutMs: number = 300000 // 5 minutes ): void { for (const id in sessions) { const session = sessions[id]; if (session && !isSessionActive(session, timeoutMs)) { delete sessions[id]; } } } // ============================================================================ // Metadata Helper Functions // ============================================================================ /** * Get session metadata safely with type checking * @param session - The session to get metadata from * @returns The metadata object or undefined */ export function getSessionMetadata( session: Session ): TMetadata | undefined { return session.metadata; } /** * Update session metadata (creates metadata object if it doesn't exist) * @param session - The session to update * @param updates - Partial metadata updates to apply */ export function updateSessionMetadata( session: Session, updates: Partial ): void { if (!session.metadata) { session.metadata = {} as TMetadata; } Object.assign(session.metadata as any, updates); } /** * Get room metadata safely with type checking * @param room - The room to get metadata from * @returns The metadata object or undefined */ export function getRoomMetadata( room: Room ): TMetadata | undefined { return room.metadata; } /** * Update room metadata (creates metadata object if it doesn't exist) * @param room - The room to update * @param updates - Partial metadata updates to apply */ export function updateRoomMetadata( room: Room, updates: Partial ): void { if (!room.metadata) { room.metadata = {} as TMetadata; } Object.assign(room.metadata as any, updates); } /** * Check if session has metadata */ export function hasSessionMetadata( session: Session ): boolean { return session.metadata !== undefined && session.metadata !== null; } /** * Check if room has metadata */ export function hasRoomMetadata( room: Room ): boolean { return room.metadata !== undefined && room.metadata !== null; }