import { a as JSONRPCSuccessResponse, i as JSONRPCResponse, n as JSONRPCErrorResponse, r as JSONRPCRequest, t as EventChannel } from "./base-Cif20s3C.cjs"; import { URL as URL$1 } from "node:url"; import * as rxjs0 from "rxjs"; import { BehaviorSubject, Observable, Observer, ReplaySubject, Subject, Subscription } from "rxjs"; //#region src/core/types/common.types.d.ts /** JSON-compatible value type for serializable data structures. */ interface JSONSerializable { [key: string]: JSONSerializable | string | number | boolean | null | undefined | JSONSerializable[]; } /** * HTTP methods supported by the HTTPRequest interface */ type HTTPMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH' | 'HEAD' | 'OPTIONS'; /** * HTTP headers as key-value pairs */ type HTTPHeaders = Record; /** * Represents an HTTP request with all necessary properties for making * REST API calls. Compatible with both browser fetch and Node.js http modules. */ interface HTTPRequest { /** HTTP method to use for the request */ method: HTTPMethod; /** Target URL for the request */ url: string | URL; /** Optional HTTP headers */ headers?: HTTPHeaders; /** Optional request body (supports various types for flexibility) */ body?: string | Blob | ArrayBuffer | FormData | URLSearchParams | ReadableStream | null; /** Optional AbortSignal for request cancellation */ signal?: AbortSignal; /** Optional timeout in milliseconds */ timeout?: number; } type HttpBody = string | Blob | ArrayBuffer | ReadableStream | null; /** * Represents an HTTP response with status, headers, and body. * Compatible with both browser Response and Node.js http.IncomingMessage. */ interface HTTPResponse { /** HTTP status code (e.g., 200, 404, 500) */ status: number; /** HTTP status text (e.g., "OK", "Not Found") */ statusText: string; /** Response headers */ headers: HTTPHeaders; /** Response body (flexible type to support various response formats) */ body?: T; /** Convenience property: true if status is 200-299 */ ok: boolean; /** Final URL after any redirects */ url: string; } /** Browser-compatible WebSocket client interface. */ interface WebSocketClient { addEventListener: WebSocket['addEventListener']; removeEventListener: WebSocket['removeEventListener']; send: WebSocket['send']; close: WebSocket['close']; readyState: WebSocket['readyState']; } /** Node.js WebSocket client interface with event listener overloads. */ interface NodeSocketClient extends WebSocketClient { addEventListener(method: 'open' | 'close' | 'error' | 'message', cb: (event: unknown) => void, options?: unknown): void; removeEventListener(method: 'open' | 'close' | 'error' | 'message', cb: (event: unknown) => void): void; send(data: unknown, cb?: (err?: Error) => void): void; } /** * There's a difference in `searchParams` between URL from * `lib` and URL from `url` (node) that makes using the same * not possible for us. */ interface NodeSocketAdapter { new (address: string | URL$1, options?: unknown): NodeSocketClient; new (address: string | URL$1, protocols?: string | string[], options?: unknown): NodeSocketClient; } /** Browser-compatible WebSocket constructor type. */ type WebSocketAdapter = new (url: string | URL, protocols?: string | string[]) => WebSocketClient; /** * Authentication credentials for the SDK. * * At least one of `token` or `authorizationState` must be provided. */ interface SDKCredential { /** JWT user access token (SAT). */ token?: string; /** Pre-authorized session state (alternative to token). */ authorizationState?: string; /** Token expiry timestamp in milliseconds since epoch. When set, the SDK attempts credential refresh before expiry. */ expiry_at?: number; } /** Types of addressable resources in the fabric. */ type ResourceType = 'app' | 'call' | 'room' | 'subscriber'; //#endregion //#region src/dependencies/interfaces.d.ts /** Persistence scope: browser `localStorage` or `sessionStorage`. */ type StorageScope = 'local' | 'session'; /** Key-value storage interface for persisting SDK preferences and state. */ interface Storage { setItem(key: string, value: string | null, scope: StorageScope): Promise; getItem(key: string, scope: StorageScope): Promise; removeItem(key: string, scope: StorageScope): Promise; /** Clears all keys in the given scope. Implementations may scope the clear to SDK keys only. */ clear(scope: StorageScope): Promise; } /** * Context provided by the SDK when calling {@link CredentialProvider.authenticate}. * * Contains optional parameters the SDK generates internally (e.g., DPoP fingerprint) * that the implementor can forward to their server-side token endpoint. */ interface AuthenticateContext { /** * JWK Thumbprint (RFC 7638) of the SDK's ephemeral DPoP key pair. * * When present, the implementor should forward this value as the `fingerprint` * parameter to the server-side SAT issuance endpoint alongside `scope: "sat:refresh"`. * This enables the server to bind the SAT to the SDK's key pair, allowing * automatic Client Bound SAT refresh without developer intervention. * * When absent (e.g., Web Crypto API not available), the implementor should * proceed without DPoP binding. */ fingerprint?: string; } /** * Provides authentication credentials to the SDK. * * Implementors are responsible for: * - Obtaining credentials (e.g. via API calls, user login flows, or third-party auth services). * - Returning a valid {@link SDKCredential} with either a `token` or `authorizationState`. * - Setting `expiry_at` when the credential has a known expiration so the SDK can schedule refresh. * - Handling errors and never leaking sensitive data through error messages. * * ## Refresh precedence * * The SDK selects exactly one refresh mechanism per session, evaluated at connect * time (and re-evaluated on reconnect): * * | `refresh` provided | SAT carries `sat:refresh` scope | Active mechanism | * | ------------------ | -------------------------------- | ------------------------------------ | * | yes | yes | Client Bound SAT (DPoP, internal) | * | yes | no | Developer-provided `refresh()` | * | no | yes | Client Bound SAT (DPoP, internal) | * | no | no | None — session ends at `expiry_at` | * * When the SDK falls back to the developer-provided `refresh()` because the SAT * lacked `sat:refresh` scope, a `credential_refresh_fallback` event is emitted on * `SignalWire.warnings$` so application code can observe the transition. * * Mint a SAT via `POST /api/fabric/subscribers/tokens` with `fingerprint` and * `scope: ["sat:refresh"]` (both currently optional on that endpoint) to enable * the Client Bound SAT path; otherwise provide `refresh()` here. */ interface CredentialProvider { /** * Obtains the initial credentials. Called once during client initialization. * * Implementor responsibilities: * - Resolve with a valid {@link SDKCredential} on success. * - Reject (throw) on failure — this will cause client initialization to fail. * - When `context.fingerprint` is provided, forward it to the server-side token * endpoint with `scope: "sat:refresh"` to enable automatic token refresh. * Ignoring `context.fingerprint` causes the SDK to fall back to `refresh()` * (if provided) or end the session at expiry. * * SDK behavior: * - Awaits this method before establishing the WebSocket connection. * - On rejection, propagates the error to the caller of `SignalWire()`. */ authenticate(context?: AuthenticateContext): Promise; /** * Obtains fresh credentials before the current ones expire. Optional. * * Implementor responsibilities: * - Resolve with a new {@link SDKCredential} containing an updated `token` (or `authorizationState`) and `expiry_at`. * - Reject (throw) if refresh is not possible — the SDK will stop the refresh schedule. * * SDK behavior: * - Only called when `expiry_at` was set on the previous credential AND the * SAT does not carry `sat:refresh` scope (otherwise the SDK refreshes * internally via Client Bound SAT). See the precedence table above. * - Scheduled automatically before expiry; implementors do not need to manage timing. * - On rejection, the refresh schedule stops and the session continues with the * current credentials until they expire. */ refresh?: () => Promise; } /** * Provides custom WebRTC API implementations for non-standard environments. * * Use this when the standard browser WebRTC APIs are not available or need * to be replaced (e.g., Citrix HDX, React Native, Electron). * * @example * ```typescript * import { SignalWire, type WebRTCApiProvider } from '@signalwire/js'; * * const provider: WebRTCApiProvider = { * RTCPeerConnection: CustomRTCPeerConnection, * mediaDevices: { * getUserMedia: (constraints) => customGetUserMedia(constraints), * enumerateDevices: () => customEnumerateDevices(), * addEventListener: (type, listener) => { ... }, * removeEventListener: (type, listener) => { ... }, * } * }; * * const client = new SignalWire(credentialProvider, { webRTCApiProvider: provider }); * ``` */ interface WebRTCApiProvider { /** Custom RTCPeerConnection constructor. */ RTCPeerConnection: typeof RTCPeerConnection; /** Custom media device access. Only the methods used by the SDK are required. */ mediaDevices: WebRTCMediaDevices; } /** * Subset of the `MediaDevices` interface actually used by the SDK. * * Implementations only need to provide these methods — the full browser * `MediaDevices` type is intentionally not required so that React Native * and other non-browser environments can conform without polyfilling * unused APIs. */ interface WebRTCMediaDevices { getUserMedia(constraints: MediaStreamConstraints): Promise; getDisplayMedia?(options: DisplayMediaStreamOptions): Promise; enumerateDevices(): Promise; addEventListener(type: string, listener: EventListenerOrEventListenerObject): void; removeEventListener(type: string, listener: EventListenerOrEventListenerObject): void; } //#endregion //#region src/managers/StorageManager.d.ts declare class StorageManager { private storageImpl; constructor(storageImpl?: Storage); /** * Validates that a value can be safely serialized to JSON * @throws SerializationError if value contains non-serializable types */ private serialize; /** * Stores a value in storage * @throws InvalidStorageValueError if value contains non-serializable types * @throws SerializationError if JSON serialization fails * @throws StorageWriteError if writing to storage fails */ setItem(key: string, value: unknown, scope?: StorageScope): Promise; /** * Retrieves a value from storage * * This method distinguishes between: * - Storage errors (network, permission, etc.) - these are thrown * - JSON parse errors - these trigger onParseError and return raw string * - Missing keys - returns null * * @returns The parsed value, raw string (on parse error), or null * @throws StorageReadError */ getItem(key: string, scope?: StorageScope): Promise; /** * Removes a value from storage * @throws Error from underlying storage implementation */ removeItem(key: string, scope?: StorageScope): Promise; /** * Clears all SDK keys from both 'local' and 'session' scopes. * @throws StorageWriteError if clearing fails */ clearAll(): Promise; } //#endregion //#region src/behaviors/Destroyable.d.ts declare abstract class Destroyable { protected subscriptions: Subscription[]; protected subjects: Subject[]; protected _destroyed$: Subject; private _observableCache?; destroy(): void; protected cachedObservable(key: string, factory: () => Observable): Observable; /** * Like `cachedObservable`, but defers emissions to the microtask queue * via `observeOn(asapScheduler)`. * * Use ONLY for public-facing observable getters that external consumers * subscribe to. Prevents a class of bugs where `BehaviorSubject` or * `ReplaySubject` replays synchronously during `subscribe()`, before * the subscription variable is assigned in the caller's scope. * * Do NOT use for observables consumed internally by the SDK — internal * code using `subscribeTo()`, `firstValueFrom()`, or `withLatestFrom()` * depends on synchronous emission delivery. */ protected publicCachedObservable(key: string, factory: () => Observable): Observable; /** * Wraps an observable so emissions are deferred to the microtask queue. * * Use ONLY for public-facing getters that expose a subject via * `.asObservable()` without going through `cachedObservable`. * * Do NOT use for observables consumed internally by the SDK. */ protected deferEmission(observable: Observable): Observable; protected subscribeTo(observable: Observable, observerOrNext: Partial> | ((value: T) => void) | undefined): void; protected createSubject(): Subject; protected createReplaySubject(bufferSize?: number, windowTime?: number): ReplaySubject; protected createBehaviorSubject(initialValue: T): BehaviorSubject; /** * Observable that emits when the instance is destroyed */ get destroyed$(): Observable; } //#endregion //#region src/core/types/media.types.d.ts /** WebRTC transceiver direction for a single media kind. */ type MediaDirection = RTCRtpTransceiverDirection; /** Audio and video directions "inactive" | "recvonly" | "sendonly" | "sendrecv" | "stopped" */ interface MediaDirections { /** Audio direction */ audio: MediaDirection; /** Video direction */ video: MediaDirection; } /** Options for starting a screen share. */ interface ScreenShareOptions { /** * Request the shared surface's audio. Defaults to `false`. * * Whether audio can actually be captured depends on the browser, the OS and * the surface the user picks — Chrome offers it for tabs and windows, and a * share the user grants without audio yields a video-only stream. */ audio?: boolean; } /** Options controlling which media tracks to send and receive. */ interface MediaOptions { /** Enable audio input. Defaults to `true` when not specified. */ audio?: boolean; /** Enable video input. Defaults to `false` when not specified. */ video?: boolean; /** Custom constraints for the audio input track. */ inputAudioDeviceConstraints?: MediaTrackConstraints; /** Custom constraints for the video input track. */ inputVideoDeviceConstraints?: MediaTrackConstraints; /** Pre-existing audio stream to use instead of `getUserMedia`. */ inputAudioStream?: MediaStream; /** Pre-existing video stream to use instead of `getUserMedia`. */ inputVideoStream?: MediaStream; /** Whether to receive remote audio. */ receiveAudio?: boolean; /** Whether to receive remote video. */ receiveVideo?: boolean; /** * When local media can't be acquired (permission denied or device * unavailable), continue the call in receive-only mode instead of failing. * Defaults to `true`. Ignored when the call is not set to receive any media. */ fallbackToReceiveOnly?: boolean; } //#endregion //#region src/containers/PreferencesContainer.d.ts /** * Public preferences API for configuring SDK behavior. * * Exposed as {@link SignalWire.preferences}. All timeout values * are in seconds when accessed through this class. * * When {@link enableSavePreferences} is called, preferences are * automatically loaded from storage and synced back on every change. */ declare class ClientPreferences { private _storage; /** * Enables persistence of preferences to storage. * Loads any previously saved preferences and syncs future changes. */ enableSavePreferences(storage: StorageManager): void; /** WebSocket connection timeout in seconds. */ get connectionTimeout(): number; set connectionTimeout(seconds: number); /** Timeout for reconnecting to previously attached calls, in seconds. */ get reconnectCallsTimeout(): number; set reconnectCallsTimeout(seconds: number); /** Minimum reconnection backoff delay in seconds. */ get reconnectDelayMin(): number; set reconnectDelayMin(seconds: number); /** Maximum reconnection backoff delay in seconds. */ get reconnectDelayMax(): number; set reconnectDelayMax(seconds: number); /** Custom relay host URL. Empty string uses the default. */ get relayHost(): string; set relayHost(value: string); /** Whether to receive remote video by default. */ get receiveVideo(): boolean; set receiveVideo(value: boolean); /** Whether to receive remote audio by default. */ get receiveAudio(): boolean; set receiveAudio(value: boolean); /** Preferred audio input device for new calls. */ get preferredAudioInput(): MediaDeviceInfo | null; set preferredAudioInput(value: MediaDeviceInfo | null); /** Preferred audio output device for new calls. */ get preferredAudioOutput(): MediaDeviceInfo | null; set preferredAudioOutput(value: MediaDeviceInfo | null); /** Preferred video input device for new calls. */ get preferredVideoInput(): MediaDeviceInfo | null; set preferredVideoInput(value: MediaDeviceInfo | null); /** Default audio input track constraints. */ get inputAudioConstraints(): MediaTrackConstraints | undefined; set inputAudioConstraints(value: MediaTrackConstraints | undefined); /** Default video input track constraints. */ get inputVideoConstraints(): MediaTrackConstraints | undefined; set inputVideoConstraints(value: MediaTrackConstraints | undefined); /** Debounce time for device change events, in seconds. */ get deviceDebounceTime(): number; set deviceDebounceTime(seconds: number); /** Polling interval for device enumeration, in seconds. */ get devicePollingInterval(): number; set devicePollingInterval(seconds: number); /** Whether to filter out UDP-based ICE servers. */ get disableUdpIceServers(): boolean; set disableUdpIceServers(value: boolean); /** Whether to force TURN relay-only ICE candidates. */ get relayOnly(): boolean; set relayOnly(value: boolean); /** Timeout for individual ICE candidate gathering, in seconds. */ get iceCandidateTimeout(): number; set iceCandidateTimeout(seconds: number); /** Timeout for the entire ICE gathering phase, in seconds. */ get iceGatheringTimeout(): number; set iceGatheringTimeout(seconds: number); /** Custom ICE servers for TURN/STUN configuration. */ get iceServers(): RTCIceServer[] | undefined; set iceServers(value: RTCIceServer[] | undefined); /** Custom user variables attached to calls. */ get userVariables(): Record; set userVariables(value: Record); /** Stats polling interval in milliseconds. */ get statsPollingInterval(): number; set statsPollingInterval(value: number); /** Number of baseline samples for stats monitoring. */ get statsBaselineSamples(): number; set statsBaselineSamples(value: number); /** Duration in ms with no inbound packets before a critical issue is emitted. */ get statsNoPacketThreshold(): number; set statsNoPacketThreshold(value: number); /** Multiplier for RTT spike detection relative to baseline. */ get statsRttSpikeMultiplier(): number; set statsRttSpikeMultiplier(value: number); /** Packet loss fraction threshold (0-1) for issue detection. */ get statsPacketLossThreshold(): number; set statsPacketLossThreshold(value: number); /** Multiplier for jitter spike detection relative to baseline. */ get statsJitterSpikeMultiplier(): number; set statsJitterSpikeMultiplier(value: number); /** Number of seconds of metrics history to retain. */ get statsHistorySize(): number; set statsHistorySize(value: number); /** Maximum keyframe requests in a burst window. */ get keyframeMaxBurst(): number; set keyframeMaxBurst(value: number); /** Keyframe burst window duration in milliseconds. */ get keyframeBurstWindow(): number; set keyframeBurstWindow(value: number); /** Cooldown period in ms after keyframe burst limit is reached. */ get keyframeCooldown(): number; set keyframeCooldown(value: number); /** Minimum time in ms between re-INVITE attempts. */ get reinviteDebounceTime(): number; set reinviteDebounceTime(value: number); /** Maximum re-INVITE attempts per call. */ get reinviteMaxAttempts(): number; set reinviteMaxAttempts(value: number); /** Timeout in ms for a single re-INVITE attempt. */ get reinviteTimeout(): number; set reinviteTimeout(value: number); /** Recovery signal debounce window in seconds. */ get recoveryDebounceTime(): number; set recoveryDebounceTime(seconds: number); /** Cooldown period between recovery attempts in seconds. */ get recoveryCooldown(): number; set recoveryCooldown(seconds: number); /** Grace period before treating ICE 'disconnected' as failure, in seconds. */ get iceDisconnectedGracePeriod(): number; set iceDisconnectedGracePeriod(seconds: number); /** Timeout for a single ICE restart attempt in seconds. */ get iceRestartTimeout(): number; set iceRestartTimeout(seconds: number); /** Maximum recovery attempts before giving up. */ get maxRecoveryAttempts(): number; set maxRecoveryAttempts(value: number); /** Whether relay-only escalation is enabled as a last-resort recovery tier. */ get enableRelayFallback(): boolean; set enableRelayFallback(value: boolean); /** Whether browser network change detection (online/offline) is enabled. */ get enableNetworkChangeDetection(): boolean; set enableNetworkChangeDetection(value: boolean); /** Whether server-sent media-timeout hangups are intercepted for recovery. */ get enableServerHangupInterception(): boolean; set enableServerHangupInterception(value: boolean); /** Whether device selections are persisted to storage. */ get persistDeviceSelection(): boolean; set persistDeviceSelection(value: boolean); /** Whether device changes are auto-applied to active calls. */ get syncDevicesToActiveCalls(): boolean; set syncDevicesToActiveCalls(value: boolean); /** Whether to auto-mute video when the tab becomes hidden. */ get autoMuteVideoOnHidden(): boolean; set autoMuteVideoOnHidden(value: boolean); /** Whether to re-enumerate devices when the page becomes visible. */ get refreshDevicesOnVisible(): boolean; set refreshDevicesOnVisible(value: boolean); /** Whether to check peer connection health when the page becomes visible. */ get checkConnectionOnVisible(): boolean; set checkConnectionOnVisible(value: boolean); /** Default audio track constraints applied when no explicit constraints are provided. */ get defaultAudioConstraints(): MediaTrackConstraints | undefined; set defaultAudioConstraints(value: MediaTrackConstraints | undefined); /** Default video track constraints applied when video is enabled without explicit constraints. */ get defaultVideoConstraints(): MediaTrackConstraints | undefined; set defaultVideoConstraints(value: MediaTrackConstraints | undefined); /** Whether stereo Opus is enabled globally. */ get stereoAudio(): boolean; set stereoAudio(value: boolean); /** Whether automatic video degradation on low bandwidth is enabled. */ get enableAutoDegradation(): boolean; set enableAutoDegradation(value: boolean); /** Bitrate in kbps below which video is automatically disabled. */ get degradationBitrateThreshold(): number; set degradationBitrateThreshold(value: number); /** Bitrate in kbps above which video is automatically re-enabled. */ get degradationRecoveryThreshold(): number; set degradationRecoveryThreshold(value: number); /** Preferred video codecs in priority order. */ get preferredVideoCodecs(): string[]; set preferredVideoCodecs(value: string[]); /** Preferred audio codecs in priority order. */ get preferredAudioCodecs(): string[]; set preferredAudioCodecs(value: string[]); /** Saves current preferences to storage (fire-and-forget). */ private _saveToStorage; /** Loads preferences from storage and applies them to the container. */ private _loadFromStorage; } //#endregion //#region src/controllers/HTTPRequestController.d.ts type HTTPRequestStatus = 'idle' | 'requesting' | 'success' | 'error'; interface HTTPRequestControllerOptions { maxRetries?: number; retryDelayMin?: number; retryDelayMax?: number; requestTimeout?: number; } declare class HTTPRequestController extends Destroyable { private baseURL; private readonly getCredential; private static readonly defaultMaxRetries; private static readonly defaultRetryDelayMinMs; private static readonly defaultRetryDelayMaxMs; private static readonly defaultRequestTimeoutMs; /** Sensitive field names to mask in debug logs. */ private static readonly SENSITIVE_BODY_FIELDS; private readonly maxRetries; private readonly retryDelayMin; private readonly retryDelayMax; private readonly requestTimeout; private _responses$; private _errors$; private _status$; constructor(baseURL: string, getCredential: () => SDKCredential, options?: HTTPRequestControllerOptions); get status$(): Observable; get status(): HTTPRequestStatus; get responses$(): Observable; get errors$(): Observable; request(request: HTTPRequest): Promise; private executeWithRetry; private executeRequest; private buildURL; private buildHeaders; /** * Sanitizes a request body for debug logging by masking sensitive fields. */ private sanitizeBody; private convertResponse; } //#endregion //#region src/behaviors/Fetchable.d.ts declare abstract class Fetchable extends Destroyable { fromPath: string; protected http: HTTPRequestController; fetched$: Observable; constructor(fromPath: string, http: HTTPRequestController); protected abstract populateInstance(data: T): void; private fetch; } //#endregion //#region src/core/types/address.types.d.ts /** * Pure address-related types (no implementation dependencies) * Types that reference model implementations are in interfaces.ts */ /** Raw address response from the SignalWire Fabric API. */ interface GetAddressResponse { /** Unique address identifier. */ id: string; /** Human-readable display name. */ display_name: string; /** Resource name (used as a URI for dialing). */ name: string; /** URL for an avatar or preview image. */ preview_url?: string; /** URL for a cover image. */ cover_url?: string; /** Underlying resource identifier. */ resource_id: string; /** Type of the underlying resource. */ type: ResourceType; /** Available communication channels for this address. */ channels: { /** Audio-only channel URI. */ audio?: string; /** Messaging channel URI. */ messaging?: string; /** Video channel URI. */ video?: string; }; /** Whether the address resource is currently locked. */ locked: boolean; /** ISO 8601 timestamp when the address was created. */ created_at: string; } //#endregion //#region src/core/types/crypto.types.d.ts /** Parameters for creating an HTTP DPoP proof (for Prime API endpoints). */ interface DPoPHttpProofParams { /** HTTP method (e.g., "POST"). */ readonly method: string; /** Request URI — should be the full URL per RFC 9449 (e.g., "https://fabric.signalwire.com/api/..."). */ readonly uri: string; /** Access token to bind via `ath` claim (SHA-256 hash). Used for resource endpoints, not token endpoints. */ readonly accessToken?: string; } /** Parameters for creating an RPC DPoP proof (for switchblade WebSocket methods). */ interface DPoPRpcProofParams { /** RPC method name (e.g., "signalwire.connect" or "signalwire.reauthenticate"). */ readonly method: string; } /** SAT claims returned by /api/fabric/subscriber/info. */ interface SATClaims { /** Token scopes (e.g., ["sat:refresh"]). */ scope?: string[]; /** Confirmation claim binding the token to a key. */ cnf?: { jkt: string; }; /** Token expiry timestamp in seconds since epoch. */ expires_at?: number; } //#endregion //#region src/core/types/user.types.d.ts /** Raw user profile response from the SignalWire Fabric API. */ interface GetUserInfoResponse { /** Unique user identifier. */ id: string; /** User's email address. */ email: string; /** User's first name. */ first_name?: string; /** User's last name. */ last_name?: string; /** User's display name. */ display_name?: string; /** User's job title. */ job_title?: string; /** User's time zone offset. */ time_zone?: number; /** User's country. */ country?: string; /** User's region or state. */ region?: string; /** User's company name. */ company_name?: string; /** Key for push notification delivery. */ push_notification_key: string; /** Application-level settings for this user. */ app_settings?: { /** Display name configured at the application level. */ display_name: string; /** Permission scopes granted to this user. */ scopes: string[]; }; /** Fabric addresses associated with this user. */ fabric_addresses: GetAddressResponse[]; /** Filtered SAT claims (scope, cnf, expires_at) returned when the token has special capabilities. */ sat_claims?: SATClaims; } //#endregion //#region src/core/entities/User.d.ts /** User online presence state. */ type UserPresence = 'online' | 'offline' | 'busy'; /** * Authenticated user profile. * * Fetched automatically when a {@link SignalWire} connects. * Contains identity, contact, and organization details. */ declare class User extends Fetchable { /** Unique user identifier. */ id: string; /** User email address. */ email: string; /** First name. */ firstName?: string; /** Last name. */ lastName?: string; /** Display name shown to other participants. */ displayName?: string; /** Job title. */ jobTitle?: string; /** Time zone offset. */ timeZone?: number; /** Country code. */ country?: string; /** Region/state. */ region?: string; /** Company name. */ companyName?: string; /** Push notification key for mobile/web push. */ pushNotificationKey: string; /** Application-level settings (display name, permission scopes). */ appSettings?: { displayName: string; scopes: string[]; }; /** Fabric addresses associated with this user. */ addresses: GetAddressResponse[]; /** Filtered SAT claims when the token has special capabilities (e.g., refresh scope). */ satClaims?: SATClaims; constructor(http: HTTPRequestController); protected populateInstance(data: GetUserInfoResponse): void; } //#endregion //#region src/core/types/call.types.d.ts /** SDP role for the peer connection negotiation. */ type RTCPeerConnectionType = 'offer' | 'answer'; /** Purpose of the peer connection (primary call, screen share, or additional device). */ type RTCPeerConnectionPropose = 'main' | 'screenshare' | 'additional-device'; /** States during call connection establishment. */ type CallConnectStates = 'connecting' | 'connected'; /** Lifecycle states of the signaling protocol for a call. */ type SignalingCallStates = 'created' | 'ringing' | 'answered' | 'ending' | 'ended'; /** Whether the call is inbound (received) or outbound (initiated). */ type CallDirection = 'inbound' | 'outbound'; /** Playback state of media being played into a call. */ type CallPlayState = 'playing' | 'paused' | 'finished'; /** Common parameters shared by all call device types. */ interface CallDeviceCommonParams { /** Optional SIP headers to include in the call setup. */ headers?: unknown[]; } /** Parameters for a WebRTC or SIP call device. */ interface CallDeviceWebRTCOrSIPParams extends CallDeviceCommonParams { /** Source address or URI for the call. */ from: string; /** Destination address or URI for the call. */ to: string; } /** Parameters for a phone (PSTN) call device. */ interface CallDevicePhoneParams extends CallDeviceCommonParams { /** Caller phone number (E.164 format). */ from_number: string; /** Destination phone number (E.164 format). */ to_number: string; } /** A WebRTC or SIP call device descriptor. */ interface CallDeviceWebRTCOrSIP { /** Transport type for the device. */ type: 'webrtc' | 'sip'; /** Connection parameters for the device. */ params: CallDeviceWebRTCOrSIPParams; } /** A phone (PSTN) call device descriptor. */ interface CallDevicePhone { /** Transport type for the device. */ type: 'phone'; /** Connection parameters for the device. */ params: CallDevicePhoneParams; } /** Discriminated union of call device types (WebRTC, SIP, or phone). */ type CallDevice = CallDeviceWebRTCOrSIP | CallDevicePhone; /** * Feature capability string that controls what actions a participant can perform. * * Capabilities are organized into categories: * - **self.\*** — Actions the local participant can perform on themselves (mute, deaf, volume, position, meta). * - **member.\*** — Actions that can be performed on other participants. * - **layout.\*** — Layout management for the video canvas. * - **digit.\*** — DTMF digit sending. * - **vmuted.\*** — Visibility control for muted video participants. * - **lock.\*** — Room lock/unlock control. * - **device** / **screenshare** — Device and screen share capabilities. * - **end** — Permission to end the call or room. */ type Capability = 'self' | 'self.mute' | 'self.mute.audio' | 'self.mute.audio.on' | 'self.mute.audio.off' | 'self.mute.video' | 'self.mute.video.on' | 'self.mute.video.off' | 'self.deaf' | 'self.deaf.on' | 'self.deaf.off' | 'self.microphone' | 'self.microphone.volume.set' | 'self.microphone.sensitivity.set' | 'self.speaker' | 'self.speaker.volume.set' | 'self.position.set' | 'self.meta' | 'self.audioflags.set' | 'member' | 'member.mute' | 'member.mute.audio' | 'member.mute.audio.on' | 'member.mute.audio.off' | 'member.mute.video' | 'member.mute.video.on' | 'member.mute.video.off' | 'member.deaf' | 'member.deaf.on' | 'member.deaf.off' | 'member.microphone' | 'member.microphone.volume.set' | 'member.microphone.sensitivity.set' | 'member.speaker' | 'member.speaker.volume.set' | 'member.position.set' | 'member.meta' | 'member.audioflags.set' | 'layout' | 'layout.set' | 'digit' | 'digit.send' | 'vmuted' | 'vmuted.hide' | 'vmuted.hide.on' | 'vmuted.hide.off' | 'lock' | 'lock.on' | 'lock.off' | 'device' | 'screenshare' | 'end'; /** * Position of a participant's video within the layout canvas. * * - `'auto'` — Automatically positioned by the layout engine. * - `` `reserved-${number}` `` — A reserved slot in the layout (e.g., `'reserved-0'`). * - `` `standard-${number}` `` — A standard slot in the layout (e.g., `'standard-1'`). * - `'off-canvas'` — Participant is not visible in the layout. * - `'playback'` — Playback position for media streams. * - `'full-screen'` — Participant occupies the entire canvas. */ type VideoPosition = 'auto' | `reserved-${number}` | `standard-${number}` | 'off-canvas' | 'playback' | 'full-screen'; //#endregion //#region src/core/RPCMessages/types/common.d.ts interface MemberTarget { member_id: string; call_id: string; node_id: string; } interface Member { room_session_id: string; room_id: string; member_id: string; call_id: string; name: string; type: 'member' | 'screen' | 'device' | (string & {}); parent_id?: string; requested_position?: string; handraised: boolean; visible: boolean; audio_muted: boolean; video_muted: boolean; deaf: boolean; input_volume?: number; output_volume?: number; input_sensitivity?: number; echo_cancellation: boolean; auto_gain: boolean; noise_suppression: boolean; lowbitrate: boolean; denoise: boolean; talking?: boolean; isAudience?: boolean; meta?: Record; subscriber_id: string; address_id: string; updated?: string[]; node_id: string; } interface MemberTalkingInfo { member_id: string; talking: boolean; node_id: string; } interface RoomSession { room_session_id: string; room_id: string; event_channel: string; name: string; layout_name: string; display_name: string; recording: boolean; streaming: boolean; prioritize_handraise: boolean; hide_video_muted: boolean; locked: boolean; meta: Record; members: Member[]; recordings: Record[]; streams: Record[]; playbacks: Record[]; } interface LayoutLayer { layer_index: number; z_index: number; member_id?: string; playing_file: boolean; position: VideoPosition; reservation: string; visible: boolean; x: number; y: number; width: number; height: number; } interface Layout { layers: LayoutLayer[]; id: string; name: string; } interface ConversationDetails { status: string; start_time: number; end_time?: number; } //#endregion //#region src/core/RPCMessages/types/verto.d.ts interface VertoParams { userVariables?: Record; } //#endregion //#region src/core/RPCMessages/types/events.d.ts interface SignalwireAuthorizationStatePayload { authorization_state: string; } interface WebrtcMessagePayload { jsonrpc: '2.0'; id: number; method: string; params: VertoParams; } interface CallJoinedPayload { room_session: RoomSession; room_id: string; room_session_id: string; call_id: string; member_id: string; capabilities: string[]; origin_call_id: string; } interface CallLeftPayload { room_session: RoomSession; room_id: string; room_session_id: string; call_id: string; member_id: string; origin_call_id: string; reason: string; } interface MemberUpdatedPayload { member: Member; room_id: string; room_session_id: string; } interface MemberJoinedPayload { member: Member; room_id: string; room_session_id: string; } interface MemberLeftPayload { member: Member; room_id: string; room_session_id: string; reason: string; } interface MemberTalkingPayload { member: MemberTalkingInfo; room_id: string; room_session_id: string; } interface LayoutChangedPayload { room_id: string; room_session_id: string; layout: Layout; } interface CallUpdatedPayload { room_session: RoomSession; room_id: string; room_session_id: string; } interface RoomUpdatedPayload { room_session: RoomSession; room_id: string; room_session_id: string; } /** * Describes the peer (remote) call referenced from a call.state event. * * Mirrors the backend (relay.c) `peer` shape. */ interface CallStateRelatedCall { call_id?: string; node_id?: string; } interface CallStatePayload { call_id: string; node_id: string; segment_id: string; call_state: SignalingCallStates; direction: CallDirection; device: CallDevice; /** * Epoch timestamps for the call lifecycle. Optional because pre-answer * states (e.g. `created`, `ringing`) do not have an `answer_time`/`end_time` * and the backend reports them as `0` or omits them. */ start_time?: number; answer_time?: number; end_time?: number; room_session_id: string; /** The peer (remote) call this call is connected to, if any. */ peer?: CallStateRelatedCall; /** Application-defined tag associated with the call. */ tag?: string; } interface CallPlayPayload { control_id: string; call_id: string; node_id: string; state: CallPlayState; room_session_id: string; } interface CallConnectPayload { connect_state: CallConnectStates; call_id: string; node_id: string; segment_id: string; room_session_id: string; peer?: { call_id: string; node_id: string; device: CallDevice; }; } interface ConversationMessagePayload { id: string; type: string; subtype: string; kind: string; hidden: boolean; group_id: string; from_fabric_address_id: string; ts: number; metadata: Record; details: ConversationDetails; text: string | null; conversation_name: string; user_name: string; } //#endregion //#region src/behaviors/types/collection.types.d.ts interface Entity { id: string; } type FetchController = { [key in keyof Partial]: (v?: unknown) => Promise } & { next: () => Promise; hasMore: boolean | undefined; filter?: (item: T) => item is T; mapper?: (item: unknown) => T; }; interface Collection { loading$: Observable; loading: boolean; hasMore$: Observable; hasMore: boolean; values: T[]; values$: Observable; get$(id: string): Observable | undefined; find$(key: keyof T, value: unknown): Promise | undefined>; loadMore(): void; destroy(): void; } //#endregion //#region src/behaviors/Collection.d.ts declare class EntityCollection extends Destroyable implements Collection { private fetchController; private update$; private readonly onError?; hasMore$: Observable; private collectionData; private observablesRegistry; private upsertData; private _loading$; private _values$; private _hasMore$; constructor(fetchController: FetchController, update$: Observable>, onError?: ((error: Error) => void) | undefined); get loading$(): Observable; get loading(): boolean; get values$(): Observable; get hasMore(): boolean; get updated$(): Observable; get values(): T[]; private init; private fetchMore; private tryFetch; get$(id: string): Observable | undefined; find$(key: keyof T, value: unknown): Promise | undefined>; loadMore(): void; destroy(): void; } declare class EntityCollectionTransformed implements Collection { private originalCollection; private filter; private mapper; private _values$?; constructor(originalCollection: EntityCollection, filter?: (i: unknown) => i is O, mapper?: (item: O) => T); get loading$(): Observable; get loading(): boolean; get hasMore$(): Observable; get hasMore(): boolean; get values(): T[]; get values$(): Observable; get$(id: string): Observable | undefined; find$(key: keyof T, value: unknown): Promise | undefined>; loadMore(): void; destroy(): void; } //#endregion //#region src/core/entities/types/participant.types.d.ts /** Options for selecting a media device. */ interface SelectDeviceOptions { savePreference?: boolean; } //#endregion //#region src/controllers/RTCStatsMonitor.d.ts interface NetworkIssue { type: 'no_inbound_audio' | 'no_inbound_video' | 'high_rtt' | 'high_packet_loss' | 'high_jitter' | 'ice_disconnected'; severity: 'warning' | 'critical'; timestamp: number; value?: number; threshold?: number; } interface NetworkMetrics { timestamp: number; audio: { packetsReceived: number; packetsLost: number; jitter: number; }; video: { packetsReceived: number; packetsLost: number; }; roundTripTime: number; availableOutgoingBitrate?: number; } //#endregion //#region src/managers/types/verto-manager.types.d.ts type ScreenShareStatus = 'none' | 'starting' | 'started' | 'stopping'; type SignalingStatus = Extract; interface TransferOptions { destination: string; } //#endregion //#region src/core/errors.d.ts declare class UnexpectedError extends Error { at?: string | undefined; constructor(at?: string | undefined, options?: ErrorOptions); } declare class InvalidCredentialsError extends Error { reason: string; constructor(reason?: string, options?: ErrorOptions); } /** * Semantic category of a call-lifecycle error. * * - `'media'` – RTCPeerConnection / media device failure * - `'signaling'` – Verto / JSON-RPC protocol error * - `'timeout'` – Call setup timed out waiting for a response * - `'rejected'` – Remote side rejected the call * - `'network'` – Transport lost during an active call * - `'internal'` – Unexpected / unknown error */ type CallErrorKind = 'media' | 'signaling' | 'timeout' | 'rejected' | 'network' | 'internal'; /** * Structured error emitted on `call.errors$`. * * Provides actionable metadata so consumers can react without * resorting to `instanceof` checks on raw `Error` objects. */ interface CallError { /** Semantic category of the error. */ readonly kind: CallErrorKind; /** * Whether the error terminates the call. * When `true`, the call will automatically transition to `'failed'` * and be destroyed — no further action is needed from the consumer. */ readonly fatal: boolean; /** The underlying error. */ readonly error: Error; /** ID of the call that produced this error. */ readonly callId: string; /** * Which peer connection failed. Auxiliary legs are never fatal, so a consumer * can surface "screen share failed, call continues". Absent for call- and * session-level errors. */ readonly leg?: RTCPeerConnectionPropose; /** `callId` is always the call's id, never the leg's. Use this for the leg. */ readonly legId?: string; } declare class CallCreateError extends Error { message: string; error: unknown; direction: 'inbound' | 'outbound'; constructor(message: string, error?: unknown, direction?: 'inbound' | 'outbound', options?: ErrorOptions); } declare class CallNotReadyError extends Error { callId: string; constructor(callId: string, options?: ErrorOptions); } declare class ParticipantNotReadyError extends Error { memberId: string; constructor(memberId: string, options?: ErrorOptions); } declare class VertoPongError extends Error { originalError: unknown; constructor(originalError: unknown); } declare class MessageParseError extends Error { originalError: unknown; constructor(originalError: unknown); } declare class CollectionFetchError extends Error { operation: string; originalError: unknown; constructor(operation: string, originalError: unknown); } /** * An auxiliary leg did not connect within its budget. Typed rather than a bare * RxJS `TimeoutError` so the leg and cause survive. */ declare class AuxiliaryLegTimeoutError extends Error { readonly leg: RTCPeerConnectionPropose; readonly originalError?: Error | undefined; constructor(leg: RTCPeerConnectionPropose, originalError?: Error | undefined); } /** * An auxiliary leg was removed before it finished connecting. * * Typed rather than a bare resolve so a caller awaiting the start can tell a * cancel apart from a share that actually came up — the public methods return * `void`, so the promise is the only signal they have. */ declare class AuxiliaryLegCancelledError extends Error { readonly leg: RTCPeerConnectionPropose; constructor(leg: RTCPeerConnectionPropose); } declare class MediaTrackError extends Error { operation: string; kind: string; originalError: unknown; constructor(operation: string, kind: string, originalError: unknown); } /** * Failure to acquire local media (camera, microphone, or screen capture) * via `getUserMedia`/`getDisplayMedia`. * * Non-fatal by default: screenshare and additional-device failures never * end the call, and main-connection failures degrade to receive-only when * possible. The wrapping site sets `fatal` to `true` only when the call * cannot continue (receive-only fallback disabled or no receive intent). */ declare class MediaAccessError extends Error { /** The SDK operation that failed, e.g. `'acquireLocalMedia'`, `'startScreenShare'`, `'addInputDevice'`. */ operation: string; /** The media being acquired: `'audio' | 'video' | 'audiovideo' | 'screen'`. */ media: string; /** The raw `getUserMedia`/`getDisplayMedia` error (typically a `DOMException`). */ originalError: unknown; /** Whether this failure terminates the call. */ readonly fatal: boolean; constructor(/** The SDK operation that failed, e.g. `'acquireLocalMedia'`, `'startScreenShare'`, `'addInputDevice'`. */ operation: string, /** The media being acquired: `'audio' | 'video' | 'audiovideo' | 'screen'`. */ media: string, /** The raw `getUserMedia`/`getDisplayMedia` error (typically a `DOMException`). */ originalError: unknown, /** Whether this failure terminates the call. */ fatal?: boolean); /** True when the underlying failure is a permission denial (user or policy). */ get denied(): boolean; } /** * Thrown by `startScreenShare()` when the call is already sharing a screen. * * A call carries at most one screen share. Accepting a second one would * overwrite the only reference the SDK holds to the first, leaving it * capturing and sending with no way to stop it — so the second request is * rejected and the live share is left untouched. Call `stopScreenShare()` * first to replace it. */ declare class ScreenShareAlreadyActiveError extends Error { /** Id of the screen share leg that is already active. */ readonly screenShareId: string; constructor(/** Id of the screen share leg that is already active. */ screenShareId: string, options?: ErrorOptions); } declare class DPoPInitError extends Error { originalError: unknown; constructor(originalError: unknown, message?: string); } /** * Error thrown when a recovery attempt fails. * * Carries the recovery action and attempt number for diagnostic purposes. */ declare class RecoveryError extends Error { action: string; attempt: number; originalError?: unknown | undefined; constructor(action: string, attempt: number, originalError?: unknown | undefined); } /** * Error thrown when getUserMedia fails with OverconstrainedError * and all fallback levels have been exhausted. */ declare class OverconstrainedFallbackError extends Error { deviceKind: string; originalError?: unknown | undefined; constructor(deviceKind: string, originalError?: unknown | undefined); } /** * Error thrown when the preflight connectivity test fails. */ declare class PreflightError extends Error { phase: string; originalError?: unknown | undefined; constructor(phase: string, originalError?: unknown | undefined); } declare class DeviceTokenError extends Error { originalError?: unknown | undefined; constructor(message: string, originalError?: unknown | undefined); } declare class TokenRefreshError extends Error { originalError?: unknown | undefined; constructor(message: string, originalError?: unknown | undefined); } //#endregion //#region src/core/types/resilience.types.d.ts /** * Types for SDK resilience, recovery, diagnostics, and quality monitoring. * * These types support: * - WebRTC stats monitoring (Section 1) * - Tiered recovery system (Section 2) * - Device recovery events (Section 5) * - Tab visibility handling (Section 4) * - Audio/video constraint management (Section 16) * - Network resilience & recovery pipeline (Section 19) * - Preflight connectivity test (Section 20) * - Call quality score (Section 21) * - Graceful degradation (Section 22) * - Platform capability detection (Section 24) * - Structured diagnostic log export (Section 26) */ /** Simplified quality level for UI indicators, derived from MOS score. */ type QualityLevel = 'excellent' | 'good' | 'fair' | 'poor' | 'critical'; /** * Extended call status that includes the 'recovering' state. * * Used when the SDK is attempting to recover a call after a network * disruption or media failure. */ type ResilienceCallStatus = 'new' | 'trying' | 'ringing' | 'connecting' | 'connected' | 'recovering' | 'disconnecting' | 'disconnected' | 'failed' | 'destroyed'; type NetworkMetrics$1 = NetworkMetrics; /** Event emitted when a recovery action is taken on a call. */ interface RecoveryEvent { /** The recovery action that was taken. */ readonly action: 'keyframe_requested' | 'reinvite_started' | 'reinvite_succeeded' | 'reinvite_failed' | 'reinvite_timeout' | 'max_attempts_reached' | 'call_recovering' | 'call_recovered' | 'call_recovery_failed' | 'signal_reconnect' | 'full_reconnect' | 'video_disabled' | 'video_restored'; /** Human-readable description of why recovery was triggered. */ readonly reason: string; /** Current attempt number (for multi-attempt recoveries). */ readonly attempt?: number; /** Maximum number of attempts allowed. */ readonly maxAttempts?: number; /** Timestamp when the event occurred (epoch ms). */ readonly timestamp: number; } /** State of the recovery pipeline state machine (Section 19.7). */ type RecoveryState = 'idle' | 'debouncing' | 'recovering' | 'cooldown'; /** Event emitted when the SDK auto-switches a device. */ interface DeviceRecoveryEvent { /** The kind of device that was switched. */ readonly kind: 'audioinput' | 'audiooutput' | 'videoinput'; /** The device that was previously selected (null if none). */ readonly previousDevice: MediaDeviceInfo | null; /** The device that was selected as a replacement (null if none available). */ readonly newDevice: MediaDeviceInfo | null; /** The reason for the device switch. */ readonly reason: 'device_disconnected' | 'device_reconnected' | 'session_restored' | 'fallback_to_default' | 'default_changed' | 'ambiguous_match'; } /** * Serializable subset of MediaDeviceInfo for persistence. * * The browser's MediaDeviceInfo interface is not serializable. * This stores the fields needed for device recovery across sessions. */ interface StoredDevicePreference { /** The device ID. */ readonly deviceId: string; /** The human-readable label. */ readonly label: string; /** The device kind. */ readonly kind: MediaDeviceKind; /** The group ID (identifies the physical device). */ readonly groupId: string; } /** Result of a media permissions request (Section 5.10). */ interface PermissionResult { /** Whether audio permission was granted. */ readonly audio: boolean; /** Whether video permission was granted. */ readonly video: boolean; /** The audio device the user selected in the browser picker, if any. */ readonly selectedAudioDevice?: MediaDeviceInfo; /** The video device the user selected in the browser picker, if any. */ readonly selectedVideoDevice?: MediaDeviceInfo; } /** Event emitted when getUserMedia falls back to looser constraints. */ interface ConstraintFallbackEvent { /** The kind of input device. */ readonly kind: 'audioinput' | 'videoinput'; /** The device that was originally requested. */ readonly requestedDevice: MediaDeviceInfo | null; /** The device that the browser actually provided. */ readonly actualDevice: MediaDeviceInfo | null; /** The constraint level that succeeded. */ readonly fallbackLevel: 'exact' | 'preferred' | 'default'; } /** Browser/platform WebRTC capability flags. */ interface PlatformCapabilities { /** Whether screen sharing is supported. */ readonly screenShare: boolean; /** Whether screen share can include system audio (Chrome-only). */ readonly screenShareAudio: boolean; /** Whether simulcast is supported. */ readonly simulcast: boolean; /** Whether insertable streams / encoded transforms are available. */ readonly insertableStreams: boolean; /** Whether setSinkId (audio output selection) is supported. */ readonly audioOutputSelection: boolean; /** List of supported video codecs. */ readonly videoCodecs: readonly string[]; /** List of supported audio codecs. */ readonly audioCodecs: readonly string[]; /** Whether the browser supports WebRTC at all. */ readonly webrtc: boolean; /** Whether getUserMedia is available. */ readonly getUserMedia: boolean; /** Whether getDisplayMedia is available. */ readonly getDisplayMedia: boolean; } /** Options for the preflight connectivity test. */ interface PreflightOptions { /** How long to run the media test in seconds (default: 10). */ readonly duration?: number; /** Skip the media/bandwidth test, only test signaling + TURN + devices. */ readonly skipMediaTest?: boolean; /** Test a specific audio device instead of the currently selected one. */ readonly audioDevice?: MediaDeviceInfo; /** Test a specific video device instead of the currently selected one. */ readonly videoDevice?: MediaDeviceInfo; } /** Results of a preflight connectivity test. */ interface PreflightResult { /** Overall pass/fail. */ readonly ok: boolean; /** Signaling server reachability. */ readonly signaling: { readonly reachable: boolean; readonly rttMs: number; }; /** ICE/TURN connectivity. */ readonly connectivity: { /** 'direct' = host/srflx worked, 'relay' = only TURN relay, 'failed' = nothing. */ readonly type: 'direct' | 'relay' | 'failed'; /** Whether TURN servers are reachable. */ readonly turnReachable: boolean; /** Whether STUN servers are reachable. */ readonly stunReachable: boolean; /** RTT to media server in ms. */ readonly rttMs: number; }; /** Bandwidth estimation (null if skipMediaTest). */ readonly bandwidth: { readonly uploadKbps: number; readonly downloadKbps: number; } | null; /** Device test results. */ readonly devices: { readonly audioInput: { readonly working: boolean; readonly device: MediaDeviceInfo | null; }; readonly videoInput: { readonly working: boolean; readonly device: MediaDeviceInfo | null; }; readonly audioOutput: { readonly available: boolean; readonly device: MediaDeviceInfo | null; }; }; /** Human-readable warnings. */ readonly warnings: readonly string[]; } /** Event emitted when audio constraints change on a call. */ interface AudioConstraintsEvent { /** The new constraints applied. */ readonly constraints: MediaTrackConstraints; /** How the constraints were applied. */ readonly method: 'applyConstraints' | 'trackReplacement'; /** Timestamp when the event occurred (epoch ms). */ readonly timestamp: number; } /** Event emitted when the server pushes media params. */ interface MediaParamsEvent { /** Audio constraints pushed by the server, if any. */ readonly audio?: MediaTrackConstraints; /** Video constraints pushed by the server, if any. */ readonly video?: MediaTrackConstraints; /** Timestamp when the event occurred (epoch ms). */ readonly timestamp: number; /** * `false` when the constraints did not reach every sender of a pushed kind: * the sender carries media the SDK did not capture, the browser refused the * constraints and re-acquisition failed, or the leg sends no media of that * kind at all. The event is emitted whether or not they were applied, but a * push naming a leg this call does not hold emits nothing at all — the event * carries no leg identity to report it against. */ readonly applied: boolean; } /** Structured diagnostic bundle for a session. */ interface SessionDiagnostics { /** SDK version. */ readonly sdkVersion: string; /** Browser/platform user agent string. */ readonly userAgent: string; /** Platform capabilities detected at construction time. */ readonly capabilities: PlatformCapabilities; /** Timeline of significant events during the session. */ readonly events: readonly DiagnosticEvent[]; /** Quality summary per call. */ readonly calls: readonly CallDiagnosticSummary[]; /** Device changes that occurred during the session. */ readonly deviceChanges: readonly DeviceRecoveryEvent[]; /** Current device list snapshot. */ readonly devices: { readonly audioInput: readonly MediaDeviceInfo[]; readonly audioOutput: readonly MediaDeviceInfo[]; readonly videoInput: readonly MediaDeviceInfo[]; }; } /** A single diagnostic event in the session timeline. */ interface DiagnosticEvent { /** Timestamp when the event occurred (epoch ms). */ readonly timestamp: number; /** Category of the event. */ readonly category: 'connection' | 'call' | 'device' | 'recovery' | 'error'; /** Event description string. */ readonly event: string; /** Additional details about the event. */ readonly details?: Readonly>; } /** Quality summary for a single call in the diagnostic bundle. */ interface CallDiagnosticSummary { /** Unique call ID. */ readonly callId: string; /** Whether the call was inbound or outbound. */ readonly direction: 'inbound' | 'outbound'; /** The destination dialed, if outbound. */ readonly destination?: string; /** Total call duration in seconds. */ readonly duration: number; /** Final call status. */ readonly status: string; /** Average MOS quality score over the call. */ readonly avgQualityScore: number; /** Worst (minimum) MOS quality score during the call. */ readonly minQualityScore: number; /** Number of recovery attempts made during the call. */ readonly recoveryAttempts: number; /** ICE candidate types that were used. */ readonly iceCandidateTypes: readonly string[]; /** Final network metrics snapshot at call end. */ readonly finalMetrics: NetworkMetrics$1; } //#endregion //#region src/core/RPCMessages/RPCConnect.d.ts interface Authorization { jti: string; project_id: string; data_zone?: string; scope?: string[]; fabric_subscriber: { version: number; expires_at: number; subscriber_id: string; application_id: string | null; project_id: string; space_id: string; }; cnf?: { jkt: string; }; } //#endregion //#region src/core/utils.d.ts interface PendingRPCOptions { /** * Timeout in milliseconds. Defaults to 5000ms (5 seconds). * If the response is not received within this time, the promise will reject with RPCTimeoutError. */ timeoutMs?: number; /** * Optional AbortSignal for cancellation support. * If the signal is aborted, the promise will reject with an AbortError. */ signal?: AbortSignal; } //#endregion //#region src/core/capabilities/types.d.ts /** * Represents an on/off capability state * Both `on` and `off` can be true if the parent permission grants both */ interface OnOffCapability { readonly on: boolean; readonly off: boolean; } /** * Member-level capabilities for self or other members */ interface MemberCapabilities { readonly muteAudio: OnOffCapability; readonly muteVideo: OnOffCapability; readonly deaf: OnOffCapability; readonly raisehand: OnOffCapability; readonly microphoneVolume: boolean; readonly microphoneSensitivity: boolean; readonly speakerVolume: boolean; readonly position: boolean; readonly meta: boolean; readonly remove: boolean; readonly audioFlags: boolean; readonly denoise: boolean; readonly lowbitrate: boolean; } /** * Call-level capabilities state */ interface CallCapabilitiesState { readonly self: MemberCapabilities; readonly member: MemberCapabilities; readonly end: boolean; readonly setLayout: boolean; readonly sendDigit: boolean; readonly vmutedHide: OnOffCapability; readonly lock: OnOffCapability; readonly device: boolean; readonly screenshare: boolean; } //#endregion //#region src/core/capabilities/SelfCapabilities.d.ts /** * SelfCapabilities manages the capability state for the self participant. * * Capabilities are received from the server via `call.joined` events and determine * what actions the current participant is allowed to perform. * * Each capability is exposed as both: * - An observable (e.g., `end$`) for reactive state management * - A synchronous getter (e.g., `end`) for immediate access * * Member-level capabilities are accessed via the grouped `self` / `member` accessors: * - `capabilities.self.muteAudio` (sync) * - `capabilities.self$` (observable) * * When a new `call.joined` event is received, the capabilities state is * completely replaced (not merged). */ declare class SelfCapabilities extends Destroyable { private _state$; /** * Updates the capabilities state from raw capability strings. * This completely replaces the current state. * * @param capabilities - Raw capability strings from the server * @internal */ updateFromRaw(capabilities: string[]): void; /** Observable for self member capabilities */ get self$(): Observable; /** Current self member capabilities */ get self(): MemberCapabilities; /** Observable for other member capabilities */ get member$(): Observable; /** Current other member capabilities */ get member(): MemberCapabilities; /** Observable for end call capability */ get end$(): Observable; /** Current end call capability */ get end(): boolean; /** Observable for set layout capability */ get setLayout$(): Observable; /** Current set layout capability */ get setLayout(): boolean; /** Observable for send digit capability */ get sendDigit$(): Observable; /** Current send digit capability */ get sendDigit(): boolean; /** Observable for vmuted hide capability */ get vmutedHide$(): Observable; /** Current vmuted hide capability */ get vmutedHide(): OnOffCapability; /** Observable for lock capability */ get lock$(): Observable; /** Current lock capability */ get lock(): OnOffCapability; /** Observable for device capability */ get device$(): Observable; /** Current device capability */ get device(): boolean; /** Observable for screenshare capability */ get screenshare$(): Observable; /** Current screenshare capability */ get screenshare(): boolean; /** Observable for the full capabilities state */ get state$(): Observable; /** Current full capabilities state */ get state(): CallCapabilitiesState; } //#endregion //#region src/interfaces/DeviceController.d.ts /** * Interface for media device management. * * Provides reactive access to available media devices, device selection, * and monitoring for device changes (connect/disconnect). */ interface DeviceController { /** Observable list of available audio input (microphone) devices. */ readonly audioInputDevices$: Observable; /** Observable list of available audio output (speaker) devices. */ readonly audioOutputDevices$: Observable; /** Observable list of available video input (camera) devices. */ readonly videoInputDevices$: Observable; /** Observable of the currently selected audio input device, or `null` if none. */ readonly selectedAudioInputDevice$: Observable; /** Observable of the currently selected audio output device, or `null` if none. */ readonly selectedAudioOutputDevice$: Observable; /** Observable of the currently selected video input device, or `null` if none. */ readonly selectedVideoInputDevice$: Observable; /** Currently selected audio input device, or `null` if none. */ readonly selectedAudioInputDevice: MediaDeviceInfo | null; /** Currently selected audio output device, or `null` if none. */ readonly selectedAudioOutputDevice: MediaDeviceInfo | null; /** Currently selected video input device, or `null` if none. */ readonly selectedVideoInputDevice: MediaDeviceInfo | null; /** Current snapshot of available audio input devices. */ readonly audioInputDevices: MediaDeviceInfo[]; /** Current snapshot of available audio output devices. */ readonly audioOutputDevices: MediaDeviceInfo[]; /** Current snapshot of available video input devices. */ readonly videoInputDevices: MediaDeviceInfo[]; /** Media track constraints for the selected audio input device. Returns `false` when disabled. */ readonly selectedAudioInputDeviceConstraints: MediaTrackConstraints | boolean; /** Media track constraints for the selected video input device. Returns `false` when disabled. */ readonly selectedVideoInputDeviceConstraints: MediaTrackConstraints | boolean; /** * Converts a {@link MediaDeviceInfo} to track constraints suitable for `getUserMedia`. * @param deviceInfo - The device to convert, or `null` for default constraints. */ deviceInfoToConstraints(deviceInfo: MediaDeviceInfo | null): MediaTrackConstraints; /** * Sets the preferred audio input device for future calls. * @param device - The device to select, or `null` to use the system default. */ selectAudioInputDevice(device: MediaDeviceInfo | null): void; /** * Sets the preferred video input device for future calls. * @param device - The device to select, or `null` to use the system default. */ selectVideoInputDevice(device: MediaDeviceInfo | null): void; /** * Sets the preferred audio output device for future calls. * @param device - The device to select, or `null` to use the system default. */ selectAudioOutputDevice(device: MediaDeviceInfo | null): void; /** Starts monitoring for media device changes (connect/disconnect). */ enableDeviceMonitoring(): void; /** Stops monitoring for media device changes. */ disableDeviceMonitoring(): void; /** * Returns the capabilities of a media device. * @param deviceInfo - The device to query. * @returns The device capabilities, or `null` if unavailable. */ getDeviceCapabilities(deviceInfo: MediaDeviceInfo): Promise; /** * Checks whether a device is still available and usable. * @param deviceInfo - The device to validate, or `null`. * @returns `true` if the device is valid and available. Returns `false` for `null`, audio output devices, or unavailable devices. */ isValidDevice(deviceInfo: MediaDeviceInfo | null): Promise; /** Observable stream of errors from device enumeration and monitoring. */ readonly errors$: Observable; /** * Observable that emits when the SDK auto-switches a device due to * disconnect, reconnect, or recovery. */ readonly deviceRecovered$: Observable; /** Disables audio input (receive-only mode). No track will be acquired. */ disableAudioInput(): void; /** Re-enables audio input, restoring the last selection or auto-selecting. */ enableAudioInput(): void; /** Disables video input (receive-only mode). No track will be acquired. */ disableVideoInput(): void; /** Re-enables video input, restoring the last selection or auto-selecting. */ enableVideoInput(): void; /** Observable that emits `true` when video input is disabled (receive-only). */ readonly videoInputDisabled$: Observable; /** Observable that emits `true` when audio input is disabled (receive-only). */ readonly audioInputDisabled$: Observable; /** Whether video input is currently disabled. */ readonly videoInputDisabled: boolean; /** Whether audio input is currently disabled. */ readonly audioInputDisabled: boolean; /** Injects the storage manager for device persistence. */ setStorageManager(storageManager: StorageManager): void; /** Clears all device state (history, selections, persisted prefs) and re-enumerates. */ clearDeviceState(): Promise; /** Force a device re-enumeration. */ enumerateDevices(): Promise; } //#endregion //#region src/interfaces/VertoManager.d.ts /** * VertoManager interface for WebRTC call management * Provides methods for screen sharing, device management, and media constraints */ interface VertoManager { readonly screenShareStatus$: Observable; readonly screenShareStatus: ScreenShareStatus; addScreenMedia(options?: ScreenShareOptions): Promise; removeScreenMedia(): Promise; addInputDevice(options?: MediaOptions): Promise; removeInputDevices(id: string): Promise; addMainInputDevices(options?: MediaOptions): Promise; updateMediaConstraints(options?: { audio?: MediaTrackConstraints; video?: MediaTrackConstraints; }): Promise; muteMainAudioInputDevice(): void; unmuteMainAudioInputDevice(): Promise; muteMainVideoInputDevice(): void; unmuteMainVideoInputDevice(): Promise; } //#endregion //#region src/core/entities/Participant.d.ts /** * Callback type for executing call methods * Injected to avoid circular dependency with Call class */ type ExecuteMethod = (target: string | MemberTarget, method: string, args: Record) => Promise; type ParticipantState = Member & { position: LayoutLayer; }; /** * Represents a participant in a call. * * Provides observable state (audio/video mute, hand raise, volume, etc.) * and control methods for the participant. See {@link SelfParticipant} for * the local participant with additional device control. */ declare class Participant extends Destroyable implements CallParticipant { private callExecuteMethod; protected deviceController: DeviceController; /** Unique member ID of this participant. */ readonly id: string; private _state$; constructor(id: string, callExecuteMethod: ExecuteMethod, deviceController: DeviceController); /** @internal */ upnext(data: Partial): void; /** Observable of the participant's display name. */ get name$(): Observable; /** Observable of the participant type (e.g. `'member'`, `'screen'`). */ get type$(): Observable; /** Observable indicating whether the participant has raised their hand. */ get handraised$(): Observable; /** Observable indicating whether the participant is visible in the layout. */ get visible$(): Observable; /** Observable indicating whether the participant's audio is muted. */ get audioMuted$(): Observable; /** Observable indicating whether the participant's video is muted. */ get videoMuted$(): Observable; /** Observable indicating whether the participant is deafened. */ get deaf$(): Observable; /** * Observable of the participant's **server-side** microphone input volume * as reported by the mix engine. This is gain applied on the bridged audio * leg (FreeSWITCH channel read volume), NOT the local browser mic. For a * local PC mic control, see {@link Call.setLocalMicrophoneGain}. * * @see {@link setAudioInputVolume} */ get inputVolume$(): Observable; /** * Observable of the participant's **server-side** speaker output volume as * reported by the mix engine (FreeSWITCH channel write volume). NOT the * local HTML `