@telnyx/webrtc 2.26.0 → 2.26.1-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/bundle.js +1 -1
- package/lib/bundle.mjs +1 -1
- package/lib/{packages/js/src → src}/Modules/Verto/BaseSession.d.ts +7 -2
- package/lib/src/Modules/Verto/util/constants/errorCodes.d.ts +36 -0
- package/lib/src/Modules/Verto/util/constants/errors.d.ts +143 -0
- package/lib/{packages/js/src → src}/Modules/Verto/util/constants/index.d.ts +2 -0
- package/lib/src/Modules/Verto/util/constants/warnings.d.ts +103 -0
- package/lib/src/Modules/Verto/util/errors.d.ts +27 -0
- package/lib/{packages/js/src → src}/Modules/Verto/util/interfaces.d.ts +1 -0
- package/lib/{packages/js/src → src}/Modules/Verto/webrtc/BaseCall.d.ts +6 -3
- package/lib/{packages/js/src → src}/Modules/Verto/webrtc/Call.d.ts +2 -2
- package/lib/src/Modules/Verto/webrtc/CallEstablishmentTimings.d.ts +12 -0
- package/lib/{packages/js/src → src}/Modules/Verto/webrtc/CallReportCollector.d.ts +15 -0
- package/lib/src/Modules/Verto/webrtc/CandidateFilter.d.ts +14 -0
- package/lib/{packages/js/src → src}/Modules/Verto/webrtc/Peer.d.ts +9 -1
- package/lib/{packages/js/src → src}/Modules/Verto/webrtc/VertoHandler.d.ts +0 -1
- package/lib/{packages/js/src → src}/Modules/Verto/webrtc/interfaces.d.ts +3 -2
- package/lib/{packages/js/src → src}/index.d.ts +2 -0
- package/package.json +3 -2
- /package/lib/{packages/js/src → src}/Modules/Verto/BrowserSession.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/index.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/BaseMessage.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/Verto.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/WebRTCStats.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/verto/AnonymousLogin.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/verto/BaseRequest.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/verto/ConverstationMessage.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/verto/Gateway.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/verto/Login.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/verto/Ping.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/messages/verto/Result.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/services/Connection.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/services/Handler.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/services/RegisterAgent.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/LogCollector.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/debug.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/helpers.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/logger.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/reconnect.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/storage/index.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/storage/index.native.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/webrtc/index.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/util/webrtc/index.native.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/webrtc/Call.native.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/webrtc/ErrorResponse.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/webrtc/LayoutHandler.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/webrtc/constants.d.ts +0 -0
- /package/lib/{packages/js/src → src}/Modules/Verto/webrtc/helpers.d.ts +0 -0
- /package/lib/{packages/js/src → src}/PreCallDiagnosis.d.ts +0 -0
- /package/lib/{packages/js/src → src}/TelnyxRTC.d.ts +0 -0
- /package/lib/{packages/js/src → src}/utils/interfaces.d.ts +0 -0
- /package/lib/{packages/js/src → src}/utils/mos.d.ts +0 -0
- /package/lib/{packages/js/src → src}/utils/types.d.ts +0 -0
|
@@ -24,6 +24,8 @@ export default abstract class BaseSession {
|
|
|
24
24
|
protected _reconnectTimeout: any;
|
|
25
25
|
protected _autoReconnect: boolean;
|
|
26
26
|
protected _idle: boolean;
|
|
27
|
+
private _tokenExpiryTimeout;
|
|
28
|
+
private static readonly TOKEN_EXPIRY_WARNING_SECONDS;
|
|
27
29
|
private _executeQueue;
|
|
28
30
|
private _pong;
|
|
29
31
|
private registerAgent;
|
|
@@ -35,12 +37,15 @@ export default abstract class BaseSession {
|
|
|
35
37
|
execute(msg: BaseMessage): Promise<any>;
|
|
36
38
|
executeRaw(text: string): void;
|
|
37
39
|
validateOptions(): boolean;
|
|
38
|
-
broadcast(
|
|
40
|
+
broadcast(_params: BroadcastParams): void;
|
|
39
41
|
disconnect(): Promise<void>;
|
|
40
42
|
on(eventName: string, callback: Function): this;
|
|
41
43
|
off(eventName: string, callback?: Function): this;
|
|
42
44
|
connect(): Promise<void>;
|
|
43
45
|
protected _handleLoginError(error: any): void;
|
|
46
|
+
private _checkTokenExpiry;
|
|
47
|
+
private _emitTokenExpiryWarning;
|
|
48
|
+
private _clearTokenExpiryTimeout;
|
|
44
49
|
login({ creds, onSuccess, onError, }?: {
|
|
45
50
|
creds?: ILoginParams;
|
|
46
51
|
onSuccess?: () => void;
|
|
@@ -49,7 +54,7 @@ export default abstract class BaseSession {
|
|
|
49
54
|
private _login;
|
|
50
55
|
protected _onSocketOpen(): Promise<void>;
|
|
51
56
|
onNetworkClose(): void;
|
|
52
|
-
protected _onSocketMessage(
|
|
57
|
+
protected _onSocketMessage(_response: any): void;
|
|
53
58
|
protected _removeSubscription(protocol: string, channel?: string): void;
|
|
54
59
|
protected _addSubscription(protocol: string, handler: Function, channel: string): void;
|
|
55
60
|
_existsSubscription(protocol: string, channel?: string): boolean;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { SdkErrorCode } from './errors';
|
|
2
|
+
import type { SdkWarningCode } from './warnings';
|
|
3
|
+
export declare const SDP_CREATE_OFFER_FAILED: SdkErrorCode;
|
|
4
|
+
export declare const SDP_CREATE_ANSWER_FAILED: SdkErrorCode;
|
|
5
|
+
export declare const SDP_SET_LOCAL_DESCRIPTION_FAILED: SdkErrorCode;
|
|
6
|
+
export declare const SDP_SET_REMOTE_DESCRIPTION_FAILED: SdkErrorCode;
|
|
7
|
+
export declare const SDP_SEND_FAILED: SdkErrorCode;
|
|
8
|
+
export declare const MEDIA_MICROPHONE_PERMISSION_DENIED: SdkErrorCode;
|
|
9
|
+
export declare const MEDIA_DEVICE_NOT_FOUND: SdkErrorCode;
|
|
10
|
+
export declare const MEDIA_GET_USER_MEDIA_FAILED: SdkErrorCode;
|
|
11
|
+
export declare const HOLD_FAILED: SdkErrorCode;
|
|
12
|
+
export declare const INVALID_CALL_PARAMETERS: SdkErrorCode;
|
|
13
|
+
export declare const BYE_SEND_FAILED: SdkErrorCode;
|
|
14
|
+
export declare const SUBSCRIBE_FAILED: SdkErrorCode;
|
|
15
|
+
export declare const WEBSOCKET_CONNECTION_FAILED: SdkErrorCode;
|
|
16
|
+
export declare const WEBSOCKET_ERROR: SdkErrorCode;
|
|
17
|
+
export declare const RECONNECTION_EXHAUSTED: SdkErrorCode;
|
|
18
|
+
export declare const GATEWAY_FAILED: SdkErrorCode;
|
|
19
|
+
export declare const LOGIN_FAILED: SdkErrorCode;
|
|
20
|
+
export declare const INVALID_CREDENTIALS: SdkErrorCode;
|
|
21
|
+
export declare const AUTHENTICATION_REQUIRED: SdkErrorCode;
|
|
22
|
+
export declare const NETWORK_OFFLINE: SdkErrorCode;
|
|
23
|
+
export declare const HIGH_RTT: SdkWarningCode;
|
|
24
|
+
export declare const HIGH_JITTER: SdkWarningCode;
|
|
25
|
+
export declare const HIGH_PACKET_LOSS: SdkWarningCode;
|
|
26
|
+
export declare const LOW_MOS: SdkWarningCode;
|
|
27
|
+
export declare const LOW_BYTES_RECEIVED: SdkWarningCode;
|
|
28
|
+
export declare const LOW_BYTES_SENT: SdkWarningCode;
|
|
29
|
+
export declare const ICE_CONNECTIVITY_LOST: SdkWarningCode;
|
|
30
|
+
export declare const ICE_GATHERING_TIMEOUT: SdkWarningCode;
|
|
31
|
+
export declare const ICE_GATHERING_EMPTY: SdkWarningCode;
|
|
32
|
+
export declare const PEER_CONNECTION_FAILED: SdkWarningCode;
|
|
33
|
+
export declare const ONLY_HOST_ICE_CANDIDATES: SdkWarningCode;
|
|
34
|
+
export declare const TOKEN_EXPIRING_SOON: SdkWarningCode;
|
|
35
|
+
export declare const SESSION_NOT_REATTACHED: SdkWarningCode;
|
|
36
|
+
export declare const HAS_NON_HOST_ICE_CANDIDATE_REGEX: RegExp;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
export declare const SDK_ERRORS: {
|
|
2
|
+
readonly 40001: {
|
|
3
|
+
readonly name: "SDP_CREATE_OFFER_FAILED";
|
|
4
|
+
readonly message: "Failed to create call offer";
|
|
5
|
+
readonly description: "The browser was unable to generate a local SDP offer. This typically indicates a WebRTC API error or invalid media constraints.";
|
|
6
|
+
readonly causes: readonly ["Browser WebRTC API error", "Missing or invalid media constraints"];
|
|
7
|
+
readonly solutions: readonly ["Check getUserMedia permissions", "Verify ICE server configuration"];
|
|
8
|
+
};
|
|
9
|
+
readonly 40002: {
|
|
10
|
+
readonly name: "SDP_CREATE_ANSWER_FAILED";
|
|
11
|
+
readonly message: "Failed to answer the call";
|
|
12
|
+
readonly description: "The browser was unable to generate a local SDP answer. The remote offer may be invalid or the browser state inconsistent.";
|
|
13
|
+
readonly causes: readonly ["Browser WebRTC API error", "Invalid remote SDP offer"];
|
|
14
|
+
readonly solutions: readonly ["Retry the call", "Check browser WebRTC compatibility"];
|
|
15
|
+
};
|
|
16
|
+
readonly 40003: {
|
|
17
|
+
readonly name: "SDP_SET_LOCAL_DESCRIPTION_FAILED";
|
|
18
|
+
readonly message: "Failed to apply local call settings";
|
|
19
|
+
readonly description: "setLocalDescription() was rejected by the browser. The generated SDP may be malformed or the browser state may be inconsistent.";
|
|
20
|
+
readonly causes: readonly ["Malformed SDP", "Browser state inconsistency"];
|
|
21
|
+
readonly solutions: readonly ["Retry the call"];
|
|
22
|
+
};
|
|
23
|
+
readonly 40004: {
|
|
24
|
+
readonly name: "SDP_SET_REMOTE_DESCRIPTION_FAILED";
|
|
25
|
+
readonly message: "Failed to apply remote call settings";
|
|
26
|
+
readonly description: "setRemoteDescription() was rejected by the browser. The remote SDP may be malformed or contain unsupported codecs.";
|
|
27
|
+
readonly causes: readonly ["Malformed remote SDP", "Browser codec mismatch"];
|
|
28
|
+
readonly solutions: readonly ["Retry the call", "Check codec configuration"];
|
|
29
|
+
};
|
|
30
|
+
readonly 40005: {
|
|
31
|
+
readonly name: "SDP_SEND_FAILED";
|
|
32
|
+
readonly message: "Failed to send call data to server";
|
|
33
|
+
readonly description: "The Invite or Answer message could not be delivered via the signaling WebSocket. The connection may have been lost.";
|
|
34
|
+
readonly causes: readonly ["WebSocket connection lost", "Server error"];
|
|
35
|
+
readonly solutions: readonly ["Check network connectivity", "Retry the call"];
|
|
36
|
+
};
|
|
37
|
+
readonly 42001: {
|
|
38
|
+
readonly name: "MEDIA_MICROPHONE_PERMISSION_DENIED";
|
|
39
|
+
readonly message: "Microphone access denied";
|
|
40
|
+
readonly description: "The user or operating system denied microphone permission. The browser permission prompt was dismissed or OS-level access is disabled.";
|
|
41
|
+
readonly causes: readonly ["User denied browser permission prompt", "OS-level microphone access disabled"];
|
|
42
|
+
readonly solutions: readonly ["Ask user to grant microphone permission in browser settings"];
|
|
43
|
+
};
|
|
44
|
+
readonly 42002: {
|
|
45
|
+
readonly name: "MEDIA_DEVICE_NOT_FOUND";
|
|
46
|
+
readonly message: "No microphone found";
|
|
47
|
+
readonly description: "The requested audio input device is not available. No microphone is connected, the device was disconnected, or an invalid deviceId was specified.";
|
|
48
|
+
readonly causes: readonly ["No microphone connected", "Device was disconnected", "Invalid deviceId"];
|
|
49
|
+
readonly solutions: readonly ["Check that a microphone is connected", "Select a valid audio input device"];
|
|
50
|
+
};
|
|
51
|
+
readonly 42003: {
|
|
52
|
+
readonly name: "MEDIA_GET_USER_MEDIA_FAILED";
|
|
53
|
+
readonly message: "Failed to access microphone";
|
|
54
|
+
readonly description: "getUserMedia() was rejected for an unexpected reason. The device may be in use by another application or the browser encountered an internal error.";
|
|
55
|
+
readonly causes: readonly ["Browser error", "Device in use by another application"];
|
|
56
|
+
readonly solutions: readonly ["Close other applications using the microphone", "Retry"];
|
|
57
|
+
};
|
|
58
|
+
readonly 44001: {
|
|
59
|
+
readonly name: "HOLD_FAILED";
|
|
60
|
+
readonly message: "Failed to hold the call";
|
|
61
|
+
readonly description: "The server rejected or did not respond to the hold request. The WebSocket connection may have been lost during the operation.";
|
|
62
|
+
readonly causes: readonly ["Server error", "WebSocket connection lost during hold"];
|
|
63
|
+
readonly solutions: readonly ["Retry the hold operation", "Check network connectivity"];
|
|
64
|
+
};
|
|
65
|
+
readonly 44002: {
|
|
66
|
+
readonly name: "INVALID_CALL_PARAMETERS";
|
|
67
|
+
readonly message: "Invalid call parameters";
|
|
68
|
+
readonly description: "The call could not be initiated because required parameters are missing or invalid. For example, no destination number was provided to newCall().";
|
|
69
|
+
readonly causes: readonly ["Missing destinationNumber in call options", "Invalid or empty call parameters"];
|
|
70
|
+
readonly solutions: readonly ["Provide a valid destinationNumber when calling newCall()", "Check the call options object for required fields"];
|
|
71
|
+
};
|
|
72
|
+
readonly 44003: {
|
|
73
|
+
readonly name: "BYE_SEND_FAILED";
|
|
74
|
+
readonly message: "Failed to hang up cleanly";
|
|
75
|
+
readonly description: "The hangup signal could not be delivered to the server. The call was terminated locally but the server may not be aware.";
|
|
76
|
+
readonly causes: readonly ["WebSocket connection lost before BYE sent"];
|
|
77
|
+
readonly solutions: readonly ["No action needed — call is terminated locally", "Check network connectivity"];
|
|
78
|
+
};
|
|
79
|
+
readonly 44004: {
|
|
80
|
+
readonly name: "SUBSCRIBE_FAILED";
|
|
81
|
+
readonly message: "Failed to subscribe to call events";
|
|
82
|
+
readonly description: "The Verto subscribe request for the call channel failed. This may prevent receiving call state updates from the server.";
|
|
83
|
+
readonly causes: readonly ["WebSocket connection lost during subscribe", "Server rejected the subscription request"];
|
|
84
|
+
readonly solutions: readonly ["Check network connectivity", "Retry the call"];
|
|
85
|
+
};
|
|
86
|
+
readonly 45001: {
|
|
87
|
+
readonly name: "WEBSOCKET_CONNECTION_FAILED";
|
|
88
|
+
readonly message: "Unable to connect to server";
|
|
89
|
+
readonly description: "The WebSocket connection to the signaling server could not be established. The server may be unreachable, the URL may be incorrect, or a firewall may be blocking the connection.";
|
|
90
|
+
readonly causes: readonly ["Server unreachable", "Incorrect WebSocket URL", "Firewall blocking WebSocket connections", "Network interruption"];
|
|
91
|
+
readonly solutions: readonly ["Check network connectivity", "Verify the signaling server URL", "Ensure WebSocket connections are not blocked by a firewall"];
|
|
92
|
+
};
|
|
93
|
+
readonly 45002: {
|
|
94
|
+
readonly name: "WEBSOCKET_ERROR";
|
|
95
|
+
readonly message: "Connection to server lost";
|
|
96
|
+
readonly description: "An error occurred on the WebSocket connection after it was established. The connection may have been dropped due to network issues or server-side closure.";
|
|
97
|
+
readonly causes: readonly ["Network interruption", "Server closed the connection", "Idle timeout"];
|
|
98
|
+
readonly solutions: readonly ["Check network connectivity", "SDK will attempt automatic reconnection if configured"];
|
|
99
|
+
};
|
|
100
|
+
readonly 45003: {
|
|
101
|
+
readonly name: "RECONNECTION_EXHAUSTED";
|
|
102
|
+
readonly message: "Unable to reconnect to server";
|
|
103
|
+
readonly description: "All automatic reconnection attempts have been exhausted. The SDK tried to re-establish the WebSocket connection multiple times but failed on every attempt.";
|
|
104
|
+
readonly causes: readonly ["Prolonged network outage", "Server unreachable", "Firewall or proxy blocking reconnection"];
|
|
105
|
+
readonly solutions: readonly ["Check network connectivity", "Call client.disconnect() and client.connect() to manually retry", "Notify the user that the connection was lost"];
|
|
106
|
+
};
|
|
107
|
+
readonly 45004: {
|
|
108
|
+
readonly name: "GATEWAY_FAILED";
|
|
109
|
+
readonly message: "Gateway connection failed";
|
|
110
|
+
readonly description: "The upstream gateway reported a FAILED or FAIL_WAIT state. The signaling server could not establish or maintain a connection to the gateway. When autoReconnect is disabled, this is immediately fatal. When enabled, the SDK will retry until RECONNECTION_EXHAUSTED.";
|
|
111
|
+
readonly causes: readonly ["Gateway down or unreachable", "Server-side infrastructure issue", "Network partition between signaling server and gateway"];
|
|
112
|
+
readonly solutions: readonly ["Wait for automatic reconnection (if autoReconnect is enabled)", "Call client.disconnect() and client.connect() to manually retry", "Check Telnyx service status"];
|
|
113
|
+
};
|
|
114
|
+
readonly 46001: {
|
|
115
|
+
readonly name: "LOGIN_FAILED";
|
|
116
|
+
readonly message: "Authentication failed";
|
|
117
|
+
readonly description: "The login request was rejected by the server. The credentials may be invalid, expired, or the account may be suspended.";
|
|
118
|
+
readonly causes: readonly ["Invalid credentials (username/password or token)", "Expired authentication token", "Account suspended or disabled"];
|
|
119
|
+
readonly solutions: readonly ["Verify credentials", "Generate a new authentication token", "Check account status"];
|
|
120
|
+
};
|
|
121
|
+
readonly 46002: {
|
|
122
|
+
readonly name: "INVALID_CREDENTIALS";
|
|
123
|
+
readonly message: "Invalid credential parameters";
|
|
124
|
+
readonly description: "The SDK rejected the login options before sending any request to the server. This is an internal client-side validation guard — the credentials object is missing required fields or has an invalid structure. No network request was made.";
|
|
125
|
+
readonly causes: readonly ["Missing login and password fields", "Missing or malformed authentication token", "Invalid combination of credential fields in the options object"];
|
|
126
|
+
readonly solutions: readonly ["Provide valid login/password or a valid authentication token", "Check the TelnyxRTC constructor options against the documentation", "Ensure the credential object matches one of the supported auth modes (credentials, token, or anonymous)"];
|
|
127
|
+
};
|
|
128
|
+
readonly 46003: {
|
|
129
|
+
readonly name: "AUTHENTICATION_REQUIRED";
|
|
130
|
+
readonly message: "Authentication required";
|
|
131
|
+
readonly description: "The server rejected a request because the session is not authenticated. This can happen when the client sends a message (e.g. Invite, Subscribe, or Ping) before login completes, after a token expires mid-session, or after the server drops the authenticated state for any reason.";
|
|
132
|
+
readonly causes: readonly ["Message sent before login completed", "Authentication token expired during the session", "Server-side session was invalidated", "WebSocket reconnected but re-authentication did not complete"];
|
|
133
|
+
readonly solutions: readonly ["Ensure the client is fully logged in before sending messages", "Re-authenticate using client.login() with fresh credentials", "Listen for telnyx.ready before making calls or sending requests"];
|
|
134
|
+
};
|
|
135
|
+
readonly 48001: {
|
|
136
|
+
readonly name: "NETWORK_OFFLINE";
|
|
137
|
+
readonly message: "Device is offline";
|
|
138
|
+
readonly description: "The browser reported that the device has lost network connectivity (navigator.onLine === false). All WebSocket and media connections will fail until the network is restored.";
|
|
139
|
+
readonly causes: readonly ["Wi-Fi or ethernet disconnected", "Airplane mode enabled", "Network interface went down"];
|
|
140
|
+
readonly solutions: readonly ["Check network connectivity", "Reconnect to Wi-Fi or ethernet", "Disable airplane mode"];
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
export declare type SdkErrorCode = keyof typeof SDK_ERRORS;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './errorCodes';
|
|
1
2
|
export declare const STORAGE_PREFIX = "@telnyx:";
|
|
2
3
|
export declare const ADD = "add";
|
|
3
4
|
export declare const REMOVE = "remove";
|
|
@@ -46,6 +47,7 @@ export declare enum SwEvent {
|
|
|
46
47
|
SpeedTest = "telnyx.internal.speedtest",
|
|
47
48
|
Ready = "telnyx.ready",
|
|
48
49
|
Error = "telnyx.error",
|
|
50
|
+
Warning = "telnyx.warning",
|
|
49
51
|
Notification = "telnyx.notification",
|
|
50
52
|
StatsFrame = "telnyx.stats.frame",
|
|
51
53
|
StatsReport = "telnyx.stats.report",
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export interface ITelnyxWarning {
|
|
2
|
+
code: SdkWarningCode;
|
|
3
|
+
name: string;
|
|
4
|
+
message: string;
|
|
5
|
+
description: string;
|
|
6
|
+
causes: string[];
|
|
7
|
+
solutions: string[];
|
|
8
|
+
}
|
|
9
|
+
export declare const SDK_WARNINGS: {
|
|
10
|
+
readonly 31001: {
|
|
11
|
+
readonly name: "HIGH_RTT";
|
|
12
|
+
readonly message: "High network latency detected";
|
|
13
|
+
readonly description: "Round-trip time (RTT) exceeded the threshold for multiple consecutive samples. High latency causes perceptible audio delays.";
|
|
14
|
+
readonly causes: readonly ["Poor network connection", "Geographic distance to media server", "Network congestion"];
|
|
15
|
+
readonly solutions: readonly ["Check network connectivity", "Use a wired connection instead of Wi-Fi", "Close bandwidth-heavy applications"];
|
|
16
|
+
};
|
|
17
|
+
readonly 31002: {
|
|
18
|
+
readonly name: "HIGH_JITTER";
|
|
19
|
+
readonly message: "High jitter detected";
|
|
20
|
+
readonly description: "Jitter (variability in packet arrival time) exceeded the threshold for multiple consecutive samples. High jitter causes crackling and choppy audio.";
|
|
21
|
+
readonly causes: readonly ["Network congestion", "Unstable Wi-Fi connection", "Overloaded network equipment"];
|
|
22
|
+
readonly solutions: readonly ["Use a wired connection instead of Wi-Fi", "Close bandwidth-heavy applications", "Check network equipment"];
|
|
23
|
+
};
|
|
24
|
+
readonly 31003: {
|
|
25
|
+
readonly name: "HIGH_PACKET_LOSS";
|
|
26
|
+
readonly message: "High packet loss detected";
|
|
27
|
+
readonly description: "Packet loss exceeded the threshold for multiple consecutive samples. High packet loss causes choppy audio or dropped calls.";
|
|
28
|
+
readonly causes: readonly ["Network congestion", "Unstable connection", "Firewall or QoS misconfiguration"];
|
|
29
|
+
readonly solutions: readonly ["Check network connectivity", "Use a wired connection", "Contact network administrator"];
|
|
30
|
+
};
|
|
31
|
+
readonly 31004: {
|
|
32
|
+
readonly name: "LOW_MOS";
|
|
33
|
+
readonly message: "Low call quality score";
|
|
34
|
+
readonly description: "Mean Opinion Score (MOS) dropped below the acceptable threshold for multiple consecutive samples. This is a composite indicator of overall call quality.";
|
|
35
|
+
readonly causes: readonly ["Combination of high latency, jitter, and/or packet loss", "Poor network conditions"];
|
|
36
|
+
readonly solutions: readonly ["Check network connectivity", "Use a wired connection", "Close bandwidth-heavy applications"];
|
|
37
|
+
};
|
|
38
|
+
readonly 32001: {
|
|
39
|
+
readonly name: "LOW_BYTES_RECEIVED";
|
|
40
|
+
readonly message: "No audio data received";
|
|
41
|
+
readonly description: "No bytes have been received from the remote party for multiple consecutive seconds. This may indicate a network interruption or remote-side issue.";
|
|
42
|
+
readonly causes: readonly ["Network interruption", "Remote party microphone issue", "Firewall blocking inbound media"];
|
|
43
|
+
readonly solutions: readonly ["Check network connectivity", "Ask remote party to check their microphone", "Check firewall rules for media ports"];
|
|
44
|
+
};
|
|
45
|
+
readonly 32002: {
|
|
46
|
+
readonly name: "LOW_BYTES_SENT";
|
|
47
|
+
readonly message: "No audio data being sent";
|
|
48
|
+
readonly description: "No bytes have been sent for multiple consecutive seconds. This may indicate a local microphone issue or network interruption.";
|
|
49
|
+
readonly causes: readonly ["Microphone muted or disconnected", "Network interruption", "Local media track ended"];
|
|
50
|
+
readonly solutions: readonly ["Check that the microphone is not muted", "Verify the microphone is still connected", "Check network connectivity"];
|
|
51
|
+
};
|
|
52
|
+
readonly 33001: {
|
|
53
|
+
readonly name: "ICE_CONNECTIVITY_LOST";
|
|
54
|
+
readonly message: "Connection interrupted";
|
|
55
|
+
readonly description: "The ICE connection transitioned to the disconnected state. The previously selected connection path was lost and renegotiation may be required. The connection may recover automatically.";
|
|
56
|
+
readonly causes: readonly ["Temporary network interruption", "Network interface change (e.g. Wi-Fi to cellular)", "NAT rebinding"];
|
|
57
|
+
readonly solutions: readonly ["Wait for automatic recovery", "Check network connectivity"];
|
|
58
|
+
};
|
|
59
|
+
readonly 33002: {
|
|
60
|
+
readonly name: "ICE_GATHERING_TIMEOUT";
|
|
61
|
+
readonly message: "ICE gathering timed out";
|
|
62
|
+
readonly description: "ICE candidate gathering did not complete within the safety timeout. This is typically caused by network restrictions blocking STUN/TURN. The call may still succeed if candidates arrive late.";
|
|
63
|
+
readonly causes: readonly ["Firewall blocking STUN/TURN", "Network unreachable", "STUN/TURN server not responding"];
|
|
64
|
+
readonly solutions: readonly ["Check STUN/TURN server reachability", "Ensure UDP traffic is not blocked", "Try forceRelayCandidate option"];
|
|
65
|
+
};
|
|
66
|
+
readonly 33003: {
|
|
67
|
+
readonly name: "ICE_GATHERING_EMPTY";
|
|
68
|
+
readonly message: "No ICE candidates gathered";
|
|
69
|
+
readonly description: "No ICE candidates were gathered after sending the initial SDP. This may indicate a firewall blocking all STUN/TURN traffic or no available network interface.";
|
|
70
|
+
readonly causes: readonly ["Firewall blocking all STUN/TURN traffic", "No network interface available", "VPN blocking UDP"];
|
|
71
|
+
readonly solutions: readonly ["Check STUN/TURN server reachability", "Ensure UDP traffic is not blocked", "Use forceRelayCandidate option"];
|
|
72
|
+
};
|
|
73
|
+
readonly 33004: {
|
|
74
|
+
readonly name: "PEER_CONNECTION_FAILED";
|
|
75
|
+
readonly message: "Connection failed";
|
|
76
|
+
readonly description: "RTCPeerConnection entered the failed state. This is a recoverable condition — the SDK may attempt ICE restart or the connection may recover. If it does not recover, the call will eventually be terminated.";
|
|
77
|
+
readonly causes: readonly ["ICE failure", "DTLS handshake failure", "Prolonged network interruption"];
|
|
78
|
+
readonly solutions: readonly ["Wait for automatic recovery", "Check network connectivity", "Verify TURN server credentials"];
|
|
79
|
+
};
|
|
80
|
+
readonly 33005: {
|
|
81
|
+
readonly name: "ONLY_HOST_ICE_CANDIDATES";
|
|
82
|
+
readonly message: "Only local network candidates available";
|
|
83
|
+
readonly description: "ICE gathering completed but only host (local network) candidates were collected — no server-reflexive (srflx) or relay (turn) candidates were found. This typically means the STUN/TURN servers are unreachable, which will prevent connections outside the local network.";
|
|
84
|
+
readonly causes: readonly ["STUN/TURN servers unreachable", "Firewall blocking UDP traffic to STUN/TURN servers", "Incorrect TURN server configuration or credentials", "Restrictive corporate network or VPN"];
|
|
85
|
+
readonly solutions: readonly ["Verify STUN/TURN server URLs and credentials", "Ensure UDP traffic to STUN/TURN ports is not blocked", "Check firewall or VPN settings", "Try using TCP-based TURN as a fallback"];
|
|
86
|
+
};
|
|
87
|
+
readonly 34001: {
|
|
88
|
+
readonly name: "TOKEN_EXPIRING_SOON";
|
|
89
|
+
readonly message: "Authentication token expiring soon";
|
|
90
|
+
readonly description: "The authentication token is approaching its expiration time. If the token expires the connection will be lost and calls will fail. A new token should be generated before expiration.";
|
|
91
|
+
readonly causes: readonly ["Token was issued with a limited lifetime"];
|
|
92
|
+
readonly solutions: readonly ["Generate a new authentication token", "Reconnect with fresh credentials before the token expires"];
|
|
93
|
+
};
|
|
94
|
+
readonly 35001: {
|
|
95
|
+
readonly name: "SESSION_NOT_REATTACHED";
|
|
96
|
+
readonly message: "Active call lost after reconnect";
|
|
97
|
+
readonly description: "The WebSocket reconnected successfully but the server returned an empty reattached_sessions list while the SDK still has an active call. The server no longer knows about the call, so any subsequent call-control operation (hangup, hold, etc.) will fail with CALL_DOES_NOT_EXIST.";
|
|
98
|
+
readonly causes: readonly ["Server-side session expired during the disconnection window", "Reconnect token was invalidated", "Backend restarted or lost in-memory call state"];
|
|
99
|
+
readonly solutions: readonly ["Terminate the local call and notify the user", "Start a new call", "Investigate why the session was not preserved on the server"];
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
export declare type SdkWarningCode = keyof typeof SDK_WARNINGS;
|
|
103
|
+
export declare function createTelnyxWarning(code: SdkWarningCode, message?: string): ITelnyxWarning;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SDK_ERRORS, SdkErrorCode } from './constants/errors';
|
|
2
|
+
import { SDK_WARNINGS, SdkWarningCode, ITelnyxWarning, createTelnyxWarning } from './constants/warnings';
|
|
3
|
+
import { MEDIA_MICROPHONE_PERMISSION_DENIED, MEDIA_DEVICE_NOT_FOUND, MEDIA_GET_USER_MEDIA_FAILED } from './constants/errorCodes';
|
|
4
|
+
export { SDK_ERRORS, SdkErrorCode };
|
|
5
|
+
export { SDK_WARNINGS, SdkWarningCode, ITelnyxWarning, createTelnyxWarning };
|
|
6
|
+
export interface ITelnyxError {
|
|
7
|
+
code: number;
|
|
8
|
+
name: string;
|
|
9
|
+
description: string;
|
|
10
|
+
message: string;
|
|
11
|
+
causes: string[];
|
|
12
|
+
solutions: string[];
|
|
13
|
+
originalError?: unknown;
|
|
14
|
+
}
|
|
15
|
+
export declare class TelnyxError extends Error implements ITelnyxError {
|
|
16
|
+
readonly code: number;
|
|
17
|
+
readonly description: string;
|
|
18
|
+
readonly causes: string[];
|
|
19
|
+
readonly solutions: string[];
|
|
20
|
+
readonly originalError?: unknown;
|
|
21
|
+
constructor(params: Omit<ITelnyxError, 'message'> & {
|
|
22
|
+
message?: string;
|
|
23
|
+
});
|
|
24
|
+
toJSON(): ITelnyxError;
|
|
25
|
+
}
|
|
26
|
+
export declare function classifyMediaErrorCode(error: unknown): typeof MEDIA_MICROPHONE_PERMISSION_DENIED | typeof MEDIA_DEVICE_NOT_FOUND | typeof MEDIA_GET_USER_MEDIA_FAILED;
|
|
27
|
+
export declare function createTelnyxError(code: SdkErrorCode, originalError?: unknown, message?: string): TelnyxError;
|
|
@@ -40,9 +40,11 @@ export default abstract class BaseCall implements IWebRTCCall {
|
|
|
40
40
|
private _isRemoteDescriptionSet;
|
|
41
41
|
private _signalingStateClosed;
|
|
42
42
|
private _creatingPeer;
|
|
43
|
+
private _firstCandidateSent;
|
|
44
|
+
private _firstNonHostCandidateSent;
|
|
43
45
|
private _isRecovering;
|
|
46
|
+
private _candidateFilter;
|
|
44
47
|
constructor(session: BrowserSession, opts?: IVertoCallOptions);
|
|
45
|
-
private get performanceMetrics();
|
|
46
48
|
get nodeId(): string;
|
|
47
49
|
set nodeId(what: string);
|
|
48
50
|
get isVideoCall(): boolean;
|
|
@@ -61,8 +63,8 @@ export default abstract class BaseCall implements IWebRTCCall {
|
|
|
61
63
|
stopRingtone(): void;
|
|
62
64
|
playRingback(): void;
|
|
63
65
|
stopRingback(): void;
|
|
64
|
-
hangup(): void
|
|
65
|
-
hangup(hangupParams: IHangupParams, hangupExecute: boolean): void
|
|
66
|
+
hangup(): Promise<void>;
|
|
67
|
+
hangup(hangupParams: IHangupParams, hangupExecute: boolean): Promise<void>;
|
|
66
68
|
hold(): Promise<any>;
|
|
67
69
|
unhold(): Promise<any>;
|
|
68
70
|
toggleHold(): Promise<any>;
|
|
@@ -102,6 +104,7 @@ export default abstract class BaseCall implements IWebRTCCall {
|
|
|
102
104
|
private _addIceCandidate;
|
|
103
105
|
private _addIceCandidateToPeer;
|
|
104
106
|
private _sendEndOfCandidates;
|
|
107
|
+
private _trackCandidateMarks;
|
|
105
108
|
private _resetTrickleIceCandidateState;
|
|
106
109
|
private _flushPendingTrickleIceCandidates;
|
|
107
110
|
private _registerPeerEvents;
|
|
@@ -3,9 +3,9 @@ import { IVertoCallOptions } from './interfaces';
|
|
|
3
3
|
export declare class Call extends BaseCall {
|
|
4
4
|
screenShare: Call;
|
|
5
5
|
private _statsInterval;
|
|
6
|
-
hangup(params?: any, execute?: boolean): void
|
|
6
|
+
hangup(params?: any, execute?: boolean): Promise<void>;
|
|
7
7
|
startScreenShare(opts?: IVertoCallOptions): Promise<Call>;
|
|
8
|
-
stopScreenShare(): void
|
|
8
|
+
stopScreenShare(): Promise<void>;
|
|
9
9
|
sendConversationMessage: (message: string, attachments?: string[]) => Promise<any>;
|
|
10
10
|
setAudioOutDevice(deviceId: string): Promise<boolean>;
|
|
11
11
|
protected _finalize(): void;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ICallEstablishmentTimings {
|
|
2
|
+
mode: 'trickle' | 'non-trickle';
|
|
3
|
+
direction: 'outbound' | 'inbound';
|
|
4
|
+
steps: Array<{
|
|
5
|
+
label: string;
|
|
6
|
+
fromStart: number;
|
|
7
|
+
delta: number;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
export declare function collectCallEstablishmentTimings(mode: 'trickle' | 'non-trickle', direction: 'outbound' | 'inbound'): ICallEstablishmentTimings;
|
|
11
|
+
export declare function logCallEstablishmentTimings(timings: ICallEstablishmentTimings): void;
|
|
12
|
+
export declare function clearCallMarks(): void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ILogEntry } from '../../../Modules/Verto/util/LogCollector';
|
|
2
|
+
import { type ITelnyxWarning } from '../../../Modules/Verto/util/errors';
|
|
2
3
|
interface ICECandidateInfo {
|
|
3
4
|
address?: string;
|
|
4
5
|
port?: number;
|
|
@@ -107,6 +108,18 @@ export declare class CallReportCollector {
|
|
|
107
108
|
private static readonly STATS_FLUSH_THRESHOLD;
|
|
108
109
|
private static readonly LOGS_FLUSH_THRESHOLD;
|
|
109
110
|
onFlushNeeded: (() => void) | null;
|
|
111
|
+
onWarning: ((warning: ITelnyxWarning) => void) | null;
|
|
112
|
+
private static readonly CONSECUTIVE_BREACHES_REQUIRED;
|
|
113
|
+
private static readonly THRESHOLD_RTT_MS;
|
|
114
|
+
private static readonly THRESHOLD_JITTER_MS;
|
|
115
|
+
private static readonly THRESHOLD_PACKET_LOSS_PCT;
|
|
116
|
+
private static readonly THRESHOLD_MOS;
|
|
117
|
+
private _breachCounters;
|
|
118
|
+
private _activeWarnings;
|
|
119
|
+
private _lastWarningEmitted;
|
|
120
|
+
private static readonly WARNING_THROTTLE_MS;
|
|
121
|
+
private _prevPacketsReceived;
|
|
122
|
+
private _prevPacketsLost;
|
|
110
123
|
private _segmentIndex;
|
|
111
124
|
private _flushing;
|
|
112
125
|
private static readonly RETRY_DELAY_MS;
|
|
@@ -121,6 +134,8 @@ export declare class CallReportCollector {
|
|
|
121
134
|
getLogs(): ILogEntry[];
|
|
122
135
|
cleanup(): void;
|
|
123
136
|
private _collectStats;
|
|
137
|
+
private _checkQualityWarnings;
|
|
138
|
+
private _trackBreach;
|
|
124
139
|
private _createStatsEntry;
|
|
125
140
|
private _resolveCandidate;
|
|
126
141
|
private _getOutboundAudioLevel;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare class CandidateFilter {
|
|
2
|
+
private _lockedInterface;
|
|
3
|
+
private _enabled;
|
|
4
|
+
private _onCandidate;
|
|
5
|
+
private _onEndOfCandidates;
|
|
6
|
+
private _filteredCount;
|
|
7
|
+
private _passedCount;
|
|
8
|
+
constructor(enabled: boolean, onCandidate: (candidate: RTCIceCandidate) => void, onEndOfCandidates: () => void);
|
|
9
|
+
add(event: RTCPeerConnectionIceEvent): void;
|
|
10
|
+
reset(): void;
|
|
11
|
+
private _extractRaddr;
|
|
12
|
+
private _extractNetworkId;
|
|
13
|
+
private _isTcpCandidate;
|
|
14
|
+
}
|
|
@@ -16,6 +16,11 @@ export default class Peer {
|
|
|
16
16
|
private _trickleIceSdpFn;
|
|
17
17
|
private _registerPeerEvents;
|
|
18
18
|
private _sleepWakeupIntervalId;
|
|
19
|
+
private _iceGatheringSafetyTimeout;
|
|
20
|
+
private _gatheredCandidatesCount;
|
|
21
|
+
private static readonly ICE_GATHERING_SAFETY_TIMEOUT_MS;
|
|
22
|
+
private _firstMediaTrackMarked;
|
|
23
|
+
private _timingsCollected;
|
|
19
24
|
constructor(type: PeerType, options: IVertoCallOptions, session: BrowserSession, trickleIceSdpFn: (sdp: RTCSessionDescriptionInit) => void, registerPeerEvents: (instance: RTCPeerConnection) => void);
|
|
20
25
|
get isOffer(): boolean;
|
|
21
26
|
get isAnswer(): boolean;
|
|
@@ -26,14 +31,17 @@ export default class Peer {
|
|
|
26
31
|
startNegotiation(): void;
|
|
27
32
|
startTrickleIceNegotiation(): Promise<void>;
|
|
28
33
|
private _logTransceivers;
|
|
29
|
-
private get trickleIcePerformanceMetrics();
|
|
30
34
|
private handleSignalingStateChangeEvent;
|
|
31
35
|
private handleNegotiationNeededEvent;
|
|
32
36
|
private handleTrackEvent;
|
|
33
37
|
private handleConnectionStateChange;
|
|
38
|
+
tryCollectTimings(): void;
|
|
34
39
|
private createPeerConnection;
|
|
35
40
|
private _handleIceConnectionStateChange;
|
|
36
41
|
private _handleIceGatheringStateChange;
|
|
42
|
+
incrementGatheredCandidates(): void;
|
|
43
|
+
private _startIceGatheringSafetyTimeout;
|
|
44
|
+
private _clearIceGatheringSafetyTimeout;
|
|
37
45
|
init(): Promise<void>;
|
|
38
46
|
private _getSenderByKind;
|
|
39
47
|
private _checkMediaToNegotiate;
|
|
@@ -66,6 +66,7 @@ export interface IVertoCallOptions {
|
|
|
66
66
|
prefetchIceCandidates?: boolean;
|
|
67
67
|
forceRelayCandidate?: boolean;
|
|
68
68
|
trickleIce?: boolean;
|
|
69
|
+
singleInterfaceIce?: boolean;
|
|
69
70
|
keepConnectionAliveOnSocketClose?: boolean;
|
|
70
71
|
mutedMicOnStart?: boolean;
|
|
71
72
|
recoveredCallId?: string;
|
|
@@ -107,7 +108,7 @@ export interface IWebRTCCall {
|
|
|
107
108
|
signalingStateClosed: boolean;
|
|
108
109
|
invite: () => void;
|
|
109
110
|
answer: (params: AnswerParams) => void;
|
|
110
|
-
hangup: (params
|
|
111
|
+
hangup: (params?: IHangupParams, execute?: boolean) => Promise<void>;
|
|
111
112
|
hold: () => void;
|
|
112
113
|
unhold: () => void;
|
|
113
114
|
toggleHold: () => void;
|
|
@@ -132,7 +133,7 @@ export interface IWebRTCCall {
|
|
|
132
133
|
_addChannel: (laChannel: any) => void;
|
|
133
134
|
handleConferenceUpdate: (packet: any, pvtData: any) => Promise<string>;
|
|
134
135
|
startScreenShare?: (opts?: object) => Promise<IWebRTCCall>;
|
|
135
|
-
stopScreenShare?: () => void
|
|
136
|
+
stopScreenShare?: () => Promise<void>;
|
|
136
137
|
setAudioOutDevice?: (deviceId: string) => Promise<boolean>;
|
|
137
138
|
setSpeakerPhone?: (flag: boolean) => void;
|
|
138
139
|
}
|
|
@@ -4,4 +4,6 @@ import { SwEvent } from './Modules/Verto/util/constants';
|
|
|
4
4
|
import { NOTIFICATION_TYPE, ERROR_TYPE } from './Modules/Verto/webrtc/constants';
|
|
5
5
|
import Call from './Modules/Verto/webrtc/Call';
|
|
6
6
|
export { Call, TelnyxRTC, IClientOptions, ICallOptions, ICredentials, INotification, SwEvent, NOTIFICATION_TYPE, ERROR_TYPE, };
|
|
7
|
+
export type { ITelnyxError } from './Modules/Verto/util/errors';
|
|
8
|
+
export type { ITelnyxWarning } from './Modules/Verto/util/constants/warnings';
|
|
7
9
|
export * from './PreCallDiagnosis';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telnyx/webrtc",
|
|
3
|
-
"version": "2.26.
|
|
3
|
+
"version": "2.26.1-beta.3",
|
|
4
4
|
"description": "Telnyx WebRTC Client",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"telnyx",
|
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
"module": "lib/bundle.mjs",
|
|
18
18
|
"types": "lib/packages/js/src/index.d.ts",
|
|
19
19
|
"files": [
|
|
20
|
-
"lib"
|
|
20
|
+
"lib",
|
|
21
|
+
"README.md"
|
|
21
22
|
],
|
|
22
23
|
"scripts": {
|
|
23
24
|
"build": "rollup -c",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|