react-jssip-kit 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/modules/debug/sip-debugger.ts","../src/core/contracts/state.ts","../src/index.ts","../src/core/sip/user-agent.ts","../src/core/modules/event/event-target.emitter.ts","../src/core/modules/state/sip.state.ts","../src/core/modules/state/sip.state.store.ts","../src/core/modules/debug/sip-debug.runtime.ts","../src/core/modules/event/sip-event-manager.adapter.ts","../src/core/modules/debug/sip-debug.logger.ts","../src/core/modules/media/mic-recovery.manager.ts","../src/core/modules/runtime/browser-unload.runtime.ts","../src/core/modules/media/webrtc-session.controller.ts","../src/core/modules/session/session.manager.ts","../src/core/modules/session/session.state.projector.ts","../src/core/modules/session/session.handlers.ts","../src/core/modules/session/session.lifecycle.ts","../src/core/modules/session/session.module.ts","../src/core/modules/ua/ua.handlers.ts","../src/core/modules/ua/ua.module.ts","../src/core/client/sip.client.ts","../src/core/modules/media/media.module.ts","../src/core/kernel/createSipKernel.ts","../src/hooks/useSipState.ts","../src/hooks/useSip.ts","../src/context/index.tsx","../src/hooks/useSipActions.ts","../src/hooks/useSipSelector.ts","../src/hooks/useActiveSipSession.ts","../src/hooks/useSipSession.ts","../src/hooks/useSipSessions.ts","../src/hooks/useSipEvent.ts","../src/hooks/useSessionMedia.ts","../src/components/call-player.tsx","../src/provider/index.tsx"],"names":["JsSIP","session","pc","useSyncExternalStore","useMemo","useEffect","useRef","jsx"],"mappings":"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","sourcesContent":["import JsSIP from \"jssip\";\n\ntype StorageLike = Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\n\nexport interface SipDebugToggleResult {\n debug: boolean;\n text: string;\n}\n\nexport class SipDebugger {\n private readonly storageKey: string;\n private readonly defaultPattern: string;\n private enabled = false;\n\n constructor(storageKey = \"sip-debug-enabled\", defaultPattern = \"JsSIP:*\") {\n this.storageKey = storageKey;\n this.defaultPattern = defaultPattern;\n }\n\n initFromSession(storage: StorageLike | null = safeSessionStorage()): void {\n try {\n const saved = storage?.getItem(this.storageKey);\n if (saved) this.enable(saved, storage);\n } catch {\n /* ignore */\n }\n }\n\n enable(\n pattern: string = this.defaultPattern,\n storage: StorageLike | null = safeSessionStorage()\n ): void {\n try {\n if (typeof JsSIP?.debug?.enable === \"function\") {\n JsSIP.debug.enable(pattern);\n }\n storage?.setItem?.(this.storageKey, pattern || this.defaultPattern);\n try {\n (window as any).sipDebugBridge?.(pattern);\n } catch {\n /* ignore */\n }\n this.enabled = true;\n } catch {\n /* ignore */\n }\n }\n\n disable(storage: StorageLike | null = safeSessionStorage()): void {\n try {\n if (typeof JsSIP?.debug?.disable === \"function\") {\n JsSIP.debug.disable();\n } else if (typeof JsSIP?.debug?.enable === \"function\") {\n JsSIP.debug.enable(\"\");\n }\n storage?.removeItem?.(this.storageKey);\n try {\n (window as any).sipDebugBridge?.(false);\n } catch {\n /* ignore */\n }\n this.enabled = false;\n } catch {\n /* ignore */\n }\n }\n\n toggle(\n pattern: string = this.defaultPattern,\n storage: StorageLike | null = safeSessionStorage()\n ): void {\n if (this.isEnabled()) {\n this.disable(storage);\n } else {\n this.enable(pattern, storage);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n attachToWindow(win: Window & typeof globalThis = window): void {\n const api = {\n enableDebug: (): SipDebugToggleResult => {\n this.enable();\n return { debug: this.isEnabled(), text: \"press F5\" };\n },\n disableDebug: (): SipDebugToggleResult => {\n this.disable();\n return { debug: this.isEnabled(), text: \"press F5\" };\n },\n toggleDebug: (): SipDebugToggleResult => {\n this.toggle();\n return { debug: this.isEnabled(), text: \"press F5\" };\n },\n debugState: (): SipDebugToggleResult => ({\n debug: this.isEnabled(),\n text: this.isEnabled() ? \"enabled\" : \"disabled\",\n }),\n sipState: () => {\n try {\n const getter = (win as any).sipState;\n return typeof getter === \"function\"\n ? getter()\n : \"sipState helper not available; ensure client debug is enabled\";\n } catch {\n return \"sipState helper not available\";\n }\n },\n sipSessions: () => {\n try {\n const getter = (win as any).sipSessions;\n return typeof getter === \"function\"\n ? getter()\n : \"sipSessions helper not available; ensure client debug is enabled\";\n } catch {\n return \"sipSessions helper not available\";\n }\n },\n };\n\n try {\n (win as any).sipSupport = api;\n } catch {\n /* ignore */\n }\n }\n}\n\nfunction safeSessionStorage(): StorageLike | null {\n if (typeof window === \"undefined\") return null;\n try {\n return window.sessionStorage;\n } catch {\n return null;\n }\n}\n\nexport const sipDebugger = new SipDebugger();\nif (typeof window !== \"undefined\") {\n sipDebugger.attachToWindow();\n sipDebugger.initFromSession();\n}\n","export const SipStatus = {\n Disconnected: \"disconnected\",\n Connecting: \"connecting\",\n Connected: \"connected\",\n Registered: \"registered\",\n Unregistered: \"unregistered\",\n RegistrationFailed: \"registrationFailed\",\n} as const;\n\nexport type SipStatus = (typeof SipStatus)[keyof typeof SipStatus];\n\nexport const CallStatus = {\n Idle: \"idle\",\n Dialing: \"dialing\",\n Ringing: \"ringing\",\n Active: \"active\",\n Hold: \"hold\",\n} as const;\nexport type CallStatus = (typeof CallStatus)[keyof typeof CallStatus];\n\nexport type CallDirection = \"local\" | \"remote\";\n\nexport type SipSessionState = {\n id: string;\n status: CallStatus;\n direction: CallDirection | null;\n from: string | null;\n to: string | null;\n muted: boolean;\n acceptedAt: number | null;\n};\n\nexport interface SipState {\n sipStatus: SipStatus;\n error: string | null;\n sessions: SipSessionState[];\n sessionsById: Record<string, SipSessionState>;\n sessionIds: string[];\n}\n\nexport const SipStatusList = Object.values(SipStatus);\nexport const CallStatusList = Object.values(CallStatus);\n\nexport function isSipStatus(v: unknown): v is SipStatus {\n return (\n typeof v === \"string\" && (SipStatusList as readonly string[]).includes(v)\n );\n}\nexport function isCallStatus(v: unknown): v is CallStatus {\n return (\n typeof v === \"string\" && (CallStatusList as readonly string[]).includes(v)\n );\n}\n\nexport type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n","import \"./core/modules/debug/sip-debugger\";\nimport {\n SipStatus,\n CallStatus,\n CallDirection,\n} from \"./core/contracts/state\";\nimport { WebSocketInterface } from \"jssip\";\nimport {\n createSipClientInstance,\n createSipEventManager,\n} from \"./core/client\";\nimport { createSipKernel } from \"./core/kernel\";\n\nexport { useSipState } from \"./hooks/useSipState\";\nexport { useSipActions } from \"./hooks/useSipActions\";\nexport { useSipKernel } from \"./hooks/useSip\";\nexport { useSipSelector } from \"./hooks/useSipSelector\";\nexport { useActiveSipSession } from \"./hooks/useActiveSipSession\";\nexport { useSipSession } from \"./hooks/useSipSession\";\nexport { useSipSessions } from \"./hooks/useSipSessions\";\nexport { useSipEvent, useSipSessionEvent } from \"./hooks/useSipEvent\";\nexport { useSessionMedia } from \"./hooks/useSessionMedia\";\nexport { CallPlayer } from \"./components/call-player\";\n\nexport { SipProvider } from \"./provider\";\nexport type { SipProviderProps } from \"./provider\";\n\nexport {\n CallStatus,\n CallDirection,\n createSipClientInstance,\n createSipKernel,\n createSipEventManager,\n WebSocketInterface,\n SipStatus,\n};\n\nimport type {\n SipState,\n SipSessionState,\n SipStatus as SipStatusType,\n CallDirection as CallDirectionType,\n CallStatus as CallStatusType,\n CallOptions,\n AnswerOptions,\n DTMFOptions,\n ReferOptions,\n JsSIPEventMap,\n JsSIPEventName,\n SessionEventName,\n SessionEventPayload,\n UAEventName,\n UAEventPayload,\n SipEventHandlers,\n SipEventManager,\n RTCSession,\n TerminateOptions,\n RTCSessionEventMap,\n SipConfiguration,\n SipKernel,\n} from \"./core/public-types\";\n\nexport type {\n SipState,\n SipSessionState,\n SipStatusType,\n CallDirectionType,\n CallStatusType,\n CallOptions,\n AnswerOptions,\n DTMFOptions,\n ReferOptions,\r\n JsSIPEventMap,\r\n JsSIPEventName,\r\n SessionEventName,\r\n SessionEventPayload,\r\n UAEventName,\r\n UAEventPayload,\r\n SipEventHandlers,\r\n SipEventManager,\r\n RTCSession,\r\n TerminateOptions,\r\n RTCSessionEventMap,\r\n SipConfiguration,\n SipKernel,\n};\n","import JsSIP, { UA } from \"jssip\";\nimport { SipConfiguration, UAConfiguration } from \"./types\";\n\ntype StartOpts = { debug?: boolean | string };\n\nexport class SipUserAgent {\n private _ua: UA | null = null;\n\n public get ua(): UA | null {\n return this._ua;\n }\n public get isStarted(): boolean {\n return !!this._ua;\n }\n public get isRegistered(): boolean {\n return !!this._ua?.isRegistered();\n }\n\n public start(\n uri: string,\n password: string,\n config: Omit<SipConfiguration, \"debug\">,\n opts?: StartOpts\n ): UA {\n this.stop();\n const uaCfg = this.buildUAConfig(config, uri, password);\n this.ensureValid(uaCfg);\n this.applyDebug(opts?.debug);\n const ua = this.createUA(uaCfg);\n ua.start();\n this._ua = ua;\n return ua;\n }\n\n public register(): void {\n const ua = this.getUA();\n if (!ua?.isRegistered()) ua?.register();\n }\n\n public stop(): void {\n const ua = this._ua;\n if (!ua) return;\n try {\n if (ua.isRegistered()) ua.unregister();\n ua.stop();\n } finally {\n this._ua = null;\n }\n }\n\n public getUA(): UA | null {\n return this._ua;\n }\n\n public setDebug(debug?: boolean | string): void {\n this.applyDebug(debug);\n }\n\n protected buildUAConfig(\n config: Omit<SipConfiguration, \"debug\">,\n uri: string,\n password: string\n ): UAConfiguration {\n return { ...(config as UAConfiguration), uri, password };\n }\n\n protected ensureValid(cfg: UAConfiguration): void {\n const sockets = cfg.sockets as UAConfiguration[\"sockets\"];\n if (\n !cfg.uri ||\n !cfg.password ||\n !sockets ||\n (Array.isArray(sockets) && sockets.length === 0)\n ) {\n throw new Error(\n \"Invalid SIP connect args: require uri, password, and at least one socket\"\n );\n }\n }\n\n protected applyDebug(debug?: boolean | string): void {\n const stored = debug === undefined ? this.readSessionFlag() : debug;\n const enabled = !!stored;\n const pattern = typeof stored === \"string\" ? stored : \"JsSIP:*\";\n\n if (enabled) {\n JsSIP.debug.enable(pattern);\n const dbg: any = (JsSIP as any).debug;\n if (dbg?.setLogger) dbg.setLogger(console);\n else if (dbg) dbg.logger = console;\n this.persistSessionFlag(typeof stored === \"string\" ? stored : undefined);\n } else {\n (JsSIP.debug as any)?.disable?.();\n this.clearSessionFlag();\n }\n }\n\n protected createUA(cfg: UAConfiguration): UA {\n return new JsSIP.UA(cfg);\n }\n\n private readSessionFlag(): string | false {\n try {\n if (typeof window === \"undefined\") return false;\n const value = window.sessionStorage.getItem(\"sip-debug-enabled\");\n if (!value) return false;\n return value;\n } catch {\n return false;\n }\n }\n\n private persistSessionFlag(pattern?: string): void {\n try {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.setItem(\n \"sip-debug-enabled\",\n pattern || \"JsSIP:*\"\n );\n }\n } catch {\n /* ignore */\n }\n }\n\n private clearSessionFlag(): void {\n try {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(\"sip-debug-enabled\");\n }\n } catch {\n /* ignore */\n }\n }\n}\n","export type Listener<T = any> = (payload: T) => void;\n\nexport class EventTargetEmitter<Events extends Record<string, any> = any> {\n private target = new EventTarget();\n\n on<K extends keyof Events>(event: K, fn: Listener<Events[K]>): () => void {\n const wrapper = (e: Event) => fn((e as CustomEvent<Events[K]>).detail);\n this.target.addEventListener(event as string, wrapper);\n return () => this.target.removeEventListener(event as string, wrapper);\n }\n\n emit<K extends keyof Events>(event: K, payload?: Events[K]): void {\n this.target.dispatchEvent(\n new CustomEvent(event as string, { detail: payload })\n );\n }\n}\n","import { SipState, SipStatus } from \"../../contracts/state\";\n\nexport function getInitialSipState(): SipState {\n return {\n sipStatus: SipStatus.Disconnected,\n error: null,\n sessions: [],\n sessionsById: {},\n sessionIds: [],\n };\n}\n\nexport function shallowEqual(objA: any, objB: any): boolean {\n if (objA === objB) return true;\n if (!objA || !objB) return false;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (objA[key] !== objB[key]) return false;\n }\n return true;\n}\n","import { SipState } from \"../../contracts/state\";\nimport { getInitialSipState, shallowEqual } from \"./sip.state\";\n\nexport type SipStateListener = (state: SipState) => void;\n\nexport class SipStateStore {\n private state: SipState = getInitialSipState();\n private lastState: SipState = getInitialSipState();\n private listeners = new Set<SipStateListener>();\n private pendingState: Partial<SipState> | null = null;\n private updateScheduled = false;\n\n getState(): SipState {\n return this.state;\n }\n\n onChange(fn: SipStateListener): () => void {\n this.listeners.add(fn);\n fn(this.state);\n return () => this.listeners.delete(fn);\n }\n\n subscribe(fn: SipStateListener): () => void {\n return this.onChange(fn);\n }\n\n setState(partial: Partial<SipState>) {\n if (!partial || Object.keys(partial).length === 0) return;\n const next = { ...this.state, ...partial };\n if (\n next.sessions === this.lastState.sessions &&\n shallowEqual(this.lastState, next)\n ) {\n return;\n }\n this.state = next;\n this.lastState = next;\n this.emit();\n }\n\n batchSet(partial: Partial<SipState>) {\n this.pendingState = { ...this.pendingState, ...partial };\n if (!this.updateScheduled) {\n this.updateScheduled = true;\n queueMicrotask(() => {\n if (this.pendingState) this.setState(this.pendingState);\n this.pendingState = null;\n this.updateScheduled = false;\n });\n }\n }\n\n reset(overrides: Partial<SipState> = {}) {\n this.setState({ ...getInitialSipState(), ...overrides });\n }\n\n private emit() {\n for (const fn of this.listeners) fn(this.state);\n }\n}\n","import type { SipState } from \"../../contracts/state\";\n\nconst SESSION_DEBUG_KEY = \"sip-debug-enabled\";\n\ntype DebugRuntimeDeps = {\n getState: () => SipState;\n onChange: (listener: (state: SipState) => void) => () => void;\n getSessions: () => unknown;\n setDebugEnabled: (enabled: boolean) => void;\n};\n\nexport class SipDebugRuntime {\n private readonly deps: DebugRuntimeDeps;\n private stateLogOff?: () => void;\n\n constructor(deps: DebugRuntimeDeps) {\n this.deps = deps;\n }\n\n attachBridge(setDebug: (debug?: boolean | string) => void): void {\n if (typeof window === \"undefined\") return;\n (window as any).sipDebugBridge = (debug?: boolean | string) =>\n setDebug(debug ?? true);\n }\n\n getPersistedDebug(): boolean | string | undefined {\n if (typeof window === \"undefined\") return undefined;\n try {\n const persisted = window.sessionStorage.getItem(SESSION_DEBUG_KEY);\n if (!persisted) return undefined;\n return persisted;\n } catch {\n return undefined;\n }\n }\n\n syncInspector(effectiveDebug?: boolean | string): void {\n if (typeof window === \"undefined\") return;\n\n const enabled = Boolean(effectiveDebug);\n this.deps.setDebugEnabled(enabled);\n this.toggleStateLogger(enabled);\n\n const win = window as any;\n const disabledInspector = () => {\n console.warn(\"SIP debug inspector disabled; enable debug to inspect.\");\n return null;\n };\n\n win.sipState = () => (enabled ? this.deps.getState() : disabledInspector());\n win.sipSessions = () =>\n enabled ? this.deps.getSessions() : disabledInspector();\n }\n\n cleanup(): void {\n this.toggleStateLogger(false);\n }\n\n private toggleStateLogger(enabled: boolean): void {\n if (!enabled) {\n this.stateLogOff?.();\n this.stateLogOff = undefined;\n return;\n }\n if (this.stateLogOff) return;\n\n let prev = this.deps.getState();\n console.info(\"[sip][state]\", { initial: true }, prev);\n\n this.stateLogOff = this.deps.onChange((next) => {\n console.info(\"[sip][state]\", next);\n prev = next;\n });\n }\n}\n","import type { SipClient } from \"../../client\";\nimport type { SipEventManager } from \"../../sip/types\";\n\nexport function createSipEventManager(client: SipClient): SipEventManager {\n return {\n onUA(event, handler) {\n return client.on(event, handler as any);\n },\n onSession(sessionId, event, handler) {\n const session = client.getSession(sessionId);\n if (!session) return () => {};\n session.on(event, handler as any);\n return () => session.off(event, handler as any);\n },\n };\n}\n","type PcSnapshot = {\n connectionState?: RTCPeerConnectionState;\n signalingState?: RTCSignalingState;\n iceConnectionState?: RTCIceConnectionState;\n};\n\nconst describePc = (pc?: RTCPeerConnection | null): PcSnapshot => ({\n connectionState: pc?.connectionState,\n signalingState: pc?.signalingState,\n iceConnectionState: pc?.iceConnectionState,\n});\n\nexport class SipDebugLogger {\n private enabled = false;\n private statsStops = new Map<string, () => void>();\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n if (!enabled) {\n this.statsStops.forEach((stop) => stop());\n this.statsStops.clear();\n }\n }\n\n isEnabled() {\n return this.enabled;\n }\n\n logLocalAudioError(\n sessionId: string,\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>\n ) {\n if (!this.enabled) return;\n console.error(message, {\n sessionId,\n pc: describePc(pc),\n ...extra,\n });\n void this.logOutboundStats(sessionId, pc, message);\n }\n\n logRemoteAudioError(\n sessionId: string,\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>\n ) {\n if (!this.enabled) return;\n console.error(message, {\n sessionId,\n pc: describePc(pc),\n ...extra,\n });\n void this.logInboundStats(sessionId, pc, message);\n }\n\n logMicRecoveryDrop(payload: {\n sessionId?: string;\n trackLive?: boolean;\n senderLive?: boolean;\n }) {\n if (!this.enabled) return;\n console.error(\"[sip] microphone dropped\", payload);\n }\n\n logIceReady(sessionId: string, payload: Record<string, unknown>) {\n if (!this.enabled) return;\n console.info(\"[sip] ice ready\", { sessionId, ...payload });\n }\n\n logIceReadyConfig(sessionId: string, delayMs: number) {\n if (!this.enabled) return;\n console.info(\"[sip] ice ready config\", { sessionId, delayMs });\n }\n\n startCallStatsLogging(sessionId: string, session: any) {\n if (!this.enabled || this.statsStops.has(sessionId)) return;\n\n let pc: RTCPeerConnection | null =\n (session as { connection?: RTCPeerConnection })?.connection ?? null;\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\n pc = data.peerconnection;\n };\n session.on?.(\"peerconnection\", onPeer);\n\n const intervalMs = 3000;\n const logStats = async () => {\n if (!this.enabled || !pc?.getStats) return;\n try {\n const report = await pc.getStats();\n const { outboundAudio, inboundAudio } = collectAudioStats(report);\n console.info(\"[sip] call stats\", {\n sessionId,\n pc: describePc(pc),\n outboundAudio,\n inboundAudio,\n });\n } catch (err) {\n console.error(\"[sip] call stats failed\", { sessionId, error: err });\n }\n };\n\n const timer = setInterval(() => {\n void logStats();\n }, intervalMs);\n void logStats();\n\n const stop = () => {\n clearInterval(timer);\n session.off?.(\"peerconnection\", onPeer);\n this.statsStops.delete(sessionId);\n };\n this.statsStops.set(sessionId, stop);\n }\n\n stopCallStatsLogging(sessionId: string) {\n const stop = this.statsStops.get(sessionId);\n if (stop) stop();\n }\n\n private async logOutboundStats(\n sessionId: string,\n pc?: RTCPeerConnection | null,\n context?: string\n ) {\n if (!pc?.getStats) return;\n try {\n const report = await pc.getStats();\n const { outboundAudio } = collectAudioStats(report);\n if (outboundAudio.length) {\n console.info(\"[sip] outgoing audio stats\", {\n sessionId,\n context,\n outboundAudio,\n });\n }\n } catch (err) {\n console.error(\"[sip] outgoing audio stats failed\", {\n sessionId,\n context,\n error: err,\n });\n }\n }\n\n private async logInboundStats(\n sessionId: string,\n pc?: RTCPeerConnection | null,\n context?: string\n ) {\n if (!pc?.getStats) return;\n try {\n const report = await pc.getStats();\n const { inboundAudio } = collectAudioStats(report);\n if (inboundAudio.length) {\n console.error(\"[sip] incoming audio stats\", {\n sessionId,\n context,\n inboundAudio,\n });\n }\n } catch (err) {\n console.error(\"[sip] incoming audio stats failed\", {\n sessionId,\n context,\n error: err,\n });\n }\n }\n}\n\nexport const sipDebugLogger = new SipDebugLogger();\n\nfunction collectAudioStats(report: RTCStatsReport) {\n const outboundAudio: Array<Record<string, unknown>> = [];\n const inboundAudio: Array<Record<string, unknown>> = [];\n\n report.forEach((stat) => {\n const kind = (stat as any).kind ?? (stat as any).mediaType;\n if (stat.type === \"outbound-rtp\" && kind === \"audio\") {\n outboundAudio.push({\n id: stat.id,\n packetsSent: (stat as any).packetsSent,\n bytesSent: (stat as any).bytesSent,\n jitter: (stat as any).jitter,\n roundTripTime: (stat as any).roundTripTime,\n });\n }\n if (stat.type === \"inbound-rtp\" && kind === \"audio\") {\n inboundAudio.push({\n id: stat.id,\n packetsReceived: (stat as any).packetsReceived,\n packetsLost: (stat as any).packetsLost,\n bytesReceived: (stat as any).bytesReceived,\n jitter: (stat as any).jitter,\n roundTripTime: (stat as any).roundTripTime,\n });\n }\n });\n\n return { outboundAudio, inboundAudio };\n}\n","import type { RTCSession } from \"../../sip/types\";\nimport type { WebRTCSessionController } from \"./webrtc-session.controller\";\nimport { sipDebugLogger } from \"../debug/sip-debug.logger\";\n\nexport type MicrophoneRecoveryOptions = {\n intervalMs?: number;\n maxRetries?: number;\n};\n\ntype MicRecoveryDeps = {\n getRtc: (sessionId: string) => WebRTCSessionController | null;\n getSession: (sessionId: string) => RTCSession | null;\n getSessionState: (sessionId: string) => { muted?: boolean } | undefined;\n setSessionMedia: (sessionId: string, stream: MediaStream) => void;\n};\n\ntype MicRecoveryConfig = {\n enabled?: boolean;\n intervalMs?: number;\n maxRetries?: number;\n};\n\nexport class MicRecoveryManager {\n private enabled = false;\n private defaults: Required<MicrophoneRecoveryOptions> = {\n intervalMs: 2000,\n maxRetries: Infinity,\n };\n private active = new Map<string, { stop: () => void }>();\n private syncedSenderTrackId = new Map<string, string>();\n private readonly deps: MicRecoveryDeps;\n\n constructor(deps: MicRecoveryDeps) {\n this.deps = deps;\n }\n\n configure(config: MicRecoveryConfig) {\n if (typeof config.enabled === \"boolean\") {\n this.enabled = config.enabled;\n }\n if (typeof config.intervalMs === \"number\") {\n this.defaults.intervalMs = config.intervalMs;\n }\n if (typeof config.maxRetries === \"number\") {\n this.defaults.maxRetries = config.maxRetries;\n }\n }\n\n enable(\n sessionId: string,\n options: MicrophoneRecoveryOptions = {}\n ): () => void {\n if (!this.enabled) return () => {};\n\n this.disable(sessionId);\n\n const intervalMs = options.intervalMs ?? this.defaults.intervalMs;\n const maxRetries = options.maxRetries ?? this.defaults.maxRetries;\n let retries = 0;\n let stopped = false;\n const startedAt = Date.now();\n const warmupMs = Math.max(intervalMs * 2, 2000);\n\n const tick = async () => {\n if (stopped || retries >= maxRetries) return;\n\n const rtc = this.deps.getRtc(sessionId);\n const session = this.deps.getSession(sessionId);\n if (!rtc || !session) return;\n\n const sessionState = this.deps.getSessionState(sessionId);\n if (sessionState?.muted) return;\n\n const stream = rtc.mediaStream;\n const track = stream?.getAudioTracks?.()[0];\n const pc: RTCPeerConnection | undefined = (session as any)?.connection;\n const sender = pc\n ?.getSenders?.()\n ?.find((s: RTCRtpSender) => s.track?.kind === \"audio\");\n\n if (!track && !sender) return;\n if (!track && sender?.track?.readyState === \"live\") {\n const nextId = sender.track.id;\n const prevId = this.syncedSenderTrackId.get(sessionId);\n if (prevId === nextId) return;\n this.syncedSenderTrackId.set(sessionId, nextId);\n this.deps.setSessionMedia(sessionId, new MediaStream([sender.track]));\n return;\n }\n\n if (Date.now() - startedAt < warmupMs) return;\n if (\n pc?.connectionState === \"new\" ||\n pc?.connectionState === \"connecting\" ||\n pc?.iceConnectionState === \"new\" ||\n pc?.iceConnectionState === \"checking\"\n ) {\n return;\n }\n\n const trackLive = track?.readyState === \"live\";\n const senderLive = sender?.track?.readyState === \"live\";\n if (trackLive && senderLive) return;\n\n sipDebugLogger.logMicRecoveryDrop({\n sessionId,\n trackLive,\n senderLive,\n });\n\n retries += 1;\n if (trackLive && !senderLive && track) {\n await rtc.replaceAudioTrack(track);\n return;\n }\n\n // No internal getUserMedia request path in library.\n // If both track and sender are not live, recovery stops here.\n };\n\n const timer = setInterval(() => {\n void tick();\n }, intervalMs);\n void tick();\n\n const session = this.deps.getSession(sessionId);\n const pc: RTCPeerConnection | undefined = (session as any)?.connection;\n const onIceChange = () => {\n const state = pc?.iceConnectionState;\n if (state === \"failed\" || state === \"disconnected\") void tick();\n };\n pc?.addEventListener?.(\"iceconnectionstatechange\", onIceChange);\n\n const stop = () => {\n stopped = true;\n clearInterval(timer);\n pc?.removeEventListener?.(\"iceconnectionstatechange\", onIceChange);\n };\n this.active.set(sessionId, { stop });\n return stop;\n }\n\n disable(sessionId: string) {\n const entry = this.active.get(sessionId);\n if (!entry) return false;\n entry.stop();\n this.active.delete(sessionId);\n this.syncedSenderTrackId.delete(sessionId);\n return true;\n }\n\n cleanupAll() {\n this.active.forEach((entry) => entry.stop());\n this.active.clear();\n this.syncedSenderTrackId.clear();\n }\n}\n","export class BrowserUnloadRuntime {\n private handler?: () => void;\n\n attach(onBeforeUnload: () => void): void {\n if (typeof window === \"undefined\" || this.handler) return;\n this.handler = () => onBeforeUnload();\n window.addEventListener(\"beforeunload\", this.handler);\n }\n\n detach(): void {\n if (typeof window === \"undefined\" || !this.handler) return;\n window.removeEventListener(\"beforeunload\", this.handler);\n this.handler = undefined;\n }\n}\n\n","import type {\n AnswerOptions,\n DTMFOptions,\n ReferOptions,\n RTCSession,\n TerminateOptions,\n} from \"../../sip/types\";\n\nexport class WebRTCSessionController {\n currentSession: RTCSession | null = null;\n mediaStream: MediaStream | null = null;\n\n public setSession(session: RTCSession | null) {\n this.currentSession = session;\n }\n\n public setMediaStream(stream: MediaStream) {\n this.mediaStream = stream;\n }\n\n private getPC(): RTCPeerConnection | null {\n return (this.currentSession as any)?.connection ?? null;\n }\n\n public cleanup(stopTracks: boolean = true): void {\n const pc = this.getPC();\n const isClosed =\n pc?.connectionState === \"closed\" || pc?.signalingState === \"closed\";\n\n if (pc && typeof pc.getSenders === \"function\") {\n if (!isClosed) {\n for (const sender of pc.getSenders()) {\n try {\n sender.replaceTrack(null);\n } catch {\n // ignore if sender/pc already closed\n }\n }\n }\n }\n\n if (stopTracks && this.mediaStream) {\n const senderTracks =\n pc && !isClosed\n ? new Set(\n pc\n .getSenders()\n .map((sender) => sender.track)\n .filter((track): track is MediaStreamTrack => Boolean(track))\n )\n : null;\n for (const track of this.mediaStream.getTracks()) {\n if (senderTracks?.has(track)) continue;\n track.stop();\n }\n }\n\n this.mediaStream = null;\n this.currentSession = null;\n }\n\n public answer(options: AnswerOptions = {}): boolean {\n return this.currentSession\n ? (this.currentSession.answer(options), true)\n : false;\n }\n\n public hangup(options?: TerminateOptions): boolean {\n return this.currentSession\n ? (this.currentSession.terminate(\n options ?? ({ status_code: 486, reason_phrase: \"Busy Here\" } as any)\n ),\n true)\n : false;\n }\n\n public mute(): boolean {\n this.mediaStream?.getAudioTracks().forEach((track) => (track.enabled = false));\n return this.currentSession\n ? (this.currentSession.mute({ audio: true }), true)\n : false;\n }\n\n public unmute(): boolean {\n this.mediaStream?.getAudioTracks().forEach((track) => (track.enabled = true));\n return this.currentSession\n ? (this.currentSession.unmute({ audio: true }), true)\n : false;\n }\n\n public hold(): boolean {\n return this.currentSession ? (this.currentSession.hold(), true) : false;\n }\n\n public unhold(): boolean {\n return this.currentSession ? (this.currentSession.unhold(), true) : false;\n }\n\n public sendDTMF(tones: string | number, options?: DTMFOptions): boolean {\n return this.currentSession\n ? (this.currentSession.sendDTMF(tones, options), true)\n : false;\n }\n\n public transfer(target: string, options?: ReferOptions): boolean {\n return this.currentSession\n ? (this.currentSession.refer(target as any, options), true)\n : false;\n }\n\n public async replaceAudioTrack(\n nextAudioTrack: MediaStreamTrack\n ): Promise<boolean> {\n const pc = this.getPC();\n if (!pc) return false;\n\n if (!this.mediaStream) this.mediaStream = new MediaStream();\n\n const old = this.mediaStream.getAudioTracks()[0];\n this.mediaStream.addTrack(nextAudioTrack);\n if (old) this.mediaStream.removeTrack(old);\n\n const sender = pc.getSenders?.().find((entry) => entry.track?.kind === \"audio\");\n if (sender) await sender.replaceTrack(nextAudioTrack);\n\n if (old && old !== nextAudioTrack) old.stop();\n\n return true;\n }\n}\n","import { WebRTCSessionController } from \"../media/webrtc-session.controller\";\nimport type { RTCSession } from \"../../sip/types\";\n\ntype SessionEntry = {\n rtc: WebRTCSessionController;\n session?: RTCSession | null;\n media?: MediaStream | null;\n};\n\nexport class SessionManager {\n private entries = new Map<string, SessionEntry>();\n\n private stopMediaStream(stream?: MediaStream | null) {\n if (!stream) return;\n for (const track of stream.getTracks()) {\n if (track.readyState !== \"ended\") track.stop();\n }\n }\n\n getOrCreateRtc(sessionId: string, session?: RTCSession) {\n let entry = this.entries.get(sessionId);\n if (!entry) {\n entry = {\n rtc: new WebRTCSessionController(),\n session: null,\n media: null,\n };\n this.entries.set(sessionId, entry);\n }\n if (session) {\n entry.session = session;\n entry.rtc.setSession(session);\n }\n if (entry.media) entry.rtc.setMediaStream(entry.media);\n return entry.rtc;\n }\n\n getRtc(sessionId: string) {\n return this.entries.get(sessionId)?.rtc ?? null;\n }\n\n setSession(sessionId: string, session: RTCSession) {\n const entry = this.entries.get(sessionId);\n if (entry) {\n entry.session = session;\n entry.rtc.setSession(session);\n } else {\n this.entries.set(sessionId, {\n rtc: new WebRTCSessionController(),\n session,\n media: null,\n });\n }\n }\n\n setSessionMedia(sessionId: string, stream: MediaStream) {\n const entry = this.entries.get(sessionId) ?? {\n rtc: new WebRTCSessionController(),\n session: null,\n media: null,\n };\n if (entry.media && entry.media !== stream) {\n this.stopMediaStream(entry.media);\n }\n entry.media = stream;\n entry.rtc.setMediaStream(stream);\n this.entries.set(sessionId, entry);\n }\n\n getSession(sessionId: string) {\n return this.entries.get(sessionId)?.session ?? null;\n }\n\n getSessionIds() {\n return Array.from(this.entries.keys());\n }\n\n getSessions() {\n return Array.from(this.entries.entries()).map(([id, entry]) => ({\n id,\n session: entry.session as RTCSession,\n }));\n }\n\n cleanupSession(sessionId: string) {\n const entry = this.entries.get(sessionId);\n if (entry) {\n entry.rtc.cleanup();\n this.stopMediaStream(entry.media);\n this.entries.delete(sessionId);\n }\n }\n\n cleanupAllSessions() {\n for (const [, entry] of this.entries.entries()) {\n entry.rtc.cleanup();\n this.stopMediaStream(entry.media);\n }\n this.entries.clear();\n }\n\n answer(sessionId: string, options: any) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.answer(options) : false;\n }\n\n hangup(sessionId: string, options?: any) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.hangup(options) : false;\n }\n\n mute(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.mute() : false;\n }\n\n unmute(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.unmute() : false;\n }\n\n hold(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.hold() : false;\n }\n\n unhold(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.unhold() : false;\n }\n\n sendDTMF(sessionId: string, tones: string | number, options?: any) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.sendDTMF(tones, options) : false;\n }\n\n transfer(sessionId: string, target: string, options?: any) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.transfer(target, options) : false;\n }\n}\n","import { CallStatus, SipSessionState } from \"../../contracts/state\";\nimport { SipStateStore } from \"../state/sip.state.store\";\n\nfunction toSessionMaps(sessions: SipSessionState[]) {\n const sessionsById: Record<string, SipSessionState> = {};\n const sessionIds: string[] = [];\n\n for (const session of sessions) {\n sessionsById[session.id] = session;\n sessionIds.push(session.id);\n }\n\n return { sessionsById, sessionIds };\n}\n\nexport function holdOtherSessions(\n state: SipStateStore,\n sessionId: string,\n holdFn: (id: string) => void\n) {\n const current = state.getState();\n current.sessionIds.forEach((id) => {\n if (id === sessionId) return;\n const session = current.sessionsById[id];\n if (session?.status === CallStatus.Active) {\n holdFn(id);\n }\n });\n}\n\nexport function upsertSessionState(\n state: SipStateStore,\n sessionId: string,\n partial: Partial<SipSessionState>\n) {\n const current = state.getState();\n const existing = current.sessionsById[sessionId];\n const base: SipSessionState = existing ?? {\n id: sessionId,\n status: CallStatus.Idle,\n direction: null,\n from: null,\n to: null,\n muted: false,\n acceptedAt: null,\n };\n\n const nextSession = { ...base, ...partial };\n const sessions = current.sessionIds.map((id) =>\n id === sessionId ? nextSession : current.sessionsById[id]\n );\n\n if (!existing) {\n sessions.push(nextSession);\n }\n\n const { sessionsById, sessionIds } = toSessionMaps(sessions);\n\n state.setState({ sessions, sessionsById, sessionIds });\n}\n\nexport function removeSessionState(state: SipStateStore, sessionId: string) {\n const current = state.getState();\n const sessions = current.sessionIds\n .filter((id) => id !== sessionId)\n .map((id) => current.sessionsById[id]);\n const { sessionsById, sessionIds } = toSessionMaps(sessions);\n\n state.setState({\n sessions,\n sessionsById,\n sessionIds,\n error: null,\n });\n}\n","import { EndEvent, RTCSessionEventMap } from \"../../sip/types\";\nimport { CallStatus } from \"../../contracts/state\";\nimport { SipStateStore } from \"../state/sip.state.store\";\nimport { WebRTCSessionController } from \"../media/webrtc-session.controller\";\nimport { JsSIPEventMap } from \"../../sip/types\";\nimport { EventTargetEmitter } from \"../event/event-target.emitter\";\nimport {\n removeSessionState,\n upsertSessionState,\n} from \"./session.state.projector\";\nimport { sipDebugLogger } from \"../debug/sip-debug.logger\";\n\nimport {\n IncomingAckEvent,\n IncomingDTMFEvent,\n IncomingEvent,\n IncomingInfoEvent,\n OutgoingAckEvent,\n OutgoingDTMFEvent,\n OutgoingEvent,\n OutgoingInfoEvent,\n PeerConnectionEvent,\n} from \"jssip/src/RTCSession\";\n\ntype Deps = {\n emitter: EventTargetEmitter<JsSIPEventMap>;\n state: SipStateStore;\n rtc: WebRTCSessionController;\n detachSessionHandlers: () => void;\n enableMicrophoneRecovery?: (sessionId: string) => void;\n iceCandidateReadyDelayMs?: number;\n sessionId: string;\n};\n\nexport function createSessionHandlers(deps: Deps): Partial<RTCSessionEventMap> {\n const {\n emitter,\n state,\n rtc,\n detachSessionHandlers,\n sessionId,\n iceCandidateReadyDelayMs,\n } = deps;\n let iceReadyCalled = false;\n let iceReadyTimer: ReturnType<typeof setTimeout> | null = null;\n const clearIceReadyTimer = () => {\n if (!iceReadyTimer) return;\n clearTimeout(iceReadyTimer);\n iceReadyTimer = null;\n };\n if (typeof iceCandidateReadyDelayMs === \"number\") {\n sipDebugLogger.logIceReadyConfig(sessionId, iceCandidateReadyDelayMs);\n }\n\n return {\n progress: (e: IncomingEvent | OutgoingEvent) => {\n emitter.emit(\"progress\", e);\n },\n accepted: (e: IncomingEvent | OutgoingEvent) => {\n emitter.emit(\"accepted\", e);\n const existing = state.getState().sessionsById[sessionId];\n upsertSessionState(state, sessionId, {\n status: CallStatus.Active,\n acceptedAt: existing?.acceptedAt ?? Date.now(),\n });\n },\n confirmed: (e: IncomingAckEvent | OutgoingAckEvent) => {\n emitter.emit(\"confirmed\", e);\n deps.enableMicrophoneRecovery?.(sessionId);\n },\n\n ended: (e) => {\n emitter.emit(\"ended\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n failed: (e) => {\n emitter.emit(\"failed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n\n muted: (e) => {\n emitter.emit(\"muted\", e);\n upsertSessionState(state, sessionId, { muted: true });\n },\n unmuted: (e) => {\n emitter.emit(\"unmuted\", e);\n upsertSessionState(state, sessionId, { muted: false });\n },\n hold: (e) => {\n emitter.emit(\"hold\", e);\n upsertSessionState(state, sessionId, { status: CallStatus.Hold });\n },\n unhold: (e) => {\n emitter.emit(\"unhold\", e);\n upsertSessionState(state, sessionId, { status: CallStatus.Active });\n },\n\n reinvite: (e) => emitter.emit(\"reinvite\", e),\n update: (e) => emitter.emit(\"update\", e),\n sdp: (e) => emitter.emit(\"sdp\", e),\n icecandidate: (e) => {\n const candidate = e?.candidate;\n const ready = typeof e?.ready === \"function\" ? e.ready : null;\n const delayMs =\n typeof iceCandidateReadyDelayMs === \"number\"\n ? iceCandidateReadyDelayMs\n : null;\n if (!iceReadyCalled && ready && delayMs != null) {\n if (\n candidate?.type === \"srflx\" &&\n candidate?.relatedAddress != null &&\n candidate?.relatedPort != null\n ) {\n iceReadyCalled = true;\n if (iceReadyTimer) {\n clearTimeout(iceReadyTimer);\n iceReadyTimer = null;\n }\n sipDebugLogger.logIceReady(sessionId, {\n source: \"srflx\",\n delayMs,\n candidateType: candidate?.type,\n });\n ready();\n } else if (!iceReadyTimer && delayMs > 0) {\n iceReadyTimer = setTimeout(() => {\n iceReadyTimer = null;\n if (iceReadyCalled) return;\n iceReadyCalled = true;\n sipDebugLogger.logIceReady(sessionId, {\n source: \"timer\",\n delayMs,\n candidateType: candidate?.type,\n });\n ready();\n }, delayMs);\n } else if (delayMs === 0) {\n iceReadyCalled = true;\n sipDebugLogger.logIceReady(sessionId, {\n source: \"immediate\",\n delayMs,\n candidateType: candidate?.type,\n });\n ready();\n }\n }\n emitter.emit(\"icecandidate\", e);\n },\n refer: (e) => emitter.emit(\"refer\", e),\n replaces: (e) => emitter.emit(\"replaces\", e),\n newDTMF: (e: IncomingDTMFEvent | OutgoingDTMFEvent) =>\n emitter.emit(\"newDTMF\", e),\n newInfo: (e: OutgoingInfoEvent | IncomingInfoEvent) =>\n emitter.emit(\"newInfo\", e),\n\n getusermediafailed: (e) => {\n emitter.emit(\"getusermediafailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:createofferfailed\": (e) => {\n emitter.emit(\"peerconnection:createofferfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:createanswerfailed\": (e) => {\n emitter.emit(\"peerconnection:createanswerfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:setlocaldescriptionfailed\": (e) => {\n emitter.emit(\"peerconnection:setlocaldescriptionfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:setremotedescriptionfailed\": (e) => {\n emitter.emit(\"peerconnection:setremotedescriptionfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n peerconnection: (e: PeerConnectionEvent) => emitter.emit(\"peerconnection\", e),\n };\n}\n","import { SipStateStore } from \"../state/sip.state.store\";\nimport { CallStatus } from \"../../contracts/state\";\nimport { SessionManager } from \"./session.manager\";\nimport { holdOtherSessions, upsertSessionState } from \"./session.state.projector\";\nimport type {\n JsSIPEventName,\n RTCSession,\n RTCSessionEvent,\n} from \"../../sip/types\";\nimport { sipDebugLogger } from \"../debug/sip-debug.logger\";\n\ntype Deps = {\n state: SipStateStore;\n sessionManager: SessionManager;\n emit: <K extends JsSIPEventName>(event: K, payload: any) => void;\n attachSessionHandlers: (sessionId: string, session: RTCSession) => void;\n getMaxSessionCount: () => number;\n};\n\nexport class SessionLifecycle {\n private readonly state: SipStateStore;\n private readonly sessionManager: SessionManager;\n private readonly emit: Deps[\"emit\"];\n private readonly attachSessionHandlers: Deps[\"attachSessionHandlers\"];\n private readonly getMaxSessionCount: Deps[\"getMaxSessionCount\"];\n\n constructor(deps: Deps) {\n this.state = deps.state;\n this.sessionManager = deps.sessionManager;\n this.emit = deps.emit;\n this.attachSessionHandlers = deps.attachSessionHandlers;\n this.getMaxSessionCount = deps.getMaxSessionCount;\n }\n\n public setDebugEnabled(enabled: boolean) {\n sipDebugLogger.setEnabled(enabled);\n }\n\n handleNewRTCSession(e: RTCSessionEvent) {\n const session = e.session;\n const sessionId = String(\n (session as any)?.id ?? crypto.randomUUID?.() ?? Date.now(),\n );\n\n const currentSessions = this.state.getState().sessions;\n if (currentSessions.length >= this.getMaxSessionCount()) {\n try {\n session.terminate?.({\n status_code: 486,\n reason_phrase: \"Busy Here\",\n } as any);\n } catch {\n /* ignore termination errors */\n }\n }\n\n const rtc = this.sessionManager.getOrCreateRtc(sessionId, session);\n this.sessionManager.setSession(sessionId, session);\n this.attachSessionHandlers(sessionId, session);\n this.attachCallStatsLogging(sessionId, session);\n\n if (e.originator === \"local\" && !rtc.mediaStream) {\n this.bindLocalOutgoingAudio(sessionId, session);\n }\n if (e.originator === \"remote\") {\n this.bindRemoteIncomingAudio(sessionId, session);\n }\n\n holdOtherSessions(this.state, sessionId, (id) => {\n const otherRtc = this.sessionManager.getRtc(id);\n otherRtc?.hold();\n });\n\n upsertSessionState(this.state, sessionId, {\n direction: e.originator,\n from: e.originator === \"remote\" ? e.request.from.uri.user : null,\n to: e.request.to.uri.user,\n status:\n e.originator === \"remote\" ? CallStatus.Ringing : CallStatus.Dialing,\n });\n\n this.emit(\"newRTCSession\", e);\n }\n\n private bindLocalOutgoingAudio(sessionId: string, session: RTCSession) {\n const maxAttempts = 50;\n const retryDelayMs = 500;\n let attempts = 0;\n let retryScheduled = false;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let stopped = false;\n let exhausted = false;\n let exhaustedCheckUsed = false;\n let attachedPc: RTCPeerConnection | null = null;\n const logLocalAudioError = (\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>,\n ) => {\n sipDebugLogger.logLocalAudioError(sessionId, message, pc, extra);\n };\n\n const tryBindFromPc = (pc?: RTCPeerConnection | null) => {\n if (\n stopped ||\n !pc ||\n this.sessionManager.getRtc(sessionId)?.mediaStream\n ) {\n return false;\n }\n const audioSender = pc\n ?.getSenders?.()\n ?.find((s: RTCRtpSender) => s.track?.kind === \"audio\");\n const audioTrack = audioSender?.track;\n if (!audioTrack) {\n logLocalAudioError(\n \"[sip] outgoing audio bind failed: no audio track\",\n pc,\n );\n return false;\n }\n const outgoingStream = new MediaStream([audioTrack]);\n this.sessionManager.setSessionMedia(sessionId, outgoingStream);\n return true;\n };\n\n const onPcStateChange = () => {\n if (stopped) return;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (tryBindFromPc(attachedPc)) stopRetry();\n return;\n }\n if (tryBindFromPc(attachedPc)) stopRetry();\n };\n\n const attachPcListeners = (pc?: RTCPeerConnection | null) => {\n if (!pc || pc === attachedPc) return;\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange,\n );\n }\n attachedPc = pc;\n attachedPc.addEventListener?.(\"signalingstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\"connectionstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange,\n );\n };\n\n const clearRetryTimer = () => {\n if (!retryTimer) return;\n clearTimeout(retryTimer);\n retryTimer = null;\n };\n\n const stopRetry = (opts: { keepTrack?: boolean } = {}) => {\n if (stopped) return;\n stopped = true;\n clearRetryTimer();\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange,\n );\n attachedPc = null;\n }\n session.off?.(\"peerconnection\", onPeer);\n session.off?.(\"confirmed\", onConfirmed);\n session.off?.(\"ended\", stopRetry);\n session.off?.(\"failed\", stopRetry);\n };\n\n const scheduleRetry = (pc?: RTCPeerConnection | null) => {\n if (stopped || retryScheduled || exhausted) return;\n if (attempts >= maxAttempts) {\n logLocalAudioError(\n \"[sip] outgoing audio bind failed: max retries reached\",\n pc,\n { attempts },\n );\n exhausted = true;\n clearRetryTimer();\n return;\n }\n if (!pc) {\n logLocalAudioError(\n \"[sip] outgoing audio bind failed: missing peerconnection\",\n pc,\n );\n }\n retryScheduled = true;\n attempts += 1;\n retryTimer = setTimeout(() => {\n retryScheduled = false;\n retryTimer = null;\n if (tryBindFromPc(pc)) {\n stopRetry();\n return;\n }\n scheduleRetry(pc);\n }, retryDelayMs);\n };\n\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\n if (stopped) return;\n attachPcListeners(data.peerconnection);\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (tryBindFromPc(data.peerconnection)) stopRetry();\n return;\n }\n if (tryBindFromPc(data.peerconnection)) {\n stopRetry();\n return;\n }\n scheduleRetry(data.peerconnection);\n };\n\n const onConfirmed = () => {\n if (stopped) return;\n const currentPc =\n (session as RTCSession & { connection?: RTCPeerConnection })\n ?.connection ?? attachedPc;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (tryBindFromPc(currentPc)) stopRetry();\n return;\n }\n if (tryBindFromPc(currentPc)) {\n stopRetry();\n return;\n }\n scheduleRetry(currentPc);\n };\n\n const existingPc = (\n session as RTCSession & {\n connection?: RTCPeerConnection;\n }\n )?.connection;\n if (!tryBindFromPc(existingPc)) {\n if (existingPc) {\n attachPcListeners(existingPc);\n scheduleRetry(existingPc);\n }\n session.on?.(\"peerconnection\", onPeer);\n }\n session.on?.(\"confirmed\", onConfirmed);\n session.on?.(\"ended\", (e) => stopRetry());\n session.on?.(\"failed\", (e) => stopRetry());\n }\n\n private bindRemoteIncomingAudio(sessionId: string, session: RTCSession) {\n const maxAttempts = 50;\n const retryDelayMs = 500;\n let attempts = 0;\n let retryScheduled = false;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let stopped = false;\n let exhausted = false;\n let exhaustedCheckUsed = false;\n let attachedPc: RTCPeerConnection | null = null;\n let attachedTrack: MediaStreamTrack | null = null;\n const logRemoteAudioError = (\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>,\n ) => {\n sipDebugLogger.logRemoteAudioError(sessionId, message, pc, extra);\n };\n\n const logMissingReceiver = (\n pc?: RTCPeerConnection | null,\n note?: string,\n ) => {\n logRemoteAudioError(\n \"[sip] incoming audio bind failed: no remote track\",\n pc,\n { note },\n );\n };\n\n const getRemoteAudioTrack = (pc?: RTCPeerConnection | null) => {\n const receiver = pc\n ?.getReceivers?.()\n ?.find((r: RTCRtpReceiver) => r.track?.kind === \"audio\");\n return receiver?.track ?? null;\n };\n\n const attachTrackListeners = (track?: MediaStreamTrack | null) => {\n if (!track || track === attachedTrack) return;\n if (attachedTrack) {\n attachedTrack.removeEventListener?.(\"ended\", onRemoteEnded);\n attachedTrack.removeEventListener?.(\"mute\", onRemoteMuted);\n }\n attachedTrack = track;\n attachedTrack.addEventListener?.(\"ended\", onRemoteEnded);\n attachedTrack.addEventListener?.(\"mute\", onRemoteMuted);\n };\n\n const checkRemoteTrack = (pc?: RTCPeerConnection | null) => {\n if (stopped || !pc) return false;\n const track = getRemoteAudioTrack(pc);\n if (!track) return false;\n attachTrackListeners(track);\n if (track.readyState !== \"live\") {\n logRemoteAudioError(\"[sip] incoming audio track not live\", pc, {\n trackState: track.readyState,\n });\n }\n return true;\n };\n\n const onRemoteEnded = () => {\n logRemoteAudioError(\"[sip] incoming audio track ended\", attachedPc);\n };\n\n const onRemoteMuted = () => {\n logRemoteAudioError(\"[sip] incoming audio track muted\", attachedPc);\n };\n\n const onPcStateChange = () => {\n if (stopped) return;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n };\n\n const attachPcListeners = (pc?: RTCPeerConnection | null) => {\n if (!pc || pc === attachedPc) return;\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\"track\", onTrack);\n }\n attachedPc = pc;\n attachedPc.addEventListener?.(\"signalingstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\"connectionstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange,\n );\n attachedPc.addEventListener?.(\"track\", onTrack);\n };\n\n const clearRetryTimer = () => {\n if (!retryTimer) return;\n clearTimeout(retryTimer);\n retryTimer = null;\n };\n\n const stopRetry = (opts: { keepTrack?: boolean } = {}) => {\n if (stopped) return;\n stopped = true;\n clearRetryTimer();\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange,\n );\n attachedPc.removeEventListener?.(\"track\", onTrack);\n attachedPc = null;\n }\n if (attachedTrack && !opts.keepTrack) {\n attachedTrack.removeEventListener?.(\"ended\", onRemoteEnded);\n attachedTrack.removeEventListener?.(\"mute\", onRemoteMuted);\n attachedTrack = null;\n }\n session.off?.(\"peerconnection\", onPeer);\n session.off?.(\"confirmed\", onConfirmed);\n session.off?.(\"ended\", stopRetry);\n session.off?.(\"failed\", stopRetry);\n };\n\n const scheduleRetry = (pc?: RTCPeerConnection | null) => {\n if (stopped || retryScheduled || exhausted) return;\n if (attempts >= maxAttempts) {\n logRemoteAudioError(\n \"[sip] incoming audio bind failed: max retries reached\",\n pc,\n { attempts },\n );\n exhausted = true;\n clearRetryTimer();\n return;\n }\n retryScheduled = true;\n attempts += 1;\n retryTimer = setTimeout(() => {\n retryScheduled = false;\n retryTimer = null;\n if (checkRemoteTrack(pc)) {\n stopRetry({ keepTrack: true });\n return;\n }\n if (!pc) logMissingReceiver(pc, \"missing peerconnection\");\n scheduleRetry(pc);\n }, retryDelayMs);\n };\n\n const onTrack = () => {\n if (stopped) return;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n };\n\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\n if (stopped) return;\n attachPcListeners(data.peerconnection);\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(data.peerconnection))\n stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(data.peerconnection)) {\n stopRetry({ keepTrack: true });\n return;\n }\n scheduleRetry(data.peerconnection);\n };\n\n const onConfirmed = () => {\n if (stopped) return;\n const currentPc =\n (session as RTCSession & { connection?: RTCPeerConnection })\n ?.connection ?? attachedPc;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(currentPc)) stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(currentPc)) {\n stopRetry({ keepTrack: true });\n return;\n }\n logMissingReceiver(currentPc, \"confirmed without remote track\");\n scheduleRetry(currentPc);\n };\n\n const existingPc = (\n session as RTCSession & {\n connection?: RTCPeerConnection;\n }\n )?.connection;\n if (!checkRemoteTrack(existingPc)) {\n if (existingPc) {\n attachPcListeners(existingPc);\n scheduleRetry(existingPc);\n }\n session.on?.(\"peerconnection\", onPeer);\n }\n session.on?.(\"confirmed\", onConfirmed);\n session.on?.(\"ended\", () => stopRetry());\n session.on?.(\"failed\", () => stopRetry());\n }\n\n private attachCallStatsLogging(sessionId: string, session: RTCSession) {\n const onConfirmed = () => {\n sipDebugLogger.startCallStatsLogging(sessionId, session);\n };\n const onEnd = () => {\n sipDebugLogger.stopCallStatsLogging(sessionId);\n };\n\n session.on?.(\"confirmed\", onConfirmed);\n session.on?.(\"ended\", onEnd);\n session.on?.(\"failed\", onEnd);\n }\n}\n","import type { SipStateStore } from \"../state/sip.state.store\";\nimport { CallStatus } from \"../../contracts/state\";\nimport type { EventTargetEmitter } from \"../event/event-target.emitter\";\nimport type {\n AnswerOptions,\n DTMFOptions,\n JsSIPEventMap,\n ReferOptions,\n RTCSession,\n RTCSessionEvent,\n RTCSessionEventMap,\n TerminateOptions,\n} from \"../../sip/types\";\nimport { createSessionHandlers } from \"./session.handlers\";\nimport { SessionManager } from \"./session.manager\";\nimport { removeSessionState } from \"./session.state.projector\";\nimport { SessionLifecycle } from \"./session.lifecycle\";\nimport { MicRecoveryManager } from \"../media/mic-recovery.manager\";\n\ntype SessionModuleDeps = {\n state: SipStateStore;\n emitter: EventTargetEmitter<JsSIPEventMap>;\n sessionManager: SessionManager;\n micRecovery: MicRecoveryManager;\n getMaxSessionCount: () => number;\n getIceCandidateReadyDelayMs: () => number | undefined;\n};\n\nexport class SessionModule {\n private sessionHandlers = new Map<string, Partial<RTCSessionEventMap>>();\n private lifecycle: SessionLifecycle;\n\n constructor(private readonly deps: SessionModuleDeps) {\n this.lifecycle = new SessionLifecycle({\n state: deps.state,\n sessionManager: deps.sessionManager,\n emit: (event, payload) => deps.emitter.emit(event as any, payload as any),\n attachSessionHandlers: (sessionId, session) =>\n this.attachSessionHandlers(sessionId, session),\n getMaxSessionCount: deps.getMaxSessionCount,\n });\n }\n\n setDebugEnabled(enabled: boolean) {\n this.lifecycle.setDebugEnabled(enabled);\n }\n\n handleNewRTCSession(e: RTCSessionEvent) {\n this.lifecycle.handleNewRTCSession(e);\n }\n\n setSessionMedia(sessionId: string, stream: MediaStream) {\n this.deps.sessionManager.setSessionMedia(sessionId, stream);\n }\n\n setSession(sessionId: string, session: RTCSession) {\n this.deps.sessionManager.setSession(sessionId, session);\n }\n\n answerSession(sessionId: string, options: AnswerOptions = {}) {\n if (!sessionId || !this.sessionExists(sessionId)) return false;\n return this.deps.sessionManager.answer(sessionId, options);\n }\n\n hangupSession(sessionId: string, options?: TerminateOptions) {\n if (!sessionId || !this.sessionExists(sessionId)) return false;\n return this.deps.sessionManager.hangup(sessionId, options);\n }\n\n hangupAll(options?: TerminateOptions) {\n const ids = this.getSessionIds();\n ids.forEach((id) => this.hangupSession(id, options));\n return ids.length > 0;\n }\n\n toggleMuteSession(sessionId?: string) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n const muted = sessionState?.muted ?? false;\n if (muted) {\n this.deps.sessionManager.unmute(resolved);\n return true;\n }\n this.deps.sessionManager.mute(resolved);\n return true;\n }\n\n toggleHoldSession(sessionId?: string) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n const isOnHold = sessionState?.status === CallStatus.Hold;\n if (isOnHold) {\n this.deps.sessionManager.unhold(resolved);\n return true;\n }\n if (sessionState?.status === CallStatus.Active) {\n this.deps.sessionManager.hold(resolved);\n return true;\n }\n return true;\n }\n\n sendDTMFSession(\n sessionId: string,\n tones: string | number,\n options?: DTMFOptions\n ) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n if (sessionState?.status === CallStatus.Active) {\n this.deps.sessionManager.sendDTMF(resolved, tones, options);\n }\n return true;\n }\n\n transferSession(sessionId: string, target: string, options?: ReferOptions) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n if (sessionState?.status === CallStatus.Active) {\n this.deps.sessionManager.transfer(resolved, target, options);\n }\n return true;\n }\n\n getSession(sessionId: string) {\n return this.deps.sessionManager.getSession(sessionId);\n }\n\n getSessionIds() {\n return this.deps.sessionManager.getSessionIds();\n }\n\n getSessions() {\n return this.deps.sessionManager.getSessions();\n }\n\n cleanupAllSessions() {\n this.deps.sessionManager.cleanupAllSessions();\n this.deps.micRecovery.cleanupAll();\n this.sessionHandlers.clear();\n this.deps.state.setState({\n sessions: [],\n sessionsById: {},\n sessionIds: [],\n error: null,\n });\n }\n\n private attachSessionHandlers(sessionId: string, session: RTCSession) {\n const handlers = this.createSessionHandlersFor(sessionId, session);\n this.sessionHandlers.set(sessionId, handlers);\n\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\n const h = handlers[ev];\n if (h) session.on(ev, h as any);\n });\n }\n\n private detachSessionHandlers(sessionId: string, session: RTCSession) {\n const handlers = this.sessionHandlers.get(sessionId);\n if (!handlers || !session) return;\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\n const h = handlers[ev];\n if (h) session.off(ev, h as any);\n });\n this.sessionHandlers.delete(sessionId);\n }\n\n private cleanupSession(sessionId: string, session?: RTCSession) {\n const targetSession =\n session ??\n this.deps.sessionManager.getSession(sessionId) ??\n this.deps.sessionManager.getRtc(sessionId)?.currentSession;\n this.detachSessionHandlers(sessionId, targetSession as any);\n this.deps.micRecovery.disable(sessionId);\n this.deps.sessionManager.cleanupSession(sessionId);\n removeSessionState(this.deps.state, sessionId);\n }\n\n private createSessionHandlersFor(\n sessionId: string,\n session: RTCSession\n ): Partial<RTCSessionEventMap> {\n const rtc = this.deps.sessionManager.getOrCreateRtc(sessionId, session);\n return createSessionHandlers({\n emitter: this.deps.emitter,\n state: this.deps.state,\n rtc,\n detachSessionHandlers: () => this.cleanupSession(sessionId, session),\n enableMicrophoneRecovery: (confirmedSessionId) =>\n this.deps.micRecovery.enable(confirmedSessionId),\n iceCandidateReadyDelayMs: this.deps.getIceCandidateReadyDelayMs(),\n sessionId,\n });\n }\n\n private resolveSessionId(sessionId?: string) {\n if (sessionId) return sessionId;\n const state = this.deps.state.getState();\n const activeId = state.sessionIds.find(\n (id) => state.sessionsById[id]?.status === CallStatus.Active\n );\n return activeId ?? state.sessionIds[0] ?? null;\n }\n\n private sessionExists(sessionId: string) {\n return (\n !!this.deps.sessionManager.getSession(sessionId) ||\n !!this.deps.sessionManager.getRtc(sessionId)\n );\n }\n\n private resolveExistingSessionId(sessionId?: string) {\n const id = this.resolveSessionId(sessionId);\n if (!id) return null;\n return this.sessionExists(id) ? id : null;\n }\n}\n","import { UAEventMap } from \"../../sip/types\";\nimport { SipStatus } from \"../../contracts/state\";\nimport { SipStateStore } from \"../state/sip.state.store\";\nimport { JsSIPEventMap } from \"../../sip/types\";\nimport { EventTargetEmitter } from \"../event/event-target.emitter\";\nimport {\n IncomingMessageEvent,\n IncomingOptionsEvent,\n OutgoingMessageEvent,\n OutgoingOptionsEvent,\n} from \"jssip/src/UA\";\n\ntype Deps = {\n emitter: EventTargetEmitter<JsSIPEventMap>;\n state: SipStateStore;\n cleanupAllSessions: () => void;\n onNewRTCSession: UAEventMap[\"newRTCSession\"];\n};\n\nexport function createUAHandlers(deps: Deps): Partial<UAEventMap> {\n const { emitter, state, cleanupAllSessions, onNewRTCSession } = deps;\n\n return {\n connecting: (e) => {\n emitter.emit(\"connecting\", e);\n state.batchSet({ sipStatus: SipStatus.Connecting });\n },\n connected: (e) => {\n emitter.emit(\"connected\", e);\n state.batchSet({ sipStatus: SipStatus.Connected });\n },\n disconnected: (e) => {\n emitter.emit(\"disconnected\", e);\n cleanupAllSessions();\n state.reset();\n },\n\n registered: (e) => {\n emitter.emit(\"registered\", e);\n state.batchSet({ sipStatus: SipStatus.Registered, error: null });\n },\n unregistered: (e) => {\n emitter.emit(\"unregistered\", e);\n state.batchSet({ sipStatus: SipStatus.Unregistered });\n },\n registrationFailed: (e) => {\n emitter.emit(\"registrationFailed\", e);\n cleanupAllSessions();\n state.batchSet({\n sipStatus: SipStatus.RegistrationFailed,\n error: e?.cause || \"registration failed\",\n });\n },\n newRTCSession: onNewRTCSession,\n newMessage: (e: IncomingMessageEvent | OutgoingMessageEvent) =>\n emitter.emit(\"newMessage\", e),\n sipEvent: (e: any) => emitter.emit(\"sipEvent\", e),\n newOptions: (e: IncomingOptionsEvent | OutgoingOptionsEvent) =>\n emitter.emit(\"newOptions\", e),\n };\n}\n","import type { SipUserAgent } from \"../../sip/user-agent\";\nimport type { SipConfiguration, UAEventMap } from \"../../sip/types\";\nimport { createUAHandlers } from \"./ua.handlers\";\n\ntype UaModuleDeps = {\n userAgent: SipUserAgent;\n createHandlers: () => Partial<UAEventMap>;\n};\n\nexport class UaModule {\n private readonly userAgent: SipUserAgent;\n private readonly uaHandlers: Partial<UAEventMap>;\n private readonly uaHandlerKeys: (keyof UAEventMap)[];\n\n constructor(deps: UaModuleDeps) {\n this.userAgent = deps.userAgent;\n this.uaHandlers = deps.createHandlers();\n this.uaHandlerKeys = Object.keys(this.uaHandlers) as (keyof UAEventMap)[];\n }\n\n start(\n uri: string,\n password: string,\n config: Omit<SipConfiguration, \"debug\">,\n debug?: boolean | string\n ) {\n this.userAgent.start(uri, password, config, { debug });\n this.attachHandlers();\n }\n\n stop() {\n this.detachHandlers();\n this.userAgent.stop();\n }\n\n register() {\n this.userAgent.register();\n }\n\n setDebug(debug?: boolean | string) {\n this.userAgent.setDebug(debug);\n }\n\n private attachHandlers() {\n const ua = this.userAgent.ua;\n if (!ua) return;\n\n this.detachHandlers();\n this.uaHandlerKeys.forEach((event) => {\n const handler = this.uaHandlers[event];\n if (handler) ua.on(event, handler as any);\n });\n }\n\n private detachHandlers() {\n const ua = this.userAgent.ua;\n if (!ua) return;\n this.uaHandlerKeys.forEach((event) => {\n const handler = this.uaHandlers[event];\n if (handler) ua.off(event, handler as any);\n });\n }\n}\n\nexport function createUaHandlers(deps: Parameters<typeof createUAHandlers>[0]) {\n return createUAHandlers(deps);\n}\n\n","import { SipUserAgent } from \"../sip/user-agent\";\nimport {\n AnswerOptions,\n CallOptions,\n DTMFOptions,\n JsSIPEventMap,\n ReferOptions,\n RTCSession,\n RTCSessionEvent,\n SipConfiguration,\n TerminateOptions,\n} from \"../sip/types\";\nimport { SipState, SipStatus } from \"../contracts/state\";\nimport { EventTargetEmitter } from \"../modules/event/event-target.emitter\";\nimport { SipStateStore } from \"../modules/state/sip.state.store\";\nimport { SipDebugRuntime } from \"../modules/debug/sip-debug.runtime\";\nimport { createSipEventManager } from \"../modules/event/sip-event-manager.adapter\";\nimport { MicRecoveryManager } from \"../modules/media/mic-recovery.manager\";\nimport { BrowserUnloadRuntime } from \"../modules/runtime/browser-unload.runtime\";\nimport { SessionManager } from \"../modules/session/session.manager\";\nimport { SessionModule } from \"../modules/session/session.module\";\nimport { createUAHandlers } from \"../modules/ua/ua.handlers\";\nimport { UaModule } from \"../modules/ua/ua.module\";\n\nexport type SipClientOptions = {\n debug?: boolean | string;\n};\n\nexport class SipClient extends EventTargetEmitter<JsSIPEventMap> {\n public readonly userAgent = new SipUserAgent();\n public readonly stateStore = new SipStateStore();\n\n private readonly uaModule: UaModule;\n private debugPattern?: boolean | string;\n private maxSessionCount = Infinity;\n private iceCandidateReadyDelayMs?: number;\n private sessionManager = new SessionManager();\n private sessionModule: SessionModule;\n private micRecovery: MicRecoveryManager;\n private unloadRuntime = new BrowserUnloadRuntime();\n private debugRuntime: SipDebugRuntime;\n\n public get state(): SipState {\n return this.stateStore.getState();\n }\n\n constructor(options: SipClientOptions = {}) {\n super();\n this.debugPattern = options.debug;\n\n this.uaModule = new UaModule({\n userAgent: this.userAgent,\n createHandlers: () =>\n createUAHandlers({\n emitter: this,\n state: this.stateStore,\n cleanupAllSessions: () => this.cleanupAllSessions(),\n onNewRTCSession: (e: RTCSessionEvent) => this.onNewRTCSession(e),\n }),\n });\n\n this.micRecovery = new MicRecoveryManager({\n getRtc: (sessionId) => this.sessionManager.getRtc(sessionId),\n getSession: (sessionId) => this.sessionManager.getSession(sessionId),\n getSessionState: (sessionId) =>\n this.stateStore.getState().sessionsById[sessionId],\n setSessionMedia: (sessionId, stream) =>\n this.sessionManager.setSessionMedia(sessionId, stream),\n });\n\n this.sessionModule = new SessionModule({\n state: this.stateStore,\n emitter: this,\n sessionManager: this.sessionManager,\n micRecovery: this.micRecovery,\n getMaxSessionCount: () => this.maxSessionCount,\n getIceCandidateReadyDelayMs: () => this.iceCandidateReadyDelayMs,\n });\n\n this.debugRuntime = new SipDebugRuntime({\n getState: () => this.stateStore.getState(),\n onChange: (listener) => this.stateStore.onChange(listener),\n getSessions: () => this.getSessions(),\n setDebugEnabled: (enabled) => this.sessionModule.setDebugEnabled(enabled),\n });\n\n this.debugRuntime.attachBridge((debug?: boolean | string) =>\n this.setDebug(debug)\n );\n }\n\n public connect(uri: string, password: string, config: SipConfiguration) {\n this.disconnect();\n this.stateStore.setState({ sipStatus: SipStatus.Connecting });\n const {\n debug: cfgDebug,\n enableMicRecovery,\n micRecoveryIntervalMs,\n micRecoveryMaxRetries,\n maxSessionCount,\n iceCandidateReadyDelayMs,\n ...uaCfg\n } = config;\n this.maxSessionCount =\n typeof maxSessionCount === \"number\" ? maxSessionCount : Infinity;\n this.iceCandidateReadyDelayMs =\n typeof iceCandidateReadyDelayMs === \"number\"\n ? iceCandidateReadyDelayMs\n : undefined;\n this.micRecovery.configure({\n enabled: Boolean(enableMicRecovery),\n intervalMs: micRecoveryIntervalMs,\n maxRetries: micRecoveryMaxRetries,\n });\n const debug =\n cfgDebug ?? this.debugRuntime.getPersistedDebug() ?? this.debugPattern;\n this.uaModule.start(uri, password, uaCfg, debug);\n this.sessionModule.setDebugEnabled(Boolean(debug));\n this.unloadRuntime.attach(() => {\n this.hangupAll();\n this.disconnect();\n });\n this.debugRuntime.syncInspector(debug);\n }\n\n public registerUA() {\n this.uaModule.register();\n }\n\n public disconnect() {\n this.unloadRuntime.detach();\n this.uaModule.stop();\n this.cleanupAllSessions();\n this.stateStore.reset();\n this.debugRuntime.cleanup();\n }\n\n public call(target: string, callOptions: CallOptions = {}) {\n try {\n const ua = this.userAgent.getUA();\n const session = ua?.call(target, callOptions) as RTCSession | undefined;\n if (session && callOptions.mediaStream) {\n const sessionId = String((session as any)?.id ?? \"\");\n if (sessionId) {\n this.sessionModule.setSessionMedia(sessionId, callOptions.mediaStream);\n this.sessionModule.setSession(sessionId, session);\n }\n }\n } catch (e: unknown) {\n console.error(e);\n this.cleanupAllSessions();\n }\n }\n\n public hangupAll(options?: TerminateOptions) {\n const ids = this.getSessionIds();\n ids.forEach((id) => this.hangupSession(id, options));\n return ids.length > 0;\n }\n\n public onChange(fn: (s: SipState) => void) {\n return this.stateStore.onChange(fn);\n }\n\n public setDebug(debug?: boolean | string) {\n this.debugPattern = debug;\n this.uaModule.setDebug(debug);\n this.sessionModule.setDebugEnabled(Boolean(debug));\n const effectiveDebug =\n debug ?? this.debugRuntime.getPersistedDebug() ?? this.debugPattern;\n this.debugRuntime.syncInspector(effectiveDebug);\n }\n\n private cleanupAllSessions() {\n this.sessionModule.cleanupAllSessions();\n }\n\n protected onNewRTCSession(e: RTCSessionEvent) {\n this.sessionModule.handleNewRTCSession(e);\n }\n\n public answerSession(sessionId: string, options: AnswerOptions = {}) {\n if (options.mediaStream) {\n this.sessionModule.setSessionMedia(sessionId, options.mediaStream);\n }\n return this.sessionModule.answerSession(sessionId, options);\n }\n\n public hangupSession(sessionId: string, options?: TerminateOptions) {\n return this.sessionModule.hangupSession(sessionId, options);\n }\n\n public toggleMuteSession(sessionId?: string) {\n return this.sessionModule.toggleMuteSession(sessionId);\n }\n\n public toggleHoldSession(sessionId?: string) {\n return this.sessionModule.toggleHoldSession(sessionId);\n }\n\n public sendDTMFSession(\n sessionId: string,\n tones: string | number,\n options?: DTMFOptions,\n ) {\n return this.sessionModule.sendDTMFSession(sessionId, tones, options);\n }\n\n public transferSession(\n sessionId: string,\n target: string,\n options?: ReferOptions,\n ) {\n return this.sessionModule.transferSession(sessionId, target, options);\n }\n\n public setSessionMedia(sessionId: string, stream: MediaStream) {\n this.sessionModule.setSessionMedia(sessionId, stream);\n }\n\n public getSession(sessionId: string) {\n return this.sessionModule.getSession(sessionId);\n }\n\n public getSessionIds() {\n return this.sessionModule.getSessionIds();\n }\n\n public getSessions() {\n return this.sessionModule.getSessions();\n }\n}\n\nexport function createSipClientInstance(options?: SipClientOptions): SipClient {\n return new SipClient(options);\n}\n\nexport { createSipEventManager };\n","import type { SipEventManager } from \"../../sip/types\";\nimport type { SipClient } from \"../../client\";\nimport type { MediaModule } from \"./types\";\n\ntype CreateMediaModuleDeps = {\n client: SipClient;\n eventManager: SipEventManager;\n};\n\nexport function createMediaModule(deps: CreateMediaModuleDeps): MediaModule {\n const { client, eventManager } = deps;\n\n return {\n getSession(sessionId: string) {\n return client.getSession(sessionId);\n },\n\n observePeerConnection(sessionId, onPeerConnection) {\n const session = client.getSession(sessionId);\n if (!session) {\n onPeerConnection(null);\n return () => {};\n }\n\n const initialPc =\n (session as { connection?: RTCPeerConnection }).connection ?? null;\n onPeerConnection(initialPc);\n\n return eventManager.onSession(sessionId, \"peerconnection\", (payload) => {\n const pc =\n (payload as { peerconnection?: RTCPeerConnection })?.peerconnection ??\n null;\n onPeerConnection(pc);\n });\n },\n\n buildRemoteStream(peerConnection: RTCPeerConnection | null) {\n if (!peerConnection || typeof peerConnection.getReceivers !== \"function\") {\n return null;\n }\n\n const tracks = peerConnection\n .getReceivers()\n .map((receiver) => receiver.track)\n .filter((track): track is MediaStreamTrack => Boolean(track));\n\n if (tracks.length === 0) return null;\n return new MediaStream(tracks);\n },\n };\n}\n","import {\n createSipClientInstance,\n} from \"../client\";\nimport type {\n AnswerOptions,\n CallOptions,\n DTMFOptions,\n ReferOptions,\n SipConfiguration,\n TerminateOptions,\n} from \"../sip/types\";\nimport type { SipKernel } from \"./types\";\nimport { createMediaModule } from \"../modules/media/media.module\";\nimport { createSipEventManager } from \"../modules/event/sip-event-manager.adapter\";\n\nexport function createSipKernel(): SipKernel {\n const client = createSipClientInstance();\n const eventManager = createSipEventManager(client);\n const media = createMediaModule({ client, eventManager });\n\n return {\n client,\n store: {\n getState: () => client.state,\n subscribe: (onStoreChange) => client.onChange(onStoreChange),\n },\n commands: {\n connect: (uri: string, password: string, config: SipConfiguration) =>\n client.connect(uri, password, config),\n disconnect: () => client.disconnect(),\n register: () => client.registerUA(),\n setDebug: (debug?: boolean | string) => client.setDebug(debug),\n call: (target: string, options?: CallOptions) => client.call(target, options),\n answer: (sessionId: string, options?: AnswerOptions) =>\n client.answerSession(sessionId, options),\n hangup: (sessionId: string, options?: TerminateOptions) =>\n client.hangupSession(sessionId, options),\n hangupAll: (options?: TerminateOptions) => client.hangupAll(options),\n toggleMute: (sessionId?: string) => client.toggleMuteSession(sessionId),\n toggleHold: (sessionId?: string) => client.toggleHoldSession(sessionId),\n sendDTMF: (\n sessionId: string,\n tones: string | number,\n options?: DTMFOptions\n ) => client.sendDTMFSession(sessionId, tones, options),\n transfer: (sessionId: string, target: string, options?: ReferOptions) =>\n client.transferSession(sessionId, target, options),\n getSession: (sessionId: string) => client.getSession(sessionId),\n getSessionIds: () => client.getSessionIds(),\n getSessions: () => client.getSessions(),\n setSessionMedia: (sessionId: string, stream: MediaStream) =>\n client.setSessionMedia(sessionId, stream),\n },\n events: {\n onUA: (event, handler) => eventManager.onUA(event, handler as any),\n onSession: (sessionId, event, handler) =>\n eventManager.onSession(sessionId, event, handler as any),\n },\n eventManager,\n media,\n };\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { SipState } from \"../core/contracts/state\";\nimport { useSipKernel } from \"./useSip\";\n\nexport function useSipState(): SipState {\n const { store } = useSipKernel();\n return useSyncExternalStore(store.subscribe, store.getState, store.getState);\n}\n","import { useContext } from \"react\";\nimport { SipContext } from \"../context\";\n\nexport function useSipKernel() {\n const ctx = useContext(SipContext);\n if (!ctx) throw new Error(\"Must be used within SipProvider\");\n return ctx;\n}\n","import { createContext } from \"react\";\nimport type { SipKernel } from \"../core/kernel/types\";\n\nexport type SipContextType = SipKernel;\nexport const SipContext = createContext<SipContextType | null>(null);\n","import { useMemo } from \"react\";\nimport { useSipKernel } from \"./useSip\";\n\nexport function useSipActions() {\n const { commands } = useSipKernel();\n return useMemo(\n () => ({\n connect: commands.connect,\n disconnect: commands.disconnect,\n register: commands.register,\n setDebug: commands.setDebug,\n call: commands.call,\n answer: commands.answer,\n hangup: commands.hangup,\n hangupAll: commands.hangupAll,\n toggleMute: commands.toggleMute,\n toggleHold: commands.toggleHold,\n sendDTMF: commands.sendDTMF,\n transfer: commands.transfer,\n getSession: commands.getSession,\n getSessionIds: commands.getSessionIds,\n getSessions: commands.getSessions,\n setSessionMedia: commands.setSessionMedia,\n }),\n [commands]\n );\n}\n","import { useRef, useSyncExternalStore } from \"react\";\nimport type { SipState } from \"../core/contracts/state\";\nimport { useSipKernel } from \"./useSip\";\n\nexport type SipSelector<TSelected> = (state: SipState) => TSelected;\nexport type SipSelectorEqualityFn<TSelected> = (\n prev: TSelected,\n next: TSelected\n) => boolean;\n\nexport function useSipSelector<TSelected>(\n selector: SipSelector<TSelected>,\n equalityFn: SipSelectorEqualityFn<TSelected> = Object.is\n): TSelected {\n const { store } = useSipKernel();\n const selectorRef = useRef(selector);\n const equalityFnRef = useRef(equalityFn);\n const selectedRef = useRef<TSelected | undefined>(undefined);\n const hasSelectedRef = useRef(false);\n\n selectorRef.current = selector;\n equalityFnRef.current = equalityFn;\n\n const getSelection = () => {\n const nextSelected = selectorRef.current(store.getState());\n if (\n hasSelectedRef.current &&\n equalityFnRef.current(selectedRef.current as TSelected, nextSelected)\n ) {\n return selectedRef.current as TSelected;\n }\n hasSelectedRef.current = true;\n selectedRef.current = nextSelected;\n return nextSelected;\n };\n\n return useSyncExternalStore(store.subscribe, getSelection, getSelection);\n}\n","import type { SipSessionState } from \"../core/contracts/state\";\nimport { useSipSelector } from \"./useSipSelector\";\nimport { CallStatus } from \"../core/contracts/state\";\n\nexport function useActiveSipSession(): SipSessionState | null {\n return useSipSelector((state) => {\n const activeId = state.sessionIds.find(\n (id) => state.sessionsById[id]?.status === CallStatus.Active\n );\n return activeId ? state.sessionsById[activeId] : null;\n });\n}\n","import type { SipSessionState } from \"../core/contracts/state\";\nimport { useSipSelector } from \"./useSipSelector\";\n\nexport function useSipSession(sessionId?: string): SipSessionState | null {\n return useSipSelector((state) => {\n if (!sessionId) return null;\n return state.sessionsById[sessionId] ?? null;\n });\n}\n","import { useMemo } from \"react\";\nimport type { SipState } from \"../core/contracts/state\";\nimport { useSipSelector } from \"./useSipSelector\";\n\nexport function useSipSessions(): Pick<SipState, \"sessions\"> {\n const sessions = useSipSelector((state) => state.sessions);\n return useMemo(() => ({ sessions }), [sessions]);\n}\n","import { useEffect } from \"react\";\nimport type {\n SessionEventName,\n SessionEventPayload,\n UAEventName,\n UAEventPayload,\n} from \"../core/sip/types\";\nimport { useSipKernel } from \"./useSip\";\n\nexport function useSipEvent<K extends UAEventName>(\n event: K,\n handler?: (payload?: UAEventPayload<K>) => void\n) {\n const { events } = useSipKernel();\n\n useEffect(() => {\n if (!handler) return;\n return events.onUA(event, handler);\n }, [event, handler, events]);\n}\n\nexport function useSipSessionEvent<K extends SessionEventName>(\n sessionId: string,\n event: K,\n handler?: (payload?: SessionEventPayload<K>) => void\n) {\n const { events } = useSipKernel();\n\n useEffect(() => {\n if (!handler) return;\n return events.onSession(sessionId, event, handler);\n }, [event, handler, sessionId, events]);\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useSipKernel } from \"./useSip\";\nimport { useSipSelector } from \"./useSipSelector\";\nimport type { SessionMediaState } from \"../core/modules/media/types\";\nimport { CallStatus } from \"../core/contracts/state\";\n\nexport function useSessionMedia(sessionId?: string): SessionMediaState {\n const { media } = useSipKernel();\n const { sessionIds, sessionsById } = useSipSelector(\n (state) => ({\n sessionIds: state.sessionIds,\n sessionsById: state.sessionsById,\n }),\n (prev, next) =>\n prev.sessionIds === next.sessionIds && prev.sessionsById === next.sessionsById\n );\n const [peerConnection, setPeerConnection] = useState<RTCPeerConnection | null>(\n null\n );\n const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);\n\n const resolvedSessionId = useMemo(() => {\n if (sessionId) return sessionId;\n const activeId = sessionIds.find(\n (id) => sessionsById[id]?.status === CallStatus.Active\n );\n return activeId ?? sessionIds[0];\n }, [sessionId, sessionIds, sessionsById]);\n\n const session = useMemo(\n () => (resolvedSessionId ? media.getSession(resolvedSessionId) : null),\n [media, resolvedSessionId]\n );\n const sessionState = useMemo(() => {\n if (!resolvedSessionId) return null;\n return sessionsById[resolvedSessionId] ?? null;\n }, [sessionsById, resolvedSessionId]);\n\n useEffect(() => {\n if (!resolvedSessionId) {\n setPeerConnection(null);\n setRemoteStream(null);\n return;\n }\n\n const off = media.observePeerConnection(resolvedSessionId, (pc) => {\n setPeerConnection(pc);\n setRemoteStream(media.buildRemoteStream(pc));\n });\n return off;\n }, [media, resolvedSessionId]);\n\n useEffect(() => {\n if (!peerConnection) {\n setRemoteStream(null);\n return;\n }\n\n const update = () => {\n setRemoteStream(media.buildRemoteStream(peerConnection));\n };\n\n peerConnection.addEventListener(\"track\", update);\n peerConnection.addEventListener(\"connectionstatechange\", update);\n peerConnection.addEventListener(\"iceconnectionstatechange\", update);\n update();\n\n return () => {\n peerConnection.removeEventListener(\"track\", update);\n peerConnection.removeEventListener(\"connectionstatechange\", update);\n peerConnection.removeEventListener(\"iceconnectionstatechange\", update);\n };\n }, [media, peerConnection]);\n\n const tracks = remoteStream?.getTracks() ?? [];\n const audioTracks = tracks.filter((track) => track.kind === \"audio\");\n\n if (!sessionState) {\n return {\n sessionId: resolvedSessionId ?? \"\",\n session,\n peerConnection,\n remoteStream,\n audioTracks,\n };\n }\n\n return {\n sessionId: sessionState.id,\n session,\n peerConnection,\n remoteStream,\n audioTracks,\n };\n}\n","import { useEffect, useRef } from \"react\";\nimport { useSessionMedia } from \"../hooks/useSessionMedia\";\n\nexport function CallPlayer({ sessionId }: { sessionId?: string }) {\n const { remoteStream } = useSessionMedia(sessionId);\n const audioRef = useRef<HTMLAudioElement | null>(null);\n\n useEffect(() => {\n if (!audioRef.current) return;\n audioRef.current.srcObject = remoteStream;\n audioRef.current.play?.().catch(() => {});\n return () => {\n if (audioRef.current) {\n audioRef.current.srcObject = null;\n }\n };\n }, [remoteStream]);\n\n return <audio ref={audioRef} autoPlay playsInline />;\n}\n","import React, { useMemo } from \"react\";\nimport { SipContext } from \"../context\";\nimport type { SipKernel } from \"../core/kernel\";\n\nexport type SipProviderProps = {\n kernel: SipKernel;\n children: React.ReactNode;\n};\n\nexport function SipProvider(props: SipProviderProps) {\n const contextValue = useMemo(() => props.kernel, [props.kernel]);\n\n return (\n <SipContext.Provider value={contextValue}>\n {props.children}\n </SipContext.Provider>\n );\n}\n"]}
1
+ {"version":3,"sources":["../src/core/modules/debug/sip-debugger.ts","../src/core/contracts/state.ts","../src/index.ts","../src/core/sip/user-agent.ts","../src/core/modules/event/event-target.emitter.ts","../src/core/modules/state/sip.state.ts","../src/core/modules/state/sip.state.store.ts","../src/core/modules/debug/sip-debug.runtime.ts","../src/core/modules/event/sip-event-manager.adapter.ts","../src/core/modules/debug/sip-debug.logger.ts","../src/core/modules/media/mic-recovery.manager.ts","../src/core/modules/runtime/browser-unload.runtime.ts","../src/core/modules/media/webrtc-session.controller.ts","../src/core/modules/session/session.manager.ts","../src/core/modules/session/session.state.projector.ts","../src/core/modules/session/session.handlers.ts","../src/core/modules/session/session.lifecycle.ts","../src/core/modules/session/session.module.ts","../src/core/modules/ua/ua.handlers.ts","../src/core/modules/ua/ua.module.ts","../src/core/client/sip.client.ts","../src/core/modules/media/media.module.ts","../src/core/kernel/createSipKernel.ts","../src/hooks/useSipState.ts","../src/hooks/useSip.ts","../src/context/index.tsx","../src/hooks/useSipActions.ts","../src/hooks/useSipSelector.ts","../src/hooks/useSipSession.ts","../src/hooks/useSipSessions.ts","../src/hooks/useSipEvent.ts","../src/hooks/useSessionMedia.ts","../src/components/call-player.tsx","../src/provider/index.tsx"],"names":["JsSIP","session","pc","useSyncExternalStore","useMemo","useEffect","useRef","jsx"],"mappings":"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","sourcesContent":["import JsSIP from \"jssip\";\n\ntype StorageLike = Pick<Storage, \"getItem\" | \"setItem\" | \"removeItem\">;\n\nexport interface SipDebugToggleResult {\n debug: boolean;\n text: string;\n}\n\nexport class SipDebugger {\n private readonly storageKey: string;\n private readonly defaultPattern: string;\n private enabled = false;\n\n constructor(storageKey = \"sip-debug-enabled\", defaultPattern = \"JsSIP:*\") {\n this.storageKey = storageKey;\n this.defaultPattern = defaultPattern;\n }\n\n initFromSession(storage: StorageLike | null = safeSessionStorage()): void {\n try {\n const saved = storage?.getItem(this.storageKey);\n if (saved) this.enable(saved, storage);\n } catch {\n /* ignore */\n }\n }\n\n enable(\n pattern: string = this.defaultPattern,\n storage: StorageLike | null = safeSessionStorage()\n ): void {\n try {\n if (typeof JsSIP?.debug?.enable === \"function\") {\n JsSIP.debug.enable(pattern);\n }\n storage?.setItem?.(this.storageKey, pattern || this.defaultPattern);\n try {\n (window as any).sipDebugBridge?.(pattern);\n } catch {\n /* ignore */\n }\n this.enabled = true;\n } catch {\n /* ignore */\n }\n }\n\n disable(storage: StorageLike | null = safeSessionStorage()): void {\n try {\n if (typeof JsSIP?.debug?.disable === \"function\") {\n JsSIP.debug.disable();\n } else if (typeof JsSIP?.debug?.enable === \"function\") {\n JsSIP.debug.enable(\"\");\n }\n storage?.removeItem?.(this.storageKey);\n try {\n (window as any).sipDebugBridge?.(false);\n } catch {\n /* ignore */\n }\n this.enabled = false;\n } catch {\n /* ignore */\n }\n }\n\n toggle(\n pattern: string = this.defaultPattern,\n storage: StorageLike | null = safeSessionStorage()\n ): void {\n if (this.isEnabled()) {\n this.disable(storage);\n } else {\n this.enable(pattern, storage);\n }\n }\n\n isEnabled(): boolean {\n return this.enabled;\n }\n\n attachToWindow(win: Window & typeof globalThis = window): void {\n const api = {\n enableDebug: (): SipDebugToggleResult => {\n this.enable();\n return { debug: this.isEnabled(), text: \"press F5\" };\n },\n disableDebug: (): SipDebugToggleResult => {\n this.disable();\n return { debug: this.isEnabled(), text: \"press F5\" };\n },\n toggleDebug: (): SipDebugToggleResult => {\n this.toggle();\n return { debug: this.isEnabled(), text: \"press F5\" };\n },\n debugState: (): SipDebugToggleResult => ({\n debug: this.isEnabled(),\n text: this.isEnabled() ? \"enabled\" : \"disabled\",\n }),\n sipState: () => {\n try {\n const getter = (win as any).sipState;\n return typeof getter === \"function\"\n ? getter()\n : \"sipState helper not available; ensure client debug is enabled\";\n } catch {\n return \"sipState helper not available\";\n }\n },\n sipSessions: () => {\n try {\n const getter = (win as any).sipSessions;\n return typeof getter === \"function\"\n ? getter()\n : \"sipSessions helper not available; ensure client debug is enabled\";\n } catch {\n return \"sipSessions helper not available\";\n }\n },\n };\n\n try {\n (win as any).sipSupport = api;\n } catch {\n /* ignore */\n }\n }\n}\n\nfunction safeSessionStorage(): StorageLike | null {\n if (typeof window === \"undefined\") return null;\n try {\n return window.sessionStorage;\n } catch {\n return null;\n }\n}\n\nexport const sipDebugger = new SipDebugger();\nif (typeof window !== \"undefined\") {\n sipDebugger.attachToWindow();\n sipDebugger.initFromSession();\n}\n","export const SipStatus = {\n Disconnected: \"disconnected\",\n Connecting: \"connecting\",\n Connected: \"connected\",\n Registered: \"registered\",\n Unregistered: \"unregistered\",\n RegistrationFailed: \"registrationFailed\",\n} as const;\n\nexport type SipStatus = (typeof SipStatus)[keyof typeof SipStatus];\n\nexport const CallStatus = {\n Idle: \"idle\",\n Dialing: \"dialing\",\n Ringing: \"ringing\",\n Active: \"active\",\n Hold: \"hold\",\n} as const;\nexport type CallStatus = (typeof CallStatus)[keyof typeof CallStatus];\n\nexport type CallDirection = \"local\" | \"remote\";\n\nexport type SipSessionState = {\n id: string;\n status: CallStatus;\n direction: CallDirection | null;\n from: string | null;\n to: string | null;\n muted: boolean;\n acceptedAt: number | null;\n};\n\nexport interface SipState {\n sipStatus: SipStatus;\n error: string | null;\n sessions: SipSessionState[];\n}\n\nexport interface InternalSipState extends SipState {\n sessionsById: Record<string, SipSessionState>;\n sessionIds: string[];\n}\n\nexport const SipStatusList = Object.values(SipStatus);\nexport const CallStatusList = Object.values(CallStatus);\n\nexport function isSipStatus(v: unknown): v is SipStatus {\n return (\n typeof v === \"string\" && (SipStatusList as readonly string[]).includes(v)\n );\n}\nexport function isCallStatus(v: unknown): v is CallStatus {\n return (\n typeof v === \"string\" && (CallStatusList as readonly string[]).includes(v)\n );\n}\n\nexport type Unsubscribe = () => void;\nexport type Listener<T> = (value: T) => void;\n","import \"./core/modules/debug/sip-debugger\";\nimport { SipStatus, CallStatus, CallDirection } from \"./core/contracts/state\";\nimport { WebSocketInterface } from \"jssip\";\nimport { createSipClientInstance, createSipEventManager } from \"./core/client\";\nimport { createSipKernel } from \"./core/kernel\";\n\nexport { useSipState } from \"./hooks/useSipState\";\nexport { useSipActions } from \"./hooks/useSipActions\";\nexport { useSipKernel } from \"./hooks/useSip\";\nexport { useSipSelector } from \"./hooks/useSipSelector\";\nexport { useSipSession } from \"./hooks/useSipSession\";\nexport { useSipSessions } from \"./hooks/useSipSessions\";\nexport { useSipEvent, useSipSessionEvent } from \"./hooks/useSipEvent\";\nexport { useSessionMedia } from \"./hooks/useSessionMedia\";\nexport { CallPlayer } from \"./components/call-player\";\n\nexport { SipProvider } from \"./provider\";\nexport type { SipProviderProps } from \"./provider\";\n\nexport {\n CallStatus,\n CallDirection,\n createSipClientInstance,\n createSipKernel,\n createSipEventManager,\n WebSocketInterface,\n SipStatus,\n};\n\nimport type {\n SipState,\n SipSessionState,\n SipStatus as SipStatusType,\n CallDirection as CallDirectionType,\n CallStatus as CallStatusType,\n CallOptions,\n AnswerOptions,\n DTMFOptions,\n ExtraHeaders,\n ReferOptions,\n RenegotiateOptions,\n SendMessageOptions,\n JsSIPEventMap,\n JsSIPEventName,\n SessionEventName,\n SessionEventPayload,\n UAEventName,\n UAEventPayload,\n SipEventHandlers,\n SipEventManager,\n SipSendOptionsOptions,\n RTCSession,\n TerminateOptions,\n RTCSessionEventMap,\n SipConfiguration,\n SipKernel,\n} from \"./core/public-types\";\n\nexport type {\n SipState,\n SipSessionState,\n SipStatusType,\n CallDirectionType,\n CallStatusType,\n CallOptions,\n AnswerOptions,\n DTMFOptions,\n ExtraHeaders,\n ReferOptions,\n RenegotiateOptions,\n SendMessageOptions,\n JsSIPEventMap,\n JsSIPEventName,\n SessionEventName,\n SessionEventPayload,\n UAEventName,\n UAEventPayload,\n SipEventHandlers,\n SipEventManager,\n SipSendOptionsOptions,\n RTCSession,\n TerminateOptions,\n RTCSessionEventMap,\n SipConfiguration,\n SipKernel,\n};\n","import type { UA } from \"jssip\";\nimport JsSIP from \"jssip\";\nimport type { SipConfiguration, UAConfiguration } from \"./types\";\n\ntype StartOpts = { debug?: boolean | string };\n\nexport class SipUserAgent {\n private _ua: UA | null = null;\n\n public get ua(): UA | null {\n return this._ua;\n }\n public get isStarted(): boolean {\n return !!this._ua;\n }\n public get isRegistered(): boolean {\n return !!this._ua?.isRegistered();\n }\n\n public start(\n uri: string,\n password: string,\n config: Omit<SipConfiguration, \"debug\">,\n opts?: StartOpts\n ): UA {\n this.stop();\n const uaCfg = this.buildUAConfig(config, uri, password);\n this.ensureValid(uaCfg);\n this.applyDebug(opts?.debug);\n const ua = this.createUA(uaCfg);\n ua.start();\n this._ua = ua;\n return ua;\n }\n\n public register(): void {\n const ua = this.getUA();\n if (!ua?.isRegistered()) ua?.register();\n }\n\n public stop(): void {\n const ua = this._ua;\n if (!ua) return;\n try {\n if (ua.isRegistered()) ua.unregister();\n ua.stop();\n } finally {\n this._ua = null;\n }\n }\n\n public getUA(): UA | null {\n return this._ua;\n }\n\n public setDebug(debug?: boolean | string): void {\n this.applyDebug(debug);\n }\n\n protected buildUAConfig(\n config: Omit<SipConfiguration, \"debug\">,\n uri: string,\n password: string\n ): UAConfiguration {\n return { ...(config as UAConfiguration), uri, password };\n }\n\n protected ensureValid(cfg: UAConfiguration): void {\n const sockets = cfg.sockets as UAConfiguration[\"sockets\"];\n if (\n !cfg.uri ||\n !cfg.password ||\n !sockets ||\n (Array.isArray(sockets) && sockets.length === 0)\n ) {\n throw new Error(\n \"Invalid SIP connect args: require uri, password, and at least one socket\"\n );\n }\n }\n\n protected applyDebug(debug?: boolean | string): void {\n const stored = debug === undefined ? this.readSessionFlag() : debug;\n const enabled = !!stored;\n const pattern = typeof stored === \"string\" ? stored : \"JsSIP:*\";\n\n if (enabled) {\n JsSIP.debug.enable(pattern);\n const dbg: any = (JsSIP as any).debug;\n if (dbg?.setLogger) dbg.setLogger(console);\n else if (dbg) dbg.logger = console;\n this.persistSessionFlag(typeof stored === \"string\" ? stored : undefined);\n } else {\n (JsSIP.debug as any)?.disable?.();\n this.clearSessionFlag();\n }\n }\n\n protected createUA(cfg: UAConfiguration): UA {\n return new JsSIP.UA(cfg);\n }\n\n private readSessionFlag(): string | false {\n try {\n if (typeof window === \"undefined\") return false;\n const value = window.sessionStorage.getItem(\"sip-debug-enabled\");\n if (!value) return false;\n return value;\n } catch {\n return false;\n }\n }\n\n private persistSessionFlag(pattern?: string): void {\n try {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.setItem(\n \"sip-debug-enabled\",\n pattern || \"JsSIP:*\"\n );\n }\n } catch {\n /* ignore */\n }\n }\n\n private clearSessionFlag(): void {\n try {\n if (typeof window !== \"undefined\") {\n window.sessionStorage.removeItem(\"sip-debug-enabled\");\n }\n } catch {\n /* ignore */\n }\n }\n}\n","export type Listener<T = unknown> = (payload: T) => void;\n\nexport class EventTargetEmitter<\n Events extends Record<string, unknown> = Record<string, unknown>,\n> {\n private target = new EventTarget();\n\n on<K extends keyof Events>(event: K, fn: Listener<Events[K]>): () => void {\n const wrapper = (e: Event) => fn((e as CustomEvent<Events[K]>).detail);\n this.target.addEventListener(event as string, wrapper);\n return () => this.target.removeEventListener(event as string, wrapper);\n }\n\n emit<K extends keyof Events>(event: K, payload?: Events[K]): void {\n this.target.dispatchEvent(\n new CustomEvent(event as string, { detail: payload })\n );\n }\n}\n","import type { InternalSipState} from \"../../contracts/state\";\nimport { SipStatus } from \"../../contracts/state\";\n\nexport function getInitialSipState(): InternalSipState {\n return {\n sipStatus: SipStatus.Disconnected,\n error: null,\n sessions: [],\n sessionsById: {},\n sessionIds: [],\n };\n}\n\nexport function shallowEqual(objA: any, objB: any): boolean {\n if (objA === objB) return true;\n if (!objA || !objB) return false;\n const keysA = Object.keys(objA);\n const keysB = Object.keys(objB);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (objA[key] !== objB[key]) return false;\n }\n return true;\n}\n","import type { InternalSipState, SipState } from \"../../contracts/state\";\nimport { getInitialSipState, shallowEqual } from \"./sip.state\";\n\nexport type SipStateListener = (state: InternalSipState) => void;\nexport type PublicSipStateListener = (state: SipState) => void;\n\nexport class SipStateStore {\n private state: InternalSipState = getInitialSipState();\n private lastState: InternalSipState = getInitialSipState();\n private publicState: SipState = {\n sipStatus: this.state.sipStatus,\n error: this.state.error,\n sessions: this.state.sessions,\n };\n private listeners = new Set<SipStateListener>();\n private publicListeners = new Set<PublicSipStateListener>();\n private pendingState: Partial<InternalSipState> | null = null;\n private updateScheduled = false;\n\n getState(): InternalSipState {\n return this.state;\n }\n\n getPublicState(): SipState {\n return this.publicState;\n }\n\n onChange(fn: SipStateListener): () => void {\n this.listeners.add(fn);\n fn(this.state);\n return () => this.listeners.delete(fn);\n }\n\n onPublicChange(fn: PublicSipStateListener): () => void {\n this.publicListeners.add(fn);\n return () => this.publicListeners.delete(fn);\n }\n\n subscribe(fn: PublicSipStateListener): () => void {\n return this.onPublicChange(fn);\n }\n\n subscribeInternal(fn: SipStateListener): () => void {\n return this.onChange(fn);\n }\n\n setState(partial: Partial<InternalSipState>) {\n if (!partial || Object.keys(partial).length === 0) return;\n const next = { ...this.state, ...partial };\n if (\n next.sessions === this.lastState.sessions &&\n shallowEqual(this.lastState, next)\n ) {\n return;\n }\n this.state = next;\n this.lastState = next;\n this.publicState = {\n sipStatus: next.sipStatus,\n error: next.error,\n sessions: next.sessions,\n };\n this.emit();\n }\n\n batchSet(partial: Partial<InternalSipState>) {\n this.pendingState = { ...this.pendingState, ...partial };\n if (!this.updateScheduled) {\n this.updateScheduled = true;\n queueMicrotask(() => {\n if (this.pendingState) this.setState(this.pendingState);\n this.pendingState = null;\n this.updateScheduled = false;\n });\n }\n }\n\n reset(overrides: Partial<InternalSipState> = {}) {\n this.setState({ ...getInitialSipState(), ...overrides });\n }\n\n private emit() {\n for (const fn of this.listeners) fn(this.state);\n for (const fn of this.publicListeners) fn(this.publicState);\n }\n}\n","import type { SipState } from \"../../contracts/state\";\n\nconst SESSION_DEBUG_KEY = \"sip-debug-enabled\";\n\ntype DebugRuntimeDeps = {\n getState: () => SipState;\n onChange: (listener: (state: SipState) => void) => () => void;\n getSessions: () => unknown;\n setDebugEnabled: (enabled: boolean) => void;\n};\n\nexport class SipDebugRuntime {\n private readonly deps: DebugRuntimeDeps;\n private stateLogOff?: () => void;\n\n constructor(deps: DebugRuntimeDeps) {\n this.deps = deps;\n }\n\n attachBridge(setDebug: (debug?: boolean | string) => void): void {\n if (typeof window === \"undefined\") return;\n (window as any).sipDebugBridge = (debug?: boolean | string) =>\n setDebug(debug ?? true);\n }\n\n getPersistedDebug(): boolean | string | undefined {\n if (typeof window === \"undefined\") return undefined;\n try {\n const persisted = window.sessionStorage.getItem(SESSION_DEBUG_KEY);\n if (!persisted) return undefined;\n return persisted;\n } catch {\n return undefined;\n }\n }\n\n syncInspector(effectiveDebug?: boolean | string): void {\n if (typeof window === \"undefined\") return;\n\n const enabled = Boolean(effectiveDebug);\n this.deps.setDebugEnabled(enabled);\n this.toggleStateLogger(enabled);\n\n const win = window as any;\n const disabledInspector = () => {\n console.warn(\"SIP debug inspector disabled; enable debug to inspect.\");\n return null;\n };\n\n win.sipState = () => (enabled ? this.deps.getState() : disabledInspector());\n win.sipSessions = () =>\n enabled ? this.deps.getSessions() : disabledInspector();\n }\n\n cleanup(): void {\n this.toggleStateLogger(false);\n }\n\n private toggleStateLogger(enabled: boolean): void {\n if (!enabled) {\n this.stateLogOff?.();\n this.stateLogOff = undefined;\n return;\n }\n if (this.stateLogOff) return;\n\n let prev = this.deps.getState();\n console.info(\"[sip][state]\", { initial: true }, prev);\n\n this.stateLogOff = this.deps.onChange((next) => {\n console.info(\"[sip][state]\", next);\n prev = next;\n });\n }\n}\n","import type { SipClient } from \"../../client\";\nimport type {\n RTCSession,\n RTCSessionEventMap,\n SessionEventName,\n SessionEventPayload,\n SipEventManager,\n} from \"../../sip/types\";\n\nfunction getSessionFromPayload(payload: unknown): RTCSession | null {\n return (payload as { session?: RTCSession } | undefined)?.session ?? null;\n}\n\nfunction getSessionId(session: RTCSession): string {\n return String(session.id ?? \"\");\n}\n\nexport function createSipEventManager(client: SipClient): SipEventManager {\n return {\n onUA(event, handler) {\n return client.on(event, handler);\n },\n onSession(sessionId, event, handler) {\n type SessionListener<K extends SessionEventName> = RTCSessionEventMap[K];\n const wrapped = ((payload: SessionEventPayload<typeof event>) => {\n handler(payload);\n }) as SessionListener<typeof event>;\n\n let attachedSession: RTCSession | null = null;\n\n const detach = () => {\n if (!attachedSession) return;\n attachedSession.off(event, wrapped);\n attachedSession = null;\n };\n\n const attach = (session: RTCSession | null) => {\n if (!session) return;\n const id = getSessionId(session);\n if (!id || id !== sessionId) return;\n if (attachedSession === session) return;\n\n detach();\n attachedSession = session;\n attachedSession.on(event, wrapped);\n };\n\n const offNewSession = client.on(\"newRTCSession\", (payload) => {\n attach(getSessionFromPayload(payload));\n });\n\n attach(client.getSession(sessionId) ?? null);\n\n const offDisconnected = client.on(\"disconnected\", () => {\n detach();\n });\n\n return () => {\n offNewSession();\n offDisconnected();\n detach();\n };\n },\n };\n}\n","type PcSnapshot = {\n connectionState?: RTCPeerConnectionState;\n signalingState?: RTCSignalingState;\n iceConnectionState?: RTCIceConnectionState;\n};\n\nconst describePc = (pc?: RTCPeerConnection | null): PcSnapshot => ({\n connectionState: pc?.connectionState,\n signalingState: pc?.signalingState,\n iceConnectionState: pc?.iceConnectionState,\n});\n\nexport class SipDebugLogger {\n private enabled = false;\n private statsStops = new Map<string, () => void>();\n\n setEnabled(enabled: boolean) {\n this.enabled = enabled;\n if (!enabled) {\n this.statsStops.forEach((stop) => stop());\n this.statsStops.clear();\n }\n }\n\n isEnabled() {\n return this.enabled;\n }\n\n logLocalAudioError(\n sessionId: string,\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>\n ) {\n if (!this.enabled) return;\n console.error(message, {\n sessionId,\n pc: describePc(pc),\n ...extra,\n });\n void this.logOutboundStats(sessionId, pc, message);\n }\n\n logRemoteAudioError(\n sessionId: string,\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>\n ) {\n if (!this.enabled) return;\n console.error(message, {\n sessionId,\n pc: describePc(pc),\n ...extra,\n });\n void this.logInboundStats(sessionId, pc, message);\n }\n\n logMicRecoveryDrop(payload: {\n sessionId?: string;\n trackLive?: boolean;\n senderLive?: boolean;\n }) {\n if (!this.enabled) return;\n console.error(\"[sip] microphone dropped\", payload);\n }\n\n logIceReady(sessionId: string, payload: Record<string, unknown>) {\n if (!this.enabled) return;\n console.info(\"[sip] ice ready\", { sessionId, ...payload });\n }\n\n logIceReadyConfig(sessionId: string, delayMs: number) {\n if (!this.enabled) return;\n console.info(\"[sip] ice ready config\", { sessionId, delayMs });\n }\n\n startCallStatsLogging(sessionId: string, session: any) {\n if (!this.enabled || this.statsStops.has(sessionId)) return;\n\n let pc: RTCPeerConnection | null =\n (session as { connection?: RTCPeerConnection })?.connection ?? null;\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\n pc = data.peerconnection;\n };\n session.on?.(\"peerconnection\", onPeer);\n\n const intervalMs = 3000;\n const logStats = async () => {\n if (!this.enabled || !pc?.getStats) return;\n try {\n const report = await pc.getStats();\n const { outboundAudio, inboundAudio } = collectAudioStats(report);\n console.info(\"[sip] call stats\", {\n sessionId,\n pc: describePc(pc),\n outboundAudio,\n inboundAudio,\n });\n } catch (err) {\n console.error(\"[sip] call stats failed\", { sessionId, error: err });\n }\n };\n\n const timer = setInterval(() => {\n void logStats();\n }, intervalMs);\n void logStats();\n\n const stop = () => {\n clearInterval(timer);\n session.off?.(\"peerconnection\", onPeer);\n this.statsStops.delete(sessionId);\n };\n this.statsStops.set(sessionId, stop);\n }\n\n stopCallStatsLogging(sessionId: string) {\n const stop = this.statsStops.get(sessionId);\n if (stop) stop();\n }\n\n private async logOutboundStats(\n sessionId: string,\n pc?: RTCPeerConnection | null,\n context?: string\n ) {\n if (!pc?.getStats) return;\n try {\n const report = await pc.getStats();\n const { outboundAudio } = collectAudioStats(report);\n if (outboundAudio.length) {\n console.info(\"[sip] outgoing audio stats\", {\n sessionId,\n context,\n outboundAudio,\n });\n }\n } catch (err) {\n console.error(\"[sip] outgoing audio stats failed\", {\n sessionId,\n context,\n error: err,\n });\n }\n }\n\n private async logInboundStats(\n sessionId: string,\n pc?: RTCPeerConnection | null,\n context?: string\n ) {\n if (!pc?.getStats) return;\n try {\n const report = await pc.getStats();\n const { inboundAudio } = collectAudioStats(report);\n if (inboundAudio.length) {\n console.error(\"[sip] incoming audio stats\", {\n sessionId,\n context,\n inboundAudio,\n });\n }\n } catch (err) {\n console.error(\"[sip] incoming audio stats failed\", {\n sessionId,\n context,\n error: err,\n });\n }\n }\n}\n\nexport const sipDebugLogger = new SipDebugLogger();\n\nfunction collectAudioStats(report: RTCStatsReport) {\n const outboundAudio: Array<Record<string, unknown>> = [];\n const inboundAudio: Array<Record<string, unknown>> = [];\n\n report.forEach((stat) => {\n const kind = (stat as any).kind ?? (stat as any).mediaType;\n if (stat.type === \"outbound-rtp\" && kind === \"audio\") {\n outboundAudio.push({\n id: stat.id,\n packetsSent: (stat as any).packetsSent,\n bytesSent: (stat as any).bytesSent,\n jitter: (stat as any).jitter,\n roundTripTime: (stat as any).roundTripTime,\n });\n }\n if (stat.type === \"inbound-rtp\" && kind === \"audio\") {\n inboundAudio.push({\n id: stat.id,\n packetsReceived: (stat as any).packetsReceived,\n packetsLost: (stat as any).packetsLost,\n bytesReceived: (stat as any).bytesReceived,\n jitter: (stat as any).jitter,\n roundTripTime: (stat as any).roundTripTime,\n });\n }\n });\n\n return { outboundAudio, inboundAudio };\n}\n","import type { RTCSession } from \"../../sip/types\";\nimport type { WebRTCSessionController } from \"./webrtc-session.controller\";\nimport { sipDebugLogger } from \"../debug/sip-debug.logger\";\n\nexport type MicrophoneRecoveryOptions = {\n intervalMs?: number;\n maxRetries?: number;\n};\n\ntype MicRecoveryDeps = {\n getRtc: (sessionId: string) => WebRTCSessionController | null;\n getSession: (sessionId: string) => RTCSession | null;\n getSessionState: (sessionId: string) => { muted?: boolean } | undefined;\n setSessionMedia: (sessionId: string, stream: MediaStream) => void;\n};\n\ntype MicRecoveryConfig = {\n enabled?: boolean;\n intervalMs?: number;\n maxRetries?: number;\n};\n\nexport class MicRecoveryManager {\n private enabled = false;\n private defaults: Required<MicrophoneRecoveryOptions> = {\n intervalMs: 2000,\n maxRetries: Infinity,\n };\n private active = new Map<string, { stop: () => void }>();\n private syncedSenderTrackId = new Map<string, string>();\n private readonly deps: MicRecoveryDeps;\n\n constructor(deps: MicRecoveryDeps) {\n this.deps = deps;\n }\n\n configure(config: MicRecoveryConfig) {\n if (typeof config.enabled === \"boolean\") {\n this.enabled = config.enabled;\n }\n if (typeof config.intervalMs === \"number\") {\n this.defaults.intervalMs = config.intervalMs;\n }\n if (typeof config.maxRetries === \"number\") {\n this.defaults.maxRetries = config.maxRetries;\n }\n }\n\n enable(\n sessionId: string,\n options: MicrophoneRecoveryOptions = {}\n ): () => void {\n if (!this.enabled) return () => {};\n\n this.disable(sessionId);\n\n const intervalMs = options.intervalMs ?? this.defaults.intervalMs;\n const maxRetries = options.maxRetries ?? this.defaults.maxRetries;\n let retries = 0;\n let stopped = false;\n const startedAt = Date.now();\n const warmupMs = Math.max(intervalMs * 2, 2000);\n\n const tick = async () => {\n if (stopped || retries >= maxRetries) return;\n\n const rtc = this.deps.getRtc(sessionId);\n const session = this.deps.getSession(sessionId);\n if (!rtc || !session) return;\n\n const sessionState = this.deps.getSessionState(sessionId);\n if (sessionState?.muted) return;\n\n const stream = rtc.mediaStream;\n const track = stream?.getAudioTracks?.()[0];\n const pc: RTCPeerConnection | undefined = (session as any)?.connection;\n const sender = pc\n ?.getSenders?.()\n ?.find((s: RTCRtpSender) => s.track?.kind === \"audio\");\n\n if (!track && !sender) return;\n if (!track && sender?.track?.readyState === \"live\") {\n const nextId = sender.track.id;\n const prevId = this.syncedSenderTrackId.get(sessionId);\n if (prevId === nextId) return;\n this.syncedSenderTrackId.set(sessionId, nextId);\n this.deps.setSessionMedia(sessionId, new MediaStream([sender.track]));\n return;\n }\n\n if (Date.now() - startedAt < warmupMs) return;\n if (\n pc?.connectionState === \"new\" ||\n pc?.connectionState === \"connecting\" ||\n pc?.iceConnectionState === \"new\" ||\n pc?.iceConnectionState === \"checking\"\n ) {\n return;\n }\n\n const trackLive = track?.readyState === \"live\";\n const senderLive = sender?.track?.readyState === \"live\";\n if (trackLive && senderLive) return;\n\n sipDebugLogger.logMicRecoveryDrop({\n sessionId,\n trackLive,\n senderLive,\n });\n\n retries += 1;\n if (trackLive && !senderLive && track) {\n await rtc.replaceAudioTrack(track);\n return;\n }\n\n // No internal getUserMedia request path in library.\n // If both track and sender are not live, recovery stops here.\n };\n\n const timer = setInterval(() => {\n void tick();\n }, intervalMs);\n void tick();\n\n const session = this.deps.getSession(sessionId);\n const pc: RTCPeerConnection | undefined = (session as any)?.connection;\n const onIceChange = () => {\n const state = pc?.iceConnectionState;\n if (state === \"failed\" || state === \"disconnected\") void tick();\n };\n pc?.addEventListener?.(\"iceconnectionstatechange\", onIceChange);\n\n const stop = () => {\n stopped = true;\n clearInterval(timer);\n pc?.removeEventListener?.(\"iceconnectionstatechange\", onIceChange);\n };\n this.active.set(sessionId, { stop });\n return stop;\n }\n\n disable(sessionId: string) {\n const entry = this.active.get(sessionId);\n if (!entry) return false;\n entry.stop();\n this.active.delete(sessionId);\n this.syncedSenderTrackId.delete(sessionId);\n return true;\n }\n\n cleanupAll() {\n this.active.forEach((entry) => entry.stop());\n this.active.clear();\n this.syncedSenderTrackId.clear();\n }\n}\n","export class BrowserUnloadRuntime {\n private handler?: () => void;\n\n attach(onBeforeUnload: () => void): void {\n if (typeof window === \"undefined\" || this.handler) return;\n this.handler = () => onBeforeUnload();\n window.addEventListener(\"beforeunload\", this.handler);\n }\n\n detach(): void {\n if (typeof window === \"undefined\" || !this.handler) return;\n window.removeEventListener(\"beforeunload\", this.handler);\n this.handler = undefined;\n }\n}\n","import type {\n AnswerOptions,\n DTMFOptions,\n ReferOptions,\n RTCSession,\n TerminateOptions,\n} from \"../../sip/types\";\n\nexport class WebRTCSessionController {\n currentSession: RTCSession | null = null;\n mediaStream: MediaStream | null = null;\n\n public setSession(session: RTCSession | null) {\n this.currentSession = session;\n }\n\n public setMediaStream(stream: MediaStream) {\n this.mediaStream = stream;\n }\n\n private getPC(): RTCPeerConnection | null {\n return (this.currentSession as any)?.connection ?? null;\n }\n\n public cleanup(stopTracks: boolean = true): void {\n const pc = this.getPC();\n const isClosed =\n pc?.connectionState === \"closed\" || pc?.signalingState === \"closed\";\n\n if (pc && typeof pc.getSenders === \"function\") {\n if (!isClosed) {\n for (const sender of pc.getSenders()) {\n try {\n sender.replaceTrack(null);\n } catch {\n // ignore if sender/pc already closed\n }\n }\n }\n }\n\n if (stopTracks && this.mediaStream) {\n const senderTracks =\n pc && !isClosed\n ? new Set(\n pc\n .getSenders()\n .map((sender) => sender.track)\n .filter((track): track is MediaStreamTrack => Boolean(track))\n )\n : null;\n for (const track of this.mediaStream.getTracks()) {\n if (senderTracks?.has(track)) continue;\n track.stop();\n }\n }\n\n this.mediaStream = null;\n this.currentSession = null;\n }\n\n public answer(options: AnswerOptions = {}): boolean {\n return this.currentSession\n ? (this.currentSession.answer(options), true)\n : false;\n }\n\n public hangup(options?: TerminateOptions): boolean {\n return this.currentSession\n ? (this.currentSession.terminate(\n options ?? ({ status_code: 486, reason_phrase: \"Busy Here\" } as any)\n ),\n true)\n : false;\n }\n\n public mute(): boolean {\n this.mediaStream\n ?.getAudioTracks()\n .forEach((track) => (track.enabled = false));\n return this.currentSession\n ? (this.currentSession.mute({ audio: true }), true)\n : false;\n }\n\n public unmute(): boolean {\n this.mediaStream\n ?.getAudioTracks()\n .forEach((track) => (track.enabled = true));\n return this.currentSession\n ? (this.currentSession.unmute({ audio: true }), true)\n : false;\n }\n\n public hold(): boolean {\n return this.currentSession ? (this.currentSession.hold(), true) : false;\n }\n\n public unhold(): boolean {\n return this.currentSession ? (this.currentSession.unhold(), true) : false;\n }\n\n public sendDTMF(tones: string | number, options?: DTMFOptions): boolean {\n return this.currentSession\n ? (this.currentSession.sendDTMF(tones, options), true)\n : false;\n }\n\n public transfer(target: string, options?: ReferOptions): boolean {\n return this.currentSession\n ? (this.currentSession.refer(target as any, options), true)\n : false;\n }\n\n public async replaceAudioTrack(\n nextAudioTrack: MediaStreamTrack\n ): Promise<boolean> {\n const pc = this.getPC();\n if (!pc) return false;\n\n if (!this.mediaStream) this.mediaStream = new MediaStream();\n\n const old = this.mediaStream.getAudioTracks()[0];\n this.mediaStream.addTrack(nextAudioTrack);\n if (old) this.mediaStream.removeTrack(old);\n\n const sender = pc\n .getSenders?.()\n .find((entry) => entry.track?.kind === \"audio\");\n if (sender) await sender.replaceTrack(nextAudioTrack);\n\n if (old && old !== nextAudioTrack) old.stop();\n\n return true;\n }\n}\n","import { WebRTCSessionController } from \"../media/webrtc-session.controller\";\nimport type {\n AnswerOptions,\n DTMFOptions,\n ReferOptions,\n RTCSession,\n TerminateOptions,\n} from \"../../sip/types\";\n\ntype SessionEntry = {\n rtc: WebRTCSessionController;\n session?: RTCSession | null;\n media?: MediaStream | null;\n};\n\nexport class SessionManager {\n private entries = new Map<string, SessionEntry>();\n\n private stopMediaStream(stream?: MediaStream | null) {\n if (!stream) return;\n for (const track of stream.getTracks()) {\n if (track.readyState !== \"ended\") track.stop();\n }\n }\n\n getOrCreateRtc(sessionId: string, session?: RTCSession) {\n let entry = this.entries.get(sessionId);\n if (!entry) {\n entry = {\n rtc: new WebRTCSessionController(),\n session: null,\n media: null,\n };\n this.entries.set(sessionId, entry);\n }\n if (session) {\n entry.session = session;\n entry.rtc.setSession(session);\n }\n if (entry.media) entry.rtc.setMediaStream(entry.media);\n return entry.rtc;\n }\n\n getRtc(sessionId: string) {\n return this.entries.get(sessionId)?.rtc ?? null;\n }\n\n setSession(sessionId: string, session: RTCSession) {\n const entry = this.entries.get(sessionId);\n if (entry) {\n entry.session = session;\n entry.rtc.setSession(session);\n } else {\n this.entries.set(sessionId, {\n rtc: new WebRTCSessionController(),\n session,\n media: null,\n });\n }\n }\n\n setSessionMedia(sessionId: string, stream: MediaStream) {\n const entry = this.entries.get(sessionId) ?? {\n rtc: new WebRTCSessionController(),\n session: null,\n media: null,\n };\n if (entry.media && entry.media !== stream) {\n this.stopMediaStream(entry.media);\n }\n entry.media = stream;\n entry.rtc.setMediaStream(stream);\n this.entries.set(sessionId, entry);\n }\n\n getSession(sessionId: string) {\n return this.entries.get(sessionId)?.session ?? null;\n }\n\n getSessionIds() {\n return Array.from(this.entries.keys());\n }\n\n getSessions() {\n return Array.from(this.entries.entries()).map(([id, entry]) => ({\n id,\n session: entry.session as RTCSession,\n }));\n }\n\n cleanupSession(sessionId: string) {\n const entry = this.entries.get(sessionId);\n if (entry) {\n entry.rtc.cleanup();\n this.stopMediaStream(entry.media);\n this.entries.delete(sessionId);\n }\n }\n\n cleanupAllSessions() {\n for (const [, entry] of this.entries.entries()) {\n entry.rtc.cleanup();\n this.stopMediaStream(entry.media);\n }\n this.entries.clear();\n }\n\n answer(sessionId: string, options: AnswerOptions) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.answer(options) : false;\n }\n\n hangup(sessionId: string, options?: TerminateOptions) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.hangup(options) : false;\n }\n\n mute(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.mute() : false;\n }\n\n unmute(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.unmute() : false;\n }\n\n hold(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.hold() : false;\n }\n\n unhold(sessionId: string) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.unhold() : false;\n }\n\n sendDTMF(sessionId: string, tones: string | number, options?: DTMFOptions) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.sendDTMF(tones, options) : false;\n }\n\n transfer(sessionId: string, target: string, options?: ReferOptions) {\n const rtc = this.getRtc(sessionId);\n return rtc ? rtc.transfer(target, options) : false;\n }\n}\n","import type { SipSessionState } from \"../../contracts/state\";\nimport { CallStatus } from \"../../contracts/state\";\nimport type { SipStateStore } from \"../state/sip.state.store\";\n\nexport function holdOtherSessions(\n state: SipStateStore,\n sessionId: string,\n holdFn: (id: string) => void\n) {\n const current = state.getState();\n current.sessionIds.forEach((id) => {\n if (id === sessionId) return;\n const session = current.sessionsById[id];\n if (session?.status === CallStatus.Active) {\n holdFn(id);\n }\n });\n}\n\nexport function upsertSessionState(\n state: SipStateStore,\n sessionId: string,\n partial: Partial<SipSessionState>\n) {\n const current = state.getState();\n const existing = current.sessionsById[sessionId];\n const base: SipSessionState = existing ?? {\n id: sessionId,\n status: CallStatus.Idle,\n direction: null,\n from: null,\n to: null,\n muted: false,\n acceptedAt: null,\n };\n\n const nextSession = { ...base, ...partial };\n const sessionsById = {\n ...current.sessionsById,\n [sessionId]: nextSession,\n };\n const sessionIds = existing\n ? current.sessionIds\n : [...current.sessionIds, sessionId];\n const sessions = existing\n ? current.sessions.map((session) =>\n session.id === sessionId ? nextSession : session\n )\n : [...current.sessions, nextSession];\n\n state.setState({ sessionsById, sessionIds, sessions });\n}\n\nexport function removeSessionState(state: SipStateStore, sessionId: string) {\n const current = state.getState();\n if (!current.sessionsById[sessionId]) return;\n const sessionsById = { ...current.sessionsById };\n delete sessionsById[sessionId];\n const sessionIds = current.sessionIds.filter((id) => id !== sessionId);\n const sessions = current.sessions.filter(\n (session) => session.id !== sessionId\n );\n\n state.setState({\n sessions,\n sessionsById,\n sessionIds,\n error: null,\n });\n}\n","import type { RTCSessionEventMap } from \"../../sip/types\";\nimport { CallStatus } from \"../../contracts/state\";\nimport type { SipStateStore } from \"../state/sip.state.store\";\nimport type { WebRTCSessionController } from \"../media/webrtc-session.controller\";\nimport type { JsSIPEventMap } from \"../../sip/types\";\nimport type { EventTargetEmitter } from \"../event/event-target.emitter\";\nimport {\n removeSessionState,\n upsertSessionState,\n} from \"./session.state.projector\";\nimport { sipDebugLogger } from \"../debug/sip-debug.logger\";\n\nimport type {\n IncomingAckEvent,\n IncomingDTMFEvent,\n IncomingEvent,\n IncomingInfoEvent,\n OutgoingAckEvent,\n OutgoingDTMFEvent,\n OutgoingEvent,\n OutgoingInfoEvent,\n PeerConnectionEvent,\n} from \"jssip/src/RTCSession\";\n\ntype Deps = {\n emitter: EventTargetEmitter<JsSIPEventMap>;\n state: SipStateStore;\n rtc: WebRTCSessionController;\n detachSessionHandlers: () => void;\n enableMicrophoneRecovery?: (sessionId: string) => void;\n iceCandidateReadyDelayMs?: number;\n sessionId: string;\n};\n\nexport function createSessionHandlers(deps: Deps): Partial<RTCSessionEventMap> {\n const {\n emitter,\n state,\n rtc,\n detachSessionHandlers,\n sessionId,\n iceCandidateReadyDelayMs,\n } = deps;\n let iceReadyCalled = false;\n let iceReadyTimer: ReturnType<typeof setTimeout> | null = null;\n const clearIceReadyTimer = () => {\n if (!iceReadyTimer) return;\n clearTimeout(iceReadyTimer);\n iceReadyTimer = null;\n };\n if (typeof iceCandidateReadyDelayMs === \"number\") {\n sipDebugLogger.logIceReadyConfig(sessionId, iceCandidateReadyDelayMs);\n }\n\n return {\n progress: (e: IncomingEvent | OutgoingEvent) => {\n emitter.emit(\"progress\", e);\n },\n accepted: (e: IncomingEvent | OutgoingEvent) => {\n emitter.emit(\"accepted\", e);\n const existing = state.getState().sessionsById[sessionId];\n upsertSessionState(state, sessionId, {\n status: CallStatus.Active,\n acceptedAt: existing?.acceptedAt ?? Date.now(),\n });\n },\n confirmed: (e: IncomingAckEvent | OutgoingAckEvent) => {\n emitter.emit(\"confirmed\", e);\n deps.enableMicrophoneRecovery?.(sessionId);\n },\n\n ended: (e) => {\n emitter.emit(\"ended\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n failed: (e) => {\n emitter.emit(\"failed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n\n muted: (e) => {\n emitter.emit(\"muted\", e);\n upsertSessionState(state, sessionId, { muted: true });\n },\n unmuted: (e) => {\n emitter.emit(\"unmuted\", e);\n upsertSessionState(state, sessionId, { muted: false });\n },\n hold: (e) => {\n emitter.emit(\"hold\", e);\n upsertSessionState(state, sessionId, { status: CallStatus.Hold });\n },\n unhold: (e) => {\n emitter.emit(\"unhold\", e);\n upsertSessionState(state, sessionId, { status: CallStatus.Active });\n },\n\n reinvite: (e) => emitter.emit(\"reinvite\", e),\n update: (e) => emitter.emit(\"update\", e),\n sdp: (e) => emitter.emit(\"sdp\", e),\n icecandidate: (e) => {\n const candidate = e?.candidate;\n const ready = typeof e?.ready === \"function\" ? e.ready : null;\n const delayMs =\n typeof iceCandidateReadyDelayMs === \"number\"\n ? iceCandidateReadyDelayMs\n : null;\n if (!iceReadyCalled && ready && delayMs != null) {\n if (\n candidate?.type === \"srflx\" &&\n candidate?.relatedAddress != null &&\n candidate?.relatedPort != null\n ) {\n iceReadyCalled = true;\n if (iceReadyTimer) {\n clearTimeout(iceReadyTimer);\n iceReadyTimer = null;\n }\n sipDebugLogger.logIceReady(sessionId, {\n source: \"srflx\",\n delayMs,\n candidateType: candidate?.type,\n });\n ready();\n } else if (!iceReadyTimer && delayMs > 0) {\n iceReadyTimer = setTimeout(() => {\n iceReadyTimer = null;\n if (iceReadyCalled) return;\n iceReadyCalled = true;\n sipDebugLogger.logIceReady(sessionId, {\n source: \"timer\",\n delayMs,\n candidateType: candidate?.type,\n });\n ready();\n }, delayMs);\n } else if (delayMs === 0) {\n iceReadyCalled = true;\n sipDebugLogger.logIceReady(sessionId, {\n source: \"immediate\",\n delayMs,\n candidateType: candidate?.type,\n });\n ready();\n }\n }\n emitter.emit(\"icecandidate\", e);\n },\n refer: (e) => emitter.emit(\"refer\", e),\n replaces: (e) => emitter.emit(\"replaces\", e),\n newDTMF: (e: IncomingDTMFEvent | OutgoingDTMFEvent) =>\n emitter.emit(\"newDTMF\", e),\n newInfo: (e: OutgoingInfoEvent | IncomingInfoEvent) =>\n emitter.emit(\"newInfo\", e),\n\n getusermediafailed: (e) => {\n emitter.emit(\"getusermediafailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:createofferfailed\": (e) => {\n emitter.emit(\"peerconnection:createofferfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:createanswerfailed\": (e) => {\n emitter.emit(\"peerconnection:createanswerfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:setlocaldescriptionfailed\": (e) => {\n emitter.emit(\"peerconnection:setlocaldescriptionfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n \"peerconnection:setremotedescriptionfailed\": (e) => {\n emitter.emit(\"peerconnection:setremotedescriptionfailed\", e);\n clearIceReadyTimer();\n detachSessionHandlers();\n rtc.cleanup();\n removeSessionState(state, sessionId);\n },\n peerconnection: (e: PeerConnectionEvent) =>\n emitter.emit(\"peerconnection\", e),\n };\n}\n","import type { SipStateStore } from \"../state/sip.state.store\";\nimport { CallStatus } from \"../../contracts/state\";\nimport type { SessionManager } from \"./session.manager\";\nimport {\n holdOtherSessions,\n upsertSessionState,\n} from \"./session.state.projector\";\nimport type {\n JsSIPEventName,\n JsSIPEventPayload,\n RTCSession,\n RTCSessionEvent,\n TerminateOptions,\n} from \"../../sip/types\";\nimport { sipDebugLogger } from \"../debug/sip-debug.logger\";\n\ntype Deps = {\n state: SipStateStore;\n sessionManager: SessionManager;\n emit: <K extends JsSIPEventName>(\n event: K,\n payload?: JsSIPEventPayload<K>\n ) => void;\n attachSessionHandlers: (sessionId: string, session: RTCSession) => void;\n getMaxSessionCount: () => number;\n};\n\nexport class SessionLifecycle {\n private readonly state: SipStateStore;\n private readonly sessionManager: SessionManager;\n private readonly emit: Deps[\"emit\"];\n private readonly attachSessionHandlers: Deps[\"attachSessionHandlers\"];\n private readonly getMaxSessionCount: Deps[\"getMaxSessionCount\"];\n\n constructor(deps: Deps) {\n this.state = deps.state;\n this.sessionManager = deps.sessionManager;\n this.emit = deps.emit;\n this.attachSessionHandlers = deps.attachSessionHandlers;\n this.getMaxSessionCount = deps.getMaxSessionCount;\n }\n\n public setDebugEnabled(enabled: boolean) {\n sipDebugLogger.setEnabled(enabled);\n }\n\n handleNewRTCSession(e: RTCSessionEvent) {\n const session = e.session;\n const sessionId = String(session.id ?? crypto.randomUUID?.() ?? Date.now());\n\n const currentSessions = this.state.getState().sessions;\n if (currentSessions.length >= this.getMaxSessionCount()) {\n try {\n const terminateOptions: TerminateOptions = {\n status_code: 486,\n reason_phrase: \"Busy Here\",\n };\n session.terminate(terminateOptions);\n } catch {\n /* ignore termination errors */\n }\n return;\n }\n\n const rtc = this.sessionManager.getOrCreateRtc(sessionId, session);\n this.sessionManager.setSession(sessionId, session);\n this.attachSessionHandlers(sessionId, session);\n this.attachCallStatsLogging(sessionId, session);\n\n if (e.originator === \"local\" && !rtc.mediaStream) {\n this.bindLocalOutgoingAudio(sessionId, session);\n }\n if (e.originator === \"remote\") {\n this.bindRemoteIncomingAudio(sessionId, session);\n }\n\n holdOtherSessions(this.state, sessionId, (id) => {\n const otherRtc = this.sessionManager.getRtc(id);\n otherRtc?.hold();\n });\n\n upsertSessionState(this.state, sessionId, {\n direction: e.originator,\n from: e.originator === \"remote\" ? e.request.from.uri.user : null,\n to: e.request.to.uri.user,\n status:\n e.originator === \"remote\" ? CallStatus.Ringing : CallStatus.Dialing,\n });\n\n this.emit(\"newRTCSession\", e);\n }\n\n private bindLocalOutgoingAudio(sessionId: string, session: RTCSession) {\n const maxAttempts = 50;\n const retryDelayMs = 500;\n let attempts = 0;\n let retryScheduled = false;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let stopped = false;\n let exhausted = false;\n let exhaustedCheckUsed = false;\n let attachedPc: RTCPeerConnection | null = null;\n const logLocalAudioError = (\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>\n ) => {\n sipDebugLogger.logLocalAudioError(sessionId, message, pc, extra);\n };\n\n const tryBindFromPc = (pc?: RTCPeerConnection | null) => {\n if (\n stopped ||\n !pc ||\n this.sessionManager.getRtc(sessionId)?.mediaStream\n ) {\n return false;\n }\n const audioSender = pc\n ?.getSenders?.()\n ?.find((s: RTCRtpSender) => s.track?.kind === \"audio\");\n const audioTrack = audioSender?.track;\n if (!audioTrack) {\n logLocalAudioError(\n \"[sip] outgoing audio bind failed: no audio track\",\n pc\n );\n return false;\n }\n const outgoingStream = new MediaStream([audioTrack]);\n this.sessionManager.setSessionMedia(sessionId, outgoingStream);\n return true;\n };\n\n const onPcStateChange = () => {\n if (stopped) return;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (tryBindFromPc(attachedPc)) stopRetry();\n return;\n }\n if (tryBindFromPc(attachedPc)) stopRetry();\n };\n\n const attachPcListeners = (pc?: RTCPeerConnection | null) => {\n if (!pc || pc === attachedPc) return;\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange\n );\n }\n attachedPc = pc;\n attachedPc.addEventListener?.(\"signalingstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\"connectionstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange\n );\n };\n\n const clearRetryTimer = () => {\n if (!retryTimer) return;\n clearTimeout(retryTimer);\n retryTimer = null;\n };\n\n const stopRetry = () => {\n if (stopped) return;\n stopped = true;\n clearRetryTimer();\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange\n );\n attachedPc = null;\n }\n session.off?.(\"peerconnection\", onPeer);\n session.off?.(\"confirmed\", onConfirmed);\n session.off?.(\"ended\", stopRetry);\n session.off?.(\"failed\", stopRetry);\n };\n\n const scheduleRetry = (pc?: RTCPeerConnection | null) => {\n if (stopped || retryScheduled || exhausted) return;\n if (attempts >= maxAttempts) {\n logLocalAudioError(\n \"[sip] outgoing audio bind failed: max retries reached\",\n pc,\n { attempts }\n );\n exhausted = true;\n clearRetryTimer();\n return;\n }\n if (!pc) {\n logLocalAudioError(\n \"[sip] outgoing audio bind failed: missing peerconnection\",\n pc\n );\n }\n retryScheduled = true;\n attempts += 1;\n retryTimer = setTimeout(() => {\n retryScheduled = false;\n retryTimer = null;\n if (tryBindFromPc(pc)) {\n stopRetry();\n return;\n }\n scheduleRetry(pc);\n }, retryDelayMs);\n };\n\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\n if (stopped) return;\n attachPcListeners(data.peerconnection);\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (tryBindFromPc(data.peerconnection)) stopRetry();\n return;\n }\n if (tryBindFromPc(data.peerconnection)) {\n stopRetry();\n return;\n }\n scheduleRetry(data.peerconnection);\n };\n\n const onConfirmed = () => {\n if (stopped) return;\n const currentPc =\n (session as RTCSession & { connection?: RTCPeerConnection })\n ?.connection ?? attachedPc;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (tryBindFromPc(currentPc)) stopRetry();\n return;\n }\n if (tryBindFromPc(currentPc)) {\n stopRetry();\n return;\n }\n scheduleRetry(currentPc);\n };\n\n const existingPc = (\n session as RTCSession & {\n connection?: RTCPeerConnection;\n }\n )?.connection;\n if (!tryBindFromPc(existingPc)) {\n if (existingPc) {\n attachPcListeners(existingPc);\n scheduleRetry(existingPc);\n }\n session.on?.(\"peerconnection\", onPeer);\n }\n session.on?.(\"confirmed\", onConfirmed);\n session.on?.(\"ended\", () => stopRetry());\n session.on?.(\"failed\", () => stopRetry());\n }\n\n private bindRemoteIncomingAudio(sessionId: string, session: RTCSession) {\n const maxAttempts = 50;\n const retryDelayMs = 500;\n let attempts = 0;\n let retryScheduled = false;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let stopped = false;\n let exhausted = false;\n let exhaustedCheckUsed = false;\n let attachedPc: RTCPeerConnection | null = null;\n let attachedTrack: MediaStreamTrack | null = null;\n const logRemoteAudioError = (\n message: string,\n pc?: RTCPeerConnection | null,\n extra?: Record<string, unknown>\n ) => {\n sipDebugLogger.logRemoteAudioError(sessionId, message, pc, extra);\n };\n\n const logMissingReceiver = (\n pc?: RTCPeerConnection | null,\n note?: string\n ) => {\n logRemoteAudioError(\n \"[sip] incoming audio bind failed: no remote track\",\n pc,\n { note }\n );\n };\n\n const getRemoteAudioTrack = (pc?: RTCPeerConnection | null) => {\n const receiver = pc\n ?.getReceivers?.()\n ?.find((r: RTCRtpReceiver) => r.track?.kind === \"audio\");\n return receiver?.track ?? null;\n };\n\n const attachTrackListeners = (track?: MediaStreamTrack | null) => {\n if (!track || track === attachedTrack) return;\n if (attachedTrack) {\n attachedTrack.removeEventListener?.(\"ended\", onRemoteEnded);\n attachedTrack.removeEventListener?.(\"mute\", onRemoteMuted);\n }\n attachedTrack = track;\n attachedTrack.addEventListener?.(\"ended\", onRemoteEnded);\n attachedTrack.addEventListener?.(\"mute\", onRemoteMuted);\n };\n\n const checkRemoteTrack = (pc?: RTCPeerConnection | null) => {\n if (stopped || !pc) return false;\n const track = getRemoteAudioTrack(pc);\n if (!track) return false;\n attachTrackListeners(track);\n if (track.readyState !== \"live\") {\n logRemoteAudioError(\"[sip] incoming audio track not live\", pc, {\n trackState: track.readyState,\n });\n }\n return true;\n };\n\n const onRemoteEnded = () => {\n logRemoteAudioError(\"[sip] incoming audio track ended\", attachedPc);\n };\n\n const onRemoteMuted = () => {\n logRemoteAudioError(\"[sip] incoming audio track muted\", attachedPc);\n };\n\n const onPcStateChange = () => {\n if (stopped) return;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n };\n\n const attachPcListeners = (pc?: RTCPeerConnection | null) => {\n if (!pc || pc === attachedPc) return;\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\"track\", onTrack);\n }\n attachedPc = pc;\n attachedPc.addEventListener?.(\"signalingstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\"connectionstatechange\", onPcStateChange);\n attachedPc.addEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange\n );\n attachedPc.addEventListener?.(\"track\", onTrack);\n };\n\n const clearRetryTimer = () => {\n if (!retryTimer) return;\n clearTimeout(retryTimer);\n retryTimer = null;\n };\n\n const stopRetry = (opts: { keepTrack?: boolean } = {}) => {\n if (stopped) return;\n stopped = true;\n clearRetryTimer();\n if (attachedPc) {\n attachedPc.removeEventListener?.(\n \"signalingstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"connectionstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\n \"iceconnectionstatechange\",\n onPcStateChange\n );\n attachedPc.removeEventListener?.(\"track\", onTrack);\n attachedPc = null;\n }\n if (attachedTrack && !opts.keepTrack) {\n attachedTrack.removeEventListener?.(\"ended\", onRemoteEnded);\n attachedTrack.removeEventListener?.(\"mute\", onRemoteMuted);\n attachedTrack = null;\n }\n session.off?.(\"peerconnection\", onPeer);\n session.off?.(\"confirmed\", onConfirmed);\n session.off?.(\"ended\", stopRetry);\n session.off?.(\"failed\", stopRetry);\n };\n\n const scheduleRetry = (pc?: RTCPeerConnection | null) => {\n if (stopped || retryScheduled || exhausted) return;\n if (attempts >= maxAttempts) {\n logRemoteAudioError(\n \"[sip] incoming audio bind failed: max retries reached\",\n pc,\n { attempts }\n );\n exhausted = true;\n clearRetryTimer();\n return;\n }\n retryScheduled = true;\n attempts += 1;\n retryTimer = setTimeout(() => {\n retryScheduled = false;\n retryTimer = null;\n if (checkRemoteTrack(pc)) {\n stopRetry({ keepTrack: true });\n return;\n }\n if (!pc) logMissingReceiver(pc, \"missing peerconnection\");\n scheduleRetry(pc);\n }, retryDelayMs);\n };\n\n const onTrack = () => {\n if (stopped) return;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(attachedPc)) stopRetry({ keepTrack: true });\n };\n\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\n if (stopped) return;\n attachPcListeners(data.peerconnection);\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(data.peerconnection))\n stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(data.peerconnection)) {\n stopRetry({ keepTrack: true });\n return;\n }\n scheduleRetry(data.peerconnection);\n };\n\n const onConfirmed = () => {\n if (stopped) return;\n const currentPc =\n (session as RTCSession & { connection?: RTCPeerConnection })\n ?.connection ?? attachedPc;\n if (exhausted) {\n if (exhaustedCheckUsed) return;\n exhaustedCheckUsed = true;\n if (checkRemoteTrack(currentPc)) stopRetry({ keepTrack: true });\n return;\n }\n if (checkRemoteTrack(currentPc)) {\n stopRetry({ keepTrack: true });\n return;\n }\n logMissingReceiver(currentPc, \"confirmed without remote track\");\n scheduleRetry(currentPc);\n };\n\n const existingPc = (\n session as RTCSession & {\n connection?: RTCPeerConnection;\n }\n )?.connection;\n if (!checkRemoteTrack(existingPc)) {\n if (existingPc) {\n attachPcListeners(existingPc);\n scheduleRetry(existingPc);\n }\n session.on?.(\"peerconnection\", onPeer);\n }\n session.on?.(\"confirmed\", onConfirmed);\n session.on?.(\"ended\", () => stopRetry());\n session.on?.(\"failed\", () => stopRetry());\n }\n\n private attachCallStatsLogging(sessionId: string, session: RTCSession) {\n const onConfirmed = () => {\n sipDebugLogger.startCallStatsLogging(sessionId, session);\n };\n const onEnd = () => {\n sipDebugLogger.stopCallStatsLogging(sessionId);\n };\n\n session.on?.(\"confirmed\", onConfirmed);\n session.on?.(\"ended\", onEnd);\n session.on?.(\"failed\", onEnd);\n }\n}\n","import type { SipStateStore } from \"../state/sip.state.store\";\nimport { CallStatus } from \"../../contracts/state\";\nimport type { EventTargetEmitter } from \"../event/event-target.emitter\";\nimport type {\n AnswerOptions,\n DTMFOptions,\n ExtraHeaders,\n JsSIPEventMap,\n RenegotiateOptions,\n ReferOptions,\n RTCSession,\n RTCSessionEvent,\n RTCSessionEventMap,\n TerminateOptions,\n} from \"../../sip/types\";\nimport { createSessionHandlers } from \"./session.handlers\";\nimport type { SessionManager } from \"./session.manager\";\nimport { removeSessionState } from \"./session.state.projector\";\nimport { SessionLifecycle } from \"./session.lifecycle\";\nimport type { MicRecoveryManager } from \"../media/mic-recovery.manager\";\n\ntype SessionModuleDeps = {\n state: SipStateStore;\n emitter: EventTargetEmitter<JsSIPEventMap>;\n sessionManager: SessionManager;\n micRecovery: MicRecoveryManager;\n getMaxSessionCount: () => number;\n getIceCandidateReadyDelayMs: () => number | undefined;\n};\n\nexport class SessionModule {\n private sessionHandlers = new Map<string, Partial<RTCSessionEventMap>>();\n private lifecycle: SessionLifecycle;\n\n constructor(private readonly deps: SessionModuleDeps) {\n this.lifecycle = new SessionLifecycle({\n state: deps.state,\n sessionManager: deps.sessionManager,\n emit: (event, payload) => deps.emitter.emit(event, payload),\n attachSessionHandlers: (sessionId, session) =>\n this.attachSessionHandlers(sessionId, session),\n getMaxSessionCount: deps.getMaxSessionCount,\n });\n }\n\n setDebugEnabled(enabled: boolean) {\n this.lifecycle.setDebugEnabled(enabled);\n }\n\n handleNewRTCSession(e: RTCSessionEvent) {\n this.lifecycle.handleNewRTCSession(e);\n }\n\n setSessionMedia(sessionId: string, stream: MediaStream) {\n this.deps.sessionManager.setSessionMedia(sessionId, stream);\n }\n\n setSession(sessionId: string, session: RTCSession) {\n this.deps.sessionManager.setSession(sessionId, session);\n }\n\n answerSession(sessionId: string, options: AnswerOptions = {}) {\n if (!sessionId || !this.sessionExists(sessionId)) return false;\n return this.deps.sessionManager.answer(sessionId, options);\n }\n\n hangupSession(sessionId: string, options?: TerminateOptions) {\n if (!sessionId || !this.sessionExists(sessionId)) return false;\n return this.deps.sessionManager.hangup(sessionId, options);\n }\n\n hangupAll(options?: TerminateOptions) {\n const ids = this.getSessionIds();\n if (ids.length === 0) return false;\n return ids.every((id) => this.hangupSession(id, options));\n }\n\n toggleMuteSession(sessionId?: string) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n const muted = sessionState?.muted ?? false;\n if (muted) {\n this.deps.sessionManager.unmute(resolved);\n return true;\n }\n this.deps.sessionManager.mute(resolved);\n return true;\n }\n\n toggleHoldSession(sessionId?: string) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n const isOnHold = sessionState?.status === CallStatus.Hold;\n if (isOnHold) {\n this.deps.sessionManager.unhold(resolved);\n return true;\n }\n if (sessionState?.status === CallStatus.Active) {\n this.deps.sessionManager.hold(resolved);\n return true;\n }\n return false;\n }\n\n sendDTMFSession(\n sessionId: string,\n tones: string | number,\n options?: DTMFOptions\n ) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n if (sessionState?.status === CallStatus.Active) {\n this.deps.sessionManager.sendDTMF(resolved, tones, options);\n return true;\n }\n return false;\n }\n\n transferSession(sessionId: string, target: string, options?: ReferOptions) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n if (sessionState?.status === CallStatus.Active) {\n this.deps.sessionManager.transfer(resolved, target, options);\n return true;\n }\n return false;\n }\n\n sendInfoSession(\n sessionId: string,\n contentType: string,\n body?: string,\n options?: ExtraHeaders\n ) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n if (\n sessionState?.status !== CallStatus.Active &&\n sessionState?.status !== CallStatus.Hold\n ) {\n return false;\n }\n const session = this.deps.sessionManager.getSession(resolved);\n if (!session) return false;\n session.sendInfo(contentType, body, options);\n return true;\n }\n\n updateSession(sessionId: string, options?: RenegotiateOptions) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return false;\n const sessionState = this.deps.state.getState().sessionsById[resolved];\n if (\n sessionState?.status !== CallStatus.Active &&\n sessionState?.status !== CallStatus.Hold\n ) {\n return false;\n }\n const session = this.deps.sessionManager.getSession(resolved);\n if (!session) return false;\n return session.renegotiate(options);\n }\n\n getSession(sessionId: string) {\n return this.deps.sessionManager.getSession(sessionId);\n }\n\n getSessionIds() {\n return this.deps.sessionManager.getSessionIds();\n }\n\n getSessions() {\n return this.deps.sessionManager.getSessions();\n }\n\n cleanupAllSessions() {\n this.deps.sessionManager.cleanupAllSessions();\n this.deps.micRecovery.cleanupAll();\n this.sessionHandlers.clear();\n this.deps.state.setState({\n sessions: [],\n sessionsById: {},\n sessionIds: [],\n error: null,\n });\n }\n\n private attachSessionHandlers(sessionId: string, session: RTCSession) {\n const handlers = this.createSessionHandlersFor(sessionId, session);\n this.sessionHandlers.set(sessionId, handlers);\n\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\n const h = handlers[ev];\n if (h) session.on(ev, h);\n });\n }\n\n private detachSessionHandlers(sessionId: string, session: RTCSession) {\n const handlers = this.sessionHandlers.get(sessionId);\n if (!handlers || !session) return;\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\n const h = handlers[ev];\n if (h) session.off(ev, h);\n });\n this.sessionHandlers.delete(sessionId);\n }\n\n private cleanupSession(sessionId: string, session?: RTCSession) {\n const targetSession =\n session ??\n this.deps.sessionManager.getSession(sessionId) ??\n this.deps.sessionManager.getRtc(sessionId)?.currentSession;\n if (targetSession) {\n this.detachSessionHandlers(sessionId, targetSession);\n }\n this.deps.micRecovery.disable(sessionId);\n this.deps.sessionManager.cleanupSession(sessionId);\n removeSessionState(this.deps.state, sessionId);\n }\n\n private createSessionHandlersFor(\n sessionId: string,\n session: RTCSession\n ): Partial<RTCSessionEventMap> {\n const rtc = this.deps.sessionManager.getOrCreateRtc(sessionId, session);\n return createSessionHandlers({\n emitter: this.deps.emitter,\n state: this.deps.state,\n rtc,\n detachSessionHandlers: () => this.cleanupSession(sessionId, session),\n enableMicrophoneRecovery: (confirmedSessionId) =>\n this.deps.micRecovery.enable(confirmedSessionId),\n iceCandidateReadyDelayMs: this.deps.getIceCandidateReadyDelayMs(),\n sessionId,\n });\n }\n\n private resolveSessionId(sessionId?: string) {\n if (sessionId) return sessionId;\n const state = this.deps.state.getState();\n const activeId = state.sessionIds.find(\n (id) => state.sessionsById[id]?.status === CallStatus.Active\n );\n return activeId ?? state.sessionIds[0] ?? null;\n }\n\n private sessionExists(sessionId: string) {\n return (\n !!this.deps.sessionManager.getSession(sessionId) ||\n !!this.deps.sessionManager.getRtc(sessionId)\n );\n }\n\n private resolveExistingSessionId(sessionId?: string) {\n const id = this.resolveSessionId(sessionId);\n if (!id) return null;\n return this.sessionExists(id) ? id : null;\n }\n}\n","import type { UAEventMap } from \"../../sip/types\";\nimport { SipStatus } from \"../../contracts/state\";\nimport type { SipStateStore } from \"../state/sip.state.store\";\nimport type { JsSIPEventMap } from \"../../sip/types\";\nimport type { EventTargetEmitter } from \"../event/event-target.emitter\";\nimport type {\n IncomingMessageEvent,\n IncomingOptionsEvent,\n OutgoingMessageEvent,\n OutgoingOptionsEvent,\n} from \"jssip/src/UA\";\n\ntype Deps = {\n emitter: EventTargetEmitter<JsSIPEventMap>;\n state: SipStateStore;\n cleanupAllSessions: () => void;\n onNewRTCSession: UAEventMap[\"newRTCSession\"];\n};\n\nexport function createUAHandlers(deps: Deps): Partial<UAEventMap> {\n const { emitter, state, cleanupAllSessions, onNewRTCSession } = deps;\n\n return {\n connecting: (e) => {\n emitter.emit(\"connecting\", e);\n state.batchSet({ sipStatus: SipStatus.Connecting });\n },\n connected: (e) => {\n emitter.emit(\"connected\", e);\n state.batchSet({ sipStatus: SipStatus.Connected });\n },\n disconnected: (e) => {\n emitter.emit(\"disconnected\", e);\n cleanupAllSessions();\n state.reset();\n },\n\n registered: (e) => {\n emitter.emit(\"registered\", e);\n state.batchSet({ sipStatus: SipStatus.Registered, error: null });\n },\n unregistered: (e) => {\n emitter.emit(\"unregistered\", e);\n state.batchSet({ sipStatus: SipStatus.Unregistered });\n },\n registrationFailed: (e) => {\n emitter.emit(\"registrationFailed\", e);\n cleanupAllSessions();\n state.batchSet({\n sipStatus: SipStatus.RegistrationFailed,\n error: e?.cause || \"registration failed\",\n });\n },\n newRTCSession: onNewRTCSession,\n newMessage: (e: IncomingMessageEvent | OutgoingMessageEvent) =>\n emitter.emit(\"newMessage\", e),\n sipEvent: (e: any) => emitter.emit(\"sipEvent\", e),\n newOptions: (e: IncomingOptionsEvent | OutgoingOptionsEvent) =>\n emitter.emit(\"newOptions\", e),\n };\n}\n","import type { SipUserAgent } from \"../../sip/user-agent\";\nimport type { SipConfiguration, UAEventMap } from \"../../sip/types\";\nimport { createUAHandlers } from \"./ua.handlers\";\n\ntype UaModuleDeps = {\n userAgent: SipUserAgent;\n createHandlers: () => Partial<UAEventMap>;\n};\n\nexport class UaModule {\n private readonly userAgent: SipUserAgent;\n private readonly uaHandlers: Partial<UAEventMap>;\n private readonly uaHandlerKeys: (keyof UAEventMap)[];\n\n constructor(deps: UaModuleDeps) {\n this.userAgent = deps.userAgent;\n this.uaHandlers = deps.createHandlers();\n this.uaHandlerKeys = Object.keys(this.uaHandlers) as (keyof UAEventMap)[];\n }\n\n start(\n uri: string,\n password: string,\n config: Omit<SipConfiguration, \"debug\">,\n debug?: boolean | string\n ) {\n this.userAgent.start(uri, password, config, { debug });\n this.attachHandlers();\n }\n\n stop() {\n this.detachHandlers();\n this.userAgent.stop();\n }\n\n register() {\n this.userAgent.register();\n }\n\n setDebug(debug?: boolean | string) {\n this.userAgent.setDebug(debug);\n }\n\n private attachHandlers() {\n const ua = this.userAgent.ua;\n if (!ua) return;\n\n this.detachHandlers();\n this.uaHandlerKeys.forEach((event) => {\n const handler = this.uaHandlers[event];\n if (handler) ua.on(event, handler);\n });\n }\n\n private detachHandlers() {\n const ua = this.userAgent.ua;\n if (!ua) return;\n this.uaHandlerKeys.forEach((event) => {\n const handler = this.uaHandlers[event];\n if (handler) ua.off(event, handler);\n });\n }\n}\n\nexport function createUaHandlers(deps: Parameters<typeof createUAHandlers>[0]) {\n return createUAHandlers(deps);\n}\n","import { SipUserAgent } from \"../sip/user-agent\";\nimport type {\n AnswerOptions,\n CallOptions,\n DTMFOptions,\n ExtraHeaders,\n JsSIPEventMap,\n RenegotiateOptions,\n ReferOptions,\n RTCSession,\n RTCSessionEvent,\n SendMessageOptions,\n SipConfiguration,\n SipSendOptionsOptions,\n TerminateOptions,\n} from \"../sip/types\";\nimport type { SipState} from \"../contracts/state\";\nimport { SipStatus } from \"../contracts/state\";\nimport { EventTargetEmitter } from \"../modules/event/event-target.emitter\";\nimport { SipStateStore } from \"../modules/state/sip.state.store\";\nimport { SipDebugRuntime } from \"../modules/debug/sip-debug.runtime\";\nimport { createSipEventManager } from \"../modules/event/sip-event-manager.adapter\";\nimport { MicRecoveryManager } from \"../modules/media/mic-recovery.manager\";\nimport { BrowserUnloadRuntime } from \"../modules/runtime/browser-unload.runtime\";\nimport { SessionManager } from \"../modules/session/session.manager\";\nimport { SessionModule } from \"../modules/session/session.module\";\nimport { createUAHandlers } from \"../modules/ua/ua.handlers\";\nimport { UaModule } from \"../modules/ua/ua.module\";\n\nexport type SipClientOptions = {\n debug?: boolean | string;\n};\n\ntype UAWithSendOptions = {\n sendOptions: (\n target: string,\n body?: string,\n options?: SipSendOptionsOptions\n ) => void;\n};\n\nexport class SipClient extends EventTargetEmitter<JsSIPEventMap> {\n public readonly userAgent = new SipUserAgent();\n public readonly stateStore = new SipStateStore();\n\n private readonly uaModule: UaModule;\n private debugPattern?: boolean | string;\n private maxSessionCount = Infinity;\n private iceCandidateReadyDelayMs?: number;\n private sessionManager = new SessionManager();\n private sessionModule: SessionModule;\n private micRecovery: MicRecoveryManager;\n private unloadRuntime = new BrowserUnloadRuntime();\n private debugRuntime: SipDebugRuntime;\n\n public get state(): SipState {\n return this.stateStore.getPublicState();\n }\n\n constructor(options: SipClientOptions = {}) {\n super();\n this.debugPattern = options.debug;\n\n this.uaModule = new UaModule({\n userAgent: this.userAgent,\n createHandlers: () =>\n createUAHandlers({\n emitter: this,\n state: this.stateStore,\n cleanupAllSessions: () => this.cleanupAllSessions(),\n onNewRTCSession: (e: RTCSessionEvent) => this.onNewRTCSession(e),\n }),\n });\n\n this.micRecovery = new MicRecoveryManager({\n getRtc: (sessionId) => this.sessionManager.getRtc(sessionId),\n getSession: (sessionId) => this.sessionManager.getSession(sessionId),\n getSessionState: (sessionId) =>\n this.stateStore.getState().sessionsById[sessionId],\n setSessionMedia: (sessionId, stream) =>\n this.sessionManager.setSessionMedia(sessionId, stream),\n });\n\n this.sessionModule = new SessionModule({\n state: this.stateStore,\n emitter: this,\n sessionManager: this.sessionManager,\n micRecovery: this.micRecovery,\n getMaxSessionCount: () => this.maxSessionCount,\n getIceCandidateReadyDelayMs: () => this.iceCandidateReadyDelayMs,\n });\n\n this.debugRuntime = new SipDebugRuntime({\n getState: () => this.stateStore.getPublicState(),\n onChange: (listener) => this.stateStore.onPublicChange(listener),\n getSessions: () => this.getSessions(),\n setDebugEnabled: (enabled) => this.sessionModule.setDebugEnabled(enabled),\n });\n\n this.debugRuntime.attachBridge((debug?: boolean | string) =>\n this.setDebug(debug)\n );\n }\n\n public connect(uri: string, password: string, config: SipConfiguration) {\n this.disconnect();\n this.stateStore.setState({ sipStatus: SipStatus.Connecting });\n const {\n debug: cfgDebug,\n enableMicRecovery,\n micRecoveryIntervalMs,\n micRecoveryMaxRetries,\n maxSessionCount,\n iceCandidateReadyDelayMs,\n ...uaCfg\n } = config;\n this.maxSessionCount =\n typeof maxSessionCount === \"number\" ? maxSessionCount : Infinity;\n this.iceCandidateReadyDelayMs =\n typeof iceCandidateReadyDelayMs === \"number\"\n ? iceCandidateReadyDelayMs\n : undefined;\n this.micRecovery.configure({\n enabled: Boolean(enableMicRecovery),\n intervalMs: micRecoveryIntervalMs,\n maxRetries: micRecoveryMaxRetries,\n });\n const debug =\n cfgDebug ?? this.debugRuntime.getPersistedDebug() ?? this.debugPattern;\n this.uaModule.start(uri, password, uaCfg, debug);\n this.sessionModule.setDebugEnabled(Boolean(debug));\n this.unloadRuntime.attach(() => {\n this.hangupAll();\n this.disconnect();\n });\n this.debugRuntime.syncInspector(debug);\n }\n\n public registerUA() {\n this.uaModule.register();\n }\n\n public disconnect() {\n this.unloadRuntime.detach();\n this.uaModule.stop();\n this.cleanupAllSessions();\n this.stateStore.reset();\n this.debugRuntime.cleanup();\n }\n\n public call(target: string, callOptions: CallOptions = {}) {\n try {\n const ua = this.userAgent.getUA();\n const session = ua?.call(target, callOptions) as RTCSession | undefined;\n if (session && callOptions.mediaStream) {\n const sessionId = String(session.id ?? \"\");\n if (sessionId) {\n this.sessionModule.setSessionMedia(\n sessionId,\n callOptions.mediaStream\n );\n this.sessionModule.setSession(sessionId, session);\n }\n }\n } catch (e: unknown) {\n console.error(e);\n this.cleanupAllSessions();\n }\n }\n\n public sendMessage(\n target: string,\n body: string,\n options?: SendMessageOptions\n ) {\n try {\n const ua = this.userAgent.getUA();\n if (!ua) return false;\n ua.sendMessage(target, body, options);\n return true;\n } catch (e: unknown) {\n console.error(e);\n return false;\n }\n }\n\n public sendOptions(\n target: string,\n body?: string,\n options?: SipSendOptionsOptions\n ) {\n try {\n const ua = this.userAgent.getUA();\n if (!ua) return false;\n const optionsUa = ua as unknown as UAWithSendOptions;\n if (typeof optionsUa.sendOptions !== \"function\") return false;\n optionsUa.sendOptions(target, body, options);\n return true;\n } catch (e: unknown) {\n console.error(e);\n return false;\n }\n }\n\n public hangupAll(options?: TerminateOptions) {\n const ids = this.getSessionIds();\n ids.forEach((id) => this.hangupSession(id, options));\n return ids.length > 0;\n }\n\n public onChange(fn: (s: SipState) => void) {\n return this.stateStore.onPublicChange(fn);\n }\n\n public setDebug(debug?: boolean | string) {\n this.debugPattern = debug;\n this.uaModule.setDebug(debug);\n this.sessionModule.setDebugEnabled(Boolean(debug));\n const effectiveDebug =\n debug ?? this.debugRuntime.getPersistedDebug() ?? this.debugPattern;\n this.debugRuntime.syncInspector(effectiveDebug);\n }\n\n private cleanupAllSessions() {\n this.sessionModule.cleanupAllSessions();\n }\n\n protected onNewRTCSession(e: RTCSessionEvent) {\n this.sessionModule.handleNewRTCSession(e);\n }\n\n public answerSession(sessionId: string, options: AnswerOptions = {}) {\n if (options.mediaStream) {\n this.sessionModule.setSessionMedia(sessionId, options.mediaStream);\n }\n return this.sessionModule.answerSession(sessionId, options);\n }\n\n public hangupSession(sessionId: string, options?: TerminateOptions) {\n return this.sessionModule.hangupSession(sessionId, options);\n }\n\n public toggleMuteSession(sessionId?: string) {\n return this.sessionModule.toggleMuteSession(sessionId);\n }\n\n public toggleHoldSession(sessionId?: string) {\n return this.sessionModule.toggleHoldSession(sessionId);\n }\n\n public sendDTMFSession(\n sessionId: string,\n tones: string | number,\n options?: DTMFOptions\n ) {\n return this.sessionModule.sendDTMFSession(sessionId, tones, options);\n }\n\n public transferSession(\n sessionId: string,\n target: string,\n options?: ReferOptions\n ) {\n return this.sessionModule.transferSession(sessionId, target, options);\n }\n\n public sendInfoSession(\n sessionId: string,\n contentType: string,\n body?: string,\n options?: ExtraHeaders\n ) {\n return this.sessionModule.sendInfoSession(\n sessionId,\n contentType,\n body,\n options\n );\n }\n\n public updateSession(sessionId: string, options?: RenegotiateOptions) {\n return this.sessionModule.updateSession(sessionId, options);\n }\n\n public reinviteSession(sessionId: string, options?: RenegotiateOptions) {\n return this.sessionModule.updateSession(sessionId, options);\n }\n\n public setSessionMedia(sessionId: string, stream: MediaStream) {\n this.sessionModule.setSessionMedia(sessionId, stream);\n }\n\n public getSession(sessionId: string) {\n return this.sessionModule.getSession(sessionId);\n }\n\n public getSessionIds() {\n return this.sessionModule.getSessionIds();\n }\n\n public getSessions() {\n return this.sessionModule.getSessions();\n }\n}\n\nexport function createSipClientInstance(options?: SipClientOptions): SipClient {\n return new SipClient(options);\n}\n\nexport { createSipEventManager };\n","import type { SipEventManager } from \"../../sip/types\";\nimport type { SipClient } from \"../../client\";\nimport type { MediaModule } from \"./types\";\n\ntype CreateMediaModuleDeps = {\n client: SipClient;\n eventManager: SipEventManager;\n};\n\nexport function createMediaModule(deps: CreateMediaModuleDeps): MediaModule {\n const { client, eventManager } = deps;\n\n return {\n getSession(sessionId: string) {\n return client.getSession(sessionId);\n },\n\n observePeerConnection(sessionId, onPeerConnection) {\n const session = client.getSession(sessionId);\n if (!session) {\n onPeerConnection(null);\n return () => {};\n }\n\n const initialPc =\n (session as { connection?: RTCPeerConnection }).connection ?? null;\n onPeerConnection(initialPc);\n\n return eventManager.onSession(sessionId, \"peerconnection\", (payload) => {\n const pc =\n (payload as { peerconnection?: RTCPeerConnection })?.peerconnection ??\n null;\n onPeerConnection(pc);\n });\n },\n\n buildRemoteStream(peerConnection: RTCPeerConnection | null) {\n if (\n !peerConnection ||\n typeof peerConnection.getReceivers !== \"function\"\n ) {\n return null;\n }\n\n const tracks = peerConnection\n .getReceivers()\n .map((receiver) => receiver.track)\n .filter((track): track is MediaStreamTrack => Boolean(track));\n\n if (tracks.length === 0) return null;\n return new MediaStream(tracks);\n },\n };\n}\n","import { createSipClientInstance } from \"../client\";\nimport type {\n AnswerOptions,\n CallOptions,\n DTMFOptions,\n ExtraHeaders,\n RenegotiateOptions,\n ReferOptions,\n SendMessageOptions,\n SipConfiguration,\n SipSendOptionsOptions,\n TerminateOptions,\n} from \"../sip/types\";\nimport type { SipKernel } from \"./types\";\nimport { createMediaModule } from \"../modules/media/media.module\";\nimport { createSipEventManager } from \"../modules/event/sip-event-manager.adapter\";\n\nexport function createSipKernel(): SipKernel {\n const client = createSipClientInstance();\n const eventManager = createSipEventManager(client);\n const media = createMediaModule({ client, eventManager });\n\n return {\n client,\n store: {\n getState: () => client.state,\n subscribe: (onStoreChange) => client.onChange(onStoreChange),\n },\n commands: {\n connect: (uri: string, password: string, config: SipConfiguration) =>\n client.connect(uri, password, config),\n disconnect: () => client.disconnect(),\n register: () => client.registerUA(),\n setDebug: (debug?: boolean | string) => client.setDebug(debug),\n call: (target: string, options?: CallOptions) =>\n client.call(target, options),\n sendMessage: (\n target: string,\n body: string,\n options?: SendMessageOptions\n ) => client.sendMessage(target, body, options),\n sendOptions: (\n target: string,\n body?: string,\n options?: SipSendOptionsOptions\n ) => client.sendOptions(target, body, options),\n answer: (sessionId: string, options?: AnswerOptions) =>\n client.answerSession(sessionId, options),\n hangup: (sessionId: string, options?: TerminateOptions) =>\n client.hangupSession(sessionId, options),\n hangupAll: (options?: TerminateOptions) => client.hangupAll(options),\n toggleMute: (sessionId?: string) => client.toggleMuteSession(sessionId),\n toggleHold: (sessionId?: string) => client.toggleHoldSession(sessionId),\n sendDTMF: (\n sessionId: string,\n tones: string | number,\n options?: DTMFOptions\n ) => client.sendDTMFSession(sessionId, tones, options),\n transfer: (sessionId: string, target: string, options?: ReferOptions) =>\n client.transferSession(sessionId, target, options),\n sendInfo: (\n sessionId: string,\n contentType: string,\n body?: string,\n options?: ExtraHeaders\n ) => client.sendInfoSession(sessionId, contentType, body, options),\n update: (sessionId: string, options?: RenegotiateOptions) =>\n client.updateSession(sessionId, options),\n reinvite: (sessionId: string, options?: RenegotiateOptions) =>\n client.reinviteSession(sessionId, options),\n getSession: (sessionId: string) => client.getSession(sessionId),\n getSessionIds: () => client.getSessionIds(),\n getSessions: () => client.getSessions(),\n setSessionMedia: (sessionId: string, stream: MediaStream) =>\n client.setSessionMedia(sessionId, stream),\n },\n events: {\n onUA: (event, handler) => eventManager.onUA(event, handler),\n onSession: (sessionId, event, handler) =>\n eventManager.onSession(sessionId, event, handler),\n },\n eventManager,\n media,\n };\n}\n","import { useSyncExternalStore } from \"react\";\nimport type { SipState } from \"../core/contracts/state\";\nimport { useSipKernel } from \"./useSip\";\n\nexport function useSipState(): SipState {\n const { store } = useSipKernel();\n return useSyncExternalStore(store.subscribe, store.getState, store.getState);\n}\n","import { useContext } from \"react\";\nimport { SipContext } from \"../context\";\n\nexport function useSipKernel() {\n const ctx = useContext(SipContext);\n if (!ctx) throw new Error(\"Must be used within SipProvider\");\n return ctx;\n}\n","import { createContext } from \"react\";\nimport type { SipKernel } from \"../core/kernel/types\";\n\nexport type SipContextType = SipKernel;\nexport const SipContext = createContext<SipContextType | null>(null);\n","import { useMemo } from \"react\";\nimport { useSipKernel } from \"./useSip\";\n\nexport function useSipActions() {\n const { commands } = useSipKernel();\n return useMemo(\n () => ({\n connect: commands.connect,\n disconnect: commands.disconnect,\n register: commands.register,\n setDebug: commands.setDebug,\n call: commands.call,\n sendMessage: commands.sendMessage,\n sendOptions: commands.sendOptions,\n answer: commands.answer,\n hangup: commands.hangup,\n hangupAll: commands.hangupAll,\n toggleMute: commands.toggleMute,\n toggleHold: commands.toggleHold,\n sendDTMF: commands.sendDTMF,\n transfer: commands.transfer,\n sendInfo: commands.sendInfo,\n update: commands.update,\n reinvite: commands.reinvite,\n getSession: commands.getSession,\n getSessionIds: commands.getSessionIds,\n getSessions: commands.getSessions,\n setSessionMedia: commands.setSessionMedia,\n }),\n [commands]\n );\n}\n","import { useRef, useSyncExternalStore } from \"react\";\nimport type { SipState } from \"../core/contracts/state\";\nimport { useSipKernel } from \"./useSip\";\n\nexport type SipSelector<TSelected> = (state: SipState) => TSelected;\nexport type SipSelectorEqualityFn<TSelected> = (\n prev: TSelected,\n next: TSelected\n) => boolean;\n\nexport function useSipSelector<TSelected>(\n selector: SipSelector<TSelected>,\n equalityFn: SipSelectorEqualityFn<TSelected> = Object.is\n): TSelected {\n const { store } = useSipKernel();\n const selectorRef = useRef(selector);\n const equalityFnRef = useRef(equalityFn);\n const selectedRef = useRef<TSelected | undefined>(undefined);\n const hasSelectedRef = useRef(false);\n\n selectorRef.current = selector;\n equalityFnRef.current = equalityFn;\n\n const getSelection = () => {\n const nextSelected = selectorRef.current(store.getState());\n if (\n hasSelectedRef.current &&\n equalityFnRef.current(selectedRef.current as TSelected, nextSelected)\n ) {\n return selectedRef.current as TSelected;\n }\n hasSelectedRef.current = true;\n selectedRef.current = nextSelected;\n return nextSelected;\n };\n\n return useSyncExternalStore(store.subscribe, getSelection, getSelection);\n}\n","import type { SipSessionState } from \"../core/contracts/state\";\nimport { useSipSelector } from \"./useSipSelector\";\n\nexport function useSipSession(sessionId?: string): SipSessionState | null {\n return useSipSelector((state) => {\n if (!sessionId) return null;\n return state.sessions.find((session) => session.id === sessionId) ?? null;\n });\n}\n","import { useMemo } from \"react\";\nimport type { SipState } from \"../core/contracts/state\";\nimport { useSipSelector } from \"./useSipSelector\";\n\nexport function useSipSessions(): Pick<SipState, \"sessions\"> {\n const sessions = useSipSelector((state) => state.sessions);\n return useMemo(() => ({ sessions }), [sessions]);\n}\n","import { useEffect } from \"react\";\nimport type {\n SessionEventName,\n SessionEventPayload,\n UAEventName,\n UAEventPayload,\n} from \"../core/sip/types\";\nimport { useSipKernel } from \"./useSip\";\n\nexport function useSipEvent<K extends UAEventName>(\n event: K,\n handler?: (payload?: UAEventPayload<K>) => void\n) {\n const { events } = useSipKernel();\n\n useEffect(() => {\n if (!handler) return;\n return events.onUA(event, handler);\n }, [event, handler, events]);\n}\n\nexport function useSipSessionEvent<K extends SessionEventName>(\n sessionId: string,\n event: K,\n handler?: (payload?: SessionEventPayload<K>) => void\n) {\n const { events } = useSipKernel();\n\n useEffect(() => {\n if (!handler) return;\n return events.onSession(sessionId, event, handler);\n }, [event, handler, sessionId, events]);\n}\n","import { useEffect, useMemo, useState } from \"react\";\nimport { useSipKernel } from \"./useSip\";\nimport { useSipSelector } from \"./useSipSelector\";\nimport type { SessionMediaState } from \"../core/modules/media/types\";\nimport { CallStatus } from \"../core/contracts/state\";\n\nexport function useSessionMedia(sessionId?: string): SessionMediaState {\n const { media } = useSipKernel();\n const sessions = useSipSelector((state) => state.sessions);\n const [peerConnection, setPeerConnection] =\n useState<RTCPeerConnection | null>(null);\n const [remoteStream, setRemoteStream] = useState<MediaStream | null>(null);\n\n const resolvedSessionId = useMemo(() => {\n if (sessionId) return sessionId;\n const active = sessions.find((s) => s.status === CallStatus.Active);\n return active?.id ?? sessions[0]?.id;\n }, [sessionId, sessions]);\n\n const session = useMemo(\n () => (resolvedSessionId ? media.getSession(resolvedSessionId) : null),\n [media, resolvedSessionId]\n );\n const sessionState = useMemo(() => {\n if (!resolvedSessionId) return null;\n return sessions.find((s) => s.id === resolvedSessionId) ?? null;\n }, [sessions, resolvedSessionId]);\n\n useEffect(() => {\n if (!resolvedSessionId) {\n setPeerConnection(null);\n setRemoteStream(null);\n return;\n }\n\n const off = media.observePeerConnection(resolvedSessionId, (pc) => {\n setPeerConnection(pc);\n setRemoteStream(media.buildRemoteStream(pc));\n });\n return off;\n }, [media, resolvedSessionId]);\n\n useEffect(() => {\n if (!peerConnection) {\n setRemoteStream(null);\n return;\n }\n\n const update = () => {\n setRemoteStream(media.buildRemoteStream(peerConnection));\n };\n\n peerConnection.addEventListener(\"track\", update);\n peerConnection.addEventListener(\"connectionstatechange\", update);\n peerConnection.addEventListener(\"iceconnectionstatechange\", update);\n update();\n\n return () => {\n peerConnection.removeEventListener(\"track\", update);\n peerConnection.removeEventListener(\"connectionstatechange\", update);\n peerConnection.removeEventListener(\"iceconnectionstatechange\", update);\n };\n }, [media, peerConnection]);\n\n const tracks = remoteStream?.getTracks() ?? [];\n const audioTracks = tracks.filter((track) => track.kind === \"audio\");\n\n if (!sessionState) {\n return {\n sessionId: resolvedSessionId ?? \"\",\n session,\n peerConnection,\n remoteStream,\n audioTracks,\n };\n }\n\n return {\n sessionId: sessionState.id,\n session,\n peerConnection,\n remoteStream,\n audioTracks,\n };\n}\n","import { useEffect, useRef } from \"react\";\nimport { useSessionMedia } from \"../hooks/useSessionMedia\";\n\nexport function CallPlayer({ sessionId }: { sessionId?: string }) {\n const { remoteStream } = useSessionMedia(sessionId);\n const audioRef = useRef<HTMLAudioElement | null>(null);\n\n useEffect(() => {\n const audioEl = audioRef.current;\n if (!audioEl) return;\n audioEl.srcObject = remoteStream;\n audioEl.play?.().catch(() => {});\n return () => {\n audioEl.srcObject = null;\n };\n }, [remoteStream]);\n\n return <audio ref={audioRef} autoPlay playsInline />;\n}\n","import React, { useMemo } from \"react\";\nimport { SipContext } from \"../context\";\nimport type { SipKernel } from \"../core/kernel\";\n\nexport type SipProviderProps = {\n kernel: SipKernel;\n children: React.ReactNode;\n};\n\nexport function SipProvider(props: SipProviderProps) {\n const contextValue = useMemo(() => props.kernel, [props.kernel]);\n\n return (\n <SipContext.Provider value={contextValue}>\n {props.children}\n </SipContext.Provider>\n );\n}\n"]}