@signalwire/js 4.0.0-beta.11 → 4.0.0-beta.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -84,7 +84,7 @@ type WebSocketAdapter = new (url: string | URL, protocols?: string | string[]) =
84
84
  * At least one of `token` or `authorizationState` must be provided.
85
85
  */
86
86
  interface SDKCredential {
87
- /** JWT subscriber access token (SAT). */
87
+ /** JWT user access token (SAT). */
88
88
  token?: string;
89
89
  /** Pre-authorized session state (alternative to token). */
90
90
  authorizationState?: string;
@@ -520,7 +520,7 @@ interface HTTPRequestControllerOptions {
520
520
  retryDelayMax?: number;
521
521
  requestTimeout?: number;
522
522
  }
523
- declare class HTTPRequestController {
523
+ declare class HTTPRequestController extends Destroyable {
524
524
  private baseURL;
525
525
  private readonly getCredential;
526
526
  private static readonly defaultMaxRetries;
@@ -626,57 +626,57 @@ interface SATClaims {
626
626
  expires_at?: number;
627
627
  }
628
628
  //#endregion
629
- //#region src/core/types/subscriber.types.d.ts
630
- /** Raw subscriber profile response from the SignalWire Fabric API. */
631
- interface GetSubscriberInfoResponse {
632
- /** Unique subscriber identifier. */
629
+ //#region src/core/types/user.types.d.ts
630
+ /** Raw user profile response from the SignalWire Fabric API. */
631
+ interface GetUserInfoResponse {
632
+ /** Unique user identifier. */
633
633
  id: string;
634
- /** Subscriber's email address. */
634
+ /** User's email address. */
635
635
  email: string;
636
- /** Subscriber's first name. */
636
+ /** User's first name. */
637
637
  first_name?: string;
638
- /** Subscriber's last name. */
638
+ /** User's last name. */
639
639
  last_name?: string;
640
- /** Subscriber's display name. */
640
+ /** User's display name. */
641
641
  display_name?: string;
642
- /** Subscriber's job title. */
642
+ /** User's job title. */
643
643
  job_title?: string;
644
- /** Subscriber's time zone offset. */
644
+ /** User's time zone offset. */
645
645
  time_zone?: number;
646
- /** Subscriber's country. */
646
+ /** User's country. */
647
647
  country?: string;
648
- /** Subscriber's region or state. */
648
+ /** User's region or state. */
649
649
  region?: string;
650
- /** Subscriber's company name. */
650
+ /** User's company name. */
651
651
  company_name?: string;
652
652
  /** Key for push notification delivery. */
653
653
  push_notification_key: string;
654
- /** Application-level settings for this subscriber. */
654
+ /** Application-level settings for this user. */
655
655
  app_settings?: {
656
656
  /** Display name configured at the application level. */
657
657
  display_name: string;
658
- /** Permission scopes granted to this subscriber. */
658
+ /** Permission scopes granted to this user. */
659
659
  scopes: string[];
660
660
  };
661
- /** Fabric addresses associated with this subscriber. */
661
+ /** Fabric addresses associated with this user. */
662
662
  fabric_addresses: GetAddressResponse[];
663
663
  /** Filtered SAT claims (scope, cnf, expires_at) returned when the token has special capabilities. */
664
664
  sat_claims?: SATClaims;
665
665
  }
666
666
  //#endregion
667
- //#region src/core/entities/Subscriber.d.ts
668
- /** Subscriber online presence state. */
669
- type SubscriberPresence = 'online' | 'offline' | 'busy';
667
+ //#region src/core/entities/User.d.ts
668
+ /** User online presence state. */
669
+ type UserPresence = 'online' | 'offline' | 'busy';
670
670
  /**
671
- * Authenticated subscriber profile.
671
+ * Authenticated user profile.
672
672
  *
673
673
  * Fetched automatically when a {@link SignalWire} connects.
674
674
  * Contains identity, contact, and organization details.
675
675
  */
676
- declare class Subscriber extends Fetchable<GetSubscriberInfoResponse> {
677
- /** Unique subscriber identifier. */
676
+ declare class User extends Fetchable<GetUserInfoResponse> {
677
+ /** Unique user identifier. */
678
678
  id: string;
679
- /** Subscriber email address. */
679
+ /** User email address. */
680
680
  email: string;
681
681
  /** First name. */
682
682
  firstName?: string;
@@ -701,12 +701,12 @@ declare class Subscriber extends Fetchable<GetSubscriberInfoResponse> {
701
701
  displayName: string;
702
702
  scopes: string[];
703
703
  };
704
- /** Fabric addresses associated with this subscriber. */
704
+ /** Fabric addresses associated with this user. */
705
705
  addresses: GetAddressResponse[];
706
706
  /** Filtered SAT claims when the token has special capabilities (e.g., refresh scope). */
707
707
  satClaims?: SATClaims;
708
708
  constructor(http: HTTPRequestController);
709
- protected populateInstance(data: GetSubscriberInfoResponse): void;
709
+ protected populateInstance(data: GetUserInfoResponse): void;
710
710
  }
711
711
  //#endregion
712
712
  //#region src/core/types/call.types.d.ts
@@ -1742,11 +1742,31 @@ declare class Participant extends Destroyable implements CallParticipant {
1742
1742
  get videoMuted$(): Observable<boolean | undefined>;
1743
1743
  /** Observable indicating whether the participant is deafened. */
1744
1744
  get deaf$(): Observable<boolean | undefined>;
1745
- /** Observable of the participant's microphone input volume. */
1745
+ /**
1746
+ * Observable of the participant's **server-side** microphone input volume
1747
+ * as reported by the mix engine. This is gain applied on the bridged audio
1748
+ * leg (FreeSWITCH channel read volume), NOT the local browser mic. For a
1749
+ * local PC mic control, see {@link Call.setLocalMicrophoneGain}.
1750
+ *
1751
+ * @see {@link setAudioInputVolume}
1752
+ */
1746
1753
  get inputVolume$(): Observable<number | undefined>;
1747
- /** Observable of the participant's speaker output volume. */
1754
+ /**
1755
+ * Observable of the participant's **server-side** speaker output volume as
1756
+ * reported by the mix engine (FreeSWITCH channel write volume). NOT the
1757
+ * local HTML `<audio>` element volume — set that on your own element.
1758
+ *
1759
+ * @see {@link setAudioOutputVolume}
1760
+ */
1748
1761
  get outputVolume$(): Observable<number | undefined>;
1749
- /** Observable of the microphone input sensitivity level. */
1762
+ /**
1763
+ * Observable of the **conference-only** microphone energy/gate sensitivity
1764
+ * level for this member. Routes through the conferencing mix engine and has
1765
+ * no effect on 1:1 WebRTC calls. Populated from `member.updated` events for
1766
+ * conference members.
1767
+ *
1768
+ * @see {@link setAudioInputSensitivity}
1769
+ */
1750
1770
  get inputSensitivity$(): Observable<number | undefined>;
1751
1771
  /** Observable indicating whether echo cancellation is enabled. */
1752
1772
  get echoCancellation$(): Observable<boolean | undefined>;
@@ -1760,8 +1780,8 @@ declare class Participant extends Destroyable implements CallParticipant {
1760
1780
  get denoise$(): Observable<boolean | undefined>;
1761
1781
  /** Observable of custom metadata for this participant. */
1762
1782
  get meta$(): Observable<Record<string, unknown> | undefined>;
1763
- /** Observable of the participant's subscriber ID. */
1764
- get subscriberId$(): Observable<string | undefined>;
1783
+ /** Observable of the participant's user ID. */
1784
+ get userId$(): Observable<string | undefined>;
1765
1785
  /** Observable of the participant's address ID. */
1766
1786
  get addressId$(): Observable<string | undefined>;
1767
1787
  /** Observable of the server node ID for this participant. */
@@ -1790,11 +1810,21 @@ declare class Participant extends Destroyable implements CallParticipant {
1790
1810
  get videoMuted(): boolean;
1791
1811
  /** Whether the participant is deafened (incoming audio muted). */
1792
1812
  get deaf(): boolean;
1793
- /** Current microphone input volume level, or `undefined` if not set. */
1813
+ /**
1814
+ * Current **server-side** microphone input volume as reported by the mix
1815
+ * engine, or `undefined` if not set. Not the local PC mic — see
1816
+ * {@link Call.setLocalMicrophoneGain} for browser-side control.
1817
+ */
1794
1818
  get inputVolume(): number | undefined;
1795
- /** Current speaker output volume level, or `undefined` if not set. */
1819
+ /**
1820
+ * Current **server-side** speaker output volume from the mix engine, or
1821
+ * `undefined` if not set. Not the local `<audio>` element volume.
1822
+ */
1796
1823
  get outputVolume(): number | undefined;
1797
- /** Current microphone input sensitivity level, or `undefined` if not set. */
1824
+ /**
1825
+ * Current **conference-only** microphone sensitivity/gate level, or
1826
+ * `undefined` if not set. Applies only to conference members.
1827
+ */
1798
1828
  get inputSensitivity(): number | undefined;
1799
1829
  /** Whether echo cancellation is enabled. */
1800
1830
  get echoCancellation(): boolean;
@@ -1808,8 +1838,8 @@ declare class Participant extends Destroyable implements CallParticipant {
1808
1838
  get denoise(): boolean;
1809
1839
  /** Custom metadata for this participant, or `undefined` if not set. */
1810
1840
  get meta(): Record<string, unknown> | undefined;
1811
- /** Subscriber ID of this participant, or `undefined` if not available. */
1812
- get subscriberId(): string | undefined;
1841
+ /** User ID of this participant, or `undefined` if not available. */
1842
+ get userId(): string | undefined;
1813
1843
  /** Address ID of this participant, or `undefined` if not available. */
1814
1844
  get addressId(): string | undefined;
1815
1845
  /** Server node ID for this participant, or `undefined` if not available. */
@@ -1839,15 +1869,40 @@ declare class Participant extends Destroyable implements CallParticipant {
1839
1869
  /** Toggles noise suppression on the audio input. */
1840
1870
  toggleNoiseSuppression(): Promise<void>;
1841
1871
  toggleLowbitrate(): Promise<void>;
1842
- /** Sets the microphone input sensitivity level. */
1872
+ /**
1873
+ * Adjusts the **conference-only** microphone energy gate / sensitivity level
1874
+ * for this member. Routes through the conferencing mix engine
1875
+ * (`signalwire.conferencing member.set_input_sensitivity`) and has no effect
1876
+ * on 1:1 WebRTC calls — for those, use browser audio constraints via
1877
+ * {@link Call.setNoiseSuppression} / {@link Call.setAutoGainControl}.
1878
+ *
1879
+ * This is **not** a local PC mic gain control; it only changes how the
1880
+ * server-side mixer decides to open the mic gate on this participant.
1881
+ *
1882
+ * @param value - Sensitivity level as understood by the conference engine
1883
+ * (integer, larger values are more sensitive).
1884
+ */
1843
1885
  setAudioInputSensitivity(value: number): Promise<void>;
1844
1886
  /**
1845
- * Sets the microphone input volume level.
1887
+ * Sets the **server-side** microphone volume on this participant's bridged
1888
+ * call leg. Applies a multiplier to the audio flowing through the mix
1889
+ * engine (FreeSWITCH channel read volume) — changes what other participants
1890
+ * hear, not what the local browser captures.
1891
+ *
1892
+ * For local PC mic gain, use {@link Call.setLocalMicrophoneGain} instead.
1893
+ *
1846
1894
  * @param value - Volume level (0-100).
1847
1895
  */
1848
1896
  setAudioInputVolume(value: number): Promise<void>;
1849
1897
  /**
1850
- * Sets the speaker output volume level.
1898
+ * Sets the **server-side** speaker volume on this participant's bridged call
1899
+ * leg (FreeSWITCH channel write volume) — what this participant hears from
1900
+ * the mix before it reaches their client.
1901
+ *
1902
+ * For local playback volume (the `<audio>` element the consumer attaches
1903
+ * `remoteStream` to), set `audioElement.volume` directly in the consumer's
1904
+ * code.
1905
+ *
1851
1906
  * @param value - Volume level (0-100).
1852
1907
  */
1853
1908
  setAudioOutputVolume(value: number): Promise<void>;
@@ -2002,7 +2057,7 @@ interface CallParticipant {
2002
2057
  readonly lowbitrate$: Observable<boolean | undefined>;
2003
2058
  readonly denoise$: Observable<boolean | undefined>;
2004
2059
  readonly meta$: Observable<Record<string, unknown> | undefined>;
2005
- readonly subscriberId$: Observable<string | undefined>;
2060
+ readonly userId$: Observable<string | undefined>;
2006
2061
  readonly addressId$: Observable<string | undefined>;
2007
2062
  readonly nodeId$: Observable<string | undefined>;
2008
2063
  readonly isTalking$: Observable<boolean | undefined>;
@@ -2023,7 +2078,7 @@ interface CallParticipant {
2023
2078
  readonly lowbitrate: boolean;
2024
2079
  readonly denoise: boolean;
2025
2080
  readonly meta: Record<string, unknown> | undefined;
2026
- readonly subscriberId: string | undefined;
2081
+ readonly userId: string | undefined;
2027
2082
  readonly addressId: string | undefined;
2028
2083
  readonly nodeId: string | undefined;
2029
2084
  readonly isTalking: boolean;
@@ -2107,7 +2162,12 @@ interface CallAddress {
2107
2162
  type CallStatus = 'new' | 'trying' | 'ringing' | 'connecting' | 'connected' | 'recovering' | 'disconnecting' | 'disconnected' | 'failed' | 'destroyed';
2108
2163
  /** Configuration options for creating a call. */
2109
2164
  interface CallOptions extends MediaOptions {
2110
- /** Target server node ID. */
2165
+ /**
2166
+ * Optional. Hint to the cluster about which node should host this call.
2167
+ * Used by reattach to pin to the original node; on fresh dials acts as a
2168
+ * steering preference (the server may ignore for placement reasons).
2169
+ * Leave undefined for normal load-balanced placement.
2170
+ */
2111
2171
  readonly nodeId?: string;
2112
2172
  /** Pre-assigned call ID (used for reattach). */
2113
2173
  readonly callId?: string;
@@ -2168,6 +2228,9 @@ interface Call extends CallState {
2168
2228
  readonly self$: Observable<CallSelfParticipant | null>;
2169
2229
  readonly self: CallSelfParticipant | null;
2170
2230
  readonly to?: string;
2231
+ readonly toName?: string;
2232
+ readonly from?: string;
2233
+ readonly fromName?: string;
2171
2234
  readonly direction: CallDirection;
2172
2235
  readonly layouts$: Observable<string[]>;
2173
2236
  readonly layouts: string[];
@@ -2225,9 +2288,6 @@ interface Call extends CallState {
2225
2288
  */
2226
2289
  interface CallManager extends Call {
2227
2290
  readonly options: CallOptions;
2228
- readonly fromName?: string;
2229
- readonly from?: string;
2230
- readonly toName?: string;
2231
2291
  readonly selfId$: Observable<string | null>;
2232
2292
  readonly selfId: string | null;
2233
2293
  readonly nodeId$: Observable<string | null>;
@@ -2497,11 +2557,19 @@ declare class AttachManager {
2497
2557
  private readonly reconnectCallsTimeout;
2498
2558
  private attachKey;
2499
2559
  private session;
2560
+ private writeQueue;
2500
2561
  constructor(storage: StorageManager, deviceController: DeviceController, reconnectCallsTimeout: number, attachKey: string);
2501
2562
  detachAll(): Promise<void>;
2502
2563
  setSession(session: OutboundCallProvider): void;
2503
2564
  private readAttached;
2504
2565
  private writeAttached;
2566
+ /**
2567
+ * Serialize a read-modify-write operation against the attached-calls
2568
+ * storage. The mutator receives the current state and returns the new
2569
+ * state. Concurrent calls queue behind the in-flight one so writes never
2570
+ * interleave.
2571
+ */
2572
+ private mutate;
2505
2573
  attach(call: AttachableCall): Promise<void>;
2506
2574
  detach(call: AttachableCall): Promise<void>;
2507
2575
  flush(): Promise<void>;
@@ -2527,10 +2595,15 @@ declare class AttachManager {
2527
2595
  */
2528
2596
  buildCallOptions(attachment: Attachment): CallOptions;
2529
2597
  /**
2530
- * Consume stored attachment data for a pending call (used by session-level
2531
- * verto.attach handler as a future path when server supports it).
2598
+ * Look up stored attachment data for a call id and return CallOptions
2599
+ * suitable for rehydrating a reattached call. Returns undefined when no
2600
+ * matching entry exists in storage.
2601
+ *
2602
+ * Used by the session-level verto.attach handler when the server pushes
2603
+ * an attach event for a call the client doesn't have an object for yet
2604
+ * (e.g. after a reload).
2532
2605
  */
2533
- consumePendingAttachment(_callId: string): CallOptions | undefined;
2606
+ consumePendingAttachment(callId: string): Promise<CallOptions | undefined>;
2534
2607
  private detachExpired;
2535
2608
  }
2536
2609
  //#endregion
@@ -2826,14 +2899,14 @@ declare class ClientSessionManager extends Destroyable implements SessionState {
2826
2899
  private _authState$;
2827
2900
  /** Sticky flag — once true, stays true for the session lifetime. */
2828
2901
  private _wasClientBound;
2829
- private _subscriberInfo$;
2902
+ private _userInfo$;
2830
2903
  private _calls$;
2831
2904
  private _iceServers$;
2832
2905
  constructor(getCredential: () => SDKCredential, transport: TransportManager, storage: StorageManager, authorizationStateKey: string, deviceController: DeviceController, attachManager: AttachManager, webRTCApiProvider: WebRTCApiProvider, dpopManager?: CryptoController | undefined, networkChange$?: Observable<NetworkChangeEvent>);
2833
2906
  get incomingCalls$(): Observable<Call[]>;
2834
2907
  get incomingCalls(): Call[];
2835
- get subscriberInfo$(): Observable<Address | null>;
2836
- get subscriberInfo(): Address | null;
2908
+ get userInfo$(): Observable<Address | null>;
2909
+ get userInfo(): Address | null;
2837
2910
  get calls$(): Observable<Call[]>;
2838
2911
  get calls(): Call[];
2839
2912
  get iceServers(): RTCIceServer[] | undefined;
@@ -3221,11 +3294,30 @@ interface SDKLogger {
3221
3294
  debug(...args: unknown[]): void;
3222
3295
  trace(...args: unknown[]): void;
3223
3296
  }
3297
+ /** Options for WebSocket traffic logging. */
3298
+ interface WsTrafficOptions {
3299
+ type: 'send' | 'recv' | 'http';
3300
+ /** Parsed object or raw string — will be JSON.stringify'd for display if an object. */
3301
+ payload: unknown;
3302
+ }
3303
+ /**
3304
+ * Options for WebSocket traffic logging using raw strings.
3305
+ * The string is only parsed when logging is enabled, avoiding
3306
+ * unnecessary JSON.parse on every message.
3307
+ */
3308
+ interface WsTrafficRawOptions {
3309
+ type: 'send' | 'recv';
3310
+ raw: string;
3311
+ }
3224
3312
  /** Debug options that control verbose SDK logging. */
3225
3313
  interface DebugOptions {
3226
3314
  /** Log all WebSocket send/recv traffic to the console. */
3227
3315
  logWsTraffic?: boolean;
3228
3316
  }
3317
+ /** Extended logger with SDK-internal helpers (wsTraffic). */
3318
+ interface InternalSDKLogger extends SDKLogger {
3319
+ wsTraffic: (options: WsTrafficOptions | WsTrafficRawOptions) => void;
3320
+ }
3229
3321
  /** Replace the built-in logger with a custom implementation. Pass `null` to restore defaults. */
3230
3322
  declare const setLogger: (logger: SDKLogger | null) => void;
3231
3323
  /** Configure debug options (e.g., `{ logWsTraffic: true }`). */
@@ -3235,13 +3327,14 @@ declare const setDebugOptions: (options: DebugOptions | null) => void;
3235
3327
  * Has no effect when a custom logger is set via `setLogger()`.
3236
3328
  */
3237
3329
  declare const setLogLevel: (level: LogLevel) => void;
3330
+ declare const getLogger: () => InternalSDKLogger;
3238
3331
  //#endregion
3239
3332
  //#region src/clients/SignalWire.d.ts
3240
3333
  /** Options for constructing a {@link SignalWire}. */
3241
3334
  interface SignalWireOptions {
3242
3335
  /** Skip automatic WebSocket connection on construction. */
3243
3336
  skipConnection?: boolean;
3244
- /** Skip automatic subscriber registration on construction. */
3337
+ /** Skip automatic user registration on construction. */
3245
3338
  skipRegister?: boolean;
3246
3339
  /** Skip monitoring media device changes. */
3247
3340
  skipDeviceMonitoring?: boolean;
@@ -3298,6 +3391,12 @@ interface DialOptions extends MediaOptions {
3298
3391
  stereo?: boolean;
3299
3392
  /** Optional node ID for routing the call */
3300
3393
  nodeId?: string;
3394
+ /**
3395
+ * Custom variables sent with the Verto invite. Merged with
3396
+ * `client.preferences.userVariables` and any query-string variables on the
3397
+ * destination URI; values here take precedence.
3398
+ */
3399
+ userVariables?: Record<string, unknown>;
3301
3400
  }
3302
3401
  /**
3303
3402
  * Main entry point for the SignalWire Browser SDK.
@@ -3314,7 +3413,7 @@ interface DialOptions extends MediaOptions {
3314
3413
  declare class SignalWire extends Destroyable implements DeviceController {
3315
3414
  /** Global SDK preferences (timeouts, ICE config, media defaults). */
3316
3415
  preferences: ClientPreferences;
3317
- private _subscriber$;
3416
+ private _user$;
3318
3417
  private _directory$;
3319
3418
  private _transport;
3320
3419
  private _clientSession;
@@ -3404,19 +3503,19 @@ declare class SignalWire extends Destroyable implements DeviceController {
3404
3503
  */
3405
3504
  connect(): Promise<void>;
3406
3505
  /**
3407
- * Observable that emits the {@link Subscriber} profile once fetched,
3506
+ * Observable that emits the {@link User} profile once fetched,
3408
3507
  * or `undefined` before authentication completes.
3409
3508
  *
3410
3509
  * @example
3411
3510
  * ```ts
3412
- * client.subscriber$.subscribe(sub => {
3413
- * if (sub) console.log('Logged in as', sub.email);
3511
+ * client.user$.subscribe(u => {
3512
+ * if (u) console.log('Logged in as', u.email);
3414
3513
  * });
3415
3514
  * ```
3416
3515
  */
3417
- get subscriber$(): Observable<Subscriber | undefined>;
3418
- /** Current subscriber snapshot, or `undefined` if not yet authenticated. */
3419
- get subscriber(): Subscriber | undefined;
3516
+ get user$(): Observable<User | undefined>;
3517
+ /** Current user snapshot, or `undefined` if not yet authenticated. */
3518
+ get user(): User | undefined;
3420
3519
  /**
3421
3520
  * Observable that emits the {@link Directory} instance once the client is connected,
3422
3521
  * or `undefined` while disconnected. Subscribe to this to safely wait for the directory
@@ -3435,9 +3534,9 @@ declare class SignalWire extends Destroyable implements DeviceController {
3435
3534
  * Prefer {@link directory$} when you need to react to the directory becoming available.
3436
3535
  */
3437
3536
  get directory(): Directory | undefined;
3438
- /** Observable that emits when the subscriber registration state changes. */
3537
+ /** Observable that emits when the user registration state changes. */
3439
3538
  get isRegistered$(): Observable<boolean>;
3440
- /** Whether the subscriber is currently registered. */
3539
+ /** Whether the user is currently registered. */
3441
3540
  get isRegistered(): boolean;
3442
3541
  /** Whether the client is currently connected. */
3443
3542
  get isConnected(): boolean;
@@ -3468,9 +3567,14 @@ declare class SignalWire extends Destroyable implements DeviceController {
3468
3567
  * which creates a fresh transport and session.
3469
3568
  */
3470
3569
  disconnect(): Promise<void>;
3570
+ /**
3571
+ * Tear down the current transport / session / attach manager. Safe to call
3572
+ * when nothing has been initialized yet (e.g. first connect()).
3573
+ */
3574
+ private teardownTransportAndSession;
3471
3575
  private waitAuthentication;
3472
3576
  /**
3473
- * Registers the subscriber as online to receive inbound calls and events.
3577
+ * Registers the user as online to receive inbound calls and events.
3474
3578
  *
3475
3579
  * Waits for authentication to complete before sending the registration.
3476
3580
  * If the initial attempt fails, reauthentication is attempted automatically.
@@ -3479,7 +3583,7 @@ declare class SignalWire extends Destroyable implements DeviceController {
3479
3583
  */
3480
3584
  register(): Promise<void>;
3481
3585
  /**
3482
- * Unregisters the subscriber, going offline for inbound calls.
3586
+ * Unregisters the user, going offline for inbound calls.
3483
3587
  *
3484
3588
  * The WebSocket connection remains open; use {@link disconnect} to fully close it.
3485
3589
  */
@@ -3568,6 +3672,21 @@ declare class SignalWire extends Destroyable implements DeviceController {
3568
3672
  selectVideoInputDevice(device: MediaDeviceInfo | null): void;
3569
3673
  /** Sets the preferred audio output device. */
3570
3674
  selectAudioOutputDevice(device: MediaDeviceInfo | null): void;
3675
+ /**
3676
+ * Apply the currently selected audio output device to an HTMLMediaElement
3677
+ * (e.g. the `<audio>` or `<video>` element the consumer attached the
3678
+ * remote stream to). Uses `HTMLMediaElement.setSinkId` under the hood.
3679
+ * Returns a `Promise<boolean>`: `true` if the sink was applied,
3680
+ * `false` if the browser doesn't support `setSinkId` or no device is
3681
+ * selected.
3682
+ *
3683
+ * @example
3684
+ * ```ts
3685
+ * audioEl.srcObject = call.remoteStream;
3686
+ * await client.applySelectedAudioOutputDevice(audioEl);
3687
+ * ```
3688
+ */
3689
+ applySelectedAudioOutputDevice(element: HTMLMediaElement): Promise<boolean>;
3571
3690
  /** Starts monitoring for media device changes (connect/disconnect). */
3572
3691
  enableDeviceMonitoring(): void;
3573
3692
  /** Stops monitoring for media device changes. */
@@ -3668,6 +3787,126 @@ declare class StaticCredentialProvider implements CredentialProvider {
3668
3787
  authenticate(): Promise<SDKCredential>;
3669
3788
  }
3670
3789
  //#endregion
3790
+ //#region src/dependencies/EmbedTokenCredentialProvider.d.ts
3791
+ /** Credential provider that exchanges an embed token for a SAT via the host's token endpoint. */
3792
+ declare class EmbedTokenCredentialProvider implements CredentialProvider {
3793
+ private host;
3794
+ private embedToken;
3795
+ constructor(host: string, embedToken: string);
3796
+ private fetchSAT;
3797
+ authenticate(): Promise<{
3798
+ token: string;
3799
+ expiry_at: number;
3800
+ }>;
3801
+ refresh(): Promise<{
3802
+ token: string;
3803
+ expiry_at: number;
3804
+ }>;
3805
+ }
3806
+ //#endregion
3807
+ //#region src/controllers/LocalAudioPipeline.d.ts
3808
+ /**
3809
+ * Options for {@link LocalAudioPipeline}.
3810
+ */
3811
+ interface LocalAudioPipelineOptions {
3812
+ /** Factory for AudioContext — override for tests. Defaults to `new AudioContext()`. */
3813
+ audioContextFactory?: () => AudioContext;
3814
+ /** Initial gain (0..2, where 1 is unity). Defaults to 1. */
3815
+ initialGain?: number;
3816
+ /** RMS level [0..1] above which speaking$ emits true. Defaults to {@link VAD_THRESHOLD}. */
3817
+ speakingThreshold?: number;
3818
+ /**
3819
+ * Milliseconds of silence below the threshold before speaking$ flips back to
3820
+ * false. Prevents flicker on normal speech gaps. Defaults to {@link VAD_HOLD_MS}.
3821
+ */
3822
+ speakingHoldMs?: number;
3823
+ /** Polling interval for level$. Defaults to {@link AUDIO_LEVEL_POLL_INTERVAL_MS}. */
3824
+ pollIntervalMs?: number;
3825
+ }
3826
+ /**
3827
+ * Web Audio pipeline for the local microphone stream.
3828
+ *
3829
+ * Wraps the raw mic `MediaStreamTrack` in a graph of:
3830
+ *
3831
+ * ```
3832
+ * MediaStreamAudioSourceNode → GainNode → AnalyserNode → MediaStreamAudioDestinationNode
3833
+ * ```
3834
+ *
3835
+ * The {@link outputTrack} from the destination node is what callers should
3836
+ * attach to the `RTCRtpSender` in place of the raw mic track. The same
3837
+ * destination track is reused across input changes (device switch, mute /
3838
+ * unmute track replacement) so the sender reference stays stable — only the
3839
+ * source end of the graph is rebuilt.
3840
+ *
3841
+ * The pipeline owns a single {@link AudioContext}. Callers must invoke
3842
+ * {@link destroy} to release it when the call ends.
3843
+ */
3844
+ declare class LocalAudioPipeline extends Destroyable {
3845
+ private readonly _audioContext;
3846
+ private readonly _gainNode;
3847
+ private readonly _analyser;
3848
+ private readonly _destination;
3849
+ private readonly _analyserBuffer;
3850
+ private readonly _speakingThreshold;
3851
+ private readonly _speakingHoldMs;
3852
+ private readonly _pollIntervalMs;
3853
+ private _inputSource;
3854
+ private _inputStream;
3855
+ private _lastSpokeAt;
3856
+ private _gain$;
3857
+ /** 1 when audio should pass through, 0 when silenced by PTT. */
3858
+ private _pttMultiplier;
3859
+ constructor(options?: LocalAudioPipelineOptions);
3860
+ /** Observable of the current gain value (0..2). */
3861
+ get gain$(): Observable<number>;
3862
+ /** Current gain value (0..2). */
3863
+ get gain(): number;
3864
+ /**
3865
+ * Processed output track to attach to the RTCRtpSender. Stable reference
3866
+ * across input changes, so `sender.replaceTrack(pipeline.outputTrack)` only
3867
+ * needs to be called once.
3868
+ */
3869
+ get outputTrack(): MediaStreamTrack;
3870
+ /**
3871
+ * Root-mean-square audio level of the input signal, 0..1. Emits on a fixed
3872
+ * interval (~30fps by default).
3873
+ */
3874
+ get level$(): Observable<number>;
3875
+ /**
3876
+ * Boolean VAD derived from {@link level$}. True while level ≥ threshold or
3877
+ * during the hold window after the last frame that crossed the threshold.
3878
+ */
3879
+ get speaking$(): Observable<boolean>;
3880
+ /**
3881
+ * Set gain multiplier applied to the input signal. 0 = silence,
3882
+ * 1 = unity, 2 = 2x. Values are clamped to [0, 2]. The effective gain on
3883
+ * the graph also respects the current PTT state.
3884
+ */
3885
+ setGain(value: number): void;
3886
+ /**
3887
+ * Silence the graph when `active = false`, otherwise restore the configured
3888
+ * gain. Use this from a PTT handler: released → `false`, held → `true`.
3889
+ * Orthogonal to {@link setGain} — once PTT returns to active, the last
3890
+ * configured gain reappears.
3891
+ */
3892
+ setPTTActive(active: boolean): void;
3893
+ private applyEffectiveGain;
3894
+ /**
3895
+ * Wire a new raw mic track as the pipeline's input. Replaces any previous
3896
+ * input source and reconnects the graph so {@link outputTrack} continues
3897
+ * to emit the processed audio. Pass `null` to disconnect the input (the
3898
+ * output track stays alive but emits silence).
3899
+ *
3900
+ * Also resumes the underlying AudioContext on attach — Chrome creates it
3901
+ * in a suspended state and the graph won't process (the destination
3902
+ * track emits silence) until resume() succeeds.
3903
+ */
3904
+ setInputTrack(track: MediaStreamTrack | null): void;
3905
+ destroy(): void;
3906
+ private computeLevel;
3907
+ private evaluateSpeaking;
3908
+ }
3909
+ //#endregion
3671
3910
  //#region src/controllers/RTCPeerConnectionController.d.ts
3672
3911
  interface RTCPeerConnectionControllerOptions extends MediaOptions {
3673
3912
  callId?: string;
@@ -3728,6 +3967,7 @@ declare class RTCPeerConnectionController extends Destroyable {
3728
3967
  private _remoteDescription$;
3729
3968
  private _remoteStream$;
3730
3969
  private _remoteOfferMediaDirections;
3970
+ private _localAudioPipeline;
3731
3971
  constructor(options?: RTCPeerConnectionControllerOptionsPartial, remoteSessionDescription?: string, deviceController?: DeviceController);
3732
3972
  private get iceGatheringController();
3733
3973
  private get shouldEmitLocalDescription();
@@ -3815,7 +4055,6 @@ declare class RTCPeerConnectionController extends Destroyable {
3815
4055
  */
3816
4056
  private setupEventListeners;
3817
4057
  private negotiationEnded;
3818
- restarIce(): void;
3819
4058
  /**
3820
4059
  * Trigger an ICE restart through the existing negotiation pipeline.
3821
4060
  *
@@ -3841,6 +4080,17 @@ declare class RTCPeerConnectionController extends Destroyable {
3841
4080
  private getDisplayMedia;
3842
4081
  private setupRemoteTracks;
3843
4082
  restoreTrackSender(kind: 'audio' | 'video' | 'both'): Promise<void>;
4083
+ /**
4084
+ * Return the lazily-created {@link LocalAudioPipeline}, constructing it on
4085
+ * first access. On creation the current audio sender's track is routed
4086
+ * through the pipeline (input → gain → analyser → destination) and the
4087
+ * sender is switched to emit the processed track. Returns `null` when no
4088
+ * audio sender exists yet (pre-negotiation).
4089
+ */
4090
+ ensureLocalAudioPipeline(): LocalAudioPipeline | null;
4091
+ /** The active LocalAudioPipeline, or null if it hasn't been created yet. */
4092
+ get localAudioPipeline(): LocalAudioPipeline | null;
4093
+ private applyLocalAudioPipelineToSender;
3844
4094
  /**
3845
4095
  * Add a local media track to the peer connection.
3846
4096
  * @param track - The MediaStreamTrack to add
@@ -3911,6 +4161,10 @@ interface WebRTCVerto extends VertoManager {
3911
4161
  requestIceRestartAll?: (relayOnly?: boolean) => Promise<void>;
3912
4162
  /** Request keyframes on all video-receiving legs (skips send-only screen share). */
3913
4163
  requestKeyframeAll?: () => void;
4164
+ /** Lazily create (or return) the local audio pipeline for the main peer connection. */
4165
+ ensureLocalAudioPipeline(): LocalAudioPipeline | null;
4166
+ /** Current local audio pipeline, or null if it has not been created yet. */
4167
+ readonly localAudioPipeline: LocalAudioPipeline | null;
3914
4168
  }
3915
4169
  //#endregion
3916
4170
  //#region src/managers/CallEventsManager.d.ts
@@ -4058,6 +4312,8 @@ declare class WebRTCCall extends Destroyable implements CallManager {
4058
4312
  private _bandwidthConstrained$;
4059
4313
  private _mediaParamsUpdated$;
4060
4314
  private _customSubscriptions;
4315
+ private _pushToTalkEnabled;
4316
+ private _remoteAudioMeter;
4061
4317
  constructor(clientSession: ClientSession, options: CallOptions, initialization: CallInitialization, address?: Address | undefined);
4062
4318
  /** Observable stream of errors from media, signaling, and peer connection layers. */
4063
4319
  get errors$(): Observable<CallError>;
@@ -4221,6 +4477,16 @@ declare class WebRTCCall extends Destroyable implements CallManager {
4221
4477
  * Called from within the status subscription to wire stats and recovery.
4222
4478
  */
4223
4479
  private initResilienceSubsystems;
4480
+ /**
4481
+ * Wait for the underlying RTCPeerConnection to reach 'connected' after
4482
+ * triggering an ICE restart. Resolves true on success, false on failure
4483
+ * or if the state doesn't transition within the configured timeout.
4484
+ *
4485
+ * Polls connectionState directly because the recovery manager already
4486
+ * wraps this call in its own withTimeout(); a separate listener-based
4487
+ * implementation would race the outer timeout in subtle ways.
4488
+ */
4489
+ private waitForPeerConnectionConnected;
4224
4490
  /**
4225
4491
  * @internal Stop and destroy resilience subsystems (on disconnect/destroy).
4226
4492
  * Clears references so they can be re-created on reconnect.
@@ -4375,12 +4641,86 @@ declare class WebRTCCall extends Destroyable implements CallManager {
4375
4641
  * @see {@link status$} to observe the transfer progress.
4376
4642
  */
4377
4643
  transfer(options: TransferOptions): Promise<void>;
4644
+ /**
4645
+ * Set the local microphone gain as a percentage applied before transmission.
4646
+ *
4647
+ * - `0` = silent
4648
+ * - `100` = unity (no change, default)
4649
+ * - `200` = 2× digital boost (max; expect clipping / noise amplification)
4650
+ *
4651
+ * Values are clamped to [0, 200]. Engages the local audio pipeline on
4652
+ * first use (one-time cost).
4653
+ *
4654
+ * Note: this is a **digital** multiplier applied in a Web Audio GainNode
4655
+ * between your mic track and the RTCRtpSender — it does not change the
4656
+ * physical mic's hardware sensitivity. Browsers' autoGainControl can
4657
+ * fight the setting; call {@link setAutoGainControl}(false) for
4658
+ * predictable behaviour.
4659
+ *
4660
+ * @param value - Gain percentage (0..200; 100 = unity).
4661
+ */
4662
+ setLocalMicrophoneGain(value: number): void;
4663
+ /** Observable of the current local microphone gain (0..200, where 100 = unity). */
4664
+ get localMicrophoneGain$(): Observable<number>;
4665
+ /**
4666
+ * Observable of the RMS audio level of the local microphone, 0..1.
4667
+ * Emits at ~30fps while a mic track is active. Engages the local audio
4668
+ * pipeline on first subscription.
4669
+ */
4670
+ get localAudioLevel$(): Observable<number>;
4671
+ /**
4672
+ * Observable that is `true` while the local participant is speaking
4673
+ * (RMS level above the VAD threshold, with hold time to avoid flicker).
4674
+ */
4675
+ get localSpeaking$(): Observable<boolean>;
4676
+ /**
4677
+ * Enable push-to-talk: while {@link setPushToTalkActive} has been called
4678
+ * with `false`, the microphone gain is forced to 0; calling
4679
+ * {@link setPushToTalkActive} with `true` restores the configured gain.
4680
+ * Use this instead of mute/unmute for instant talk/silence transitions
4681
+ * because it doesn't rebuild the track.
4682
+ *
4683
+ * This method installs the pipeline but does not attach any keyboard
4684
+ * listener — consumers bind the key themselves and call
4685
+ * {@link setPushToTalkActive} on keydown/keyup.
4686
+ */
4687
+ enablePushToTalk(): void;
4688
+ /** Disable push-to-talk; mic gain returns to the configured value. */
4689
+ disablePushToTalk(): void;
4690
+ /**
4691
+ * While push-to-talk is enabled, sets the talk state. `true` = transmitting,
4692
+ * `false` = silent. No-op if push-to-talk has not been enabled.
4693
+ */
4694
+ setPushToTalkActive(active: boolean): void;
4695
+ /**
4696
+ * Toggle echo cancellation on the local mic at runtime. Applied via
4697
+ * `track.applyConstraints`; browsers that don't honour runtime constraints
4698
+ * (notably iOS Safari) fall back to re-acquiring the track with the new
4699
+ * constraint set and plumbing the replacement through the local audio
4700
+ * pipeline if one is active.
4701
+ */
4702
+ setEchoCancellation(enabled: boolean): Promise<void>;
4703
+ /** Toggle browser noise suppression on the local mic at runtime. */
4704
+ setNoiseSuppression(enabled: boolean): Promise<void>;
4705
+ /** Toggle browser automatic gain control on the local mic at runtime. */
4706
+ setAutoGainControl(enabled: boolean): Promise<void>;
4707
+ /**
4708
+ * Observable of the aggregate remote audio level, 0..1 RMS. The server
4709
+ * delivers a single mixed audio stream for all remote participants — this
4710
+ * meter reports that mix. Per-participant audio is not available client-side.
4711
+ *
4712
+ * Engages a shared AudioContext on first subscription (cheap — one
4713
+ * AnalyserNode, no GainNode, no destination) so it does not affect the
4714
+ * caller's audio element playback.
4715
+ */
4716
+ get remoteAudioLevel$(): Observable<number>;
4378
4717
  /** Destroys the call, releasing all resources and subscriptions. */
4379
4718
  destroy(): void;
4380
4719
  /**
4381
4720
  * @internal Send a verto.subscribe message to add an event type to the
4382
- * server's subscription list for this call. Best-effort failures are
4383
- * logged but don't prevent the filtered observable from being returned.
4721
+ * server's subscription list for this call. Returns the underlying RPC
4722
+ * promise so callers can decide whether to cache the observable on success
4723
+ * or retry on failure.
4384
4724
  */
4385
4725
  private _sendVertoSubscribe;
4386
4726
  }
@@ -4397,5 +4737,5 @@ declare const version: string;
4397
4737
  */
4398
4738
  declare const ready: boolean;
4399
4739
  //#endregion
4400
- 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 CredentialProvider, DPoPInitError, type DebugOptions, type DeviceController, type DeviceRecoveryEvent, DeviceTokenError, type DiagnosticEvent, type DialOptions, type Directory, 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 ScreenShareStatus, type SelectDeviceOptions, SelfCapabilities, SelfParticipant, type SessionDiagnostics, type SessionState, SignalWire, type SignalWireOptions, StaticCredentialProvider, type Storage, type StoredDevicePreference, Subscriber, type SubscriberPresence, type TextMessage, TokenRefreshError, type TransferOptions, UnexpectedError, VertoPongError, type VideoPosition, type WebRTCApiProvider, WebRTCCall, type WebRTCMediaDevices, type WebSocketAdapter, embeddableCall, isSelfParticipant, ready, setDebugOptions, setLogLevel, setLogger, version };
4740
+ 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 CredentialProvider, 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 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 };
4401
4741
  //# sourceMappingURL=index.d.mts.map