112 lines
4.6 KiB
TypeScript
112 lines
4.6 KiB
TypeScript
import { Subject } from 'rxjs';
|
|
import { ChatEvent } from '../../../shared-kernel';
|
|
import { WebRTCLogger } from '../logging/webrtc-logger';
|
|
import {
|
|
DisconnectedPeerEntry,
|
|
IdentifyCredentials,
|
|
PeerData,
|
|
VoiceStateSnapshot
|
|
} from '../realtime.types';
|
|
|
|
/**
|
|
* Callbacks the PeerConnectionManager needs from the owning service.
|
|
* This keeps the manager decoupled from Angular DI / signals.
|
|
*/
|
|
export interface PeerConnectionCallbacks {
|
|
/** Send a raw JSON message via the signaling server. */
|
|
sendRawMessage(msg: Record<string, unknown>): void;
|
|
/** Get the current local media stream (mic audio). */
|
|
getLocalMediaStream(): MediaStream | null;
|
|
/** Whether signaling is currently connected. */
|
|
isSignalingConnected(): boolean;
|
|
/** Returns the current voice/screen state snapshot for broadcasting. */
|
|
getVoiceStateSnapshot(): VoiceStateSnapshot;
|
|
/** Returns the identify credentials (oderId + displayName). */
|
|
getIdentifyCredentials(): IdentifyCredentials | null;
|
|
/** Returns the local peer ID. */
|
|
getLocalPeerId(): string;
|
|
/** Whether screen sharing is active. */
|
|
isScreenSharingActive(): boolean;
|
|
/** Whether the local camera is active. */
|
|
isCameraEnabled(): boolean;
|
|
}
|
|
|
|
export interface PeerConnectionManagerState {
|
|
activePeerConnections: Map<string, PeerData>;
|
|
remotePeerStreams: Map<string, MediaStream>;
|
|
remotePeerVoiceStreams: Map<string, MediaStream>;
|
|
remotePeerCameraStreams: Map<string, MediaStream>;
|
|
remotePeerScreenShareStreams: Map<string, MediaStream>;
|
|
disconnectedPeerTracker: Map<string, DisconnectedPeerEntry>;
|
|
peerReconnectTimers: Map<string, ReturnType<typeof setInterval>>;
|
|
peerDisconnectGraceTimers: Map<string, ReturnType<typeof setTimeout>>;
|
|
pendingPings: Map<string, number>;
|
|
peerPingTimers: Map<string, ReturnType<typeof setInterval>>;
|
|
peerLatencies: Map<string, number>;
|
|
peerLatencyChanged$: Subject<{ peerId: string; latencyMs: number }>;
|
|
peerNegotiationQueue: Map<string, Promise<void>>;
|
|
peerConnected$: Subject<string>;
|
|
peerDisconnected$: Subject<string>;
|
|
remoteStream$: Subject<{ peerId: string; stream: MediaStream }>;
|
|
messageReceived$: Subject<ChatEvent>;
|
|
connectedPeersChanged$: Subject<string[]>;
|
|
connectedPeersList: string[];
|
|
}
|
|
|
|
export interface PeerConnectionManagerContext {
|
|
readonly logger: WebRTCLogger;
|
|
readonly callbacks: PeerConnectionCallbacks;
|
|
readonly state: PeerConnectionManagerState;
|
|
}
|
|
|
|
export interface RemovePeerOptions {
|
|
preserveReconnectState?: boolean;
|
|
}
|
|
|
|
export interface ConnectionLifecycleHandlers {
|
|
clearPeerDisconnectGraceTimer(peerId: string): void;
|
|
addToConnectedPeers(peerId: string): void;
|
|
clearPeerReconnectTimer(peerId: string): void;
|
|
requestVoiceStateFromPeer(peerId: string): void;
|
|
schedulePeerDisconnectRecovery(peerId: string): void;
|
|
trackDisconnectedPeer(peerId: string): void;
|
|
removePeer(peerId: string, options?: RemovePeerOptions): void;
|
|
schedulePeerReconnect(peerId: string): void;
|
|
handleRemoteTrack(event: RTCTrackEvent, remotePeerId: string): void;
|
|
setupDataChannel(channel: RTCDataChannel, remotePeerId: string): void;
|
|
}
|
|
|
|
export interface NegotiationHandlers {
|
|
createPeerConnection(remotePeerId: string, isInitiator: boolean): PeerData;
|
|
}
|
|
|
|
export interface RecoveryHandlers {
|
|
removePeer(peerId: string, options?: RemovePeerOptions): void;
|
|
createPeerConnection(peerId: string, isInitiator: boolean): PeerData;
|
|
createAndSendOffer(peerId: string): Promise<void>;
|
|
}
|
|
|
|
export function createPeerConnectionManagerState(): PeerConnectionManagerState {
|
|
return {
|
|
activePeerConnections: new Map<string, PeerData>(),
|
|
remotePeerStreams: new Map<string, MediaStream>(),
|
|
remotePeerVoiceStreams: new Map<string, MediaStream>(),
|
|
remotePeerCameraStreams: new Map<string, MediaStream>(),
|
|
remotePeerScreenShareStreams: new Map<string, MediaStream>(),
|
|
disconnectedPeerTracker: new Map<string, DisconnectedPeerEntry>(),
|
|
peerReconnectTimers: new Map<string, ReturnType<typeof setInterval>>(),
|
|
peerDisconnectGraceTimers: new Map<string, ReturnType<typeof setTimeout>>(),
|
|
pendingPings: new Map<string, number>(),
|
|
peerPingTimers: new Map<string, ReturnType<typeof setInterval>>(),
|
|
peerLatencies: new Map<string, number>(),
|
|
peerLatencyChanged$: new Subject<{ peerId: string; latencyMs: number }>(),
|
|
peerNegotiationQueue: new Map<string, Promise<void>>(),
|
|
peerConnected$: new Subject<string>(),
|
|
peerDisconnected$: new Subject<string>(),
|
|
remoteStream$: new Subject<{ peerId: string; stream: MediaStream }>(),
|
|
messageReceived$: new Subject<ChatEvent>(),
|
|
connectedPeersChanged$: new Subject<string[]>(),
|
|
connectedPeersList: []
|
|
};
|
|
}
|