200 lines
5.0 KiB
TypeScript
200 lines
5.0 KiB
TypeScript
/**
|
|
* 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<TMetadata = any>(
|
|
sessions: Record<string, Session<TMetadata>>
|
|
): 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<TMetadata = any>(
|
|
sessions: Record<string, Session<TMetadata>>,
|
|
sessionId: string
|
|
): Session<TMetadata> | 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<TMetadata = any>(
|
|
session: Session<TMetadata>
|
|
): void {
|
|
session.lastActive = Date.now();
|
|
session.live = true;
|
|
}
|
|
|
|
/**
|
|
* Check if a session is active
|
|
*/
|
|
export function isSessionActive<TMetadata = any>(
|
|
session: Session<TMetadata>,
|
|
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<TMetadata = any>(
|
|
session: Session<TMetadata> | undefined
|
|
): string {
|
|
if (!session) return 'Unknown';
|
|
return session.name || session.id;
|
|
}
|
|
|
|
/**
|
|
* Filter active sessions
|
|
*/
|
|
export function getActiveSessions<TMetadata = any>(
|
|
sessions: Record<string, Session<TMetadata>>
|
|
): Session<TMetadata>[] {
|
|
return Object.values(sessions).filter(s => s && isSessionActive(s));
|
|
}
|
|
|
|
/**
|
|
* Count active sessions
|
|
*/
|
|
export function countActiveSessions<TMetadata = any>(
|
|
sessions: Record<string, Session<TMetadata>>
|
|
): number {
|
|
return getActiveSessions(sessions).length;
|
|
}
|
|
|
|
/**
|
|
* Remove inactive sessions
|
|
*/
|
|
export function cleanupInactiveSessions<TMetadata = any>(
|
|
sessions: Record<string, Session<TMetadata>>,
|
|
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<TMetadata = any>(
|
|
session: Session<TMetadata>
|
|
): 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<TMetadata = any>(
|
|
session: Session<TMetadata>,
|
|
updates: Partial<TMetadata>
|
|
): 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<TMetadata = any>(
|
|
room: Room<TMetadata>
|
|
): 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<TMetadata = any>(
|
|
room: Room<TMetadata>,
|
|
updates: Partial<TMetadata>
|
|
): void {
|
|
if (!room.metadata) {
|
|
room.metadata = {} as TMetadata;
|
|
}
|
|
Object.assign(room.metadata as any, updates);
|
|
}
|
|
|
|
/**
|
|
* Check if session has metadata
|
|
*/
|
|
export function hasSessionMetadata<TMetadata = any>(
|
|
session: Session<TMetadata>
|
|
): boolean {
|
|
return session.metadata !== undefined && session.metadata !== null;
|
|
}
|
|
|
|
/**
|
|
* Check if room has metadata
|
|
*/
|
|
export function hasRoomMetadata<TMetadata = any>(
|
|
room: Room<TMetadata>
|
|
): boolean {
|
|
return room.metadata !== undefined && room.metadata !== null;
|
|
}
|