react-jssip-kit 0.7.0 → 0.7.2

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/jssip-lib/sip/debugger.ts","../src/jssip-lib/sip/userAgent.ts","../src/jssip-lib/core/types.ts","../src/jssip-lib/core/eventEmitter.ts","../src/jssip-lib/core/sipErrorHandler.ts","../src/jssip-lib/core/sipState.ts","../src/jssip-lib/core/sipStateStore.ts","../src/jssip-lib/sip/handlers/uaHandlers.ts","../src/jssip-lib/sip/sessionState.ts","../src/jssip-lib/sip/handlers/sessionHandlers.ts","../src/jssip-lib/sip/sessionController.ts","../src/jssip-lib/sip/sessionManager.ts","../src/jssip-lib/sip/sessionLifecycle.ts","../src/jssip-lib/sip/client.ts","../src/jssip-lib/index.ts","../src/context/index.tsx","../src/hooks/useSipState.ts","../src/hooks/useSip.ts","../src/hooks/useSipActions.ts","../src/hooks/useSipSessions.ts","../src/hooks/useSipEvent.ts","../src/components/call-player.tsx","../src/jssip-lib/adapters/dom/createCallPlayer.ts","../src/provider/index.tsx"],"names":["JsSIP","message","session","useEffect","useMemo","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\n/**\n * Browser-friendly debugger toggle for JsSIP.\n * Persists preference in sessionStorage and exposes helpers on window for console use.\n */\nexport class SipDebugger {\n private readonly storageKey: string;\n private readonly defaultPattern: string;\n private enabled = false;\n private logger: any;\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 this.logger = console;\n }\n // Persist pattern in sessionStorage only.\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","import JsSIP, { UA } from \"jssip\";\r\nimport { SipConfiguration, UAConfiguration } from \"./types\";\r\n\r\ntype StartOpts = { debug?: boolean | string };\r\n\r\nexport class SipUserAgent {\r\n private _ua: UA | null = null;\r\n\r\n public get ua(): UA | null {\r\n return this._ua;\r\n }\r\n public get isStarted(): boolean {\r\n return !!this._ua;\r\n }\r\n public get isRegistered(): boolean {\r\n return !!this._ua?.isRegistered();\r\n }\r\n\r\n public start(\r\n uri: string,\r\n password: string,\r\n config: Omit<SipConfiguration, \"debug\">,\r\n opts?: StartOpts\r\n ): UA {\r\n this.stop();\r\n const uaCfg = this.buildUAConfig(config, uri, password);\r\n this.ensureValid(uaCfg);\r\n this.applyDebug(opts?.debug);\r\n const ua = this.createUA(uaCfg);\r\n ua.start();\r\n this._ua = ua;\r\n return ua;\r\n }\r\n\r\n public register(): void {\r\n const ua = this.getUA();\r\n if (!ua?.isRegistered()) ua?.register();\r\n }\r\n\r\n public stop(): void {\r\n const ua = this._ua;\r\n if (!ua) return;\r\n try {\r\n if (ua.isRegistered()) ua.unregister();\r\n ua.stop();\r\n } finally {\r\n this._ua = null;\r\n }\r\n }\r\n\r\n public getUA(): UA | null {\r\n return this._ua;\r\n }\r\n\r\n public setDebug(debug?: boolean | string): void {\r\n this.applyDebug(debug);\r\n }\r\n\r\n protected buildUAConfig(\r\n config: Omit<SipConfiguration, \"debug\">,\r\n uri: string,\r\n password: string\r\n ): UAConfiguration {\r\n return { ...(config as UAConfiguration), uri, password };\r\n }\r\n\r\n protected ensureValid(cfg: UAConfiguration): void {\r\n const sockets = cfg.sockets as UAConfiguration[\"sockets\"];\r\n if (\r\n !cfg.uri ||\r\n !cfg.password ||\r\n !sockets ||\r\n (Array.isArray(sockets) && sockets.length === 0)\r\n ) {\r\n throw new Error(\r\n \"Invalid SIP connect args: require uri, password, and at least one socket\"\r\n );\r\n }\r\n }\r\n\r\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\r\n protected createUA(cfg: UAConfiguration): UA {\r\n return new JsSIP.UA(cfg);\r\n }\r\n\r\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 }\r\n\r\n private clearSessionFlag(): void {\r\n try {\r\n if (typeof window !== \"undefined\") {\r\n window.sessionStorage.removeItem(\"sip-debug-enabled\");\r\n }\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n}\r\n","import { Originator } from \"jssip/src/RTCSession\";\r\n\r\nexport const SipStatus = {\r\n Disconnected: \"disconnected\",\r\n Connecting: \"connecting\",\r\n Connected: \"connected\",\r\n Registered: \"registered\",\r\n Unregistered: \"unregistered\",\r\n RegistrationFailed: \"registrationFailed\",\r\n} as const;\r\n\r\nexport type SipStatus = (typeof SipStatus)[keyof typeof SipStatus];\r\n\r\nexport const CallStatus = {\r\n Idle: \"idle\",\r\n Dialing: \"dialing\",\r\n Ringing: \"ringing\",\r\n Active: \"active\",\r\n Hold: \"hold\",\r\n} as const;\r\nexport type CallStatus = (typeof CallStatus)[keyof typeof CallStatus];\r\n\r\nexport type CallDirection = Originator.LOCAL | Originator.REMOTE;\r\n\r\nexport type SipSessionState = {\r\n id: string;\r\n status: CallStatus;\r\n direction: CallDirection | null;\r\n from: string | null;\r\n to: string | null;\r\n muted: boolean;\r\n acceptedAt: number | null;\r\n mediaKind: \"audio\" | \"video\";\r\n remoteVideoEnabled: boolean;\r\n};\r\n\r\nexport interface SipState {\r\n sipStatus: SipStatus;\r\n error: string | null;\r\n sessions: SipSessionState[];\r\n}\r\n\r\nexport const SipStatusList = Object.values(SipStatus);\r\nexport const CallStatusList = Object.values(CallStatus);\r\n\r\nexport function isSipStatus(v: unknown): v is SipStatus {\r\n return (\r\n typeof v === \"string\" && (SipStatusList as readonly string[]).includes(v)\r\n );\r\n}\r\nexport function isCallStatus(v: unknown): v is CallStatus {\r\n return (\r\n typeof v === \"string\" && (CallStatusList as readonly string[]).includes(v)\r\n );\r\n}\r\n\r\nexport type Unsubscribe = () => void;\r\nexport type Listener<T> = (value: T) => void;\r\n","export type Listener<T = any> = (payload: T) => void;\r\n\r\nexport class EventTargetEmitter<Events extends Record<string, any> = any> {\r\n private target = new EventTarget();\r\n\r\n on<K extends keyof Events>(event: K, fn: Listener<Events[K]>): () => void {\r\n const wrapper = (e: Event) => fn((e as CustomEvent<Events[K]>).detail);\r\n this.target.addEventListener(event as string, wrapper);\r\n return () => this.target.removeEventListener(event as string, wrapper);\r\n }\r\n\r\n emit<K extends keyof Events>(event: K, payload?: Events[K]): void {\r\n this.target.dispatchEvent(\r\n new CustomEvent(event as string, { detail: payload })\r\n );\r\n }\r\n}\r\n","export interface SipErrorPayload {\r\n cause: string;\r\n code?: string;\r\n raw?: any;\r\n message?: string;\r\n}\r\n\r\nexport interface SipErrorFormatInput {\r\n raw: any;\r\n code?: string;\r\n fallback?: string;\r\n}\r\n\r\nexport type SipErrorFormatter = (\r\n input: SipErrorFormatInput\r\n) => SipErrorPayload | undefined;\r\n\r\ntype SipErrorHandlerOptions = {\r\n formatter?: SipErrorFormatter;\r\n messages?: Record<string, string>;\r\n};\r\n\r\nexport class SipErrorHandler {\r\n private readonly formatter?: SipErrorFormatter;\r\n private readonly messages?: Record<string, string>;\r\n\r\n constructor(options: SipErrorHandlerOptions = {}) {\r\n this.formatter = options.formatter;\r\n this.messages = options.messages;\r\n }\r\n\r\n format(input: SipErrorFormatInput): SipErrorPayload {\r\n const { code, raw, fallback } = input;\r\n const mappedMessage =\r\n code && this.messages ? this.messages[code] : undefined;\r\n\r\n // Allow consumer to fully customize formatting.\r\n if (this.formatter) {\r\n const custom = this.formatter({\r\n raw,\r\n code,\r\n fallback: mappedMessage ?? fallback,\r\n });\r\n const message =\r\n custom?.message ??\r\n custom?.cause ??\r\n mappedMessage ??\r\n fallback ??\r\n this.readRawMessage(raw) ??\r\n \"unknown error\";\r\n\r\n return {\r\n cause: custom?.cause ?? message,\r\n code: custom?.code ?? code,\r\n raw: custom?.raw ?? raw,\r\n message,\r\n };\r\n }\r\n\r\n const message =\r\n mappedMessage ?? this.readRawMessage(raw) ?? fallback ?? \"unknown error\";\r\n\r\n return {\r\n cause: message,\r\n code,\r\n raw,\r\n message,\r\n };\r\n }\r\n\r\n private readRawMessage(raw: any): string | undefined {\r\n if (raw == null) return undefined;\r\n if (typeof raw === \"string\") return raw;\r\n if (typeof raw?.cause === \"string\") return raw.cause;\r\n if (typeof raw?.message === \"string\") return raw.message;\r\n return undefined;\r\n }\r\n}\r\n","import { SipState, SipStatus } from \"./types\";\r\n\r\nexport function getInitialSipState(): SipState {\r\n return {\r\n sipStatus: SipStatus.Disconnected,\r\n error: null,\r\n sessions: [],\r\n };\r\n}\r\n\r\nexport function shallowEqual(objA: any, objB: any): boolean {\r\n if (objA === objB) return true;\r\n if (!objA || !objB) return false;\r\n const keysA = Object.keys(objA);\r\n const keysB = Object.keys(objB);\r\n if (keysA.length !== keysB.length) return false;\r\n for (const key of keysA) {\r\n if (objA[key] !== objB[key]) return false;\r\n }\r\n return true;\r\n}\r\n","import { SipState } from \"./types\";\r\nimport { getInitialSipState, shallowEqual } from \"./sipState\";\r\n\r\nexport type SipStateListener = (state: SipState) => void;\r\n\r\nexport class SipStateStore {\r\n private state: SipState = getInitialSipState();\r\n private lastState: SipState = getInitialSipState();\r\n private listeners = new Set<SipStateListener>();\r\n private pendingState: Partial<SipState> | null = null;\r\n private updateScheduled = false;\r\n\r\n getState(): SipState {\r\n return this.state;\r\n }\r\n\r\n onChange(fn: SipStateListener): () => void {\r\n this.listeners.add(fn);\r\n fn(this.state);\r\n return () => this.listeners.delete(fn);\r\n }\r\n\r\n subscribe(fn: SipStateListener): () => void {\r\n return this.onChange(fn);\r\n }\r\n\r\n setState(partial: Partial<SipState>) {\r\n if (!partial || Object.keys(partial).length === 0) return;\r\n const next = { ...this.state, ...partial };\r\n // Fast-path: if sessions reference unchanged and shallow contents equal, skip emit.\r\n if (next.sessions === this.lastState.sessions && shallowEqual(this.lastState, next)) {\r\n return;\r\n }\r\n this.state = next;\r\n this.lastState = next;\r\n this.emit();\r\n }\r\n\r\n batchSet(partial: Partial<SipState>) {\r\n this.pendingState = { ...this.pendingState, ...partial };\r\n if (!this.updateScheduled) {\r\n this.updateScheduled = true;\r\n queueMicrotask(() => {\r\n if (this.pendingState) this.setState(this.pendingState);\r\n this.pendingState = null;\r\n this.updateScheduled = false;\r\n });\r\n }\r\n }\r\n\r\n reset(overrides: Partial<SipState> = {}) {\r\n this.setState({ ...getInitialSipState(), ...overrides });\r\n }\r\n\r\n private emit() {\r\n for (const fn of this.listeners) fn(this.state);\r\n }\r\n}\r\n","import { UAEventMap } from \"../types\";\r\nimport { SipStatus } from \"../../core/types\";\r\nimport { SipStateStore } from \"../../core/sipStateStore\";\r\nimport { JsSIPEventMap } from \"../types\";\r\nimport { EventTargetEmitter } from \"../../core/eventEmitter\";\r\nimport { SipErrorPayload } from \"../../core/sipErrorHandler\";\r\n\r\ntype Deps = {\r\n emitter: EventTargetEmitter<JsSIPEventMap>;\r\n state: SipStateStore;\r\n cleanupAllSessions: () => void;\r\n emitError: (\r\n raw: any,\r\n code?: string,\r\n fallback?: string\r\n ) => SipErrorPayload;\r\n onNewRTCSession: UAEventMap[\"newRTCSession\"];\r\n};\r\n\r\nexport function createUAHandlers(deps: Deps): Partial<UAEventMap> {\r\n const { emitter, state, cleanupAllSessions, emitError, onNewRTCSession } =\r\n deps;\r\n\r\n return {\r\n connecting: (e: any) => {\r\n emitter.emit(\"connecting\", e);\r\n state.batchSet({ sipStatus: SipStatus.Connecting });\r\n },\r\n connected: (e: any) => {\r\n emitter.emit(\"connected\", e);\r\n state.batchSet({ sipStatus: SipStatus.Connected });\r\n },\r\n disconnected: (e: any) => {\r\n emitter.emit(\"disconnected\", e);\r\n cleanupAllSessions();\r\n state.reset();\r\n },\r\n\r\n registered: (e: any) => {\r\n emitter.emit(\"registered\", e);\r\n state.batchSet({ sipStatus: SipStatus.Registered, error: null });\r\n },\r\n unregistered: (e: any) => {\r\n emitter.emit(\"unregistered\", e);\r\n state.batchSet({ sipStatus: SipStatus.Unregistered });\r\n },\r\n registrationFailed: (e: any) => {\r\n emitter.emit(\"registrationFailed\", e);\r\n cleanupAllSessions();\r\n emitError(\r\n {\r\n raw: e,\r\n cause: e?.cause,\r\n statusCode: e?.response?.status_code,\r\n statusText: e?.response?.reason_phrase,\r\n },\r\n \"REGISTRATION_FAILED\",\r\n \"registration failed\"\r\n );\r\n state.batchSet({\r\n sipStatus: SipStatus.RegistrationFailed,\r\n error: e?.cause || \"registration failed\",\r\n });\r\n },\r\n newRTCSession: onNewRTCSession,\r\n newMessage: (e: any) => emitter.emit(\"newMessage\", e),\r\n sipEvent: (e: any) => emitter.emit(\"sipEvent\", e),\r\n newOptions: (e: any) => emitter.emit(\"newOptions\", e),\r\n };\r\n}\r\n","import { CallStatus, SipSessionState } from \"../core/types\";\r\nimport { SipStateStore } from \"../core/sipStateStore\";\r\n\r\nexport function holdOtherSessions(\r\n state: SipStateStore,\r\n sessionId: string,\r\n holdFn: (id: string) => void\r\n) {\r\n const current = state.getState();\r\n current.sessions.forEach((s) => {\r\n if (s.id === sessionId) return;\r\n if (s.status === CallStatus.Active) {\r\n holdFn(s.id);\r\n }\r\n });\r\n}\r\n\r\nexport function upsertSessionState(\r\n state: SipStateStore,\r\n sessionId: string,\r\n partial: Partial<SipSessionState>\r\n) {\r\n const current = state.getState();\r\n const existing = current.sessions.find((s) => s.id === sessionId);\r\n const base: SipSessionState = existing ?? {\r\n id: sessionId,\r\n status: CallStatus.Idle,\r\n direction: null,\r\n from: null,\r\n to: null,\r\n muted: false,\r\n acceptedAt: null,\r\n mediaKind: \"audio\",\r\n remoteVideoEnabled: false,\r\n };\r\n\r\n const nextSession = { ...base, ...partial };\r\n const sessions = existing\r\n ? current.sessions.map((s) => (s.id === sessionId ? nextSession : s))\r\n : [...current.sessions, nextSession];\r\n\r\n state.setState({ sessions });\r\n}\r\n\r\nexport function removeSessionState(state: SipStateStore, sessionId: string) {\r\n const current = state.getState();\r\n const sessions = current.sessions.filter((s) => s.id !== sessionId);\r\n state.setState({\r\n sessions,\r\n error: null,\r\n });\r\n}\r\n","import { EndEvent, RTCSessionEventMap } from \"../types\";\nimport { CallStatus } from \"../../core/types\";\nimport { SipStateStore } from \"../../core/sipStateStore\";\nimport { WebRTCSessionController } from \"../sessionController\";\nimport { JsSIPEventMap } from \"../types\";\nimport { EventTargetEmitter } from \"../../core/eventEmitter\";\nimport { SipErrorPayload } from \"../../core/sipErrorHandler\";\nimport { upsertSessionState } from \"../sessionState\";\nimport { IncomingAckEvent, IncomingEvent, OutgoingAckEvent, OutgoingEvent } from \"jssip/src/RTCSession\";\n\ntype Deps = {\n emitter: EventTargetEmitter<JsSIPEventMap>;\n state: SipStateStore;\n rtc: WebRTCSessionController;\n detachSessionHandlers: () => void;\n emitError: (raw: any, code?: string, fallback?: string) => SipErrorPayload;\n onSessionFailed: (error?: string, event?: any) => void;\n sessionId: string;\n};\n\nexport function createSessionHandlers(deps: Deps): Partial<RTCSessionEventMap> {\n const {\n emitter,\n state,\n rtc,\n detachSessionHandlers,\n onSessionFailed,\n sessionId,\n } = deps;\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 state.batchSet({\n sessions: state.getState().sessions.map((s) =>\n s.id === sessionId\n ? {\n ...s,\n status: CallStatus.Active,\n acceptedAt: s.acceptedAt ?? Date.now(),\n }\n : s\n ),\n });\n },\n confirmed: (e: IncomingAckEvent | OutgoingAckEvent) =>\n emitter.emit(\"confirmed\", e),\n\n ended: (e: EndEvent) => {\n emitter.emit(\"ended\", e);\n detachSessionHandlers();\n rtc.cleanup();\n const nextSessions = state\n .getState()\n .sessions.filter((s) => s.id !== sessionId);\n state.batchSet({\n sessions: nextSessions,\n });\n },\n failed: (e: EndEvent) => {\n emitter.emit(\"failed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n const cause = e?.cause || \"call failed\";\n onSessionFailed(cause, e);\n const nextSessions = state\n .getState()\n .sessions.filter((s) => s.id !== sessionId);\n state.batchSet({\n sessions: nextSessions,\n });\n },\n\n muted: () => {\n emitter.emit(\"muted\", undefined);\n upsertSessionState(state, sessionId, { muted: true });\n },\n unmuted: () => {\n emitter.emit(\"unmuted\", undefined);\n upsertSessionState(state, sessionId, { muted: false });\n },\n hold: () => {\n emitter.emit(\"hold\", undefined);\n upsertSessionState(state, sessionId, { status: CallStatus.Hold });\n },\n unhold: () => {\n emitter.emit(\"unhold\", undefined);\n upsertSessionState(state, sessionId, { status: CallStatus.Active });\n },\n\n reinvite: (e: any) => emitter.emit(\"reinvite\", e),\n update: (e: any) => emitter.emit(\"update\", e),\n sdp: (e: any) => emitter.emit(\"sdp\", e),\n icecandidate: (e: any) => emitter.emit(\"icecandidate\", e),\n refer: (e: any) => emitter.emit(\"refer\", e),\n replaces: (e: any) => emitter.emit(\"replaces\", e),\n newDTMF: (e: any) => emitter.emit(\"newDTMF\", e),\n newInfo: (e: any) => emitter.emit(\"newInfo\", e),\n\n getusermediafailed: (e: any) => {\n emitter.emit(\"getusermediafailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"getUserMedia failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:createofferfailed\": (e: any) => {\n emitter.emit(\"peerconnection:createofferfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection createOffer failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:createanswerfailed\": (e: any) => {\n emitter.emit(\"peerconnection:createanswerfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection createAnswer failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:setlocaldescriptionfailed\": (e: any) => {\n emitter.emit(\"peerconnection:setlocaldescriptionfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection setLocalDescription failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:setremotedescriptionfailed\": (e: any) => {\n emitter.emit(\"peerconnection:setremotedescriptionfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection setRemoteDescription failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n peerconnection: (e: any) => emitter.emit(\"peerconnection\", e),\n };\n}\n","import type {\r\n AnswerOptions,\r\n DTMFOptions,\r\n ReferOptions,\r\n RTCSession,\r\n TerminateOptions,\r\n} from \"./types\";\r\n\r\nexport class WebRTCSessionController {\r\n currentSession: RTCSession | null = null;\r\n mediaStream: MediaStream | null = null;\r\n\r\n public setSession(session: RTCSession | null) {\r\n this.currentSession = session;\r\n }\r\n\r\n public setMediaStream(stream: MediaStream) {\r\n this.mediaStream = stream;\r\n }\r\n\r\n private getPC(): RTCPeerConnection | null {\r\n return (this.currentSession as any)?.connection ?? null;\r\n }\r\n\r\n public cleanup(stopTracks: boolean = true): void {\r\n const pc = this.getPC();\r\n\r\n if (pc && typeof pc.getSenders === \"function\") {\r\n const isClosed =\r\n pc.connectionState === \"closed\" || pc.signalingState === \"closed\";\r\n if (!isClosed) {\r\n for (const s of pc.getSenders()) {\r\n try {\r\n s.replaceTrack(null);\r\n } catch {\r\n // ignore if sender/pc already closed\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (stopTracks && this.mediaStream) {\r\n for (const t of this.mediaStream.getTracks()) t.stop();\r\n }\r\n\r\n this.mediaStream = null;\r\n this.currentSession = null;\r\n }\r\n\r\n public answer(options: AnswerOptions = {}): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.answer(options), true)\r\n : false;\r\n }\r\n\r\n public hangup(options?: TerminateOptions): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.terminate(\r\n options ?? ({ status_code: 486, reason_phrase: \"Busy Here\" } as any)\r\n ),\r\n true)\r\n : false;\r\n }\r\n\r\n public mute(): boolean {\r\n this.mediaStream?.getAudioTracks().forEach((t) => (t.enabled = false));\r\n return this.currentSession\r\n ? (this.currentSession.mute({ audio: true }), true)\r\n : false;\r\n }\r\n\r\n public unmute(): boolean {\r\n this.mediaStream?.getAudioTracks().forEach((t) => (t.enabled = true));\r\n return this.currentSession\r\n ? (this.currentSession.unmute({ audio: true }), true)\r\n : false;\r\n }\r\n\r\n public hold(): boolean {\r\n return this.currentSession ? (this.currentSession.hold(), true) : false;\r\n }\r\n\r\n public unhold(): boolean {\r\n return this.currentSession ? (this.currentSession.unhold(), true) : false;\r\n }\r\n\r\n public sendDTMF(tones: string | number, options?: DTMFOptions): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.sendDTMF(tones, options), true)\r\n : false;\r\n }\r\n\r\n public transfer(target: string, options?: ReferOptions): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.refer(target as any, options), true)\r\n : false;\r\n }\r\n\r\n public enableVideo(): void {\r\n this.mediaStream?.getVideoTracks().forEach((t) => (t.enabled = true));\r\n }\r\n\r\n public disableVideo(): void {\r\n this.mediaStream?.getVideoTracks().forEach((t) => (t.enabled = false));\r\n }\r\n\r\n public async switchCamera(\n nextVideoTrack: MediaStreamTrack\n ): Promise<boolean> {\n const pc = this.getPC();\r\n if (!pc) return false;\r\n\r\n if (!this.mediaStream) this.mediaStream = new MediaStream();\r\n\r\n const old = this.mediaStream.getVideoTracks()[0];\r\n this.mediaStream.addTrack(nextVideoTrack);\r\n if (old) this.mediaStream.removeTrack(old);\r\n\r\n const sender = pc.getSenders?.().find((s) => s.track?.kind === \"video\");\r\n if (sender) await sender.replaceTrack(nextVideoTrack);\r\n\r\n if (old && old !== nextVideoTrack) old.stop();\r\n\r\n return true;\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((s) => s.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 \"./sessionController\";\r\nimport type { RTCSession } from \"./types\";\r\n\r\ntype SessionEntry = {\r\n rtc: WebRTCSessionController;\r\n session?: RTCSession | null;\r\n media?: MediaStream | null;\r\n};\r\n\r\nexport class SessionManager {\r\n private entries = new Map<string, SessionEntry>();\r\n private pendingMediaQueue: Array<{ stream: MediaStream; addedAt: number }> =\r\n [];\r\n private pendingMediaTtlMs = 30000;\r\n\r\n setPendingMediaTtl(ms: number | undefined) {\r\n if (typeof ms === \"number\" && ms > 0) this.pendingMediaTtlMs = ms;\r\n }\r\n\r\n enqueueOutgoingMedia(stream: MediaStream) {\r\n this.pendingMediaQueue.push({ stream, addedAt: Date.now() });\r\n }\r\n\r\n dequeueOutgoingMedia(): MediaStream | null {\r\n const now = Date.now();\r\n while (this.pendingMediaQueue.length) {\r\n const next = this.pendingMediaQueue.shift();\r\n if (!next) break;\r\n if (now - next.addedAt <= this.pendingMediaTtlMs) {\r\n return next.stream;\r\n } else {\r\n // drop stale stream\r\n next.stream.getTracks().forEach((t) => t.stop());\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n getOrCreateRtc(sessionId: string, session?: RTCSession) {\r\n let entry = this.entries.get(sessionId);\r\n if (!entry) {\r\n entry = {\r\n rtc: new WebRTCSessionController(),\r\n session: null,\r\n media: null,\r\n };\r\n this.entries.set(sessionId, entry);\r\n }\r\n if (session) {\r\n entry.session = session;\r\n entry.rtc.setSession(session);\r\n }\r\n if (entry.media) entry.rtc.setMediaStream(entry.media);\r\n return entry.rtc;\r\n }\r\n\r\n getRtc(sessionId: string) {\r\n return this.entries.get(sessionId)?.rtc ?? null;\r\n }\r\n\r\n setSession(sessionId: string, session: RTCSession) {\r\n const entry = this.entries.get(sessionId);\r\n if (entry) {\r\n entry.session = session;\r\n entry.rtc.setSession(session);\r\n } else {\r\n this.entries.set(sessionId, {\r\n rtc: new WebRTCSessionController(),\r\n session,\r\n media: null,\r\n });\r\n }\r\n }\r\n\r\n setSessionMedia(sessionId: string, stream: MediaStream) {\r\n const entry = this.entries.get(sessionId) ?? {\r\n rtc: new WebRTCSessionController(),\r\n session: null,\r\n media: null,\r\n };\r\n entry.media = stream;\r\n entry.rtc.setMediaStream(stream);\r\n this.entries.set(sessionId, entry);\r\n }\r\n\r\n getSession(sessionId: string) {\r\n return this.entries.get(sessionId)?.session ?? null;\r\n }\r\n\r\n getSessionIds() {\r\n return Array.from(this.entries.keys());\r\n }\r\n\r\n getSessions() {\r\n return Array.from(this.entries.entries()).map(([id, entry]) => ({\r\n id,\r\n session: entry.session as RTCSession,\r\n }));\r\n }\r\n\r\n getActiveSessionId(activeStatuses: string[] = [\"active\"]): string | null {\r\n for (const [id, entry] of Array.from(this.entries.entries()).reverse()) {\r\n const status = (entry.session as any)?.status;\r\n if (status && activeStatuses.includes(String(status).toLowerCase())) {\r\n return id;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n cleanupSession(sessionId: string) {\r\n const entry = this.entries.get(sessionId);\r\n if (entry) {\r\n entry.rtc.cleanup();\r\n this.entries.delete(sessionId);\r\n }\r\n }\r\n\r\n cleanupAllSessions() {\r\n for (const [, entry] of this.entries.entries()) {\r\n entry.rtc.cleanup();\r\n }\r\n this.entries.clear();\r\n this.pendingMediaQueue = [];\r\n }\r\n\r\n answer(sessionId: string, options: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.answer(options) : false;\r\n }\r\n\r\n hangup(sessionId: string, options?: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.hangup(options) : false;\r\n }\r\n\r\n mute(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.mute() : false;\r\n }\r\n\r\n unmute(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.unmute() : false;\r\n }\r\n\r\n hold(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.hold() : false;\r\n }\r\n\r\n unhold(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.unhold() : false;\r\n }\r\n\r\n sendDTMF(sessionId: string, tones: string | number, options?: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.sendDTMF(tones, options) : false;\r\n }\r\n\r\n transfer(sessionId: string, target: string, options?: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.transfer(target, options) : false;\r\n }\r\n}\r\n","import { SipStateStore } from \"../core/sipStateStore\";\r\nimport { CallDirection, CallStatus } from \"../core/types\";\r\nimport { SessionManager } from \"./sessionManager\";\r\nimport { holdOtherSessions, upsertSessionState } from \"./sessionState\";\r\nimport type { JsSIPEventName, RTCSession, RTCSessionEvent } from \"./types\";\r\nimport type { SipErrorPayload } from \"../core/sipErrorHandler\";\r\n\r\ntype Deps = {\r\n state: SipStateStore;\r\n sessionManager: SessionManager;\r\n emit: <K extends JsSIPEventName>(event: K, payload: any) => void;\r\n emitError: (raw: any, code?: string, fallback?: string) => SipErrorPayload;\r\n attachSessionHandlers: (sessionId: string, session: RTCSession) => void;\r\n getMaxSessionCount: () => number;\r\n};\r\n\r\nexport class SessionLifecycle {\r\n private readonly state: SipStateStore;\r\n private readonly sessionManager: SessionManager;\r\n private readonly emit: Deps[\"emit\"];\r\n private readonly emitError: Deps[\"emitError\"];\r\n private readonly attachSessionHandlers: Deps[\"attachSessionHandlers\"];\r\n private readonly getMaxSessionCount: Deps[\"getMaxSessionCount\"];\r\n\r\n constructor(deps: Deps) {\r\n this.state = deps.state;\r\n this.sessionManager = deps.sessionManager;\r\n this.emit = deps.emit;\r\n this.emitError = deps.emitError;\r\n this.attachSessionHandlers = deps.attachSessionHandlers;\r\n this.getMaxSessionCount = deps.getMaxSessionCount;\r\n }\r\n\r\n handleNewRTCSession(e: RTCSessionEvent) {\r\n const session = e.session;\r\n const sessionId = String((session as any)?.id ?? crypto.randomUUID?.() ?? Date.now());\r\n\r\n const currentSessions = this.state.getState().sessions;\r\n if (currentSessions.length >= this.getMaxSessionCount()) {\r\n try {\r\n session.terminate?.({ status_code: 486, reason_phrase: \"Busy Here\" } as any);\r\n } catch {\r\n /* ignore termination errors */\r\n }\r\n if (e.originator === \"remote\") {\r\n this.emit(\"missed\", e);\r\n }\r\n this.emitError(\"max session count reached\", \"MAX_SESSIONS_REACHED\", \"max session count reached\");\r\n return;\r\n }\r\n\r\n const outgoingMedia = e.originator === \"local\" ? this.sessionManager.dequeueOutgoingMedia() : null;\r\n\r\n if (outgoingMedia) this.sessionManager.setSessionMedia(sessionId, outgoingMedia);\r\n\r\n const rtc = this.sessionManager.getOrCreateRtc(sessionId, session);\r\n if (outgoingMedia) rtc.setMediaStream(outgoingMedia);\r\n\r\n this.sessionManager.setSession(sessionId, session);\r\n this.attachSessionHandlers(sessionId, session);\r\n\r\n holdOtherSessions(\r\n this.state,\r\n sessionId,\r\n (id) => {\r\n const otherRtc = this.sessionManager.getRtc(id);\r\n otherRtc?.hold();\r\n }\r\n );\r\n\r\n const sdpHasVideo =\r\n (e.request?.body && e.request.body.toString().includes(\"m=video\")) ||\r\n (session as RTCSession & { connection?: RTCPeerConnection })?.connection\r\n ?.getReceivers?.()\r\n ?.some((r: RTCRtpReceiver) => r.track?.kind === \"video\");\r\n\r\n upsertSessionState(this.state, sessionId, {\r\n direction: e.originator,\r\n from: e.originator === \"remote\" ? e.request.from.uri.user : null,\r\n to: e.request.to.uri.user,\r\n status: e.originator === \"remote\" ? CallStatus.Ringing : CallStatus.Dialing,\r\n mediaKind: sdpHasVideo ? \"video\" : \"audio\",\r\n remoteVideoEnabled: sdpHasVideo,\r\n });\r\n\r\n this.emit(\"newRTCSession\", e);\r\n }\r\n}\r\n","import { SipUserAgent } from \"./userAgent\";\r\nimport {\r\n AnswerOptions,\r\n CallOptions,\r\n DTMFOptions,\r\n JsSIPEventMap,\r\n ReferOptions,\r\n RTCSession,\r\n RTCSessionEvent,\r\n RTCSessionEventMap,\r\n SipConfiguration,\r\n SipEventManager,\r\n TerminateOptions,\r\n UAEventMap,\r\n} from \"./types\";\r\n\r\nimport { SipState, SipStatus, CallStatus } from \"../core/types\";\r\nimport { EventTargetEmitter } from \"../core/eventEmitter\";\r\nimport {\r\n SipErrorHandler,\r\n SipErrorFormatter,\r\n SipErrorPayload,\r\n} from \"../core/sipErrorHandler\";\r\nimport { SipStateStore } from \"../core/sipStateStore\";\r\nimport { createUAHandlers } from \"./handlers/uaHandlers\";\r\nimport { createSessionHandlers } from \"./handlers/sessionHandlers\";\r\nimport { SessionManager } from \"./sessionManager\";\r\nimport { removeSessionState } from \"./sessionState\";\r\nimport { SessionLifecycle } from \"./sessionLifecycle\";\r\n\r\ntype SipClientOptions = {\r\n errorMessages?: Record<string, string>;\r\n formatError?: SipErrorFormatter;\r\n errorHandler?: SipErrorHandler;\r\n debug?: boolean | string;\r\n};\r\n\r\nexport type MicrophoneRecoveryOptions = {\n intervalMs?: number;\n maxRetries?: number;\n};\n\r\nconst SESSION_DEBUG_KEY = \"sip-debug-enabled\";\r\n\r\nexport class SipClient extends EventTargetEmitter<JsSIPEventMap> {\r\n public readonly userAgent = new SipUserAgent();\r\n public readonly stateStore = new SipStateStore();\r\n\r\n private readonly uaHandlers: Partial<UAEventMap>;\r\n private readonly uaHandlerKeys: (keyof UAEventMap)[];\r\n private sessionHandlers = new Map<string, Partial<RTCSessionEventMap>>();\r\n private readonly errorHandler: SipErrorHandler;\r\n private debugPattern?: boolean | string;\r\n private maxSessionCount = Infinity;\r\n private sessionManager = new SessionManager();\n private lifecycle: SessionLifecycle;\n private micRecovery = new Map<string, { stop: () => void }>();\n private requestMicrophoneStream?: () => Promise<MediaStream>;\n private micRecoveryEnabled = false;\n private micRecoveryDefaults: Required<MicrophoneRecoveryOptions> = {\n intervalMs: 2000,\n maxRetries: Infinity,\n };\n private unloadHandler?: () => void;\r\n private stateLogOff?: () => void;\r\n\r\n public get state(): SipState {\r\n return this.stateStore.getState();\r\n }\r\n\r\n constructor(options: SipClientOptions = {}) {\r\n super();\r\n\r\n this.errorHandler =\r\n options.errorHandler ??\r\n new SipErrorHandler({\r\n formatter: options.formatError,\r\n messages: options.errorMessages,\r\n });\r\n this.debugPattern = options.debug;\r\n\r\n this.uaHandlers = createUAHandlers({\r\n emitter: this,\r\n state: this.stateStore,\r\n cleanupAllSessions: () => this.cleanupAllSessions(),\r\n emitError: (raw, code, fallback) => this.emitError(raw, code, fallback),\r\n onNewRTCSession: (e: RTCSessionEvent) => this.onNewRTCSession(e),\r\n });\r\n this.uaHandlerKeys = Object.keys(this.uaHandlers) as (keyof UAEventMap)[];\r\n this.lifecycle = new SessionLifecycle({\r\n state: this.stateStore,\r\n sessionManager: this.sessionManager,\r\n emit: (event, payload) => this.emit(event as any, payload as any),\r\n emitError: (raw, code, fallback) => this.emitError(raw, code, fallback),\r\n attachSessionHandlers: (sessionId, session) =>\r\n this.attachSessionHandlers(sessionId, session),\r\n getMaxSessionCount: () => this.maxSessionCount,\r\n });\r\n\r\n if (typeof window !== \"undefined\") {\r\n // Let window.sipSupport trigger client debug toggles.\r\n (window as any).sipDebugBridge = (debug?: boolean | string) =>\r\n this.setDebug(debug ?? true);\r\n }\r\n }\r\n\r\n public connect(uri: string, password: string, config: SipConfiguration) {\r\n this.disconnect();\r\n this.stateStore.setState({ sipStatus: SipStatus.Connecting });\r\n const {\n debug: cfgDebug,\n enableMicRecovery,\n micRecoveryIntervalMs,\n micRecoveryMaxRetries,\n maxSessionCount,\n pendingMediaTtlMs,\n ...uaCfg\n } = config;\n this.maxSessionCount =\n typeof maxSessionCount === \"number\" ? maxSessionCount : Infinity;\n this.micRecoveryEnabled = Boolean(enableMicRecovery);\n if (typeof micRecoveryIntervalMs === \"number\") {\n this.micRecoveryDefaults.intervalMs = micRecoveryIntervalMs;\n }\n if (typeof micRecoveryMaxRetries === \"number\") {\n this.micRecoveryDefaults.maxRetries = micRecoveryMaxRetries;\n }\n this.sessionManager.setPendingMediaTtl(pendingMediaTtlMs);\n // Config debug has priority, then persisted session flag, then prior setting.\r\n const debug = cfgDebug ?? this.getPersistedDebug() ?? this.debugPattern;\r\n this.userAgent.start(uri, password, uaCfg, { debug });\r\n this.attachUAHandlers();\r\n this.attachBeforeUnload();\r\n this.syncDebugInspector(debug);\r\n }\r\n\r\n public setMicrophoneProvider(fn?: () => Promise<MediaStream>) {\n this.requestMicrophoneStream = fn;\n if (fn && this.micRecoveryEnabled) {\n this.sessionManager.getSessions().forEach(({ id }) => {\n this.enableMicrophoneRecovery(id);\n });\n }\n }\n\r\n public registerUA() {\r\n this.userAgent.register();\r\n }\r\n\r\n public disconnect() {\r\n this.detachBeforeUnload();\r\n this.detachUAHandlers();\r\n this.userAgent.stop();\r\n this.cleanupAllSessions();\r\n this.stateStore.reset();\r\n }\r\n\r\n public call(target: string, callOptions: CallOptions = {}) {\r\n if (!callOptions.mediaStream && this.requestMicrophoneStream) {\r\n void this.requestMicrophoneStream()\r\n .then((stream) => {\r\n if (!stream) throw new Error(\"microphone stream unavailable\");\r\n this.call(target, { ...callOptions, mediaStream: stream });\r\n })\r\n .catch((e: unknown) => {\r\n const err = this.emitError(\r\n e,\r\n \"MICROPHONE_FAILED\",\r\n \"microphone failed\"\r\n );\r\n this.stateStore.batchSet({ error: err.cause });\r\n });\r\n return;\r\n }\r\n try {\r\n const opts = this.ensureMediaConstraints(callOptions);\r\n if (opts.mediaStream)\r\n this.sessionManager.enqueueOutgoingMedia(opts.mediaStream);\r\n\r\n const ua = this.userAgent.getUA();\r\n ua?.call(target, opts);\r\n } catch (e: unknown) {\r\n const err = this.emitError(e, \"CALL_FAILED\", \"call failed\");\r\n this.cleanupAllSessions();\r\n this.stateStore.batchSet({\r\n error: err.cause,\r\n });\r\n }\r\n }\r\n\r\n public answer(sessionId: string, options: AnswerOptions = {}) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n return this.answerSession(resolved, options);\r\n }\r\n public hangup(sessionId: string, options?: TerminateOptions) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n return this.hangupSession(resolved, options);\r\n }\r\n\r\n public hangupAll(options?: TerminateOptions) {\r\n const ids = this.getSessionIds();\r\n ids.forEach((id) => this.hangupSession(id, options));\r\n return ids.length > 0;\r\n }\r\n\r\n public toggleMute(sessionId: string) {\r\n return this.toggleMuteSession(sessionId);\r\n }\r\n public toggleHold(sessionId: string) {\r\n return this.toggleHoldSession(sessionId);\r\n }\r\n public sendDTMF(\r\n sessionId: string,\r\n tones: string | number,\r\n options?: DTMFOptions\r\n ) {\r\n return this.sendDTMFSession(sessionId, tones, options);\r\n }\r\n public transfer(sessionId: string, target: string, options?: ReferOptions) {\r\n return this.transferSession(sessionId, target, options);\r\n }\r\n\r\n public onChange(fn: (s: SipState) => void) {\r\n return this.stateStore.onChange(fn);\r\n }\r\n\r\n private attachUAHandlers() {\r\n const ua = this.userAgent.ua;\r\n if (!ua) return;\r\n\r\n this.detachUAHandlers();\r\n this.uaHandlerKeys.forEach((ev) => {\r\n const h = this.uaHandlers[ev];\r\n if (h) ua.on(ev, h as any);\r\n });\r\n }\r\n\r\n public setDebug(debug?: boolean | string) {\r\n this.debugPattern = debug;\r\n this.userAgent.setDebug(debug);\r\n this.syncDebugInspector(debug);\r\n }\r\n\r\n private attachSessionHandlers(sessionId: string, session: RTCSession) {\r\n const handlers = this.createSessionHandlersFor(sessionId, session);\r\n this.sessionHandlers.set(sessionId, handlers);\r\n\r\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\r\n const h = handlers[ev];\r\n if (h) session.on(ev, h as any);\r\n });\r\n if (this.requestMicrophoneStream && this.micRecoveryEnabled) {\n this.enableMicrophoneRecovery(sessionId);\n }\n }\r\n\r\n private detachSessionHandlers(sessionId: string, session: RTCSession) {\r\n const handlers = this.sessionHandlers.get(sessionId);\r\n if (!handlers || !session) return;\r\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\r\n const h = handlers[ev];\r\n if (h) session.off(ev, h as any);\r\n });\r\n this.sessionHandlers.delete(sessionId);\r\n }\r\n\r\n private detachUAHandlers() {\r\n const ua = this.userAgent.ua;\r\n if (!ua) return;\r\n this.uaHandlerKeys.forEach((ev) => {\r\n const h = this.uaHandlers[ev];\r\n if (h) ua.off(ev, h as any);\r\n });\r\n }\r\n\r\n private cleanupSession(sessionId: string, session?: RTCSession) {\r\n const targetSession =\r\n session ??\r\n this.sessionManager.getSession(sessionId) ??\r\n this.sessionManager.getRtc(sessionId)?.currentSession;\r\n this.detachSessionHandlers(sessionId, targetSession as any);\r\n this.disableMicrophoneRecovery(sessionId);\r\n this.sessionManager.cleanupSession(sessionId);\r\n removeSessionState(this.stateStore, sessionId);\r\n }\r\n\r\n private cleanupAllSessions() {\r\n this.sessionManager.cleanupAllSessions();\r\n this.micRecovery.forEach((entry) => entry.stop());\r\n this.micRecovery.clear();\r\n this.sessionHandlers.clear();\r\n this.stateStore.setState({\r\n sessions: [],\r\n error: null,\r\n });\r\n }\r\n\r\n private createSessionHandlersFor(\r\n sessionId: string,\r\n session: RTCSession\r\n ): Partial<RTCSessionEventMap> {\r\n const rtc = this.sessionManager.getOrCreateRtc(sessionId, session);\r\n return createSessionHandlers({\r\n emitter: this,\r\n state: this.stateStore,\r\n rtc,\r\n detachSessionHandlers: () => this.cleanupSession(sessionId, session),\r\n emitError: (raw, code, fallback) => this.emitError(raw, code, fallback),\r\n onSessionFailed: (err?: string, event?: RTCSessionEvent) =>\r\n this.onSessionFailed(err, event),\r\n sessionId,\r\n });\r\n }\r\n\r\n protected onNewRTCSession(e: RTCSessionEvent) {\r\n this.lifecycle.handleNewRTCSession(e);\r\n }\r\n\r\n protected onSessionFailed(error?: string, event?: RTCSessionEvent) {\r\n const rawCause = (event as any)?.cause ?? error;\r\n const statusCode = (event as any)?.message?.status_code;\r\n const statusText = (event as any)?.message?.reason_phrase;\r\n const causeText =\r\n rawCause ||\r\n (statusCode\r\n ? `${statusCode}${statusText ? \" \" + statusText : \"\"}`\r\n : \"call failed\");\r\n this.emitError(\r\n { raw: event, cause: rawCause, statusCode, statusText },\r\n \"SESSION_FAILED\",\r\n causeText\r\n );\r\n }\r\n\r\n private emitError(\r\n raw: unknown,\r\n code?: string,\r\n fallback?: string\r\n ): SipErrorPayload {\r\n const payload = this.errorHandler.format({ raw, code, fallback });\r\n this.emit(\"error\", payload);\r\n return payload;\r\n }\r\n\r\n private resolveSessionId(sessionId?: string) {\r\n if (sessionId) return sessionId;\r\n const sessions = this.stateStore.getState().sessions;\r\n const active = sessions.find((s) => s.status === CallStatus.Active);\r\n return active?.id ?? sessions[0]?.id ?? null;\r\n }\r\n\r\n private sessionExists(sessionId: string) {\r\n return (\r\n !!this.sessionManager.getSession(sessionId) ||\r\n !!this.sessionManager.getRtc(sessionId)\r\n );\r\n }\r\n\r\n private resolveExistingSessionId(sessionId?: string) {\r\n const id = this.resolveSessionId(sessionId);\r\n if (!id) return null;\r\n return this.sessionExists(id) ? id : null;\r\n }\r\n\r\n private ensureMediaConstraints<\r\n T extends {\r\n mediaStream?: MediaStream;\r\n mediaConstraints?: MediaStreamConstraints;\r\n }\r\n >(opts: T): T {\r\n if (opts.mediaStream || opts.mediaConstraints) return opts;\r\n return { ...opts, mediaConstraints: { audio: true, video: false } } as T;\r\n }\r\n\r\n public answerSession(sessionId: string, options: AnswerOptions = {}) {\r\n if (!sessionId || !this.sessionExists(sessionId)) return false;\r\n if (!options.mediaStream && this.requestMicrophoneStream) {\r\n void this.requestMicrophoneStream()\r\n .then((stream) => {\r\n if (!stream) throw new Error(\"microphone stream unavailable\");\r\n this.answerSession(sessionId, { ...options, mediaStream: stream });\r\n })\r\n .catch((e: unknown) => {\r\n const err = this.emitError(\r\n e,\r\n \"MICROPHONE_FAILED\",\r\n \"microphone failed\"\r\n );\r\n this.stateStore.batchSet({ error: err.cause });\r\n });\r\n return true;\r\n }\r\n const opts = this.ensureMediaConstraints(options);\r\n return this.sessionManager.answer(sessionId, opts);\r\n }\r\n\r\n public hangupSession(sessionId: string, options?: TerminateOptions) {\r\n if (!sessionId || !this.sessionExists(sessionId)) return false;\r\n return this.sessionManager.hangup(sessionId, options);\r\n }\r\n\r\n public toggleMuteSession(sessionId?: string) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n const muted = sessionState?.muted ?? false;\r\n if (muted) {\r\n this.sessionManager.unmute(resolved);\r\n return true;\r\n }\r\n this.sessionManager.mute(resolved);\r\n return true;\r\n }\r\n\r\n public toggleHoldSession(sessionId?: string) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n const isOnHold = sessionState?.status === CallStatus.Hold;\r\n if (isOnHold) {\r\n this.sessionManager.unhold(resolved);\r\n return true;\r\n }\r\n if (sessionState?.status === CallStatus.Active) {\r\n this.sessionManager.hold(resolved);\r\n return true;\r\n }\r\n return true;\r\n }\r\n\r\n public sendDTMFSession(\r\n sessionId: string,\r\n tones: string | number,\r\n options?: DTMFOptions\r\n ) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n if (sessionState?.status === CallStatus.Active)\r\n this.sessionManager.sendDTMF(resolved, tones, options);\r\n return true;\r\n }\r\n\r\n public transferSession(\r\n sessionId: string,\r\n target: string,\r\n options?: ReferOptions\r\n ) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n if (sessionState?.status === CallStatus.Active)\r\n this.sessionManager.transfer(resolved, target, options);\r\n return true;\r\n }\r\n\r\n public setSessionMedia(sessionId: string, stream: MediaStream) {\r\n this.sessionManager.setSessionMedia(sessionId, stream);\r\n }\r\n\r\n public enableMicrophoneRecovery(\n sessionId: string,\n options: MicrophoneRecoveryOptions = {}\n ) {\n const resolved = this.resolveExistingSessionId(sessionId);\n if (!resolved) return () => {};\n if (!this.requestMicrophoneStream) return () => {};\n\n this.disableMicrophoneRecovery(resolved);\n\n const intervalMs =\n options.intervalMs ?? this.micRecoveryDefaults.intervalMs;\n const maxRetries = options.maxRetries ?? this.micRecoveryDefaults.maxRetries;\n let retries = 0;\n let stopped = false;\n\r\n const tick = async () => {\r\n if (stopped || retries >= maxRetries) return;\r\n\r\n const rtc = this.sessionManager.getRtc(resolved);\r\n const session = this.sessionManager.getSession(resolved);\r\n if (!rtc || !session) return;\r\n\r\n const sessionState = this.stateStore\n .getState()\n .sessions.find((s) => s.id === resolved);\n if (sessionState?.muted) return;\n\r\n const stream = rtc.mediaStream;\r\n const track = stream?.getAudioTracks?.()[0];\r\n const sender = (session as any)?.connection\r\n ?.getSenders?.()\r\n .find((s: RTCRtpSender) => s.track?.kind === \"audio\");\r\n\r\n const trackLive = track?.readyState === \"live\";\r\n const senderLive = sender?.track?.readyState === \"live\";\r\n if (trackLive && senderLive) return;\r\n\r\n retries += 1;\r\n let nextStream: MediaStream;\r\n try {\r\n if (!this.requestMicrophoneStream) return;\r\n nextStream = await this.requestMicrophoneStream();\r\n } catch (err) {\r\n console.warn(\"[sip] mic recovery failed to get stream\", err);\r\n return;\r\n }\r\n const nextTrack = nextStream.getAudioTracks()[0];\r\n if (!nextTrack) return;\r\n\r\n await rtc.replaceAudioTrack(nextTrack);\r\n this.sessionManager.setSessionMedia(resolved, nextStream);\r\n };\r\n\r\n const timer = setInterval(() => {\r\n void tick();\r\n }, intervalMs);\r\n void tick();\r\n\r\n const session = this.sessionManager.getSession(resolved);\r\n const pc: RTCPeerConnection | undefined = (session as any)?.connection;\r\n const onIceChange = () => {\r\n const state = pc?.iceConnectionState;\r\n if (state === \"failed\" || state === \"disconnected\") void tick();\r\n };\r\n pc?.addEventListener?.(\"iceconnectionstatechange\", onIceChange);\r\n\r\n const stop = () => {\r\n stopped = true;\r\n clearInterval(timer);\r\n pc?.removeEventListener?.(\"iceconnectionstatechange\", onIceChange);\r\n };\r\n this.micRecovery.set(resolved, { stop });\r\n return stop;\r\n }\r\n\r\n public disableMicrophoneRecovery(sessionId: string) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const entry = this.micRecovery.get(resolved);\r\n if (!entry) return false;\r\n entry.stop();\r\n this.micRecovery.delete(resolved);\r\n return true;\r\n }\r\n\r\n public switchCameraSession(sessionId: string, track: MediaStreamTrack) {\r\n if (!this.sessionExists(sessionId)) return false;\r\n const rtc = this.sessionManager.getRtc(sessionId);\r\n return rtc ? rtc.switchCamera(track) : false;\r\n }\r\n\r\n public enableVideoSession(sessionId: string) {\r\n if (!this.sessionExists(sessionId)) return false;\r\n const rtc = this.sessionManager.getRtc(sessionId);\r\n rtc?.enableVideo();\r\n return !!rtc;\r\n }\r\n\r\n public disableVideoSession(sessionId: string) {\r\n if (!this.sessionExists(sessionId)) return false;\r\n const rtc = this.sessionManager.getRtc(sessionId);\r\n rtc?.disableVideo();\r\n return !!rtc;\r\n }\r\n\r\n public getSession(sessionId: string) {\r\n return this.sessionManager.getSession(sessionId);\r\n }\r\n\r\n public getSessionIds() {\r\n return this.sessionManager.getSessionIds();\r\n }\r\n\r\n public getSessions() {\r\n return this.sessionManager.getSessions();\r\n }\r\n\r\n private attachBeforeUnload() {\r\n if (typeof window === \"undefined\" || this.unloadHandler) return;\r\n\r\n const handler = () => {\r\n this.hangupAll();\r\n this.disconnect();\r\n };\r\n\r\n window.addEventListener(\"beforeunload\", handler);\r\n this.unloadHandler = handler;\r\n }\r\n\r\n private detachBeforeUnload() {\r\n if (typeof window === \"undefined\" || !this.unloadHandler) return;\r\n window.removeEventListener(\"beforeunload\", this.unloadHandler);\r\n this.unloadHandler = undefined;\r\n }\r\n\r\n private syncDebugInspector(debug?: boolean | string) {\r\n if (typeof window === \"undefined\") return;\r\n this.toggleStateLogger(Boolean(debug));\r\n\r\n const win = window as any;\r\n const disabledInspector = () => {\r\n console.warn(\"SIP debug inspector disabled; enable debug to inspect.\");\r\n return null;\r\n };\r\n win.sipState = () =>\r\n debug ? this.stateStore.getState() : disabledInspector();\r\n win.sipSessions = () => (debug ? this.getSessions() : disabledInspector());\r\n }\r\n\r\n private toggleStateLogger(enabled: boolean) {\r\n if (!enabled) {\r\n this.stateLogOff?.();\r\n this.stateLogOff = undefined;\r\n return;\r\n }\r\n if (this.stateLogOff) return;\r\n\r\n let prev = this.stateStore.getState();\r\n // Emit initial snapshot right away for visibility.\r\n console.info(\"[sip][state]\", { initial: true }, prev);\r\n\r\n this.stateLogOff = this.stateStore.onChange((next) => {\r\n const changes = this.diffState(prev, next);\r\n if (changes) {\r\n // Log concise diff and the current snapshot for quick inspection.\r\n console.info(\"[sip][state]\", changes, next);\r\n }\r\n prev = next;\r\n });\r\n }\r\n\r\n private diffState(\r\n prev: SipState,\r\n next: SipState\r\n ): Record<string, { from: unknown; to: unknown }> | null {\r\n const changed: Record<string, { from: unknown; to: unknown }> = {};\r\n for (const key of Object.keys(next) as Array<keyof SipState>) {\r\n if (prev[key] !== next[key]) {\r\n changed[key as string] = { from: prev[key], to: next[key] };\r\n }\r\n }\r\n return Object.keys(changed).length ? changed : null;\r\n }\r\n\r\n private getPersistedDebug(): boolean | string | undefined {\r\n if (typeof window === \"undefined\") return undefined;\r\n try {\r\n const persisted = window.sessionStorage.getItem(SESSION_DEBUG_KEY);\r\n if (!persisted) return undefined;\r\n return persisted;\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n}\r\n\r\nexport function createSipClientInstance(options?: SipClientOptions): SipClient {\r\n return new SipClient(options);\r\n}\r\n\r\nexport function createSipEventManager(client: SipClient): SipEventManager {\r\n return {\r\n onUA(event, handler) {\r\n return client.on(event, handler as any);\r\n },\r\n onSession(sessionId, event, handler) {\r\n const session = client.getSession(sessionId);\r\n if (!session) return () => {};\r\n session.on(event as any, handler as any);\r\n return () => session.off(event as any, handler as any);\r\n },\r\n };\r\n}\r\n","import \"./sip/debugger\"; // ensure window helpers attach on load\r\n\r\nexport * from \"./sip/types\";\r\n\r\nexport {\n SipClient,\n type MicrophoneRecoveryOptions,\n createSipClientInstance,\n createSipEventManager,\n} from \"./sip/client\";\nexport {\r\n SipDebugger,\r\n sipDebugger,\r\n type SipDebugToggleResult,\r\n} from \"./sip/debugger\";\r\n\r\nexport { WebRTCSessionController } from \"./sip/sessionController\";\r\nexport { SessionManager } from \"./sip/sessionManager\";\r\n\r\nexport {\r\n SipErrorHandler,\r\n type SipErrorPayload,\r\n type SipErrorFormatter,\r\n} from \"./core/sipErrorHandler\";\r\n\r\nexport { WebSocketInterface } from \"jssip\";\r\n\r\nexport {\r\n SipStatus,\r\n CallStatus,\r\n CallDirection,\r\n SipStatusList,\r\n CallStatusList,\r\n isSipStatus,\r\n isCallStatus,\r\n} from \"./core/types\";\r\n\r\nexport type {\r\n SipStatus as SipStatusType,\r\n CallStatus as CallStatusType,\r\n CallDirection as CallDirectionType,\r\n SipState,\r\n SipSessionState,\r\n} from \"./core/types\";\r\n","import { createContext } from \"react\";\r\nimport type { SipClient } from \"jssip-lib\";\r\nimport type { SipEventManager } from \"jssip-lib\";\r\n\r\nexport type SipContextType = { client: SipClient, sipEventManager: SipEventManager };\r\nexport const SipContext = createContext<SipContextType | null>(null);\r\n","import { useCallback, useSyncExternalStore } from \"react\";\r\nimport type { SipState } from \"jssip-lib\";\r\nimport { useSip } from \"./useSip\";\r\n\r\nexport function useSipState(): SipState {\r\n const { client } = useSip();\r\n const subscribe = useCallback(\r\n (onStoreChange: () => void) => client.onChange(onStoreChange),\r\n [client]\r\n );\r\n\r\n const getSnapshot = useCallback(() => client.state, [client]);\r\n\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n}\r\n","import { useContext } from \"react\";\r\nimport { SipContext } from \"../context\";\r\n\r\nexport function useSip() {\r\n const ctx = useContext(SipContext);\r\n if (!ctx) throw new Error(\"Must be used within SipProvider\");\r\n return ctx;\r\n}\r\n","import { useMemo } from \"react\";\nimport { useSip } from \"./useSip\";\n\nexport function useSipActions() {\n const { client } = useSip();\n return useMemo(\n () => ({\n call: (...args: Parameters<typeof client.call>) => client.call(...args),\n answer: (...args: Parameters<typeof client.answerSession>) =>\n client.answerSession(...args),\n hangup: (...args: Parameters<typeof client.hangupSession>) =>\n client.hangupSession(...args),\n toggleMute: (...args: Parameters<typeof client.toggleMuteSession>) =>\n client.toggleMuteSession(...args),\n toggleHold: (...args: Parameters<typeof client.toggleHoldSession>) =>\n client.toggleHoldSession(...args),\n sendDTMF: (...args: Parameters<typeof client.sendDTMFSession>) =>\n client.sendDTMFSession(...args),\n transfer: (...args: Parameters<typeof client.transferSession>) =>\n client.transferSession(...args),\n getSession: (...args: Parameters<typeof client.getSession>) =>\n client.getSession(...args),\n getSessionIds: () => client.getSessionIds(),\n getSessions: () => client.getSessions(),\n setSessionMedia: (...args: Parameters<typeof client.setSessionMedia>) =>\n client.setSessionMedia(...args),\n enableMicrophoneRecovery: (\n ...args: Parameters<typeof client.enableMicrophoneRecovery>\n ) => client.enableMicrophoneRecovery(...args),\n disableMicrophoneRecovery: (\n ...args: Parameters<typeof client.disableMicrophoneRecovery>\n ) => client.disableMicrophoneRecovery(...args),\n switchCamera: (...args: Parameters<typeof client.switchCameraSession>) =>\n client.switchCameraSession(...args),\n enableVideo: (...args: Parameters<typeof client.enableVideoSession>) =>\n client.enableVideoSession(...args),\n disableVideo: (...args: Parameters<typeof client.disableVideoSession>) =>\n client.disableVideoSession(...args),\n }),\n [client]\n );\n}\n","import type { SipState } from \"jssip-lib\";\nimport { useSipState } from \"./useSipState\";\n\nexport function useSipSessions(): Pick<SipState, \"sessions\"> {\n const { sessions } = useSipState();\n return { sessions };\n}\n","import { useEffect } from \"react\";\nimport type {\n SessionEventName,\n SessionEventPayload,\n UAEventName,\n UAEventPayload,\n} from \"jssip-lib\";\nimport { useSip } from \"./useSip\";\n\nexport function useSipEvent<K extends UAEventName>(\n event: K,\n handler?: (payload?: UAEventPayload<K>) => void\n) {\n const { sipEventManager } = useSip();\n\n useEffect(() => {\n if (!handler) return;\n return sipEventManager.onUA(event, handler);\n }, [event, handler, sipEventManager]);\n}\n\nexport function useSipSessionEvent<K extends SessionEventName>(\n sessionId: string,\n event: K,\n handler?: (payload?: SessionEventPayload<K>) => void\n) {\n const { sipEventManager } = useSip();\n\n useEffect(() => {\n if (!handler) return;\n return sipEventManager.onSession(sessionId, event, handler);\n }, [event, handler, sessionId, sipEventManager]);\n}\n","import { useEffect, useRef } from \"react\";\r\nimport { useSip } from \"../hooks/useSip\";\r\nimport { createCallPlayer } from \"jssip-lib/dom\";\r\n\r\nexport function CallPlayer({ sessionId }: { sessionId?: string }) {\r\n const { client } = useSip();\r\n const audioRef = useRef<HTMLAudioElement | null>(null);\r\n\r\n useEffect(() => {\r\n if (!audioRef.current) return;\r\n\r\n const player = createCallPlayer(audioRef.current);\r\n const session = sessionId ? client.getSession(sessionId) : null;\r\n const off = session\r\n ? player.bindToSession(session)\r\n : player.bindToClient(client);\r\n\r\n return () => {\r\n off?.();\r\n player.detach();\r\n };\r\n }, [client, sessionId]);\r\n\r\n return <audio ref={audioRef} autoPlay playsInline />;\r\n}\r\n","import { SipClient } from \"../../sip/client\";\r\nimport type { RTCSession, RTCSessionEvent } from \"../../sip/types\";\r\n\r\nexport function createCallPlayer(audioEl: HTMLAudioElement) {\r\n let cleanupTrackListener: (() => void) | null = null;\r\n let cleanupSessionPeerListener: (() => void) | null = null;\r\n let cleanupClientListeners: (() => void) | null = null;\r\n\r\n const dispose = (fn: (() => void) | null) => {\r\n if (fn) fn();\r\n return null as null;\r\n };\r\n\r\n /** Stop all tracks and clear audio element */\r\n function clearAudioStream(stream?: MediaStream | null) {\r\n if (stream) {\r\n for (const t of stream.getTracks()) {\r\n t.stop();\r\n }\r\n }\r\n audioEl.srcObject = null;\r\n }\r\n\r\n const attachTracks = (pc: RTCPeerConnection) => {\r\n const onTrack = (e: RTCTrackEvent) => {\r\n if (e.track.kind !== \"audio\") return;\r\n\r\n const nextStream = e.streams?.[0] ?? new MediaStream([e.track]);\r\n const prev = audioEl.srcObject as MediaStream | null;\r\n\r\n if (prev && prev !== nextStream) {\r\n clearAudioStream(prev);\r\n }\r\n\r\n audioEl.srcObject = nextStream;\r\n audioEl.play?.().catch(() => {});\r\n };\r\n\r\n pc.addEventListener(\"track\", onTrack);\r\n return () => pc.removeEventListener(\"track\", onTrack);\r\n };\r\n\r\n const listenSessionPeerconnection = (session: RTCSession) => {\r\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n cleanupTrackListener = attachTracks(data.peerconnection);\r\n };\r\n session.on(\"peerconnection\", onPeer);\r\n return () => session.off(\"peerconnection\", onPeer);\r\n };\r\n\r\n function bindToSession(session: RTCSession) {\r\n if (\r\n session?.direction === \"outgoing\" &&\r\n session.connection instanceof RTCPeerConnection\r\n ) {\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n cleanupTrackListener = attachTracks(session.connection);\r\n }\r\n\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupSessionPeerListener = listenSessionPeerconnection(session);\r\n\r\n return () => {\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n };\r\n }\r\n\r\n function bindToClient(client: SipClient) {\r\n const offNew = client.on(\"newRTCSession\", (payload) => {\r\n const e = (payload as any)?.data as RTCSessionEvent | undefined;\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n\r\n if (!e?.session) return;\r\n\r\n cleanupSessionPeerListener = listenSessionPeerconnection(e.session);\r\n if (\r\n e.session.direction === \"outgoing\" &&\r\n e.session.connection instanceof RTCPeerConnection\r\n ) {\r\n cleanupTrackListener = attachTracks(e.session.connection);\r\n }\r\n });\r\n\r\n const offEnded = client.on(\"ended\", () => detach());\r\n const offFailed = client.on(\"failed\", () => detach());\r\n const offDisconnected = client.on(\"disconnected\", () => detach());\r\n\r\n cleanupClientListeners = () => {\r\n offNew();\r\n offEnded();\r\n offFailed();\r\n offDisconnected();\r\n };\r\n return cleanupClientListeners;\r\n }\r\n\r\n function detach() {\r\n cleanupClientListeners = dispose(cleanupClientListeners);\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n clearAudioStream(audioEl.srcObject as MediaStream | null);\r\n }\r\n\r\n return {\r\n bindToSession,\r\n bindToClient,\r\n detach,\r\n };\r\n}\r\n","import React, { useMemo } from \"react\";\r\nimport { SipContext } from \"../context\";\r\nimport { createSipEventManager, type SipClient, type SipEventManager } from \"jssip-lib\";\r\n\r\nexport function SipProvider({\n client,\n children,\n sipEventManager,\n requestMicrophoneStream,\n}: {\n sipEventManager?: SipEventManager;\n client: SipClient;\n children: React.ReactNode;\n requestMicrophoneStream?: () => Promise<MediaStream>;\n}) {\n const manager = useMemo(\n () => sipEventManager ?? createSipEventManager(client),\n [client, sipEventManager]\n );\n\n React.useEffect(() => {\n client.setMicrophoneProvider(requestMicrophoneStream);\n }, [client, requestMicrophoneStream]);\n\n const contextValue = useMemo(() => ({ client, sipEventManager: manager }), [client, manager]);\n\r\n return (\r\n <SipContext.Provider value={contextValue}>\r\n {children}\r\n </SipContext.Provider>\r\n );\r\n}\r\n"]}
1
+ {"version":3,"sources":["../src/jssip-lib/sip/debugger.ts","../src/jssip-lib/sip/userAgent.ts","../src/jssip-lib/core/types.ts","../src/jssip-lib/core/eventEmitter.ts","../src/jssip-lib/core/sipErrorHandler.ts","../src/jssip-lib/core/sipState.ts","../src/jssip-lib/core/sipStateStore.ts","../src/jssip-lib/sip/handlers/uaHandlers.ts","../src/jssip-lib/sip/sessionState.ts","../src/jssip-lib/sip/handlers/sessionHandlers.ts","../src/jssip-lib/sip/sessionController.ts","../src/jssip-lib/sip/sessionManager.ts","../src/jssip-lib/sip/sessionLifecycle.ts","../src/jssip-lib/sip/client.ts","../src/jssip-lib/index.ts","../src/context/index.tsx","../src/hooks/useSipState.ts","../src/hooks/useSip.ts","../src/hooks/useSipActions.ts","../src/hooks/useSipSessions.ts","../src/hooks/useSipEvent.ts","../src/components/call-player.tsx","../src/jssip-lib/adapters/dom/createCallPlayer.ts","../src/provider/index.tsx"],"names":["JsSIP","message","session","useEffect","useMemo","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\n/**\n * Browser-friendly debugger toggle for JsSIP.\n * Persists preference in sessionStorage and exposes helpers on window for console use.\n */\nexport class SipDebugger {\n private readonly storageKey: string;\n private readonly defaultPattern: string;\n private enabled = false;\n private logger: any;\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 this.logger = console;\n }\n // Persist pattern in sessionStorage only.\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","import JsSIP, { UA } from \"jssip\";\r\nimport { SipConfiguration, UAConfiguration } from \"./types\";\r\n\r\ntype StartOpts = { debug?: boolean | string };\r\n\r\nexport class SipUserAgent {\r\n private _ua: UA | null = null;\r\n\r\n public get ua(): UA | null {\r\n return this._ua;\r\n }\r\n public get isStarted(): boolean {\r\n return !!this._ua;\r\n }\r\n public get isRegistered(): boolean {\r\n return !!this._ua?.isRegistered();\r\n }\r\n\r\n public start(\r\n uri: string,\r\n password: string,\r\n config: Omit<SipConfiguration, \"debug\">,\r\n opts?: StartOpts\r\n ): UA {\r\n this.stop();\r\n const uaCfg = this.buildUAConfig(config, uri, password);\r\n this.ensureValid(uaCfg);\r\n this.applyDebug(opts?.debug);\r\n const ua = this.createUA(uaCfg);\r\n ua.start();\r\n this._ua = ua;\r\n return ua;\r\n }\r\n\r\n public register(): void {\r\n const ua = this.getUA();\r\n if (!ua?.isRegistered()) ua?.register();\r\n }\r\n\r\n public stop(): void {\r\n const ua = this._ua;\r\n if (!ua) return;\r\n try {\r\n if (ua.isRegistered()) ua.unregister();\r\n ua.stop();\r\n } finally {\r\n this._ua = null;\r\n }\r\n }\r\n\r\n public getUA(): UA | null {\r\n return this._ua;\r\n }\r\n\r\n public setDebug(debug?: boolean | string): void {\r\n this.applyDebug(debug);\r\n }\r\n\r\n protected buildUAConfig(\r\n config: Omit<SipConfiguration, \"debug\">,\r\n uri: string,\r\n password: string\r\n ): UAConfiguration {\r\n return { ...(config as UAConfiguration), uri, password };\r\n }\r\n\r\n protected ensureValid(cfg: UAConfiguration): void {\r\n const sockets = cfg.sockets as UAConfiguration[\"sockets\"];\r\n if (\r\n !cfg.uri ||\r\n !cfg.password ||\r\n !sockets ||\r\n (Array.isArray(sockets) && sockets.length === 0)\r\n ) {\r\n throw new Error(\r\n \"Invalid SIP connect args: require uri, password, and at least one socket\"\r\n );\r\n }\r\n }\r\n\r\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\r\n protected createUA(cfg: UAConfiguration): UA {\r\n return new JsSIP.UA(cfg);\r\n }\r\n\r\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 }\r\n\r\n private clearSessionFlag(): void {\r\n try {\r\n if (typeof window !== \"undefined\") {\r\n window.sessionStorage.removeItem(\"sip-debug-enabled\");\r\n }\r\n } catch {\r\n /* ignore */\r\n }\r\n }\r\n}\r\n","import { Originator } from \"jssip/src/RTCSession\";\r\n\r\nexport const SipStatus = {\r\n Disconnected: \"disconnected\",\r\n Connecting: \"connecting\",\r\n Connected: \"connected\",\r\n Registered: \"registered\",\r\n Unregistered: \"unregistered\",\r\n RegistrationFailed: \"registrationFailed\",\r\n} as const;\r\n\r\nexport type SipStatus = (typeof SipStatus)[keyof typeof SipStatus];\r\n\r\nexport const CallStatus = {\r\n Idle: \"idle\",\r\n Dialing: \"dialing\",\r\n Ringing: \"ringing\",\r\n Active: \"active\",\r\n Hold: \"hold\",\r\n} as const;\r\nexport type CallStatus = (typeof CallStatus)[keyof typeof CallStatus];\r\n\r\nexport type CallDirection = Originator.LOCAL | Originator.REMOTE;\r\n\r\nexport type SipSessionState = {\r\n id: string;\r\n status: CallStatus;\r\n direction: CallDirection | null;\r\n from: string | null;\r\n to: string | null;\r\n muted: boolean;\r\n acceptedAt: number | null;\r\n mediaKind: \"audio\" | \"video\";\r\n remoteVideoEnabled: boolean;\r\n};\r\n\r\nexport interface SipState {\r\n sipStatus: SipStatus;\r\n error: string | null;\r\n sessions: SipSessionState[];\r\n}\r\n\r\nexport const SipStatusList = Object.values(SipStatus);\r\nexport const CallStatusList = Object.values(CallStatus);\r\n\r\nexport function isSipStatus(v: unknown): v is SipStatus {\r\n return (\r\n typeof v === \"string\" && (SipStatusList as readonly string[]).includes(v)\r\n );\r\n}\r\nexport function isCallStatus(v: unknown): v is CallStatus {\r\n return (\r\n typeof v === \"string\" && (CallStatusList as readonly string[]).includes(v)\r\n );\r\n}\r\n\r\nexport type Unsubscribe = () => void;\r\nexport type Listener<T> = (value: T) => void;\r\n","export type Listener<T = any> = (payload: T) => void;\r\n\r\nexport class EventTargetEmitter<Events extends Record<string, any> = any> {\r\n private target = new EventTarget();\r\n\r\n on<K extends keyof Events>(event: K, fn: Listener<Events[K]>): () => void {\r\n const wrapper = (e: Event) => fn((e as CustomEvent<Events[K]>).detail);\r\n this.target.addEventListener(event as string, wrapper);\r\n return () => this.target.removeEventListener(event as string, wrapper);\r\n }\r\n\r\n emit<K extends keyof Events>(event: K, payload?: Events[K]): void {\r\n this.target.dispatchEvent(\r\n new CustomEvent(event as string, { detail: payload })\r\n );\r\n }\r\n}\r\n","export interface SipErrorPayload {\r\n cause: string;\r\n code?: string;\r\n raw?: any;\r\n message?: string;\r\n}\r\n\r\nexport interface SipErrorFormatInput {\r\n raw: any;\r\n code?: string;\r\n fallback?: string;\r\n}\r\n\r\nexport type SipErrorFormatter = (\r\n input: SipErrorFormatInput\r\n) => SipErrorPayload | undefined;\r\n\r\ntype SipErrorHandlerOptions = {\r\n formatter?: SipErrorFormatter;\r\n messages?: Record<string, string>;\r\n};\r\n\r\nexport class SipErrorHandler {\r\n private readonly formatter?: SipErrorFormatter;\r\n private readonly messages?: Record<string, string>;\r\n\r\n constructor(options: SipErrorHandlerOptions = {}) {\r\n this.formatter = options.formatter;\r\n this.messages = options.messages;\r\n }\r\n\r\n format(input: SipErrorFormatInput): SipErrorPayload {\r\n const { code, raw, fallback } = input;\r\n const mappedMessage =\r\n code && this.messages ? this.messages[code] : undefined;\r\n\r\n // Allow consumer to fully customize formatting.\r\n if (this.formatter) {\r\n const custom = this.formatter({\r\n raw,\r\n code,\r\n fallback: mappedMessage ?? fallback,\r\n });\r\n const message =\r\n custom?.message ??\r\n custom?.cause ??\r\n mappedMessage ??\r\n fallback ??\r\n this.readRawMessage(raw) ??\r\n \"unknown error\";\r\n\r\n return {\r\n cause: custom?.cause ?? message,\r\n code: custom?.code ?? code,\r\n raw: custom?.raw ?? raw,\r\n message,\r\n };\r\n }\r\n\r\n const message =\r\n mappedMessage ?? this.readRawMessage(raw) ?? fallback ?? \"unknown error\";\r\n\r\n return {\r\n cause: message,\r\n code,\r\n raw,\r\n message,\r\n };\r\n }\r\n\r\n private readRawMessage(raw: any): string | undefined {\r\n if (raw == null) return undefined;\r\n if (typeof raw === \"string\") return raw;\r\n if (typeof raw?.cause === \"string\") return raw.cause;\r\n if (typeof raw?.message === \"string\") return raw.message;\r\n return undefined;\r\n }\r\n}\r\n","import { SipState, SipStatus } from \"./types\";\r\n\r\nexport function getInitialSipState(): SipState {\r\n return {\r\n sipStatus: SipStatus.Disconnected,\r\n error: null,\r\n sessions: [],\r\n };\r\n}\r\n\r\nexport function shallowEqual(objA: any, objB: any): boolean {\r\n if (objA === objB) return true;\r\n if (!objA || !objB) return false;\r\n const keysA = Object.keys(objA);\r\n const keysB = Object.keys(objB);\r\n if (keysA.length !== keysB.length) return false;\r\n for (const key of keysA) {\r\n if (objA[key] !== objB[key]) return false;\r\n }\r\n return true;\r\n}\r\n","import { SipState } from \"./types\";\r\nimport { getInitialSipState, shallowEqual } from \"./sipState\";\r\n\r\nexport type SipStateListener = (state: SipState) => void;\r\n\r\nexport class SipStateStore {\r\n private state: SipState = getInitialSipState();\r\n private lastState: SipState = getInitialSipState();\r\n private listeners = new Set<SipStateListener>();\r\n private pendingState: Partial<SipState> | null = null;\r\n private updateScheduled = false;\r\n\r\n getState(): SipState {\r\n return this.state;\r\n }\r\n\r\n onChange(fn: SipStateListener): () => void {\r\n this.listeners.add(fn);\r\n fn(this.state);\r\n return () => this.listeners.delete(fn);\r\n }\r\n\r\n subscribe(fn: SipStateListener): () => void {\r\n return this.onChange(fn);\r\n }\r\n\r\n setState(partial: Partial<SipState>) {\r\n if (!partial || Object.keys(partial).length === 0) return;\r\n const next = { ...this.state, ...partial };\r\n // Fast-path: if sessions reference unchanged and shallow contents equal, skip emit.\r\n if (next.sessions === this.lastState.sessions && shallowEqual(this.lastState, next)) {\r\n return;\r\n }\r\n this.state = next;\r\n this.lastState = next;\r\n this.emit();\r\n }\r\n\r\n batchSet(partial: Partial<SipState>) {\r\n this.pendingState = { ...this.pendingState, ...partial };\r\n if (!this.updateScheduled) {\r\n this.updateScheduled = true;\r\n queueMicrotask(() => {\r\n if (this.pendingState) this.setState(this.pendingState);\r\n this.pendingState = null;\r\n this.updateScheduled = false;\r\n });\r\n }\r\n }\r\n\r\n reset(overrides: Partial<SipState> = {}) {\r\n this.setState({ ...getInitialSipState(), ...overrides });\r\n }\r\n\r\n private emit() {\r\n for (const fn of this.listeners) fn(this.state);\r\n }\r\n}\r\n","import { UAEventMap } from \"../types\";\r\nimport { SipStatus } from \"../../core/types\";\r\nimport { SipStateStore } from \"../../core/sipStateStore\";\r\nimport { JsSIPEventMap } from \"../types\";\r\nimport { EventTargetEmitter } from \"../../core/eventEmitter\";\r\nimport { SipErrorPayload } from \"../../core/sipErrorHandler\";\r\n\r\ntype Deps = {\r\n emitter: EventTargetEmitter<JsSIPEventMap>;\r\n state: SipStateStore;\r\n cleanupAllSessions: () => void;\r\n emitError: (\r\n raw: any,\r\n code?: string,\r\n fallback?: string\r\n ) => SipErrorPayload;\r\n onNewRTCSession: UAEventMap[\"newRTCSession\"];\r\n};\r\n\r\nexport function createUAHandlers(deps: Deps): Partial<UAEventMap> {\r\n const { emitter, state, cleanupAllSessions, emitError, onNewRTCSession } =\r\n deps;\r\n\r\n return {\r\n connecting: (e: any) => {\r\n emitter.emit(\"connecting\", e);\r\n state.batchSet({ sipStatus: SipStatus.Connecting });\r\n },\r\n connected: (e: any) => {\r\n emitter.emit(\"connected\", e);\r\n state.batchSet({ sipStatus: SipStatus.Connected });\r\n },\r\n disconnected: (e: any) => {\r\n emitter.emit(\"disconnected\", e);\r\n cleanupAllSessions();\r\n state.reset();\r\n },\r\n\r\n registered: (e: any) => {\r\n emitter.emit(\"registered\", e);\r\n state.batchSet({ sipStatus: SipStatus.Registered, error: null });\r\n },\r\n unregistered: (e: any) => {\r\n emitter.emit(\"unregistered\", e);\r\n state.batchSet({ sipStatus: SipStatus.Unregistered });\r\n },\r\n registrationFailed: (e: any) => {\r\n emitter.emit(\"registrationFailed\", e);\r\n cleanupAllSessions();\r\n emitError(\r\n {\r\n raw: e,\r\n cause: e?.cause,\r\n statusCode: e?.response?.status_code,\r\n statusText: e?.response?.reason_phrase,\r\n },\r\n \"REGISTRATION_FAILED\",\r\n \"registration failed\"\r\n );\r\n state.batchSet({\r\n sipStatus: SipStatus.RegistrationFailed,\r\n error: e?.cause || \"registration failed\",\r\n });\r\n },\r\n newRTCSession: onNewRTCSession,\r\n newMessage: (e: any) => emitter.emit(\"newMessage\", e),\r\n sipEvent: (e: any) => emitter.emit(\"sipEvent\", e),\r\n newOptions: (e: any) => emitter.emit(\"newOptions\", e),\r\n };\r\n}\r\n","import { CallStatus, SipSessionState } from \"../core/types\";\r\nimport { SipStateStore } from \"../core/sipStateStore\";\r\n\r\nexport function holdOtherSessions(\r\n state: SipStateStore,\r\n sessionId: string,\r\n holdFn: (id: string) => void\r\n) {\r\n const current = state.getState();\r\n current.sessions.forEach((s) => {\r\n if (s.id === sessionId) return;\r\n if (s.status === CallStatus.Active) {\r\n holdFn(s.id);\r\n }\r\n });\r\n}\r\n\r\nexport function upsertSessionState(\r\n state: SipStateStore,\r\n sessionId: string,\r\n partial: Partial<SipSessionState>\r\n) {\r\n const current = state.getState();\r\n const existing = current.sessions.find((s) => s.id === sessionId);\r\n const base: SipSessionState = existing ?? {\r\n id: sessionId,\r\n status: CallStatus.Idle,\r\n direction: null,\r\n from: null,\r\n to: null,\r\n muted: false,\r\n acceptedAt: null,\r\n mediaKind: \"audio\",\r\n remoteVideoEnabled: false,\r\n };\r\n\r\n const nextSession = { ...base, ...partial };\r\n const sessions = existing\r\n ? current.sessions.map((s) => (s.id === sessionId ? nextSession : s))\r\n : [...current.sessions, nextSession];\r\n\r\n state.setState({ sessions });\r\n}\r\n\r\nexport function removeSessionState(state: SipStateStore, sessionId: string) {\r\n const current = state.getState();\r\n const sessions = current.sessions.filter((s) => s.id !== sessionId);\r\n state.setState({\r\n sessions,\r\n error: null,\r\n });\r\n}\r\n","import { EndEvent, RTCSessionEventMap } from \"../types\";\nimport { CallStatus } from \"../../core/types\";\nimport { SipStateStore } from \"../../core/sipStateStore\";\nimport { WebRTCSessionController } from \"../sessionController\";\nimport { JsSIPEventMap } from \"../types\";\nimport { EventTargetEmitter } from \"../../core/eventEmitter\";\nimport { SipErrorPayload } from \"../../core/sipErrorHandler\";\nimport { upsertSessionState } from \"../sessionState\";\nimport { IncomingAckEvent, IncomingEvent, OutgoingAckEvent, OutgoingEvent } from \"jssip/src/RTCSession\";\n\ntype Deps = {\n emitter: EventTargetEmitter<JsSIPEventMap>;\n state: SipStateStore;\n rtc: WebRTCSessionController;\n detachSessionHandlers: () => void;\n emitError: (raw: any, code?: string, fallback?: string) => SipErrorPayload;\n onSessionFailed: (error?: string, event?: any) => void;\n onSessionConfirmed?: (sessionId: string) => void;\n sessionId: string;\n};\n\nexport function createSessionHandlers(deps: Deps): Partial<RTCSessionEventMap> {\n const {\n emitter,\n state,\n rtc,\n detachSessionHandlers,\n onSessionFailed,\n sessionId,\n } = deps;\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 state.batchSet({\n sessions: state.getState().sessions.map((s) =>\n s.id === sessionId\n ? {\n ...s,\n status: CallStatus.Active,\n acceptedAt: s.acceptedAt ?? Date.now(),\n }\n : s\n ),\n });\n },\n confirmed: (e: IncomingAckEvent | OutgoingAckEvent) => {\n emitter.emit(\"confirmed\", e);\n onSessionConfirmed?.(sessionId);\n },\n\n ended: (e: EndEvent) => {\n emitter.emit(\"ended\", e);\n detachSessionHandlers();\n rtc.cleanup();\n const nextSessions = state\n .getState()\n .sessions.filter((s) => s.id !== sessionId);\n state.batchSet({\n sessions: nextSessions,\n });\n },\n failed: (e: EndEvent) => {\n emitter.emit(\"failed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n const cause = e?.cause || \"call failed\";\n onSessionFailed(cause, e);\n const nextSessions = state\n .getState()\n .sessions.filter((s) => s.id !== sessionId);\n state.batchSet({\n sessions: nextSessions,\n });\n },\n\n muted: () => {\n emitter.emit(\"muted\", undefined);\n upsertSessionState(state, sessionId, { muted: true });\n },\n unmuted: () => {\n emitter.emit(\"unmuted\", undefined);\n upsertSessionState(state, sessionId, { muted: false });\n },\n hold: () => {\n emitter.emit(\"hold\", undefined);\n upsertSessionState(state, sessionId, { status: CallStatus.Hold });\n },\n unhold: () => {\n emitter.emit(\"unhold\", undefined);\n upsertSessionState(state, sessionId, { status: CallStatus.Active });\n },\n\n reinvite: (e: any) => emitter.emit(\"reinvite\", e),\n update: (e: any) => emitter.emit(\"update\", e),\n sdp: (e: any) => emitter.emit(\"sdp\", e),\n icecandidate: (e: any) => emitter.emit(\"icecandidate\", e),\n refer: (e: any) => emitter.emit(\"refer\", e),\n replaces: (e: any) => emitter.emit(\"replaces\", e),\n newDTMF: (e: any) => emitter.emit(\"newDTMF\", e),\n newInfo: (e: any) => emitter.emit(\"newInfo\", e),\n\n getusermediafailed: (e: any) => {\n emitter.emit(\"getusermediafailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"getUserMedia failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:createofferfailed\": (e: any) => {\n emitter.emit(\"peerconnection:createofferfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection createOffer failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:createanswerfailed\": (e: any) => {\n emitter.emit(\"peerconnection:createanswerfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection createAnswer failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:setlocaldescriptionfailed\": (e: any) => {\n emitter.emit(\"peerconnection:setlocaldescriptionfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection setLocalDescription failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n \"peerconnection:setremotedescriptionfailed\": (e: any) => {\n emitter.emit(\"peerconnection:setremotedescriptionfailed\", e);\n detachSessionHandlers();\n rtc.cleanup();\n onSessionFailed(\"peer connection setRemoteDescription failed\", e);\n state.batchSet({\n sessions: state.getState().sessions.filter((s) => s.id !== sessionId),\n });\n },\n peerconnection: (e: any) => emitter.emit(\"peerconnection\", e),\n };\n}\n","import type {\r\n AnswerOptions,\r\n DTMFOptions,\r\n ReferOptions,\r\n RTCSession,\r\n TerminateOptions,\r\n} from \"./types\";\r\n\r\nexport class WebRTCSessionController {\r\n currentSession: RTCSession | null = null;\r\n mediaStream: MediaStream | null = null;\r\n\r\n public setSession(session: RTCSession | null) {\r\n this.currentSession = session;\r\n }\r\n\r\n public setMediaStream(stream: MediaStream) {\r\n this.mediaStream = stream;\r\n }\r\n\r\n private getPC(): RTCPeerConnection | null {\r\n return (this.currentSession as any)?.connection ?? null;\r\n }\r\n\r\n public cleanup(stopTracks: boolean = true): void {\r\n const pc = this.getPC();\r\n\r\n if (pc && typeof pc.getSenders === \"function\") {\r\n const isClosed =\r\n pc.connectionState === \"closed\" || pc.signalingState === \"closed\";\r\n if (!isClosed) {\r\n for (const s of pc.getSenders()) {\r\n try {\r\n s.replaceTrack(null);\r\n } catch {\r\n // ignore if sender/pc already closed\r\n }\r\n }\r\n }\r\n }\r\n\r\n if (stopTracks && this.mediaStream) {\r\n for (const t of this.mediaStream.getTracks()) t.stop();\r\n }\r\n\r\n this.mediaStream = null;\r\n this.currentSession = null;\r\n }\r\n\r\n public answer(options: AnswerOptions = {}): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.answer(options), true)\r\n : false;\r\n }\r\n\r\n public hangup(options?: TerminateOptions): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.terminate(\r\n options ?? ({ status_code: 486, reason_phrase: \"Busy Here\" } as any)\r\n ),\r\n true)\r\n : false;\r\n }\r\n\r\n public mute(): boolean {\r\n this.mediaStream?.getAudioTracks().forEach((t) => (t.enabled = false));\r\n return this.currentSession\r\n ? (this.currentSession.mute({ audio: true }), true)\r\n : false;\r\n }\r\n\r\n public unmute(): boolean {\r\n this.mediaStream?.getAudioTracks().forEach((t) => (t.enabled = true));\r\n return this.currentSession\r\n ? (this.currentSession.unmute({ audio: true }), true)\r\n : false;\r\n }\r\n\r\n public hold(): boolean {\r\n return this.currentSession ? (this.currentSession.hold(), true) : false;\r\n }\r\n\r\n public unhold(): boolean {\r\n return this.currentSession ? (this.currentSession.unhold(), true) : false;\r\n }\r\n\r\n public sendDTMF(tones: string | number, options?: DTMFOptions): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.sendDTMF(tones, options), true)\r\n : false;\r\n }\r\n\r\n public transfer(target: string, options?: ReferOptions): boolean {\r\n return this.currentSession\r\n ? (this.currentSession.refer(target as any, options), true)\r\n : false;\r\n }\r\n\r\n public enableVideo(): void {\r\n this.mediaStream?.getVideoTracks().forEach((t) => (t.enabled = true));\r\n }\r\n\r\n public disableVideo(): void {\r\n this.mediaStream?.getVideoTracks().forEach((t) => (t.enabled = false));\r\n }\r\n\r\n public async switchCamera(\n nextVideoTrack: MediaStreamTrack\n ): Promise<boolean> {\n const pc = this.getPC();\r\n if (!pc) return false;\r\n\r\n if (!this.mediaStream) this.mediaStream = new MediaStream();\r\n\r\n const old = this.mediaStream.getVideoTracks()[0];\r\n this.mediaStream.addTrack(nextVideoTrack);\r\n if (old) this.mediaStream.removeTrack(old);\r\n\r\n const sender = pc.getSenders?.().find((s) => s.track?.kind === \"video\");\r\n if (sender) await sender.replaceTrack(nextVideoTrack);\r\n\r\n if (old && old !== nextVideoTrack) old.stop();\r\n\r\n return true;\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((s) => s.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 \"./sessionController\";\r\nimport type { RTCSession } from \"./types\";\r\n\r\ntype SessionEntry = {\r\n rtc: WebRTCSessionController;\r\n session?: RTCSession | null;\r\n media?: MediaStream | null;\r\n};\r\n\r\nexport class SessionManager {\r\n private entries = new Map<string, SessionEntry>();\r\n private pendingMediaQueue: Array<{ stream: MediaStream; addedAt: number }> =\r\n [];\r\n private pendingMediaTtlMs = 30000;\r\n\r\n setPendingMediaTtl(ms: number | undefined) {\r\n if (typeof ms === \"number\" && ms > 0) this.pendingMediaTtlMs = ms;\r\n }\r\n\r\n enqueueOutgoingMedia(stream: MediaStream) {\r\n this.pendingMediaQueue.push({ stream, addedAt: Date.now() });\r\n }\r\n\r\n dequeueOutgoingMedia(): MediaStream | null {\r\n const now = Date.now();\r\n while (this.pendingMediaQueue.length) {\r\n const next = this.pendingMediaQueue.shift();\r\n if (!next) break;\r\n if (now - next.addedAt <= this.pendingMediaTtlMs) {\r\n return next.stream;\r\n } else {\r\n // drop stale stream\r\n next.stream.getTracks().forEach((t) => t.stop());\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n getOrCreateRtc(sessionId: string, session?: RTCSession) {\r\n let entry = this.entries.get(sessionId);\r\n if (!entry) {\r\n entry = {\r\n rtc: new WebRTCSessionController(),\r\n session: null,\r\n media: null,\r\n };\r\n this.entries.set(sessionId, entry);\r\n }\r\n if (session) {\r\n entry.session = session;\r\n entry.rtc.setSession(session);\r\n }\r\n if (entry.media) entry.rtc.setMediaStream(entry.media);\r\n return entry.rtc;\r\n }\r\n\r\n getRtc(sessionId: string) {\r\n return this.entries.get(sessionId)?.rtc ?? null;\r\n }\r\n\r\n setSession(sessionId: string, session: RTCSession) {\r\n const entry = this.entries.get(sessionId);\r\n if (entry) {\r\n entry.session = session;\r\n entry.rtc.setSession(session);\r\n } else {\r\n this.entries.set(sessionId, {\r\n rtc: new WebRTCSessionController(),\r\n session,\r\n media: null,\r\n });\r\n }\r\n }\r\n\r\n setSessionMedia(sessionId: string, stream: MediaStream) {\r\n const entry = this.entries.get(sessionId) ?? {\r\n rtc: new WebRTCSessionController(),\r\n session: null,\r\n media: null,\r\n };\r\n entry.media = stream;\r\n entry.rtc.setMediaStream(stream);\r\n this.entries.set(sessionId, entry);\r\n }\r\n\r\n getSession(sessionId: string) {\r\n return this.entries.get(sessionId)?.session ?? null;\r\n }\r\n\r\n getSessionIds() {\r\n return Array.from(this.entries.keys());\r\n }\r\n\r\n getSessions() {\r\n return Array.from(this.entries.entries()).map(([id, entry]) => ({\r\n id,\r\n session: entry.session as RTCSession,\r\n }));\r\n }\r\n\r\n getActiveSessionId(activeStatuses: string[] = [\"active\"]): string | null {\r\n for (const [id, entry] of Array.from(this.entries.entries()).reverse()) {\r\n const status = (entry.session as any)?.status;\r\n if (status && activeStatuses.includes(String(status).toLowerCase())) {\r\n return id;\r\n }\r\n }\r\n return null;\r\n }\r\n\r\n cleanupSession(sessionId: string) {\r\n const entry = this.entries.get(sessionId);\r\n if (entry) {\r\n entry.rtc.cleanup();\r\n this.entries.delete(sessionId);\r\n }\r\n }\r\n\r\n cleanupAllSessions() {\r\n for (const [, entry] of this.entries.entries()) {\r\n entry.rtc.cleanup();\r\n }\r\n this.entries.clear();\r\n this.pendingMediaQueue = [];\r\n }\r\n\r\n answer(sessionId: string, options: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.answer(options) : false;\r\n }\r\n\r\n hangup(sessionId: string, options?: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.hangup(options) : false;\r\n }\r\n\r\n mute(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.mute() : false;\r\n }\r\n\r\n unmute(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.unmute() : false;\r\n }\r\n\r\n hold(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.hold() : false;\r\n }\r\n\r\n unhold(sessionId: string) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.unhold() : false;\r\n }\r\n\r\n sendDTMF(sessionId: string, tones: string | number, options?: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.sendDTMF(tones, options) : false;\r\n }\r\n\r\n transfer(sessionId: string, target: string, options?: any) {\r\n const rtc = this.getRtc(sessionId);\r\n return rtc ? rtc.transfer(target, options) : false;\r\n }\r\n}\r\n","import { SipStateStore } from \"../core/sipStateStore\";\r\nimport { CallDirection, CallStatus } from \"../core/types\";\r\nimport { SessionManager } from \"./sessionManager\";\r\nimport { holdOtherSessions, upsertSessionState } from \"./sessionState\";\r\nimport type { JsSIPEventName, RTCSession, RTCSessionEvent } from \"./types\";\r\nimport type { SipErrorPayload } from \"../core/sipErrorHandler\";\r\n\r\ntype Deps = {\r\n state: SipStateStore;\r\n sessionManager: SessionManager;\r\n emit: <K extends JsSIPEventName>(event: K, payload: any) => void;\r\n emitError: (raw: any, code?: string, fallback?: string) => SipErrorPayload;\r\n attachSessionHandlers: (sessionId: string, session: RTCSession) => void;\r\n getMaxSessionCount: () => number;\r\n};\r\n\r\nexport class SessionLifecycle {\r\n private readonly state: SipStateStore;\r\n private readonly sessionManager: SessionManager;\r\n private readonly emit: Deps[\"emit\"];\r\n private readonly emitError: Deps[\"emitError\"];\r\n private readonly attachSessionHandlers: Deps[\"attachSessionHandlers\"];\r\n private readonly getMaxSessionCount: Deps[\"getMaxSessionCount\"];\r\n\r\n constructor(deps: Deps) {\r\n this.state = deps.state;\r\n this.sessionManager = deps.sessionManager;\r\n this.emit = deps.emit;\r\n this.emitError = deps.emitError;\r\n this.attachSessionHandlers = deps.attachSessionHandlers;\r\n this.getMaxSessionCount = deps.getMaxSessionCount;\r\n }\r\n\r\n handleNewRTCSession(e: RTCSessionEvent) {\r\n const session = e.session;\r\n const sessionId = String((session as any)?.id ?? crypto.randomUUID?.() ?? Date.now());\r\n\r\n const currentSessions = this.state.getState().sessions;\r\n if (currentSessions.length >= this.getMaxSessionCount()) {\r\n try {\r\n session.terminate?.({ status_code: 486, reason_phrase: \"Busy Here\" } as any);\r\n } catch {\r\n /* ignore termination errors */\r\n }\r\n if (e.originator === \"remote\") {\r\n this.emit(\"missed\", e);\r\n }\r\n this.emitError(\"max session count reached\", \"MAX_SESSIONS_REACHED\", \"max session count reached\");\r\n return;\r\n }\r\n\r\n const outgoingMedia = e.originator === \"local\" ? this.sessionManager.dequeueOutgoingMedia() : null;\r\n\r\n if (outgoingMedia) this.sessionManager.setSessionMedia(sessionId, outgoingMedia);\r\n\r\n const rtc = this.sessionManager.getOrCreateRtc(sessionId, session);\r\n if (outgoingMedia) rtc.setMediaStream(outgoingMedia);\r\n\r\n this.sessionManager.setSession(sessionId, session);\r\n this.attachSessionHandlers(sessionId, session);\r\n\r\n holdOtherSessions(\r\n this.state,\r\n sessionId,\r\n (id) => {\r\n const otherRtc = this.sessionManager.getRtc(id);\r\n otherRtc?.hold();\r\n }\r\n );\r\n\r\n const sdpHasVideo =\r\n (e.request?.body && e.request.body.toString().includes(\"m=video\")) ||\r\n (session as RTCSession & { connection?: RTCPeerConnection })?.connection\r\n ?.getReceivers?.()\r\n ?.some((r: RTCRtpReceiver) => r.track?.kind === \"video\");\r\n\r\n upsertSessionState(this.state, sessionId, {\r\n direction: e.originator,\r\n from: e.originator === \"remote\" ? e.request.from.uri.user : null,\r\n to: e.request.to.uri.user,\r\n status: e.originator === \"remote\" ? CallStatus.Ringing : CallStatus.Dialing,\r\n mediaKind: sdpHasVideo ? \"video\" : \"audio\",\r\n remoteVideoEnabled: sdpHasVideo,\r\n });\r\n\r\n this.emit(\"newRTCSession\", e);\r\n }\r\n}\r\n","import { SipUserAgent } from \"./userAgent\";\r\nimport {\r\n AnswerOptions,\r\n CallOptions,\r\n DTMFOptions,\r\n JsSIPEventMap,\r\n ReferOptions,\r\n RTCSession,\r\n RTCSessionEvent,\r\n RTCSessionEventMap,\r\n SipConfiguration,\r\n SipEventManager,\r\n TerminateOptions,\r\n UAEventMap,\r\n} from \"./types\";\r\n\r\nimport { SipState, SipStatus, CallStatus } from \"../core/types\";\r\nimport { EventTargetEmitter } from \"../core/eventEmitter\";\r\nimport {\r\n SipErrorHandler,\r\n SipErrorFormatter,\r\n SipErrorPayload,\r\n} from \"../core/sipErrorHandler\";\r\nimport { SipStateStore } from \"../core/sipStateStore\";\r\nimport { createUAHandlers } from \"./handlers/uaHandlers\";\r\nimport { createSessionHandlers } from \"./handlers/sessionHandlers\";\r\nimport { SessionManager } from \"./sessionManager\";\r\nimport { removeSessionState } from \"./sessionState\";\r\nimport { SessionLifecycle } from \"./sessionLifecycle\";\r\n\r\ntype SipClientOptions = {\r\n errorMessages?: Record<string, string>;\r\n formatError?: SipErrorFormatter;\r\n errorHandler?: SipErrorHandler;\r\n debug?: boolean | string;\r\n};\r\n\r\nexport type MicrophoneRecoveryOptions = {\r\n intervalMs?: number;\r\n maxRetries?: number;\r\n};\r\n\r\nconst SESSION_DEBUG_KEY = \"sip-debug-enabled\";\r\n\r\nexport class SipClient extends EventTargetEmitter<JsSIPEventMap> {\r\n public readonly userAgent = new SipUserAgent();\r\n public readonly stateStore = new SipStateStore();\r\n\r\n private readonly uaHandlers: Partial<UAEventMap>;\r\n private readonly uaHandlerKeys: (keyof UAEventMap)[];\r\n private sessionHandlers = new Map<string, Partial<RTCSessionEventMap>>();\r\n private readonly errorHandler: SipErrorHandler;\r\n private debugPattern?: boolean | string;\r\n private maxSessionCount = Infinity;\r\n private sessionManager = new SessionManager();\r\n private lifecycle: SessionLifecycle;\r\n private micRecovery = new Map<string, { stop: () => void }>();\r\n private micRecoveryEnabled = false;\r\n private micRecoveryDefaults: Required<MicrophoneRecoveryOptions> = {\r\n intervalMs: 2000,\r\n maxRetries: Infinity,\r\n };\r\n private unloadHandler?: () => void;\r\n private stateLogOff?: () => void;\r\n\r\n public get state(): SipState {\r\n return this.stateStore.getState();\r\n }\r\n\r\n constructor(options: SipClientOptions = {}) {\r\n super();\r\n\r\n this.errorHandler =\r\n options.errorHandler ??\r\n new SipErrorHandler({\r\n formatter: options.formatError,\r\n messages: options.errorMessages,\r\n });\r\n this.debugPattern = options.debug;\r\n\r\n this.uaHandlers = createUAHandlers({\r\n emitter: this,\r\n state: this.stateStore,\r\n cleanupAllSessions: () => this.cleanupAllSessions(),\r\n emitError: (raw, code, fallback) => this.emitError(raw, code, fallback),\r\n onNewRTCSession: (e: RTCSessionEvent) => this.onNewRTCSession(e),\r\n });\r\n\r\n this.uaHandlerKeys = Object.keys(this.uaHandlers) as (keyof UAEventMap)[];\r\n\r\n this.lifecycle = new SessionLifecycle({\r\n state: this.stateStore,\r\n sessionManager: this.sessionManager,\r\n emit: (event, payload) => this.emit(event as any, payload as any),\r\n emitError: (raw, code, fallback) => this.emitError(raw, code, fallback),\r\n attachSessionHandlers: (sessionId, session) =>\r\n this.attachSessionHandlers(sessionId, session),\r\n getMaxSessionCount: () => this.maxSessionCount,\r\n });\r\n\r\n if (typeof window !== \"undefined\") {\r\n // Let window.sipSupport trigger client debug toggles.\r\n (window as any).sipDebugBridge = (debug?: boolean | string) =>\r\n this.setDebug(debug ?? true);\r\n }\r\n }\r\n\r\n public connect(uri: string, password: string, config: SipConfiguration) {\r\n this.disconnect();\r\n this.stateStore.setState({ sipStatus: SipStatus.Connecting });\r\n const {\r\n debug: cfgDebug,\r\n enableMicRecovery,\r\n micRecoveryIntervalMs,\r\n micRecoveryMaxRetries,\r\n maxSessionCount,\r\n pendingMediaTtlMs,\r\n ...uaCfg\r\n } = config;\r\n this.maxSessionCount =\r\n typeof maxSessionCount === \"number\" ? maxSessionCount : Infinity;\r\n this.micRecoveryEnabled = Boolean(enableMicRecovery);\r\n if (typeof micRecoveryIntervalMs === \"number\") {\r\n this.micRecoveryDefaults.intervalMs = micRecoveryIntervalMs;\r\n }\r\n if (typeof micRecoveryMaxRetries === \"number\") {\r\n this.micRecoveryDefaults.maxRetries = micRecoveryMaxRetries;\r\n }\r\n this.sessionManager.setPendingMediaTtl(pendingMediaTtlMs);\r\n // Config debug has priority, then persisted session flag, then prior setting.\r\n const debug = cfgDebug ?? this.getPersistedDebug() ?? this.debugPattern;\r\n this.userAgent.start(uri, password, uaCfg, { debug });\r\n this.attachUAHandlers();\r\n this.attachBeforeUnload();\r\n this.syncDebugInspector(debug);\r\n }\r\n\r\n public registerUA() {\r\n this.userAgent.register();\r\n }\r\n\r\n public disconnect() {\r\n this.detachBeforeUnload();\r\n this.detachUAHandlers();\r\n this.userAgent.stop();\r\n this.cleanupAllSessions();\r\n this.stateStore.reset();\r\n }\r\n\r\n public call(target: string, callOptions: CallOptions = {}) {\r\n try {\r\n const opts = this.ensureMediaConstraints(callOptions);\r\n if (opts.mediaStream)\r\n this.sessionManager.enqueueOutgoingMedia(opts.mediaStream);\r\n\r\n const ua = this.userAgent.getUA();\r\n ua?.call(target, opts);\r\n } catch (e: unknown) {\r\n const err = this.emitError(e, \"CALL_FAILED\", \"call failed\");\r\n this.cleanupAllSessions();\r\n this.stateStore.batchSet({\r\n error: err.cause,\r\n });\r\n }\r\n }\r\n\r\n public answer(sessionId: string, options: AnswerOptions = {}) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n return this.answerSession(resolved, options);\r\n }\r\n public hangup(sessionId: string, options?: TerminateOptions) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n return this.hangupSession(resolved, options);\r\n }\r\n\r\n public hangupAll(options?: TerminateOptions) {\r\n const ids = this.getSessionIds();\r\n ids.forEach((id) => this.hangupSession(id, options));\r\n return ids.length > 0;\r\n }\r\n\r\n public toggleMute(sessionId: string) {\r\n return this.toggleMuteSession(sessionId);\r\n }\r\n public toggleHold(sessionId: string) {\r\n return this.toggleHoldSession(sessionId);\r\n }\r\n public sendDTMF(\r\n sessionId: string,\r\n tones: string | number,\r\n options?: DTMFOptions\r\n ) {\r\n return this.sendDTMFSession(sessionId, tones, options);\r\n }\r\n public transfer(sessionId: string, target: string, options?: ReferOptions) {\r\n return this.transferSession(sessionId, target, options);\r\n }\r\n\r\n public onChange(fn: (s: SipState) => void) {\r\n return this.stateStore.onChange(fn);\r\n }\r\n\r\n private attachUAHandlers() {\r\n const ua = this.userAgent.ua;\r\n if (!ua) return;\r\n\r\n this.detachUAHandlers();\r\n this.uaHandlerKeys.forEach((ev) => {\r\n const h = this.uaHandlers[ev];\r\n if (h) ua.on(ev, h as any);\r\n });\r\n }\r\n\r\n public setDebug(debug?: boolean | string) {\r\n this.debugPattern = debug;\r\n this.userAgent.setDebug(debug);\r\n this.syncDebugInspector(debug);\r\n }\r\n\r\n private attachSessionHandlers(sessionId: string, session: RTCSession) {\r\n const handlers = this.createSessionHandlersFor(sessionId, session);\r\n this.sessionHandlers.set(sessionId, handlers);\r\n\r\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\r\n const h = handlers[ev];\r\n if (h) session.on(ev, h as any);\r\n });\r\n }\r\n\r\n private detachSessionHandlers(sessionId: string, session: RTCSession) {\r\n const handlers = this.sessionHandlers.get(sessionId);\r\n if (!handlers || !session) return;\r\n (Object.keys(handlers) as (keyof RTCSessionEventMap)[]).forEach((ev) => {\r\n const h = handlers[ev];\r\n if (h) session.off(ev, h as any);\r\n });\r\n this.sessionHandlers.delete(sessionId);\r\n }\r\n\r\n private detachUAHandlers() {\r\n const ua = this.userAgent.ua;\r\n if (!ua) return;\r\n this.uaHandlerKeys.forEach((ev) => {\r\n const h = this.uaHandlers[ev];\r\n if (h) ua.off(ev, h as any);\r\n });\r\n }\r\n\r\n private cleanupSession(sessionId: string, session?: RTCSession) {\r\n const targetSession =\r\n session ??\r\n this.sessionManager.getSession(sessionId) ??\r\n this.sessionManager.getRtc(sessionId)?.currentSession;\r\n this.detachSessionHandlers(sessionId, targetSession as any);\r\n this.disableMicrophoneRecovery(sessionId);\r\n this.sessionManager.cleanupSession(sessionId);\r\n removeSessionState(this.stateStore, sessionId);\r\n }\r\n\r\n private cleanupAllSessions() {\r\n this.sessionManager.cleanupAllSessions();\r\n this.micRecovery.forEach((entry) => entry.stop());\r\n this.micRecovery.clear();\r\n this.sessionHandlers.clear();\r\n this.stateStore.setState({\r\n sessions: [],\r\n error: null,\r\n });\r\n }\r\n\r\n private createSessionHandlersFor(\n sessionId: string,\n session: RTCSession\n ): Partial<RTCSessionEventMap> {\n const rtc = this.sessionManager.getOrCreateRtc(sessionId, session);\r\n return createSessionHandlers({\r\n emitter: this,\r\n state: this.stateStore,\r\n rtc,\r\n detachSessionHandlers: () => this.cleanupSession(sessionId, session),\r\n emitError: (raw, code, fallback) => this.emitError(raw, code, fallback),\r\n onSessionFailed: (err?: string, event?: RTCSessionEvent) =>\r\n this.onSessionFailed(err, event),\r\n onSessionConfirmed: (confirmedSessionId) => {\n if (this.micRecoveryEnabled) {\n this.enableMicrophoneRecovery(confirmedSessionId);\n }\n },\n sessionId,\n });\n }\n\r\n protected onNewRTCSession(e: RTCSessionEvent) {\r\n this.lifecycle.handleNewRTCSession(e);\r\n }\r\n\r\n protected onSessionFailed(error?: string, event?: RTCSessionEvent) {\r\n const rawCause = (event as any)?.cause ?? error;\r\n const statusCode = (event as any)?.message?.status_code;\r\n const statusText = (event as any)?.message?.reason_phrase;\r\n const causeText =\r\n rawCause ||\r\n (statusCode\r\n ? `${statusCode}${statusText ? \" \" + statusText : \"\"}`\r\n : \"call failed\");\r\n this.emitError(\r\n { raw: event, cause: rawCause, statusCode, statusText },\r\n \"SESSION_FAILED\",\r\n causeText\r\n );\r\n }\r\n\r\n private emitError(\r\n raw: unknown,\r\n code?: string,\r\n fallback?: string\r\n ): SipErrorPayload {\r\n const payload = this.errorHandler.format({ raw, code, fallback });\r\n this.emit(\"error\", payload);\r\n return payload;\r\n }\r\n\r\n private resolveSessionId(sessionId?: string) {\r\n if (sessionId) return sessionId;\r\n const sessions = this.stateStore.getState().sessions;\r\n const active = sessions.find((s) => s.status === CallStatus.Active);\r\n return active?.id ?? sessions[0]?.id ?? null;\r\n }\r\n\r\n private sessionExists(sessionId: string) {\r\n return (\r\n !!this.sessionManager.getSession(sessionId) ||\r\n !!this.sessionManager.getRtc(sessionId)\r\n );\r\n }\r\n\r\n private resolveExistingSessionId(sessionId?: string) {\r\n const id = this.resolveSessionId(sessionId);\r\n if (!id) return null;\r\n return this.sessionExists(id) ? id : null;\r\n }\r\n\r\n private ensureMediaConstraints<\r\n T extends {\r\n mediaStream?: MediaStream;\r\n mediaConstraints?: MediaStreamConstraints;\r\n }\r\n >(opts: T): T {\r\n if (opts.mediaStream || opts.mediaConstraints) return opts;\r\n return { ...opts, mediaConstraints: { audio: true, video: false } } as T;\r\n }\r\n\r\n public answerSession(sessionId: string, options: AnswerOptions = {}) {\r\n if (!sessionId || !this.sessionExists(sessionId)) return false;\r\n const opts = this.ensureMediaConstraints(options);\r\n if (opts.mediaStream) {\r\n this.sessionManager.setSessionMedia(sessionId, opts.mediaStream);\r\n }\r\n return this.sessionManager.answer(sessionId, opts);\r\n }\r\n\r\n public hangupSession(sessionId: string, options?: TerminateOptions) {\r\n if (!sessionId || !this.sessionExists(sessionId)) return false;\r\n return this.sessionManager.hangup(sessionId, options);\r\n }\r\n\r\n public toggleMuteSession(sessionId?: string) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n const muted = sessionState?.muted ?? false;\r\n if (muted) {\r\n this.sessionManager.unmute(resolved);\r\n return true;\r\n }\r\n this.sessionManager.mute(resolved);\r\n return true;\r\n }\r\n\r\n public toggleHoldSession(sessionId?: string) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n const isOnHold = sessionState?.status === CallStatus.Hold;\r\n if (isOnHold) {\r\n this.sessionManager.unhold(resolved);\r\n return true;\r\n }\r\n if (sessionState?.status === CallStatus.Active) {\r\n this.sessionManager.hold(resolved);\r\n return true;\r\n }\r\n return true;\r\n }\r\n\r\n public sendDTMFSession(\r\n sessionId: string,\r\n tones: string | number,\r\n options?: DTMFOptions\r\n ) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n if (sessionState?.status === CallStatus.Active)\r\n this.sessionManager.sendDTMF(resolved, tones, options);\r\n return true;\r\n }\r\n\r\n public transferSession(\r\n sessionId: string,\r\n target: string,\r\n options?: ReferOptions\r\n ) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n if (sessionState?.status === CallStatus.Active)\r\n this.sessionManager.transfer(resolved, target, options);\r\n return true;\r\n }\r\n\r\n public setSessionMedia(sessionId: string, stream: MediaStream) {\r\n this.sessionManager.setSessionMedia(sessionId, stream);\r\n }\r\n\r\n public enableMicrophoneRecovery(\r\n sessionId: string,\r\n options: MicrophoneRecoveryOptions = {}\r\n ) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return () => {};\r\n\r\n this.disableMicrophoneRecovery(resolved);\r\n\r\n const intervalMs =\r\n options.intervalMs ?? this.micRecoveryDefaults.intervalMs;\r\n const maxRetries =\r\n options.maxRetries ?? this.micRecoveryDefaults.maxRetries;\r\n let retries = 0;\r\n let stopped = false;\r\n\r\n const tick = async () => {\r\n if (stopped || retries >= maxRetries) return;\r\n\r\n const rtc = this.sessionManager.getRtc(resolved);\r\n const session = this.sessionManager.getSession(resolved);\r\n if (!rtc || !session) return;\r\n\r\n const sessionState = this.stateStore\r\n .getState()\r\n .sessions.find((s) => s.id === resolved);\r\n if (sessionState?.muted) return;\r\n\r\n const stream = rtc.mediaStream;\r\n const track = stream?.getAudioTracks?.()[0];\r\n const sender = (session as any)?.connection\r\n ?.getSenders?.()\r\n .find((s: RTCRtpSender) => s.track?.kind === \"audio\");\r\n\r\n const trackLive = track?.readyState === \"live\";\n const senderLive = sender?.track?.readyState === \"live\";\n if (trackLive && senderLive) return;\n\n this.emitError(\n {\n cause: \"microphone dropped\",\n trackLive,\n senderLive,\n },\n \"MICROPHONE_DROPPED\",\n \"microphone dropped\"\n );\n\n retries += 1;\n if (trackLive && !senderLive && track) {\n await rtc.replaceAudioTrack(track);\n return;\n }\n\r\n let nextStream: MediaStream;\r\n try {\r\n const deviceId =\r\n track?.getSettings?.().deviceId ??\r\n sender?.track?.getSettings?.().deviceId;\r\n nextStream = await this.requestMicrophoneStreamInternal(deviceId);\r\n } catch (err) {\r\n console.warn(\"[sip] mic recovery failed to get stream\", err);\r\n return;\r\n }\r\n const nextTrack = nextStream.getAudioTracks()[0];\r\n if (!nextTrack) return;\r\n\r\n await rtc.replaceAudioTrack(nextTrack);\r\n this.sessionManager.setSessionMedia(resolved, nextStream);\r\n };\r\n\r\n const timer = setInterval(() => {\r\n void tick();\r\n }, intervalMs);\r\n void tick();\r\n\r\n const session = this.sessionManager.getSession(resolved);\r\n const pc: RTCPeerConnection | undefined = (session as any)?.connection;\r\n const onIceChange = () => {\r\n const state = pc?.iceConnectionState;\r\n if (state === \"failed\" || state === \"disconnected\") void tick();\r\n };\r\n pc?.addEventListener?.(\"iceconnectionstatechange\", onIceChange);\r\n\r\n const stop = () => {\r\n stopped = true;\r\n clearInterval(timer);\r\n pc?.removeEventListener?.(\"iceconnectionstatechange\", onIceChange);\r\n };\r\n this.micRecovery.set(resolved, { stop });\r\n return stop;\r\n }\r\n\r\n public disableMicrophoneRecovery(sessionId: string) {\r\n const resolved = this.resolveExistingSessionId(sessionId);\r\n if (!resolved) return false;\r\n const entry = this.micRecovery.get(resolved);\r\n if (!entry) return false;\r\n entry.stop();\r\n this.micRecovery.delete(resolved);\r\n return true;\r\n }\r\n\r\n public switchCameraSession(sessionId: string, track: MediaStreamTrack) {\r\n if (!this.sessionExists(sessionId)) return false;\r\n const rtc = this.sessionManager.getRtc(sessionId);\r\n return rtc ? rtc.switchCamera(track) : false;\r\n }\r\n\r\n public enableVideoSession(sessionId: string) {\r\n if (!this.sessionExists(sessionId)) return false;\r\n const rtc = this.sessionManager.getRtc(sessionId);\r\n rtc?.enableVideo();\r\n return !!rtc;\r\n }\r\n\r\n public disableVideoSession(sessionId: string) {\r\n if (!this.sessionExists(sessionId)) return false;\r\n const rtc = this.sessionManager.getRtc(sessionId);\r\n rtc?.disableVideo();\r\n return !!rtc;\r\n }\r\n\r\n public getSession(sessionId: string) {\r\n return this.sessionManager.getSession(sessionId);\r\n }\r\n\r\n public getSessionIds() {\r\n return this.sessionManager.getSessionIds();\r\n }\r\n\r\n public getSessions() {\r\n return this.sessionManager.getSessions();\r\n }\r\n\r\n private attachBeforeUnload() {\r\n if (typeof window === \"undefined\" || this.unloadHandler) return;\r\n\r\n const handler = () => {\r\n this.hangupAll();\r\n this.disconnect();\r\n };\r\n\r\n window.addEventListener(\"beforeunload\", handler);\r\n this.unloadHandler = handler;\r\n }\r\n\r\n private detachBeforeUnload() {\r\n if (typeof window === \"undefined\" || !this.unloadHandler) return;\r\n window.removeEventListener(\"beforeunload\", this.unloadHandler);\r\n this.unloadHandler = undefined;\r\n }\r\n\r\n private syncDebugInspector(debug?: boolean | string) {\r\n if (typeof window === \"undefined\") return;\r\n this.toggleStateLogger(Boolean(debug));\r\n\r\n const win = window as any;\r\n const disabledInspector = () => {\r\n console.warn(\"SIP debug inspector disabled; enable debug to inspect.\");\r\n return null;\r\n };\r\n win.sipState = () =>\r\n debug ? this.stateStore.getState() : disabledInspector();\r\n win.sipSessions = () => (debug ? this.getSessions() : disabledInspector());\r\n }\r\n\r\n private toggleStateLogger(enabled: boolean) {\r\n if (!enabled) {\r\n this.stateLogOff?.();\r\n this.stateLogOff = undefined;\r\n return;\r\n }\r\n if (this.stateLogOff) return;\r\n\r\n let prev = this.stateStore.getState();\r\n // Emit initial snapshot right away for visibility.\r\n console.info(\"[sip][state]\", { initial: true }, prev);\r\n\r\n this.stateLogOff = this.stateStore.onChange((next) => {\r\n const changes = this.diffState(prev, next);\r\n if (changes) {\r\n // Log concise diff and the current snapshot for quick inspection.\r\n console.info(\"[sip][state]\", changes, next);\r\n }\r\n prev = next;\r\n });\r\n }\r\n\r\n private diffState(\r\n prev: SipState,\r\n next: SipState\r\n ): Record<string, { from: unknown; to: unknown }> | null {\r\n const changed: Record<string, { from: unknown; to: unknown }> = {};\r\n for (const key of Object.keys(next) as Array<keyof SipState>) {\r\n if (prev[key] !== next[key]) {\r\n changed[key as string] = { from: prev[key], to: next[key] };\r\n }\r\n }\r\n return Object.keys(changed).length ? changed : null;\r\n }\r\n\r\n private getPersistedDebug(): boolean | string | undefined {\r\n if (typeof window === \"undefined\") return undefined;\r\n try {\r\n const persisted = window.sessionStorage.getItem(SESSION_DEBUG_KEY);\r\n if (!persisted) return undefined;\r\n return persisted;\r\n } catch {\r\n return undefined;\r\n }\r\n }\r\n\r\n private async requestMicrophoneStreamInternal(\n deviceId?: string\n ): Promise<MediaStream> {\n if (\n typeof navigator === \"undefined\" ||\n !navigator.mediaDevices?.getUserMedia\n ) {\n throw new Error(\"getUserMedia not available\");\n }\n const audio =\n deviceId && deviceId !== \"default\"\n ? { deviceId: { exact: deviceId } }\n : true;\n try {\n return await navigator.mediaDevices.getUserMedia({ audio });\n } catch (err: any) {\n const cause = err?.name || \"getUserMedia failed\";\n this.emitError(\n { raw: err, cause },\n \"MICROPHONE_UNAVAILABLE\",\n \"microphone unavailable\"\n );\n throw err;\n }\n }\n}\n\r\nexport function createSipClientInstance(options?: SipClientOptions): SipClient {\r\n return new SipClient(options);\r\n}\r\n\r\nexport function createSipEventManager(client: SipClient): SipEventManager {\r\n return {\r\n onUA(event, handler) {\r\n return client.on(event, handler as any);\r\n },\r\n onSession(sessionId, event, handler) {\r\n const session = client.getSession(sessionId);\r\n if (!session) return () => {};\r\n session.on(event as any, handler as any);\r\n return () => session.off(event as any, handler as any);\r\n },\r\n };\r\n}\r\n","import \"./sip/debugger\"; // ensure window helpers attach on load\r\n\r\nexport * from \"./sip/types\";\r\n\r\nexport {\n SipClient,\n type MicrophoneRecoveryOptions,\n createSipClientInstance,\n createSipEventManager,\n} from \"./sip/client\";\nexport {\r\n SipDebugger,\r\n sipDebugger,\r\n type SipDebugToggleResult,\r\n} from \"./sip/debugger\";\r\n\r\nexport { WebRTCSessionController } from \"./sip/sessionController\";\r\nexport { SessionManager } from \"./sip/sessionManager\";\r\n\r\nexport {\r\n SipErrorHandler,\r\n type SipErrorPayload,\r\n type SipErrorFormatter,\r\n} from \"./core/sipErrorHandler\";\r\n\r\nexport { WebSocketInterface } from \"jssip\";\r\n\r\nexport {\r\n SipStatus,\r\n CallStatus,\r\n CallDirection,\r\n SipStatusList,\r\n CallStatusList,\r\n isSipStatus,\r\n isCallStatus,\r\n} from \"./core/types\";\r\n\r\nexport type {\r\n SipStatus as SipStatusType,\r\n CallStatus as CallStatusType,\r\n CallDirection as CallDirectionType,\r\n SipState,\r\n SipSessionState,\r\n} from \"./core/types\";\r\n","import { createContext } from \"react\";\r\nimport type { SipClient } from \"jssip-lib\";\r\nimport type { SipEventManager } from \"jssip-lib\";\r\n\r\nexport type SipContextType = { client: SipClient, sipEventManager: SipEventManager };\r\nexport const SipContext = createContext<SipContextType | null>(null);\r\n","import { useCallback, useSyncExternalStore } from \"react\";\r\nimport type { SipState } from \"jssip-lib\";\r\nimport { useSip } from \"./useSip\";\r\n\r\nexport function useSipState(): SipState {\r\n const { client } = useSip();\r\n const subscribe = useCallback(\r\n (onStoreChange: () => void) => client.onChange(onStoreChange),\r\n [client]\r\n );\r\n\r\n const getSnapshot = useCallback(() => client.state, [client]);\r\n\r\n return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);\r\n}\r\n","import { useContext } from \"react\";\r\nimport { SipContext } from \"../context\";\r\n\r\nexport function useSip() {\r\n const ctx = useContext(SipContext);\r\n if (!ctx) throw new Error(\"Must be used within SipProvider\");\r\n return ctx;\r\n}\r\n","import { useMemo } from \"react\";\nimport { useSip } from \"./useSip\";\n\nexport function useSipActions() {\n const { client } = useSip();\n return useMemo(\n () => ({\n call: (...args: Parameters<typeof client.call>) => client.call(...args),\n answer: (...args: Parameters<typeof client.answerSession>) =>\n client.answerSession(...args),\n hangup: (...args: Parameters<typeof client.hangupSession>) =>\n client.hangupSession(...args),\n toggleMute: (...args: Parameters<typeof client.toggleMuteSession>) =>\n client.toggleMuteSession(...args),\n toggleHold: (...args: Parameters<typeof client.toggleHoldSession>) =>\n client.toggleHoldSession(...args),\n sendDTMF: (...args: Parameters<typeof client.sendDTMFSession>) =>\n client.sendDTMFSession(...args),\n transfer: (...args: Parameters<typeof client.transferSession>) =>\n client.transferSession(...args),\n getSession: (...args: Parameters<typeof client.getSession>) =>\n client.getSession(...args),\n getSessionIds: () => client.getSessionIds(),\n getSessions: () => client.getSessions(),\n setSessionMedia: (...args: Parameters<typeof client.setSessionMedia>) =>\n client.setSessionMedia(...args),\n enableMicrophoneRecovery: (\n ...args: Parameters<typeof client.enableMicrophoneRecovery>\n ) => client.enableMicrophoneRecovery(...args),\n disableMicrophoneRecovery: (\n ...args: Parameters<typeof client.disableMicrophoneRecovery>\n ) => client.disableMicrophoneRecovery(...args),\n switchCamera: (...args: Parameters<typeof client.switchCameraSession>) =>\n client.switchCameraSession(...args),\n enableVideo: (...args: Parameters<typeof client.enableVideoSession>) =>\n client.enableVideoSession(...args),\n disableVideo: (...args: Parameters<typeof client.disableVideoSession>) =>\n client.disableVideoSession(...args),\n }),\n [client]\n );\n}\n","import type { SipState } from \"jssip-lib\";\nimport { useSipState } from \"./useSipState\";\n\nexport function useSipSessions(): Pick<SipState, \"sessions\"> {\n const { sessions } = useSipState();\n return { sessions };\n}\n","import { useEffect } from \"react\";\nimport type {\n SessionEventName,\n SessionEventPayload,\n UAEventName,\n UAEventPayload,\n} from \"jssip-lib\";\nimport { useSip } from \"./useSip\";\n\nexport function useSipEvent<K extends UAEventName>(\n event: K,\n handler?: (payload?: UAEventPayload<K>) => void\n) {\n const { sipEventManager } = useSip();\n\n useEffect(() => {\n if (!handler) return;\n return sipEventManager.onUA(event, handler);\n }, [event, handler, sipEventManager]);\n}\n\nexport function useSipSessionEvent<K extends SessionEventName>(\n sessionId: string,\n event: K,\n handler?: (payload?: SessionEventPayload<K>) => void\n) {\n const { sipEventManager } = useSip();\n\n useEffect(() => {\n if (!handler) return;\n return sipEventManager.onSession(sessionId, event, handler);\n }, [event, handler, sessionId, sipEventManager]);\n}\n","import { useEffect, useRef } from \"react\";\r\nimport { useSip } from \"../hooks/useSip\";\r\nimport { createCallPlayer } from \"jssip-lib/dom\";\r\n\r\nexport function CallPlayer({ sessionId }: { sessionId?: string }) {\r\n const { client } = useSip();\r\n const audioRef = useRef<HTMLAudioElement | null>(null);\r\n\r\n useEffect(() => {\r\n if (!audioRef.current) return;\r\n\r\n const player = createCallPlayer(audioRef.current);\r\n const session = sessionId ? client.getSession(sessionId) : null;\r\n const off = session\r\n ? player.bindToSession(session)\r\n : player.bindToClient(client);\r\n\r\n return () => {\r\n off?.();\r\n player.detach();\r\n };\r\n }, [client, sessionId]);\r\n\r\n return <audio ref={audioRef} autoPlay playsInline />;\r\n}\r\n","import { SipClient } from \"../../sip/client\";\r\nimport type { RTCSession, RTCSessionEvent } from \"../../sip/types\";\r\n\r\nexport function createCallPlayer(audioEl: HTMLAudioElement) {\r\n let cleanupTrackListener: (() => void) | null = null;\r\n let cleanupSessionPeerListener: (() => void) | null = null;\r\n let cleanupClientListeners: (() => void) | null = null;\r\n\r\n const dispose = (fn: (() => void) | null) => {\r\n if (fn) fn();\r\n return null as null;\r\n };\r\n\r\n /** Stop all tracks and clear audio element */\r\n function clearAudioStream(stream?: MediaStream | null) {\r\n if (stream) {\r\n for (const t of stream.getTracks()) {\r\n t.stop();\r\n }\r\n }\r\n audioEl.srcObject = null;\r\n }\r\n\r\n const attachTracks = (pc: RTCPeerConnection) => {\r\n const onTrack = (e: RTCTrackEvent) => {\r\n if (e.track.kind !== \"audio\") return;\r\n\r\n const nextStream = e.streams?.[0] ?? new MediaStream([e.track]);\r\n const prev = audioEl.srcObject as MediaStream | null;\r\n\r\n if (prev && prev !== nextStream) {\r\n clearAudioStream(prev);\r\n }\r\n\r\n audioEl.srcObject = nextStream;\r\n audioEl.play?.().catch(() => {});\r\n };\r\n\r\n pc.addEventListener(\"track\", onTrack);\r\n return () => pc.removeEventListener(\"track\", onTrack);\r\n };\r\n\r\n const listenSessionPeerconnection = (session: RTCSession) => {\r\n const onPeer = (data: { peerconnection: RTCPeerConnection }) => {\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n cleanupTrackListener = attachTracks(data.peerconnection);\r\n };\r\n session.on(\"peerconnection\", onPeer);\r\n return () => session.off(\"peerconnection\", onPeer);\r\n };\r\n\r\n function bindToSession(session: RTCSession) {\r\n if (\r\n session?.direction === \"outgoing\" &&\r\n session.connection instanceof RTCPeerConnection\r\n ) {\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n cleanupTrackListener = attachTracks(session.connection);\r\n }\r\n\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupSessionPeerListener = listenSessionPeerconnection(session);\r\n\r\n return () => {\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n };\r\n }\r\n\r\n function bindToClient(client: SipClient) {\r\n const offNew = client.on(\"newRTCSession\", (payload) => {\r\n const e = (payload as any)?.data as RTCSessionEvent | undefined;\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n\r\n if (!e?.session) return;\r\n\r\n cleanupSessionPeerListener = listenSessionPeerconnection(e.session);\r\n if (\r\n e.session.direction === \"outgoing\" &&\r\n e.session.connection instanceof RTCPeerConnection\r\n ) {\r\n cleanupTrackListener = attachTracks(e.session.connection);\r\n }\r\n });\r\n\r\n const offEnded = client.on(\"ended\", () => detach());\r\n const offFailed = client.on(\"failed\", () => detach());\r\n const offDisconnected = client.on(\"disconnected\", () => detach());\r\n\r\n cleanupClientListeners = () => {\r\n offNew();\r\n offEnded();\r\n offFailed();\r\n offDisconnected();\r\n };\r\n return cleanupClientListeners;\r\n }\r\n\r\n function detach() {\r\n cleanupClientListeners = dispose(cleanupClientListeners);\r\n cleanupSessionPeerListener = dispose(cleanupSessionPeerListener);\r\n cleanupTrackListener = dispose(cleanupTrackListener);\r\n clearAudioStream(audioEl.srcObject as MediaStream | null);\r\n }\r\n\r\n return {\r\n bindToSession,\r\n bindToClient,\r\n detach,\r\n };\r\n}\r\n","import React, { useMemo } from \"react\";\nimport { SipContext } from \"../context\";\nimport { createSipEventManager, type SipClient, type SipEventManager } from \"jssip-lib\";\n\nexport function SipProvider({\n client,\n children,\n sipEventManager,\n}: {\n sipEventManager?: SipEventManager;\n client: SipClient;\n children: React.ReactNode;\n}) {\n const manager = useMemo(\n () => sipEventManager ?? createSipEventManager(client),\n [client, sipEventManager]\n );\n\n const contextValue = useMemo(() => ({ client, sipEventManager: manager }), [client, manager]);\n\n return (\n <SipContext.Provider value={contextValue}>\n {children}\n </SipContext.Provider>\n );\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -189,7 +189,6 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
189
189
  private sessionManager;
190
190
  private lifecycle;
191
191
  private micRecovery;
192
- private requestMicrophoneStream?;
193
192
  private micRecoveryEnabled;
194
193
  private micRecoveryDefaults;
195
194
  private unloadHandler?;
@@ -197,7 +196,6 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
197
196
  get state(): SipState;
198
197
  constructor(options?: SipClientOptions);
199
198
  connect(uri: string, password: string, config: SipConfiguration): void;
200
- setMicrophoneProvider(fn?: () => Promise<MediaStream>): void;
201
199
  registerUA(): void;
202
200
  disconnect(): void;
203
201
  call(target: string, callOptions?: CallOptions): void;
@@ -248,6 +246,7 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
248
246
  private toggleStateLogger;
249
247
  private diffState;
250
248
  private getPersistedDebug;
249
+ private requestMicrophoneStreamInternal;
251
250
  }
252
251
  declare function createSipClientInstance(options?: SipClientOptions): SipClient;
253
252
  declare function createSipEventManager(client: SipClient): SipEventManager;
@@ -293,11 +292,10 @@ declare function CallPlayer({ sessionId }: {
293
292
  sessionId?: string;
294
293
  }): react_jsx_runtime.JSX.Element;
295
294
 
296
- declare function SipProvider({ client, children, sipEventManager, requestMicrophoneStream, }: {
295
+ declare function SipProvider({ client, children, sipEventManager, }: {
297
296
  sipEventManager?: SipEventManager;
298
297
  client: SipClient;
299
298
  children: react__default.ReactNode;
300
- requestMicrophoneStream?: () => Promise<MediaStream>;
301
299
  }): react_jsx_runtime.JSX.Element;
302
300
 
303
301
  export { type CallDirection, type CallDirection as CallDirectionType, CallPlayer, CallStatus, CallStatus as CallStatusType, type JsSIPEventMap, type JsSIPEventName, type SessionEventName, type SessionEventPayload, type SipConfiguration, SipContext, type SipContextType, type SipEventHandlers, type SipEventManager, SipProvider, type SipSessionState, type SipState, SipStatus, SipStatus as SipStatusType, type UAEventName, type UAEventPayload, createSipClientInstance, createSipEventManager, useSip, useSipActions, useSipEvent, useSipSessionEvent, useSipSessions, useSipState };
package/dist/index.d.ts CHANGED
@@ -189,7 +189,6 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
189
189
  private sessionManager;
190
190
  private lifecycle;
191
191
  private micRecovery;
192
- private requestMicrophoneStream?;
193
192
  private micRecoveryEnabled;
194
193
  private micRecoveryDefaults;
195
194
  private unloadHandler?;
@@ -197,7 +196,6 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
197
196
  get state(): SipState;
198
197
  constructor(options?: SipClientOptions);
199
198
  connect(uri: string, password: string, config: SipConfiguration): void;
200
- setMicrophoneProvider(fn?: () => Promise<MediaStream>): void;
201
199
  registerUA(): void;
202
200
  disconnect(): void;
203
201
  call(target: string, callOptions?: CallOptions): void;
@@ -248,6 +246,7 @@ declare class SipClient extends EventTargetEmitter<JsSIPEventMap> {
248
246
  private toggleStateLogger;
249
247
  private diffState;
250
248
  private getPersistedDebug;
249
+ private requestMicrophoneStreamInternal;
251
250
  }
252
251
  declare function createSipClientInstance(options?: SipClientOptions): SipClient;
253
252
  declare function createSipEventManager(client: SipClient): SipEventManager;
@@ -293,11 +292,10 @@ declare function CallPlayer({ sessionId }: {
293
292
  sessionId?: string;
294
293
  }): react_jsx_runtime.JSX.Element;
295
294
 
296
- declare function SipProvider({ client, children, sipEventManager, requestMicrophoneStream, }: {
295
+ declare function SipProvider({ client, children, sipEventManager, }: {
297
296
  sipEventManager?: SipEventManager;
298
297
  client: SipClient;
299
298
  children: react__default.ReactNode;
300
- requestMicrophoneStream?: () => Promise<MediaStream>;
301
299
  }): react_jsx_runtime.JSX.Element;
302
300
 
303
301
  export { type CallDirection, type CallDirection as CallDirectionType, CallPlayer, CallStatus, CallStatus as CallStatusType, type JsSIPEventMap, type JsSIPEventName, type SessionEventName, type SessionEventPayload, type SipConfiguration, SipContext, type SipContextType, type SipEventHandlers, type SipEventManager, SipProvider, type SipSessionState, type SipState, SipStatus, SipStatus as SipStatusType, type UAEventName, type UAEventPayload, createSipClientInstance, createSipEventManager, useSip, useSipActions, useSipEvent, useSipSessionEvent, useSipSessions, useSipState };