@signalwire/js 4.0.0-rc.1 → 4.0.0-rc.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/dist/browser.mjs +1905 -586
- package/dist/browser.mjs.map +1 -1
- package/dist/browser.umd.js +1910 -585
- package/dist/browser.umd.js.map +1 -1
- package/dist/index.cjs +1714 -642
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2360 -1817
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +2360 -1817
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1637 -571
- package/dist/index.mjs.map +1 -1
- package/dist/operators/index.cjs +1 -1
- package/dist/operators/index.mjs +1 -1
- package/dist/operators-BJ6QW1VP.cjs +1466 -0
- package/dist/operators-BJ6QW1VP.cjs.map +1 -0
- package/dist/operators-BVxi3KpN.mjs +731 -0
- package/dist/operators-BVxi3KpN.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/operators-CX_lCCJm.mjs +0 -478
- package/dist/operators-CX_lCCJm.mjs.map +0 -1
- package/dist/operators-D6a2J1KA.cjs +0 -763
- package/dist/operators-D6a2J1KA.cjs.map +0 -1
package/dist/index.d.cts
CHANGED
|
@@ -324,6 +324,17 @@ interface MediaDirections {
|
|
|
324
324
|
/** Video direction */
|
|
325
325
|
video: MediaDirection;
|
|
326
326
|
}
|
|
327
|
+
/** Options for starting a screen share. */
|
|
328
|
+
interface ScreenShareOptions {
|
|
329
|
+
/**
|
|
330
|
+
* Request the shared surface's audio. Defaults to `false`.
|
|
331
|
+
*
|
|
332
|
+
* Whether audio can actually be captured depends on the browser, the OS and
|
|
333
|
+
* the surface the user picks — Chrome offers it for tabs and windows, and a
|
|
334
|
+
* share the user grants without audio yields a video-only stream.
|
|
335
|
+
*/
|
|
336
|
+
audio?: boolean;
|
|
337
|
+
}
|
|
327
338
|
/** Options controlling which media tracks to send and receive. */
|
|
328
339
|
interface MediaOptions {
|
|
329
340
|
/** Enable audio input. Defaults to `true` when not specified. */
|
|
@@ -342,6 +353,12 @@ interface MediaOptions {
|
|
|
342
353
|
receiveAudio?: boolean;
|
|
343
354
|
/** Whether to receive remote video. */
|
|
344
355
|
receiveVideo?: boolean;
|
|
356
|
+
/**
|
|
357
|
+
* When local media can't be acquired (permission denied or device
|
|
358
|
+
* unavailable), continue the call in receive-only mode instead of failing.
|
|
359
|
+
* Defaults to `true`. Ignored when the call is not set to receive any media.
|
|
360
|
+
*/
|
|
361
|
+
fallbackToReceiveOnly?: boolean;
|
|
345
362
|
}
|
|
346
363
|
//#endregion
|
|
347
364
|
//#region src/containers/PreferencesContainer.d.ts
|
|
@@ -1160,6 +1177,14 @@ interface CallError {
|
|
|
1160
1177
|
readonly error: Error;
|
|
1161
1178
|
/** ID of the call that produced this error. */
|
|
1162
1179
|
readonly callId: string;
|
|
1180
|
+
/**
|
|
1181
|
+
* Which peer connection failed. Auxiliary legs are never fatal, so a consumer
|
|
1182
|
+
* can surface "screen share failed, call continues". Absent for call- and
|
|
1183
|
+
* session-level errors.
|
|
1184
|
+
*/
|
|
1185
|
+
readonly leg?: RTCPeerConnectionPropose;
|
|
1186
|
+
/** `callId` is always the call's id, never the leg's. Use this for the leg. */
|
|
1187
|
+
readonly legId?: string;
|
|
1163
1188
|
}
|
|
1164
1189
|
declare class CallCreateError extends Error {
|
|
1165
1190
|
message: string;
|
|
@@ -1167,6 +1192,14 @@ declare class CallCreateError extends Error {
|
|
|
1167
1192
|
direction: 'inbound' | 'outbound';
|
|
1168
1193
|
constructor(message: string, error?: unknown, direction?: 'inbound' | 'outbound', options?: ErrorOptions);
|
|
1169
1194
|
}
|
|
1195
|
+
declare class CallNotReadyError extends Error {
|
|
1196
|
+
callId: string;
|
|
1197
|
+
constructor(callId: string, options?: ErrorOptions);
|
|
1198
|
+
}
|
|
1199
|
+
declare class ParticipantNotReadyError extends Error {
|
|
1200
|
+
memberId: string;
|
|
1201
|
+
constructor(memberId: string, options?: ErrorOptions);
|
|
1202
|
+
}
|
|
1170
1203
|
declare class VertoPongError extends Error {
|
|
1171
1204
|
originalError: unknown;
|
|
1172
1205
|
constructor(originalError: unknown);
|
|
@@ -1180,12 +1213,73 @@ declare class CollectionFetchError extends Error {
|
|
|
1180
1213
|
originalError: unknown;
|
|
1181
1214
|
constructor(operation: string, originalError: unknown);
|
|
1182
1215
|
}
|
|
1216
|
+
/**
|
|
1217
|
+
* An auxiliary leg did not connect within its budget. Typed rather than a bare
|
|
1218
|
+
* RxJS `TimeoutError` so the leg and cause survive.
|
|
1219
|
+
*/
|
|
1220
|
+
declare class AuxiliaryLegTimeoutError extends Error {
|
|
1221
|
+
readonly leg: RTCPeerConnectionPropose;
|
|
1222
|
+
readonly originalError?: Error | undefined;
|
|
1223
|
+
constructor(leg: RTCPeerConnectionPropose, originalError?: Error | undefined);
|
|
1224
|
+
}
|
|
1225
|
+
/**
|
|
1226
|
+
* An auxiliary leg was removed before it finished connecting.
|
|
1227
|
+
*
|
|
1228
|
+
* Typed rather than a bare resolve so a caller awaiting the start can tell a
|
|
1229
|
+
* cancel apart from a share that actually came up — the public methods return
|
|
1230
|
+
* `void`, so the promise is the only signal they have.
|
|
1231
|
+
*/
|
|
1232
|
+
declare class AuxiliaryLegCancelledError extends Error {
|
|
1233
|
+
readonly leg: RTCPeerConnectionPropose;
|
|
1234
|
+
constructor(leg: RTCPeerConnectionPropose);
|
|
1235
|
+
}
|
|
1183
1236
|
declare class MediaTrackError extends Error {
|
|
1184
1237
|
operation: string;
|
|
1185
1238
|
kind: string;
|
|
1186
1239
|
originalError: unknown;
|
|
1187
1240
|
constructor(operation: string, kind: string, originalError: unknown);
|
|
1188
1241
|
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Failure to acquire local media (camera, microphone, or screen capture)
|
|
1244
|
+
* via `getUserMedia`/`getDisplayMedia`.
|
|
1245
|
+
*
|
|
1246
|
+
* Non-fatal by default: screenshare and additional-device failures never
|
|
1247
|
+
* end the call, and main-connection failures degrade to receive-only when
|
|
1248
|
+
* possible. The wrapping site sets `fatal` to `true` only when the call
|
|
1249
|
+
* cannot continue (receive-only fallback disabled or no receive intent).
|
|
1250
|
+
*/
|
|
1251
|
+
declare class MediaAccessError extends Error {
|
|
1252
|
+
/** The SDK operation that failed, e.g. `'acquireLocalMedia'`, `'startScreenShare'`, `'addInputDevice'`. */
|
|
1253
|
+
operation: string;
|
|
1254
|
+
/** The media being acquired: `'audio' | 'video' | 'audiovideo' | 'screen'`. */
|
|
1255
|
+
media: string;
|
|
1256
|
+
/** The raw `getUserMedia`/`getDisplayMedia` error (typically a `DOMException`). */
|
|
1257
|
+
originalError: unknown;
|
|
1258
|
+
/** Whether this failure terminates the call. */
|
|
1259
|
+
readonly fatal: boolean;
|
|
1260
|
+
constructor(/** The SDK operation that failed, e.g. `'acquireLocalMedia'`, `'startScreenShare'`, `'addInputDevice'`. */
|
|
1261
|
+
operation: string, /** The media being acquired: `'audio' | 'video' | 'audiovideo' | 'screen'`. */
|
|
1262
|
+
media: string, /** The raw `getUserMedia`/`getDisplayMedia` error (typically a `DOMException`). */
|
|
1263
|
+
originalError: unknown, /** Whether this failure terminates the call. */
|
|
1264
|
+
fatal?: boolean);
|
|
1265
|
+
/** True when the underlying failure is a permission denial (user or policy). */
|
|
1266
|
+
get denied(): boolean;
|
|
1267
|
+
}
|
|
1268
|
+
/**
|
|
1269
|
+
* Thrown by `startScreenShare()` when the call is already sharing a screen.
|
|
1270
|
+
*
|
|
1271
|
+
* A call carries at most one screen share. Accepting a second one would
|
|
1272
|
+
* overwrite the only reference the SDK holds to the first, leaving it
|
|
1273
|
+
* capturing and sending with no way to stop it — so the second request is
|
|
1274
|
+
* rejected and the live share is left untouched. Call `stopScreenShare()`
|
|
1275
|
+
* first to replace it.
|
|
1276
|
+
*/
|
|
1277
|
+
declare class ScreenShareAlreadyActiveError extends Error {
|
|
1278
|
+
/** Id of the screen share leg that is already active. */
|
|
1279
|
+
readonly screenShareId: string;
|
|
1280
|
+
constructor(/** Id of the screen share leg that is already active. */
|
|
1281
|
+
screenShareId: string, options?: ErrorOptions);
|
|
1282
|
+
}
|
|
1189
1283
|
declare class DPoPInitError extends Error {
|
|
1190
1284
|
originalError: unknown;
|
|
1191
1285
|
constructor(originalError: unknown, message?: string);
|
|
@@ -1404,7 +1498,7 @@ interface AudioConstraintsEvent {
|
|
|
1404
1498
|
/** Timestamp when the event occurred (epoch ms). */
|
|
1405
1499
|
readonly timestamp: number;
|
|
1406
1500
|
}
|
|
1407
|
-
/** Event emitted when server
|
|
1501
|
+
/** Event emitted when the server pushes media params. */
|
|
1408
1502
|
interface MediaParamsEvent {
|
|
1409
1503
|
/** Audio constraints pushed by the server, if any. */
|
|
1410
1504
|
readonly audio?: MediaTrackConstraints;
|
|
@@ -1412,6 +1506,15 @@ interface MediaParamsEvent {
|
|
|
1412
1506
|
readonly video?: MediaTrackConstraints;
|
|
1413
1507
|
/** Timestamp when the event occurred (epoch ms). */
|
|
1414
1508
|
readonly timestamp: number;
|
|
1509
|
+
/**
|
|
1510
|
+
* `false` when the constraints did not reach every sender of a pushed kind:
|
|
1511
|
+
* the sender carries media the SDK did not capture, the browser refused the
|
|
1512
|
+
* constraints and re-acquisition failed, or the leg sends no media of that
|
|
1513
|
+
* kind at all. The event is emitted whether or not they were applied, but a
|
|
1514
|
+
* push naming a leg this call does not hold emits nothing at all — the event
|
|
1515
|
+
* carries no leg identity to report it against.
|
|
1516
|
+
*/
|
|
1517
|
+
readonly applied: boolean;
|
|
1415
1518
|
}
|
|
1416
1519
|
/** Structured diagnostic bundle for a session. */
|
|
1417
1520
|
interface SessionDiagnostics {
|
|
@@ -1725,7 +1828,7 @@ interface DeviceController {
|
|
|
1725
1828
|
interface VertoManager {
|
|
1726
1829
|
readonly screenShareStatus$: Observable<ScreenShareStatus>;
|
|
1727
1830
|
readonly screenShareStatus: ScreenShareStatus;
|
|
1728
|
-
addScreenMedia(): Promise<void>;
|
|
1831
|
+
addScreenMedia(options?: ScreenShareOptions): Promise<void>;
|
|
1729
1832
|
removeScreenMedia(): Promise<void>;
|
|
1730
1833
|
addInputDevice(options?: MediaOptions): Promise<string | undefined>;
|
|
1731
1834
|
removeInputDevices(id: string): Promise<void>;
|
|
@@ -1733,7 +1836,7 @@ interface VertoManager {
|
|
|
1733
1836
|
updateMediaConstraints(options?: {
|
|
1734
1837
|
audio?: MediaTrackConstraints;
|
|
1735
1838
|
video?: MediaTrackConstraints;
|
|
1736
|
-
}): Promise<
|
|
1839
|
+
}): Promise<boolean>;
|
|
1737
1840
|
muteMainAudioInputDevice(): void;
|
|
1738
1841
|
unmuteMainAudioInputDevice(): Promise<void>;
|
|
1739
1842
|
muteMainVideoInputDevice(): void;
|
|
@@ -1757,12 +1860,12 @@ type ParticipantState = Member & {
|
|
|
1757
1860
|
* the local participant with additional device control.
|
|
1758
1861
|
*/
|
|
1759
1862
|
declare class Participant extends Destroyable implements CallParticipant {
|
|
1760
|
-
|
|
1863
|
+
private callExecuteMethod;
|
|
1761
1864
|
protected deviceController: DeviceController;
|
|
1762
1865
|
/** Unique member ID of this participant. */
|
|
1763
1866
|
readonly id: string;
|
|
1764
1867
|
private _state$;
|
|
1765
|
-
constructor(id: string,
|
|
1868
|
+
constructor(id: string, callExecuteMethod: ExecuteMethod, deviceController: DeviceController);
|
|
1766
1869
|
/** @internal */
|
|
1767
1870
|
upnext(data: Partial<ParticipantState>): void;
|
|
1768
1871
|
/** Observable of the participant's display name. */
|
|
@@ -1885,6 +1988,30 @@ declare class Participant extends Destroyable implements CallParticipant {
|
|
|
1885
1988
|
get callId(): string | undefined;
|
|
1886
1989
|
/** @internal */
|
|
1887
1990
|
get value(): Partial<Member>;
|
|
1991
|
+
/**
|
|
1992
|
+
* Target triple for member RPCs, built from the participant's own state.
|
|
1993
|
+
* The backend locates the member's session by the target `call_id`/`node_id`,
|
|
1994
|
+
* so this must always be the participant's own call context — never the
|
|
1995
|
+
* local call's id (issue #19400).
|
|
1996
|
+
*
|
|
1997
|
+
* Reading it doubles as a readiness probe: it throws until the first full
|
|
1998
|
+
* member event (`member.joined`/`member.updated` or the `call.joined`
|
|
1999
|
+
* roster) arrives, and never regresses afterwards.
|
|
2000
|
+
*
|
|
2001
|
+
* @throws {ParticipantNotReadyError} If the member state has not been
|
|
2002
|
+
* received yet (e.g. a participant first seen via `member.talking`) — an
|
|
2003
|
+
* empty call context can never address the member, so fail fast instead of
|
|
2004
|
+
* sending a doomed RPC.
|
|
2005
|
+
*/
|
|
2006
|
+
get target(): MemberTarget;
|
|
2007
|
+
/**
|
|
2008
|
+
* Executes a member RPC against this participant, injecting its own
|
|
2009
|
+
* {@link target} as the target.
|
|
2010
|
+
*
|
|
2011
|
+
* @throws {ParticipantNotReadyError} Via {@link target}, when the
|
|
2012
|
+
* member state has not been received yet.
|
|
2013
|
+
*/
|
|
2014
|
+
protected executeMethod(method: string, args: Record<string, unknown>): Promise<JSONRPCResponse>;
|
|
1888
2015
|
/** Toggles the deafened state (mutes/unmutes incoming audio). */
|
|
1889
2016
|
toggleDeaf(): Promise<void>;
|
|
1890
2017
|
/** Toggles the hand-raised state. */
|
|
@@ -1949,12 +2076,10 @@ declare class Participant extends Destroyable implements CallParticipant {
|
|
|
1949
2076
|
/**
|
|
1950
2077
|
* Sets the participant's position in the video layout.
|
|
1951
2078
|
*
|
|
1952
|
-
* Requires the `member.position` capability. The gateway
|
|
1953
|
-
*
|
|
1954
|
-
*
|
|
1955
|
-
*
|
|
1956
|
-
* guarantee a visible change: the backend silently returns `200` (no-op) for
|
|
1957
|
-
* non-conference targets.
|
|
2079
|
+
* Requires the `member.position` capability. The gateway requires a
|
|
2080
|
+
* `targets` array of `{ target, position }` entries (issue #19400). A
|
|
2081
|
+
* resolved promise does not guarantee a visible change: the backend silently
|
|
2082
|
+
* returns `200` (no-op) for non-conference targets.
|
|
1958
2083
|
*
|
|
1959
2084
|
* @param value - The {@link VideoPosition} to assign (e.g. `'auto'`, `'reserved-0'`).
|
|
1960
2085
|
*/
|
|
@@ -1998,7 +2123,7 @@ declare class SelfParticipant extends Participant implements CallSelfParticipant
|
|
|
1998
2123
|
*/
|
|
1999
2124
|
private _studioAudio$;
|
|
2000
2125
|
/** @internal */
|
|
2001
|
-
constructor(id: string,
|
|
2126
|
+
constructor(id: string, callExecuteMethod: ExecuteMethod, vertoManager: VertoManager, deviceController: DeviceController);
|
|
2002
2127
|
destroy(): void;
|
|
2003
2128
|
/** Observable indicating whether studio audio (raw/unprocessed audio) mode is enabled. */
|
|
2004
2129
|
get studioAudio$(): Observable<boolean>;
|
|
@@ -2014,15 +2139,42 @@ declare class SelfParticipant extends Participant implements CallSelfParticipant
|
|
|
2014
2139
|
* Sets echoCancellation, noiseSuppression, and autoGainControl to true.
|
|
2015
2140
|
*/
|
|
2016
2141
|
disableStudioAudio(): Promise<void>;
|
|
2017
|
-
/**
|
|
2018
|
-
|
|
2142
|
+
/**
|
|
2143
|
+
* Starts sharing the local screen.
|
|
2144
|
+
*
|
|
2145
|
+
* A call carries at most one screen share. Read `screenShareStatus` before
|
|
2146
|
+
* calling and treat `'starting'`/`'stopping'` as busy.
|
|
2147
|
+
*
|
|
2148
|
+
* The call is unaffected when acquisition fails.
|
|
2149
|
+
*
|
|
2150
|
+
* @param options - Pass `{ audio: true }` to also request the shared
|
|
2151
|
+
* surface's audio. Defaults to video only.
|
|
2152
|
+
* @throws {ScreenShareAlreadyActiveError} When this call is already
|
|
2153
|
+
* sharing a screen. Call {@link stopScreenShare} before starting another.
|
|
2154
|
+
* @throws {AuxiliaryLegCancelledError} When {@link stopScreenShare} removes
|
|
2155
|
+
* the share before its leg finishes connecting.
|
|
2156
|
+
* @throws The raw `getDisplayMedia` error. A dismissed picker or a
|
|
2157
|
+
* permission denial rejects with a `NotAllowedError` `DOMException` —
|
|
2158
|
+
* inspect `error.name` to tell benign cancels apart from real failures.
|
|
2159
|
+
*/
|
|
2160
|
+
startScreenShare(options?: ScreenShareOptions): Promise<void>;
|
|
2019
2161
|
/** Observable of the current screen share status. */
|
|
2020
2162
|
get screenShareStatus$(): Observable<ScreenShareStatus>;
|
|
2021
2163
|
/** Current screen share status. */
|
|
2022
2164
|
get screenShareStatus(): ScreenShareStatus;
|
|
2023
2165
|
/** Stops the current screen share. */
|
|
2024
2166
|
stopScreenShare(): Promise<void>;
|
|
2025
|
-
/**
|
|
2167
|
+
/**
|
|
2168
|
+
* Adds an additional media input device to the call.
|
|
2169
|
+
*
|
|
2170
|
+
* The call is unaffected when acquisition fails.
|
|
2171
|
+
*
|
|
2172
|
+
* @throws {AuxiliaryLegCancelledError} When {@link removeAdditionalDevice}
|
|
2173
|
+
* removes the device before its leg finishes connecting.
|
|
2174
|
+
* @throws The raw `getUserMedia` error (e.g. `NotAllowedError` on
|
|
2175
|
+
* permission denial) — inspect `error.name` to decide how to react — or
|
|
2176
|
+
* `AuxiliaryLegTimeoutError` if the leg does not connect in time.
|
|
2177
|
+
*/
|
|
2026
2178
|
addAdditionalDevice(options: MediaOptions): Promise<void>;
|
|
2027
2179
|
/** Removes an additional media input device by ID. */
|
|
2028
2180
|
removeAdditionalDevice(id: string): Promise<void>;
|
|
@@ -2046,17 +2198,26 @@ declare class SelfParticipant extends Participant implements CallSelfParticipant
|
|
|
2046
2198
|
addInputDevices(options?: MediaOptions): Promise<void>;
|
|
2047
2199
|
/** Selects the audio input device for future calls. Optionally saves as a preference. */
|
|
2048
2200
|
selectAudioInputDevice(device: MediaDeviceInfo, options?: SelectDeviceOptions): void;
|
|
2049
|
-
/**
|
|
2050
|
-
|
|
2051
|
-
|
|
2201
|
+
/**
|
|
2202
|
+
* Updates the audio input track constraints for the active call.
|
|
2203
|
+
* @returns whether the constraints reached the media the call is sending.
|
|
2204
|
+
*/
|
|
2205
|
+
setAudioInputDeviceConstraints(constraints: MediaTrackConstraints): Promise<boolean>;
|
|
2206
|
+
/**
|
|
2207
|
+
* Updates both audio and video input track constraints for the active call.
|
|
2208
|
+
* @returns whether both kinds took the constraints.
|
|
2209
|
+
*/
|
|
2052
2210
|
setInputDevicesConstraints(constraints: {
|
|
2053
2211
|
audio: MediaTrackConstraints;
|
|
2054
2212
|
video: MediaTrackConstraints;
|
|
2055
|
-
}): Promise<
|
|
2213
|
+
}): Promise<boolean>;
|
|
2056
2214
|
/** Selects the video input device for future calls. Optionally saves as a preference. */
|
|
2057
2215
|
selectVideoInputDevice(device: MediaDeviceInfo, options?: SelectDeviceOptions): void;
|
|
2058
|
-
/**
|
|
2059
|
-
|
|
2216
|
+
/**
|
|
2217
|
+
* Updates the video input track constraints for the active call.
|
|
2218
|
+
* @returns whether the constraints reached the media the call is sending.
|
|
2219
|
+
*/
|
|
2220
|
+
setVideoInputDeviceConstraints(constraints: MediaTrackConstraints): Promise<boolean>;
|
|
2060
2221
|
/** Selects the audio output device. Optionally saves as a preference. */
|
|
2061
2222
|
selectAudioOutputDevice(device: MediaDeviceInfo, options?: SelectDeviceOptions): void;
|
|
2062
2223
|
/**
|
|
@@ -2130,6 +2291,9 @@ interface CallParticipant {
|
|
|
2130
2291
|
readonly addressId: string | undefined;
|
|
2131
2292
|
readonly nodeId: string | undefined;
|
|
2132
2293
|
readonly callId: string | undefined;
|
|
2294
|
+
/** The member's own RPC target triple. Throws `ParticipantNotReadyError`
|
|
2295
|
+
* until the member's call context has been received. */
|
|
2296
|
+
readonly target: MemberTarget;
|
|
2133
2297
|
readonly isTalking: boolean;
|
|
2134
2298
|
readonly position: LayoutLayer | undefined;
|
|
2135
2299
|
readonly isAudience: boolean;
|
|
@@ -2165,7 +2329,7 @@ interface CallSelfParticipant extends CallParticipant {
|
|
|
2165
2329
|
readonly studioAudio: boolean;
|
|
2166
2330
|
enableStudioAudio(): Promise<void>;
|
|
2167
2331
|
disableStudioAudio(): Promise<void>;
|
|
2168
|
-
startScreenShare(): Promise<void>;
|
|
2332
|
+
startScreenShare(options?: ScreenShareOptions): Promise<void>;
|
|
2169
2333
|
stopScreenShare(): Promise<void>;
|
|
2170
2334
|
selectAudioInputDevice(device: MediaDeviceInfo, options?: SelectDeviceOptions): void;
|
|
2171
2335
|
selectVideoInputDevice(device: MediaDeviceInfo, options?: SelectDeviceOptions): void;
|
|
@@ -2181,12 +2345,12 @@ interface CallSelfParticipant extends CallParticipant {
|
|
|
2181
2345
|
stream?: MediaStream;
|
|
2182
2346
|
}): Promise<void>;
|
|
2183
2347
|
addInputDevices(options?: MediaOptions): Promise<void>;
|
|
2184
|
-
setAudioInputDeviceConstraints(constraints: MediaTrackConstraints): Promise<
|
|
2185
|
-
setVideoInputDeviceConstraints(constraints: MediaTrackConstraints): Promise<
|
|
2348
|
+
setAudioInputDeviceConstraints(constraints: MediaTrackConstraints): Promise<boolean>;
|
|
2349
|
+
setVideoInputDeviceConstraints(constraints: MediaTrackConstraints): Promise<boolean>;
|
|
2186
2350
|
setInputDevicesConstraints(constraints: {
|
|
2187
2351
|
audio: MediaTrackConstraints;
|
|
2188
2352
|
video: MediaTrackConstraints;
|
|
2189
|
-
}): Promise<
|
|
2353
|
+
}): Promise<boolean>;
|
|
2190
2354
|
}
|
|
2191
2355
|
/**
|
|
2192
2356
|
* Minimal interface for a collection with pagination
|
|
@@ -2274,7 +2438,8 @@ interface Call extends CallState {
|
|
|
2274
2438
|
readonly capabilities: Capability[];
|
|
2275
2439
|
readonly mediaDirections$: Observable<MediaDirections>;
|
|
2276
2440
|
readonly mediaDirections: MediaDirections;
|
|
2277
|
-
|
|
2441
|
+
/** Withholds emission until self exists, so it never emits `null` — unlike {@link Call.self}. */
|
|
2442
|
+
readonly self$: Observable<CallSelfParticipant>;
|
|
2278
2443
|
readonly self: CallSelfParticipant | null;
|
|
2279
2444
|
readonly to?: string;
|
|
2280
2445
|
readonly toName?: string;
|
|
@@ -2328,6 +2493,17 @@ interface Call extends CallState {
|
|
|
2328
2493
|
answer(options?: MediaOptions): void;
|
|
2329
2494
|
reject(): void;
|
|
2330
2495
|
sendDigits(digits: string): Promise<void>;
|
|
2496
|
+
readonly localAudioLevel$: Observable<number>;
|
|
2497
|
+
readonly localSpeaking$: Observable<boolean>;
|
|
2498
|
+
readonly remoteAudioLevel$: Observable<number>;
|
|
2499
|
+
readonly localMicrophoneGain$: Observable<number>;
|
|
2500
|
+
setLocalMicrophoneGain(value: number): void;
|
|
2501
|
+
enablePushToTalk(): void;
|
|
2502
|
+
disablePushToTalk(): void;
|
|
2503
|
+
setPushToTalkActive(active: boolean): void;
|
|
2504
|
+
setEchoCancellation(enabled: boolean): Promise<boolean>;
|
|
2505
|
+
setNoiseSuppression(enabled: boolean): Promise<boolean>;
|
|
2506
|
+
setAutoGainControl(enabled: boolean): Promise<boolean>;
|
|
2331
2507
|
executeMethod<T extends JSONRPCResponse = JSONRPCResponse>(target: string, method: string, args: Record<string, unknown>): Promise<T>;
|
|
2332
2508
|
execute<T extends JSONRPCResponse = JSONRPCResponse>(request: JSONRPCRequest, options?: PendingRPCOptions): Promise<T>;
|
|
2333
2509
|
}
|
|
@@ -2605,9 +2781,27 @@ declare class AttachManager {
|
|
|
2605
2781
|
private readonly deviceController;
|
|
2606
2782
|
private readonly reconnectCallsTimeout;
|
|
2607
2783
|
private attachKey;
|
|
2784
|
+
/**
|
|
2785
|
+
* Whether a credential recovery has been verified on this client — the
|
|
2786
|
+
* session reauthenticated with a fresh token AND the operation that
|
|
2787
|
+
* reauthentication was meant to unblock then succeeded. Gates attach-record
|
|
2788
|
+
* discard together with the failure kind: a record is dropped only when
|
|
2789
|
+
* this is true AND the reattach refusal was NOT a credential refusal
|
|
2790
|
+
* (-32003). See {@link reattachCalls}.
|
|
2791
|
+
*/
|
|
2792
|
+
private readonly credentialRecovered;
|
|
2608
2793
|
private session;
|
|
2609
2794
|
private writeQueue;
|
|
2610
|
-
constructor(storage: StorageManager, deviceController: DeviceController, reconnectCallsTimeout: number, attachKey: string
|
|
2795
|
+
constructor(storage: StorageManager, deviceController: DeviceController, reconnectCallsTimeout: number, attachKey: string,
|
|
2796
|
+
/**
|
|
2797
|
+
* Whether a credential recovery has been verified on this client — the
|
|
2798
|
+
* session reauthenticated with a fresh token AND the operation that
|
|
2799
|
+
* reauthentication was meant to unblock then succeeded. Gates attach-record
|
|
2800
|
+
* discard together with the failure kind: a record is dropped only when
|
|
2801
|
+
* this is true AND the reattach refusal was NOT a credential refusal
|
|
2802
|
+
* (-32003). See {@link reattachCalls}.
|
|
2803
|
+
*/
|
|
2804
|
+
credentialRecovered: () => boolean);
|
|
2611
2805
|
detachAll(): Promise<void>;
|
|
2612
2806
|
setSession(session: OutboundCallProvider): void;
|
|
2613
2807
|
private readAttached;
|
|
@@ -2620,6 +2814,19 @@ declare class AttachManager {
|
|
|
2620
2814
|
*/
|
|
2621
2815
|
private mutate;
|
|
2622
2816
|
attach(call: AttachableCall): Promise<void>;
|
|
2817
|
+
/**
|
|
2818
|
+
* Keep an already-stored call's reference alive and current — the periodic
|
|
2819
|
+
* refresh the `verto.ping` keepalive drives.
|
|
2820
|
+
*
|
|
2821
|
+
* Only ever updates: a call with no record is one nothing wants reattached,
|
|
2822
|
+
* and re-creating it here would undo a `detach`. That matters because a ping
|
|
2823
|
+
* can land in the window between `bye()` detaching and the call being torn
|
|
2824
|
+
* down, and a record revived there survives the hangup — so the next page
|
|
2825
|
+
* load dials a call nobody is on. The existence check and the write share
|
|
2826
|
+
* one {@link mutate} turn, so a concurrent detach cannot slip between them.
|
|
2827
|
+
*/
|
|
2828
|
+
refresh(call: AttachableCall): Promise<void>;
|
|
2829
|
+
private buildAttachment;
|
|
2623
2830
|
detach(call: AttachableCall): Promise<void>;
|
|
2624
2831
|
flush(): Promise<void>;
|
|
2625
2832
|
/**
|
|
@@ -2634,8 +2841,14 @@ declare class AttachManager {
|
|
|
2634
2841
|
* rejecting. Once that fix is deployed, this will work for both
|
|
2635
2842
|
* page reloads and WebSocket reconnects.
|
|
2636
2843
|
*
|
|
2637
|
-
*
|
|
2638
|
-
*
|
|
2844
|
+
* A failed reattach does NOT generally cost the stored reference. It is
|
|
2845
|
+
* discarded only when the server denied the reattach on a session whose
|
|
2846
|
+
* credential it had already accepted — a verified reauthentication followed
|
|
2847
|
+
* by a refusal is the server saying the call is gone, and that is the one
|
|
2848
|
+
* refusal worth acting on. Until then the credential may be what is being
|
|
2849
|
+
* refused, and the record is the only way a later reload can try again;
|
|
2850
|
+
* keeping it costs nothing, since `detachExpired` reaps it once it is older
|
|
2851
|
+
* than `reconnectCallsTimeout`.
|
|
2639
2852
|
*/
|
|
2640
2853
|
reattachCalls(): Promise<void>;
|
|
2641
2854
|
/**
|
|
@@ -2792,56 +3005,6 @@ interface NetworkChangeEvent {
|
|
|
2792
3005
|
networkType?: string;
|
|
2793
3006
|
}
|
|
2794
3007
|
//#endregion
|
|
2795
|
-
//#region src/core/entities/Directory.d.ts
|
|
2796
|
-
/**
|
|
2797
|
-
* Directory interface for managing addresses
|
|
2798
|
-
*
|
|
2799
|
-
* This is the public API contract for address directory functionality.
|
|
2800
|
-
* It provides access to addresses, loading capabilities, and search functionality.
|
|
2801
|
-
*
|
|
2802
|
-
* @public
|
|
2803
|
-
*/
|
|
2804
|
-
interface Directory extends AddressProvider<Address> {
|
|
2805
|
-
/**
|
|
2806
|
-
* Observable stream of all addresses in the directory
|
|
2807
|
-
* Emits a new array whenever addresses are added, removed, or updated
|
|
2808
|
-
*/
|
|
2809
|
-
readonly addresses$: Observable<Address[]>;
|
|
2810
|
-
/**
|
|
2811
|
-
* Current snapshot of all addresses in the directory
|
|
2812
|
-
*/
|
|
2813
|
-
readonly addresses: Address[];
|
|
2814
|
-
/**
|
|
2815
|
-
* Observable indicating whether more addresses can be loaded from the server
|
|
2816
|
-
*/
|
|
2817
|
-
readonly hasMore$: Observable<boolean>;
|
|
2818
|
-
/**
|
|
2819
|
-
* Observable indicating the current loading state
|
|
2820
|
-
* Emits `true` when loading, `false` when idle
|
|
2821
|
-
*/
|
|
2822
|
-
readonly loading$: Observable<boolean>;
|
|
2823
|
-
readonly loading: boolean;
|
|
2824
|
-
/**
|
|
2825
|
-
* Load more addresses from the server
|
|
2826
|
-
* Only loads if `hasMore` is true
|
|
2827
|
-
*/
|
|
2828
|
-
loadMore(): void;
|
|
2829
|
-
/**
|
|
2830
|
-
* Get a specific address by ID
|
|
2831
|
-
*
|
|
2832
|
-
* @param addressId - The address ID to retrieve
|
|
2833
|
-
* @returns The address instance, or undefined if not found
|
|
2834
|
-
*/
|
|
2835
|
-
get(addressId: string): Address | undefined;
|
|
2836
|
-
/**
|
|
2837
|
-
* Find an address ID by searching for a name
|
|
2838
|
-
*
|
|
2839
|
-
* @param uri - The address name to search for
|
|
2840
|
-
* @returns Promise resolving to the address ID, or undefined if not found
|
|
2841
|
-
*/
|
|
2842
|
-
findAddressIdByURI(uri: string): Promise<string | undefined>;
|
|
2843
|
-
}
|
|
2844
|
-
//#endregion
|
|
2845
3008
|
//#region src/interfaces/ClientSession.d.ts
|
|
2846
3009
|
/**
|
|
2847
3010
|
* Minimal interface for what Call needs from session management
|
|
@@ -2871,2026 +3034,2406 @@ interface ClientSession {
|
|
|
2871
3034
|
* indicates a re-authentication after the initial connect).
|
|
2872
3035
|
*/
|
|
2873
3036
|
readonly authenticated$: Observable<boolean>;
|
|
3037
|
+
/**
|
|
3038
|
+
* Control transport for every call in this session: `'routed'` (default) sends
|
|
3039
|
+
* call.* verbs on the client's session channel; `'in-dialog'` carries them on
|
|
3040
|
+
* each call's own signaling channel via `verto.info`. Set once as a client
|
|
3041
|
+
* config ({@link SignalWireOptions.callControl}) — it is session-wide, so a
|
|
3042
|
+
* reattached call reads it here rather than restoring it from persisted state.
|
|
3043
|
+
* Read by {@link Call.executeMethod}.
|
|
3044
|
+
*/
|
|
3045
|
+
readonly callControl: 'routed' | 'in-dialog';
|
|
2874
3046
|
}
|
|
2875
3047
|
//#endregion
|
|
2876
|
-
//#region src/
|
|
3048
|
+
//#region src/controllers/LocalAudioPipeline.d.ts
|
|
2877
3049
|
/**
|
|
2878
|
-
*
|
|
2879
|
-
|
|
3050
|
+
* Options for {@link LocalAudioPipeline}.
|
|
3051
|
+
*/
|
|
3052
|
+
interface LocalAudioPipelineOptions {
|
|
3053
|
+
/** Factory for AudioContext — override for tests. Defaults to `new AudioContext()`. */
|
|
3054
|
+
audioContextFactory?: () => AudioContext;
|
|
3055
|
+
/** Initial gain (0..2, where 1 is unity). Defaults to 1. */
|
|
3056
|
+
initialGain?: number;
|
|
3057
|
+
/** RMS level [0..1] above which speaking$ emits true. Defaults to {@link VAD_THRESHOLD}. */
|
|
3058
|
+
speakingThreshold?: number;
|
|
3059
|
+
/**
|
|
3060
|
+
* Milliseconds of silence below the threshold before speaking$ flips back to
|
|
3061
|
+
* false. Prevents flicker on normal speech gaps. Defaults to {@link VAD_HOLD_MS}.
|
|
3062
|
+
*/
|
|
3063
|
+
speakingHoldMs?: number;
|
|
3064
|
+
/** Polling interval for level$. Defaults to {@link AUDIO_LEVEL_POLL_INTERVAL_MS}. */
|
|
3065
|
+
pollIntervalMs?: number;
|
|
3066
|
+
}
|
|
3067
|
+
/**
|
|
3068
|
+
* Web Audio pipeline for the local microphone stream.
|
|
2880
3069
|
*
|
|
2881
|
-
*
|
|
2882
|
-
*
|
|
3070
|
+
* Wraps the raw mic `MediaStreamTrack` in a graph of:
|
|
3071
|
+
*
|
|
3072
|
+
* ```
|
|
3073
|
+
* MediaStreamAudioSourceNode → GainNode → AnalyserNode → MediaStreamAudioDestinationNode
|
|
3074
|
+
* ```
|
|
3075
|
+
*
|
|
3076
|
+
* The {@link outputTrack} from the destination node is what callers should
|
|
3077
|
+
* attach to the `RTCRtpSender` in place of the raw mic track. The same
|
|
3078
|
+
* destination track is reused across input changes (device switch, mute /
|
|
3079
|
+
* unmute track replacement) so the sender reference stays stable — only the
|
|
3080
|
+
* source end of the graph is rebuilt.
|
|
3081
|
+
*
|
|
3082
|
+
* The pipeline owns a single {@link AudioContext}. Callers must invoke
|
|
3083
|
+
* {@link destroy} to release it when the call ends.
|
|
2883
3084
|
*/
|
|
2884
|
-
|
|
3085
|
+
declare class LocalAudioPipeline extends Destroyable {
|
|
3086
|
+
private readonly _audioContext;
|
|
3087
|
+
private readonly _gainNode;
|
|
3088
|
+
private readonly _analyser;
|
|
3089
|
+
private readonly _destination;
|
|
3090
|
+
private readonly _analyserBuffer;
|
|
3091
|
+
private readonly _speakingThreshold;
|
|
3092
|
+
private readonly _speakingHoldMs;
|
|
3093
|
+
private readonly _pollIntervalMs;
|
|
3094
|
+
private _inputSource;
|
|
3095
|
+
private _inputStream;
|
|
3096
|
+
private _lastSpokeAt;
|
|
3097
|
+
private _gain$;
|
|
3098
|
+
/** 1 when audio should pass through, 0 when silenced by PTT. */
|
|
3099
|
+
private _pttMultiplier;
|
|
3100
|
+
constructor(options?: LocalAudioPipelineOptions);
|
|
3101
|
+
/** Observable of the current gain value (0..2). */
|
|
3102
|
+
get gain$(): Observable<number>;
|
|
3103
|
+
/** Current gain value (0..2). */
|
|
3104
|
+
get gain(): number;
|
|
2885
3105
|
/**
|
|
2886
|
-
*
|
|
2887
|
-
*
|
|
3106
|
+
* Processed output track to attach to the RTCRtpSender. Stable reference
|
|
3107
|
+
* across input changes, so `sender.replaceTrack(pipeline.outputTrack)` only
|
|
3108
|
+
* needs to be called once.
|
|
2888
3109
|
*/
|
|
2889
|
-
|
|
3110
|
+
get outputTrack(): MediaStreamTrack;
|
|
2890
3111
|
/**
|
|
2891
|
-
*
|
|
3112
|
+
* Root-mean-square audio level of the input signal, 0..1. Emits on a fixed
|
|
3113
|
+
* interval (~30fps by default).
|
|
2892
3114
|
*/
|
|
2893
|
-
|
|
3115
|
+
get level$(): Observable<number>;
|
|
2894
3116
|
/**
|
|
2895
|
-
*
|
|
3117
|
+
* Boolean VAD derived from {@link level$}. True while level ≥ threshold or
|
|
3118
|
+
* during the hold window after the last frame that crossed the threshold.
|
|
2896
3119
|
*/
|
|
2897
|
-
|
|
3120
|
+
get speaking$(): Observable<boolean>;
|
|
2898
3121
|
/**
|
|
2899
|
-
*
|
|
3122
|
+
* Set gain multiplier applied to the input signal. 0 = silence,
|
|
3123
|
+
* 1 = unity, 2 = 2x. Values are clamped to [0, 2]. The effective gain on
|
|
3124
|
+
* the graph also respects the current PTT state.
|
|
2900
3125
|
*/
|
|
2901
|
-
|
|
3126
|
+
setGain(value: number): void;
|
|
2902
3127
|
/**
|
|
2903
|
-
*
|
|
2904
|
-
*
|
|
3128
|
+
* Silence the graph when `active = false`, otherwise restore the configured
|
|
3129
|
+
* gain. Use this from a PTT handler: released → `false`, held → `true`.
|
|
3130
|
+
* Orthogonal to {@link setGain} — once PTT returns to active, the last
|
|
3131
|
+
* configured gain reappears.
|
|
2905
3132
|
*/
|
|
2906
|
-
|
|
3133
|
+
setPTTActive(active: boolean): void;
|
|
3134
|
+
private applyEffectiveGain;
|
|
2907
3135
|
/**
|
|
2908
|
-
*
|
|
2909
|
-
*
|
|
3136
|
+
* Wire a new raw mic track as the pipeline's input. Replaces any previous
|
|
3137
|
+
* input source and reconnects the graph so {@link outputTrack} continues
|
|
3138
|
+
* to emit the processed audio. Pass `null` to disconnect the input (the
|
|
3139
|
+
* output track stays alive but emits silence).
|
|
3140
|
+
*
|
|
3141
|
+
* Also resumes the underlying AudioContext on attach — Chrome creates it
|
|
3142
|
+
* in a suspended state and the graph won't process (the destination
|
|
3143
|
+
* track emits silence) until resume() succeeds.
|
|
2910
3144
|
*/
|
|
2911
|
-
|
|
3145
|
+
setInputTrack(track: MediaStreamTrack | null): void;
|
|
3146
|
+
destroy(): void;
|
|
3147
|
+
private computeLevel;
|
|
3148
|
+
private evaluateSpeaking;
|
|
2912
3149
|
}
|
|
2913
3150
|
//#endregion
|
|
2914
|
-
//#region src/
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
|
|
2922
|
-
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
private readonly agent;
|
|
2935
|
-
private readonly eventAcks;
|
|
2936
|
-
initialized$: Observable<boolean>;
|
|
2937
|
-
private authorizationState$;
|
|
2938
|
-
private connectVersion;
|
|
2939
|
-
/**
|
|
2940
|
-
* Optional hook called before a fresh connect on reconnect.
|
|
2941
|
-
* Used by SignalWire to refresh expired credentials before re-authenticating.
|
|
2942
|
-
* @internal
|
|
2943
|
-
*/
|
|
2944
|
-
onBeforeReconnect?: () => Promise<void>;
|
|
2945
|
-
private _authorization$;
|
|
2946
|
-
private _errors$;
|
|
2947
|
-
private _directory?;
|
|
2948
|
-
private _authState$;
|
|
2949
|
-
/** Sticky flag — once true, stays true for the session lifetime. */
|
|
2950
|
-
private _wasClientBound;
|
|
2951
|
-
private _userInfo$;
|
|
2952
|
-
private _calls$;
|
|
2953
|
-
private _iceServers$;
|
|
2954
|
-
constructor(getCredential: () => SDKCredential, transport: TransportManager, storage: StorageManager, authorizationStateKey: string, deviceController: DeviceController, attachManager: AttachManager, webRTCApiProvider: WebRTCApiProvider, dpopManager?: CryptoController | undefined, networkChange$?: Observable<NetworkChangeEvent>);
|
|
2955
|
-
get incomingCalls$(): Observable<Call[]>;
|
|
2956
|
-
get incomingCalls(): Call[];
|
|
2957
|
-
get userInfo$(): Observable<Address | null>;
|
|
2958
|
-
get userInfo(): Address | null;
|
|
2959
|
-
get calls$(): Observable<Call[]>;
|
|
2960
|
-
get calls(): Call[];
|
|
2961
|
-
get iceServers(): RTCIceServer[] | undefined;
|
|
2962
|
-
get authorization$(): Observable<Authorization | undefined>;
|
|
2963
|
-
get authorization(): Authorization | undefined;
|
|
2964
|
-
get errors$(): Observable<Error>;
|
|
2965
|
-
get authenticated$(): Observable<boolean>;
|
|
2966
|
-
get authenticated(): boolean;
|
|
3151
|
+
//#region src/controllers/RTCPeerConnectionController.d.ts
|
|
3152
|
+
interface RTCPeerConnectionControllerOptions extends MediaOptions {
|
|
3153
|
+
callId?: string;
|
|
3154
|
+
rtcConfiguration?: RTCConfiguration;
|
|
3155
|
+
simulcast?: boolean;
|
|
3156
|
+
sfu?: boolean;
|
|
3157
|
+
msStreamsNumber?: number;
|
|
3158
|
+
propose: RTCPeerConnectionPropose;
|
|
3159
|
+
iceServers?: RTCIceServer[];
|
|
3160
|
+
disableUdpIceServers?: boolean;
|
|
3161
|
+
relayOnly?: boolean;
|
|
3162
|
+
iceCandidateTimeout?: number;
|
|
3163
|
+
iceGatheringTimeout?: number;
|
|
3164
|
+
webRTCApiProvider?: WebRTCApiProvider;
|
|
3165
|
+
/** Per-call preferred video codecs (overrides global preferences). */
|
|
3166
|
+
preferredVideoCodecs?: string[];
|
|
3167
|
+
/** Per-call preferred audio codecs (overrides global preferences). */
|
|
3168
|
+
preferredAudioCodecs?: string[];
|
|
3169
|
+
/** Per-call stereo Opus setting (overrides global preferences). */
|
|
3170
|
+
stereo?: boolean;
|
|
2967
3171
|
/**
|
|
2968
|
-
*
|
|
2969
|
-
*
|
|
2970
|
-
* authentication errors rather than silently degraded.
|
|
2971
|
-
* @internal
|
|
3172
|
+
* Request the shared surface's audio on a `'screenshare'` connection. Kept
|
|
3173
|
+
* apart from `audio`, which selects a microphone the share must not inherit.
|
|
2972
3174
|
*/
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
|
|
3175
|
+
screenShareAudio?: boolean;
|
|
3176
|
+
}
|
|
3177
|
+
type RTCPeerConnectionControllerOptionsPartial = Partial<RTCPeerConnectionControllerOptions>;
|
|
3178
|
+
interface UpdateSDPStatusParams {
|
|
3179
|
+
status: 'received' | 'sent' | 'failed';
|
|
3180
|
+
sdp?: string;
|
|
3181
|
+
}
|
|
3182
|
+
declare class RTCPeerConnectionController extends Destroyable {
|
|
3183
|
+
protected options: RTCPeerConnectionControllerOptionsPartial;
|
|
3184
|
+
readonly id: string;
|
|
3185
|
+
firstSDPExchangeCompleted: boolean;
|
|
3186
|
+
sdpInit?: RTCSessionDescriptionInit;
|
|
3187
|
+
private negotiationNeeded$;
|
|
3188
|
+
private deviceController;
|
|
3189
|
+
private localStreamController;
|
|
3190
|
+
private transceiverController?;
|
|
3191
|
+
readonly localDescription$: Observable<RTCSessionDescription | null>;
|
|
3192
|
+
peerConnection?: RTCPeerConnection;
|
|
3193
|
+
private initPromise?;
|
|
3194
|
+
private connectionTimeout;
|
|
3195
|
+
private connectionTimer?;
|
|
3196
|
+
private oniceconnectionstatechangeHandler;
|
|
3197
|
+
private onconnectionstatechangeHandler;
|
|
3198
|
+
private onsignalingstatechangeHandler;
|
|
3199
|
+
private onicegatheringstatechangeHandler;
|
|
3200
|
+
private onnegotiationneededHandler;
|
|
3201
|
+
private updateSelectedInputDevice;
|
|
3202
|
+
private _isNegotiating$;
|
|
3203
|
+
private _iceGatheringController?;
|
|
3204
|
+
private _memberId;
|
|
3205
|
+
private _nodeId;
|
|
3206
|
+
private _type;
|
|
3207
|
+
private _iceConnectionState$;
|
|
3208
|
+
private _connectionState$;
|
|
3209
|
+
private _signalingState$;
|
|
3210
|
+
private _iceGatheringState$;
|
|
3211
|
+
private _errors$;
|
|
3212
|
+
private _iceCandidates$;
|
|
2976
3213
|
/**
|
|
2977
|
-
*
|
|
2978
|
-
*
|
|
2979
|
-
*
|
|
3214
|
+
* Emits once local media is settled: acquired, intentionally receive-only, or
|
|
3215
|
+
* failed and degraded. Separates the media and signalling phases of call
|
|
3216
|
+
* creation. Not `localStream$` — the receive-only paths never build a stream,
|
|
3217
|
+
* so that would hang exactly the calls with nothing to acquire.
|
|
3218
|
+
*/
|
|
3219
|
+
private _localMediaSettled$;
|
|
3220
|
+
private _initialized$;
|
|
3221
|
+
private _remoteDescription$;
|
|
3222
|
+
private _remoteStream$;
|
|
3223
|
+
private _remoteOfferMediaDirections;
|
|
3224
|
+
private _localAudioPipeline;
|
|
3225
|
+
constructor(options?: RTCPeerConnectionControllerOptionsPartial, remoteSessionDescription?: string, deviceController?: DeviceController);
|
|
3226
|
+
private get iceGatheringController();
|
|
3227
|
+
private get shouldEmitLocalDescription();
|
|
3228
|
+
private removeConnectionTimer;
|
|
3229
|
+
setMemberId(memberId: string | null): void;
|
|
3230
|
+
get memberId(): string | null;
|
|
3231
|
+
/** The node this leg's invite landed on — auxiliary legs are placed independently. */
|
|
3232
|
+
setNodeId(nodeId: string | null): void;
|
|
3233
|
+
get nodeId(): string | null;
|
|
3234
|
+
stopTrackSender(kind: 'audio' | 'video' | 'both', options?: {
|
|
3235
|
+
updateTransceiverDirection: boolean;
|
|
3236
|
+
}): void;
|
|
3237
|
+
private stopRawAudioInputForPipeline;
|
|
3238
|
+
get isNegotiating$(): Observable<boolean>;
|
|
3239
|
+
get isNegotiating(): boolean;
|
|
3240
|
+
updateMediaDevicesOptions(options: MediaOptions): void;
|
|
3241
|
+
get iceGatheringState$(): Observable<RTCIceGatheringState>;
|
|
3242
|
+
get mediaTrackEnded$(): Observable<MediaStreamTrack>;
|
|
3243
|
+
get errors$(): Observable<Error>;
|
|
3244
|
+
get iceCandidates$(): Observable<RTCIceCandidate[]>;
|
|
3245
|
+
get initialized$(): Observable<boolean>;
|
|
3246
|
+
get remoteDescription$(): Observable<RTCSessionDescription | null>;
|
|
3247
|
+
/** Emits once local media is settled — acquired, or knowingly receive-only. */
|
|
3248
|
+
get localMediaSettled$(): Observable<void>;
|
|
3249
|
+
get localStream$(): Observable<MediaStream | null>;
|
|
3250
|
+
get remoteStream$(): Observable<MediaStream | null>;
|
|
3251
|
+
get localAudioTracks$(): Observable<MediaStreamTrack[]>;
|
|
3252
|
+
get localVideoTracks$(): Observable<MediaStreamTrack[]>;
|
|
3253
|
+
get iceConnectionState$(): Observable<RTCIceConnectionState>;
|
|
3254
|
+
get connectionState$(): Observable<RTCPeerConnectionState>;
|
|
3255
|
+
get signalingState$(): Observable<RTCSignalingState>;
|
|
3256
|
+
get type(): RTCPeerConnectionType;
|
|
3257
|
+
get propose(): RTCPeerConnectionPropose;
|
|
3258
|
+
get connectionState(): RTCPeerConnectionState | undefined;
|
|
3259
|
+
get isAdditionalDevice(): boolean;
|
|
3260
|
+
get isMainDevice(): boolean;
|
|
3261
|
+
get isScreenShare(): boolean;
|
|
3262
|
+
protected get iceServers(): RTCIceServer[];
|
|
3263
|
+
private get rtcConfiguration();
|
|
3264
|
+
get receiveVideo(): boolean;
|
|
3265
|
+
get receiveAudio(): boolean;
|
|
3266
|
+
get localStream(): MediaStream | null;
|
|
3267
|
+
get remoteStream(): MediaStream | null;
|
|
3268
|
+
private get inputAudioDeviceConstraints();
|
|
3269
|
+
private get inputVideoDeviceConstraints();
|
|
3270
|
+
private get WebRTCPeerConnectionConstructor();
|
|
3271
|
+
private get offerOptions();
|
|
3272
|
+
private get answerOptions();
|
|
3273
|
+
/**
|
|
3274
|
+
* Initialize the RTCPeerConnection and setup event listeners.
|
|
3275
|
+
* Called automatically when localDescription$ is subscribed to (deferred pattern).
|
|
3276
|
+
* Uses Promise memoization to ensure initialization only happens once,
|
|
3277
|
+
* even if called concurrently.
|
|
2980
3278
|
*/
|
|
2981
|
-
setDirectory(directory: Directory): void;
|
|
2982
|
-
execute<T extends JSONRPCResponse = JSONRPCResponse>(request: JSONRPCRequest, options?: PendingRPCOptions): Promise<T>;
|
|
2983
|
-
send(message: JSONSerializable): void;
|
|
2984
3279
|
private init;
|
|
2985
|
-
private setupMessageHandlers;
|
|
2986
|
-
private loadAuthorizationStateFromStorage;
|
|
2987
|
-
private updateAuthorizationStateInStorage;
|
|
2988
|
-
private get authStateEvent$();
|
|
2989
|
-
get signalingEvent$(): Observable<(Omit<{
|
|
2990
|
-
event_type: "webrtc.message";
|
|
2991
|
-
event_channel: EventChannel;
|
|
2992
|
-
timestamp: number;
|
|
2993
|
-
project_id?: string;
|
|
2994
|
-
node_id?: string;
|
|
2995
|
-
is_author?: boolean;
|
|
2996
|
-
params: WebrtcMessagePayload;
|
|
2997
|
-
}, "event_channel" | "project_id" | "node_id"> & {
|
|
2998
|
-
event_channel: string;
|
|
2999
|
-
project_id: string;
|
|
3000
|
-
node_id: string;
|
|
3001
|
-
}) | {
|
|
3002
|
-
event_type: "signalwire.authorization.state";
|
|
3003
|
-
params: SignalwireAuthorizationStatePayload;
|
|
3004
|
-
} | (Omit<{
|
|
3005
|
-
event_type: "call.joined";
|
|
3006
|
-
event_channel: EventChannel;
|
|
3007
|
-
timestamp: number;
|
|
3008
|
-
project_id?: string;
|
|
3009
|
-
node_id?: string;
|
|
3010
|
-
is_author?: boolean;
|
|
3011
|
-
params: CallJoinedPayload;
|
|
3012
|
-
}, "event_channel"> & {
|
|
3013
|
-
event_channel: string;
|
|
3014
|
-
}) | (Omit<{
|
|
3015
|
-
event_type: "call.left";
|
|
3016
|
-
event_channel: EventChannel;
|
|
3017
|
-
timestamp: number;
|
|
3018
|
-
project_id?: string;
|
|
3019
|
-
node_id?: string;
|
|
3020
|
-
is_author?: boolean;
|
|
3021
|
-
params: CallLeftPayload;
|
|
3022
|
-
}, "event_channel"> & {
|
|
3023
|
-
event_channel: string;
|
|
3024
|
-
}) | (Omit<{
|
|
3025
|
-
event_type: "call.updated";
|
|
3026
|
-
event_channel: EventChannel;
|
|
3027
|
-
timestamp: number;
|
|
3028
|
-
project_id?: string;
|
|
3029
|
-
node_id?: string;
|
|
3030
|
-
is_author?: boolean;
|
|
3031
|
-
params: CallUpdatedPayload;
|
|
3032
|
-
}, "event_channel"> & {
|
|
3033
|
-
event_channel: string;
|
|
3034
|
-
}) | (Omit<{
|
|
3035
|
-
event_type: "call.state";
|
|
3036
|
-
event_channel: EventChannel;
|
|
3037
|
-
timestamp: number;
|
|
3038
|
-
project_id?: string;
|
|
3039
|
-
node_id?: string;
|
|
3040
|
-
is_author?: boolean;
|
|
3041
|
-
params: CallStatePayload;
|
|
3042
|
-
}, "event_channel"> & {
|
|
3043
|
-
event_channel: string;
|
|
3044
|
-
}) | (Omit<{
|
|
3045
|
-
event_type: "call.play";
|
|
3046
|
-
event_channel: EventChannel;
|
|
3047
|
-
timestamp: number;
|
|
3048
|
-
project_id?: string;
|
|
3049
|
-
node_id?: string;
|
|
3050
|
-
is_author?: boolean;
|
|
3051
|
-
params: CallPlayPayload;
|
|
3052
|
-
}, "event_channel"> & {
|
|
3053
|
-
event_channel: string;
|
|
3054
|
-
}) | (Omit<{
|
|
3055
|
-
event_type: "call.connect";
|
|
3056
|
-
event_channel: EventChannel;
|
|
3057
|
-
timestamp: number;
|
|
3058
|
-
project_id?: string;
|
|
3059
|
-
node_id?: string;
|
|
3060
|
-
is_author?: boolean;
|
|
3061
|
-
params: CallConnectPayload;
|
|
3062
|
-
}, "event_channel"> & {
|
|
3063
|
-
event_channel: string;
|
|
3064
|
-
}) | (Omit<{
|
|
3065
|
-
event_type: "room.updated";
|
|
3066
|
-
event_channel: EventChannel;
|
|
3067
|
-
timestamp: number;
|
|
3068
|
-
project_id?: string;
|
|
3069
|
-
node_id?: string;
|
|
3070
|
-
is_author?: boolean;
|
|
3071
|
-
params: RoomUpdatedPayload;
|
|
3072
|
-
}, "event_channel"> & {
|
|
3073
|
-
event_channel: string;
|
|
3074
|
-
}) | Omit<{
|
|
3075
|
-
event_type: "member.updated";
|
|
3076
|
-
event_channel: EventChannel;
|
|
3077
|
-
timestamp: number;
|
|
3078
|
-
project_id?: string;
|
|
3079
|
-
node_id?: string;
|
|
3080
|
-
is_author?: boolean;
|
|
3081
|
-
params: MemberUpdatedPayload;
|
|
3082
|
-
}, never> | Omit<{
|
|
3083
|
-
event_type: "member.joined";
|
|
3084
|
-
event_channel: EventChannel;
|
|
3085
|
-
timestamp: number;
|
|
3086
|
-
project_id?: string;
|
|
3087
|
-
node_id?: string;
|
|
3088
|
-
is_author?: boolean;
|
|
3089
|
-
params: MemberJoinedPayload;
|
|
3090
|
-
}, never> | Omit<{
|
|
3091
|
-
event_type: "member.left";
|
|
3092
|
-
event_channel: EventChannel;
|
|
3093
|
-
timestamp: number;
|
|
3094
|
-
project_id?: string;
|
|
3095
|
-
node_id?: string;
|
|
3096
|
-
is_author?: boolean;
|
|
3097
|
-
params: MemberLeftPayload;
|
|
3098
|
-
}, never> | Omit<{
|
|
3099
|
-
event_type: "member.talking";
|
|
3100
|
-
event_channel: EventChannel;
|
|
3101
|
-
timestamp: number;
|
|
3102
|
-
project_id?: string;
|
|
3103
|
-
node_id?: string;
|
|
3104
|
-
is_author?: boolean;
|
|
3105
|
-
params: MemberTalkingPayload;
|
|
3106
|
-
}, never> | Omit<{
|
|
3107
|
-
event_type: "layout.changed";
|
|
3108
|
-
event_channel: EventChannel;
|
|
3109
|
-
timestamp: number;
|
|
3110
|
-
project_id?: string;
|
|
3111
|
-
node_id?: string;
|
|
3112
|
-
is_author?: boolean;
|
|
3113
|
-
params: LayoutChangedPayload;
|
|
3114
|
-
}, never> | (Omit<{
|
|
3115
|
-
event_type: "conversation.message";
|
|
3116
|
-
event_channel: EventChannel;
|
|
3117
|
-
timestamp: number;
|
|
3118
|
-
project_id?: string;
|
|
3119
|
-
node_id?: string;
|
|
3120
|
-
is_author?: boolean;
|
|
3121
|
-
params: ConversationMessagePayload;
|
|
3122
|
-
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
3123
|
-
event_channel: string;
|
|
3124
|
-
timestamp: string;
|
|
3125
|
-
is_author: boolean;
|
|
3126
|
-
}) | (Omit<{
|
|
3127
|
-
event_type: "conversation.message.updated";
|
|
3128
|
-
event_channel: EventChannel;
|
|
3129
|
-
timestamp: number;
|
|
3130
|
-
project_id?: string;
|
|
3131
|
-
node_id?: string;
|
|
3132
|
-
is_author?: boolean;
|
|
3133
|
-
params: ConversationMessagePayload;
|
|
3134
|
-
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
3135
|
-
event_channel: string;
|
|
3136
|
-
timestamp: string;
|
|
3137
|
-
is_author: boolean;
|
|
3138
|
-
})>;
|
|
3139
|
-
private get vertoInvite$();
|
|
3140
|
-
private get vertoAttach$();
|
|
3141
|
-
private get contexts();
|
|
3142
|
-
private get eventing();
|
|
3143
|
-
private get topics();
|
|
3144
|
-
private get authentication();
|
|
3145
|
-
connect(): Promise<void>;
|
|
3146
|
-
private handleAuthenticationError;
|
|
3147
3280
|
/**
|
|
3148
|
-
*
|
|
3281
|
+
* Internal initialization implementation.
|
|
3282
|
+
* Should only be called via init() to ensure single execution.
|
|
3283
|
+
*/
|
|
3284
|
+
private doInit;
|
|
3285
|
+
private setupPeerConnection;
|
|
3286
|
+
private startNegotiation;
|
|
3287
|
+
/**
|
|
3288
|
+
* Create an SDP offer and set it as local description.
|
|
3289
|
+
*/
|
|
3290
|
+
private createOffer;
|
|
3291
|
+
updateAnswerStatus({
|
|
3292
|
+
status,
|
|
3293
|
+
sdp
|
|
3294
|
+
}: UpdateSDPStatusParams): Promise<void>;
|
|
3295
|
+
updateOfferStatus({
|
|
3296
|
+
status,
|
|
3297
|
+
sdp
|
|
3298
|
+
}: UpdateSDPStatusParams): Promise<void>;
|
|
3299
|
+
/**
|
|
3300
|
+
* Accept an inbound call by creating the SDP answer.
|
|
3301
|
+
* Optionally override media options before the answer is generated.
|
|
3302
|
+
* Must be called after initialization for inbound (answer-type) connections.
|
|
3303
|
+
*/
|
|
3304
|
+
acceptInbound(mediaOverrides?: MediaOptions): Promise<void>;
|
|
3305
|
+
private handleOfferReceived;
|
|
3306
|
+
private readyToConnect;
|
|
3307
|
+
private setRemoteDescriptionBefore;
|
|
3308
|
+
protected setLocalDescription(params: RTCSessionDescriptionInit): Promise<void>;
|
|
3309
|
+
setLocalDescriptionBefore(sdp?: string): Promise<string>;
|
|
3310
|
+
/**
|
|
3311
|
+
* Create an SDP answer and set it as local description.
|
|
3312
|
+
*/
|
|
3313
|
+
private createAnswer;
|
|
3314
|
+
/**
|
|
3315
|
+
* Setup event listeners on RTCPeerConnection for state changes.
|
|
3316
|
+
*/
|
|
3317
|
+
private setupEventListeners;
|
|
3318
|
+
private negotiationEnded;
|
|
3319
|
+
/**
|
|
3320
|
+
* Trigger an ICE restart through the existing negotiation pipeline.
|
|
3149
3321
|
*
|
|
3150
|
-
* This
|
|
3151
|
-
*
|
|
3152
|
-
*
|
|
3153
|
-
*
|
|
3154
|
-
*
|
|
3322
|
+
* This creates an offer with iceRestart: true and goes through the full
|
|
3323
|
+
* SDP pipeline (setLocalDescription → ICE gathering → localDescription$ emission).
|
|
3324
|
+
* The caller should NOT send the SDP manually — the existing
|
|
3325
|
+
* setupLocalDescriptionHandler in VertoManager will pick up the emission
|
|
3326
|
+
* from localDescription$ and send it as a verto.modify.
|
|
3155
3327
|
*
|
|
3156
|
-
*
|
|
3157
|
-
*
|
|
3328
|
+
* Unlike calling pc.createOffer/setLocalDescription directly, this method:
|
|
3329
|
+
* - Sets _isNegotiating$ so ICEGatheringController arms its timers
|
|
3330
|
+
* - Waits for ICE gathering to complete before localDescription$ emits
|
|
3331
|
+
* - Goes through setLocalDescriptionBefore() for any SDP munging
|
|
3158
3332
|
*/
|
|
3159
|
-
|
|
3333
|
+
triggerIceRestart(relayOnly?: boolean): Promise<void>;
|
|
3334
|
+
private restoreIceTransportPolicy;
|
|
3160
3335
|
/**
|
|
3161
|
-
*
|
|
3162
|
-
* state (authorization_state + protocol) AND the attach records as one
|
|
3163
|
-
* atomic unit.
|
|
3336
|
+
* Setup track handling for remote tracks.
|
|
3164
3337
|
*
|
|
3165
|
-
*
|
|
3166
|
-
*
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3338
|
+
* @returns `false` when the connection went away while local media was being
|
|
3339
|
+
* acquired — see {@link setupLocalTracks}.
|
|
3340
|
+
*/
|
|
3341
|
+
private setupTrackHandling;
|
|
3342
|
+
/**
|
|
3343
|
+
* @returns `false` when the connection was torn down while getUserMedia was
|
|
3344
|
+
* in flight. The acquisition is not cancellable, so the caller must stop
|
|
3345
|
+
* rather than go on to touch a peer connection that is closed or gone.
|
|
3346
|
+
*/
|
|
3347
|
+
private setupLocalTracks;
|
|
3348
|
+
/** True for a main connection with no local media to send. */
|
|
3349
|
+
private hasNoLocalMediaToSend;
|
|
3350
|
+
/** The media kinds this connection wants to send: 'audiovideo' | 'video' | 'audio'. */
|
|
3351
|
+
private get requestedMediaKinds();
|
|
3352
|
+
/**
|
|
3353
|
+
* Handle a local media acquisition failure with a typed, semantically
|
|
3354
|
+
* accurate MediaAccessError created at the acquisition site:
|
|
3355
|
+
* - Auxiliary connections (screenshare / additional-device) throw a
|
|
3356
|
+
* non-fatal error — VertoManager surfaces it and the call is unaffected.
|
|
3357
|
+
* - The main connection degrades to receive-only when allowed (default),
|
|
3358
|
+
* otherwise fails with a fatal error.
|
|
3359
|
+
*/
|
|
3360
|
+
private handleLocalMediaFailure;
|
|
3361
|
+
/**
|
|
3362
|
+
* Negotiate receive-only m-lines when there are no local tracks to send.
|
|
3363
|
+
* Only offer-type connections add transceivers — answer-type connections
|
|
3364
|
+
* reuse the transceivers created from the remote offer.
|
|
3365
|
+
*/
|
|
3366
|
+
private setupReceiveOnlyTransceivers;
|
|
3367
|
+
private getUserMedia;
|
|
3368
|
+
private getDisplayMedia;
|
|
3369
|
+
private setupRemoteTracks;
|
|
3370
|
+
restoreTrackSender(kind: 'audio' | 'video' | 'both'): Promise<void>;
|
|
3371
|
+
private restoreRawAudioInputForPipeline;
|
|
3372
|
+
/**
|
|
3373
|
+
* Capture the newly selected device, leaving the current capture running.
|
|
3170
3374
|
*
|
|
3171
|
-
*
|
|
3172
|
-
*
|
|
3375
|
+
* A rejection must leave the current track sending, so nothing is released
|
|
3376
|
+
* until the replacement is in hand. The one exception is hardware that admits
|
|
3377
|
+
* a single opener — a phone's front and back cameras, typically — which
|
|
3378
|
+
* rejects the second capture until the first is closed.
|
|
3173
3379
|
*/
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
private authenticate;
|
|
3180
|
-
disconnect(): Promise<void>;
|
|
3181
|
-
private createInboundCall;
|
|
3380
|
+
private acquireInputTrack;
|
|
3381
|
+
private captureTrack;
|
|
3382
|
+
/** Best-effort return to the device that was released for an exclusive retry. */
|
|
3383
|
+
private restorePreviousInputTrack;
|
|
3384
|
+
private attachInputTrack;
|
|
3182
3385
|
/**
|
|
3183
|
-
*
|
|
3386
|
+
* Return the lazily-created {@link LocalAudioPipeline}, constructing it on
|
|
3387
|
+
* first access. On creation the current audio sender's track is routed
|
|
3388
|
+
* through the pipeline (input → gain → analyser → destination) and the
|
|
3389
|
+
* sender is switched to emit the processed track. Returns `null` when no
|
|
3390
|
+
* audio sender exists yet (pre-negotiation).
|
|
3391
|
+
*/
|
|
3392
|
+
ensureLocalAudioPipeline(): LocalAudioPipeline | null;
|
|
3393
|
+
/** The active LocalAudioPipeline, or null if it hasn't been created yet. */
|
|
3394
|
+
get localAudioPipeline(): LocalAudioPipeline | null;
|
|
3395
|
+
private applyLocalAudioPipelineToSender;
|
|
3396
|
+
/**
|
|
3397
|
+
* Add a local media track to the peer connection.
|
|
3398
|
+
* @param track - The MediaStreamTrack to add
|
|
3399
|
+
*/
|
|
3400
|
+
addLocalTrack(track: MediaStreamTrack): void;
|
|
3401
|
+
/**
|
|
3402
|
+
* Remove a local media track from the peer connection.
|
|
3403
|
+
* @param trackId - The ID of the track to remove
|
|
3404
|
+
*/
|
|
3405
|
+
removeLocalTrack(trackId: string): void;
|
|
3406
|
+
/**
|
|
3407
|
+
* Replace all existing media tracks with a new media track.
|
|
3408
|
+
* Convenience method for single-track scenarios.
|
|
3409
|
+
* @param track - The MediaStreamTrack to set
|
|
3410
|
+
*/
|
|
3411
|
+
setLocalTrack(track: MediaStreamTrack): void;
|
|
3412
|
+
/**
|
|
3413
|
+
* @returns whether the constraints reached the media the leg is sending.
|
|
3184
3414
|
*
|
|
3185
|
-
*
|
|
3186
|
-
*
|
|
3187
|
-
*
|
|
3188
|
-
*
|
|
3189
|
-
*
|
|
3415
|
+
* With the pipeline engaged the audio sender carries the processed
|
|
3416
|
+
* destination track, so the sender scan would find nothing it may touch and
|
|
3417
|
+
* every audio constraint API would silently no-op. The constraints belong to
|
|
3418
|
+
* the pipeline's device source, which is the capture that sender ultimately
|
|
3419
|
+
* carries.
|
|
3420
|
+
*/
|
|
3421
|
+
updateSendersConstraints(kind: 'audio' | 'video', constraints?: MediaTrackConstraints): Promise<boolean>;
|
|
3422
|
+
/**
|
|
3423
|
+
* Mirror of the sender path for a piped audio leg: same merge, same fallback
|
|
3424
|
+
* ladder, same device-capture invariant — but the swap target is the pipeline
|
|
3425
|
+
* input, so the sender keeps emitting the pipeline's output track and its
|
|
3426
|
+
* identity survives the change.
|
|
3427
|
+
*/
|
|
3428
|
+
private applyPipelineSourceConstraints;
|
|
3429
|
+
/**
|
|
3430
|
+
* Clean up resources and close the peer connection.
|
|
3431
|
+
* Completes all observables to prevent memory leaks.
|
|
3190
3432
|
*/
|
|
3191
|
-
private handleVertoAttach;
|
|
3192
|
-
createOutboundCall(destination: string | Address, options?: CallOptions): Promise<Call>;
|
|
3193
|
-
private createCall;
|
|
3194
3433
|
destroy(): void;
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
event_type: "webrtc.message";
|
|
3203
|
-
event_channel: EventChannel;
|
|
3204
|
-
timestamp: number;
|
|
3205
|
-
project_id?: string;
|
|
3206
|
-
node_id?: string;
|
|
3207
|
-
is_author?: boolean;
|
|
3208
|
-
params: WebrtcMessagePayload;
|
|
3209
|
-
}, "event_channel" | "project_id" | "node_id"> & {
|
|
3210
|
-
event_channel: string;
|
|
3211
|
-
project_id: string;
|
|
3212
|
-
node_id: string;
|
|
3213
|
-
}) | {
|
|
3214
|
-
event_type: "signalwire.authorization.state";
|
|
3215
|
-
params: SignalwireAuthorizationStatePayload;
|
|
3216
|
-
} | (Omit<{
|
|
3217
|
-
event_type: "call.joined";
|
|
3218
|
-
event_channel: EventChannel;
|
|
3219
|
-
timestamp: number;
|
|
3220
|
-
project_id?: string;
|
|
3221
|
-
node_id?: string;
|
|
3222
|
-
is_author?: boolean;
|
|
3223
|
-
params: CallJoinedPayload;
|
|
3224
|
-
}, "event_channel"> & {
|
|
3225
|
-
event_channel: string;
|
|
3226
|
-
}) | (Omit<{
|
|
3227
|
-
event_type: "call.left";
|
|
3228
|
-
event_channel: EventChannel;
|
|
3229
|
-
timestamp: number;
|
|
3230
|
-
project_id?: string;
|
|
3231
|
-
node_id?: string;
|
|
3232
|
-
is_author?: boolean;
|
|
3233
|
-
params: CallLeftPayload;
|
|
3234
|
-
}, "event_channel"> & {
|
|
3235
|
-
event_channel: string;
|
|
3236
|
-
}) | (Omit<{
|
|
3237
|
-
event_type: "call.updated";
|
|
3238
|
-
event_channel: EventChannel;
|
|
3239
|
-
timestamp: number;
|
|
3240
|
-
project_id?: string;
|
|
3241
|
-
node_id?: string;
|
|
3242
|
-
is_author?: boolean;
|
|
3243
|
-
params: CallUpdatedPayload;
|
|
3244
|
-
}, "event_channel"> & {
|
|
3245
|
-
event_channel: string;
|
|
3246
|
-
}) | (Omit<{
|
|
3247
|
-
event_type: "call.state";
|
|
3248
|
-
event_channel: EventChannel;
|
|
3249
|
-
timestamp: number;
|
|
3250
|
-
project_id?: string;
|
|
3251
|
-
node_id?: string;
|
|
3252
|
-
is_author?: boolean;
|
|
3253
|
-
params: CallStatePayload;
|
|
3254
|
-
}, "event_channel"> & {
|
|
3255
|
-
event_channel: string;
|
|
3256
|
-
}) | (Omit<{
|
|
3257
|
-
event_type: "call.play";
|
|
3258
|
-
event_channel: EventChannel;
|
|
3259
|
-
timestamp: number;
|
|
3260
|
-
project_id?: string;
|
|
3261
|
-
node_id?: string;
|
|
3262
|
-
is_author?: boolean;
|
|
3263
|
-
params: CallPlayPayload;
|
|
3264
|
-
}, "event_channel"> & {
|
|
3265
|
-
event_channel: string;
|
|
3266
|
-
}) | (Omit<{
|
|
3267
|
-
event_type: "call.connect";
|
|
3268
|
-
event_channel: EventChannel;
|
|
3269
|
-
timestamp: number;
|
|
3270
|
-
project_id?: string;
|
|
3271
|
-
node_id?: string;
|
|
3272
|
-
is_author?: boolean;
|
|
3273
|
-
params: CallConnectPayload;
|
|
3274
|
-
}, "event_channel"> & {
|
|
3275
|
-
event_channel: string;
|
|
3276
|
-
}) | (Omit<{
|
|
3277
|
-
event_type: "room.updated";
|
|
3278
|
-
event_channel: EventChannel;
|
|
3279
|
-
timestamp: number;
|
|
3280
|
-
project_id?: string;
|
|
3281
|
-
node_id?: string;
|
|
3282
|
-
is_author?: boolean;
|
|
3283
|
-
params: RoomUpdatedPayload;
|
|
3284
|
-
}, "event_channel"> & {
|
|
3285
|
-
event_channel: string;
|
|
3286
|
-
}) | Omit<{
|
|
3287
|
-
event_type: "member.updated";
|
|
3288
|
-
event_channel: EventChannel;
|
|
3289
|
-
timestamp: number;
|
|
3290
|
-
project_id?: string;
|
|
3291
|
-
node_id?: string;
|
|
3292
|
-
is_author?: boolean;
|
|
3293
|
-
params: MemberUpdatedPayload;
|
|
3294
|
-
}, never> | Omit<{
|
|
3295
|
-
event_type: "member.joined";
|
|
3296
|
-
event_channel: EventChannel;
|
|
3297
|
-
timestamp: number;
|
|
3298
|
-
project_id?: string;
|
|
3299
|
-
node_id?: string;
|
|
3300
|
-
is_author?: boolean;
|
|
3301
|
-
params: MemberJoinedPayload;
|
|
3302
|
-
}, never> | Omit<{
|
|
3303
|
-
event_type: "member.left";
|
|
3304
|
-
event_channel: EventChannel;
|
|
3305
|
-
timestamp: number;
|
|
3306
|
-
project_id?: string;
|
|
3307
|
-
node_id?: string;
|
|
3308
|
-
is_author?: boolean;
|
|
3309
|
-
params: MemberLeftPayload;
|
|
3310
|
-
}, never> | Omit<{
|
|
3311
|
-
event_type: "member.talking";
|
|
3312
|
-
event_channel: EventChannel;
|
|
3313
|
-
timestamp: number;
|
|
3314
|
-
project_id?: string;
|
|
3315
|
-
node_id?: string;
|
|
3316
|
-
is_author?: boolean;
|
|
3317
|
-
params: MemberTalkingPayload;
|
|
3318
|
-
}, never> | Omit<{
|
|
3319
|
-
event_type: "layout.changed";
|
|
3320
|
-
event_channel: EventChannel;
|
|
3321
|
-
timestamp: number;
|
|
3322
|
-
project_id?: string;
|
|
3323
|
-
node_id?: string;
|
|
3324
|
-
is_author?: boolean;
|
|
3325
|
-
params: LayoutChangedPayload;
|
|
3326
|
-
}, never> | (Omit<{
|
|
3327
|
-
event_type: "conversation.message";
|
|
3328
|
-
event_channel: EventChannel;
|
|
3329
|
-
timestamp: number;
|
|
3330
|
-
project_id?: string;
|
|
3331
|
-
node_id?: string;
|
|
3332
|
-
is_author?: boolean;
|
|
3333
|
-
params: ConversationMessagePayload;
|
|
3334
|
-
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
3335
|
-
event_channel: string;
|
|
3336
|
-
timestamp: string;
|
|
3337
|
-
is_author: boolean;
|
|
3338
|
-
}) | (Omit<{
|
|
3339
|
-
event_type: "conversation.message.updated";
|
|
3340
|
-
event_channel: EventChannel;
|
|
3341
|
-
timestamp: number;
|
|
3342
|
-
project_id?: string;
|
|
3343
|
-
node_id?: string;
|
|
3344
|
-
is_author?: boolean;
|
|
3345
|
-
params: ConversationMessagePayload;
|
|
3346
|
-
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
3347
|
-
event_channel: string;
|
|
3348
|
-
timestamp: string;
|
|
3349
|
-
is_author: boolean;
|
|
3350
|
-
})>;
|
|
3351
|
-
get iceServers(): RTCIceServer[] | undefined;
|
|
3352
|
-
execute<T extends JSONRPCResponse = JSONRPCResponse>(request: JSONRPCRequest, options?: PendingRPCOptions): Promise<T>;
|
|
3353
|
-
get incomingCalls$(): Observable<Call[]>;
|
|
3354
|
-
get incomingCalls(): Call[];
|
|
3355
|
-
get calls$(): Observable<Call[]>;
|
|
3356
|
-
get calls(): Call[];
|
|
3434
|
+
private removeAllListeners;
|
|
3435
|
+
private stopRemoteTracks;
|
|
3436
|
+
get mediaDirections(): {
|
|
3437
|
+
audio: RTCRtpTransceiverDirection;
|
|
3438
|
+
video: RTCRtpTransceiverDirection;
|
|
3439
|
+
};
|
|
3440
|
+
protected _setRemoteDescription(params: RTCSessionDescriptionInit): Promise<void>;
|
|
3357
3441
|
}
|
|
3358
3442
|
//#endregion
|
|
3359
|
-
//#region src/
|
|
3360
|
-
/**
|
|
3361
|
-
* Non-fatal warning emitted via {@link SignalWire.warnings$ | client.warnings$}.
|
|
3362
|
-
*
|
|
3363
|
-
* Use to detect SDK behaviors that affect session liveness or developer-facing
|
|
3364
|
-
* contracts but do not warrant disconnection. Discriminated by `code`.
|
|
3365
|
-
*
|
|
3366
|
-
* Existing consumers of `errors$` are NOT notified — `warnings$` is a separate
|
|
3367
|
-
* channel so application code can react to warnings without triggering
|
|
3368
|
-
* error-handling code paths (e.g., disconnect cascades, user-facing toasts).
|
|
3369
|
-
*/
|
|
3370
|
-
type SDKWarning = CredentialRefreshFallbackWarning | CredentialNoRefreshHandlerWarning;
|
|
3371
|
-
/**
|
|
3372
|
-
* Diagnostic detail for {@link CredentialRefreshFallbackWarning}. Stable
|
|
3373
|
-
* values, but treat unknown strings as "fell back for an unspecified cause" —
|
|
3374
|
-
* do not branch on this value for control flow. New values may be added in
|
|
3375
|
-
* future releases.
|
|
3376
|
-
*/
|
|
3377
|
-
type CredentialRefreshFallbackReason = 'no-scope' | 'no-dpop-support' | 'endpoint-failed' | 'activation-timeout' | (string & {});
|
|
3443
|
+
//#region src/interfaces/WebRTCVerto.d.ts
|
|
3378
3444
|
/**
|
|
3379
|
-
*
|
|
3380
|
-
*
|
|
3381
|
-
* could not take over.
|
|
3382
|
-
*
|
|
3383
|
-
* Common causes:
|
|
3384
|
-
* - The minted SAT lacks `sat:refresh` scope (`reason: 'no-scope'`).
|
|
3385
|
-
* - The `/devices/token` exchange failed transiently (`reason: 'endpoint-failed'`).
|
|
3386
|
-
*
|
|
3387
|
-
* Subscribe to this warning to detect:
|
|
3388
|
-
* - SDKs running with plain SATs that rely on developer-managed refresh
|
|
3389
|
-
* - Deployments expected to use bound tokens that silently downgraded to bearer
|
|
3390
|
-
* (a security-relevant signal for fleet observability)
|
|
3445
|
+
* Extended interface for WebRTC Verto Manager
|
|
3446
|
+
* Includes WebRTC-specific state and peer connection management
|
|
3391
3447
|
*/
|
|
3392
|
-
interface
|
|
3393
|
-
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3448
|
+
interface WebRTCVerto extends VertoManager {
|
|
3449
|
+
readonly selfId$: Observable<string | null>;
|
|
3450
|
+
/** Separates the media phase of call creation from the signalling phase. */
|
|
3451
|
+
readonly localMediaSettled$: Observable<void>;
|
|
3452
|
+
readonly selfId: string | null;
|
|
3453
|
+
readonly nodeId$: Observable<string | null>;
|
|
3454
|
+
readonly nodeId: string | null;
|
|
3455
|
+
readonly localStream$: Observable<MediaStream>;
|
|
3456
|
+
readonly localStream: MediaStream | null;
|
|
3457
|
+
readonly remoteStream$: Observable<MediaStream>;
|
|
3458
|
+
readonly remoteStream: MediaStream | null;
|
|
3459
|
+
readonly mediaDirections$: Observable<MediaDirections>;
|
|
3460
|
+
readonly mediaDirections: MediaDirections;
|
|
3461
|
+
readonly signalingStatus$: Observable<SignalingStatus>;
|
|
3462
|
+
readonly mainPeerConnection: RTCPeerConnectionController;
|
|
3463
|
+
bye(cause?: string): Promise<void>;
|
|
3464
|
+
sendDigits(dtmf: string): Promise<void>;
|
|
3465
|
+
/**
|
|
3466
|
+
* Send a member-control op in-dialog via verto.info (no self/target member
|
|
3467
|
+
* tuple). The payload rides in the verto.info `params.command` body — a
|
|
3468
|
+
* sibling of `dialogParams`, same level as `dtmf` — matched to this call's
|
|
3469
|
+
* channel by `dialogParams.callID`, so control lands on the call's own channel
|
|
3470
|
+
* without relying on the {node_id,call_id,member_id} addressing the routed
|
|
3471
|
+
* transport uses.
|
|
3472
|
+
*/
|
|
3473
|
+
sendCallControl(method: string, params: Record<string, unknown>): Promise<unknown>;
|
|
3474
|
+
hold(): Promise<void>;
|
|
3475
|
+
unhold(): Promise<void>;
|
|
3476
|
+
destroy(): void;
|
|
3477
|
+
transfer(options: TransferOptions): Promise<void>;
|
|
3478
|
+
/** Request a video keyframe via verto.modify. */
|
|
3479
|
+
requestKeyframe?: () => void;
|
|
3480
|
+
/** Request an ICE restart via verto.modify with iceRestart offer. */
|
|
3481
|
+
requestIceRestart?: (relayOnly?: boolean) => Promise<void>;
|
|
3482
|
+
/** Request an ICE restart on all active peer connections (multi-leg). */
|
|
3483
|
+
requestIceRestartAll?: (relayOnly?: boolean) => Promise<void>;
|
|
3484
|
+
/** Request keyframes on all video-receiving legs (skips send-only screen share). */
|
|
3485
|
+
requestKeyframeAll?: () => void;
|
|
3486
|
+
/** Lazily create (or return) the local audio pipeline for the main peer connection. */
|
|
3487
|
+
ensureLocalAudioPipeline(): LocalAudioPipeline | null;
|
|
3488
|
+
/** Current local audio pipeline, or null if it has not been created yet. */
|
|
3489
|
+
readonly localAudioPipeline: LocalAudioPipeline | null;
|
|
3490
|
+
}
|
|
3491
|
+
//#endregion
|
|
3492
|
+
//#region src/managers/CallEventsManager.d.ts
|
|
3493
|
+
interface WebRTCCallEventManagerOptions {}
|
|
3494
|
+
/** @internal */
|
|
3495
|
+
declare class CallEventsManager extends Destroyable {
|
|
3496
|
+
protected webRtcCallSession: CallManager;
|
|
3497
|
+
protected options: WebRTCCallEventManagerOptions;
|
|
3498
|
+
private selfId?;
|
|
3499
|
+
private originCallId?;
|
|
3500
|
+
private callIds;
|
|
3501
|
+
private roomSessionIds;
|
|
3502
|
+
private _participants$;
|
|
3503
|
+
private _self$;
|
|
3504
|
+
private _sessionState$;
|
|
3505
|
+
constructor(webRtcCallSession: CallManager, options?: WebRTCCallEventManagerOptions);
|
|
3506
|
+
get participants$(): Observable<CallParticipant[]>;
|
|
3507
|
+
get participants(): CallParticipant[];
|
|
3508
|
+
get self$(): Observable<CallSelfParticipant>;
|
|
3509
|
+
isRoomSessionIdValid(roomSessionId: string): boolean;
|
|
3510
|
+
addCallId(callId: string): void;
|
|
3511
|
+
isCallIdValid(callId: string): boolean;
|
|
3512
|
+
get recording$(): Observable<boolean>;
|
|
3513
|
+
get recordings$(): Observable<Record<string, unknown>[]>;
|
|
3514
|
+
get streaming$(): Observable<boolean>;
|
|
3515
|
+
get streams$(): Observable<Record<string, unknown>[]>;
|
|
3516
|
+
get playbacks$(): Observable<Record<string, unknown>[]>;
|
|
3517
|
+
get raiseHandPriority$(): Observable<boolean>;
|
|
3518
|
+
get locked$(): Observable<boolean>;
|
|
3519
|
+
get meta$(): Observable<Record<string, unknown>>;
|
|
3520
|
+
get capabilities$(): Observable<Capability[]>;
|
|
3521
|
+
get layout$(): Observable<string>;
|
|
3522
|
+
get layouts$(): Observable<string[]>;
|
|
3523
|
+
get layoutLayers$(): Observable<LayoutLayer[]>;
|
|
3524
|
+
get self(): CallSelfParticipant | null;
|
|
3525
|
+
get layoutLayers(): LayoutLayer[];
|
|
3526
|
+
get recording(): boolean;
|
|
3527
|
+
get streaming(): boolean;
|
|
3528
|
+
get raiseHandPriority(): boolean;
|
|
3529
|
+
get locked(): boolean;
|
|
3530
|
+
get meta(): Record<string, unknown>;
|
|
3531
|
+
get layout(): string | undefined;
|
|
3532
|
+
get layouts(): string[];
|
|
3533
|
+
get capabilities(): Capability[];
|
|
3534
|
+
isSessionEvent(id: string): boolean;
|
|
3535
|
+
protected initSubscriptions(): void;
|
|
3536
|
+
private updateParticipantPositions;
|
|
3537
|
+
updateLayouts(): void;
|
|
3538
|
+
private updateParticipants;
|
|
3539
|
+
private upsertParticipant;
|
|
3540
|
+
private get callJoinedEvent$();
|
|
3541
|
+
private get layoutChangedEvent$();
|
|
3542
|
+
private get memberUpdates$();
|
|
3543
|
+
destroy(): void;
|
|
3544
|
+
}
|
|
3545
|
+
//#endregion
|
|
3546
|
+
//#region src/managers/CallRecoveryManager.d.ts
|
|
3547
|
+
type RecoveryState$1 = 'idle' | 'debouncing' | 'recovering' | 'cooldown';
|
|
3548
|
+
interface RecoveryEvent$1 {
|
|
3549
|
+
action: 'keyframe_requested' | 'reinvite_started' | 'reinvite_succeeded' | 'reinvite_failed' | 'reinvite_timeout' | 'max_attempts_reached' | 'signal_reconnect' | 'full_reconnect' | 'video_disabled' | 'video_restored';
|
|
3550
|
+
reason: string;
|
|
3551
|
+
attempt?: number;
|
|
3552
|
+
maxAttempts?: number;
|
|
3553
|
+
timestamp: number;
|
|
3397
3554
|
}
|
|
3555
|
+
//#endregion
|
|
3556
|
+
//#region src/utils/qualityScore.d.ts
|
|
3398
3557
|
/**
|
|
3399
|
-
*
|
|
3400
|
-
*
|
|
3558
|
+
* MOS (Mean Opinion Score) quality computation based on the simplified
|
|
3559
|
+
* ITU-T G.107 E-model.
|
|
3401
3560
|
*
|
|
3402
|
-
*
|
|
3403
|
-
*
|
|
3561
|
+
* Provides a single 1-5 number that applications can use for a
|
|
3562
|
+
* green / yellow / red quality indicator without understanding raw
|
|
3563
|
+
* jitter and packet-loss values.
|
|
3404
3564
|
*/
|
|
3405
|
-
|
|
3406
|
-
code: 'credential_no_refresh_handler';
|
|
3407
|
-
source: 'CredentialProvider';
|
|
3408
|
-
message: string;
|
|
3409
|
-
/** Token expiry timestamp (epoch milliseconds). */
|
|
3410
|
-
expiresAt: number;
|
|
3411
|
-
}
|
|
3565
|
+
type QualityLevel$1 = 'excellent' | 'good' | 'fair' | 'poor' | 'critical';
|
|
3412
3566
|
//#endregion
|
|
3413
|
-
//#region src/
|
|
3414
|
-
/** Log level names supported by the SDK. */
|
|
3415
|
-
type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
3567
|
+
//#region src/core/entities/Call.d.ts
|
|
3416
3568
|
/**
|
|
3417
|
-
*
|
|
3418
|
-
* All methods accept variadic arguments matching the browser console API.
|
|
3569
|
+
* Manager instances returned by initialization callback
|
|
3419
3570
|
*/
|
|
3420
|
-
interface
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
info(...args: unknown[]): void;
|
|
3424
|
-
debug(...args: unknown[]): void;
|
|
3425
|
-
trace(...args: unknown[]): void;
|
|
3426
|
-
}
|
|
3427
|
-
/** Options for WebSocket traffic logging. */
|
|
3428
|
-
interface WsTrafficOptions {
|
|
3429
|
-
type: 'send' | 'recv' | 'http';
|
|
3430
|
-
/** Parsed object or raw string — will be JSON.stringify'd for display if an object. */
|
|
3431
|
-
payload: unknown;
|
|
3571
|
+
interface CallManagers {
|
|
3572
|
+
vertoManager: WebRTCVerto;
|
|
3573
|
+
callEventsManager: CallEventsManager;
|
|
3432
3574
|
}
|
|
3433
3575
|
/**
|
|
3434
|
-
*
|
|
3435
|
-
*
|
|
3436
|
-
*
|
|
3576
|
+
* Initialization callback that creates managers for a Call instance
|
|
3577
|
+
* @param call - The WebRTCCall instance being initialized
|
|
3578
|
+
* @returns Manager instances for the call
|
|
3437
3579
|
*/
|
|
3438
|
-
|
|
3439
|
-
|
|
3440
|
-
|
|
3441
|
-
}
|
|
3442
|
-
|
|
3443
|
-
interface
|
|
3444
|
-
/**
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3580
|
+
type ManagerInitializer = (call: WebRTCCall) => CallManagers;
|
|
3581
|
+
/**
|
|
3582
|
+
* Required initialization configuration for Call constructor.
|
|
3583
|
+
* Calls must be created via {@link CallFactory} which provides these dependencies.
|
|
3584
|
+
*/
|
|
3585
|
+
interface CallInitialization {
|
|
3586
|
+
/**
|
|
3587
|
+
* Callback function that creates and wires manager instances
|
|
3588
|
+
*/
|
|
3589
|
+
initializeManagers: ManagerInitializer;
|
|
3590
|
+
/**
|
|
3591
|
+
* Device controller for media device access
|
|
3592
|
+
*/
|
|
3593
|
+
deviceController: DeviceController;
|
|
3594
|
+
/**
|
|
3595
|
+
* Network change events for feeding recovery pipeline
|
|
3596
|
+
*/
|
|
3597
|
+
networkChange$?: Observable<NetworkChangeEvent>;
|
|
3450
3598
|
}
|
|
3451
|
-
/** Replace the built-in logger with a custom implementation. Pass `null` to restore defaults. */
|
|
3452
|
-
declare const setLogger: (logger: SDKLogger | null) => void;
|
|
3453
|
-
/** Configure debug options (e.g., `{ logWsTraffic: true }`). */
|
|
3454
|
-
declare const setDebugOptions: (options: DebugOptions | null) => void;
|
|
3455
3599
|
/**
|
|
3456
|
-
*
|
|
3457
|
-
*
|
|
3600
|
+
* Concrete WebRTC call implementation.
|
|
3601
|
+
*
|
|
3602
|
+
* Manages the full lifecycle of a call including signaling, media streams,
|
|
3603
|
+
* participants, layout, and event routing. Created via {@link SignalWire.dial}
|
|
3604
|
+
* or received as an inbound call.
|
|
3458
3605
|
*/
|
|
3459
|
-
declare
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
/**
|
|
3464
|
-
|
|
3465
|
-
/**
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
3606
|
+
declare class WebRTCCall extends Destroyable implements CallManager, Call {
|
|
3607
|
+
clientSession: ClientSession;
|
|
3608
|
+
options: CallOptions;
|
|
3609
|
+
address?: Address | undefined;
|
|
3610
|
+
/** Unique identifier for this call. */
|
|
3611
|
+
readonly id: string;
|
|
3612
|
+
/** Destination URI this call was placed to. */
|
|
3613
|
+
to?: string;
|
|
3614
|
+
private vertoManager;
|
|
3615
|
+
private callEventsManager;
|
|
3616
|
+
private participantFactory;
|
|
3617
|
+
private _errors$;
|
|
3618
|
+
private _status$;
|
|
3619
|
+
private _lastMergedStatus;
|
|
3620
|
+
private _answered$;
|
|
3621
|
+
private _answerMediaOptions?;
|
|
3622
|
+
private _holdState;
|
|
3623
|
+
private _userVariables$;
|
|
3624
|
+
private _statsMonitor?;
|
|
3625
|
+
private _recoveryManager?;
|
|
3626
|
+
private _networkChange$?;
|
|
3627
|
+
private _networkIssues$;
|
|
3628
|
+
private _networkMetrics$;
|
|
3629
|
+
private _isNetworkHealthy$;
|
|
3630
|
+
private _qualityScore$;
|
|
3631
|
+
private _qualityLevel$;
|
|
3632
|
+
private _recoveryState$;
|
|
3633
|
+
private _recoveryEvent$;
|
|
3634
|
+
private _bandwidthConstrained$;
|
|
3635
|
+
private _mediaParamsUpdated$;
|
|
3636
|
+
private _customSubscriptions;
|
|
3637
|
+
private _pushToTalkEnabled;
|
|
3638
|
+
private _remoteAudioMeter;
|
|
3639
|
+
constructor(clientSession: ClientSession, options: CallOptions, initialization: CallInitialization, address?: Address | undefined);
|
|
3640
|
+
/** Observable stream of errors from media, signaling, and peer connection layers. */
|
|
3641
|
+
get errors$(): Observable<CallError>;
|
|
3475
3642
|
/**
|
|
3476
|
-
*
|
|
3643
|
+
* @internal Push an error to the call's error stream.
|
|
3644
|
+
* Fatal errors automatically transition the call to `'failed'` and destroy it.
|
|
3645
|
+
*/
|
|
3646
|
+
emitError(callError: CallError): void;
|
|
3647
|
+
/** Notify the recovery manager that a verto.modify signaling exchange failed. */
|
|
3648
|
+
notifyModifyFailed(): void;
|
|
3649
|
+
/** Whether this call is `'inbound'` or `'outbound'`. */
|
|
3650
|
+
get direction(): CallDirection;
|
|
3651
|
+
/** Observable of the address associated with this call. */
|
|
3652
|
+
get address$(): Observable<Address | undefined>;
|
|
3653
|
+
/** Display name of the caller. */
|
|
3654
|
+
get fromName(): string | undefined;
|
|
3655
|
+
/** Address URI of the caller. */
|
|
3656
|
+
get from(): string | undefined;
|
|
3657
|
+
/** Display name of the callee. */
|
|
3658
|
+
get toName(): string | undefined;
|
|
3659
|
+
/** Toggles whether incoming video is received. @throws {UnimplementedError} Not yet implemented. */
|
|
3660
|
+
toggleIncomingVideo(): Promise<void>;
|
|
3661
|
+
/** Toggles whether incoming audio is received. @throws {UnimplementedError} Not yet implemented. */
|
|
3662
|
+
toggleIncomingAudio(): Promise<void>;
|
|
3663
|
+
/** @internal Registers an additional call ID for event routing. */
|
|
3664
|
+
addCallId(callId: string): void;
|
|
3665
|
+
/** List of capabilities available in the current call. */
|
|
3666
|
+
get capabilities(): Capability[];
|
|
3667
|
+
/** Current snapshot of all participants in the call. */
|
|
3668
|
+
get participants(): CallParticipant[];
|
|
3669
|
+
/** The local participant, or `null` if not yet joined. */
|
|
3670
|
+
get self(): CallSelfParticipant | null;
|
|
3671
|
+
/** Toggles the call lock state, preventing or allowing new participants from joining. */
|
|
3672
|
+
toggleLock(): Promise<void>;
|
|
3673
|
+
/**
|
|
3674
|
+
* Toggles the hold state of the call (pauses/resumes local media transmission).
|
|
3477
3675
|
*
|
|
3478
|
-
*
|
|
3479
|
-
|
|
3480
|
-
|
|
3481
|
-
|
|
3676
|
+
* Distinct from {@link Participant.toggleMute} which mutes individual tracks.
|
|
3677
|
+
*/
|
|
3678
|
+
toggleHold(): Promise<void>;
|
|
3679
|
+
/** @throws {UnimplementedError} Not yet implemented. Status tracked via {@link recording$}. */
|
|
3680
|
+
startRecording(): Promise<void>;
|
|
3681
|
+
/** @throws {UnimplementedError} Not yet implemented. Status tracked via {@link streaming$}. */
|
|
3682
|
+
startStreaming(): Promise<void>;
|
|
3683
|
+
/**
|
|
3684
|
+
* Replaces the call's custom metadata.
|
|
3685
|
+
* @param _meta - Metadata object to set.
|
|
3686
|
+
* @throws {UnimplementedError} Not yet implemented.
|
|
3687
|
+
*/
|
|
3688
|
+
setMeta(_meta: Record<string, unknown>): Promise<void>;
|
|
3689
|
+
/**
|
|
3690
|
+
* Merges values into the call's custom metadata (unlike {@link setMeta} which replaces).
|
|
3691
|
+
* @param _meta - Metadata to merge.
|
|
3692
|
+
* @throws {UnimplementedError} Not yet implemented.
|
|
3693
|
+
*/
|
|
3694
|
+
updateMeta(_meta: Record<string, unknown>): Promise<void>;
|
|
3695
|
+
/** Observable of layout layer positions for all participants. */
|
|
3696
|
+
get layoutLayers$(): Observable<LayoutLayer[]>;
|
|
3697
|
+
/** Current snapshot of layout layers. */
|
|
3698
|
+
get layoutLayers(): LayoutLayer[];
|
|
3699
|
+
/**
|
|
3700
|
+
* Executes a Verto RPC method targeting a specific participant.
|
|
3482
3701
|
*
|
|
3483
|
-
*
|
|
3484
|
-
* lost on reload.
|
|
3702
|
+
* Constructs call context (node_id, call_id, member_id) and sends the RPC request.
|
|
3485
3703
|
*
|
|
3486
|
-
*
|
|
3487
|
-
*
|
|
3488
|
-
*
|
|
3489
|
-
*
|
|
3490
|
-
*
|
|
3491
|
-
*
|
|
3704
|
+
* @param target - Target {@link MemberTarget} triple, or the local member's
|
|
3705
|
+
* ID string for self-operations (any other string is rejected — a bare
|
|
3706
|
+
* member id cannot carry the remote member's own call context).
|
|
3707
|
+
* @param method - Verto method name (e.g. `'call.mute'`, `'call.member.remove'`).
|
|
3708
|
+
* @param args - Parameters for the RPC method.
|
|
3709
|
+
* @returns The RPC response.
|
|
3710
|
+
* @throws {CallNotReadyError} If the call has no self member context yet.
|
|
3711
|
+
* @throws {InvalidParams} If a string target is not the local member's ID.
|
|
3712
|
+
* @throws {JSONRPCError} If the RPC call returns an error.
|
|
3492
3713
|
*/
|
|
3493
|
-
|
|
3494
|
-
/** Custom storage implementation for persistence. */
|
|
3495
|
-
storageImplementation?: Storage;
|
|
3496
|
-
/** Custom WebSocket constructor */
|
|
3497
|
-
webSocketConstructor?: WebSocketAdapter | NodeSocketAdapter;
|
|
3498
|
-
/** Custom WebRTC API provider */
|
|
3499
|
-
webRTCApiProvider?: WebRTCApiProvider;
|
|
3714
|
+
executeMethod<T extends JSONRPCResponse = JSONRPCResponse>(target: string | MemberTarget, method: string, args: Record<string, unknown>): Promise<T>;
|
|
3500
3715
|
/**
|
|
3501
|
-
*
|
|
3502
|
-
* Pass `null` to restore the built-in logger.
|
|
3716
|
+
* `executeMethod` for a call opened with `callControl: 'in-dialog'`.
|
|
3503
3717
|
*
|
|
3504
|
-
*
|
|
3718
|
+
* Translates the routed transport's calling convention into the in-dialog one. No
|
|
3719
|
+
* `self` tuple is sent, but a `target` is — the same {call_id, member_id} the routed
|
|
3720
|
+
* transport puts in `target` (minus node_id), for self-ops and cross-member ops alike.
|
|
3721
|
+
*
|
|
3722
|
+
* Target shapes are per-verb and irregular, so they are centralised here rather
|
|
3723
|
+
* than left to callers: most verbs take a singular `target`, `call.member.remove`
|
|
3724
|
+
* takes a plural `targets` array, and `call.member.position.set` takes a flat
|
|
3725
|
+
* `targets` of `{call_id, position}` — the one verb keyed on call_id rather than
|
|
3726
|
+
* member_id, so the member triple `Participant.setPosition` built is unwrapped.
|
|
3505
3727
|
*/
|
|
3506
|
-
|
|
3728
|
+
private executeMethodInDialog;
|
|
3507
3729
|
/**
|
|
3508
|
-
*
|
|
3509
|
-
*
|
|
3510
|
-
* Has no effect when a custom `logger` is provided.
|
|
3730
|
+
* Sends a `call.*` control verb **in-dialog** via `verto.info`, as an alternative
|
|
3731
|
+
* to the routed {@link executeMethod} transport.
|
|
3511
3732
|
*
|
|
3512
|
-
*
|
|
3733
|
+
* Why both exist: `executeMethod` addresses the member with an explicit
|
|
3734
|
+
* `{node_id, call_id, member_id}` tuple, which does not resolve for every conference,
|
|
3735
|
+
* so the op can fail. An in-dialog frame carries the verb on the member's own
|
|
3736
|
+
* signaling channel instead, so control works without the client needing to know how
|
|
3737
|
+
* the conference is hosted.
|
|
3738
|
+
*
|
|
3739
|
+
* The trade-off is reach: the in-dialog transport is only accepted for calls that
|
|
3740
|
+
* join a conference over SWML (e.g. an SWML `join_conference`); use the routed
|
|
3741
|
+
* default otherwise.
|
|
3742
|
+
*
|
|
3743
|
+
* `params` are sent verbatim — nothing is built for you, which includes the target.
|
|
3744
|
+
* **A self-directed op still needs one**, or it is refused; name yourself explicitly:
|
|
3745
|
+
*
|
|
3746
|
+
* ```ts
|
|
3747
|
+
* const { call_id, member_id } = call.self.target;
|
|
3748
|
+
* await call.sendCommand('call.mute', { channels: ['audio'], target: { call_id, member_id } });
|
|
3749
|
+
* ```
|
|
3750
|
+
*
|
|
3751
|
+
* Never include `node_id` — only the two ids. The shapes are per-verb: most take a
|
|
3752
|
+
* singular `target`, `call.member.remove` takes a plural `targets` array, and
|
|
3753
|
+
* `call.member.position.set` takes a flat `targets: [{call_id, position}]` (the one
|
|
3754
|
+
* verb keyed on `call_id` rather than `member_id`). Verbs that act on the call as a
|
|
3755
|
+
* whole, or that the SDK does not wrap at all, take no target.
|
|
3756
|
+
*
|
|
3757
|
+
* For the typed alternative that handles all of this, create the client with
|
|
3758
|
+
* `callControl: 'in-dialog'` and use the ordinary `Call`/`Participant` methods.
|
|
3759
|
+
*
|
|
3760
|
+
* @internal Not part of the supported surface while the in-dialog transport is still
|
|
3761
|
+
* rolling out. `WebRTCCall` is exported from the package entry, so without this tag
|
|
3762
|
+
* TypeDoc publishes the method — and the example above — as public API.
|
|
3763
|
+
*
|
|
3764
|
+
* @param method - A `call.*` method name (e.g. `'call.mute'`).
|
|
3765
|
+
* @param params - Method parameters, sent verbatim.
|
|
3766
|
+
* @returns The method's own reply, unwrapped from the `verto.info` envelope.
|
|
3767
|
+
* @throws {JSONRPCError} If the control op fails.
|
|
3513
3768
|
*/
|
|
3514
|
-
|
|
3515
|
-
/** Debug options for verbose SDK diagnostics (e.g., `{ logWsTraffic: true }`). */
|
|
3516
|
-
debug?: DebugOptions;
|
|
3517
|
-
}
|
|
3518
|
-
/** Options for {@link SignalWire.dial}. Extends {@link MediaOptions} with dial-specific settings. */
|
|
3519
|
-
interface DialOptions extends MediaOptions {
|
|
3520
|
-
/** Preferred video codecs for this call (overrides global preferences). */
|
|
3521
|
-
preferredVideoCodecs?: string[];
|
|
3522
|
-
/** Preferred audio codecs for this call (overrides global preferences). */
|
|
3523
|
-
preferredAudioCodecs?: string[];
|
|
3524
|
-
/** Enable stereo Opus for this call (overrides global preferences). */
|
|
3525
|
-
stereo?: boolean;
|
|
3526
|
-
/** Optional node ID for routing the call */
|
|
3527
|
-
nodeId?: string;
|
|
3769
|
+
sendCommand<T extends JSONRPCResponse = JSONRPCResponse>(method: string, params?: Record<string, unknown>): Promise<T>;
|
|
3528
3770
|
/**
|
|
3529
|
-
*
|
|
3530
|
-
* `
|
|
3531
|
-
*
|
|
3771
|
+
* The local leg's member triple — sent as `self` in every member RPC
|
|
3772
|
+
* envelope, and as the `target` of call-scoped self-operations (e.g. lock,
|
|
3773
|
+
* layout).
|
|
3774
|
+
*
|
|
3775
|
+
* @throws {CallNotReadyError} Before `call.joined` delivers the self member
|
|
3776
|
+
* context (`selfId`/`nodeId`) — an RPC without it cannot be routed, so fail
|
|
3777
|
+
* fast instead of sending a doomed request.
|
|
3532
3778
|
*/
|
|
3533
|
-
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3546
|
-
*/
|
|
3547
|
-
|
|
3548
|
-
/**
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
|
|
3569
|
-
|
|
3779
|
+
private get callSelf();
|
|
3780
|
+
/** Observable of the current call status (e.g. `'ringing'`, `'connected'`). */
|
|
3781
|
+
get status$(): Observable<CallStatus>;
|
|
3782
|
+
/** Observable of the participants list, emits on join/leave/update. */
|
|
3783
|
+
get participants$(): Observable<CallParticipant[]>;
|
|
3784
|
+
/** Observable of the local (self) participant. */
|
|
3785
|
+
get self$(): Observable<CallSelfParticipant>;
|
|
3786
|
+
/** Observable indicating whether the call is being recorded. */
|
|
3787
|
+
get recording$(): Observable<boolean>;
|
|
3788
|
+
/** Observable indicating whether the call is being streamed. */
|
|
3789
|
+
get streaming$(): Observable<boolean>;
|
|
3790
|
+
/** Observable indicating whether raise-hand priority is active. */
|
|
3791
|
+
get raiseHandPriority$(): Observable<boolean>;
|
|
3792
|
+
/** Observable indicating whether the call room is locked. */
|
|
3793
|
+
get locked$(): Observable<boolean>;
|
|
3794
|
+
/** Observable of custom metadata associated with the call. */
|
|
3795
|
+
get meta$(): Observable<Record<string, unknown>>;
|
|
3796
|
+
/** Observable of the call's capability flags. */
|
|
3797
|
+
get capabilities$(): Observable<Capability[]>;
|
|
3798
|
+
/** Observable of the current layout name. */
|
|
3799
|
+
get layout$(): Observable<string>;
|
|
3800
|
+
/** Current call status. */
|
|
3801
|
+
get status(): CallStatus;
|
|
3802
|
+
/** Whether the call is currently being recorded. */
|
|
3803
|
+
get recording(): boolean;
|
|
3804
|
+
/** Whether the call is currently being streamed. */
|
|
3805
|
+
get streaming(): boolean;
|
|
3806
|
+
/** Whether raise-hand priority is active. */
|
|
3807
|
+
get raiseHandPriority(): boolean;
|
|
3808
|
+
/** Whether the call room is locked. */
|
|
3809
|
+
get locked(): boolean;
|
|
3810
|
+
/** Current custom metadata of the call. */
|
|
3811
|
+
get meta(): Record<string, unknown>;
|
|
3812
|
+
/** Current layout name, or `undefined` if not set. */
|
|
3813
|
+
get layout(): string | undefined;
|
|
3814
|
+
/** Observable of available layout names. */
|
|
3815
|
+
get layouts$(): Observable<string[]>;
|
|
3816
|
+
/** Current snapshot of available layout names. */
|
|
3817
|
+
get layouts(): string[];
|
|
3818
|
+
/** Observable of the local media stream (camera/microphone). */
|
|
3819
|
+
get localStream$(): Observable<MediaStream>;
|
|
3820
|
+
/** Current local media stream, or `null` if not available. */
|
|
3821
|
+
get localStream(): MediaStream | null;
|
|
3822
|
+
/** Observable of the remote media stream from the far end. */
|
|
3823
|
+
get remoteStream$(): Observable<MediaStream>;
|
|
3824
|
+
/** Current remote media stream, or `null` if not available. */
|
|
3825
|
+
get remoteStream(): MediaStream | null;
|
|
3826
|
+
/** Observable of custom user variables associated with the call. */
|
|
3827
|
+
get userVariables$(): Observable<Record<string, unknown>>;
|
|
3828
|
+
/** a copy of the current custom user variables of the call. */
|
|
3829
|
+
get userVariables(): Record<string, unknown>;
|
|
3830
|
+
/** Merge current custom user variables of the call. */
|
|
3831
|
+
set userVariables(variables: Record<string, unknown>);
|
|
3832
|
+
/** Observable of current network health issues (empty array = healthy). */
|
|
3833
|
+
get networkIssues$(): Observable<NetworkIssue[]>;
|
|
3834
|
+
/** Current snapshot of network issues. */
|
|
3835
|
+
get networkIssues(): NetworkIssue[];
|
|
3836
|
+
/** Simple boolean health indicator derived from stats monitor. */
|
|
3837
|
+
get isNetworkHealthy$(): Observable<boolean>;
|
|
3838
|
+
/** Whether the network is currently healthy. */
|
|
3839
|
+
get isNetworkHealthy(): boolean;
|
|
3840
|
+
/** Rolling history of raw network metrics (RTT, jitter, packet loss, bitrate). */
|
|
3841
|
+
get networkMetrics$(): Observable<NetworkMetrics[]>;
|
|
3842
|
+
/** Current snapshot of the metrics rolling window. */
|
|
3843
|
+
get networkMetrics(): NetworkMetrics[];
|
|
3844
|
+
/** Observable of MOS quality score (1-5) computed from stats metrics. */
|
|
3845
|
+
get qualityScore$(): Observable<number>;
|
|
3846
|
+
/** Observable of simplified quality level (excellent/good/fair/poor/critical). */
|
|
3847
|
+
get qualityLevel$(): Observable<QualityLevel$1>;
|
|
3848
|
+
/** Observable of the recovery pipeline state machine. */
|
|
3849
|
+
get recoveryState$(): Observable<RecoveryState$1>;
|
|
3850
|
+
/** Observable of recovery events (keyframe requested, ICE restart, etc.). */
|
|
3851
|
+
get recoveryEvent$(): Observable<RecoveryEvent$1>;
|
|
3852
|
+
/** Observable indicating whether the call is bandwidth-constrained. */
|
|
3853
|
+
get bandwidthConstrained$(): Observable<boolean>;
|
|
3854
|
+
/** Observable that emits when the server pushes media params. */
|
|
3855
|
+
get mediaParamsUpdated$(): Observable<MediaParamsEvent>;
|
|
3570
3856
|
/**
|
|
3571
|
-
*
|
|
3572
|
-
*
|
|
3573
|
-
* @param credentialProvider - Provider that supplies authentication credentials.
|
|
3574
|
-
* @param options - Configuration options (connection, device monitoring, preferences).
|
|
3857
|
+
* @internal Emit a media params update event.
|
|
3858
|
+
* Called by the VertoManager when the server pushes media params.
|
|
3575
3859
|
*/
|
|
3576
|
-
|
|
3860
|
+
emitMediaParamsUpdated(event: MediaParamsEvent): void;
|
|
3861
|
+
/** Request a video keyframe via RTCP PLI/FIR. */
|
|
3862
|
+
requestKeyframe(): void;
|
|
3863
|
+
/** Force an ICE restart / re-INVITE. */
|
|
3864
|
+
requestIceRestart(): Promise<void>;
|
|
3577
3865
|
/**
|
|
3578
|
-
*
|
|
3866
|
+
* @internal Initialize resilience subsystems when the call reaches 'connected'.
|
|
3867
|
+
* Called from within the status subscription to wire stats and recovery.
|
|
3579
3868
|
*/
|
|
3580
|
-
private
|
|
3869
|
+
private initResilienceSubsystems;
|
|
3581
3870
|
/**
|
|
3582
|
-
*
|
|
3871
|
+
* Wait for the underlying RTCPeerConnection to reach 'connected' after
|
|
3872
|
+
* triggering an ICE restart. Resolves true on success, false on failure
|
|
3873
|
+
* or if the state doesn't transition within the configured timeout.
|
|
3583
3874
|
*
|
|
3584
|
-
*
|
|
3585
|
-
*
|
|
3586
|
-
*
|
|
3587
|
-
* 4. If no provider AND no cache → throw
|
|
3875
|
+
* Polls connectionState directly because the recovery manager already
|
|
3876
|
+
* wraps this call in its own withTimeout(); a separate listener-based
|
|
3877
|
+
* implementation would race the outer timeout in subtle ways.
|
|
3588
3878
|
*/
|
|
3589
|
-
private
|
|
3590
|
-
private validateCredentials;
|
|
3591
|
-
/** Persist credential to localStorage when persistSession is enabled. */
|
|
3592
|
-
private persistCredential;
|
|
3593
|
-
private init;
|
|
3594
|
-
private handleAttachments;
|
|
3879
|
+
private waitForPeerConnectionConnected;
|
|
3595
3880
|
/**
|
|
3596
|
-
*
|
|
3597
|
-
*
|
|
3598
|
-
|
|
3599
|
-
|
|
3600
|
-
|
|
3601
|
-
|
|
3602
|
-
|
|
3603
|
-
|
|
3881
|
+
* @internal Stop and destroy resilience subsystems (on disconnect/destroy).
|
|
3882
|
+
* Clears references so they can be re-created on reconnect.
|
|
3883
|
+
*/
|
|
3884
|
+
private stopResilienceSubsystems;
|
|
3885
|
+
/** @internal */
|
|
3886
|
+
createParticipant(memberId: string, selfId?: string | null): Participant | SelfParticipant;
|
|
3887
|
+
/** Observable of the current audio/video send/receive directions. */
|
|
3888
|
+
get mediaDirections$(): Observable<MediaDirections>;
|
|
3889
|
+
/** Current audio/video send/receive directions. */
|
|
3890
|
+
get mediaDirections(): MediaDirections;
|
|
3891
|
+
protected get participantsId$(): Observable<string[]>;
|
|
3892
|
+
/**
|
|
3893
|
+
* Executes a raw JSON-RPC request on the client session.
|
|
3604
3894
|
*
|
|
3605
|
-
* -
|
|
3606
|
-
* - Each subsequent retry doubles the delay up to `reconnectDelayMax`
|
|
3607
|
-
* (default **3 s**).
|
|
3608
|
-
* - The delay resets to `reconnectDelayMin` once a connection succeeds.
|
|
3609
|
-
* - A per-attempt `connectionTimeout` (default **10 s**) aborts the
|
|
3610
|
-
* attempt and schedules the next retry if the server does not respond.
|
|
3895
|
+
* Lower-level than {@link executeMethod} — allows full control over the RPC request structure.
|
|
3611
3896
|
*
|
|
3612
|
-
*
|
|
3897
|
+
* @param request - Complete JSON-RPC request object.
|
|
3898
|
+
* @param options - Optional RPC execution options (timeout, etc.).
|
|
3899
|
+
* @returns The RPC response.
|
|
3900
|
+
* @throws {JSONRPCError} If the RPC call returns an error response.
|
|
3901
|
+
*/
|
|
3902
|
+
execute<T extends JSONRPCResponse = JSONRPCResponse>(request: JSONRPCRequest, options?: PendingRPCOptions): Promise<T>;
|
|
3903
|
+
/** Observable of the local participant's member ID. */
|
|
3904
|
+
get selfId$(): Observable<string | null>;
|
|
3905
|
+
/** @internal Lets call creation bound the media and signalling phases apart. */
|
|
3906
|
+
get localMediaSettled$(): Observable<void>;
|
|
3907
|
+
/** Local participant's member ID, or `null` if not joined. */
|
|
3908
|
+
get selfId(): string | null;
|
|
3909
|
+
/** Observable of the server node ID handling this call. */
|
|
3910
|
+
get nodeId$(): Observable<string | null>;
|
|
3911
|
+
/** Server node ID handling this call, or `null`. */
|
|
3912
|
+
get nodeId(): string | null;
|
|
3913
|
+
private isCallSessionEvent;
|
|
3914
|
+
private get callSessionEvents$();
|
|
3915
|
+
/** Observable of call-updated events. */
|
|
3916
|
+
get callUpdated$(): Observable<CallUpdatedPayload>;
|
|
3917
|
+
/** Observable of member-joined events, emitted when a remote participant joins the call. */
|
|
3918
|
+
get memberJoined$(): Observable<MemberJoinedPayload>;
|
|
3919
|
+
/** Observable of member-left events, emitted when a participant leaves the call. */
|
|
3920
|
+
get memberLeft$(): Observable<MemberLeftPayload>;
|
|
3921
|
+
/** Observable of member-updated events (mute, volume, etc.). */
|
|
3922
|
+
get memberUpdated$(): Observable<MemberUpdatedPayload>;
|
|
3923
|
+
/** Observable of member-talking events (speech start/stop). */
|
|
3924
|
+
get memberTalking$(): Observable<MemberTalkingPayload>;
|
|
3925
|
+
/** Observable of call state-change events. */
|
|
3926
|
+
get callStates$(): Observable<CallStatePayload>;
|
|
3927
|
+
/** Observable of layout-changed events. */
|
|
3928
|
+
get layoutUpdates$(): Observable<LayoutChangedPayload>;
|
|
3929
|
+
/** Underlying `RTCPeerConnection`, for advanced use cases. */
|
|
3930
|
+
get rtcPeerConnection(): RTCPeerConnection | undefined;
|
|
3931
|
+
/** Observable of raw signaling events as plain objects. */
|
|
3932
|
+
get signalingEvent$(): Observable<Record<string, unknown>>;
|
|
3933
|
+
/**
|
|
3934
|
+
* Subscribe to a custom signaling event type on this call.
|
|
3613
3935
|
*
|
|
3614
|
-
*
|
|
3936
|
+
* Returns a cached observable that filters `callSessionEvents$` for events
|
|
3937
|
+
* whose `event_type` matches the given string. The observable completes
|
|
3938
|
+
* when the call is destroyed.
|
|
3615
3939
|
*
|
|
3616
|
-
*
|
|
3617
|
-
*
|
|
3618
|
-
* re-established the queue is flushed in order so no outgoing RPC call is
|
|
3619
|
-
* lost.
|
|
3940
|
+
* Unlike `signalingEvent$` (which only emits known call-level event types),
|
|
3941
|
+
* this method also matches custom/user-defined event types.
|
|
3620
3942
|
*
|
|
3621
|
-
*
|
|
3622
|
-
*
|
|
3623
|
-
* re-delivered by the server after the session is re-authenticated.
|
|
3624
|
-
* Active RPC calls that were awaiting a response will time out
|
|
3625
|
-
* (default **5 s**) and reject with an `RPCTimeoutError`; callers should
|
|
3626
|
-
* handle this and retry if appropriate.
|
|
3943
|
+
* The SDK does not validate event type strings --- the server decides
|
|
3944
|
+
* whether a given type is valid.
|
|
3627
3945
|
*
|
|
3628
|
-
*
|
|
3629
|
-
*
|
|
3630
|
-
* `'reconnecting'`, `'disconnecting'`, or `'disconnected'`.
|
|
3631
|
-
*/
|
|
3632
|
-
connect(): Promise<void>;
|
|
3633
|
-
/**
|
|
3634
|
-
* Observable that emits the {@link User} profile once fetched,
|
|
3635
|
-
* or `undefined` before authentication completes.
|
|
3946
|
+
* @param eventType - The event type to subscribe to (e.g. `'my.custom.event'`).
|
|
3947
|
+
* @returns An observable that emits matching signaling events.
|
|
3636
3948
|
*
|
|
3637
3949
|
* @example
|
|
3638
3950
|
* ```ts
|
|
3639
|
-
*
|
|
3640
|
-
*
|
|
3951
|
+
* call.subscribe('my.custom.event').subscribe(event => {
|
|
3952
|
+
* console.log('Custom event:', event);
|
|
3641
3953
|
* });
|
|
3642
3954
|
* ```
|
|
3643
3955
|
*/
|
|
3644
|
-
|
|
3645
|
-
|
|
3646
|
-
get
|
|
3956
|
+
subscribe(eventType: string): Observable<Record<string, unknown>>;
|
|
3957
|
+
get webrtcMessages$(): Observable<WebrtcMessagePayload>;
|
|
3958
|
+
get callEvent$(): Observable<WebrtcMessagePayload | CallJoinedPayload | CallLeftPayload | CallUpdatedPayload | CallStatePayload | CallPlayPayload | CallConnectPayload | RoomUpdatedPayload | MemberUpdatedPayload | MemberJoinedPayload | MemberLeftPayload | MemberTalkingPayload | LayoutChangedPayload | ConversationMessagePayload>;
|
|
3959
|
+
get layoutEvent$(): Observable<LayoutChangedPayload>;
|
|
3647
3960
|
/**
|
|
3648
|
-
*
|
|
3649
|
-
*
|
|
3650
|
-
* to
|
|
3961
|
+
* Hangs up the call and releases all resources.
|
|
3962
|
+
*
|
|
3963
|
+
* Sends a Verto `bye` to the server, transitions status to `'disconnecting'`,
|
|
3964
|
+
* then destroys the call. After this, the call instance is no longer usable.
|
|
3651
3965
|
*
|
|
3652
3966
|
* @example
|
|
3653
3967
|
* ```ts
|
|
3654
|
-
*
|
|
3655
|
-
* if (dir) dir.addresses$.subscribe(console.log);
|
|
3656
|
-
* });
|
|
3968
|
+
* await call.hangup();
|
|
3657
3969
|
* ```
|
|
3658
3970
|
*/
|
|
3659
|
-
|
|
3660
|
-
/**
|
|
3661
|
-
* Current directory snapshot, or `undefined` if the client is not yet connected.
|
|
3662
|
-
* Prefer {@link directory$} when you need to react to the directory becoming available.
|
|
3663
|
-
*/
|
|
3664
|
-
get directory(): Directory | undefined;
|
|
3665
|
-
/** Observable that emits when the user registration state changes. */
|
|
3666
|
-
get isRegistered$(): Observable<boolean>;
|
|
3667
|
-
/** Whether the user is currently registered. */
|
|
3668
|
-
get isRegistered(): boolean;
|
|
3669
|
-
/** Whether the client is currently connected. */
|
|
3670
|
-
get isConnected(): boolean;
|
|
3671
|
-
/** Observable that emits when the connection state changes. */
|
|
3672
|
-
get isConnected$(): Observable<boolean>;
|
|
3673
|
-
/** Observable that emits `true` when the client is both connected and authenticated. */
|
|
3674
|
-
get ready$(): Observable<boolean>;
|
|
3675
|
-
/** Observable stream of errors from transport, authentication, and devices. */
|
|
3676
|
-
get errors$(): Observable<Error>;
|
|
3971
|
+
hangup(): Promise<void>;
|
|
3677
3972
|
/**
|
|
3678
|
-
*
|
|
3973
|
+
* Sends DTMF digits on the call.
|
|
3679
3974
|
*
|
|
3680
|
-
*
|
|
3681
|
-
* contracts but do not warrant disconnection — e.g., a fallback from Client Bound SAT
|
|
3682
|
-
* refresh to the developer-provided `refresh()` because the SAT lacks `sat:refresh`
|
|
3683
|
-
* scope. Discriminated by `code`.
|
|
3975
|
+
* @param dtmf - The digit string to send (e.g. `'1234#'`).
|
|
3684
3976
|
*
|
|
3685
|
-
*
|
|
3686
|
-
|
|
3687
|
-
|
|
3688
|
-
|
|
3689
|
-
get platformCapabilities(): PlatformCapabilities;
|
|
3690
|
-
/** Observable that emits when the SDK auto-switches a device. */
|
|
3691
|
-
get deviceRecovered$(): Observable<DeviceRecoveryEvent>;
|
|
3692
|
-
/**
|
|
3693
|
-
* Export a structured diagnostic bundle for support/debugging.
|
|
3694
|
-
* Includes connection events, call summaries, and device changes.
|
|
3695
|
-
*/
|
|
3696
|
-
exportDiagnostics(): SessionDiagnostics;
|
|
3697
|
-
/**
|
|
3698
|
-
* Initialize resilience subsystems. Non-fatal: any failure is logged and
|
|
3699
|
-
* the SDK continues working without the failing subsystem.
|
|
3977
|
+
* @example
|
|
3978
|
+
* ```ts
|
|
3979
|
+
* await call.sendDigits('1234#');
|
|
3980
|
+
* ```
|
|
3700
3981
|
*/
|
|
3701
|
-
|
|
3982
|
+
sendDigits(dtmf: string): Promise<void>;
|
|
3983
|
+
/** Observable of WebRTC-specific signaling messages. */
|
|
3984
|
+
/** Observable of call-level signaling events. */
|
|
3985
|
+
/** Observable of layout-changed signaling events. */
|
|
3702
3986
|
/**
|
|
3703
|
-
*
|
|
3704
|
-
*
|
|
3705
|
-
* Ends the session identified by the protocol and clears its persisted
|
|
3706
|
-
* resume state (`authorization_state` + protocol) and attach records
|
|
3707
|
-
* together — a later {@link connect} with the same credentials starts a
|
|
3708
|
-
* fresh session and cannot reattach to the ended session's calls.
|
|
3709
|
-
* Credentials and device preferences are preserved. To temporarily stop
|
|
3710
|
-
* receiving inbound calls while keeping the session alive, use
|
|
3711
|
-
* `unregister()` instead.
|
|
3987
|
+
* Accepts an inbound call, optionally overriding media options for the answer.
|
|
3712
3988
|
*
|
|
3713
|
-
*
|
|
3714
|
-
* which creates a fresh transport and session.
|
|
3715
|
-
*/
|
|
3716
|
-
disconnect(): Promise<void>;
|
|
3717
|
-
/**
|
|
3718
|
-
* Tear down the current transport / session / attach manager. Safe to call
|
|
3719
|
-
* when nothing has been initialized yet (e.g. first connect()).
|
|
3720
|
-
*/
|
|
3721
|
-
private teardownTransportAndSession;
|
|
3722
|
-
private waitAuthentication;
|
|
3723
|
-
/**
|
|
3724
|
-
* Registers the user as online to receive inbound calls and events.
|
|
3989
|
+
* @param options - Optional media constraints for the answer (audio/video).
|
|
3725
3990
|
*
|
|
3726
|
-
*
|
|
3727
|
-
*
|
|
3991
|
+
* @example
|
|
3992
|
+
* ```ts
|
|
3993
|
+
* // Accept with defaults
|
|
3994
|
+
* call.answer();
|
|
3728
3995
|
*
|
|
3729
|
-
*
|
|
3996
|
+
* // Accept audio-only
|
|
3997
|
+
* call.answer({ audio: true, video: false });
|
|
3998
|
+
* ```
|
|
3999
|
+
* @see {@link reject} to decline the call instead.
|
|
4000
|
+
* @see {@link answered$} to observe the acceptance state.
|
|
3730
4001
|
*/
|
|
3731
|
-
|
|
4002
|
+
answer(options?: MediaOptions): void;
|
|
4003
|
+
/** Media options provided when answering. Used internally by the VertoManager. */
|
|
4004
|
+
get answerMediaOptions(): MediaOptions | undefined;
|
|
3732
4005
|
/**
|
|
3733
|
-
*
|
|
4006
|
+
* Rejects an inbound call, preventing media negotiation.
|
|
3734
4007
|
*
|
|
3735
|
-
*
|
|
4008
|
+
* @see {@link answer} to accept the call instead.
|
|
4009
|
+
* @see {@link answered$} to observe the rejection state.
|
|
3736
4010
|
*/
|
|
3737
|
-
|
|
4011
|
+
reject(): void;
|
|
4012
|
+
/** Observable that emits `true` when answered, `false` when rejected. */
|
|
4013
|
+
get answered$(): Observable<boolean>;
|
|
3738
4014
|
/**
|
|
3739
|
-
*
|
|
4015
|
+
* Sets the call layout and, optionally, individual participant positions.
|
|
3740
4016
|
*
|
|
3741
|
-
*
|
|
3742
|
-
*
|
|
3743
|
-
*
|
|
4017
|
+
* The gateway `call.layout.set` DTO has **no** `positions` member, so when
|
|
4018
|
+
* `positions` is provided this method issues a `call.member.position.set`
|
|
4019
|
+
* request per member (via {@link Participant.setPosition}, which keys each
|
|
4020
|
+
* position by that member's own call context) alongside `call.layout.set`
|
|
4021
|
+
* (issue #19400, Flag #6).
|
|
3744
4022
|
*
|
|
3745
|
-
*
|
|
3746
|
-
*
|
|
4023
|
+
* **These operations are NOT atomic.** The layout is applied first, then each
|
|
4024
|
+
* member position sequentially, so members may briefly flash into their
|
|
4025
|
+
* default slots before being moved to the requested positions. Targeted
|
|
4026
|
+
* members are validated upfront, though: when any of them has no
|
|
4027
|
+
* {@link Participant.target | member call context} yet, the whole call
|
|
4028
|
+
* rejects before any request is sent and the layout is left unchanged.
|
|
3747
4029
|
*
|
|
3748
|
-
* @param
|
|
3749
|
-
* @param
|
|
3750
|
-
*
|
|
3751
|
-
* @throws {
|
|
4030
|
+
* @param layout - Layout name (must be one of {@link layouts}).
|
|
4031
|
+
* @param positions - Optional map of member IDs to {@link VideoPosition} values.
|
|
4032
|
+
* When omitted or empty, only the layout is changed.
|
|
4033
|
+
* @throws {InvalidParams} If the layout is not in the available {@link layouts}.
|
|
4034
|
+
* @throws {ParticipantNotReadyError} If a targeted member's call context has
|
|
4035
|
+
* not been received yet — thrown before any request is sent.
|
|
3752
4036
|
*
|
|
3753
4037
|
* @example
|
|
3754
4038
|
* ```ts
|
|
3755
|
-
*
|
|
3756
|
-
*
|
|
3757
|
-
* video: true,
|
|
4039
|
+
* await call.setLayout('grid-responsive', {
|
|
4040
|
+
* [participantId]: 'reserved-0',
|
|
3758
4041
|
* });
|
|
3759
|
-
* call.status$.subscribe(status => console.log('Call:', status));
|
|
3760
4042
|
* ```
|
|
3761
4043
|
*/
|
|
3762
|
-
|
|
4044
|
+
setLayout(layout: string, positions?: Record<string, VideoPosition>): Promise<void>;
|
|
3763
4045
|
/**
|
|
3764
|
-
*
|
|
3765
|
-
*
|
|
3766
|
-
* The test checks:
|
|
3767
|
-
* 1. **Signaling** -- WebSocket connected, RTT measurement
|
|
3768
|
-
* 2. **Devices** -- getUserMedia succeeds with selected (or specified) devices
|
|
3769
|
-
* 3. **ICE/TURN** -- gathers ICE candidates to verify STUN/TURN reachability
|
|
3770
|
-
* 4. **Media/bandwidth** (unless `skipMediaTest`) -- dials the destination,
|
|
3771
|
-
* collects getStats() for `duration` seconds, computes bandwidth estimates
|
|
3772
|
-
*
|
|
3773
|
-
* @param destination - A destination to dial for the media test (e.g. `'/private/network-test'`).
|
|
3774
|
-
* @param options - Preflight options (duration, skipMediaTest, device overrides).
|
|
3775
|
-
* @returns A {@link PreflightResult} describing connectivity health.
|
|
4046
|
+
* Transfers the call to another destination.
|
|
3776
4047
|
*
|
|
3777
|
-
* @
|
|
3778
|
-
*
|
|
3779
|
-
* const result = await client.preflight('/private/network-test', { duration: 5 });
|
|
3780
|
-
* if (!result.ok) console.warn('Connectivity issues:', result.warnings);
|
|
3781
|
-
* ```
|
|
4048
|
+
* @param options - Transfer configuration including the target destination.
|
|
4049
|
+
* @see {@link status$} to observe the transfer progress.
|
|
3782
4050
|
*/
|
|
3783
|
-
|
|
3784
|
-
/** The underlying client session for advanced RPC operations. */
|
|
3785
|
-
get session(): ClientSessionWrapper;
|
|
3786
|
-
/** Observable list of available audio input (microphone) devices. */
|
|
3787
|
-
get audioInputDevices$(): Observable<MediaDeviceInfo[]>;
|
|
3788
|
-
/** Current snapshot of available audio input devices. */
|
|
3789
|
-
get audioInputDevices(): MediaDeviceInfo[];
|
|
3790
|
-
/** Observable list of available audio output (speaker) devices. */
|
|
3791
|
-
get audioOutputDevices$(): Observable<MediaDeviceInfo[]>;
|
|
3792
|
-
/** Current snapshot of available audio output devices. */
|
|
3793
|
-
get audioOutputDevices(): MediaDeviceInfo[];
|
|
3794
|
-
/** Observable list of available video input (camera) devices. */
|
|
3795
|
-
get videoInputDevices$(): Observable<MediaDeviceInfo[]>;
|
|
3796
|
-
/** Current snapshot of available video input devices. */
|
|
3797
|
-
get videoInputDevices(): MediaDeviceInfo[];
|
|
3798
|
-
/** Observable of the currently selected audio input device. */
|
|
3799
|
-
get selectedAudioInputDevice$(): Observable<MediaDeviceInfo | null>;
|
|
3800
|
-
/** Observable of the currently selected audio output device. */
|
|
3801
|
-
get selectedAudioOutputDevice$(): Observable<MediaDeviceInfo | null>;
|
|
3802
|
-
/** Observable of the currently selected video input device. */
|
|
3803
|
-
get selectedVideoInputDevice$(): Observable<MediaDeviceInfo | null>;
|
|
3804
|
-
/** Currently selected audio input device, or `null` if none. */
|
|
3805
|
-
get selectedAudioInputDevice(): MediaDeviceInfo | null;
|
|
3806
|
-
/** Currently selected audio output device, or `null` if none. */
|
|
3807
|
-
get selectedAudioOutputDevice(): MediaDeviceInfo | null;
|
|
3808
|
-
/** Currently selected video input device, or `null` if none. */
|
|
3809
|
-
get selectedVideoInputDevice(): MediaDeviceInfo | null;
|
|
3810
|
-
/** Media track constraints for the selected audio input device. Returns `false` when disabled. */
|
|
3811
|
-
get selectedAudioInputDeviceConstraints(): MediaTrackConstraints | boolean;
|
|
3812
|
-
/** Media track constraints for the selected video input device. Returns `false` when disabled. */
|
|
3813
|
-
get selectedVideoInputDeviceConstraints(): MediaTrackConstraints | boolean;
|
|
3814
|
-
/** Converts a `MediaDeviceInfo` to track constraints suitable for `getUserMedia`. */
|
|
3815
|
-
deviceInfoToConstraints(deviceInfo: MediaDeviceInfo | null): MediaTrackConstraints;
|
|
3816
|
-
/** Sets the preferred audio input device. */
|
|
3817
|
-
selectAudioInputDevice(device: MediaDeviceInfo | null): void;
|
|
3818
|
-
/** Sets the preferred video input device. */
|
|
3819
|
-
selectVideoInputDevice(device: MediaDeviceInfo | null): void;
|
|
3820
|
-
/** Sets the preferred audio output device. */
|
|
3821
|
-
selectAudioOutputDevice(device: MediaDeviceInfo | null): void;
|
|
4051
|
+
transfer(options: TransferOptions): Promise<void>;
|
|
3822
4052
|
/**
|
|
3823
|
-
*
|
|
3824
|
-
* (e.g. the `<audio>` or `<video>` element the consumer attached the
|
|
3825
|
-
* remote stream to). Uses `HTMLMediaElement.setSinkId` under the hood.
|
|
3826
|
-
* Returns a `Promise<boolean>`: `true` if the sink was applied,
|
|
3827
|
-
* `false` if the browser doesn't support `setSinkId` or no device is
|
|
3828
|
-
* selected.
|
|
4053
|
+
* Set the local microphone gain as a percentage applied before transmission.
|
|
3829
4054
|
*
|
|
3830
|
-
*
|
|
3831
|
-
*
|
|
3832
|
-
*
|
|
3833
|
-
*
|
|
3834
|
-
*
|
|
4055
|
+
* - `0` = silent
|
|
4056
|
+
* - `100` = unity (no change, default)
|
|
4057
|
+
* - `200` = 2× digital boost (max; expect clipping / noise amplification)
|
|
4058
|
+
*
|
|
4059
|
+
* Values are clamped to [0, 200]. Engages the local audio pipeline on
|
|
4060
|
+
* first use (one-time cost).
|
|
4061
|
+
*
|
|
4062
|
+
* Note: this is a **digital** multiplier applied in a Web Audio GainNode
|
|
4063
|
+
* between your mic track and the RTCRtpSender — it does not change the
|
|
4064
|
+
* physical mic's hardware sensitivity. Browsers' autoGainControl can
|
|
4065
|
+
* fight the setting; call {@link setAutoGainControl}(false) for
|
|
4066
|
+
* predictable behaviour.
|
|
4067
|
+
*
|
|
4068
|
+
* @param value - Gain percentage (0..200; 100 = unity).
|
|
3835
4069
|
*/
|
|
3836
|
-
|
|
3837
|
-
/**
|
|
3838
|
-
|
|
3839
|
-
/** Stops monitoring for media device changes. */
|
|
3840
|
-
disableDeviceMonitoring(): void;
|
|
4070
|
+
setLocalMicrophoneGain(value: number): void;
|
|
4071
|
+
/** Observable of the current local microphone gain (0..200, where 100 = unity). */
|
|
4072
|
+
get localMicrophoneGain$(): Observable<number>;
|
|
3841
4073
|
/**
|
|
3842
|
-
*
|
|
3843
|
-
*
|
|
3844
|
-
*
|
|
4074
|
+
* Observable of the RMS audio level of the local microphone, 0..1.
|
|
4075
|
+
* Emits at ~30fps while a mic track is active. Engages the local audio
|
|
4076
|
+
* pipeline on first subscription.
|
|
3845
4077
|
*/
|
|
3846
|
-
|
|
4078
|
+
get localAudioLevel$(): Observable<number>;
|
|
3847
4079
|
/**
|
|
3848
|
-
*
|
|
3849
|
-
*
|
|
3850
|
-
* @returns `true` if the device is valid and available. Returns `false` for `null`, audio output devices, or unavailable devices.
|
|
4080
|
+
* Observable that is `true` while the local participant is speaking
|
|
4081
|
+
* (RMS level above the VAD threshold, with hold time to avoid flicker).
|
|
3851
4082
|
*/
|
|
3852
|
-
|
|
3853
|
-
/** Injects a storage manager into the device controller for persistence. */
|
|
3854
|
-
setStorageManager(storageManager: StorageManager): void;
|
|
3855
|
-
/** Clears all device state and re-enumerates. */
|
|
3856
|
-
clearDeviceState(): Promise<void>;
|
|
3857
|
-
/** Forces a device re-enumeration. */
|
|
3858
|
-
enumerateDevices(): Promise<void>;
|
|
3859
|
-
/** Disables audio input (receive-only mode). No audio track will be acquired. */
|
|
3860
|
-
disableAudioInput(): void;
|
|
3861
|
-
/** Re-enables audio input, restoring the last selection or auto-selecting. */
|
|
3862
|
-
enableAudioInput(): void;
|
|
3863
|
-
/** Disables video input (receive-only mode). No video track will be acquired. */
|
|
3864
|
-
disableVideoInput(): void;
|
|
3865
|
-
/** Re-enables video input, restoring the last selection or auto-selecting. */
|
|
3866
|
-
enableVideoInput(): void;
|
|
3867
|
-
/** Observable that emits `true` when video input is disabled (receive-only). */
|
|
3868
|
-
get videoInputDisabled$(): Observable<boolean>;
|
|
3869
|
-
/** Observable that emits `true` when audio input is disabled (receive-only). */
|
|
3870
|
-
get audioInputDisabled$(): Observable<boolean>;
|
|
3871
|
-
/** Whether video input is currently disabled. */
|
|
3872
|
-
get videoInputDisabled(): boolean;
|
|
3873
|
-
/** Whether audio input is currently disabled. */
|
|
3874
|
-
get audioInputDisabled(): boolean;
|
|
4083
|
+
get localSpeaking$(): Observable<boolean>;
|
|
3875
4084
|
/**
|
|
3876
|
-
*
|
|
4085
|
+
* Enable push-to-talk: while {@link setPushToTalkActive} has been called
|
|
4086
|
+
* with `false`, the microphone gain is forced to 0; calling
|
|
4087
|
+
* {@link setPushToTalkActive} with `true` restores the configured gain.
|
|
4088
|
+
* Use this instead of mute/unmute for instant talk/silence transitions
|
|
4089
|
+
* because it doesn't rebuild the track.
|
|
3877
4090
|
*
|
|
3878
|
-
*
|
|
3879
|
-
*
|
|
3880
|
-
* @
|
|
3881
|
-
* @returns The permission result with selected devices.
|
|
4091
|
+
* This method installs the pipeline but does not attach any keyboard
|
|
4092
|
+
* listener — consumers bind the key themselves and call
|
|
4093
|
+
* {@link setPushToTalkActive} on keydown/keyup.
|
|
3882
4094
|
*/
|
|
3883
|
-
|
|
3884
|
-
|
|
3885
|
-
|
|
3886
|
-
}): Promise<PermissionResult>;
|
|
4095
|
+
enablePushToTalk(): void;
|
|
4096
|
+
/** Disable push-to-talk; mic gain returns to the configured value. */
|
|
4097
|
+
disablePushToTalk(): void;
|
|
3887
4098
|
/**
|
|
3888
|
-
*
|
|
3889
|
-
*
|
|
3890
|
-
* This clears device preferences, device history, authorization state,
|
|
3891
|
-
* attached call IDs, and all SDK storage keys, then re-enumerates devices.
|
|
4099
|
+
* While push-to-talk is enabled, sets the talk state. `true` = transmitting,
|
|
4100
|
+
* `false` = silent. No-op if push-to-talk has not been enabled.
|
|
3892
4101
|
*/
|
|
3893
|
-
|
|
4102
|
+
setPushToTalkActive(active: boolean): void;
|
|
3894
4103
|
/**
|
|
3895
|
-
*
|
|
4104
|
+
* Toggle echo cancellation on the local mic at runtime. Applied via
|
|
4105
|
+
* `track.applyConstraints`; browsers that don't honour runtime constraints
|
|
4106
|
+
* (notably iOS Safari) fall back to re-acquiring the track with the new
|
|
4107
|
+
* constraint set and plumbing the replacement through the local audio
|
|
4108
|
+
* pipeline if one is active.
|
|
3896
4109
|
*
|
|
3897
|
-
*
|
|
3898
|
-
*
|
|
3899
|
-
*
|
|
3900
|
-
*
|
|
3901
|
-
* inbound calls while keeping the session alive, use `unregister()`.
|
|
4110
|
+
* @returns whether the constraint reached the microphone. `false` is an
|
|
4111
|
+
* outcome rather than an error — a leg sending media the SDK did not capture
|
|
4112
|
+
* is left alone — so a UI that reflects the toggle must read it. Any failure
|
|
4113
|
+
* behind a `false` is also reported on {@link errors$}.
|
|
3902
4114
|
*/
|
|
3903
|
-
|
|
3904
|
-
}
|
|
3905
|
-
//#endregion
|
|
3906
|
-
//#region src/utils/embeddableCall.d.ts
|
|
3907
|
-
/** Options for {@link embeddableCall}. */
|
|
3908
|
-
interface EmbeddableCallOptions {
|
|
3909
|
-
/** Destination URI to call. */
|
|
3910
|
-
to: string;
|
|
3911
|
-
/** Embed token for authentication. */
|
|
3912
|
-
embedToken: string;
|
|
3913
|
-
/** SignalWire host URL. */
|
|
3914
|
-
host: string;
|
|
3915
|
-
}
|
|
3916
|
-
/**
|
|
3917
|
-
* Creates a call using an embed token for simple, embeddable integrations.
|
|
3918
|
-
*
|
|
3919
|
-
* Handles client creation, authentication, and dialing in a single call.
|
|
3920
|
-
*
|
|
3921
|
-
* @param options - Embed token, host, and destination.
|
|
3922
|
-
* @returns The created {@link Call} instance.
|
|
3923
|
-
*/
|
|
3924
|
-
declare function embeddableCall(options: EmbeddableCallOptions): Promise<Call>;
|
|
3925
|
-
//#endregion
|
|
3926
|
-
//#region src/dependencies/StaticCredentialProvider.d.ts
|
|
3927
|
-
/**
|
|
3928
|
-
* Credential provider that returns a fixed set of credentials.
|
|
3929
|
-
*
|
|
3930
|
-
* Use when the token is already available (e.g. from a backend endpoint).
|
|
3931
|
-
*
|
|
3932
|
-
* @example
|
|
3933
|
-
* ```ts
|
|
3934
|
-
* const provider = new StaticCredentialProvider({ token: 'my-sat-token' });
|
|
3935
|
-
* const client = new SignalWire(provider);
|
|
3936
|
-
* ```
|
|
3937
|
-
*/
|
|
3938
|
-
declare class StaticCredentialProvider implements CredentialProvider {
|
|
3939
|
-
private credentials;
|
|
3940
|
-
constructor(credentials: SDKCredential);
|
|
3941
|
-
/** Returns the static credentials. */
|
|
3942
|
-
authenticate(): Promise<SDKCredential>;
|
|
3943
|
-
}
|
|
3944
|
-
//#endregion
|
|
3945
|
-
//#region src/dependencies/EmbedTokenCredentialProvider.d.ts
|
|
3946
|
-
/** Credential provider that exchanges an embed token for a SAT via the host's token endpoint. */
|
|
3947
|
-
declare class EmbedTokenCredentialProvider implements CredentialProvider {
|
|
3948
|
-
private host;
|
|
3949
|
-
private embedToken;
|
|
3950
|
-
constructor(host: string, embedToken: string);
|
|
3951
|
-
private fetchSAT;
|
|
3952
|
-
authenticate(): Promise<{
|
|
3953
|
-
token: string;
|
|
3954
|
-
expiry_at: number;
|
|
3955
|
-
}>;
|
|
3956
|
-
refresh(): Promise<{
|
|
3957
|
-
token: string;
|
|
3958
|
-
expiry_at: number;
|
|
3959
|
-
}>;
|
|
3960
|
-
}
|
|
3961
|
-
//#endregion
|
|
3962
|
-
//#region src/controllers/LocalAudioPipeline.d.ts
|
|
3963
|
-
/**
|
|
3964
|
-
* Options for {@link LocalAudioPipeline}.
|
|
3965
|
-
*/
|
|
3966
|
-
interface LocalAudioPipelineOptions {
|
|
3967
|
-
/** Factory for AudioContext — override for tests. Defaults to `new AudioContext()`. */
|
|
3968
|
-
audioContextFactory?: () => AudioContext;
|
|
3969
|
-
/** Initial gain (0..2, where 1 is unity). Defaults to 1. */
|
|
3970
|
-
initialGain?: number;
|
|
3971
|
-
/** RMS level [0..1] above which speaking$ emits true. Defaults to {@link VAD_THRESHOLD}. */
|
|
3972
|
-
speakingThreshold?: number;
|
|
4115
|
+
setEchoCancellation(enabled: boolean): Promise<boolean>;
|
|
3973
4116
|
/**
|
|
3974
|
-
*
|
|
3975
|
-
*
|
|
4117
|
+
* Toggle browser noise suppression on the local mic at runtime.
|
|
4118
|
+
* @returns whether the constraint reached the microphone.
|
|
3976
4119
|
*/
|
|
3977
|
-
|
|
3978
|
-
/**
|
|
3979
|
-
|
|
4120
|
+
setNoiseSuppression(enabled: boolean): Promise<boolean>;
|
|
4121
|
+
/**
|
|
4122
|
+
* Toggle browser automatic gain control on the local mic at runtime.
|
|
4123
|
+
* @returns whether the constraint reached the microphone.
|
|
4124
|
+
*/
|
|
4125
|
+
setAutoGainControl(enabled: boolean): Promise<boolean>;
|
|
4126
|
+
/**
|
|
4127
|
+
* Observable of the aggregate remote audio level, 0..1 RMS. The server
|
|
4128
|
+
* delivers a single mixed audio stream for all remote participants — this
|
|
4129
|
+
* meter reports that mix. Per-participant audio is not available client-side.
|
|
4130
|
+
*
|
|
4131
|
+
* Engages a shared AudioContext on first subscription (cheap — one
|
|
4132
|
+
* AnalyserNode, no GainNode, no destination) so it does not affect the
|
|
4133
|
+
* caller's audio element playback.
|
|
4134
|
+
*/
|
|
4135
|
+
get remoteAudioLevel$(): Observable<number>;
|
|
4136
|
+
/** Destroys the call, releasing all resources and subscriptions. */
|
|
4137
|
+
destroy(): void;
|
|
4138
|
+
/**
|
|
4139
|
+
* @internal Send a verto.subscribe message to add an event type to the
|
|
4140
|
+
* server's subscription list for this call. Returns the underlying RPC
|
|
4141
|
+
* promise so callers can decide whether to cache the observable on success
|
|
4142
|
+
* or retry on failure.
|
|
4143
|
+
*/
|
|
4144
|
+
private _sendVertoSubscribe;
|
|
3980
4145
|
}
|
|
4146
|
+
//#endregion
|
|
4147
|
+
//#region src/core/entities/Directory.d.ts
|
|
3981
4148
|
/**
|
|
3982
|
-
*
|
|
3983
|
-
*
|
|
3984
|
-
* Wraps the raw mic `MediaStreamTrack` in a graph of:
|
|
3985
|
-
*
|
|
3986
|
-
* ```
|
|
3987
|
-
* MediaStreamAudioSourceNode → GainNode → AnalyserNode → MediaStreamAudioDestinationNode
|
|
3988
|
-
* ```
|
|
4149
|
+
* Directory interface for managing addresses
|
|
3989
4150
|
*
|
|
3990
|
-
*
|
|
3991
|
-
*
|
|
3992
|
-
* destination track is reused across input changes (device switch, mute /
|
|
3993
|
-
* unmute track replacement) so the sender reference stays stable — only the
|
|
3994
|
-
* source end of the graph is rebuilt.
|
|
4151
|
+
* This is the public API contract for address directory functionality.
|
|
4152
|
+
* It provides access to addresses, loading capabilities, and search functionality.
|
|
3995
4153
|
*
|
|
3996
|
-
*
|
|
3997
|
-
* {@link destroy} to release it when the call ends.
|
|
4154
|
+
* @public
|
|
3998
4155
|
*/
|
|
3999
|
-
|
|
4000
|
-
private readonly _audioContext;
|
|
4001
|
-
private readonly _gainNode;
|
|
4002
|
-
private readonly _analyser;
|
|
4003
|
-
private readonly _destination;
|
|
4004
|
-
private readonly _analyserBuffer;
|
|
4005
|
-
private readonly _speakingThreshold;
|
|
4006
|
-
private readonly _speakingHoldMs;
|
|
4007
|
-
private readonly _pollIntervalMs;
|
|
4008
|
-
private _inputSource;
|
|
4009
|
-
private _inputStream;
|
|
4010
|
-
private _lastSpokeAt;
|
|
4011
|
-
private _gain$;
|
|
4012
|
-
/** 1 when audio should pass through, 0 when silenced by PTT. */
|
|
4013
|
-
private _pttMultiplier;
|
|
4014
|
-
constructor(options?: LocalAudioPipelineOptions);
|
|
4015
|
-
/** Observable of the current gain value (0..2). */
|
|
4016
|
-
get gain$(): Observable<number>;
|
|
4017
|
-
/** Current gain value (0..2). */
|
|
4018
|
-
get gain(): number;
|
|
4156
|
+
interface Directory extends AddressProvider<Address> {
|
|
4019
4157
|
/**
|
|
4020
|
-
*
|
|
4021
|
-
*
|
|
4022
|
-
* needs to be called once.
|
|
4158
|
+
* Observable stream of all addresses in the directory
|
|
4159
|
+
* Emits a new array whenever addresses are added, removed, or updated
|
|
4023
4160
|
*/
|
|
4024
|
-
|
|
4161
|
+
readonly addresses$: Observable<Address[]>;
|
|
4025
4162
|
/**
|
|
4026
|
-
*
|
|
4027
|
-
* interval (~30fps by default).
|
|
4163
|
+
* Current snapshot of all addresses in the directory
|
|
4028
4164
|
*/
|
|
4029
|
-
|
|
4165
|
+
readonly addresses: Address[];
|
|
4030
4166
|
/**
|
|
4031
|
-
*
|
|
4032
|
-
* during the hold window after the last frame that crossed the threshold.
|
|
4167
|
+
* Observable indicating whether more addresses can be loaded from the server
|
|
4033
4168
|
*/
|
|
4034
|
-
|
|
4169
|
+
readonly hasMore$: Observable<boolean>;
|
|
4035
4170
|
/**
|
|
4036
|
-
*
|
|
4037
|
-
*
|
|
4038
|
-
* the graph also respects the current PTT state.
|
|
4171
|
+
* Observable indicating the current loading state
|
|
4172
|
+
* Emits `true` when loading, `false` when idle
|
|
4039
4173
|
*/
|
|
4040
|
-
|
|
4174
|
+
readonly loading$: Observable<boolean>;
|
|
4175
|
+
readonly loading: boolean;
|
|
4041
4176
|
/**
|
|
4042
|
-
*
|
|
4043
|
-
*
|
|
4044
|
-
* Orthogonal to {@link setGain} — once PTT returns to active, the last
|
|
4045
|
-
* configured gain reappears.
|
|
4177
|
+
* Load more addresses from the server
|
|
4178
|
+
* Only loads if `hasMore` is true
|
|
4046
4179
|
*/
|
|
4047
|
-
|
|
4048
|
-
private applyEffectiveGain;
|
|
4180
|
+
loadMore(): void;
|
|
4049
4181
|
/**
|
|
4050
|
-
*
|
|
4051
|
-
* input source and reconnects the graph so {@link outputTrack} continues
|
|
4052
|
-
* to emit the processed audio. Pass `null` to disconnect the input (the
|
|
4053
|
-
* output track stays alive but emits silence).
|
|
4182
|
+
* Get a specific address by ID
|
|
4054
4183
|
*
|
|
4055
|
-
*
|
|
4056
|
-
*
|
|
4057
|
-
* track emits silence) until resume() succeeds.
|
|
4184
|
+
* @param addressId - The address ID to retrieve
|
|
4185
|
+
* @returns The address instance, or undefined if not found
|
|
4058
4186
|
*/
|
|
4059
|
-
|
|
4060
|
-
|
|
4061
|
-
|
|
4062
|
-
|
|
4187
|
+
get(addressId: string): Address | undefined;
|
|
4188
|
+
/**
|
|
4189
|
+
* Find an address ID by searching for a name
|
|
4190
|
+
*
|
|
4191
|
+
* @param uri - The address name to search for
|
|
4192
|
+
* @returns Promise resolving to the address ID, or undefined if not found
|
|
4193
|
+
*/
|
|
4194
|
+
findAddressIdByURI(uri: string): Promise<string | undefined>;
|
|
4063
4195
|
}
|
|
4064
4196
|
//#endregion
|
|
4065
|
-
//#region src/
|
|
4066
|
-
|
|
4067
|
-
|
|
4068
|
-
|
|
4069
|
-
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
disableUdpIceServers?: boolean;
|
|
4075
|
-
relayOnly?: boolean;
|
|
4076
|
-
iceCandidateTimeout?: number;
|
|
4077
|
-
iceGatheringTimeout?: number;
|
|
4078
|
-
webRTCApiProvider?: WebRTCApiProvider;
|
|
4079
|
-
/** Per-call preferred video codecs (overrides global preferences). */
|
|
4080
|
-
preferredVideoCodecs?: string[];
|
|
4081
|
-
/** Per-call preferred audio codecs (overrides global preferences). */
|
|
4082
|
-
preferredAudioCodecs?: string[];
|
|
4083
|
-
/** Per-call stereo Opus setting (overrides global preferences). */
|
|
4084
|
-
stereo?: boolean;
|
|
4085
|
-
}
|
|
4086
|
-
type RTCPeerConnectionControllerOptionsPartial = Partial<RTCPeerConnectionControllerOptions>;
|
|
4087
|
-
interface UpdateSDPStatusParams {
|
|
4088
|
-
status: 'received' | 'sent' | 'failed';
|
|
4089
|
-
sdp?: string;
|
|
4090
|
-
}
|
|
4091
|
-
declare class RTCPeerConnectionController extends Destroyable {
|
|
4092
|
-
protected options: RTCPeerConnectionControllerOptionsPartial;
|
|
4093
|
-
readonly id: string;
|
|
4094
|
-
firstSDPExchangeCompleted: boolean;
|
|
4095
|
-
sdpInit?: RTCSessionDescriptionInit;
|
|
4096
|
-
private negotiationNeeded$;
|
|
4097
|
-
private deviceController;
|
|
4098
|
-
private localStreamController;
|
|
4099
|
-
private transceiverController?;
|
|
4100
|
-
readonly localDescription$: Observable<RTCSessionDescription | null>;
|
|
4101
|
-
peerConnection?: RTCPeerConnection;
|
|
4102
|
-
private initPromise?;
|
|
4103
|
-
private connectionTimeout;
|
|
4104
|
-
private connectionTimer?;
|
|
4105
|
-
private oniceconnectionstatechangeHandler;
|
|
4106
|
-
private onconnectionstatechangeHandler;
|
|
4107
|
-
private onsignalingstatechangeHandler;
|
|
4108
|
-
private onicegatheringstatechangeHandler;
|
|
4109
|
-
private onnegotiationneededHandler;
|
|
4110
|
-
private updateSelectedInputDevice;
|
|
4111
|
-
private _isNegotiating$;
|
|
4112
|
-
private _iceGatheringController?;
|
|
4113
|
-
private _memberId;
|
|
4114
|
-
private _type;
|
|
4115
|
-
private _iceConnectionState$;
|
|
4116
|
-
private _connectionState$;
|
|
4117
|
-
private _signalingState$;
|
|
4118
|
-
private _iceGatheringState$;
|
|
4119
|
-
private _errors$;
|
|
4120
|
-
private _iceCandidates$;
|
|
4121
|
-
private _initialized$;
|
|
4122
|
-
private _remoteDescription$;
|
|
4123
|
-
private _remoteStream$;
|
|
4124
|
-
private _remoteOfferMediaDirections;
|
|
4125
|
-
private _localAudioPipeline;
|
|
4126
|
-
constructor(options?: RTCPeerConnectionControllerOptionsPartial, remoteSessionDescription?: string, deviceController?: DeviceController);
|
|
4127
|
-
private get iceGatheringController();
|
|
4128
|
-
private get shouldEmitLocalDescription();
|
|
4129
|
-
private removeConnectionTimer;
|
|
4130
|
-
setMemberId(memberId: string | null): void;
|
|
4131
|
-
get memberId(): string | null;
|
|
4132
|
-
stopTrackSender(kind: 'audio' | 'video' | 'both', options?: {
|
|
4133
|
-
updateTransceiverDirection: boolean;
|
|
4134
|
-
}): void;
|
|
4135
|
-
private stopRawAudioInputForPipeline;
|
|
4136
|
-
get isNegotiating$(): Observable<boolean>;
|
|
4137
|
-
get isNegotiating(): boolean;
|
|
4138
|
-
updateMediaDevicesOptions(options: MediaOptions): void;
|
|
4139
|
-
get iceGatheringState$(): Observable<RTCIceGatheringState>;
|
|
4140
|
-
get mediaTrackEnded$(): Observable<MediaStreamTrack>;
|
|
4141
|
-
get errors$(): Observable<Error>;
|
|
4142
|
-
get iceCandidates$(): Observable<RTCIceCandidate[]>;
|
|
4143
|
-
get initialized$(): Observable<boolean>;
|
|
4144
|
-
get remoteDescription$(): Observable<RTCSessionDescription | null>;
|
|
4145
|
-
get localStream$(): Observable<MediaStream | null>;
|
|
4146
|
-
get remoteStream$(): Observable<MediaStream | null>;
|
|
4147
|
-
get localAudioTracks$(): Observable<MediaStreamTrack[]>;
|
|
4148
|
-
get localVideoTracks$(): Observable<MediaStreamTrack[]>;
|
|
4149
|
-
get iceConnectionState$(): Observable<RTCIceConnectionState>;
|
|
4150
|
-
get connectionState$(): Observable<RTCPeerConnectionState>;
|
|
4151
|
-
get signalingState$(): Observable<RTCSignalingState>;
|
|
4152
|
-
get type(): RTCPeerConnectionType;
|
|
4153
|
-
get propose(): RTCPeerConnectionPropose;
|
|
4154
|
-
get isAdditionalDevice(): boolean;
|
|
4155
|
-
get isMainDevice(): boolean;
|
|
4156
|
-
get isScreenShare(): boolean;
|
|
4157
|
-
protected get iceServers(): RTCIceServer[];
|
|
4158
|
-
private get rtcConfiguration();
|
|
4159
|
-
get receiveVideo(): boolean;
|
|
4160
|
-
get receiveAudio(): boolean;
|
|
4161
|
-
get localStream(): MediaStream | null;
|
|
4162
|
-
get remoteStream(): MediaStream | null;
|
|
4163
|
-
private get inputAudioDeviceConstraints();
|
|
4164
|
-
private get inputVideoDeviceConstraints();
|
|
4165
|
-
private get WebRTCPeerConnectionConstructor();
|
|
4166
|
-
private get offerOptions();
|
|
4167
|
-
private get answerOptions();
|
|
4197
|
+
//#region src/interfaces/SessionState.d.ts
|
|
4198
|
+
/**
|
|
4199
|
+
* Extended session interface that adds call management and authentication
|
|
4200
|
+
* state on top of the narrow ClientSession contract.
|
|
4201
|
+
*
|
|
4202
|
+
* Accessible via `client.session`. Call and CallFactory continue to depend
|
|
4203
|
+
* only on the narrow ClientSession interface.
|
|
4204
|
+
*/
|
|
4205
|
+
interface SessionState extends ClientSession {
|
|
4168
4206
|
/**
|
|
4169
|
-
*
|
|
4170
|
-
*
|
|
4171
|
-
|
|
4172
|
-
|
|
4207
|
+
* Observable stream of currently active inbound calls.
|
|
4208
|
+
* Filters `calls$` to only include calls with `direction === 'inbound'`.
|
|
4209
|
+
*/
|
|
4210
|
+
readonly incomingCalls$: Observable<Call[]>;
|
|
4211
|
+
/**
|
|
4212
|
+
* Current snapshot of active inbound calls.
|
|
4213
|
+
*/
|
|
4214
|
+
readonly incomingCalls: Call[];
|
|
4215
|
+
/**
|
|
4216
|
+
* Observable stream of all currently active calls (both inbound and outbound).
|
|
4217
|
+
*/
|
|
4218
|
+
readonly calls$: Observable<Call[]>;
|
|
4219
|
+
/**
|
|
4220
|
+
* Current snapshot of all active calls.
|
|
4221
|
+
*/
|
|
4222
|
+
readonly calls: Call[];
|
|
4223
|
+
/**
|
|
4224
|
+
* Observable that emits `true` once the session has been authenticated,
|
|
4225
|
+
* and `false` after disconnect.
|
|
4173
4226
|
*/
|
|
4174
|
-
|
|
4227
|
+
readonly authenticated$: Observable<boolean>;
|
|
4175
4228
|
/**
|
|
4176
|
-
*
|
|
4177
|
-
*
|
|
4229
|
+
* Current authentication state.
|
|
4230
|
+
* Returns `true` if the session is currently authenticated.
|
|
4178
4231
|
*/
|
|
4179
|
-
|
|
4180
|
-
|
|
4181
|
-
|
|
4232
|
+
readonly authenticated: boolean;
|
|
4233
|
+
}
|
|
4234
|
+
//#endregion
|
|
4235
|
+
//#region src/managers/ClientSessionManager.d.ts
|
|
4236
|
+
/**
|
|
4237
|
+
* Discriminated union for session authentication state.
|
|
4238
|
+
* clientBound is tracked separately via _wasClientBound (sticky flag)
|
|
4239
|
+
* to avoid dual sources of truth.
|
|
4240
|
+
*/
|
|
4241
|
+
type SessionAuthState = {
|
|
4242
|
+
kind: 'unauthenticated';
|
|
4243
|
+
} | {
|
|
4244
|
+
kind: 'authenticated';
|
|
4245
|
+
};
|
|
4246
|
+
declare class ClientSessionManager extends Destroyable implements SessionState {
|
|
4247
|
+
private readonly getCredential;
|
|
4248
|
+
private readonly transport;
|
|
4249
|
+
private readonly storage;
|
|
4250
|
+
private readonly authorizationStateKey;
|
|
4251
|
+
private readonly attachManager;
|
|
4252
|
+
private readonly dpopManager?;
|
|
4253
|
+
private callFactory;
|
|
4254
|
+
private readonly agent;
|
|
4255
|
+
private readonly eventAcks;
|
|
4256
|
+
initialized$: Observable<boolean>;
|
|
4257
|
+
private authorizationState$;
|
|
4258
|
+
private connectVersion;
|
|
4182
4259
|
/**
|
|
4183
|
-
*
|
|
4260
|
+
* Optional hook called before a fresh connect on reconnect.
|
|
4261
|
+
* Used by SignalWire to refresh expired credentials before re-authenticating.
|
|
4262
|
+
* @internal
|
|
4184
4263
|
*/
|
|
4185
|
-
|
|
4186
|
-
updateAnswerStatus({
|
|
4187
|
-
status,
|
|
4188
|
-
sdp
|
|
4189
|
-
}: UpdateSDPStatusParams): Promise<void>;
|
|
4190
|
-
updateOfferStatus({
|
|
4191
|
-
status,
|
|
4192
|
-
sdp
|
|
4193
|
-
}: UpdateSDPStatusParams): Promise<void>;
|
|
4264
|
+
onBeforeReconnect?: () => Promise<void>;
|
|
4194
4265
|
/**
|
|
4195
|
-
*
|
|
4196
|
-
*
|
|
4197
|
-
*
|
|
4266
|
+
* Session-wide call control transport (see {@link ClientSession.callControl}).
|
|
4267
|
+
* Set from {@link SignalWireOptions.callControl} by SignalWire after construction;
|
|
4268
|
+
* defaults to `'routed'`. Read by every Call, so it needs no per-call persistence.
|
|
4198
4269
|
*/
|
|
4199
|
-
|
|
4200
|
-
private
|
|
4201
|
-
private
|
|
4202
|
-
private
|
|
4203
|
-
|
|
4204
|
-
|
|
4270
|
+
callControl: 'routed' | 'in-dialog';
|
|
4271
|
+
private _authorization$;
|
|
4272
|
+
private _errors$;
|
|
4273
|
+
private _directory?;
|
|
4274
|
+
private _authState$;
|
|
4275
|
+
/** Sticky flag — once true, stays true for the session lifetime. */
|
|
4276
|
+
private _wasClientBound;
|
|
4277
|
+
private _userInfo$;
|
|
4278
|
+
private _calls$;
|
|
4279
|
+
private _iceServers$;
|
|
4280
|
+
constructor(getCredential: () => SDKCredential, transport: TransportManager, storage: StorageManager, authorizationStateKey: string, deviceController: DeviceController, attachManager: AttachManager, webRTCApiProvider: WebRTCApiProvider, dpopManager?: CryptoController | undefined, networkChange$?: Observable<NetworkChangeEvent>);
|
|
4281
|
+
get incomingCalls$(): Observable<Call[]>;
|
|
4282
|
+
get incomingCalls(): Call[];
|
|
4283
|
+
get userInfo$(): Observable<Address | null>;
|
|
4284
|
+
get userInfo(): Address | null;
|
|
4285
|
+
get calls$(): Observable<Call[]>;
|
|
4286
|
+
get calls(): Call[];
|
|
4287
|
+
get iceServers(): RTCIceServer[] | undefined;
|
|
4288
|
+
get authorization$(): Observable<Authorization | undefined>;
|
|
4289
|
+
get authorization(): Authorization | undefined;
|
|
4290
|
+
get errors$(): Observable<Error>;
|
|
4291
|
+
get authenticated$(): Observable<boolean>;
|
|
4292
|
+
get authenticated(): boolean;
|
|
4205
4293
|
/**
|
|
4206
|
-
*
|
|
4294
|
+
* Whether this session is client-bound (using a Client Bound SAT).
|
|
4295
|
+
* When client-bound, DPoP proof creation failures are treated as
|
|
4296
|
+
* authentication errors rather than silently degraded.
|
|
4297
|
+
* @internal
|
|
4207
4298
|
*/
|
|
4208
|
-
|
|
4299
|
+
get clientBound(): boolean;
|
|
4300
|
+
/** @internal Current auth state for debugging/testing. */
|
|
4301
|
+
get authState(): SessionAuthState;
|
|
4209
4302
|
/**
|
|
4210
|
-
*
|
|
4303
|
+
* Set the directory instance
|
|
4304
|
+
* Called by SignalWire after directory is created
|
|
4305
|
+
* @internal
|
|
4211
4306
|
*/
|
|
4212
|
-
|
|
4213
|
-
|
|
4307
|
+
setDirectory(directory: Directory): void;
|
|
4308
|
+
execute<T extends JSONRPCResponse = JSONRPCResponse>(request: JSONRPCRequest, options?: PendingRPCOptions): Promise<T>;
|
|
4309
|
+
send(message: JSONSerializable): void;
|
|
4310
|
+
private init;
|
|
4311
|
+
private setupMessageHandlers;
|
|
4312
|
+
private loadAuthorizationStateFromStorage;
|
|
4313
|
+
private updateAuthorizationStateInStorage;
|
|
4314
|
+
private get authStateEvent$();
|
|
4315
|
+
get signalingEvent$(): Observable<(Omit<{
|
|
4316
|
+
event_type: "webrtc.message";
|
|
4317
|
+
event_channel: EventChannel;
|
|
4318
|
+
timestamp: number;
|
|
4319
|
+
project_id?: string;
|
|
4320
|
+
node_id?: string;
|
|
4321
|
+
is_author?: boolean;
|
|
4322
|
+
params: WebrtcMessagePayload;
|
|
4323
|
+
}, "event_channel" | "project_id" | "node_id"> & {
|
|
4324
|
+
event_channel: string;
|
|
4325
|
+
project_id: string;
|
|
4326
|
+
node_id: string;
|
|
4327
|
+
}) | {
|
|
4328
|
+
event_type: "signalwire.authorization.state";
|
|
4329
|
+
params: SignalwireAuthorizationStatePayload;
|
|
4330
|
+
} | (Omit<{
|
|
4331
|
+
event_type: "call.joined";
|
|
4332
|
+
event_channel: EventChannel;
|
|
4333
|
+
timestamp: number;
|
|
4334
|
+
project_id?: string;
|
|
4335
|
+
node_id?: string;
|
|
4336
|
+
is_author?: boolean;
|
|
4337
|
+
params: CallJoinedPayload;
|
|
4338
|
+
}, "event_channel"> & {
|
|
4339
|
+
event_channel: string;
|
|
4340
|
+
}) | (Omit<{
|
|
4341
|
+
event_type: "call.left";
|
|
4342
|
+
event_channel: EventChannel;
|
|
4343
|
+
timestamp: number;
|
|
4344
|
+
project_id?: string;
|
|
4345
|
+
node_id?: string;
|
|
4346
|
+
is_author?: boolean;
|
|
4347
|
+
params: CallLeftPayload;
|
|
4348
|
+
}, "event_channel"> & {
|
|
4349
|
+
event_channel: string;
|
|
4350
|
+
}) | (Omit<{
|
|
4351
|
+
event_type: "call.updated";
|
|
4352
|
+
event_channel: EventChannel;
|
|
4353
|
+
timestamp: number;
|
|
4354
|
+
project_id?: string;
|
|
4355
|
+
node_id?: string;
|
|
4356
|
+
is_author?: boolean;
|
|
4357
|
+
params: CallUpdatedPayload;
|
|
4358
|
+
}, "event_channel"> & {
|
|
4359
|
+
event_channel: string;
|
|
4360
|
+
}) | (Omit<{
|
|
4361
|
+
event_type: "call.state";
|
|
4362
|
+
event_channel: EventChannel;
|
|
4363
|
+
timestamp: number;
|
|
4364
|
+
project_id?: string;
|
|
4365
|
+
node_id?: string;
|
|
4366
|
+
is_author?: boolean;
|
|
4367
|
+
params: CallStatePayload;
|
|
4368
|
+
}, "event_channel"> & {
|
|
4369
|
+
event_channel: string;
|
|
4370
|
+
}) | (Omit<{
|
|
4371
|
+
event_type: "call.play";
|
|
4372
|
+
event_channel: EventChannel;
|
|
4373
|
+
timestamp: number;
|
|
4374
|
+
project_id?: string;
|
|
4375
|
+
node_id?: string;
|
|
4376
|
+
is_author?: boolean;
|
|
4377
|
+
params: CallPlayPayload;
|
|
4378
|
+
}, "event_channel"> & {
|
|
4379
|
+
event_channel: string;
|
|
4380
|
+
}) | (Omit<{
|
|
4381
|
+
event_type: "call.connect";
|
|
4382
|
+
event_channel: EventChannel;
|
|
4383
|
+
timestamp: number;
|
|
4384
|
+
project_id?: string;
|
|
4385
|
+
node_id?: string;
|
|
4386
|
+
is_author?: boolean;
|
|
4387
|
+
params: CallConnectPayload;
|
|
4388
|
+
}, "event_channel"> & {
|
|
4389
|
+
event_channel: string;
|
|
4390
|
+
}) | (Omit<{
|
|
4391
|
+
event_type: "room.updated";
|
|
4392
|
+
event_channel: EventChannel;
|
|
4393
|
+
timestamp: number;
|
|
4394
|
+
project_id?: string;
|
|
4395
|
+
node_id?: string;
|
|
4396
|
+
is_author?: boolean;
|
|
4397
|
+
params: RoomUpdatedPayload;
|
|
4398
|
+
}, "event_channel"> & {
|
|
4399
|
+
event_channel: string;
|
|
4400
|
+
}) | Omit<{
|
|
4401
|
+
event_type: "member.updated";
|
|
4402
|
+
event_channel: EventChannel;
|
|
4403
|
+
timestamp: number;
|
|
4404
|
+
project_id?: string;
|
|
4405
|
+
node_id?: string;
|
|
4406
|
+
is_author?: boolean;
|
|
4407
|
+
params: MemberUpdatedPayload;
|
|
4408
|
+
}, never> | Omit<{
|
|
4409
|
+
event_type: "member.joined";
|
|
4410
|
+
event_channel: EventChannel;
|
|
4411
|
+
timestamp: number;
|
|
4412
|
+
project_id?: string;
|
|
4413
|
+
node_id?: string;
|
|
4414
|
+
is_author?: boolean;
|
|
4415
|
+
params: MemberJoinedPayload;
|
|
4416
|
+
}, never> | Omit<{
|
|
4417
|
+
event_type: "member.left";
|
|
4418
|
+
event_channel: EventChannel;
|
|
4419
|
+
timestamp: number;
|
|
4420
|
+
project_id?: string;
|
|
4421
|
+
node_id?: string;
|
|
4422
|
+
is_author?: boolean;
|
|
4423
|
+
params: MemberLeftPayload;
|
|
4424
|
+
}, never> | Omit<{
|
|
4425
|
+
event_type: "member.talking";
|
|
4426
|
+
event_channel: EventChannel;
|
|
4427
|
+
timestamp: number;
|
|
4428
|
+
project_id?: string;
|
|
4429
|
+
node_id?: string;
|
|
4430
|
+
is_author?: boolean;
|
|
4431
|
+
params: MemberTalkingPayload;
|
|
4432
|
+
}, never> | Omit<{
|
|
4433
|
+
event_type: "layout.changed";
|
|
4434
|
+
event_channel: EventChannel;
|
|
4435
|
+
timestamp: number;
|
|
4436
|
+
project_id?: string;
|
|
4437
|
+
node_id?: string;
|
|
4438
|
+
is_author?: boolean;
|
|
4439
|
+
params: LayoutChangedPayload;
|
|
4440
|
+
}, never> | (Omit<{
|
|
4441
|
+
event_type: "conversation.message";
|
|
4442
|
+
event_channel: EventChannel;
|
|
4443
|
+
timestamp: number;
|
|
4444
|
+
project_id?: string;
|
|
4445
|
+
node_id?: string;
|
|
4446
|
+
is_author?: boolean;
|
|
4447
|
+
params: ConversationMessagePayload;
|
|
4448
|
+
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
4449
|
+
event_channel: string;
|
|
4450
|
+
timestamp: string;
|
|
4451
|
+
is_author: boolean;
|
|
4452
|
+
}) | (Omit<{
|
|
4453
|
+
event_type: "conversation.message.updated";
|
|
4454
|
+
event_channel: EventChannel;
|
|
4455
|
+
timestamp: number;
|
|
4456
|
+
project_id?: string;
|
|
4457
|
+
node_id?: string;
|
|
4458
|
+
is_author?: boolean;
|
|
4459
|
+
params: ConversationMessagePayload;
|
|
4460
|
+
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
4461
|
+
event_channel: string;
|
|
4462
|
+
timestamp: string;
|
|
4463
|
+
is_author: boolean;
|
|
4464
|
+
})>;
|
|
4465
|
+
private get vertoInvite$();
|
|
4466
|
+
private get vertoAttach$();
|
|
4467
|
+
private get contexts();
|
|
4468
|
+
private get eventing();
|
|
4469
|
+
private get topics();
|
|
4470
|
+
private get authentication();
|
|
4471
|
+
connect(): Promise<void>;
|
|
4472
|
+
private handleAuthenticationError;
|
|
4214
4473
|
/**
|
|
4215
|
-
*
|
|
4474
|
+
* Clear the resume state (authorization_state + protocol) and ask the
|
|
4475
|
+
* transport to reconnect. The `connected` event re-triggers
|
|
4476
|
+
* `authenticate()`, which now has no stored state and so performs a fresh
|
|
4477
|
+
* connect.
|
|
4216
4478
|
*
|
|
4217
|
-
* This
|
|
4218
|
-
*
|
|
4219
|
-
*
|
|
4220
|
-
*
|
|
4221
|
-
*
|
|
4479
|
+
* This is the stale-auth-state recovery helper used by handleAuthError:
|
|
4480
|
+
* the server rejected a reconnect, so the resume state is discarded and a
|
|
4481
|
+
* fresh connect follows. Attach records are deliberately preserved — the
|
|
4482
|
+
* session lives on through the reconnect and reattachCalls() needs the
|
|
4483
|
+
* stored call references afterwards. Do NOT add detachAll() here.
|
|
4222
4484
|
*
|
|
4223
|
-
*
|
|
4224
|
-
*
|
|
4225
|
-
*
|
|
4226
|
-
*
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
* Setup track handling for remote tracks.
|
|
4232
|
-
*/
|
|
4233
|
-
private setupTrackHandling;
|
|
4234
|
-
private setupLocalTracks;
|
|
4235
|
-
private getUserMedia;
|
|
4236
|
-
private getDisplayMedia;
|
|
4237
|
-
private setupRemoteTracks;
|
|
4238
|
-
restoreTrackSender(kind: 'audio' | 'video' | 'both'): Promise<void>;
|
|
4239
|
-
private restoreRawAudioInputForPipeline;
|
|
4240
|
-
/**
|
|
4241
|
-
* Return the lazily-created {@link LocalAudioPipeline}, constructing it on
|
|
4242
|
-
* first access. On creation the current audio sender's track is routed
|
|
4243
|
-
* through the pipeline (input → gain → analyser → destination) and the
|
|
4244
|
-
* sender is switched to emit the processed track. Returns `null` when no
|
|
4245
|
-
* audio sender exists yet (pre-negotiation).
|
|
4246
|
-
*/
|
|
4247
|
-
ensureLocalAudioPipeline(): LocalAudioPipeline | null;
|
|
4248
|
-
/** The active LocalAudioPipeline, or null if it hasn't been created yet. */
|
|
4249
|
-
get localAudioPipeline(): LocalAudioPipeline | null;
|
|
4250
|
-
private applyLocalAudioPipelineToSender;
|
|
4251
|
-
/**
|
|
4252
|
-
* Add a local media track to the peer connection.
|
|
4253
|
-
* @param track - The MediaStreamTrack to add
|
|
4254
|
-
*/
|
|
4255
|
-
addLocalTrack(track: MediaStreamTrack): void;
|
|
4256
|
-
/**
|
|
4257
|
-
* Remove a local media track from the peer connection.
|
|
4258
|
-
* @param trackId - The ID of the track to remove
|
|
4485
|
+
* Connect-time recovery only. A *request* refused on an already
|
|
4486
|
+
* authenticated session is never healed here: dropping the resume state
|
|
4487
|
+
* destroys the association between the socket and the previous session,
|
|
4488
|
+
* which is what reattach depends on. That path mints a fresh credential and
|
|
4489
|
+
* reauthenticates instead (see `SignalWire.recoverAndRetry`).
|
|
4490
|
+
*
|
|
4491
|
+
* For public teardown (disconnect/destroy), use {@link teardownSessionState}
|
|
4492
|
+
* instead, which clears the attach records as well.
|
|
4259
4493
|
*/
|
|
4260
|
-
|
|
4494
|
+
private discardResumeStateAndReconnect;
|
|
4495
|
+
cleanupStoredConnectionParams(): Promise<void>;
|
|
4261
4496
|
/**
|
|
4262
|
-
*
|
|
4263
|
-
*
|
|
4264
|
-
*
|
|
4497
|
+
* Public-teardown helper for disconnect()/destroy(). Clears the resume
|
|
4498
|
+
* state (authorization_state + protocol) AND the attach records as one
|
|
4499
|
+
* atomic unit.
|
|
4500
|
+
*
|
|
4501
|
+
* The two stores are coupled: the backend only honors attach records
|
|
4502
|
+
* within the session identified by the resume state, so ending the
|
|
4503
|
+
* session must clear both. Clearing one without the other strands records
|
|
4504
|
+
* no future session can honor (disconnect) or revives a session the
|
|
4505
|
+
* developer explicitly ended (destroy).
|
|
4506
|
+
*
|
|
4507
|
+
* Distinct from {@link cleanupStoredConnectionParams}, which keeps the
|
|
4508
|
+
* attach records for the stale-auth-state recovery path.
|
|
4265
4509
|
*/
|
|
4266
|
-
|
|
4267
|
-
|
|
4510
|
+
teardownSessionState(): Promise<void>;
|
|
4511
|
+
protected updateAuthState(authorization_state: string): Promise<void>;
|
|
4512
|
+
reauthenticate(token: string, dpopToken?: string, options?: {
|
|
4513
|
+
clientBound?: boolean;
|
|
4514
|
+
}): Promise<void>;
|
|
4515
|
+
private authenticate;
|
|
4516
|
+
disconnect(): Promise<void>;
|
|
4517
|
+
private createInboundCall;
|
|
4268
4518
|
/**
|
|
4269
|
-
*
|
|
4270
|
-
*
|
|
4271
|
-
*
|
|
4272
|
-
*
|
|
4519
|
+
* Handle a server-pushed verto.attach event at the session level.
|
|
4520
|
+
*
|
|
4521
|
+
* On page reload the server detects the reconnected session and pushes
|
|
4522
|
+
* verto.attach for any active calls. If a call object already exists
|
|
4523
|
+
* (network blip, no reload), the per-call handler in VertoManager deals
|
|
4524
|
+
* with it. This method only creates a new call object when no existing
|
|
4525
|
+
* one matches the callID.
|
|
4273
4526
|
*/
|
|
4274
|
-
|
|
4527
|
+
private handleVertoAttach;
|
|
4528
|
+
createOutboundCall(destination: string | Address, options?: CallOptions): Promise<Call>;
|
|
4529
|
+
private createCall;
|
|
4530
|
+
destroy(): void;
|
|
4531
|
+
}
|
|
4532
|
+
declare class ClientSessionWrapper implements SessionState {
|
|
4533
|
+
private clientSessionManager;
|
|
4534
|
+
constructor(clientSessionManager: ClientSessionManager);
|
|
4535
|
+
get authenticated$(): Observable<boolean>;
|
|
4536
|
+
get authenticated(): boolean;
|
|
4275
4537
|
/**
|
|
4276
|
-
*
|
|
4277
|
-
*
|
|
4538
|
+
* Whether the session is using a Client Bound SAT (DPoP). Sticky — set
|
|
4539
|
+
* when the binding is established or restored from a resumed session's
|
|
4540
|
+
* server authorization.
|
|
4278
4541
|
*/
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4542
|
+
get clientBound(): boolean;
|
|
4543
|
+
get signalingEvent$(): Observable<(Omit<{
|
|
4544
|
+
event_type: "webrtc.message";
|
|
4545
|
+
event_channel: EventChannel;
|
|
4546
|
+
timestamp: number;
|
|
4547
|
+
project_id?: string;
|
|
4548
|
+
node_id?: string;
|
|
4549
|
+
is_author?: boolean;
|
|
4550
|
+
params: WebrtcMessagePayload;
|
|
4551
|
+
}, "event_channel" | "project_id" | "node_id"> & {
|
|
4552
|
+
event_channel: string;
|
|
4553
|
+
project_id: string;
|
|
4554
|
+
node_id: string;
|
|
4555
|
+
}) | {
|
|
4556
|
+
event_type: "signalwire.authorization.state";
|
|
4557
|
+
params: SignalwireAuthorizationStatePayload;
|
|
4558
|
+
} | (Omit<{
|
|
4559
|
+
event_type: "call.joined";
|
|
4560
|
+
event_channel: EventChannel;
|
|
4561
|
+
timestamp: number;
|
|
4562
|
+
project_id?: string;
|
|
4563
|
+
node_id?: string;
|
|
4564
|
+
is_author?: boolean;
|
|
4565
|
+
params: CallJoinedPayload;
|
|
4566
|
+
}, "event_channel"> & {
|
|
4567
|
+
event_channel: string;
|
|
4568
|
+
}) | (Omit<{
|
|
4569
|
+
event_type: "call.left";
|
|
4570
|
+
event_channel: EventChannel;
|
|
4571
|
+
timestamp: number;
|
|
4572
|
+
project_id?: string;
|
|
4573
|
+
node_id?: string;
|
|
4574
|
+
is_author?: boolean;
|
|
4575
|
+
params: CallLeftPayload;
|
|
4576
|
+
}, "event_channel"> & {
|
|
4577
|
+
event_channel: string;
|
|
4578
|
+
}) | (Omit<{
|
|
4579
|
+
event_type: "call.updated";
|
|
4580
|
+
event_channel: EventChannel;
|
|
4581
|
+
timestamp: number;
|
|
4582
|
+
project_id?: string;
|
|
4583
|
+
node_id?: string;
|
|
4584
|
+
is_author?: boolean;
|
|
4585
|
+
params: CallUpdatedPayload;
|
|
4586
|
+
}, "event_channel"> & {
|
|
4587
|
+
event_channel: string;
|
|
4588
|
+
}) | (Omit<{
|
|
4589
|
+
event_type: "call.state";
|
|
4590
|
+
event_channel: EventChannel;
|
|
4591
|
+
timestamp: number;
|
|
4592
|
+
project_id?: string;
|
|
4593
|
+
node_id?: string;
|
|
4594
|
+
is_author?: boolean;
|
|
4595
|
+
params: CallStatePayload;
|
|
4596
|
+
}, "event_channel"> & {
|
|
4597
|
+
event_channel: string;
|
|
4598
|
+
}) | (Omit<{
|
|
4599
|
+
event_type: "call.play";
|
|
4600
|
+
event_channel: EventChannel;
|
|
4601
|
+
timestamp: number;
|
|
4602
|
+
project_id?: string;
|
|
4603
|
+
node_id?: string;
|
|
4604
|
+
is_author?: boolean;
|
|
4605
|
+
params: CallPlayPayload;
|
|
4606
|
+
}, "event_channel"> & {
|
|
4607
|
+
event_channel: string;
|
|
4608
|
+
}) | (Omit<{
|
|
4609
|
+
event_type: "call.connect";
|
|
4610
|
+
event_channel: EventChannel;
|
|
4611
|
+
timestamp: number;
|
|
4612
|
+
project_id?: string;
|
|
4613
|
+
node_id?: string;
|
|
4614
|
+
is_author?: boolean;
|
|
4615
|
+
params: CallConnectPayload;
|
|
4616
|
+
}, "event_channel"> & {
|
|
4617
|
+
event_channel: string;
|
|
4618
|
+
}) | (Omit<{
|
|
4619
|
+
event_type: "room.updated";
|
|
4620
|
+
event_channel: EventChannel;
|
|
4621
|
+
timestamp: number;
|
|
4622
|
+
project_id?: string;
|
|
4623
|
+
node_id?: string;
|
|
4624
|
+
is_author?: boolean;
|
|
4625
|
+
params: RoomUpdatedPayload;
|
|
4626
|
+
}, "event_channel"> & {
|
|
4627
|
+
event_channel: string;
|
|
4628
|
+
}) | Omit<{
|
|
4629
|
+
event_type: "member.updated";
|
|
4630
|
+
event_channel: EventChannel;
|
|
4631
|
+
timestamp: number;
|
|
4632
|
+
project_id?: string;
|
|
4633
|
+
node_id?: string;
|
|
4634
|
+
is_author?: boolean;
|
|
4635
|
+
params: MemberUpdatedPayload;
|
|
4636
|
+
}, never> | Omit<{
|
|
4637
|
+
event_type: "member.joined";
|
|
4638
|
+
event_channel: EventChannel;
|
|
4639
|
+
timestamp: number;
|
|
4640
|
+
project_id?: string;
|
|
4641
|
+
node_id?: string;
|
|
4642
|
+
is_author?: boolean;
|
|
4643
|
+
params: MemberJoinedPayload;
|
|
4644
|
+
}, never> | Omit<{
|
|
4645
|
+
event_type: "member.left";
|
|
4646
|
+
event_channel: EventChannel;
|
|
4647
|
+
timestamp: number;
|
|
4648
|
+
project_id?: string;
|
|
4649
|
+
node_id?: string;
|
|
4650
|
+
is_author?: boolean;
|
|
4651
|
+
params: MemberLeftPayload;
|
|
4652
|
+
}, never> | Omit<{
|
|
4653
|
+
event_type: "member.talking";
|
|
4654
|
+
event_channel: EventChannel;
|
|
4655
|
+
timestamp: number;
|
|
4656
|
+
project_id?: string;
|
|
4657
|
+
node_id?: string;
|
|
4658
|
+
is_author?: boolean;
|
|
4659
|
+
params: MemberTalkingPayload;
|
|
4660
|
+
}, never> | Omit<{
|
|
4661
|
+
event_type: "layout.changed";
|
|
4662
|
+
event_channel: EventChannel;
|
|
4663
|
+
timestamp: number;
|
|
4664
|
+
project_id?: string;
|
|
4665
|
+
node_id?: string;
|
|
4666
|
+
is_author?: boolean;
|
|
4667
|
+
params: LayoutChangedPayload;
|
|
4668
|
+
}, never> | (Omit<{
|
|
4669
|
+
event_type: "conversation.message";
|
|
4670
|
+
event_channel: EventChannel;
|
|
4671
|
+
timestamp: number;
|
|
4672
|
+
project_id?: string;
|
|
4673
|
+
node_id?: string;
|
|
4674
|
+
is_author?: boolean;
|
|
4675
|
+
params: ConversationMessagePayload;
|
|
4676
|
+
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
4677
|
+
event_channel: string;
|
|
4678
|
+
timestamp: string;
|
|
4679
|
+
is_author: boolean;
|
|
4680
|
+
}) | (Omit<{
|
|
4681
|
+
event_type: "conversation.message.updated";
|
|
4682
|
+
event_channel: EventChannel;
|
|
4683
|
+
timestamp: number;
|
|
4684
|
+
project_id?: string;
|
|
4685
|
+
node_id?: string;
|
|
4686
|
+
is_author?: boolean;
|
|
4687
|
+
params: ConversationMessagePayload;
|
|
4688
|
+
}, "event_channel" | "timestamp" | "is_author"> & {
|
|
4689
|
+
event_channel: string;
|
|
4690
|
+
timestamp: string;
|
|
4691
|
+
is_author: boolean;
|
|
4692
|
+
})>;
|
|
4693
|
+
get iceServers(): RTCIceServer[] | undefined;
|
|
4694
|
+
get callControl(): 'routed' | 'in-dialog';
|
|
4695
|
+
execute<T extends JSONRPCResponse = JSONRPCResponse>(request: JSONRPCRequest, options?: PendingRPCOptions): Promise<T>;
|
|
4696
|
+
get incomingCalls$(): Observable<Call[]>;
|
|
4697
|
+
get incomingCalls(): Call[];
|
|
4698
|
+
get calls$(): Observable<Call[]>;
|
|
4699
|
+
get calls(): Call[];
|
|
4287
4700
|
}
|
|
4288
4701
|
//#endregion
|
|
4289
|
-
//#region src/
|
|
4702
|
+
//#region src/core/types/warnings.types.d.ts
|
|
4290
4703
|
/**
|
|
4291
|
-
*
|
|
4292
|
-
*
|
|
4704
|
+
* Non-fatal warning emitted via {@link SignalWire.warnings$ | client.warnings$}.
|
|
4705
|
+
*
|
|
4706
|
+
* Use to detect SDK behaviors that affect session liveness or developer-facing
|
|
4707
|
+
* contracts but do not warrant disconnection. Discriminated by `code`.
|
|
4708
|
+
*
|
|
4709
|
+
* Existing consumers of `errors$` are NOT notified — `warnings$` is a separate
|
|
4710
|
+
* channel so application code can react to warnings without triggering
|
|
4711
|
+
* error-handling code paths (e.g., disconnect cascades, user-facing toasts).
|
|
4293
4712
|
*/
|
|
4294
|
-
|
|
4295
|
-
|
|
4296
|
-
|
|
4297
|
-
|
|
4298
|
-
|
|
4299
|
-
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
|
|
4310
|
-
|
|
4311
|
-
|
|
4312
|
-
|
|
4313
|
-
|
|
4314
|
-
|
|
4315
|
-
|
|
4316
|
-
|
|
4317
|
-
|
|
4318
|
-
|
|
4319
|
-
|
|
4320
|
-
|
|
4321
|
-
/** Lazily create (or return) the local audio pipeline for the main peer connection. */
|
|
4322
|
-
ensureLocalAudioPipeline(): LocalAudioPipeline | null;
|
|
4323
|
-
/** Current local audio pipeline, or null if it has not been created yet. */
|
|
4324
|
-
readonly localAudioPipeline: LocalAudioPipeline | null;
|
|
4325
|
-
}
|
|
4326
|
-
//#endregion
|
|
4327
|
-
//#region src/managers/CallEventsManager.d.ts
|
|
4328
|
-
interface WebRTCCallEventManagerOptions {}
|
|
4329
|
-
/** @internal */
|
|
4330
|
-
declare class CallEventsManager extends Destroyable {
|
|
4331
|
-
protected webRtcCallSession: CallManager;
|
|
4332
|
-
protected options: WebRTCCallEventManagerOptions;
|
|
4333
|
-
private selfId?;
|
|
4334
|
-
private originCallId?;
|
|
4335
|
-
private callIds;
|
|
4336
|
-
private roomSessionIds;
|
|
4337
|
-
private _participants$;
|
|
4338
|
-
private _self$;
|
|
4339
|
-
private _sessionState$;
|
|
4340
|
-
constructor(webRtcCallSession: CallManager, options?: WebRTCCallEventManagerOptions);
|
|
4341
|
-
get participants$(): Observable<CallParticipant[]>;
|
|
4342
|
-
get participants(): CallParticipant[];
|
|
4343
|
-
get self$(): Observable<CallSelfParticipant>;
|
|
4344
|
-
isRoomSessionIdValid(roomSessionId: string): boolean;
|
|
4345
|
-
addCallId(callId: string): void;
|
|
4346
|
-
isCallIdValid(callId: string): boolean;
|
|
4347
|
-
get recording$(): Observable<boolean>;
|
|
4348
|
-
get recordings$(): Observable<Record<string, unknown>[]>;
|
|
4349
|
-
get streaming$(): Observable<boolean>;
|
|
4350
|
-
get streams$(): Observable<Record<string, unknown>[]>;
|
|
4351
|
-
get playbacks$(): Observable<Record<string, unknown>[]>;
|
|
4352
|
-
get raiseHandPriority$(): Observable<boolean>;
|
|
4353
|
-
get locked$(): Observable<boolean>;
|
|
4354
|
-
get meta$(): Observable<Record<string, unknown>>;
|
|
4355
|
-
get capabilities$(): Observable<Capability[]>;
|
|
4356
|
-
get layout$(): Observable<string>;
|
|
4357
|
-
get layouts$(): Observable<string[]>;
|
|
4358
|
-
get layoutLayers$(): Observable<LayoutLayer[]>;
|
|
4359
|
-
get self(): CallSelfParticipant | null;
|
|
4360
|
-
get layoutLayers(): LayoutLayer[];
|
|
4361
|
-
get recording(): boolean;
|
|
4362
|
-
get streaming(): boolean;
|
|
4363
|
-
get raiseHandPriority(): boolean;
|
|
4364
|
-
get locked(): boolean;
|
|
4365
|
-
get meta(): Record<string, unknown>;
|
|
4366
|
-
get layout(): string | undefined;
|
|
4367
|
-
get layouts(): string[];
|
|
4368
|
-
get capabilities(): Capability[];
|
|
4369
|
-
isSessionEvent(id: string): boolean;
|
|
4370
|
-
protected initSubscriptions(): void;
|
|
4371
|
-
private updateParticipantPositions;
|
|
4372
|
-
updateLayouts(): void;
|
|
4373
|
-
private updateParticipants;
|
|
4374
|
-
private upsertParticipant;
|
|
4375
|
-
private get callJoinedEvent$();
|
|
4376
|
-
private get layoutChangedEvent$();
|
|
4377
|
-
private get memberUpdates$();
|
|
4378
|
-
destroy(): void;
|
|
4379
|
-
}
|
|
4380
|
-
//#endregion
|
|
4381
|
-
//#region src/managers/CallRecoveryManager.d.ts
|
|
4382
|
-
type RecoveryState$1 = 'idle' | 'debouncing' | 'recovering' | 'cooldown';
|
|
4383
|
-
interface RecoveryEvent$1 {
|
|
4384
|
-
action: 'keyframe_requested' | 'reinvite_started' | 'reinvite_succeeded' | 'reinvite_failed' | 'reinvite_timeout' | 'max_attempts_reached' | 'signal_reconnect' | 'full_reconnect' | 'video_disabled' | 'video_restored';
|
|
4385
|
-
reason: string;
|
|
4386
|
-
attempt?: number;
|
|
4387
|
-
maxAttempts?: number;
|
|
4388
|
-
timestamp: number;
|
|
4713
|
+
type SDKWarning = CredentialRefreshFallbackWarning | CredentialNoRefreshHandlerWarning;
|
|
4714
|
+
/**
|
|
4715
|
+
* Diagnostic detail for {@link CredentialRefreshFallbackWarning}. Stable
|
|
4716
|
+
* values, but treat unknown strings as "fell back for an unspecified cause" —
|
|
4717
|
+
* do not branch on this value for control flow. New values may be added in
|
|
4718
|
+
* future releases.
|
|
4719
|
+
*/
|
|
4720
|
+
type CredentialRefreshFallbackReason = 'no-scope' | 'no-dpop-support' | 'endpoint-failed' | 'activation-timeout' | (string & {});
|
|
4721
|
+
/**
|
|
4722
|
+
* Emitted when the SDK falls back to the developer-provided
|
|
4723
|
+
* {@link CredentialProvider.refresh} because the Client Bound SAT path
|
|
4724
|
+
* could not take over.
|
|
4725
|
+
*
|
|
4726
|
+
* Common causes:
|
|
4727
|
+
* - The minted SAT lacks `sat:refresh` scope (`reason: 'no-scope'`).
|
|
4728
|
+
* - The `/devices/token` exchange failed transiently (`reason: 'endpoint-failed'`).
|
|
4729
|
+
*
|
|
4730
|
+
* Subscribe to this warning to detect:
|
|
4731
|
+
* - SDKs running with plain SATs that rely on developer-managed refresh
|
|
4732
|
+
* - Deployments expected to use bound tokens that silently downgraded to bearer
|
|
4733
|
+
* (a security-relevant signal for fleet observability)
|
|
4734
|
+
*/
|
|
4735
|
+
interface CredentialRefreshFallbackWarning {
|
|
4736
|
+
code: 'credential_refresh_fallback';
|
|
4737
|
+
source: 'CredentialProvider';
|
|
4738
|
+
reason: CredentialRefreshFallbackReason;
|
|
4739
|
+
message: string;
|
|
4389
4740
|
}
|
|
4390
|
-
//#endregion
|
|
4391
|
-
//#region src/utils/qualityScore.d.ts
|
|
4392
4741
|
/**
|
|
4393
|
-
*
|
|
4394
|
-
*
|
|
4742
|
+
* Emitted when a credential has an `expiry_at` but the provider supplies no
|
|
4743
|
+
* `refresh()` handler. The session will terminate at expiry with no fallback.
|
|
4395
4744
|
*
|
|
4396
|
-
*
|
|
4397
|
-
*
|
|
4398
|
-
* jitter and packet-loss values.
|
|
4745
|
+
* Implementors who want long-lived sessions must provide a `refresh()` handler
|
|
4746
|
+
* or mint tokens with the `sat:refresh` scope (Client Bound SAT path).
|
|
4399
4747
|
*/
|
|
4400
|
-
|
|
4748
|
+
interface CredentialNoRefreshHandlerWarning {
|
|
4749
|
+
code: 'credential_no_refresh_handler';
|
|
4750
|
+
source: 'CredentialProvider';
|
|
4751
|
+
message: string;
|
|
4752
|
+
/** Token expiry timestamp (epoch milliseconds). */
|
|
4753
|
+
expiresAt: number;
|
|
4754
|
+
}
|
|
4401
4755
|
//#endregion
|
|
4402
|
-
//#region src/
|
|
4756
|
+
//#region src/utils/logger.d.ts
|
|
4757
|
+
/** Log level names supported by the SDK. */
|
|
4758
|
+
type LogLevel = 'trace' | 'debug' | 'info' | 'warn' | 'error' | 'silent';
|
|
4403
4759
|
/**
|
|
4404
|
-
*
|
|
4760
|
+
* Logger interface that consumers can implement to replace the built-in logger.
|
|
4761
|
+
* All methods accept variadic arguments matching the browser console API.
|
|
4405
4762
|
*/
|
|
4406
|
-
interface
|
|
4407
|
-
|
|
4408
|
-
|
|
4763
|
+
interface SDKLogger {
|
|
4764
|
+
error(...args: unknown[]): void;
|
|
4765
|
+
warn(...args: unknown[]): void;
|
|
4766
|
+
info(...args: unknown[]): void;
|
|
4767
|
+
debug(...args: unknown[]): void;
|
|
4768
|
+
trace(...args: unknown[]): void;
|
|
4769
|
+
}
|
|
4770
|
+
/** Options for WebSocket traffic logging. */
|
|
4771
|
+
interface WsTrafficOptions {
|
|
4772
|
+
type: 'send' | 'recv' | 'http';
|
|
4773
|
+
/** Parsed object or raw string — will be JSON.stringify'd for display if an object. */
|
|
4774
|
+
payload: unknown;
|
|
4409
4775
|
}
|
|
4410
4776
|
/**
|
|
4411
|
-
*
|
|
4412
|
-
*
|
|
4413
|
-
*
|
|
4777
|
+
* Options for WebSocket traffic logging using raw strings.
|
|
4778
|
+
* The string is only parsed when logging is enabled, avoiding
|
|
4779
|
+
* unnecessary JSON.parse on every message.
|
|
4414
4780
|
*/
|
|
4415
|
-
|
|
4781
|
+
interface WsTrafficRawOptions {
|
|
4782
|
+
type: 'send' | 'recv';
|
|
4783
|
+
raw: string;
|
|
4784
|
+
}
|
|
4785
|
+
/** Debug options that control verbose SDK logging. */
|
|
4786
|
+
interface DebugOptions {
|
|
4787
|
+
/** Log all WebSocket send/recv traffic to the console. */
|
|
4788
|
+
logWsTraffic?: boolean;
|
|
4789
|
+
}
|
|
4790
|
+
/** Extended logger with SDK-internal helpers (wsTraffic). */
|
|
4791
|
+
interface InternalSDKLogger extends SDKLogger {
|
|
4792
|
+
wsTraffic: (options: WsTrafficOptions | WsTrafficRawOptions) => void;
|
|
4793
|
+
}
|
|
4794
|
+
/** Replace the built-in logger with a custom implementation. Pass `null` to restore defaults. */
|
|
4795
|
+
declare const setLogger: (logger: SDKLogger | null) => void;
|
|
4796
|
+
/** Configure debug options (e.g., `{ logWsTraffic: true }`). */
|
|
4797
|
+
declare const setDebugOptions: (options: DebugOptions | null) => void;
|
|
4416
4798
|
/**
|
|
4417
|
-
*
|
|
4418
|
-
*
|
|
4799
|
+
* Set the log level for the built-in logger.
|
|
4800
|
+
* Has no effect when a custom logger is set via `setLogger()`.
|
|
4419
4801
|
*/
|
|
4420
|
-
|
|
4802
|
+
declare const setLogLevel: (level: LogLevel) => void;
|
|
4803
|
+
declare const getLogger: () => InternalSDKLogger;
|
|
4804
|
+
//#endregion
|
|
4805
|
+
//#region src/clients/SignalWire.d.ts
|
|
4806
|
+
/** Options for constructing a {@link SignalWire}. */
|
|
4807
|
+
interface SignalWireOptions {
|
|
4808
|
+
/** Skip automatic WebSocket connection on construction. */
|
|
4809
|
+
skipConnection?: boolean;
|
|
4810
|
+
/** Skip automatic user registration on construction. */
|
|
4811
|
+
skipRegister?: boolean;
|
|
4812
|
+
/** Skip monitoring media device changes. */
|
|
4813
|
+
skipDeviceMonitoring?: boolean;
|
|
4814
|
+
/** Whether to reconnect to previously attached calls. */
|
|
4815
|
+
reconnectAttachedCalls?: boolean;
|
|
4816
|
+
/** Whether to save preferences. */
|
|
4817
|
+
savePreferences?: boolean;
|
|
4818
|
+
/**
|
|
4819
|
+
* Persist the session across page reloads.
|
|
4820
|
+
*
|
|
4821
|
+
* When `true`, credential, authorization state, and protocol are stored in
|
|
4822
|
+
* `localStorage` (survives reload). The DPoP key pair is persisted in
|
|
4823
|
+
* IndexedDB. On reload, the SDK restores the session from cache
|
|
4824
|
+
* without calling `credentialProvider.authenticate()`.
|
|
4825
|
+
*
|
|
4826
|
+
* When `false` (default), session data lives in `sessionStorage` and is
|
|
4827
|
+
* lost on reload.
|
|
4828
|
+
*
|
|
4829
|
+
* Both {@link SignalWire.disconnect | disconnect()} and
|
|
4830
|
+
* {@link SignalWire.destroy | destroy()} end the session and clear the
|
|
4831
|
+
* persisted resume state and attach records; credentials and device
|
|
4832
|
+
* preferences survive. Use `resetToDefaults()` for a full wipe, or
|
|
4833
|
+
* `unregister()` to temporarily stop receiving inbound calls while keeping
|
|
4834
|
+
* the session alive.
|
|
4835
|
+
*/
|
|
4836
|
+
persistSession?: boolean;
|
|
4837
|
+
/** Custom storage implementation for persistence. */
|
|
4838
|
+
storageImplementation?: Storage;
|
|
4839
|
+
/** Custom WebSocket constructor */
|
|
4840
|
+
webSocketConstructor?: WebSocketAdapter | NodeSocketAdapter;
|
|
4841
|
+
/** Custom WebRTC API provider */
|
|
4842
|
+
webRTCApiProvider?: WebRTCApiProvider;
|
|
4421
4843
|
/**
|
|
4422
|
-
*
|
|
4844
|
+
* Custom logger implementation. Must implement the {@link SDKLogger} interface.
|
|
4845
|
+
* Pass `null` to restore the built-in logger.
|
|
4846
|
+
*
|
|
4847
|
+
* **Note:** Logger configuration is global — setting it on one instance affects all instances.
|
|
4423
4848
|
*/
|
|
4424
|
-
|
|
4849
|
+
logger?: SDKLogger | null;
|
|
4425
4850
|
/**
|
|
4426
|
-
*
|
|
4851
|
+
* Log level for the built-in logger.
|
|
4852
|
+
* Default: `'warn'`. Set to `'debug'` for verbose SDK output.
|
|
4853
|
+
* Has no effect when a custom `logger` is provided.
|
|
4854
|
+
*
|
|
4855
|
+
* **Note:** Logger configuration is global — setting it on one instance affects all instances.
|
|
4427
4856
|
*/
|
|
4428
|
-
|
|
4857
|
+
logLevel?: LogLevel;
|
|
4858
|
+
/** Debug options for verbose SDK diagnostics (e.g., `{ logWsTraffic: true }`). */
|
|
4859
|
+
debug?: DebugOptions;
|
|
4429
4860
|
/**
|
|
4430
|
-
*
|
|
4861
|
+
* Control transport for `call.*` verbs across ALL calls in this session:
|
|
4862
|
+
* - `'routed'` (default) sends them on the client's session channel.
|
|
4863
|
+
* - `'in-dialog'` carries them on each call's own signaling channel via `verto.info`,
|
|
4864
|
+
* so control works without the client needing to know how the conference is hosted.
|
|
4865
|
+
*
|
|
4866
|
+
* `'in-dialog'` is opt-in because it does not reach everywhere `'routed'` does: use it
|
|
4867
|
+
* only for calls that join a conference over SWML (e.g. an SWML `join_conference`).
|
|
4868
|
+
*
|
|
4869
|
+
* It is a client-wide setting rather than per-`dial()` because the SDK issues some
|
|
4870
|
+
* control RPCs itself (fetching the layout list on join, for example), and those must
|
|
4871
|
+
* travel the same way as the app's own, or reads and writes land on different transports.
|
|
4872
|
+
*
|
|
4873
|
+
* @experimental A rollout switch, not a long-term part of the API. Expected to
|
|
4874
|
+
* disappear once `'in-dialog'` becomes the only transport, so it carries no semver
|
|
4875
|
+
* promise and application code should not depend on it.
|
|
4431
4876
|
*/
|
|
4432
|
-
|
|
4877
|
+
callControl?: 'routed' | 'in-dialog';
|
|
4878
|
+
}
|
|
4879
|
+
/** Options for {@link SignalWire.dial}. Extends {@link MediaOptions} with dial-specific settings. */
|
|
4880
|
+
interface DialOptions extends MediaOptions {
|
|
4881
|
+
/** Preferred video codecs for this call (overrides global preferences). */
|
|
4882
|
+
preferredVideoCodecs?: string[];
|
|
4883
|
+
/** Preferred audio codecs for this call (overrides global preferences). */
|
|
4884
|
+
preferredAudioCodecs?: string[];
|
|
4885
|
+
/** Enable stereo Opus for this call (overrides global preferences). */
|
|
4886
|
+
stereo?: boolean;
|
|
4887
|
+
/** Optional node ID for routing the call */
|
|
4888
|
+
nodeId?: string;
|
|
4889
|
+
/**
|
|
4890
|
+
* Custom variables sent with the Verto invite. Merged with
|
|
4891
|
+
* `client.preferences.userVariables` and any query-string variables on the
|
|
4892
|
+
* destination URI; values here take precedence.
|
|
4893
|
+
*/
|
|
4894
|
+
userVariables?: Record<string, unknown>;
|
|
4433
4895
|
}
|
|
4434
4896
|
/**
|
|
4435
|
-
*
|
|
4897
|
+
* Main entry point for the SignalWire Browser SDK.
|
|
4436
4898
|
*
|
|
4437
|
-
* Manages
|
|
4438
|
-
*
|
|
4439
|
-
*
|
|
4899
|
+
* Manages authentication, WebSocket transport, call creation, and media devices.
|
|
4900
|
+
*
|
|
4901
|
+
* @example
|
|
4902
|
+
* ```ts
|
|
4903
|
+
* const client = new SignalWire(credentialProvider);
|
|
4904
|
+
* client.isConnected$.subscribe(connected => console.log('Connected:', connected));
|
|
4905
|
+
* const call = await client.dial('/public/my-room');
|
|
4906
|
+
* ```
|
|
4440
4907
|
*/
|
|
4441
|
-
declare class
|
|
4442
|
-
|
|
4443
|
-
|
|
4444
|
-
|
|
4445
|
-
|
|
4446
|
-
|
|
4447
|
-
|
|
4448
|
-
|
|
4449
|
-
private
|
|
4450
|
-
private
|
|
4451
|
-
private participantFactory;
|
|
4452
|
-
private _errors$;
|
|
4453
|
-
private _status$;
|
|
4454
|
-
private _lastMergedStatus;
|
|
4455
|
-
private _answered$;
|
|
4456
|
-
private _answerMediaOptions?;
|
|
4457
|
-
private _holdState;
|
|
4458
|
-
private _userVariables$;
|
|
4459
|
-
private _statsMonitor?;
|
|
4460
|
-
private _recoveryManager?;
|
|
4461
|
-
private _networkChange$?;
|
|
4462
|
-
private _networkIssues$;
|
|
4463
|
-
private _networkMetrics$;
|
|
4464
|
-
private _isNetworkHealthy$;
|
|
4465
|
-
private _qualityScore$;
|
|
4466
|
-
private _qualityLevel$;
|
|
4467
|
-
private _recoveryState$;
|
|
4468
|
-
private _recoveryEvent$;
|
|
4469
|
-
private _bandwidthConstrained$;
|
|
4470
|
-
private _mediaParamsUpdated$;
|
|
4471
|
-
private _customSubscriptions;
|
|
4472
|
-
private _pushToTalkEnabled;
|
|
4473
|
-
private _remoteAudioMeter;
|
|
4474
|
-
constructor(clientSession: ClientSession, options: CallOptions, initialization: CallInitialization, address?: Address | undefined);
|
|
4475
|
-
/** Observable stream of errors from media, signaling, and peer connection layers. */
|
|
4476
|
-
get errors$(): Observable<CallError>;
|
|
4908
|
+
declare class SignalWire extends Destroyable implements DeviceController {
|
|
4909
|
+
/** Global SDK preferences (timeouts, ICE config, media defaults). */
|
|
4910
|
+
preferences: ClientPreferences;
|
|
4911
|
+
private _user$;
|
|
4912
|
+
private _directory$;
|
|
4913
|
+
private _transport;
|
|
4914
|
+
private _clientSession;
|
|
4915
|
+
private _publicSession;
|
|
4916
|
+
private _deviceController;
|
|
4917
|
+
private _attachManager?;
|
|
4477
4918
|
/**
|
|
4478
|
-
*
|
|
4479
|
-
*
|
|
4919
|
+
* Set once a credential recovery has been *verified* — reauthenticated and
|
|
4920
|
+
* then proven by the operation it was meant to unblock. Read by the attach
|
|
4921
|
+
* path, which may only discard an attach record when a reattach is refused
|
|
4922
|
+
* on a credential the server has already accepted.
|
|
4480
4923
|
*/
|
|
4481
|
-
|
|
4482
|
-
|
|
4483
|
-
|
|
4484
|
-
|
|
4485
|
-
|
|
4486
|
-
|
|
4487
|
-
|
|
4488
|
-
|
|
4489
|
-
|
|
4490
|
-
|
|
4491
|
-
|
|
4492
|
-
|
|
4493
|
-
|
|
4494
|
-
|
|
4495
|
-
|
|
4496
|
-
|
|
4497
|
-
|
|
4498
|
-
|
|
4499
|
-
addCallId(callId: string): void;
|
|
4500
|
-
/** List of capabilities available in the current call. */
|
|
4501
|
-
get capabilities(): Capability[];
|
|
4502
|
-
/** Current snapshot of all participants in the call. */
|
|
4503
|
-
get participants(): CallParticipant[];
|
|
4504
|
-
/** The local participant, or `null` if not yet joined. */
|
|
4505
|
-
get self(): CallSelfParticipant | null;
|
|
4506
|
-
/** Toggles the call lock state, preventing or allowing new participants from joining. */
|
|
4507
|
-
toggleLock(): Promise<void>;
|
|
4924
|
+
private _credentialRecovered;
|
|
4925
|
+
private _isConnected$;
|
|
4926
|
+
private _isRegistered$;
|
|
4927
|
+
private _errors$;
|
|
4928
|
+
private _warnings$;
|
|
4929
|
+
private _options;
|
|
4930
|
+
private _dpopManager?;
|
|
4931
|
+
private _refreshCoordinator?;
|
|
4932
|
+
/** The refresh path's own HTTP controller — see resolveCredentials. */
|
|
4933
|
+
private _refreshHttp?;
|
|
4934
|
+
/** Host `_refreshHttp` was built against, so it can be rebuilt when the token's `ch` changes. */
|
|
4935
|
+
private _refreshHttpHost?;
|
|
4936
|
+
private _credentialProvider?;
|
|
4937
|
+
private _deps;
|
|
4938
|
+
private _networkMonitor?;
|
|
4939
|
+
private _visibilityController?;
|
|
4940
|
+
private _diagnosticsCollector?;
|
|
4941
|
+
private _platformCapabilities?;
|
|
4508
4942
|
/**
|
|
4509
|
-
*
|
|
4943
|
+
* Creates a new SignalWire client and begins connecting.
|
|
4510
4944
|
*
|
|
4511
|
-
*
|
|
4945
|
+
* @param credentialProvider - Provider that supplies authentication credentials.
|
|
4946
|
+
* @param options - Configuration options (connection, device monitoring, preferences).
|
|
4512
4947
|
*/
|
|
4513
|
-
|
|
4514
|
-
/** @throws {UnimplementedError} Not yet implemented. Status tracked via {@link recording$}. */
|
|
4515
|
-
startRecording(): Promise<void>;
|
|
4516
|
-
/** @throws {UnimplementedError} Not yet implemented. Status tracked via {@link streaming$}. */
|
|
4517
|
-
startStreaming(): Promise<void>;
|
|
4948
|
+
constructor(credentialProvider: CredentialProvider | undefined, options?: SignalWireOptions);
|
|
4518
4949
|
/**
|
|
4519
|
-
*
|
|
4520
|
-
*
|
|
4521
|
-
*
|
|
4950
|
+
* Build the refresh path's own HTTP controller, against whatever host is current.
|
|
4951
|
+
*
|
|
4952
|
+
* Called on first use rather than up front, so `apiHost` already reflects the
|
|
4953
|
+
* token's `ch` claim. Same credential source as the container's controller — only
|
|
4954
|
+
* the instance, and therefore its observable streams, is separate.
|
|
4522
4955
|
*/
|
|
4523
|
-
|
|
4956
|
+
private createRefreshHttpController;
|
|
4524
4957
|
/**
|
|
4525
|
-
*
|
|
4526
|
-
* @param _meta - Metadata to merge.
|
|
4527
|
-
* @throws {UnimplementedError} Not yet implemented.
|
|
4958
|
+
* Initializes DPoP if not already set up. Returns the fingerprint on success.
|
|
4528
4959
|
*/
|
|
4529
|
-
|
|
4530
|
-
/** Observable of layout layer positions for all participants. */
|
|
4531
|
-
get layoutLayers$(): Observable<LayoutLayer[]>;
|
|
4532
|
-
/** Current snapshot of layout layers. */
|
|
4533
|
-
get layoutLayers(): LayoutLayer[];
|
|
4960
|
+
private initDPoP;
|
|
4534
4961
|
/**
|
|
4535
|
-
*
|
|
4536
|
-
*
|
|
4537
|
-
* Constructs call context (node_id, call_id, member_id) and sends the RPC request.
|
|
4962
|
+
* Resolves credentials using cache-first strategy when persistSession is enabled.
|
|
4538
4963
|
*
|
|
4539
|
-
*
|
|
4540
|
-
*
|
|
4541
|
-
*
|
|
4542
|
-
*
|
|
4543
|
-
* @throws {JSONRPCError} If the RPC call returns an error.
|
|
4964
|
+
* 1. If persistSession → check localStorage for cached credential
|
|
4965
|
+
* 2. If cached and not expired → use it (skip provider.authenticate())
|
|
4966
|
+
* 3. If no cache or expired → call provider.authenticate()
|
|
4967
|
+
* 4. If no provider AND no cache → throw
|
|
4544
4968
|
*/
|
|
4545
|
-
|
|
4546
|
-
private
|
|
4547
|
-
/** Observable of the current call status (e.g. `'ringing'`, `'connected'`). */
|
|
4548
|
-
get status$(): Observable<CallStatus>;
|
|
4549
|
-
/** Observable of the participants list, emits on join/leave/update. */
|
|
4550
|
-
get participants$(): Observable<CallParticipant[]>;
|
|
4551
|
-
/** Observable of the local (self) participant. */
|
|
4552
|
-
get self$(): Observable<CallSelfParticipant>;
|
|
4553
|
-
/** Observable indicating whether the call is being recorded. */
|
|
4554
|
-
get recording$(): Observable<boolean>;
|
|
4555
|
-
/** Observable indicating whether the call is being streamed. */
|
|
4556
|
-
get streaming$(): Observable<boolean>;
|
|
4557
|
-
/** Observable indicating whether raise-hand priority is active. */
|
|
4558
|
-
get raiseHandPriority$(): Observable<boolean>;
|
|
4559
|
-
/** Observable indicating whether the call room is locked. */
|
|
4560
|
-
get locked$(): Observable<boolean>;
|
|
4561
|
-
/** Observable of custom metadata associated with the call. */
|
|
4562
|
-
get meta$(): Observable<Record<string, unknown>>;
|
|
4563
|
-
/** Observable of the call's capability flags. */
|
|
4564
|
-
get capabilities$(): Observable<Capability[]>;
|
|
4565
|
-
/** Observable of the current layout name. */
|
|
4566
|
-
get layout$(): Observable<string>;
|
|
4567
|
-
/** Current call status. */
|
|
4568
|
-
get status(): CallStatus;
|
|
4569
|
-
/** Whether the call is currently being recorded. */
|
|
4570
|
-
get recording(): boolean;
|
|
4571
|
-
/** Whether the call is currently being streamed. */
|
|
4572
|
-
get streaming(): boolean;
|
|
4573
|
-
/** Whether raise-hand priority is active. */
|
|
4574
|
-
get raiseHandPriority(): boolean;
|
|
4575
|
-
/** Whether the call room is locked. */
|
|
4576
|
-
get locked(): boolean;
|
|
4577
|
-
/** Current custom metadata of the call. */
|
|
4578
|
-
get meta(): Record<string, unknown>;
|
|
4579
|
-
/** Current layout name, or `undefined` if not set. */
|
|
4580
|
-
get layout(): string | undefined;
|
|
4581
|
-
/** Observable of available layout names. */
|
|
4582
|
-
get layouts$(): Observable<string[]>;
|
|
4583
|
-
/** Current snapshot of available layout names. */
|
|
4584
|
-
get layouts(): string[];
|
|
4585
|
-
/** Observable of the local media stream (camera/microphone). */
|
|
4586
|
-
get localStream$(): Observable<MediaStream>;
|
|
4587
|
-
/** Current local media stream, or `null` if not available. */
|
|
4588
|
-
get localStream(): MediaStream | null;
|
|
4589
|
-
/** Observable of the remote media stream from the far end. */
|
|
4590
|
-
get remoteStream$(): Observable<MediaStream>;
|
|
4591
|
-
/** Current remote media stream, or `null` if not available. */
|
|
4592
|
-
get remoteStream(): MediaStream | null;
|
|
4593
|
-
/** Observable of custom user variables associated with the call. */
|
|
4594
|
-
get userVariables$(): Observable<Record<string, unknown>>;
|
|
4595
|
-
/** a copy of the current custom user variables of the call. */
|
|
4596
|
-
get userVariables(): Record<string, unknown>;
|
|
4597
|
-
/** Merge current custom user variables of the call. */
|
|
4598
|
-
set userVariables(variables: Record<string, unknown>);
|
|
4599
|
-
/** Observable of current network health issues (empty array = healthy). */
|
|
4600
|
-
get networkIssues$(): Observable<NetworkIssue[]>;
|
|
4601
|
-
/** Current snapshot of network issues. */
|
|
4602
|
-
get networkIssues(): NetworkIssue[];
|
|
4603
|
-
/** Simple boolean health indicator derived from stats monitor. */
|
|
4604
|
-
get isNetworkHealthy$(): Observable<boolean>;
|
|
4605
|
-
/** Whether the network is currently healthy. */
|
|
4606
|
-
get isNetworkHealthy(): boolean;
|
|
4607
|
-
/** Rolling history of raw network metrics (RTT, jitter, packet loss, bitrate). */
|
|
4608
|
-
get networkMetrics$(): Observable<NetworkMetrics[]>;
|
|
4609
|
-
/** Current snapshot of the metrics rolling window. */
|
|
4610
|
-
get networkMetrics(): NetworkMetrics[];
|
|
4611
|
-
/** Observable of MOS quality score (1-5) computed from stats metrics. */
|
|
4612
|
-
get qualityScore$(): Observable<number>;
|
|
4613
|
-
/** Observable of simplified quality level (excellent/good/fair/poor/critical). */
|
|
4614
|
-
get qualityLevel$(): Observable<QualityLevel$1>;
|
|
4615
|
-
/** Observable of the recovery pipeline state machine. */
|
|
4616
|
-
get recoveryState$(): Observable<RecoveryState$1>;
|
|
4617
|
-
/** Observable of recovery events (keyframe requested, ICE restart, etc.). */
|
|
4618
|
-
get recoveryEvent$(): Observable<RecoveryEvent$1>;
|
|
4619
|
-
/** Observable indicating whether the call is bandwidth-constrained. */
|
|
4620
|
-
get bandwidthConstrained$(): Observable<boolean>;
|
|
4621
|
-
/** Observable that emits when server-pushed media params are applied. */
|
|
4622
|
-
get mediaParamsUpdated$(): Observable<MediaParamsEvent>;
|
|
4969
|
+
private resolveCredentials;
|
|
4970
|
+
private validateCredentials;
|
|
4623
4971
|
/**
|
|
4624
|
-
*
|
|
4625
|
-
*
|
|
4972
|
+
* Reauthenticate the currently-open session with a freshly obtained
|
|
4973
|
+
* credential so the new token takes effect on the live socket immediately —
|
|
4974
|
+
* not just on the next reconnect. No-op when the session is not
|
|
4975
|
+
* connected/authenticated or the credential carries no token (e.g. an
|
|
4976
|
+
* authorization-state-only refresh). Non-fatal: reauth failures surface on
|
|
4977
|
+
* `errors$` without aborting the refresh that triggered this.
|
|
4626
4978
|
*/
|
|
4627
|
-
|
|
4628
|
-
/** Request a video keyframe via RTCP PLI/FIR. */
|
|
4629
|
-
requestKeyframe(): void;
|
|
4630
|
-
/** Force an ICE restart / re-INVITE. */
|
|
4631
|
-
requestIceRestart(): Promise<void>;
|
|
4979
|
+
private reauthenticateLiveSession;
|
|
4632
4980
|
/**
|
|
4633
|
-
*
|
|
4634
|
-
*
|
|
4981
|
+
* Recover a session the server is refusing: mint a fresh credential,
|
|
4982
|
+
* reauthenticate the live session with it, and retry the operation.
|
|
4983
|
+
*
|
|
4984
|
+
* The connection is deliberately kept. A reload authenticates the new socket
|
|
4985
|
+
* against the persisted `authorization_state`, and that handshake is what
|
|
4986
|
+
* associates the socket with the previous session — the association reattach
|
|
4987
|
+
* depends on. `signalwire.reauthenticate` swaps the credential *on that same
|
|
4988
|
+
* session*, so recovery never touches the resume state. Discarding it would
|
|
4989
|
+
* heal the credential by destroying the very thing the caller is trying to
|
|
4990
|
+
* get back to.
|
|
4991
|
+
*
|
|
4992
|
+
* The operation is still the verdict, never the RPC. Reauthenticating with
|
|
4993
|
+
* the in-memory token is accepted by a resume even while requests stay
|
|
4994
|
+
* refused, because the persisted `authorization_state` short-circuits token
|
|
4995
|
+
* validation — and `signalwire.reauthenticate` with a *freshly minted* token
|
|
4996
|
+
* has also been observed accepted while `subscriber.online` keeps being
|
|
4997
|
+
* refused (staging run 33826974634). Both look like success and are not.
|
|
4998
|
+
*
|
|
4999
|
+
* @returns the operation's value, or the reason recovery could not deliver
|
|
5000
|
+
* one. `error` is undefined when there was no way to mint at all.
|
|
4635
5001
|
*/
|
|
4636
|
-
private
|
|
5002
|
+
private recoverAndRetry;
|
|
4637
5003
|
/**
|
|
4638
|
-
*
|
|
4639
|
-
* triggering an ICE restart. Resolves true on success, false on failure
|
|
4640
|
-
* or if the state doesn't transition within the configured timeout.
|
|
5004
|
+
* Re-mint a credential and adopt it only if the live session accepts it.
|
|
4641
5005
|
*
|
|
4642
|
-
*
|
|
4643
|
-
*
|
|
4644
|
-
*
|
|
5006
|
+
* The mechanism follows the binding: a client-bound session re-mints a bound
|
|
5007
|
+
* base SAT through `authenticate()` with the DPoP fingerprint, because the
|
|
5008
|
+
* developer refresh handler would hand back an unbound token and silently
|
|
5009
|
+
* degrade the session. An unbound session uses the refresh handler. Rotation
|
|
5010
|
+
* cost is not a reason to skip this — the only reason is having no mechanism.
|
|
5011
|
+
*
|
|
5012
|
+
* @returns whether the session is now running on a freshly accepted credential.
|
|
5013
|
+
*/
|
|
5014
|
+
private remintAndReauthenticate;
|
|
5015
|
+
/**
|
|
5016
|
+
* Re-mint a credential via `provider.refresh()`, routed through the
|
|
5017
|
+
* coordinator's shared in-flight guard so concurrent re-mint paths (a
|
|
5018
|
+
* scheduled/resume refresh, -32003 recovery, and reconnect) never fire a
|
|
5019
|
+
* second `provider.refresh()` in parallel — which rotating one-time-use
|
|
5020
|
+
* refresh tokens reject. Falls back to a direct call only if the coordinator
|
|
5021
|
+
* has not been constructed yet.
|
|
5022
|
+
*/
|
|
5023
|
+
private remintCredential;
|
|
5024
|
+
/**
|
|
5025
|
+
* Re-mint credentials before a fresh (re)connect (`onBeforeReconnect` hook).
|
|
5026
|
+
* The session invokes this only when it is client-bound OR the in-memory
|
|
5027
|
+
* token is expired. The re-mint mechanism depends on the binding:
|
|
5028
|
+
* - Client-bound: `authenticate()` with the DPoP fingerprint to obtain a
|
|
5029
|
+
* fresh base SAT the upcoming reconnect can re-bind (the
|
|
5030
|
+
* DeviceTokenManager re-activates afterwards).
|
|
5031
|
+
* - Unbound: the developer's non-interactive `refresh()` handler.
|
|
5032
|
+
* `authenticate()` is deliberately NOT used here — it may be interactive
|
|
5033
|
+
* (a login prompt) and must not fire on a background reconnect.
|
|
5034
|
+
*
|
|
5035
|
+
* Rejects on failure so the session aborts the reconnect rather than
|
|
5036
|
+
* replaying a stale token.
|
|
4645
5037
|
*/
|
|
4646
|
-
private
|
|
5038
|
+
private refreshCredentialForReconnect;
|
|
5039
|
+
/** Persist credential to localStorage when persistSession is enabled. */
|
|
5040
|
+
private persistCredential;
|
|
4647
5041
|
/**
|
|
4648
|
-
*
|
|
4649
|
-
*
|
|
5042
|
+
* Persist whether the session is client-bound, mirroring the credential's
|
|
5043
|
+
* storage scopes so it survives a reload. The preflight recovery reads it
|
|
5044
|
+
* before any session exists to decide whether to re-bind via `authenticate()`
|
|
5045
|
+
* or refresh an unbound token; the marker tracks the latest binding, so an
|
|
5046
|
+
* unbound reconnect clears a stale marker from an earlier client-bound login.
|
|
4650
5047
|
*/
|
|
4651
|
-
private
|
|
4652
|
-
/** @
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
/** Current audio/video send/receive directions. */
|
|
4657
|
-
get mediaDirections(): MediaDirections;
|
|
4658
|
-
protected get participantsId$(): Observable<string[]>;
|
|
5048
|
+
private persistClientBoundMarker;
|
|
5049
|
+
/** Read the persisted client-bound marker (see {@link persistClientBoundMarker}). */
|
|
5050
|
+
private wasClientBound;
|
|
5051
|
+
private init;
|
|
5052
|
+
private handleAttachments;
|
|
4659
5053
|
/**
|
|
4660
|
-
*
|
|
5054
|
+
* Fetch the authenticated user profile, recovering a stale credential.
|
|
4661
5055
|
*
|
|
4662
|
-
*
|
|
4663
|
-
*
|
|
4664
|
-
*
|
|
4665
|
-
*
|
|
4666
|
-
*
|
|
4667
|
-
*
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
|
|
4673
|
-
get selfId(): string | null;
|
|
4674
|
-
/** Observable of the server node ID handling this call. */
|
|
4675
|
-
get nodeId$(): Observable<string | null>;
|
|
4676
|
-
/** Server node ID handling this call, or `null`. */
|
|
4677
|
-
get nodeId(): string | null;
|
|
4678
|
-
private isCallSessionEvent;
|
|
4679
|
-
private get callSessionEvents$();
|
|
4680
|
-
/** Observable of call-updated events. */
|
|
4681
|
-
get callUpdated$(): Observable<CallUpdatedPayload>;
|
|
4682
|
-
/** Observable of member-joined events, emitted when a remote participant joins the call. */
|
|
4683
|
-
get memberJoined$(): Observable<MemberJoinedPayload>;
|
|
4684
|
-
/** Observable of member-left events, emitted when a participant leaves the call. */
|
|
4685
|
-
get memberLeft$(): Observable<MemberLeftPayload>;
|
|
4686
|
-
/** Observable of member-updated events (mute, volume, etc.). */
|
|
4687
|
-
get memberUpdated$(): Observable<MemberUpdatedPayload>;
|
|
4688
|
-
/** Observable of member-talking events (speech start/stop). */
|
|
4689
|
-
get memberTalking$(): Observable<MemberTalkingPayload>;
|
|
4690
|
-
/** Observable of call state-change events. */
|
|
4691
|
-
get callStates$(): Observable<CallStatePayload>;
|
|
4692
|
-
/** Observable of layout-changed events. */
|
|
4693
|
-
get layoutUpdates$(): Observable<LayoutChangedPayload>;
|
|
4694
|
-
/** Underlying `RTCPeerConnection`, for advanced use cases. */
|
|
4695
|
-
get rtcPeerConnection(): RTCPeerConnection | undefined;
|
|
4696
|
-
/** Observable of raw signaling events as plain objects. */
|
|
4697
|
-
get signalingEvent$(): Observable<Record<string, unknown>>;
|
|
5056
|
+
* On a reload the persisted credential can be expired. Unlike the WS resume —
|
|
5057
|
+
* which the server accepts against the persisted `authorization_state` even
|
|
5058
|
+
* with an expired token — this REST preflight has no such short-circuit and is
|
|
5059
|
+
* refused (401). There is no session yet to reauthenticate, so recovery
|
|
5060
|
+
* re-mints the credential through the provider ({@link refreshCredentialForReconnect})
|
|
5061
|
+
* and retries with a FRESH {@link User}: Fetchable memoizes its result
|
|
5062
|
+
* (shareReplay), so reusing the instance would replay the 401 instead of
|
|
5063
|
+
* re-fetching with the new token. Without the user id the transport/session —
|
|
5064
|
+
* and the reattach a reload is trying to preserve — cannot even be addressed.
|
|
5065
|
+
*/
|
|
5066
|
+
private fetchUserOrRecover;
|
|
4698
5067
|
/**
|
|
4699
|
-
*
|
|
5068
|
+
* Establishes the WebSocket connection and authenticates the session.
|
|
4700
5069
|
*
|
|
4701
|
-
*
|
|
4702
|
-
* whose `event_type` matches the given string. The observable completes
|
|
4703
|
-
* when the call is destroyed.
|
|
5070
|
+
* ## Reconnection behavior
|
|
4704
5071
|
*
|
|
4705
|
-
*
|
|
4706
|
-
*
|
|
5072
|
+
* After a successful connection the underlying {@link WebSocketController}
|
|
5073
|
+
* automatically attempts to reconnect whenever the socket closes
|
|
5074
|
+
* unexpectedly (e.g. network change, server restart). Reconnection uses an
|
|
5075
|
+
* **exponential back-off** strategy:
|
|
4707
5076
|
*
|
|
4708
|
-
*
|
|
4709
|
-
*
|
|
5077
|
+
* - First retry after `reconnectDelayMin` (default **0.1 s**).
|
|
5078
|
+
* - Each subsequent retry doubles the delay up to `reconnectDelayMax`
|
|
5079
|
+
* (default **3 s**).
|
|
5080
|
+
* - The delay resets to `reconnectDelayMin` once a connection succeeds.
|
|
5081
|
+
* - A per-attempt `connectionTimeout` (default **10 s**) aborts the
|
|
5082
|
+
* attempt and schedules the next retry if the server does not respond.
|
|
4710
5083
|
*
|
|
4711
|
-
* @
|
|
4712
|
-
*
|
|
5084
|
+
* Calling {@link disconnect} stops the reconnection loop entirely.
|
|
5085
|
+
*
|
|
5086
|
+
* ## Message handling during temporary disconnections
|
|
5087
|
+
*
|
|
5088
|
+
* While the socket is not in the `connected` state, **outgoing messages
|
|
5089
|
+
* are queued** in an internal buffer. Once the connection is
|
|
5090
|
+
* re-established the queue is flushed in order so no outgoing RPC call is
|
|
5091
|
+
* lost.
|
|
5092
|
+
*
|
|
5093
|
+
* **Incoming** server-to-client messages that arrive while the socket is
|
|
5094
|
+
* down are *not* buffered by the SDK — they are expected to be
|
|
5095
|
+
* re-delivered by the server after the session is re-authenticated.
|
|
5096
|
+
* Active RPC calls that were awaiting a response will time out
|
|
5097
|
+
* (default **5 s**) and reject with an `RPCTimeoutError`; callers should
|
|
5098
|
+
* handle this and retry if appropriate.
|
|
5099
|
+
*
|
|
5100
|
+
* The connection status can be observed via the `status$` observable on
|
|
5101
|
+
* the transport layer, which emits `'connecting'`, `'connected'`,
|
|
5102
|
+
* `'reconnecting'`, `'disconnecting'`, or `'disconnected'`.
|
|
5103
|
+
*/
|
|
5104
|
+
connect(): Promise<void>;
|
|
5105
|
+
/**
|
|
5106
|
+
* Observable that emits the {@link User} profile once fetched,
|
|
5107
|
+
* or `undefined` before authentication completes.
|
|
4713
5108
|
*
|
|
4714
5109
|
* @example
|
|
4715
5110
|
* ```ts
|
|
4716
|
-
*
|
|
4717
|
-
* console.log('
|
|
5111
|
+
* client.user$.subscribe(u => {
|
|
5112
|
+
* if (u) console.log('Logged in as', u.email);
|
|
4718
5113
|
* });
|
|
4719
5114
|
* ```
|
|
4720
5115
|
*/
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
get
|
|
4724
|
-
get layoutEvent$(): Observable<LayoutChangedPayload>;
|
|
5116
|
+
get user$(): Observable<User | undefined>;
|
|
5117
|
+
/** Current user snapshot, or `undefined` if not yet authenticated. */
|
|
5118
|
+
get user(): User | undefined;
|
|
4725
5119
|
/**
|
|
4726
|
-
*
|
|
4727
|
-
*
|
|
4728
|
-
*
|
|
4729
|
-
* then destroys the call. After this, the call instance is no longer usable.
|
|
5120
|
+
* Observable that emits the {@link Directory} instance once the client is connected,
|
|
5121
|
+
* or `undefined` while disconnected. Subscribe to this to safely wait for the directory
|
|
5122
|
+
* to become available without risking an error.
|
|
4730
5123
|
*
|
|
4731
5124
|
* @example
|
|
4732
5125
|
* ```ts
|
|
4733
|
-
*
|
|
5126
|
+
* client.directory$.subscribe(dir => {
|
|
5127
|
+
* if (dir) dir.addresses$.subscribe(console.log);
|
|
5128
|
+
* });
|
|
4734
5129
|
* ```
|
|
4735
5130
|
*/
|
|
4736
|
-
|
|
5131
|
+
get directory$(): Observable<Directory | undefined>;
|
|
4737
5132
|
/**
|
|
4738
|
-
*
|
|
5133
|
+
* Current directory snapshot, or `undefined` if the client is not yet connected.
|
|
5134
|
+
* Prefer {@link directory$} when you need to react to the directory becoming available.
|
|
5135
|
+
*/
|
|
5136
|
+
get directory(): Directory | undefined;
|
|
5137
|
+
/** Observable that emits when the user registration state changes. */
|
|
5138
|
+
get isRegistered$(): Observable<boolean>;
|
|
5139
|
+
/** Whether the user is currently registered. */
|
|
5140
|
+
get isRegistered(): boolean;
|
|
5141
|
+
/** Whether the client is currently connected. */
|
|
5142
|
+
get isConnected(): boolean;
|
|
5143
|
+
/** Observable that emits when the connection state changes. */
|
|
5144
|
+
get isConnected$(): Observable<boolean>;
|
|
5145
|
+
/** Observable that emits `true` when the client is both connected and authenticated. */
|
|
5146
|
+
get ready$(): Observable<boolean>;
|
|
5147
|
+
/** Observable stream of errors from transport, authentication, and devices. */
|
|
5148
|
+
get errors$(): Observable<Error>;
|
|
5149
|
+
/**
|
|
5150
|
+
* Observable stream of non-fatal SDK warnings.
|
|
4739
5151
|
*
|
|
4740
|
-
*
|
|
5152
|
+
* Subscribe to detect SDK behaviors that affect session liveness or developer-facing
|
|
5153
|
+
* contracts but do not warrant disconnection — e.g., a fallback from Client Bound SAT
|
|
5154
|
+
* refresh to the developer-provided `refresh()` because the SAT lacks `sat:refresh`
|
|
5155
|
+
* scope. Discriminated by `code`.
|
|
4741
5156
|
*
|
|
4742
|
-
* @
|
|
4743
|
-
* ```ts
|
|
4744
|
-
* await call.sendDigits('1234#');
|
|
4745
|
-
* ```
|
|
5157
|
+
* Independent from {@link errors$}: existing error consumers are not notified.
|
|
4746
5158
|
*/
|
|
4747
|
-
|
|
4748
|
-
/**
|
|
4749
|
-
|
|
4750
|
-
/** Observable
|
|
5159
|
+
get warnings$(): Observable<SDKWarning>;
|
|
5160
|
+
/** Platform WebRTC capabilities detected at construction time. */
|
|
5161
|
+
get platformCapabilities(): PlatformCapabilities;
|
|
5162
|
+
/** Observable that emits when the SDK auto-switches a device. */
|
|
5163
|
+
get deviceRecovered$(): Observable<DeviceRecoveryEvent>;
|
|
4751
5164
|
/**
|
|
4752
|
-
*
|
|
5165
|
+
* Export a structured diagnostic bundle for support/debugging.
|
|
5166
|
+
* Includes connection events, call summaries, and device changes.
|
|
5167
|
+
*/
|
|
5168
|
+
exportDiagnostics(): SessionDiagnostics;
|
|
5169
|
+
/**
|
|
5170
|
+
* Initialize resilience subsystems. Non-fatal: any failure is logged and
|
|
5171
|
+
* the SDK continues working without the failing subsystem.
|
|
5172
|
+
*/
|
|
5173
|
+
private initResilienceSubsystems;
|
|
5174
|
+
/**
|
|
5175
|
+
* Disconnects the WebSocket and tears down the current session.
|
|
4753
5176
|
*
|
|
4754
|
-
*
|
|
5177
|
+
* Ends the session identified by the protocol and clears its persisted
|
|
5178
|
+
* resume state (`authorization_state` + protocol) and attach records
|
|
5179
|
+
* together — a later {@link connect} with the same credentials starts a
|
|
5180
|
+
* fresh session and cannot reattach to the ended session's calls.
|
|
5181
|
+
* Credentials and device preferences are preserved. To temporarily stop
|
|
5182
|
+
* receiving inbound calls while keeping the session alive, use
|
|
5183
|
+
* `unregister()` instead.
|
|
4755
5184
|
*
|
|
4756
|
-
* @
|
|
4757
|
-
*
|
|
4758
|
-
|
|
4759
|
-
|
|
5185
|
+
* The client can be reconnected by calling {@link connect} again,
|
|
5186
|
+
* which creates a fresh transport and session.
|
|
5187
|
+
*/
|
|
5188
|
+
disconnect(): Promise<void>;
|
|
5189
|
+
/**
|
|
5190
|
+
* Tear down the current transport / session / attach manager. Safe to call
|
|
5191
|
+
* when nothing has been initialized yet (e.g. first connect()).
|
|
5192
|
+
*/
|
|
5193
|
+
private teardownTransportAndSession;
|
|
5194
|
+
private waitAuthentication;
|
|
5195
|
+
/**
|
|
5196
|
+
* Registers the user as online to receive inbound calls and events.
|
|
4760
5197
|
*
|
|
4761
|
-
*
|
|
4762
|
-
*
|
|
4763
|
-
*
|
|
4764
|
-
* @
|
|
4765
|
-
* @see {@link answered$} to observe the acceptance state.
|
|
5198
|
+
* Waits for authentication to complete before sending the registration.
|
|
5199
|
+
* If the initial attempt fails, reauthentication is attempted automatically.
|
|
5200
|
+
*
|
|
5201
|
+
* @throws {InvalidCredentialsError} If registration and reauthentication both fail.
|
|
4766
5202
|
*/
|
|
4767
|
-
|
|
4768
|
-
/** Media options provided when answering. Used internally by the VertoManager. */
|
|
4769
|
-
get answerMediaOptions(): MediaOptions | undefined;
|
|
5203
|
+
register(): Promise<void>;
|
|
4770
5204
|
/**
|
|
4771
|
-
*
|
|
5205
|
+
* Unregisters the user, going offline for inbound calls.
|
|
4772
5206
|
*
|
|
4773
|
-
*
|
|
4774
|
-
* @see {@link answered$} to observe the rejection state.
|
|
5207
|
+
* The WebSocket connection remains open; use {@link disconnect} to fully close it.
|
|
4775
5208
|
*/
|
|
4776
|
-
|
|
4777
|
-
/** Observable that emits `true` when answered, `false` when rejected. */
|
|
4778
|
-
get answered$(): Observable<boolean>;
|
|
5209
|
+
unregister(): Promise<void>;
|
|
4779
5210
|
/**
|
|
4780
|
-
*
|
|
5211
|
+
* Places an outbound call to the given destination.
|
|
4781
5212
|
*
|
|
4782
|
-
*
|
|
4783
|
-
*
|
|
4784
|
-
*
|
|
4785
|
-
* position by that member's own call context) alongside `call.layout.set`
|
|
4786
|
-
* (issue #19400, Flag #6).
|
|
5213
|
+
* Waits for authentication before dialing. Media options are merged from
|
|
5214
|
+
* saved preferences, destination query parameters (e.g. `?channel=video`),
|
|
5215
|
+
* and the provided `options` (highest priority).
|
|
4787
5216
|
*
|
|
4788
|
-
*
|
|
4789
|
-
*
|
|
4790
|
-
* default slots before being moved to the requested positions.
|
|
5217
|
+
* Returns a {@link Call} in `'ringing'` state. Subscribe to {@link Call.status$}
|
|
5218
|
+
* to track progression through `'connected'` → `'disconnected'`.
|
|
4791
5219
|
*
|
|
4792
|
-
*
|
|
4793
|
-
*
|
|
4794
|
-
*
|
|
4795
|
-
*
|
|
5220
|
+
* Local media acquisition is deliberately unbounded: an unanswered permission
|
|
5221
|
+
* prompt leaves this promise pending indefinitely, so apply your own bound if
|
|
5222
|
+
* your UI needs one. The 12 s signaling budget starts only once acquisition
|
|
5223
|
+
* settles.
|
|
5224
|
+
*
|
|
5225
|
+
* @param destination - Address URI string (e.g. `'/public/my-room'`) or {@link Address} instance.
|
|
5226
|
+
* @param options - Media and dial options (audio/video, device constraints). Overrides defaults.
|
|
5227
|
+
* @returns The created {@link Call} instance.
|
|
5228
|
+
* @throws {Error} If authentication is not complete or call creation fails.
|
|
4796
5229
|
*
|
|
4797
5230
|
* @example
|
|
4798
5231
|
* ```ts
|
|
4799
|
-
* await
|
|
4800
|
-
*
|
|
5232
|
+
* const call = await client.dial('/public/conference', {
|
|
5233
|
+
* audio: true,
|
|
5234
|
+
* video: true,
|
|
4801
5235
|
* });
|
|
5236
|
+
* call.status$.subscribe(status => console.log('Call:', status));
|
|
4802
5237
|
* ```
|
|
4803
5238
|
*/
|
|
4804
|
-
|
|
4805
|
-
/**
|
|
4806
|
-
* Transfers the call to another destination.
|
|
4807
|
-
*
|
|
4808
|
-
* @param options - Transfer configuration including the target destination.
|
|
4809
|
-
* @see {@link status$} to observe the transfer progress.
|
|
4810
|
-
*/
|
|
4811
|
-
transfer(options: TransferOptions): Promise<void>;
|
|
5239
|
+
dial(destination: string | Address, options?: DialOptions): Promise<Call>;
|
|
4812
5240
|
/**
|
|
4813
|
-
*
|
|
4814
|
-
*
|
|
4815
|
-
* - `0` = silent
|
|
4816
|
-
* - `100` = unity (no change, default)
|
|
4817
|
-
* - `200` = 2× digital boost (max; expect clipping / noise amplification)
|
|
5241
|
+
* Runs a multi-phase connectivity test against the given destination.
|
|
4818
5242
|
*
|
|
4819
|
-
*
|
|
4820
|
-
*
|
|
5243
|
+
* The test checks:
|
|
5244
|
+
* 1. **Signaling** -- WebSocket connected, RTT measurement
|
|
5245
|
+
* 2. **Devices** -- getUserMedia succeeds with selected (or specified) devices
|
|
5246
|
+
* 3. **ICE/TURN** -- gathers ICE candidates to verify STUN/TURN reachability
|
|
5247
|
+
* 4. **Media/bandwidth** (unless `skipMediaTest`) -- dials the destination,
|
|
5248
|
+
* collects getStats() for `duration` seconds, computes bandwidth estimates
|
|
4821
5249
|
*
|
|
4822
|
-
*
|
|
4823
|
-
*
|
|
4824
|
-
*
|
|
4825
|
-
* fight the setting; call {@link setAutoGainControl}(false) for
|
|
4826
|
-
* predictable behaviour.
|
|
5250
|
+
* @param destination - A destination to dial for the media test (e.g. `'/private/network-test'`).
|
|
5251
|
+
* @param options - Preflight options (duration, skipMediaTest, device overrides).
|
|
5252
|
+
* @returns A {@link PreflightResult} describing connectivity health.
|
|
4827
5253
|
*
|
|
4828
|
-
* @
|
|
5254
|
+
* @example
|
|
5255
|
+
* ```ts
|
|
5256
|
+
* const result = await client.preflight('/private/network-test', { duration: 5 });
|
|
5257
|
+
* if (!result.ok) console.warn('Connectivity issues:', result.warnings);
|
|
5258
|
+
* ```
|
|
4829
5259
|
*/
|
|
4830
|
-
|
|
4831
|
-
/**
|
|
4832
|
-
get
|
|
5260
|
+
preflight(destination: string, options?: PreflightOptions): Promise<PreflightResult>;
|
|
5261
|
+
/** The underlying client session for advanced RPC operations. */
|
|
5262
|
+
get session(): ClientSessionWrapper;
|
|
5263
|
+
/** Observable list of available audio input (microphone) devices. */
|
|
5264
|
+
get audioInputDevices$(): Observable<MediaDeviceInfo[]>;
|
|
5265
|
+
/** Current snapshot of available audio input devices. */
|
|
5266
|
+
get audioInputDevices(): MediaDeviceInfo[];
|
|
5267
|
+
/** Observable list of available audio output (speaker) devices. */
|
|
5268
|
+
get audioOutputDevices$(): Observable<MediaDeviceInfo[]>;
|
|
5269
|
+
/** Current snapshot of available audio output devices. */
|
|
5270
|
+
get audioOutputDevices(): MediaDeviceInfo[];
|
|
5271
|
+
/** Observable list of available video input (camera) devices. */
|
|
5272
|
+
get videoInputDevices$(): Observable<MediaDeviceInfo[]>;
|
|
5273
|
+
/** Current snapshot of available video input devices. */
|
|
5274
|
+
get videoInputDevices(): MediaDeviceInfo[];
|
|
5275
|
+
/** Observable of the currently selected audio input device. */
|
|
5276
|
+
get selectedAudioInputDevice$(): Observable<MediaDeviceInfo | null>;
|
|
5277
|
+
/** Observable of the currently selected audio output device. */
|
|
5278
|
+
get selectedAudioOutputDevice$(): Observable<MediaDeviceInfo | null>;
|
|
5279
|
+
/** Observable of the currently selected video input device. */
|
|
5280
|
+
get selectedVideoInputDevice$(): Observable<MediaDeviceInfo | null>;
|
|
5281
|
+
/** Currently selected audio input device, or `null` if none. */
|
|
5282
|
+
get selectedAudioInputDevice(): MediaDeviceInfo | null;
|
|
5283
|
+
/** Currently selected audio output device, or `null` if none. */
|
|
5284
|
+
get selectedAudioOutputDevice(): MediaDeviceInfo | null;
|
|
5285
|
+
/** Currently selected video input device, or `null` if none. */
|
|
5286
|
+
get selectedVideoInputDevice(): MediaDeviceInfo | null;
|
|
5287
|
+
/** Media track constraints for the selected audio input device. Returns `false` when disabled. */
|
|
5288
|
+
get selectedAudioInputDeviceConstraints(): MediaTrackConstraints | boolean;
|
|
5289
|
+
/** Media track constraints for the selected video input device. Returns `false` when disabled. */
|
|
5290
|
+
get selectedVideoInputDeviceConstraints(): MediaTrackConstraints | boolean;
|
|
5291
|
+
/** Converts a `MediaDeviceInfo` to track constraints suitable for `getUserMedia`. */
|
|
5292
|
+
deviceInfoToConstraints(deviceInfo: MediaDeviceInfo | null): MediaTrackConstraints;
|
|
5293
|
+
/** Sets the preferred audio input device. */
|
|
5294
|
+
selectAudioInputDevice(device: MediaDeviceInfo | null): void;
|
|
5295
|
+
/** Sets the preferred video input device. */
|
|
5296
|
+
selectVideoInputDevice(device: MediaDeviceInfo | null): void;
|
|
5297
|
+
/** Sets the preferred audio output device. */
|
|
5298
|
+
selectAudioOutputDevice(device: MediaDeviceInfo | null): void;
|
|
4833
5299
|
/**
|
|
4834
|
-
*
|
|
4835
|
-
*
|
|
4836
|
-
*
|
|
5300
|
+
* Apply the currently selected audio output device to an HTMLMediaElement
|
|
5301
|
+
* (e.g. the `<audio>` or `<video>` element the consumer attached the
|
|
5302
|
+
* remote stream to). Uses `HTMLMediaElement.setSinkId` under the hood.
|
|
5303
|
+
* Returns a `Promise<boolean>`: `true` if the sink was applied,
|
|
5304
|
+
* `false` if the browser doesn't support `setSinkId` or no device is
|
|
5305
|
+
* selected.
|
|
5306
|
+
*
|
|
5307
|
+
* @example
|
|
5308
|
+
* ```ts
|
|
5309
|
+
* audioEl.srcObject = call.remoteStream;
|
|
5310
|
+
* await client.applySelectedAudioOutputDevice(audioEl);
|
|
5311
|
+
* ```
|
|
4837
5312
|
*/
|
|
4838
|
-
|
|
5313
|
+
applySelectedAudioOutputDevice(element: HTMLMediaElement): Promise<boolean>;
|
|
5314
|
+
/** Starts monitoring for media device changes (connect/disconnect). */
|
|
5315
|
+
enableDeviceMonitoring(): void;
|
|
5316
|
+
/** Stops monitoring for media device changes. */
|
|
5317
|
+
disableDeviceMonitoring(): void;
|
|
4839
5318
|
/**
|
|
4840
|
-
*
|
|
4841
|
-
*
|
|
5319
|
+
* Returns the capabilities of a media device.
|
|
5320
|
+
* @param deviceInfo - The device to query.
|
|
5321
|
+
* @returns The device capabilities, or `null` if unavailable.
|
|
4842
5322
|
*/
|
|
4843
|
-
|
|
5323
|
+
getDeviceCapabilities(deviceInfo: MediaDeviceInfo): Promise<MediaTrackCapabilities | null>;
|
|
4844
5324
|
/**
|
|
4845
|
-
*
|
|
4846
|
-
*
|
|
4847
|
-
*
|
|
4848
|
-
* Use this instead of mute/unmute for instant talk/silence transitions
|
|
4849
|
-
* because it doesn't rebuild the track.
|
|
4850
|
-
*
|
|
4851
|
-
* This method installs the pipeline but does not attach any keyboard
|
|
4852
|
-
* listener — consumers bind the key themselves and call
|
|
4853
|
-
* {@link setPushToTalkActive} on keydown/keyup.
|
|
5325
|
+
* Checks whether a device is still available and usable.
|
|
5326
|
+
* @param deviceInfo - The device to validate, or `null`.
|
|
5327
|
+
* @returns `true` if the device is valid and available. Returns `false` for `null`, audio output devices, or unavailable devices.
|
|
4854
5328
|
*/
|
|
4855
|
-
|
|
4856
|
-
/**
|
|
4857
|
-
|
|
5329
|
+
isValidDevice(deviceInfo: MediaDeviceInfo | null): Promise<boolean>;
|
|
5330
|
+
/** Injects a storage manager into the device controller for persistence. */
|
|
5331
|
+
setStorageManager(storageManager: StorageManager): void;
|
|
5332
|
+
/** Clears all device state and re-enumerates. */
|
|
5333
|
+
clearDeviceState(): Promise<void>;
|
|
5334
|
+
/** Forces a device re-enumeration. */
|
|
5335
|
+
enumerateDevices(): Promise<void>;
|
|
5336
|
+
/** Disables audio input (receive-only mode). No audio track will be acquired. */
|
|
5337
|
+
disableAudioInput(): void;
|
|
5338
|
+
/** Re-enables audio input, restoring the last selection or auto-selecting. */
|
|
5339
|
+
enableAudioInput(): void;
|
|
5340
|
+
/** Disables video input (receive-only mode). No video track will be acquired. */
|
|
5341
|
+
disableVideoInput(): void;
|
|
5342
|
+
/** Re-enables video input, restoring the last selection or auto-selecting. */
|
|
5343
|
+
enableVideoInput(): void;
|
|
5344
|
+
/** Observable that emits `true` when video input is disabled (receive-only). */
|
|
5345
|
+
get videoInputDisabled$(): Observable<boolean>;
|
|
5346
|
+
/** Observable that emits `true` when audio input is disabled (receive-only). */
|
|
5347
|
+
get audioInputDisabled$(): Observable<boolean>;
|
|
5348
|
+
/** Whether video input is currently disabled. */
|
|
5349
|
+
get videoInputDisabled(): boolean;
|
|
5350
|
+
/** Whether audio input is currently disabled. */
|
|
5351
|
+
get audioInputDisabled(): boolean;
|
|
4858
5352
|
/**
|
|
4859
|
-
*
|
|
4860
|
-
*
|
|
5353
|
+
* Triggers the browser's media permission dialog and captures the user's device selections.
|
|
5354
|
+
*
|
|
5355
|
+
* @param options - Which permissions to request.
|
|
5356
|
+
* @param options.audio - Whether to request audio permission.
|
|
5357
|
+
* @param options.video - Whether to request video permission.
|
|
5358
|
+
* @returns The permission result with selected devices.
|
|
4861
5359
|
*/
|
|
4862
|
-
|
|
5360
|
+
requestMediaPermissions(options?: {
|
|
5361
|
+
audio?: boolean;
|
|
5362
|
+
video?: boolean;
|
|
5363
|
+
}): Promise<PermissionResult>;
|
|
4863
5364
|
/**
|
|
4864
|
-
*
|
|
4865
|
-
*
|
|
4866
|
-
*
|
|
4867
|
-
*
|
|
4868
|
-
* pipeline if one is active.
|
|
5365
|
+
* Clears all SDK-persisted state and resets to defaults.
|
|
5366
|
+
*
|
|
5367
|
+
* This clears device preferences, device history, authorization state,
|
|
5368
|
+
* attached call IDs, and all SDK storage keys, then re-enumerates devices.
|
|
4869
5369
|
*/
|
|
4870
|
-
|
|
4871
|
-
/** Toggle browser noise suppression on the local mic at runtime. */
|
|
4872
|
-
setNoiseSuppression(enabled: boolean): Promise<void>;
|
|
4873
|
-
/** Toggle browser automatic gain control on the local mic at runtime. */
|
|
4874
|
-
setAutoGainControl(enabled: boolean): Promise<void>;
|
|
5370
|
+
resetToDefaults(): Promise<void>;
|
|
4875
5371
|
/**
|
|
4876
|
-
*
|
|
4877
|
-
* delivers a single mixed audio stream for all remote participants — this
|
|
4878
|
-
* meter reports that mix. Per-participant audio is not available client-side.
|
|
5372
|
+
* Destroys the client, clearing timers and releasing all resources.
|
|
4879
5373
|
*
|
|
4880
|
-
*
|
|
4881
|
-
*
|
|
4882
|
-
*
|
|
5374
|
+
* Intentionally destroying the client ends its session: the resume state
|
|
5375
|
+
* (`authorization_state` + protocol) and the attach records are both
|
|
5376
|
+
* cleared. Credentials and device preferences are preserved — use
|
|
5377
|
+
* {@link resetToDefaults} for a full wipe. To temporarily stop receiving
|
|
5378
|
+
* inbound calls while keeping the session alive, use `unregister()`.
|
|
4883
5379
|
*/
|
|
4884
|
-
get remoteAudioLevel$(): Observable<number>;
|
|
4885
|
-
/** Destroys the call, releasing all resources and subscriptions. */
|
|
4886
5380
|
destroy(): void;
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
5381
|
+
}
|
|
5382
|
+
//#endregion
|
|
5383
|
+
//#region src/utils/embeddableCall.d.ts
|
|
5384
|
+
/** Options for {@link embeddableCall}. */
|
|
5385
|
+
interface EmbeddableCallOptions {
|
|
5386
|
+
/** Destination URI to call. */
|
|
5387
|
+
to: string;
|
|
5388
|
+
/** Embed token for authentication. */
|
|
5389
|
+
embedToken: string;
|
|
5390
|
+
/** SignalWire host URL. */
|
|
5391
|
+
host: string;
|
|
5392
|
+
}
|
|
5393
|
+
/**
|
|
5394
|
+
* Creates a call using an embed token for simple, embeddable integrations.
|
|
5395
|
+
*
|
|
5396
|
+
* Handles client creation, authentication, and dialing in a single call.
|
|
5397
|
+
*
|
|
5398
|
+
* @param options - Embed token, host, and destination.
|
|
5399
|
+
* @returns The created {@link Call} instance.
|
|
5400
|
+
*/
|
|
5401
|
+
declare function embeddableCall(options: EmbeddableCallOptions): Promise<Call>;
|
|
5402
|
+
//#endregion
|
|
5403
|
+
//#region src/dependencies/StaticCredentialProvider.d.ts
|
|
5404
|
+
/**
|
|
5405
|
+
* Credential provider that returns a fixed set of credentials.
|
|
5406
|
+
*
|
|
5407
|
+
* Use when the token is already available (e.g. from a backend endpoint).
|
|
5408
|
+
*
|
|
5409
|
+
* @example
|
|
5410
|
+
* ```ts
|
|
5411
|
+
* const provider = new StaticCredentialProvider({ token: 'my-sat-token' });
|
|
5412
|
+
* const client = new SignalWire(provider);
|
|
5413
|
+
* ```
|
|
5414
|
+
*/
|
|
5415
|
+
declare class StaticCredentialProvider implements CredentialProvider {
|
|
5416
|
+
private credentials;
|
|
5417
|
+
constructor(credentials: SDKCredential);
|
|
5418
|
+
/** Returns the static credentials. */
|
|
5419
|
+
authenticate(): Promise<SDKCredential>;
|
|
5420
|
+
}
|
|
5421
|
+
//#endregion
|
|
5422
|
+
//#region src/dependencies/EmbedTokenCredentialProvider.d.ts
|
|
5423
|
+
/** Credential provider that exchanges an embed token for a SAT via the host's token endpoint. */
|
|
5424
|
+
declare class EmbedTokenCredentialProvider implements CredentialProvider {
|
|
5425
|
+
private host;
|
|
5426
|
+
private embedToken;
|
|
5427
|
+
constructor(host: string, embedToken: string);
|
|
5428
|
+
private fetchSAT;
|
|
5429
|
+
authenticate(): Promise<{
|
|
5430
|
+
token: string;
|
|
5431
|
+
expiry_at: number;
|
|
5432
|
+
}>;
|
|
5433
|
+
refresh(): Promise<{
|
|
5434
|
+
token: string;
|
|
5435
|
+
expiry_at: number;
|
|
5436
|
+
}>;
|
|
4894
5437
|
}
|
|
4895
5438
|
//#endregion
|
|
4896
5439
|
//#region src/index.d.ts
|
|
@@ -4905,5 +5448,5 @@ declare const version: string;
|
|
|
4905
5448
|
*/
|
|
4906
5449
|
declare const ready: boolean;
|
|
4907
5450
|
//#endregion
|
|
4908
|
-
export { Address, type AddressHistory, type AudioConstraintsEvent, type AuthenticateContext, type Call, type CallAddress, type CallCapabilitiesState, CallCreateError, type CallDiagnosticSummary, type CallDirection, type CallError, type CallErrorKind, type NetworkIssue as CallNetworkIssue, type NetworkIssue, type NetworkMetrics as CallNetworkMetrics, type NetworkMetrics, type CallOptions, type CallParticipant, type CallSelfParticipant, type CallState, type CallStatus, type Capability, ClientPreferences, CollectionFetchError, type ConstraintFallbackEvent, type CredentialNoRefreshHandlerWarning, type CredentialProvider, type CredentialRefreshFallbackReason, type CredentialRefreshFallbackWarning, DPoPInitError, type DebugOptions, type DeviceController, type DeviceRecoveryEvent, DeviceTokenError, type DiagnosticEvent, type DialOptions, type Directory, EmbedTokenCredentialProvider, type ExecuteMethod, InvalidCredentialsError, type JSONRPCErrorResponse, type JSONRPCRequest, type JSONRPCResponse, type JSONRPCSuccessResponse, type LayoutLayer, type LogLevel, type MediaDirection, type MediaDirections, type MediaOptions, type MediaParamsEvent, MediaTrackError, type MemberCapabilities, MessageParseError, type NodeSocketAdapter, type OnOffCapability, OverconstrainedFallbackError, Participant, type PendingRPCOptions, type PermissionResult, type PlatformCapabilities, PreflightError, type PreflightOptions, type PreflightResult, type QualityLevel, RecoveryError, type RecoveryEvent, type RecoveryState, type ResilienceCallStatus, type SATClaims, type SDKCredential, type SDKLogger, type SDKWarning, type ScreenShareStatus, type SelectDeviceOptions, SelfCapabilities, SelfParticipant, type SessionDiagnostics, type SessionState, SignalWire, type SignalWireOptions, StaticCredentialProvider, type Storage, type StoredDevicePreference, type TextMessage, TokenRefreshError, type TransferOptions, UnexpectedError, User, type UserPresence, VertoPongError, type VideoPosition, type WebRTCApiProvider, WebRTCCall, type WebRTCMediaDevices, type WebSocketAdapter, embeddableCall, getLogger, isSelfParticipant, ready, setDebugOptions, setLogLevel, setLogger, version };
|
|
5451
|
+
export { Address, type AddressHistory, type AudioConstraintsEvent, type AuthenticateContext, AuxiliaryLegCancelledError, AuxiliaryLegTimeoutError, type Call, type CallAddress, type CallCapabilitiesState, CallCreateError, type CallDiagnosticSummary, type CallDirection, type CallError, type CallErrorKind, type NetworkIssue as CallNetworkIssue, type NetworkIssue, type NetworkMetrics as CallNetworkMetrics, type NetworkMetrics, CallNotReadyError, type CallOptions, type CallParticipant, type CallSelfParticipant, type CallState, type CallStatus, type Capability, ClientPreferences, CollectionFetchError, type ConstraintFallbackEvent, type CredentialNoRefreshHandlerWarning, type CredentialProvider, type CredentialRefreshFallbackReason, type CredentialRefreshFallbackWarning, DPoPInitError, type DebugOptions, type DeviceController, type DeviceRecoveryEvent, DeviceTokenError, type DiagnosticEvent, type DialOptions, type Directory, EmbedTokenCredentialProvider, type ExecuteMethod, InvalidCredentialsError, type JSONRPCErrorResponse, type JSONRPCRequest, type JSONRPCResponse, type JSONRPCSuccessResponse, type LayoutLayer, type LogLevel, MediaAccessError, type MediaDirection, type MediaDirections, type MediaOptions, type MediaParamsEvent, MediaTrackError, type MemberCapabilities, MessageParseError, type NodeSocketAdapter, type OnOffCapability, OverconstrainedFallbackError, Participant, ParticipantNotReadyError, type PendingRPCOptions, type PermissionResult, type PlatformCapabilities, PreflightError, type PreflightOptions, type PreflightResult, type QualityLevel, RecoveryError, type RecoveryEvent, type RecoveryState, type ResilienceCallStatus, type SATClaims, type SDKCredential, type SDKLogger, type SDKWarning, ScreenShareAlreadyActiveError, type ScreenShareOptions, type ScreenShareStatus, type SelectDeviceOptions, SelfCapabilities, SelfParticipant, type SessionDiagnostics, type SessionState, SignalWire, type SignalWireOptions, StaticCredentialProvider, type Storage, type StoredDevicePreference, type TextMessage, TokenRefreshError, type TransferOptions, UnexpectedError, User, type UserPresence, VertoPongError, type VideoPosition, type WebRTCApiProvider, WebRTCCall, type WebRTCMediaDevices, type WebSocketAdapter, embeddableCall, getLogger, isSelfParticipant, ready, setDebugOptions, setLogLevel, setLogger, version };
|
|
4909
5452
|
//# sourceMappingURL=index.d.cts.map
|