@signalwire/js 4.0.0-dev-20260326210326 → 4.0.0-dev-20260401154549

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 CHANGED
@@ -4140,7 +4140,7 @@ var require_timer = /* @__PURE__ */ __commonJSMin(((exports) => {
4140
4140
  var async_1$11 = require_async();
4141
4141
  var isScheduler_1 = require_isScheduler();
4142
4142
  var isDate_1$1 = require_isDate();
4143
- function timer(dueTime, intervalOrScheduler, scheduler) {
4143
+ function timer$1(dueTime, intervalOrScheduler, scheduler) {
4144
4144
  if (dueTime === void 0) dueTime = 0;
4145
4145
  if (scheduler === void 0) scheduler = async_1$11.async;
4146
4146
  var intervalDuration = -1;
@@ -4159,7 +4159,7 @@ var require_timer = /* @__PURE__ */ __commonJSMin(((exports) => {
4159
4159
  }, due);
4160
4160
  });
4161
4161
  }
4162
- exports.timer = timer;
4162
+ exports.timer = timer$1;
4163
4163
  }));
4164
4164
 
4165
4165
  //#endregion
@@ -4293,7 +4293,7 @@ var require_filter = /* @__PURE__ */ __commonJSMin(((exports) => {
4293
4293
  exports.filter = void 0;
4294
4294
  var lift_1$62 = require_lift();
4295
4295
  var OperatorSubscriber_1$49 = require_OperatorSubscriber();
4296
- function filter$12(predicate, thisArg) {
4296
+ function filter$13(predicate, thisArg) {
4297
4297
  return lift_1$62.operate(function(source, subscriber) {
4298
4298
  var index = 0;
4299
4299
  source.subscribe(OperatorSubscriber_1$49.createOperatorSubscriber(subscriber, function(value) {
@@ -4301,7 +4301,7 @@ var require_filter = /* @__PURE__ */ __commonJSMin(((exports) => {
4301
4301
  }));
4302
4302
  });
4303
4303
  }
4304
- exports.filter = filter$12;
4304
+ exports.filter = filter$13;
4305
4305
  }));
4306
4306
 
4307
4307
  //#endregion
@@ -5627,9 +5627,9 @@ var require_exhaustMap = /* @__PURE__ */ __commonJSMin(((exports) => {
5627
5627
  var innerFrom_1$16 = require_innerFrom();
5628
5628
  var lift_1$39 = require_lift();
5629
5629
  var OperatorSubscriber_1$28 = require_OperatorSubscriber();
5630
- function exhaustMap$1(project, resultSelector) {
5630
+ function exhaustMap$2(project, resultSelector) {
5631
5631
  if (resultSelector) return function(source) {
5632
- return source.pipe(exhaustMap$1(function(a, i) {
5632
+ return source.pipe(exhaustMap$2(function(a, i) {
5633
5633
  return innerFrom_1$16.innerFrom(project(a, i)).pipe(map_1$4.map(function(b, ii) {
5634
5634
  return resultSelector(a, b, i, ii);
5635
5635
  }));
@@ -5653,7 +5653,7 @@ var require_exhaustMap = /* @__PURE__ */ __commonJSMin(((exports) => {
5653
5653
  }));
5654
5654
  });
5655
5655
  }
5656
- exports.exhaustMap = exhaustMap$1;
5656
+ exports.exhaustMap = exhaustMap$2;
5657
5657
  }));
5658
5658
 
5659
5659
  //#endregion
@@ -6825,12 +6825,12 @@ var require_skip = /* @__PURE__ */ __commonJSMin(((exports) => {
6825
6825
  Object.defineProperty(exports, "__esModule", { value: true });
6826
6826
  exports.skip = void 0;
6827
6827
  var filter_1$3 = require_filter();
6828
- function skip$2(count$1) {
6828
+ function skip$3(count$1) {
6829
6829
  return filter_1$3.filter(function(_, index) {
6830
6830
  return count$1 <= index;
6831
6831
  });
6832
6832
  }
6833
- exports.skip = skip$2;
6833
+ exports.skip = skip$3;
6834
6834
  }));
6835
6835
 
6836
6836
  //#endregion
@@ -6934,7 +6934,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6934
6934
  var innerFrom_1$6 = require_innerFrom();
6935
6935
  var lift_1$13 = require_lift();
6936
6936
  var OperatorSubscriber_1$11 = require_OperatorSubscriber();
6937
- function switchMap$4(project, resultSelector) {
6937
+ function switchMap$5(project, resultSelector) {
6938
6938
  return lift_1$13.operate(function(source, subscriber) {
6939
6939
  var innerSubscriber = null;
6940
6940
  var index = 0;
@@ -6958,7 +6958,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6958
6958
  }));
6959
6959
  });
6960
6960
  }
6961
- exports.switchMap = switchMap$4;
6961
+ exports.switchMap = switchMap$5;
6962
6962
  }));
6963
6963
 
6964
6964
  //#endregion
@@ -8933,12 +8933,12 @@ var require_cjs = /* @__PURE__ */ __commonJSMin(((exports) => {
8933
8933
 
8934
8934
  //#endregion
8935
8935
  //#region src/behaviors/Destroyable.ts
8936
- var import_cjs$22 = require_cjs();
8936
+ var import_cjs$23 = require_cjs();
8937
8937
  var Destroyable = class {
8938
8938
  constructor() {
8939
8939
  this.subscriptions = [];
8940
8940
  this.subjects = [];
8941
- this._destroyed$ = new import_cjs$22.Subject();
8941
+ this._destroyed$ = new import_cjs$23.Subject();
8942
8942
  }
8943
8943
  destroy() {
8944
8944
  this._observableCache?.clear();
@@ -8974,7 +8974,7 @@ var Destroyable = class {
8974
8974
  this._observableCache ??= /* @__PURE__ */ new Map();
8975
8975
  let cached = this._observableCache.get(publicKey);
8976
8976
  if (!cached) {
8977
- cached = factory().pipe((0, import_cjs$22.observeOn)(import_cjs$22.asapScheduler));
8977
+ cached = factory().pipe((0, import_cjs$23.observeOn)(import_cjs$23.asapScheduler));
8978
8978
  this._observableCache.set(publicKey, cached);
8979
8979
  }
8980
8980
  return cached;
@@ -8988,29 +8988,29 @@ var Destroyable = class {
8988
8988
  * Do NOT use for observables consumed internally by the SDK.
8989
8989
  */
8990
8990
  deferEmission(observable) {
8991
- return observable.pipe((0, import_cjs$22.observeOn)(import_cjs$22.asapScheduler));
8991
+ return observable.pipe((0, import_cjs$23.observeOn)(import_cjs$23.asapScheduler));
8992
8992
  }
8993
8993
  subscribeTo(observable, observerOrNext) {
8994
8994
  const subscription = observable.subscribe(observerOrNext);
8995
8995
  this.subscriptions.push(subscription);
8996
8996
  }
8997
8997
  createSubject() {
8998
- const subject = new import_cjs$22.Subject();
8998
+ const subject = new import_cjs$23.Subject();
8999
8999
  this.subjects.push(subject);
9000
9000
  return subject;
9001
9001
  }
9002
9002
  createReplaySubject(bufferSize, windowTime$1) {
9003
- const subject = new import_cjs$22.ReplaySubject(bufferSize, windowTime$1);
9003
+ const subject = new import_cjs$23.ReplaySubject(bufferSize, windowTime$1);
9004
9004
  this.subjects.push(subject);
9005
9005
  return subject;
9006
9006
  }
9007
9007
  createBehaviorSubject(initialValue) {
9008
- const subject = new import_cjs$22.BehaviorSubject(initialValue);
9008
+ const subject = new import_cjs$23.BehaviorSubject(initialValue);
9009
9009
  this.subjects.push(subject);
9010
9010
  return subject;
9011
9011
  }
9012
9012
  get $() {
9013
- return this.cachedObservable("$", () => (0, import_cjs$22.merge)(...this.subjects.map((s) => s instanceof import_cjs$22.BehaviorSubject ? s.pipe((0, import_cjs$22.skip)(1)) : s)).pipe((0, import_cjs$22.map)((_) => this)));
9013
+ return this.cachedObservable("$", () => (0, import_cjs$23.merge)(...this.subjects.map((s) => s instanceof import_cjs$23.BehaviorSubject ? s.pipe((0, import_cjs$23.skip)(1)) : s)).pipe((0, import_cjs$23.map)((_) => this)));
9014
9014
  }
9015
9015
  /**
9016
9016
  * Observable that emits when the instance is destroyed
@@ -9219,6 +9219,27 @@ var MediaTrackError = class extends Error {
9219
9219
  this.name = "MediaTrackError";
9220
9220
  }
9221
9221
  };
9222
+ var DPoPInitError = class extends Error {
9223
+ constructor(originalError, message = "Failed to initialize DPoP key pair") {
9224
+ super(message, { cause: originalError instanceof Error ? originalError : void 0 });
9225
+ this.originalError = originalError;
9226
+ this.name = "DPoPInitError";
9227
+ }
9228
+ };
9229
+ var DeviceTokenError = class extends Error {
9230
+ constructor(message, originalError) {
9231
+ super(message, { cause: originalError instanceof Error ? originalError : void 0 });
9232
+ this.originalError = originalError;
9233
+ this.name = "DeviceTokenError";
9234
+ }
9235
+ };
9236
+ var TokenRefreshError = class extends Error {
9237
+ constructor(message, originalError) {
9238
+ super(message, { cause: originalError instanceof Error ? originalError : void 0 });
9239
+ this.originalError = originalError;
9240
+ this.name = "TokenRefreshError";
9241
+ }
9242
+ };
9222
9243
 
9223
9244
  //#endregion
9224
9245
  //#region ../../node_modules/loglevel/lib/loglevel.js
@@ -9401,9 +9422,9 @@ var require_loglevel = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9401
9422
  defaultLogger$1 = new Logger();
9402
9423
  defaultLogger$1.getLogger = function getLogger$1(name) {
9403
9424
  if (typeof name !== "symbol" && typeof name !== "string" || name === "") throw new TypeError("You must supply a name when creating a logger.");
9404
- var logger$22 = _loggersByName[name];
9405
- if (!logger$22) logger$22 = _loggersByName[name] = new Logger(name, defaultLogger$1.methodFactory);
9406
- return logger$22;
9425
+ var logger$24 = _loggersByName[name];
9426
+ if (!logger$24) logger$24 = _loggersByName[name] = new Logger(name, defaultLogger$1.methodFactory);
9427
+ return logger$24;
9407
9428
  };
9408
9429
  var _log = typeof window !== undefinedType ? window.log : void 0;
9409
9430
  defaultLogger$1.noConflict = function() {
@@ -9443,15 +9464,15 @@ const shouldStringify = (payload) => {
9443
9464
  return true;
9444
9465
  };
9445
9466
  const wsTraffic = ({ type, payload }) => {
9446
- const logger$22 = getLoggerInstance();
9467
+ const logger$24 = getLoggerInstance();
9447
9468
  const { logWsTraffic } = debugOptions ?? {};
9448
9469
  if (!logWsTraffic) return;
9449
9470
  const msg = shouldStringify(payload) ? JSON.stringify(payload, null, 2) : payload;
9450
- return logger$22.debug(`${type.toUpperCase()}: \n`, msg, "\n");
9471
+ return logger$24.debug(`${type.toUpperCase()}: \n`, msg, "\n");
9451
9472
  };
9452
9473
  const getLogger = () => {
9453
- const logger$22 = getLoggerInstance();
9454
- return new Proxy(logger$22, { get(target, prop, receiver) {
9474
+ const logger$24 = getLoggerInstance();
9475
+ return new Proxy(logger$24, { get(target, prop, receiver) {
9455
9476
  if (prop === "wsTraffic") return wsTraffic;
9456
9477
  return Reflect.get(target, prop, receiver);
9457
9478
  } });
@@ -9500,8 +9521,8 @@ const asyncRetry = async ({ asyncCallable, maxRetries: retries = DEFAULT_MAX_RET
9500
9521
 
9501
9522
  //#endregion
9502
9523
  //#region src/controllers/HTTPRequestController.ts
9503
- var import_cjs$21 = require_cjs();
9504
- const logger$21 = getLogger();
9524
+ var import_cjs$22 = require_cjs();
9525
+ const logger$23 = getLogger();
9505
9526
  const GET_PARAMS = {
9506
9527
  method: "GET",
9507
9528
  headers: { Accept: "application/json" }
@@ -9526,12 +9547,19 @@ var HTTPRequestController = class HTTPRequestController {
9526
9547
  static {
9527
9548
  this.defaultRequestTimeoutMs = 3e4;
9528
9549
  }
9529
- constructor(baseURL, credential, options = {}) {
9550
+ static {
9551
+ this.SENSITIVE_BODY_FIELDS = new Set([
9552
+ "dpop_token",
9553
+ "token",
9554
+ "jwt_token"
9555
+ ]);
9556
+ }
9557
+ constructor(baseURL, getCredential, options = {}) {
9530
9558
  this.baseURL = baseURL;
9531
- this.credential = credential;
9532
- this._responses$ = new import_cjs$21.Subject();
9533
- this._errors$ = new import_cjs$21.Subject();
9534
- this._status$ = new import_cjs$21.BehaviorSubject("idle");
9559
+ this.getCredential = getCredential;
9560
+ this._responses$ = new import_cjs$22.Subject();
9561
+ this._errors$ = new import_cjs$22.Subject();
9562
+ this._status$ = new import_cjs$22.BehaviorSubject("idle");
9535
9563
  this.maxRetries = options.maxRetries ?? HTTPRequestController.defaultMaxRetries;
9536
9564
  this.retryDelayMin = options.retryDelayMin ?? HTTPRequestController.defaultRetryDelayMinMs;
9537
9565
  this.retryDelayMax = options.retryDelayMax ?? HTTPRequestController.defaultRetryDelayMaxMs;
@@ -9557,7 +9585,7 @@ var HTTPRequestController = class HTTPRequestController {
9557
9585
  this._responses$.next(response);
9558
9586
  return response;
9559
9587
  } catch (error) {
9560
- logger$21.error("[HTTPRequestController] Request error:", error);
9588
+ logger$23.error("[HTTPRequestController] Request error:", error);
9561
9589
  this._status$.next("error");
9562
9590
  const err = error instanceof Error ? error : new Error("HTTP request failed", { cause: error });
9563
9591
  this._errors$.next(err);
@@ -9584,14 +9612,14 @@ var HTTPRequestController = class HTTPRequestController {
9584
9612
  const url = this.buildURL(request.url);
9585
9613
  const headers = this.buildHeaders(request.headers);
9586
9614
  const timeout$4 = request.timeout ?? this.requestTimeout;
9587
- logger$21.debug("[HTTPRequestController] Executing request:", {
9615
+ logger$23.debug("[HTTPRequestController] Executing request:", {
9588
9616
  method: request.method,
9589
9617
  url,
9590
9618
  headers: Object.keys(headers).reduce((acc, key) => {
9591
9619
  acc[key] = key === "Authorization" ? `${headers[key].substring(0, 20)}...` : headers[key];
9592
9620
  return acc;
9593
9621
  }, {}),
9594
- body: request.body
9622
+ body: this.sanitizeBody(request.body)
9595
9623
  });
9596
9624
  const controller = new AbortController();
9597
9625
  const timeoutId = setTimeout(() => controller.abort(), timeout$4);
@@ -9604,7 +9632,7 @@ var HTTPRequestController = class HTTPRequestController {
9604
9632
  });
9605
9633
  clearTimeout(timeoutId);
9606
9634
  const httpResponse = await this.convertResponse(response);
9607
- logger$21.debug("[HTTPRequestController] Response received:", {
9635
+ logger$23.debug("[HTTPRequestController] Response received:", {
9608
9636
  status: response.status,
9609
9637
  statusText: response.statusText,
9610
9638
  headers: [...response.headers.entries()],
@@ -9614,7 +9642,7 @@ var HTTPRequestController = class HTTPRequestController {
9614
9642
  } catch (error) {
9615
9643
  clearTimeout(timeoutId);
9616
9644
  if (error instanceof Error && error.name === "AbortError") throw new RequestTimeoutError(`Request timeout after ${timeout$4}ms`, { cause: error });
9617
- logger$21.error("[HTTPRequestController] Request failed:", error);
9645
+ logger$23.error("[HTTPRequestController] Request failed:", error);
9618
9646
  throw error;
9619
9647
  }
9620
9648
  }
@@ -9625,12 +9653,26 @@ var HTTPRequestController = class HTTPRequestController {
9625
9653
  }
9626
9654
  buildHeaders(requestHeaders) {
9627
9655
  const headers = { ...requestHeaders ?? {} };
9628
- if (this.credential.token) {
9629
- headers.Authorization = `Bearer ${this.credential.token}`;
9630
- logger$21.debug("[HTTPRequestController] Using Bearer token auth, token length:", this.credential.token.length);
9631
- } else logger$21.warn("[HTTPRequestController] No credentials available for authentication");
9656
+ const credential = this.getCredential();
9657
+ if (credential.token) {
9658
+ headers.Authorization = `Bearer ${credential.token}`;
9659
+ logger$23.debug("[HTTPRequestController] Using Bearer token auth, token length:", credential.token.length);
9660
+ } else logger$23.warn("[HTTPRequestController] No credentials available for authentication");
9632
9661
  return headers;
9633
9662
  }
9663
+ /**
9664
+ * Sanitizes a request body for debug logging by masking sensitive fields.
9665
+ */
9666
+ sanitizeBody(body) {
9667
+ if (!body || typeof body !== "string") return body ? "(non-string body)" : void 0;
9668
+ try {
9669
+ const sanitized = { ...JSON.parse(body) };
9670
+ for (const key of Object.keys(sanitized)) if (HTTPRequestController.SENSITIVE_BODY_FIELDS.has(key) && typeof sanitized[key] === "string") sanitized[key] = `${sanitized[key].substring(0, 20)}...[redacted]`;
9671
+ return JSON.stringify(sanitized);
9672
+ } catch {
9673
+ return body.length > 200 ? `${body.substring(0, 200)}...` : body;
9674
+ }
9675
+ }
9634
9676
  async convertResponse(response) {
9635
9677
  const headers = {};
9636
9678
  response.headers.forEach((value, key) => {
@@ -9660,6 +9702,25 @@ const DEFAULT_RECONNECT_DELAY_MAX_MS = 3e3;
9660
9702
  const DEFAULT_DEVICE_DEBOUNCE_TIME_MS = 1500;
9661
9703
  const DEFAULT_DEVICE_POLLING_INTERVAL_MS = 0;
9662
9704
  const PREFERENCES_STORAGE_KEY = "sw:preferences";
9705
+ /** Scope value that enables automatic token refresh. */
9706
+ const SAT_REFRESH_SCOPE = "sat:refresh";
9707
+ /** API endpoints for device token operations. */
9708
+ const DEVICE_TOKEN_ENDPOINT = "/api/fabric/subscriber/devices/token";
9709
+ const DEVICE_REFRESH_ENDPOINT = "/api/fabric/subscriber/devices/refresh";
9710
+ /** Default device token TTL in seconds (15 minutes). */
9711
+ const DEVICE_TOKEN_DEFAULT_EXPIRE_IN = 900;
9712
+ /** Buffer time in milliseconds before expiry to trigger refresh. */
9713
+ const DEVICE_TOKEN_REFRESH_BUFFER_MS = 3e4;
9714
+ /** Maximum retry attempts for device token refresh on transient failure. */
9715
+ const DEVICE_TOKEN_REFRESH_MAX_RETRIES = 3;
9716
+ /** Base delay in milliseconds for exponential backoff on refresh retry. */
9717
+ const DEVICE_TOKEN_REFRESH_RETRY_BASE_MS = 1e3;
9718
+ /** JSON-RPC error code for requester validation failure (corrupted auth state). */
9719
+ const RPC_ERROR_REQUESTER_VALIDATION_FAILED = -32003;
9720
+ /** JSON-RPC error code for invalid params (e.g., missing authentication block). */
9721
+ const RPC_ERROR_INVALID_PARAMS = -32602;
9722
+ /** JSON-RPC error code for authentication failure (invalid token, missing DPoP, etc.). */
9723
+ const RPC_ERROR_AUTHENTICATION_FAILED = -32002;
9663
9724
 
9664
9725
  //#endregion
9665
9726
  //#region src/utils/time.ts
@@ -9672,7 +9733,7 @@ function fromMsToSec(milliseconds) {
9672
9733
 
9673
9734
  //#endregion
9674
9735
  //#region src/containers/PreferencesContainer.ts
9675
- const logger$20 = getLogger();
9736
+ const logger$22 = getLogger();
9676
9737
  var PreferencesContainer = class PreferencesContainer {
9677
9738
  static get instance() {
9678
9739
  this._instance ??= new PreferencesContainer();
@@ -9966,7 +10027,7 @@ var ClientPreferences = class {
9966
10027
  if (!this._storage) return;
9967
10028
  const data = collectStoredPreferences();
9968
10029
  this._storage.setItem(PREFERENCES_STORAGE_KEY, data, "local").catch((error) => {
9969
- logger$20.error(`[ClientPreferences] Failed to save preferences: ${String(error)}`);
10030
+ logger$22.error(`[ClientPreferences] Failed to save preferences: ${String(error)}`);
9970
10031
  });
9971
10032
  }
9972
10033
  /** Loads preferences from storage and applies them to the container. */
@@ -9975,15 +10036,15 @@ var ClientPreferences = class {
9975
10036
  this._storage.getItem(PREFERENCES_STORAGE_KEY, "local").then((stored) => {
9976
10037
  if (stored) applyStoredPreferences(stored);
9977
10038
  }).catch((error) => {
9978
- logger$20.error(`[ClientPreferences] Failed to load preferences: ${String(error)}`);
10039
+ logger$22.error(`[ClientPreferences] Failed to load preferences: ${String(error)}`);
9979
10040
  });
9980
10041
  }
9981
10042
  };
9982
10043
 
9983
10044
  //#endregion
9984
10045
  //#region src/controllers/NavigatorDeviceController.ts
9985
- var import_cjs$20 = require_cjs();
9986
- const logger$19 = getLogger();
10046
+ var import_cjs$21 = require_cjs();
10047
+ const logger$21 = getLogger();
9987
10048
  const initialDevicesState = {
9988
10049
  audioinput: [],
9989
10050
  audiooutput: [],
@@ -10004,7 +10065,7 @@ var NavigatorDeviceController = class extends Destroyable {
10004
10065
  super();
10005
10066
  this.webRTCApiProvider = webRTCApiProvider;
10006
10067
  this.deviceChangeHandler = () => {
10007
- logger$19.debug("[DeviceController] Device change detected");
10068
+ logger$21.debug("[DeviceController] Device change detected");
10008
10069
  this.enumerateDevices();
10009
10070
  };
10010
10071
  this._devicesState$ = this.createBehaviorSubject(initialDevicesState);
@@ -10026,25 +10087,25 @@ var NavigatorDeviceController = class extends Destroyable {
10026
10087
  return {};
10027
10088
  }
10028
10089
  get errors$() {
10029
- return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$20.takeUntil)(this.destroyed$)));
10090
+ return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$21.takeUntil)(this.destroyed$)));
10030
10091
  }
10031
10092
  get audioInputDevices$() {
10032
- return this.cachedObservable("audioInputDevices$", () => this._devicesState$.pipe((0, import_cjs$20.map)((state) => state.audioinput), (0, import_cjs$20.distinctUntilChanged)(), (0, import_cjs$20.takeUntil)(this.destroyed$)));
10093
+ return this.cachedObservable("audioInputDevices$", () => this._devicesState$.pipe((0, import_cjs$21.map)((state) => state.audioinput), (0, import_cjs$21.distinctUntilChanged)(), (0, import_cjs$21.takeUntil)(this.destroyed$)));
10033
10094
  }
10034
10095
  get audioOutputDevices$() {
10035
- return this.cachedObservable("audioOutputDevices$", () => this._devicesState$.pipe((0, import_cjs$20.map)((state) => state.audiooutput), (0, import_cjs$20.distinctUntilChanged)(), (0, import_cjs$20.takeUntil)(this.destroyed$)));
10096
+ return this.cachedObservable("audioOutputDevices$", () => this._devicesState$.pipe((0, import_cjs$21.map)((state) => state.audiooutput), (0, import_cjs$21.distinctUntilChanged)(), (0, import_cjs$21.takeUntil)(this.destroyed$)));
10036
10097
  }
10037
10098
  get videoInputDevices$() {
10038
- return this.cachedObservable("videoInputDevices$", () => this._devicesState$.pipe((0, import_cjs$20.map)((state) => state.videoinput), (0, import_cjs$20.distinctUntilChanged)(), (0, import_cjs$20.takeUntil)(this.destroyed$)));
10099
+ return this.cachedObservable("videoInputDevices$", () => this._devicesState$.pipe((0, import_cjs$21.map)((state) => state.videoinput), (0, import_cjs$21.distinctUntilChanged)(), (0, import_cjs$21.takeUntil)(this.destroyed$)));
10039
10100
  }
10040
10101
  get selectedAudioInputDevice$() {
10041
- return this.cachedObservable("selectedAudioInputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, import_cjs$20.map)((state) => state.audioinput), (0, import_cjs$20.distinctUntilChanged)(), (0, import_cjs$20.takeUntil)(this.destroyed$), (0, import_cjs$20.tap)((info) => logger$19.debug("[DeviceController] Selected audio input device changed:", info))));
10102
+ return this.cachedObservable("selectedAudioInputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, import_cjs$21.map)((state) => state.audioinput), (0, import_cjs$21.distinctUntilChanged)(), (0, import_cjs$21.takeUntil)(this.destroyed$), (0, import_cjs$21.tap)((info) => logger$21.debug("[DeviceController] Selected audio input device changed:", info))));
10042
10103
  }
10043
10104
  get selectedAudioOutputDevice$() {
10044
- return this.cachedObservable("selectedAudioOutputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, import_cjs$20.map)((state) => state.audiooutput), (0, import_cjs$20.distinctUntilChanged)(), (0, import_cjs$20.takeUntil)(this.destroyed$), (0, import_cjs$20.tap)((info) => logger$19.debug("[DeviceController] Selected audio output device changed:", info))));
10105
+ return this.cachedObservable("selectedAudioOutputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, import_cjs$21.map)((state) => state.audiooutput), (0, import_cjs$21.distinctUntilChanged)(), (0, import_cjs$21.takeUntil)(this.destroyed$), (0, import_cjs$21.tap)((info) => logger$21.debug("[DeviceController] Selected audio output device changed:", info))));
10045
10106
  }
10046
10107
  get selectedVideoInputDevice$() {
10047
- return this.cachedObservable("selectedVideoInputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, import_cjs$20.map)((state) => state.videoinput), (0, import_cjs$20.distinctUntilChanged)(), (0, import_cjs$20.takeUntil)(this.destroyed$), (0, import_cjs$20.tap)((info) => logger$19.debug("[DeviceController] Selected video input device changed:", info))));
10108
+ return this.cachedObservable("selectedVideoInputDevice$", () => this._selectedDevicesState$.asObservable().pipe((0, import_cjs$21.map)((state) => state.videoinput), (0, import_cjs$21.distinctUntilChanged)(), (0, import_cjs$21.takeUntil)(this.destroyed$), (0, import_cjs$21.tap)((info) => logger$21.debug("[DeviceController] Selected video input device changed:", info))));
10048
10109
  }
10049
10110
  get selectedAudioInputDevice() {
10050
10111
  return this._selectedDevicesState$.value.audioinput;
@@ -10071,7 +10132,7 @@ var NavigatorDeviceController = class extends Destroyable {
10071
10132
  });
10072
10133
  }
10073
10134
  selectVideoInputDevice(device) {
10074
- logger$19.debug("[DeviceController] Setting selected video input device:", device);
10135
+ logger$21.debug("[DeviceController] Setting selected video input device:", device);
10075
10136
  this._selectedDevicesState$.next({
10076
10137
  ...this._selectedDevicesState$.value,
10077
10138
  videoinput: device
@@ -10084,7 +10145,7 @@ var NavigatorDeviceController = class extends Destroyable {
10084
10145
  });
10085
10146
  }
10086
10147
  init() {
10087
- this.subscribeTo(this._devicesState$.pipe((0, import_cjs$20.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10148
+ this.subscribeTo(this._devicesState$.pipe((0, import_cjs$21.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10088
10149
  const currentSelected = this._selectedDevicesState$.value;
10089
10150
  const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
10090
10151
  const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
@@ -10100,8 +10161,8 @@ var NavigatorDeviceController = class extends Destroyable {
10100
10161
  enableDeviceMonitoring() {
10101
10162
  this.disableDeviceMonitoring();
10102
10163
  this.webRTCApiProvider.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
10103
- if (PreferencesContainer.instance.devicePollingInterval > 0) this._devicesPoolingSubscription = (0, import_cjs$20.interval)(PreferencesContainer.instance.devicePollingInterval).subscribe(() => {
10104
- logger$19.debug("[DeviceController] Polling devices due to interval");
10164
+ if (PreferencesContainer.instance.devicePollingInterval > 0) this._devicesPoolingSubscription = (0, import_cjs$21.interval)(PreferencesContainer.instance.devicePollingInterval).subscribe(() => {
10165
+ logger$21.debug("[DeviceController] Polling devices due to interval");
10105
10166
  this.enumerateDevices();
10106
10167
  });
10107
10168
  this.enumerateDevices();
@@ -10124,13 +10185,13 @@ var NavigatorDeviceController = class extends Destroyable {
10124
10185
  videoinput: []
10125
10186
  });
10126
10187
  this._devicesState$.next(devicesByKind);
10127
- logger$19.debug("[DeviceController] Devices enumerated:", {
10188
+ logger$21.debug("[DeviceController] Devices enumerated:", {
10128
10189
  audioInputs: devicesByKind.audioinput.length,
10129
10190
  audioOutputs: devicesByKind.audiooutput.length,
10130
10191
  videoInputs: devicesByKind.videoinput.length
10131
10192
  });
10132
10193
  } catch (error) {
10133
- logger$19.error("[DeviceController] Failed to enumerate devices:", error);
10194
+ logger$21.error("[DeviceController] Failed to enumerate devices:", error);
10134
10195
  this._errors$.next(error);
10135
10196
  }
10136
10197
  }
@@ -10146,7 +10207,7 @@ var NavigatorDeviceController = class extends Destroyable {
10146
10207
  stream.getTracks().forEach((t) => t.stop());
10147
10208
  return capabilities;
10148
10209
  } catch (error) {
10149
- logger$19.error("[DeviceController] Failed to get device capabilities:", error);
10210
+ logger$21.error("[DeviceController] Failed to get device capabilities:", error);
10150
10211
  this._errors$.next(error);
10151
10212
  throw error;
10152
10213
  }
@@ -10293,7 +10354,7 @@ var DependencyContainer = class {
10293
10354
  return this._storageManager;
10294
10355
  }
10295
10356
  get http() {
10296
- this._httpRequestController ??= new HTTPRequestController(this._baseURL, this._credential);
10357
+ this._httpRequestController ??= new HTTPRequestController(this._baseURL, () => this._credential);
10297
10358
  return this._httpRequestController;
10298
10359
  }
10299
10360
  get conversationManager() {
@@ -10349,7 +10410,6 @@ var DependencyContainer = class {
10349
10410
  }
10350
10411
  set credential(credential) {
10351
10412
  this._credential = credential;
10352
- this._httpRequestController = void 0;
10353
10413
  }
10354
10414
  set storageImpl(storageImpl) {
10355
10415
  this._storageImpl = storageImpl;
@@ -10362,24 +10422,206 @@ var DependencyContainer = class {
10362
10422
  this._host = ch.substring(0, firstDot);
10363
10423
  this._domain = ch.substring(firstDot + 1);
10364
10424
  }
10425
+ this._baseURL = this.apiHost;
10426
+ this._httpRequestController = void 0;
10365
10427
  }
10366
10428
  get relayHost() {
10367
10429
  return `wss://${this._host ?? "puc"}.${this._domain ?? "signalwire.com"}`;
10368
10430
  }
10369
10431
  get apiHost() {
10370
- return `https://${this._host ?? "fabric"}.${this._domain ?? "signalwire.com"}`;
10432
+ return `https://fabric.${this._domain ?? "signalwire.com"}`;
10433
+ }
10434
+ };
10435
+
10436
+ //#endregion
10437
+ //#region src/controllers/CryptoController.ts
10438
+ const logger$20 = getLogger();
10439
+ /**
10440
+ * Base64url-encodes an ArrayBuffer (no padding, URL-safe).
10441
+ */
10442
+ const base64url = (buffer$1) => {
10443
+ const bytes = new Uint8Array(buffer$1);
10444
+ let binary = "";
10445
+ for (const byte of bytes) binary += String.fromCharCode(byte);
10446
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
10447
+ };
10448
+ /**
10449
+ * Base64url-encodes a UTF-8 string.
10450
+ */
10451
+ const base64urlEncode = (str) => {
10452
+ return base64url(new TextEncoder().encode(str).buffer);
10453
+ };
10454
+ /**
10455
+ * Computes the JWK Thumbprint per RFC 7638.
10456
+ *
10457
+ * Only supports RSA keys — the canonical JSON uses lexicographic member ordering: { e, kty, n }.
10458
+ * The thumbprint is SHA-256 of the canonical JSON, base64url-encoded.
10459
+ *
10460
+ * @throws {Error} If the JWK is not an RSA key.
10461
+ */
10462
+ const computeJwkThumbprint = async (jwk) => {
10463
+ if (jwk.kty !== "RSA") throw new Error(`Unsupported key type for JWK Thumbprint: ${jwk.kty}. Only RSA is supported.`);
10464
+ const canonical = JSON.stringify({
10465
+ e: jwk.e,
10466
+ kty: jwk.kty,
10467
+ n: jwk.n
10468
+ });
10469
+ return base64url(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonical)));
10470
+ };
10471
+ /**
10472
+ * Controls DPoP (Demonstrating Proof-of-Possession) cryptographic operations.
10473
+ *
10474
+ * Generates an ephemeral RSA-2048 key pair where the private key is
10475
+ * non-extractable, computes the JWK Thumbprint (RFC 7638) as the fingerprint,
10476
+ * and creates signed DPoP proof JWTs for both HTTP API requests and
10477
+ * WebSocket RPC calls.
10478
+ *
10479
+ * @example
10480
+ * ```typescript
10481
+ * const crypto = new CryptoController();
10482
+ * await crypto.init();
10483
+ *
10484
+ * // Get fingerprint for SAT issuance
10485
+ * const fingerprint = crypto.fingerprint;
10486
+ *
10487
+ * // Create proof for HTTP endpoint
10488
+ * const httpProof = await crypto.createHttpProof({
10489
+ * method: 'POST',
10490
+ * uri: '/api/fabric/subscriber/devices/token'
10491
+ * });
10492
+ *
10493
+ * // Create proof for RPC call
10494
+ * const rpcProof = await crypto.createRpcProof({
10495
+ * method: 'signalwire.connect'
10496
+ * });
10497
+ * ```
10498
+ */
10499
+ var CryptoController = class {
10500
+ constructor() {
10501
+ this._keyPair = null;
10502
+ this._publicJwk = null;
10503
+ this._fingerprint = null;
10504
+ this._initialized = false;
10505
+ }
10506
+ /**
10507
+ * Generates the ephemeral RSA key pair and computes the fingerprint.
10508
+ *
10509
+ * Must be called before any other method. The private key is generated
10510
+ * as non-extractable to prevent accidental exposure.
10511
+ *
10512
+ * @returns The JWK Thumbprint (fingerprint) for the generated key.
10513
+ */
10514
+ async init() {
10515
+ if (this._initialized) return this.fingerprint;
10516
+ logger$20.debug("[DPoP] Generating ephemeral RSA key pair");
10517
+ this._keyPair = await crypto.subtle.generateKey({
10518
+ name: "RSASSA-PKCS1-v1_5",
10519
+ modulusLength: 2048,
10520
+ publicExponent: new Uint8Array([
10521
+ 1,
10522
+ 0,
10523
+ 1
10524
+ ]),
10525
+ hash: "SHA-256"
10526
+ }, false, ["sign", "verify"]);
10527
+ this._publicJwk = await crypto.subtle.exportKey("jwk", this._keyPair.publicKey);
10528
+ this._fingerprint = await computeJwkThumbprint(this._publicJwk);
10529
+ this._initialized = true;
10530
+ logger$20.debug("[DPoP] Key pair generated, fingerprint computed");
10531
+ return this._fingerprint;
10532
+ }
10533
+ /**
10534
+ * The JWK Thumbprint (RFC 7638) of the public key.
10535
+ * Used as the `fingerprint` parameter when requesting scoped SATs.
10536
+ *
10537
+ * @throws {DPoPInitError} If {@link init} has not been called.
10538
+ */
10539
+ get fingerprint() {
10540
+ if (!this._fingerprint) throw new DPoPInitError("CryptoController not initialized. Call init() first.");
10541
+ return this._fingerprint;
10542
+ }
10543
+ /**
10544
+ * Whether the controller has been initialized with a key pair.
10545
+ */
10546
+ get initialized() {
10547
+ return this._initialized;
10548
+ }
10549
+ /**
10550
+ * Creates a DPoP proof JWT for an HTTP API request.
10551
+ *
10552
+ * Used for Prime API endpoints like `/api/fabric/subscriber/devices/token`
10553
+ * and `/api/fabric/subscriber/devices/refresh`.
10554
+ *
10555
+ * @param params - HTTP method and URI for the proof.
10556
+ * @returns Signed DPoP proof JWT string.
10557
+ */
10558
+ async createHttpProof(params) {
10559
+ const payload = {
10560
+ jti: crypto.randomUUID(),
10561
+ htm: params.method,
10562
+ htu: params.uri,
10563
+ iat: Math.floor(Date.now() / 1e3)
10564
+ };
10565
+ if (params.accessToken) payload.ath = base64url(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(params.accessToken)));
10566
+ return this.signProof(payload);
10567
+ }
10568
+ /**
10569
+ * Creates a DPoP proof JWT for a WebSocket RPC call.
10570
+ *
10571
+ * Used for switchblade RPC methods like `signalwire.connect` and
10572
+ * `signalwire.reauthenticate`.
10573
+ *
10574
+ * @param params - RPC method name for the proof.
10575
+ * @returns Signed DPoP proof JWT string.
10576
+ */
10577
+ async createRpcProof(params) {
10578
+ const payload = {
10579
+ jti: crypto.randomUUID(),
10580
+ rpc: "request",
10581
+ mth: params.method,
10582
+ iat: Math.floor(Date.now() / 1e3)
10583
+ };
10584
+ return this.signProof(payload);
10585
+ }
10586
+ /**
10587
+ * Releases the key pair references.
10588
+ * After calling destroy, the controller must be re-initialized to be used again.
10589
+ */
10590
+ destroy() {
10591
+ this._keyPair = null;
10592
+ this._publicJwk = null;
10593
+ this._fingerprint = null;
10594
+ this._initialized = false;
10595
+ logger$20.debug("[DPoP] Controller destroyed");
10596
+ }
10597
+ get publicJwk() {
10598
+ if (!this._publicJwk) throw new DPoPInitError("CryptoController not initialized. Call init() first.");
10599
+ return this._publicJwk;
10600
+ }
10601
+ get privateKey() {
10602
+ if (!this._keyPair) throw new DPoPInitError("CryptoController not initialized. Call init() first.");
10603
+ return this._keyPair.privateKey;
10604
+ }
10605
+ async signProof(payload) {
10606
+ const header = {
10607
+ typ: "dpop+jwt",
10608
+ alg: "RS256",
10609
+ jwk: this.publicJwk
10610
+ };
10611
+ const signingInput = `${base64urlEncode(JSON.stringify(header))}.${base64urlEncode(JSON.stringify(payload))}`;
10612
+ return `${signingInput}.${base64url(await crypto.subtle.sign("RSASSA-PKCS1-v1_5", this.privateKey, new TextEncoder().encode(signingInput)))}`;
10371
10613
  }
10372
10614
  };
10373
10615
 
10374
10616
  //#endregion
10375
10617
  //#region src/behaviors/Fetchable.ts
10376
- var import_cjs$19 = require_cjs();
10618
+ var import_cjs$20 = require_cjs();
10377
10619
  var Fetchable = class extends Destroyable {
10378
10620
  constructor(fromPath, http) {
10379
10621
  super();
10380
10622
  this.fromPath = fromPath;
10381
10623
  this.http = http;
10382
- this.fetched$ = (0, import_cjs$19.defer)(() => (0, import_cjs$19.from)(this.fetch())).pipe((0, import_cjs$19.shareReplay)(1), (0, import_cjs$19.takeUntil)(this.destroyed$));
10624
+ this.fetched$ = (0, import_cjs$20.defer)(() => (0, import_cjs$20.from)(this.fetch())).pipe((0, import_cjs$20.shareReplay)(1), (0, import_cjs$20.takeUntil)(this.destroyed$));
10383
10625
  }
10384
10626
  async fetch() {
10385
10627
  const response = await this.http.request({
@@ -10425,6 +10667,7 @@ var Subscriber = class extends Fetchable {
10425
10667
  scopes: data.app_settings.scopes
10426
10668
  } : void 0;
10427
10669
  this.addresses = data.fabric_addresses;
10670
+ this.satClaims = data.sat_claims;
10428
10671
  }
10429
10672
  };
10430
10673
 
@@ -10510,10 +10753,14 @@ const RPCConnect = (params) => {
10510
10753
 
10511
10754
  //#endregion
10512
10755
  //#region src/core/RPCMessages/RPCReauthenticate.ts
10513
- const RPCReauthenticate = (authentication) => {
10756
+ const RPCReauthenticate = (params) => {
10757
+ const { dpop_token, ...authFields } = params;
10514
10758
  return buildRPCRequest({
10515
10759
  method: "signalwire.reauthenticate",
10516
- params: { authentication }
10760
+ params: {
10761
+ authentication: authFields,
10762
+ ...dpop_token ? { dpop_token } : {}
10763
+ }
10517
10764
  });
10518
10765
  };
10519
10766
 
@@ -10609,7 +10856,7 @@ const RPCEventAckResponse = (id) => makeRPCResponse({
10609
10856
 
10610
10857
  //#endregion
10611
10858
  //#region src/managers/AttachManager.ts
10612
- const logger$18 = getLogger();
10859
+ const logger$19 = getLogger();
10613
10860
  var AttachManager = class {
10614
10861
  constructor(storage, deviceController, reconnectCallsTimeout, attachKey) {
10615
10862
  this.storage = storage;
@@ -10631,7 +10878,7 @@ var AttachManager = class {
10631
10878
  try {
10632
10879
  return await this.storage.getItem(this.attachKey) ?? {};
10633
10880
  } catch (error) {
10634
- logger$18.warn("[AttachManager] Failed to retrieve attached calls from storage", error);
10881
+ logger$19.warn("[AttachManager] Failed to retrieve attached calls from storage", error);
10635
10882
  return {};
10636
10883
  }
10637
10884
  }
@@ -10639,12 +10886,12 @@ var AttachManager = class {
10639
10886
  try {
10640
10887
  await this.storage.setItem(this.attachKey, attached);
10641
10888
  } catch (error) {
10642
- logger$18.warn("[AttachManager] Failed to write attached calls to storage", error);
10889
+ logger$19.warn("[AttachManager] Failed to write attached calls to storage", error);
10643
10890
  }
10644
10891
  }
10645
10892
  async attach(call) {
10646
10893
  if (!call.to) {
10647
- logger$18.warn("[AttachManager] Skip attach for calls with no destination");
10894
+ logger$19.warn("[AttachManager] Skip attach for calls with no destination");
10648
10895
  return;
10649
10896
  }
10650
10897
  const attachment = {
@@ -11567,7 +11814,7 @@ var require_operators = /* @__PURE__ */ __commonJSMin(((exports) => {
11567
11814
  //#endregion
11568
11815
  //#region src/operators/filterNull.ts
11569
11816
  var import_operators$1 = require_operators();
11570
- var import_cjs$18 = require_cjs();
11817
+ var import_cjs$19 = require_cjs();
11571
11818
  /**
11572
11819
  * RxJS operator that filters out `null` and `undefined` values with type narrowing.
11573
11820
  *
@@ -11579,7 +11826,7 @@ var import_cjs$18 = require_cjs();
11579
11826
  * ```
11580
11827
  */
11581
11828
  function filterNull() {
11582
- return (0, import_cjs$18.filter)((value) => value != null);
11829
+ return (0, import_cjs$19.filter)((value) => value != null);
11583
11830
  }
11584
11831
 
11585
11832
  //#endregion
@@ -11707,7 +11954,7 @@ function computeCapabilities(capabilities) {
11707
11954
 
11708
11955
  //#endregion
11709
11956
  //#region src/core/capabilities/SelfCapabilities.ts
11710
- var import_cjs$17 = require_cjs();
11957
+ var import_cjs$18 = require_cjs();
11711
11958
  /**
11712
11959
  * SelfCapabilities manages the capability state for the self participant.
11713
11960
  *
@@ -11743,7 +11990,7 @@ var SelfCapabilities = class extends Destroyable {
11743
11990
  }
11744
11991
  /** Observable for self member capabilities */
11745
11992
  get self$() {
11746
- return this.cachedObservable("self$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.self), (0, import_cjs$17.distinctUntilChanged)()));
11993
+ return this.cachedObservable("self$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.self), (0, import_cjs$18.distinctUntilChanged)()));
11747
11994
  }
11748
11995
  /** Current self member capabilities */
11749
11996
  get self() {
@@ -11751,7 +11998,7 @@ var SelfCapabilities = class extends Destroyable {
11751
11998
  }
11752
11999
  /** Observable for other member capabilities */
11753
12000
  get member$() {
11754
- return this.cachedObservable("member$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.member), (0, import_cjs$17.distinctUntilChanged)()));
12001
+ return this.cachedObservable("member$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.member), (0, import_cjs$18.distinctUntilChanged)()));
11755
12002
  }
11756
12003
  /** Current other member capabilities */
11757
12004
  get member() {
@@ -11759,7 +12006,7 @@ var SelfCapabilities = class extends Destroyable {
11759
12006
  }
11760
12007
  /** Observable for end call capability */
11761
12008
  get end$() {
11762
- return this.cachedObservable("end$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.end), (0, import_cjs$17.distinctUntilChanged)()));
12009
+ return this.cachedObservable("end$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.end), (0, import_cjs$18.distinctUntilChanged)()));
11763
12010
  }
11764
12011
  /** Current end call capability */
11765
12012
  get end() {
@@ -11767,7 +12014,7 @@ var SelfCapabilities = class extends Destroyable {
11767
12014
  }
11768
12015
  /** Observable for set layout capability */
11769
12016
  get setLayout$() {
11770
- return this.cachedObservable("setLayout$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.setLayout), (0, import_cjs$17.distinctUntilChanged)()));
12017
+ return this.cachedObservable("setLayout$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.setLayout), (0, import_cjs$18.distinctUntilChanged)()));
11771
12018
  }
11772
12019
  /** Current set layout capability */
11773
12020
  get setLayout() {
@@ -11775,7 +12022,7 @@ var SelfCapabilities = class extends Destroyable {
11775
12022
  }
11776
12023
  /** Observable for send digit capability */
11777
12024
  get sendDigit$() {
11778
- return this.cachedObservable("sendDigit$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.sendDigit), (0, import_cjs$17.distinctUntilChanged)()));
12025
+ return this.cachedObservable("sendDigit$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.sendDigit), (0, import_cjs$18.distinctUntilChanged)()));
11779
12026
  }
11780
12027
  /** Current send digit capability */
11781
12028
  get sendDigit() {
@@ -11783,7 +12030,7 @@ var SelfCapabilities = class extends Destroyable {
11783
12030
  }
11784
12031
  /** Observable for vmuted hide capability */
11785
12032
  get vmutedHide$() {
11786
- return this.cachedObservable("vmutedHide$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.vmutedHide), (0, import_cjs$17.distinctUntilChanged)()));
12033
+ return this.cachedObservable("vmutedHide$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.vmutedHide), (0, import_cjs$18.distinctUntilChanged)()));
11787
12034
  }
11788
12035
  /** Current vmuted hide capability */
11789
12036
  get vmutedHide() {
@@ -11791,7 +12038,7 @@ var SelfCapabilities = class extends Destroyable {
11791
12038
  }
11792
12039
  /** Observable for lock capability */
11793
12040
  get lock$() {
11794
- return this.cachedObservable("lock$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.lock), (0, import_cjs$17.distinctUntilChanged)()));
12041
+ return this.cachedObservable("lock$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.lock), (0, import_cjs$18.distinctUntilChanged)()));
11795
12042
  }
11796
12043
  /** Current lock capability */
11797
12044
  get lock() {
@@ -11799,7 +12046,7 @@ var SelfCapabilities = class extends Destroyable {
11799
12046
  }
11800
12047
  /** Observable for device capability */
11801
12048
  get device$() {
11802
- return this.cachedObservable("device$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.device), (0, import_cjs$17.distinctUntilChanged)()));
12049
+ return this.cachedObservable("device$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.device), (0, import_cjs$18.distinctUntilChanged)()));
11803
12050
  }
11804
12051
  /** Current device capability */
11805
12052
  get device() {
@@ -11807,7 +12054,7 @@ var SelfCapabilities = class extends Destroyable {
11807
12054
  }
11808
12055
  /** Observable for screenshare capability */
11809
12056
  get screenshare$() {
11810
- return this.cachedObservable("screenshare$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.screenshare), (0, import_cjs$17.distinctUntilChanged)()));
12057
+ return this.cachedObservable("screenshare$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.screenshare), (0, import_cjs$18.distinctUntilChanged)()));
11811
12058
  }
11812
12059
  /** Current screenshare capability */
11813
12060
  get screenshare() {
@@ -11834,7 +12081,7 @@ function toggleHandraiseMethod(is) {
11834
12081
 
11835
12082
  //#endregion
11836
12083
  //#region src/core/entities/Participant.ts
11837
- const logger$17 = getLogger();
12084
+ const logger$18 = getLogger();
11838
12085
  const initialState = {};
11839
12086
  /**
11840
12087
  * Represents a participant in a call.
@@ -12177,7 +12424,7 @@ var SelfParticipant = class extends Participant {
12177
12424
  try {
12178
12425
  await this.vertoManager.addScreenMedia();
12179
12426
  } catch (error) {
12180
- logger$17.error("[Participant.startScreenShare] Screen share error:", error);
12427
+ logger$18.error("[Participant.startScreenShare] Screen share error:", error);
12181
12428
  }
12182
12429
  }
12183
12430
  /** Observable of the current screen share status. */
@@ -12197,7 +12444,7 @@ var SelfParticipant = class extends Participant {
12197
12444
  try {
12198
12445
  await this.vertoManager.addInputDevice(options);
12199
12446
  } catch (error) {
12200
- logger$17.error("[Participant.startScreenShare] Screen share error:", error);
12447
+ logger$18.error("[Participant.startScreenShare] Screen share error:", error);
12201
12448
  }
12202
12449
  }
12203
12450
  /** Removes an additional media input device by ID. */
@@ -12258,7 +12505,7 @@ var SelfParticipant = class extends Participant {
12258
12505
  try {
12259
12506
  await super.mute();
12260
12507
  } catch (error) {
12261
- logger$17.warn("[Participant.toggleAudioInput] Server Error while muting audio input, proceeding with local toggle anyway", error);
12508
+ logger$18.warn("[Participant.toggleAudioInput] Server Error while muting audio input, proceeding with local toggle anyway", error);
12262
12509
  } finally {
12263
12510
  this.vertoManager.muteMainAudioInputDevice();
12264
12511
  }
@@ -12268,7 +12515,7 @@ var SelfParticipant = class extends Participant {
12268
12515
  try {
12269
12516
  await super.unmute();
12270
12517
  } catch (error) {
12271
- logger$17.warn("[Participant.toggleAudioInput] Server Error while unmuting audio input, proceeding with local toggle anyway", error);
12518
+ logger$18.warn("[Participant.toggleAudioInput] Server Error while unmuting audio input, proceeding with local toggle anyway", error);
12272
12519
  } finally {
12273
12520
  await this.vertoManager.unmuteMainAudioInputDevice();
12274
12521
  }
@@ -12278,7 +12525,7 @@ var SelfParticipant = class extends Participant {
12278
12525
  try {
12279
12526
  await super.muteVideo();
12280
12527
  } catch (error) {
12281
- logger$17.warn("[Participant.toggleVideoInput] Server Error while muting video input, proceeding with local toggle anyway", error);
12528
+ logger$18.warn("[Participant.toggleVideoInput] Server Error while muting video input, proceeding with local toggle anyway", error);
12282
12529
  } finally {
12283
12530
  this.vertoManager.muteMainVideoInputDevice();
12284
12531
  }
@@ -12288,7 +12535,7 @@ var SelfParticipant = class extends Participant {
12288
12535
  try {
12289
12536
  await super.unmuteVideo();
12290
12537
  } catch (error) {
12291
- logger$17.warn("[Participant.toggleVideoInput] Server Error while unmuting video input, proceeding with local toggle anyway", error);
12538
+ logger$18.warn("[Participant.toggleVideoInput] Server Error while unmuting video input, proceeding with local toggle anyway", error);
12292
12539
  } finally {
12293
12540
  await this.vertoManager.unmuteMainVideoInputDevice();
12294
12541
  }
@@ -12319,6 +12566,7 @@ function isJSONRPCErrorResponse(value) {
12319
12566
 
12320
12567
  //#endregion
12321
12568
  //#region src/core/RPCMessages/guards/events.guards.ts
12569
+ /** @internal @packageDocumentation */
12322
12570
  /**
12323
12571
  * Factory function to create Request-level type guards.
12324
12572
  */
@@ -12342,6 +12590,7 @@ const isCallUpdatedRequest = createEventRequestGuard("call.updated");
12342
12590
  const isCallStateRequest = createEventRequestGuard("call.state");
12343
12591
  const isCallPlayRequest = createEventRequestGuard("call.play");
12344
12592
  const isCallConnectRequest = createEventRequestGuard("call.connect");
12593
+ const isRoomUpdatedRequest = createEventRequestGuard("room.updated");
12345
12594
  const isMemberUpdatedRequest = createEventRequestGuard("member.updated");
12346
12595
  const isMemberJoinedRequest = createEventRequestGuard("member.joined");
12347
12596
  const isMemberLeftRequest = createEventRequestGuard("member.left");
@@ -12353,7 +12602,7 @@ function isSignalwireMetadata(value) {
12353
12602
  return isObject(value) && hasProperty(value, "event_type") && typeof value.event_type === "string" && hasProperty(value, "params");
12354
12603
  }
12355
12604
  function isSignalwireCallMetadata(value) {
12356
- return isSignalwireMetadata(value) && (isCallJoinedMetadata(value) || isCallLeftMetadata(value) || isCallUpdatedMetadata(value) || isCallStateMetadata(value) || isCallPlayMetadata(value) || isCallConnectMetadata(value) || isMemberUpdatedMetadata(value) || isMemberJoinedMetadata(value) || isMemberLeftMetadata(value) || isMemberTalkingMetadata(value) || isLayoutChangedMetadata(value) || isWebrtcMessageMetadata(value) || isConversationMessageMetadata(value) || isConversationMessageUpdatedMetadata(value));
12605
+ return isSignalwireMetadata(value) && (isCallJoinedMetadata(value) || isCallLeftMetadata(value) || isCallUpdatedMetadata(value) || isCallStateMetadata(value) || isCallPlayMetadata(value) || isCallConnectMetadata(value) || isRoomUpdatedMetadata(value) || isMemberUpdatedMetadata(value) || isMemberJoinedMetadata(value) || isMemberLeftMetadata(value) || isMemberTalkingMetadata(value) || isLayoutChangedMetadata(value) || isWebrtcMessageMetadata(value) || isConversationMessageMetadata(value) || isConversationMessageUpdatedMetadata(value));
12357
12606
  }
12358
12607
  const isSignalwireAuthorizationStateMetadata = createEventMetadataGuard("signalwire.authorization.state");
12359
12608
  const isWebrtcMessageMetadata = createEventMetadataGuard("webrtc.message");
@@ -12363,6 +12612,7 @@ const isCallUpdatedMetadata = createEventMetadataGuard("call.updated");
12363
12612
  const isCallStateMetadata = createEventMetadataGuard("call.state");
12364
12613
  const isCallPlayMetadata = createEventMetadataGuard("call.play");
12365
12614
  const isCallConnectMetadata = createEventMetadataGuard("call.connect");
12615
+ const isRoomUpdatedMetadata = createEventMetadataGuard("room.updated");
12366
12616
  const isMemberUpdatedMetadata = createEventMetadataGuard("member.updated");
12367
12617
  const isMemberJoinedMetadata = createEventMetadataGuard("member.joined");
12368
12618
  const isMemberLeftMetadata = createEventMetadataGuard("member.left");
@@ -12389,7 +12639,7 @@ const getValueFrom = (obj, path, defaultValue) => {
12389
12639
 
12390
12640
  //#endregion
12391
12641
  //#region src/operators/filterEventAs.ts
12392
- var import_cjs$16 = require_cjs();
12642
+ var import_cjs$17 = require_cjs();
12393
12643
  var import_operators = require_operators();
12394
12644
  /**
12395
12645
  * RxJS operator that filters events based on a predicate and maps matching events.
@@ -12423,7 +12673,7 @@ var import_operators = require_operators();
12423
12673
  * ```
12424
12674
  */
12425
12675
  function ifIsMap(predicate, mapFn) {
12426
- return (0, import_cjs$16.pipe)((0, import_operators.filter)(predicate), (0, import_operators.map)(mapFn));
12676
+ return (0, import_cjs$17.pipe)((0, import_operators.filter)(predicate), (0, import_operators.map)(mapFn));
12427
12677
  }
12428
12678
  /**
12429
12679
  * Generic RxJS operator that filters events using a type guard and extracts a property.
@@ -12465,39 +12715,40 @@ function ifIsMap(predicate, mapFn) {
12465
12715
  * ```
12466
12716
  */
12467
12717
  function filterAs(predicate, resultPath) {
12468
- return (0, import_cjs$16.pipe)(ifIsMap(predicate, (event) => {
12718
+ return (0, import_cjs$17.pipe)(ifIsMap(predicate, (event) => {
12469
12719
  return getValueFrom(event, resultPath);
12470
12720
  }), (0, import_operators.filter)((value) => value !== void 0));
12471
12721
  }
12472
12722
 
12473
12723
  //#endregion
12474
12724
  //#region src/operators/throwOnRPCError.ts
12475
- var import_cjs$15 = require_cjs();
12476
- const logger$16 = getLogger();
12725
+ var import_cjs$16 = require_cjs();
12726
+ const logger$17 = getLogger();
12477
12727
  /**
12478
12728
  * RxJS operator that throws a {@link JSONRPCError} when the RPC response contains an error.
12479
12729
  * Passes successful responses through unchanged.
12480
12730
  */
12481
12731
  function throwOnRPCError() {
12482
- return (0, import_cjs$15.map)((response) => {
12732
+ return (0, import_cjs$16.map)((response) => {
12483
12733
  if (response.error) {
12484
- logger$16.error("[throwOnRPCError] RPC error response:", {
12734
+ logger$17.error("[throwOnRPCError] RPC error response:", {
12485
12735
  code: response.error.code,
12486
12736
  message: response.error.message,
12487
12737
  data: response.error.data
12488
12738
  });
12489
12739
  throw new JSONRPCError(response.error.code, response.error.message, response.error.data);
12490
12740
  }
12491
- logger$16.debug("[throwOnRPCError] RPC successful response:", response);
12741
+ logger$17.debug("[throwOnRPCError] RPC successful response:", response);
12492
12742
  return response;
12493
12743
  });
12494
12744
  }
12495
12745
 
12496
12746
  //#endregion
12497
12747
  //#region src/managers/CallEventsManager.ts
12498
- var import_cjs$14 = require_cjs();
12499
- const logger$15 = getLogger();
12748
+ var import_cjs$15 = require_cjs();
12749
+ const logger$16 = getLogger();
12500
12750
  const initialSessionState = {};
12751
+ /** @internal */
12501
12752
  var CallEventsManager = class extends Destroyable {
12502
12753
  constructor(webRtcCallSession, options = {}) {
12503
12754
  super();
@@ -12511,7 +12762,7 @@ var CallEventsManager = class extends Destroyable {
12511
12762
  this.initSubscriptions();
12512
12763
  }
12513
12764
  get participants$() {
12514
- return this.cachedObservable("participants$", () => this._participants$.asObservable().pipe((0, import_cjs$14.map)((participantsRecord) => Object.values(participantsRecord))));
12765
+ return this.cachedObservable("participants$", () => this._participants$.asObservable().pipe((0, import_cjs$15.map)((participantsRecord) => Object.values(participantsRecord))));
12515
12766
  }
12516
12767
  get participants() {
12517
12768
  return Object.values(this._participants$.value);
@@ -12529,40 +12780,40 @@ var CallEventsManager = class extends Destroyable {
12529
12780
  return this.callIds.has(callId);
12530
12781
  }
12531
12782
  get recording$() {
12532
- return this.cachedObservable("recording$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.recording), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12783
+ return this.cachedObservable("recording$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.recording), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12533
12784
  }
12534
12785
  get recordings$() {
12535
- return this.cachedObservable("recordings$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.recordings), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12786
+ return this.cachedObservable("recordings$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.recordings), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12536
12787
  }
12537
12788
  get streaming$() {
12538
- return this.cachedObservable("streaming$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.streaming), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12789
+ return this.cachedObservable("streaming$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.streaming), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12539
12790
  }
12540
12791
  get streams$() {
12541
- return this.cachedObservable("streams$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.streams), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12792
+ return this.cachedObservable("streams$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.streams), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12542
12793
  }
12543
12794
  get playbacks$() {
12544
- return this.cachedObservable("playbacks$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.playbacks), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12795
+ return this.cachedObservable("playbacks$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.playbacks), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12545
12796
  }
12546
12797
  get raiseHandPriority$() {
12547
- return this.cachedObservable("raiseHandPriority$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.prioritize_handraise), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12798
+ return this.cachedObservable("raiseHandPriority$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.prioritize_handraise), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12548
12799
  }
12549
12800
  get locked$() {
12550
- return this.cachedObservable("locked$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.locked), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12801
+ return this.cachedObservable("locked$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.locked), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12551
12802
  }
12552
12803
  get meta$() {
12553
- return this.cachedObservable("meta$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.meta), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12804
+ return this.cachedObservable("meta$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.meta), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12554
12805
  }
12555
12806
  get capabilities$() {
12556
- return this.cachedObservable("capabilities$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.capabilities), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12807
+ return this.cachedObservable("capabilities$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.capabilities), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12557
12808
  }
12558
12809
  get layout$() {
12559
- return this.cachedObservable("layout$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.layout_name), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12810
+ return this.cachedObservable("layout$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.layout_name), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12560
12811
  }
12561
12812
  get layouts$() {
12562
- return this.cachedObservable("layouts$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.layouts), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12813
+ return this.cachedObservable("layouts$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.layouts), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12563
12814
  }
12564
12815
  get layoutLayers$() {
12565
- return this.cachedObservable("layoutLayers$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.layout_layers), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12816
+ return this.cachedObservable("layoutLayers$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.layout_layers), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12566
12817
  }
12567
12818
  get self() {
12568
12819
  return this._self$.value;
@@ -12599,7 +12850,7 @@ var CallEventsManager = class extends Destroyable {
12599
12850
  }
12600
12851
  initSubscriptions() {
12601
12852
  this.subscribeTo(this.callJoinedEvent$, (callJoinedEvent) => {
12602
- logger$15.debug("[CallEventsManager] Handling call.joined event for call/session IDs:", {
12853
+ logger$16.debug("[CallEventsManager] Handling call.joined event for call/session IDs:", {
12603
12854
  callId: callJoinedEvent.call_id,
12604
12855
  roomSessionId: callJoinedEvent.room_session_id
12605
12856
  });
@@ -12626,19 +12877,34 @@ var CallEventsManager = class extends Destroyable {
12626
12877
  if (this._self$.value?.capabilities.setLayout) this.updateLayouts();
12627
12878
  });
12628
12879
  this.subscribeTo(this.memberUpdates$, (member) => {
12629
- logger$15.debug("[CallEventsManager] Handling member update event for member ID:", member);
12880
+ logger$16.debug("[CallEventsManager] Handling member update event for member ID:", member);
12630
12881
  this.upsertParticipant(member);
12631
12882
  });
12632
12883
  this.subscribeTo(this.webRtcCallSession.memberLeft$, (memberLeftEvent) => {
12633
- logger$15.debug("[CallEventsManager] Handling member.left event for member ID:", memberLeftEvent.member.member_id);
12884
+ logger$16.debug("[CallEventsManager] Handling member.left event for member ID:", memberLeftEvent.member.member_id);
12634
12885
  const participants = { ...this._participants$.value };
12635
12886
  if (memberLeftEvent.member.member_id in participants) {
12636
12887
  delete participants[memberLeftEvent.member.member_id];
12637
12888
  this._participants$.next(participants);
12638
- } else logger$15.warn(`[CallEventsManager] Received member.left event for unknown member ID: ${memberLeftEvent.member.member_id}`);
12889
+ } else logger$16.warn(`[CallEventsManager] Received member.left event for unknown member ID: ${memberLeftEvent.member.member_id}`);
12890
+ });
12891
+ this.subscribeTo(this.webRtcCallSession.callUpdated$, (callUpdatedEvent) => {
12892
+ logger$16.debug("[CallEventsManager] Handling call.updated event:", callUpdatedEvent);
12893
+ const roomSession = callUpdatedEvent.room_session;
12894
+ this._sessionState$.next({
12895
+ ...this._sessionState$.value,
12896
+ recording: roomSession.recording,
12897
+ recordings: roomSession.recordings,
12898
+ streaming: roomSession.streaming,
12899
+ streams: roomSession.streams,
12900
+ playbacks: roomSession.playbacks,
12901
+ prioritize_handraise: roomSession.prioritize_handraise,
12902
+ locked: roomSession.locked,
12903
+ meta: roomSession.meta
12904
+ });
12639
12905
  });
12640
12906
  this.subscribeTo(this.layoutChangedEvent$, (layoutChangedEvent) => {
12641
- logger$15.debug("[CallEventsManager] Handling layout.changed event:", layoutChangedEvent);
12907
+ logger$16.debug("[CallEventsManager] Handling layout.changed event:", layoutChangedEvent);
12642
12908
  this._sessionState$.next({
12643
12909
  ...this._sessionState$.value,
12644
12910
  layout_name: layoutChangedEvent.id,
@@ -12648,7 +12914,7 @@ var CallEventsManager = class extends Destroyable {
12648
12914
  });
12649
12915
  }
12650
12916
  updateParticipantPositions(layoutChangedEvent) {
12651
- if (Object.keys(this._participants$.value).length > 0 && !layoutChangedEvent.layers.some((layer) => !!layer.member_id)) logger$15.warn("[CallEventsManager] No layers with member_id found in layout.changed event. Nothing to update.");
12917
+ if (Object.keys(this._participants$.value).length > 0 && !layoutChangedEvent.layers.some((layer) => !!layer.member_id)) logger$16.warn("[CallEventsManager] No layers with member_id found in layout.changed event. Nothing to update.");
12652
12918
  layoutChangedEvent.layers.filter((layer) => Boolean(layer.member_id)).map((layer) => {
12653
12919
  if (!layer.member_id) throw new DependencyError("Layer member_id is required");
12654
12920
  this._participants$.value[layer.member_id].upnext({ position: layer });
@@ -12669,7 +12935,7 @@ var CallEventsManager = class extends Destroyable {
12669
12935
  layouts: response.result.layouts
12670
12936
  });
12671
12937
  }).catch((error) => {
12672
- logger$15.error("[CallEventsManager] Error fetching layouts:", error);
12938
+ logger$16.error("[CallEventsManager] Error fetching layouts:", error);
12673
12939
  });
12674
12940
  }
12675
12941
  updateParticipants(members) {
@@ -12685,7 +12951,7 @@ var CallEventsManager = class extends Destroyable {
12685
12951
  }
12686
12952
  const participant = this._participants$.value[member.member_id];
12687
12953
  const oldValue = participant.value;
12688
- logger$15.debug("[CallEventsManager] Updating participant:", member.member_id, {
12954
+ logger$16.debug("[CallEventsManager] Updating participant:", member.member_id, {
12689
12955
  oldValue,
12690
12956
  newValue: member
12691
12957
  });
@@ -12697,18 +12963,18 @@ var CallEventsManager = class extends Destroyable {
12697
12963
  this._participants$.next(this._participants$.value);
12698
12964
  }
12699
12965
  get callJoinedEvent$() {
12700
- return this.cachedObservable("callJoinedEvent$", () => this.webRtcCallSession.callEvent$.pipe((0, import_cjs$14.filter)(isCallJoinedPayload), (0, import_cjs$14.tap)((event) => {
12701
- logger$15.debug("[CallEventsManager] Call joined event:", event);
12966
+ return this.cachedObservable("callJoinedEvent$", () => this.webRtcCallSession.callEvent$.pipe((0, import_cjs$15.filter)(isCallJoinedPayload), (0, import_cjs$15.tap)((event) => {
12967
+ logger$16.debug("[CallEventsManager] Call joined event:", event);
12702
12968
  })));
12703
12969
  }
12704
12970
  get layoutChangedEvent$() {
12705
- return this.cachedObservable("layoutChangedEvent$", () => this.webRtcCallSession.callEvent$.pipe(filterAs(isLayoutChangedPayload, "layout"), (0, import_cjs$14.tap)((event) => {
12706
- logger$15.debug("[CallEventsManager] Layout changed event:", event);
12971
+ return this.cachedObservable("layoutChangedEvent$", () => this.webRtcCallSession.callEvent$.pipe(filterAs(isLayoutChangedPayload, "layout"), (0, import_cjs$15.tap)((event) => {
12972
+ logger$16.debug("[CallEventsManager] Layout changed event:", event);
12707
12973
  })));
12708
12974
  }
12709
12975
  get memberUpdates$() {
12710
- return this.cachedObservable("memberUpdates$", () => (0, import_cjs$14.merge)(this.webRtcCallSession.memberJoined$, this.webRtcCallSession.memberUpdated$, this.webRtcCallSession.memberTalking$).pipe((0, import_cjs$14.map)((event) => event.member), (0, import_cjs$14.tap)((event) => {
12711
- logger$15.debug("[CallEventsManager] Member update event:", event);
12976
+ return this.cachedObservable("memberUpdates$", () => (0, import_cjs$15.merge)(this.webRtcCallSession.memberJoined$, this.webRtcCallSession.memberUpdated$, this.webRtcCallSession.memberTalking$).pipe((0, import_cjs$15.map)((event) => event.member), (0, import_cjs$15.tap)((event) => {
12977
+ logger$16.debug("[CallEventsManager] Member update event:", event);
12712
12978
  })));
12713
12979
  }
12714
12980
  destroy() {
@@ -12816,8 +13082,8 @@ function isValidLocalDescription(sdp) {
12816
13082
 
12817
13083
  //#endregion
12818
13084
  //#region src/controllers/ICEGatheringController.ts
12819
- var import_cjs$13 = require_cjs();
12820
- const logger$14 = getLogger();
13085
+ var import_cjs$14 = require_cjs();
13086
+ const logger$15 = getLogger();
12821
13087
  var ICEGatheringController = class extends Destroyable {
12822
13088
  constructor(peerConnection, peerConnectionControllerNegotiating$, options = {}) {
12823
13089
  super();
@@ -12825,23 +13091,23 @@ var ICEGatheringController = class extends Destroyable {
12825
13091
  this.peerConnectionControllerNegotiating$ = peerConnectionControllerNegotiating$;
12826
13092
  this.onicegatheringstatechangeHandler = () => {
12827
13093
  const { iceGatheringState } = this.peerConnection;
12828
- logger$14.debug(`[ICEGatheringController] ICE gathering state changed to: ${iceGatheringState}`);
13094
+ logger$15.debug(`[ICEGatheringController] ICE gathering state changed to: ${iceGatheringState}`);
12829
13095
  if (iceGatheringState === "gathering") this._iceCandidatesState.next({
12830
13096
  state: "gathering",
12831
13097
  validSDP: false
12832
13098
  });
12833
13099
  };
12834
13100
  this.onicecandidateHandler = (event) => {
12835
- logger$14.debug("[ICEGatheringController] ICE candidate event received:", event.candidate);
13101
+ logger$15.debug("[ICEGatheringController] ICE candidate event received:", event.candidate);
12836
13102
  this.removeTimer("iceCandidateTimer");
12837
13103
  if (event.candidate) this.iceCandidateTimer = setTimeout(() => {
12838
13104
  if (this.peerConnection.iceGatheringState !== "complete") {
12839
- logger$14.warn("[ICEGatheringController] ICE candidate timeout, using current SDP");
13105
+ logger$15.warn("[ICEGatheringController] ICE candidate timeout, using current SDP");
12840
13106
  this.handleICECandidateTimeout();
12841
13107
  }
12842
13108
  }, this.iceCandidateTimeout);
12843
13109
  else {
12844
- logger$14.debug("[ICEGatheringController] ICE gathering completed: null candidate received");
13110
+ logger$15.debug("[ICEGatheringController] ICE gathering completed: null candidate received");
12845
13111
  this.removeTimer("iceGatheringTimer");
12846
13112
  this.handleICEGatheringComplete();
12847
13113
  }
@@ -12854,12 +13120,12 @@ var ICEGatheringController = class extends Destroyable {
12854
13120
  this.iceGatheringTimeout = options.iceGatheringTimeout ?? DEFAULT_ICE_GATHERING_TIMEOUT_MS;
12855
13121
  this.relayOnly = options.relayOnly ?? false;
12856
13122
  this.setupEventListeners();
12857
- this.subscribeTo(this.peerConnectionControllerNegotiating$.pipe((0, import_cjs$13.filter)((isNegotiating) => isNegotiating)), (isNegotiating) => {
13123
+ this.subscribeTo(this.peerConnectionControllerNegotiating$.pipe((0, import_cjs$14.filter)((isNegotiating) => isNegotiating)), (isNegotiating) => {
12858
13124
  if (isNegotiating) {
12859
13125
  this.setupEventListeners();
12860
13126
  this.iceGatheringTimer = setTimeout(() => {
12861
13127
  if (this.peerConnection.iceGatheringState !== "complete") {
12862
- logger$14.warn("[ICEGatheringController] ICE gathering timeout, using current SDP");
13128
+ logger$15.warn("[ICEGatheringController] ICE gathering timeout, using current SDP");
12863
13129
  this.handleICEGatheringTimeout();
12864
13130
  }
12865
13131
  }, this.iceGatheringTimeout);
@@ -12873,7 +13139,7 @@ var ICEGatheringController = class extends Destroyable {
12873
13139
  this.peerConnection.addEventListener("icegatheringstatechange", this.onicegatheringstatechangeHandler);
12874
13140
  }
12875
13141
  get iceCandidatesState$() {
12876
- return this._iceCandidatesState.pipe((0, import_cjs$13.withLatestFrom)(this.peerConnectionControllerNegotiating$), (0, import_cjs$13.filter)(([_, isNegotiating]) => isNegotiating), (0, import_cjs$13.map)(([state, _]) => state.state));
13142
+ return this._iceCandidatesState.pipe((0, import_cjs$14.withLatestFrom)(this.peerConnectionControllerNegotiating$), (0, import_cjs$14.filter)(([_, isNegotiating]) => isNegotiating), (0, import_cjs$14.map)(([state, _]) => state.state));
12877
13143
  }
12878
13144
  get hasValidLocalDescriptionSDP() {
12879
13145
  const sdp = this.peerConnection.localDescription?.sdp;
@@ -12886,9 +13152,9 @@ var ICEGatheringController = class extends Destroyable {
12886
13152
  this.relayOnly = value;
12887
13153
  }
12888
13154
  handleICEGatheringComplete() {
12889
- logger$14.debug("[ICEGatheringController] Handling ICE gathering complete");
12890
- logger$14.debug(`[ICEGatheringController] Checking ICE gathering state: ${this.peerConnection.iceGatheringState}`);
12891
- logger$14.debug("[ICEGatheringController] ICE gathering complete");
13155
+ logger$15.debug("[ICEGatheringController] Handling ICE gathering complete");
13156
+ logger$15.debug(`[ICEGatheringController] Checking ICE gathering state: ${this.peerConnection.iceGatheringState}`);
13157
+ logger$15.debug("[ICEGatheringController] ICE gathering complete");
12892
13158
  this._iceCandidatesState.next({
12893
13159
  state: "complete",
12894
13160
  validSDP: this.hasValidLocalDescriptionSDP
@@ -12904,21 +13170,21 @@ var ICEGatheringController = class extends Destroyable {
12904
13170
  this.removeTimer("iceGatheringTimer");
12905
13171
  const validSDP = this.hasValidLocalDescriptionSDP;
12906
13172
  if (validSDP) {
12907
- logger$14.debug("[ICEGatheringController] Local SDP is valid");
13173
+ logger$15.debug("[ICEGatheringController] Local SDP is valid");
12908
13174
  this._iceCandidatesState.next({
12909
13175
  state: "timeout",
12910
13176
  validSDP
12911
13177
  });
12912
13178
  this.stopGathering();
12913
- } else logger$14.debug("### ICE gathering timeout\n", this.peerConnection.localDescription?.sdp);
13179
+ } else logger$15.debug("### ICE gathering timeout\n", this.peerConnection.localDescription?.sdp);
12914
13180
  }
12915
13181
  handleICECandidateTimeout() {
12916
13182
  if (this.iceCandidateTimer) this.removeTimer("iceCandidateTimer");
12917
- logger$14.warn("[ICEGatheringController] ICE candidate timeout");
13183
+ logger$15.warn("[ICEGatheringController] ICE candidate timeout");
12918
13184
  const validSDP = this.hasValidLocalDescriptionSDP;
12919
13185
  if (!validSDP && !this.relayOnly) this.restartICEGatheringWithRelayOnly();
12920
13186
  else {
12921
- logger$14.debug("[ICEGatheringController] Using current SDP due to ICE candidate timeout");
13187
+ logger$15.debug("[ICEGatheringController] Using current SDP due to ICE candidate timeout");
12922
13188
  this._iceCandidatesState.next({
12923
13189
  state: "timeout",
12924
13190
  validSDP
@@ -12927,7 +13193,7 @@ var ICEGatheringController = class extends Destroyable {
12927
13193
  }
12928
13194
  }
12929
13195
  restartICEGatheringWithRelayOnly() {
12930
- logger$14.debug("[ICEGatheringController] Restarting ICE gathering with relay-only candidates");
13196
+ logger$15.debug("[ICEGatheringController] Restarting ICE gathering with relay-only candidates");
12931
13197
  this.relayOnly = true;
12932
13198
  this.peerConnection.setConfiguration({
12933
13199
  ...this.peerConnection.getConfiguration(),
@@ -12935,14 +13201,14 @@ var ICEGatheringController = class extends Destroyable {
12935
13201
  });
12936
13202
  if (!(this.peerConnection.connectionState === "connected")) this.peerConnection.restartIce();
12937
13203
  }
12938
- removeTimer(timer$1) {
12939
- if (this[timer$1]) {
12940
- clearTimeout(this[timer$1]);
12941
- this[timer$1] = void 0;
13204
+ removeTimer(timer$2) {
13205
+ if (this[timer$2]) {
13206
+ clearTimeout(this[timer$2]);
13207
+ this[timer$2] = void 0;
12942
13208
  }
12943
13209
  }
12944
13210
  clearAllTimers() {
12945
- logger$14.debug("[ICEGatheringController] Clearing all timers");
13211
+ logger$15.debug("[ICEGatheringController] Clearing all timers");
12946
13212
  this.removeTimer("iceGatheringTimer");
12947
13213
  this.removeTimer("iceCandidateTimer");
12948
13214
  }
@@ -12951,7 +13217,7 @@ var ICEGatheringController = class extends Destroyable {
12951
13217
  this.peerConnection.removeEventListener("icecandidate", this.onicecandidateHandler);
12952
13218
  }
12953
13219
  destroy() {
12954
- logger$14.debug("[ICEGatheringController] Destroying ICEGatheringController");
13220
+ logger$15.debug("[ICEGatheringController] Destroying ICEGatheringController");
12955
13221
  this.clearAllTimers();
12956
13222
  this.removeEventListeners();
12957
13223
  super.destroy();
@@ -12960,8 +13226,8 @@ var ICEGatheringController = class extends Destroyable {
12960
13226
 
12961
13227
  //#endregion
12962
13228
  //#region src/controllers/LocalStreamController.ts
12963
- var import_cjs$12 = require_cjs();
12964
- const logger$13 = getLogger();
13229
+ var import_cjs$13 = require_cjs();
13230
+ const logger$14 = getLogger();
12965
13231
  var LocalStreamController = class extends Destroyable {
12966
13232
  constructor(options) {
12967
13233
  super();
@@ -12975,16 +13241,16 @@ var LocalStreamController = class extends Destroyable {
12975
13241
  this._mediaTrackEnded$ = this.createSubject();
12976
13242
  }
12977
13243
  get localStream$() {
12978
- return this._localStream$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13244
+ return this._localStream$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12979
13245
  }
12980
13246
  get localAudioTracks$() {
12981
- return this._localAudioTracks$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13247
+ return this._localAudioTracks$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12982
13248
  }
12983
13249
  get localVideoTracks$() {
12984
- return this._localVideoTracks$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13250
+ return this._localVideoTracks$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12985
13251
  }
12986
13252
  get mediaTrackEnded$() {
12987
- return this._mediaTrackEnded$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13253
+ return this._mediaTrackEnded$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12988
13254
  }
12989
13255
  get localStream() {
12990
13256
  return this._localStream$.value;
@@ -12999,26 +13265,26 @@ var LocalStreamController = class extends Destroyable {
12999
13265
  * Build the local media stream based on the provided options.
13000
13266
  */
13001
13267
  async buildLocalStream() {
13002
- logger$13.debug("[LocalStreamController] Building local media stream.");
13268
+ logger$14.debug("[LocalStreamController] Building local media stream.");
13003
13269
  let stream;
13004
13270
  if (this.options.inputAudioStream ?? this.options.inputVideoStream) {
13005
13271
  const tracks = [...this.options.inputAudioStream?.getTracks() ?? [], ...this.options.inputVideoStream?.getTracks() ?? []];
13006
13272
  stream = new MediaStream(tracks);
13007
13273
  } else if (this.options.propose === "screenshare") {
13008
- logger$13.debug("[LocalStreamController] Requesting display media for screen sharing with audio:", Boolean(this.options.inputAudioDeviceConstraints));
13274
+ logger$14.debug("[LocalStreamController] Requesting display media for screen sharing with audio:", Boolean(this.options.inputAudioDeviceConstraints));
13009
13275
  stream = await this.options.getDisplayMedia({
13010
13276
  video: true,
13011
13277
  audio: Boolean(this.options.inputAudioDeviceConstraints)
13012
13278
  });
13013
- logger$13.debug("[LocalStreamController] Screen share media obtained:", stream);
13279
+ logger$14.debug("[LocalStreamController] Screen share media obtained:", stream);
13014
13280
  } else {
13015
13281
  const constraints = {
13016
13282
  audio: this.options.inputAudioDeviceConstraints,
13017
13283
  video: this.options.inputVideoDeviceConstraints
13018
13284
  };
13019
- logger$13.debug("[LocalStreamController] Requesting user media with constraints:", constraints);
13285
+ logger$14.debug("[LocalStreamController] Requesting user media with constraints:", constraints);
13020
13286
  stream = await this.options.getUserMedia(constraints);
13021
- logger$13.debug("[LocalStreamController] User media obtained:", stream);
13287
+ logger$14.debug("[LocalStreamController] User media obtained:", stream);
13022
13288
  }
13023
13289
  this._localStream$.next(stream);
13024
13290
  return stream;
@@ -13035,7 +13301,7 @@ var LocalStreamController = class extends Destroyable {
13035
13301
  this._localStream$.next(localStream);
13036
13302
  if (track.kind === "video") this._localVideoTracks$.next(localStream.getVideoTracks());
13037
13303
  else this._localAudioTracks$.next(localStream.getAudioTracks());
13038
- logger$13.debug(`[LocalStreamController] ${track.kind} track added:`, track.id);
13304
+ logger$14.debug(`[LocalStreamController] ${track.kind} track added:`, track.id);
13039
13305
  return localStream;
13040
13306
  }
13041
13307
  /**
@@ -13047,7 +13313,7 @@ var LocalStreamController = class extends Destroyable {
13047
13313
  const stream = this._localStream$.value;
13048
13314
  const track = stream?.getTracks().find((t) => t.id === trackId);
13049
13315
  if (!track) {
13050
- logger$13.debug(`[LocalStreamController] track not found: ${trackId}`);
13316
+ logger$14.debug(`[LocalStreamController] track not found: ${trackId}`);
13051
13317
  return;
13052
13318
  }
13053
13319
  track.removeEventListener("ended", this.mediaTrackEndedHandler);
@@ -13056,7 +13322,7 @@ var LocalStreamController = class extends Destroyable {
13056
13322
  this._localStream$.next(stream);
13057
13323
  if (track.kind === "video") this._localVideoTracks$.next(stream?.getVideoTracks() ?? []);
13058
13324
  else this._localAudioTracks$.next(stream?.getAudioTracks() ?? []);
13059
- logger$13.debug(`[LocalStreamController] ${track.kind} track removed:`, trackId);
13325
+ logger$14.debug(`[LocalStreamController] ${track.kind} track removed:`, trackId);
13060
13326
  return track;
13061
13327
  }
13062
13328
  /**
@@ -13091,7 +13357,7 @@ var LocalStreamController = class extends Destroyable {
13091
13357
  */
13092
13358
  stopAllTracks() {
13093
13359
  this._localStream$.value?.getTracks().forEach((track) => {
13094
- logger$13.debug(`[LocalStreamController] Stopping local track: ${track.kind}`);
13360
+ logger$14.debug(`[LocalStreamController] Stopping local track: ${track.kind}`);
13095
13361
  track.removeEventListener("ended", this.mediaTrackEndedHandler);
13096
13362
  track.stop();
13097
13363
  });
@@ -13107,7 +13373,7 @@ var LocalStreamController = class extends Destroyable {
13107
13373
 
13108
13374
  //#endregion
13109
13375
  //#region src/controllers/TransceiverController.ts
13110
- const logger$12 = getLogger();
13376
+ const logger$13 = getLogger();
13111
13377
  const getDirection = (send, recv) => {
13112
13378
  if (send && recv) return "sendrecv";
13113
13379
  else if (send && !recv) return "sendonly";
@@ -13209,7 +13475,7 @@ var TransceiverController = class extends Destroyable {
13209
13475
  sendEncodings: isAudio ? void 0 : this.sendEncodings,
13210
13476
  streams: direction === "recvonly" ? void 0 : [localStream]
13211
13477
  };
13212
- logger$12.debug(`[TransceiverController] Setting up transceiver sender for local ${track.kind} track:`, {
13478
+ logger$13.debug(`[TransceiverController] Setting up transceiver sender for local ${track.kind} track:`, {
13213
13479
  transceiver,
13214
13480
  transceiverParams
13215
13481
  });
@@ -13217,11 +13483,11 @@ var TransceiverController = class extends Destroyable {
13217
13483
  await transceiver.sender.replaceTrack(track);
13218
13484
  transceiver.direction = transceiverParams.direction;
13219
13485
  if (transceiverParams.streams?.some((stream) => Boolean(stream))) {
13220
- logger$12.debug(`[TransceiverController] Setting streams for transceiver sender for local ${track.kind} track:`, transceiverParams.streams);
13486
+ logger$13.debug(`[TransceiverController] Setting streams for transceiver sender for local ${track.kind} track:`, transceiverParams.streams);
13221
13487
  transceiver.sender.setStreams(...transceiverParams.streams);
13222
13488
  }
13223
13489
  } else {
13224
- logger$12.debug(`[TransceiverController] Adding new transceiver for local ${track.kind} track:`, track.id);
13490
+ logger$13.debug(`[TransceiverController] Adding new transceiver for local ${track.kind} track:`, track.id);
13225
13491
  this.peerConnection.addTransceiver(track, transceiverParams);
13226
13492
  }
13227
13493
  }
@@ -13235,13 +13501,13 @@ var TransceiverController = class extends Destroyable {
13235
13501
  if (options.updateTransceiverDirection) transceiver.direction = "inactive";
13236
13502
  }
13237
13503
  } catch (error) {
13238
- logger$12.error("[TransceiverController] stopTrackSender error", kind, error);
13504
+ logger$13.error("[TransceiverController] stopTrackSender error", kind, error);
13239
13505
  this.options.onError?.(new MediaTrackError("stopTrackSender", kind, error));
13240
13506
  }
13241
13507
  }
13242
13508
  async restoreTrackSender(kind) {
13243
13509
  try {
13244
- logger$12.debug("[TransceiverController] restoreTrackSender called", kind);
13510
+ logger$13.debug("[TransceiverController] restoreTrackSender called", kind);
13245
13511
  const constraints = {};
13246
13512
  const transceivers = this.transceiverByKind(kind);
13247
13513
  for (const transceiver of transceivers) {
@@ -13251,23 +13517,23 @@ var TransceiverController = class extends Destroyable {
13251
13517
  if (trackKind === "audio" || trackKind === "video") constraints[trackKind] = this.getConstraintsFor(trackKind);
13252
13518
  }
13253
13519
  }
13254
- logger$12.debug("[TransceiverController] restoreTrackSender constraints:", constraints);
13520
+ logger$13.debug("[TransceiverController] restoreTrackSender constraints:", constraints);
13255
13521
  if (Object.keys(constraints).length === 0) {
13256
- logger$12.warn("[TransceiverController] restoreTrackSender: no tracks need restoration", kind);
13522
+ logger$13.warn("[TransceiverController] restoreTrackSender: no tracks need restoration", kind);
13257
13523
  return;
13258
13524
  }
13259
13525
  const newTracks = (await this.options.getUserMedia(constraints)).getTracks();
13260
- logger$12.debug("[TransceiverController] restoreTrackSender new tracks:", newTracks);
13526
+ logger$13.debug("[TransceiverController] restoreTrackSender new tracks:", newTracks);
13261
13527
  for (const newTrack of newTracks) {
13262
13528
  this.options.localStreamController.addTrack(newTrack);
13263
13529
  const trackKind = newTrack.kind;
13264
13530
  const transceiverOfKind = this.transceiverByKind(trackKind)[0];
13265
13531
  transceiverOfKind.direction = trackKind === "audio" ? this.audioDirection : this.videoDirection;
13266
- logger$12.debug("[TransceiverController] restoreTrackSender setting direction for", trackKind, transceiverOfKind.direction);
13532
+ logger$13.debug("[TransceiverController] restoreTrackSender setting direction for", trackKind, transceiverOfKind.direction);
13267
13533
  await transceiverOfKind.sender.replaceTrack(newTrack);
13268
13534
  }
13269
13535
  } catch (error) {
13270
- logger$12.error("[TransceiverController] restoreTrackSender error", kind, error);
13536
+ logger$13.error("[TransceiverController] restoreTrackSender error", kind, error);
13271
13537
  this.options.onError?.(new MediaTrackError("restoreTrackSender", kind, error));
13272
13538
  }
13273
13539
  }
@@ -13308,10 +13574,10 @@ var TransceiverController = class extends Destroyable {
13308
13574
  };
13309
13575
  try {
13310
13576
  await track.applyConstraints(constraintsToApply);
13311
- logger$12.debug(`[TransceiverController] Updated ${kind} sender constraints:`, constraintsToApply);
13312
- logger$12.debug(`[TransceiverController] Updated ${kind} sender constraints:`, track.getConstraints());
13577
+ logger$13.debug(`[TransceiverController] Updated ${kind} sender constraints:`, constraintsToApply);
13578
+ logger$13.debug(`[TransceiverController] Updated ${kind} sender constraints:`, track.getConstraints());
13313
13579
  } catch (error) {
13314
- logger$12.warn(`[TransceiverController] Failed to apply constraints to ${kind} track ${track.id}:`, error);
13580
+ logger$13.warn(`[TransceiverController] Failed to apply constraints to ${kind} track ${track.id}:`, error);
13315
13581
  this.options.onError?.(new MediaTrackError("updateSendersConstraints", kind, error));
13316
13582
  }
13317
13583
  }
@@ -13345,60 +13611,60 @@ var TransceiverController = class extends Destroyable {
13345
13611
 
13346
13612
  //#endregion
13347
13613
  //#region src/controllers/RTCPeerConnectionController.ts
13348
- var import_cjs$11 = require_cjs();
13349
- const logger$11 = getLogger();
13614
+ var import_cjs$12 = require_cjs();
13615
+ const logger$12 = getLogger();
13350
13616
  var RTCPeerConnectionController = class extends Destroyable {
13351
13617
  constructor(options = {}, remoteSessionDescription, deviceController) {
13352
13618
  super();
13353
13619
  this.options = options;
13354
13620
  this.firstSDPExchangeCompleted = false;
13355
13621
  this.negotiationNeeded$ = this.createSubject();
13356
- this.localDescription$ = (0, import_cjs$11.defer)(() => (0, import_cjs$11.from)(this.init())).pipe((0, import_cjs$11.switchMap)(() => this.iceGatheringController.iceCandidatesState$.pipe((0, import_cjs$11.filter)((iceCandidateState) => !["new", "gathering"].includes(iceCandidateState)), (0, import_cjs$11.tap)(() => {
13622
+ this.localDescription$ = (0, import_cjs$12.defer)(() => (0, import_cjs$12.from)(this.init())).pipe((0, import_cjs$12.switchMap)(() => this.iceGatheringController.iceCandidatesState$.pipe((0, import_cjs$12.filter)((iceCandidateState) => !["new", "gathering"].includes(iceCandidateState)), (0, import_cjs$12.tap)(() => {
13357
13623
  this.negotiationEnded();
13358
- }), (0, import_cjs$11.filter)(() => this.shouldEmitLocalDescription), (0, import_cjs$11.map)(() => this.peerConnection?.localDescription), filterNull(), (0, import_cjs$11.tap)((desc) => {
13624
+ }), (0, import_cjs$12.filter)(() => this.shouldEmitLocalDescription), (0, import_cjs$12.map)(() => this.peerConnection?.localDescription), filterNull(), (0, import_cjs$12.tap)((desc) => {
13359
13625
  if (desc.type === "answer") this._type = "offer";
13360
- }))), (0, import_cjs$11.shareReplay)(1), (0, import_cjs$11.takeUntil)(this.destroyed$));
13626
+ }))), (0, import_cjs$12.shareReplay)(1), (0, import_cjs$12.takeUntil)(this.destroyed$));
13361
13627
  this.connectionTimeout = 3e3;
13362
13628
  this.oniceconnectionstatechangeHandler = () => {
13363
13629
  if (this.peerConnection) {
13364
13630
  const { iceConnectionState } = this.peerConnection;
13365
- logger$11.debug(`[RTCPeerConnectionController] ICE connection state changed to: ${iceConnectionState}`);
13631
+ logger$12.debug(`[RTCPeerConnectionController] ICE connection state changed to: ${iceConnectionState}`);
13366
13632
  this._iceConnectionState$.next(this.peerConnection.iceConnectionState);
13367
13633
  }
13368
13634
  };
13369
13635
  this.onconnectionstatechangeHandler = () => {
13370
13636
  if (this.peerConnection) {
13371
13637
  const { connectionState } = this.peerConnection;
13372
- logger$11.debug(`[RTCPeerConnectionController] Connection state changed to: ${connectionState}`);
13638
+ logger$12.debug(`[RTCPeerConnectionController] Connection state changed to: ${connectionState}`);
13373
13639
  if (connectionState === "connected") this.removeConnectionTimer();
13374
13640
  this._connectionState$.next(this.peerConnection.connectionState);
13375
13641
  }
13376
13642
  };
13377
13643
  this.onsignalingstatechangeHandler = () => {
13378
- logger$11.debug(`[RTCPeerConnectionController] Signaling state changed to: ${this.peerConnection?.signalingState}`);
13644
+ logger$12.debug(`[RTCPeerConnectionController] Signaling state changed to: ${this.peerConnection?.signalingState}`);
13379
13645
  };
13380
13646
  this.onicegatheringstatechangeHandler = () => {
13381
13647
  if (this.peerConnection) this._iceGatheringState$.next(this.peerConnection.iceGatheringState);
13382
13648
  };
13383
13649
  this.onnegotiationneededHandler = (event) => {
13384
- logger$11.debug("[RTCPeerConnectionController] Negotiation needed event received.", event);
13650
+ logger$12.debug("[RTCPeerConnectionController] Negotiation needed event received.", event);
13385
13651
  this.negotiationNeeded$.next();
13386
13652
  };
13387
13653
  this.updateSelectedInputDevice = async (kind, deviceInfo) => {
13388
13654
  try {
13389
13655
  const { localStream } = this;
13390
13656
  if (!localStream) {
13391
- logger$11.warn("[RTCPeerConnectionController] No local stream available to update input device.");
13657
+ logger$12.warn("[RTCPeerConnectionController] No local stream available to update input device.");
13392
13658
  return;
13393
13659
  }
13394
- logger$11.debug(`[RTCPeerConnectionController] Updating selected ${kind} input device:`, localStream.getTracks());
13660
+ logger$12.debug(`[RTCPeerConnectionController] Updating selected ${kind} input device:`, localStream.getTracks());
13395
13661
  const track = localStream.getTracks().find((track$1) => track$1.kind === kind);
13396
13662
  if (track) {
13397
13663
  this.transceiverController?.stopTrackSender(kind);
13398
13664
  this.localStream?.removeTrack(track);
13399
- logger$11.debug(`[RTCPeerConnectionController] Stopped existing ${kind} track: ${track.id}`, localStream.getTracks());
13665
+ logger$12.debug(`[RTCPeerConnectionController] Stopped existing ${kind} track: ${track.id}`, localStream.getTracks());
13400
13666
  if (!deviceInfo) {
13401
- logger$11.debug(`[RTCPeerConnectionController] ${kind} input device selected: none`);
13667
+ logger$12.debug(`[RTCPeerConnectionController] ${kind} input device selected: none`);
13402
13668
  return;
13403
13669
  }
13404
13670
  const streamTrack = (await this.getUserMedia({ [kind]: {
@@ -13406,15 +13672,15 @@ var RTCPeerConnectionController = class extends Destroyable {
13406
13672
  ...this.deviceController.deviceInfoToConstraints(deviceInfo)
13407
13673
  } })).getTracks().find((t) => t.kind === kind);
13408
13674
  if (streamTrack) {
13409
- logger$11.debug(`[RTCPeerConnectionController] Adding new ${kind} track: ${streamTrack.id}`);
13675
+ logger$12.debug(`[RTCPeerConnectionController] Adding new ${kind} track: ${streamTrack.id}`);
13410
13676
  this.localStream?.addTrack(streamTrack);
13411
13677
  await this.transceiverController?.replaceSenderTrack(kind, streamTrack);
13412
- logger$11.debug(`[RTCPeerConnectionController] Added new ${kind} track: ${streamTrack.id}`, this.localStream?.getTracks());
13678
+ logger$12.debug(`[RTCPeerConnectionController] Added new ${kind} track: ${streamTrack.id}`, this.localStream?.getTracks());
13413
13679
  }
13414
13680
  }
13415
- logger$11.debug(`[RTCPeerConnectionController] ${kind} input device selected:`, deviceInfo?.label);
13681
+ logger$12.debug(`[RTCPeerConnectionController] ${kind} input device selected:`, deviceInfo?.label);
13416
13682
  } catch (error) {
13417
- logger$11.error(`[RTCPeerConnectionController] Failed to select ${kind} input device:`, error);
13683
+ logger$12.error(`[RTCPeerConnectionController] Failed to select ${kind} input device:`, error);
13418
13684
  this._errors$.next(error);
13419
13685
  throw error;
13420
13686
  }
@@ -13500,43 +13766,43 @@ var RTCPeerConnectionController = class extends Destroyable {
13500
13766
  };
13501
13767
  }
13502
13768
  get iceGatheringState$() {
13503
- return this.cachedObservable("iceGatheringState$", () => this._iceGatheringState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13769
+ return this.cachedObservable("iceGatheringState$", () => this._iceGatheringState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13504
13770
  }
13505
13771
  get mediaTrackEnded$() {
13506
- return this.cachedObservable("mediaTrackEnded$", () => this.localStreamController.mediaTrackEnded$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13772
+ return this.cachedObservable("mediaTrackEnded$", () => this.localStreamController.mediaTrackEnded$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13507
13773
  }
13508
13774
  get errors$() {
13509
- return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13775
+ return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13510
13776
  }
13511
13777
  get iceCandidates$() {
13512
- return this.cachedObservable("iceCandidates$", () => this._iceCandidates$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13778
+ return this.cachedObservable("iceCandidates$", () => this._iceCandidates$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13513
13779
  }
13514
13780
  get initialized$() {
13515
- return this.cachedObservable("initialized$", () => this._initialized$.asObservable().pipe((0, import_cjs$11.filter)((initialized) => initialized), (0, import_cjs$11.takeUntil)(this.destroyed$)));
13781
+ return this.cachedObservable("initialized$", () => this._initialized$.asObservable().pipe((0, import_cjs$12.filter)((initialized) => initialized), (0, import_cjs$12.takeUntil)(this.destroyed$)));
13516
13782
  }
13517
13783
  get remoteDescription$() {
13518
- return this.cachedObservable("remoteDescription$", () => this._remoteDescription$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13784
+ return this.cachedObservable("remoteDescription$", () => this._remoteDescription$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13519
13785
  }
13520
13786
  get localStream$() {
13521
- return this.cachedObservable("localStream$", () => this.localStreamController.localStream$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13787
+ return this.cachedObservable("localStream$", () => this.localStreamController.localStream$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13522
13788
  }
13523
13789
  get remoteStream$() {
13524
- return this.cachedObservable("remoteStream$", () => this._remoteStream$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13790
+ return this.cachedObservable("remoteStream$", () => this._remoteStream$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13525
13791
  }
13526
13792
  get localAudioTracks$() {
13527
- return this.cachedObservable("localAudioTracks$", () => this.localStreamController.localAudioTracks$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13793
+ return this.cachedObservable("localAudioTracks$", () => this.localStreamController.localAudioTracks$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13528
13794
  }
13529
13795
  get localVideoTracks$() {
13530
- return this.cachedObservable("localVideoTracks$", () => this.localStreamController.localVideoTracks$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13796
+ return this.cachedObservable("localVideoTracks$", () => this.localStreamController.localVideoTracks$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13531
13797
  }
13532
13798
  get iceConnectionState$() {
13533
- return this.cachedObservable("iceConnectionState$", () => this._iceConnectionState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13799
+ return this.cachedObservable("iceConnectionState$", () => this._iceConnectionState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13534
13800
  }
13535
13801
  get connectionState$() {
13536
- return this.cachedObservable("connectionState$", () => this._connectionState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13802
+ return this.cachedObservable("connectionState$", () => this._connectionState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13537
13803
  }
13538
13804
  get signalingState$() {
13539
- return this.cachedObservable("signalingState$", () => this._signalingState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13805
+ return this.cachedObservable("signalingState$", () => this._signalingState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13540
13806
  }
13541
13807
  get type() {
13542
13808
  return this._type;
@@ -13641,17 +13907,17 @@ var RTCPeerConnectionController = class extends Destroyable {
13641
13907
  async doInit() {
13642
13908
  try {
13643
13909
  this.setupPeerConnection();
13644
- this.subscribeTo(this.negotiationNeeded$.pipe((0, import_cjs$11.auditTime)(0), (0, import_cjs$11.exhaustMap)(async () => this.startNegotiation())), {
13910
+ this.subscribeTo(this.negotiationNeeded$.pipe((0, import_cjs$12.auditTime)(0), (0, import_cjs$12.exhaustMap)(async () => this.startNegotiation())), {
13645
13911
  next: () => {
13646
- logger$11.debug("[RTCPeerConnectionController] Start Negotiation completed successfully");
13912
+ logger$12.debug("[RTCPeerConnectionController] Start Negotiation completed successfully");
13647
13913
  },
13648
13914
  error: (error) => {
13649
- logger$11.error("[RTCPeerConnectionController] Start Negotiation error:", error);
13915
+ logger$12.error("[RTCPeerConnectionController] Start Negotiation error:", error);
13650
13916
  this._errors$.next(error);
13651
13917
  }
13652
13918
  });
13653
- this.subscribeTo((0, import_cjs$11.merge)(this.deviceController.selectedAudioInputDevice$.pipe((0, import_cjs$11.map)((deviceInfo) => ["audio", deviceInfo])), this.deviceController.selectedVideoInputDevice$.pipe((0, import_cjs$11.map)((deviceInfo) => ["video", deviceInfo]))).pipe((0, import_cjs$11.skipWhile)(() => !this.localStreamController.localStream)), async ([kind, deviceInfo]) => {
13654
- logger$11.debug(`[RTCPeerConnectionController] Selected input device changed for:`, {
13919
+ this.subscribeTo((0, import_cjs$12.merge)(this.deviceController.selectedAudioInputDevice$.pipe((0, import_cjs$12.map)((deviceInfo) => ["audio", deviceInfo])), this.deviceController.selectedVideoInputDevice$.pipe((0, import_cjs$12.map)((deviceInfo) => ["video", deviceInfo]))).pipe((0, import_cjs$12.skipWhile)(() => !this.localStreamController.localStream)), async ([kind, deviceInfo]) => {
13920
+ logger$12.debug(`[RTCPeerConnectionController] Selected input device changed for:`, {
13655
13921
  kind,
13656
13922
  deviceInfo
13657
13923
  });
@@ -13668,7 +13934,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13668
13934
  this._initialized$.next(true);
13669
13935
  }
13670
13936
  } catch (error) {
13671
- logger$11.error("[RTCPeerConnectionController] Initialization error:", error);
13937
+ logger$12.error("[RTCPeerConnectionController] Initialization error:", error);
13672
13938
  this._errors$.next(error);
13673
13939
  this.destroy();
13674
13940
  }
@@ -13700,22 +13966,22 @@ var RTCPeerConnectionController = class extends Destroyable {
13700
13966
  }
13701
13967
  async startNegotiation() {
13702
13968
  if (this.isNegotiating) {
13703
- logger$11.debug("[RTCPeerConnectionController] Negotiation already in progress, skipping.");
13969
+ logger$12.debug("[RTCPeerConnectionController] Negotiation already in progress, skipping.");
13704
13970
  return;
13705
13971
  }
13706
13972
  this.setupEventListeners();
13707
13973
  if (this.type === "answer") {
13708
- logger$11.debug("[RTCPeerConnectionController] This is an answer type still, skipping offer creation.");
13974
+ logger$12.debug("[RTCPeerConnectionController] This is an answer type still, skipping offer creation.");
13709
13975
  return;
13710
13976
  }
13711
13977
  this._isNegotiating$.next(true);
13712
- logger$11.debug("[RTCPeerConnectionController] Starting negotiation.");
13978
+ logger$12.debug("[RTCPeerConnectionController] Starting negotiation.");
13713
13979
  try {
13714
13980
  const { offerOptions } = this;
13715
- logger$11.debug("[RTCPeerConnectionController] Creating offer with options:", offerOptions);
13981
+ logger$12.debug("[RTCPeerConnectionController] Creating offer with options:", offerOptions);
13716
13982
  await this.createOffer(offerOptions);
13717
13983
  } catch (error) {
13718
- logger$11.error("[RTCPeerConnectionController] Error during negotiation:", error);
13984
+ logger$12.error("[RTCPeerConnectionController] Error during negotiation:", error);
13719
13985
  this._errors$.next(error);
13720
13986
  }
13721
13987
  }
@@ -13731,14 +13997,14 @@ var RTCPeerConnectionController = class extends Destroyable {
13731
13997
  let readyToConnect = status !== "failed";
13732
13998
  try {
13733
13999
  if (status === "received" && sdp) {
13734
- logger$11.debug("[RTCPeerConnectionController] Received answer SDP:", sdp);
14000
+ logger$12.debug("[RTCPeerConnectionController] Received answer SDP:", sdp);
13735
14001
  await this._setRemoteDescription({
13736
14002
  type: "answer",
13737
14003
  sdp
13738
14004
  });
13739
14005
  }
13740
14006
  } catch (error) {
13741
- logger$11.error("[RTCPeerConnectionController] Error updating answer status:", error);
14007
+ logger$12.error("[RTCPeerConnectionController] Error updating answer status:", error);
13742
14008
  this._errors$.next(error);
13743
14009
  readyToConnect = false;
13744
14010
  } finally {
@@ -13757,7 +14023,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13757
14023
  await this.handleOfferReceived();
13758
14024
  break;
13759
14025
  case "failed":
13760
- logger$11.error("[RTCPeerConnectionController] Offer failed to be processed by remote.");
14026
+ logger$12.error("[RTCPeerConnectionController] Offer failed to be processed by remote.");
13761
14027
  break;
13762
14028
  case "sent":
13763
14029
  default:
@@ -13789,7 +14055,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13789
14055
  }
13790
14056
  await this.setupLocalTracks();
13791
14057
  const { answerOptions } = this;
13792
- logger$11.debug("[RTCPeerConnectionController] Creating inbound answer with options:", answerOptions);
14058
+ logger$12.debug("[RTCPeerConnectionController] Creating inbound answer with options:", answerOptions);
13793
14059
  await this.createAnswer(answerOptions);
13794
14060
  }
13795
14061
  async handleOfferReceived() {
@@ -13797,7 +14063,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13797
14063
  this._isNegotiating$.next(true);
13798
14064
  await this._setRemoteDescription(this.sdpInit);
13799
14065
  const { answerOptions } = this;
13800
- logger$11.debug("[RTCPeerConnectionController] Creating answer with options:", answerOptions);
14066
+ logger$12.debug("[RTCPeerConnectionController] Creating answer with options:", answerOptions);
13801
14067
  await this.createAnswer(answerOptions);
13802
14068
  }
13803
14069
  readyToConnect() {
@@ -13805,7 +14071,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13805
14071
  this.connectionTimer = setTimeout(() => {
13806
14072
  this.removeConnectionTimer();
13807
14073
  if (this.peerConnection?.connectionState !== "connected") {
13808
- logger$11.debug("[RTCPeerConnectionController] Connection timeout, restarting ICE gathering with relay only.");
14074
+ logger$12.debug("[RTCPeerConnectionController] Connection timeout, restarting ICE gathering with relay only.");
13809
14075
  this.iceGatheringController.restartICEGatheringWithRelayOnly();
13810
14076
  }
13811
14077
  }, this.connectionTimeout);
@@ -13865,13 +14131,13 @@ var RTCPeerConnectionController = class extends Destroyable {
13865
14131
  await this.setupRemoteTracks();
13866
14132
  }
13867
14133
  async setupLocalTracks() {
13868
- logger$11.debug("[RTCPeerConnectionController] Setting up local tracks/transceivers.");
14134
+ logger$12.debug("[RTCPeerConnectionController] Setting up local tracks/transceivers.");
13869
14135
  const localStream = this.localStream ?? await this.localStreamController.buildLocalStream();
13870
14136
  if (this.transceiverController?.useAddStream ?? false) {
13871
- logger$11.warn("[RTCPeerConnectionController] Using deprecated addStream API to add local stream.");
14137
+ logger$12.warn("[RTCPeerConnectionController] Using deprecated addStream API to add local stream.");
13872
14138
  this.peerConnection?.addStream(localStream);
13873
14139
  if (!this.isNegotiating) {
13874
- logger$11.debug("[RTCPeerConnectionController] Forcing negotiationneeded after local tracks setup.");
14140
+ logger$12.debug("[RTCPeerConnectionController] Forcing negotiationneeded after local tracks setup.");
13875
14141
  this.negotiationNeeded$.next();
13876
14142
  }
13877
14143
  return;
@@ -13887,7 +14153,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13887
14153
  const transceivers = (kind === "audio" ? this.transceiverController?.audioTransceivers : this.transceiverController?.videoTransceivers) ?? [];
13888
14154
  await this.transceiverController?.setupTransceiverSender(track, localStream, transceivers[index]);
13889
14155
  } else {
13890
- logger$11.debug(`[RTCPeerConnectionController] Using addTrack for local ${kind} track:`, track.id);
14156
+ logger$12.debug(`[RTCPeerConnectionController] Using addTrack for local ${kind} track:`, track.id);
13891
14157
  this.peerConnection?.addTrack(track, localStream);
13892
14158
  }
13893
14159
  }
@@ -13904,7 +14170,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13904
14170
  async setupRemoteTracks() {
13905
14171
  if (!this.peerConnection) throw new DependencyError("RTCPeerConnection is not initialized");
13906
14172
  this.peerConnection.ontrack = (event) => {
13907
- logger$11.debug("[RTCPeerConnectionController] Remote track received:", event.track.kind);
14173
+ logger$12.debug("[RTCPeerConnectionController] Remote track received:", event.track.kind);
13908
14174
  if (event.streams[0]) this._remoteStream$.next(event.streams[0]);
13909
14175
  else {
13910
14176
  const existingTracks = this._remoteStream$.value?.getTracks() ?? [];
@@ -13930,9 +14196,9 @@ var RTCPeerConnectionController = class extends Destroyable {
13930
14196
  try {
13931
14197
  const localStream = this.localStreamController.addTrack(track);
13932
14198
  this.peerConnection.addTrack(track, localStream);
13933
- logger$11.debug(`[RTCPeerConnectionController] ${track.kind} track added:`, track.id);
14199
+ logger$12.debug(`[RTCPeerConnectionController] ${track.kind} track added:`, track.id);
13934
14200
  } catch (error) {
13935
- logger$11.error(`[RTCPeerConnectionController] Failed to add ${track.kind} track:`, error);
14201
+ logger$12.error(`[RTCPeerConnectionController] Failed to add ${track.kind} track:`, error);
13936
14202
  this._errors$.next(error);
13937
14203
  throw error;
13938
14204
  }
@@ -13949,15 +14215,15 @@ var RTCPeerConnectionController = class extends Destroyable {
13949
14215
  }
13950
14216
  const sender = this.peerConnection.getSenders().find((sender$1) => sender$1.track?.id === trackId);
13951
14217
  if (!sender) {
13952
- logger$11.debug(`[RTCPeerConnectionController] track not found: ${trackId}`);
14218
+ logger$12.debug(`[RTCPeerConnectionController] track not found: ${trackId}`);
13953
14219
  return;
13954
14220
  }
13955
14221
  try {
13956
14222
  this.peerConnection.removeTrack(sender);
13957
14223
  this.localStreamController.removeTrack(trackId);
13958
- logger$11.debug(`[RTCPeerConnectionController] ${sender.track?.kind} track removed:`, trackId);
14224
+ logger$12.debug(`[RTCPeerConnectionController] ${sender.track?.kind} track removed:`, trackId);
13959
14225
  } catch (error) {
13960
- logger$11.error(`[RTCPeerConnectionController] Failed to remove ${sender.track?.kind} track:`, error);
14226
+ logger$12.error(`[RTCPeerConnectionController] Failed to remove ${sender.track?.kind} track:`, error);
13961
14227
  this._errors$.next(error);
13962
14228
  throw error;
13963
14229
  }
@@ -13980,7 +14246,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13980
14246
  * Completes all observables to prevent memory leaks.
13981
14247
  */
13982
14248
  destroy() {
13983
- logger$11.debug(`[RTCPeerConnectionController] Destroying RTCPeerConnectionController. ${this.propose}`);
14249
+ logger$12.debug(`[RTCPeerConnectionController] Destroying RTCPeerConnectionController. ${this.propose}`);
13984
14250
  this.removeConnectionTimer();
13985
14251
  this._iceGatheringController?.destroy();
13986
14252
  this.localStreamController.destroy();
@@ -14004,7 +14270,7 @@ var RTCPeerConnectionController = class extends Destroyable {
14004
14270
  }
14005
14271
  stopRemoteTracks() {
14006
14272
  this._remoteStream$.value?.getTracks().forEach((track) => {
14007
- logger$11.debug(`[RTCPeerConnectionController] Stopping remote track: ${track.kind}`);
14273
+ logger$12.debug(`[RTCPeerConnectionController] Stopping remote track: ${track.kind}`);
14008
14274
  track.stop();
14009
14275
  });
14010
14276
  }
@@ -14021,7 +14287,7 @@ var RTCPeerConnectionController = class extends Destroyable {
14021
14287
  ...params,
14022
14288
  sdp: finalRemote
14023
14289
  };
14024
- logger$11.debug("[RTCPeerConnectionController] Setting remote description:", answer);
14290
+ logger$12.debug("[RTCPeerConnectionController] Setting remote description:", answer);
14025
14291
  return this.peerConnection.setRemoteDescription(answer);
14026
14292
  }
14027
14293
  };
@@ -14059,8 +14325,8 @@ function isVertoPingInnerParams(value) {
14059
14325
 
14060
14326
  //#endregion
14061
14327
  //#region src/managers/VertoManager.ts
14062
- var import_cjs$10 = require_cjs();
14063
- const logger$10 = getLogger();
14328
+ var import_cjs$11 = require_cjs();
14329
+ const logger$11 = getLogger();
14064
14330
  var VertoManager = class extends Destroyable {
14065
14331
  constructor(callSession) {
14066
14332
  super();
@@ -14098,7 +14364,7 @@ var WebRTCVertoManager = class extends VertoManager {
14098
14364
  try {
14099
14365
  await this.executeVerto(vertoModifyMessage);
14100
14366
  } catch (error) {
14101
- logger$10.warn("[WebRTCManager] Call might already be disconnected, error sending Verto hold:", error);
14367
+ logger$11.warn("[WebRTCManager] Call might already be disconnected, error sending Verto hold:", error);
14102
14368
  throw error;
14103
14369
  }
14104
14370
  }
@@ -14111,7 +14377,7 @@ var WebRTCVertoManager = class extends VertoManager {
14111
14377
  try {
14112
14378
  await this.executeVerto(vertoModifyMessage);
14113
14379
  } catch (error) {
14114
- logger$10.warn("[WebRTCManager] Call might already be disconnected, error sending Verto unhold:", error);
14380
+ logger$11.warn("[WebRTCManager] Call might already be disconnected, error sending Verto unhold:", error);
14115
14381
  throw error;
14116
14382
  }
14117
14383
  }
@@ -14151,7 +14417,7 @@ var WebRTCVertoManager = class extends VertoManager {
14151
14417
  return rtcPeerConnection;
14152
14418
  }
14153
14419
  get signalingStatus$() {
14154
- return this.cachedObservable("signalingStatus$", () => (0, import_cjs$10.merge)(this._signalingStatus$.pipe(filterNull()), this.mainPeerConnection.connectionState$.pipe((0, import_cjs$10.filter)((connectionState) => [
14420
+ return this.cachedObservable("signalingStatus$", () => (0, import_cjs$11.merge)(this._signalingStatus$.pipe(filterNull()), this.mainPeerConnection.connectionState$.pipe((0, import_cjs$11.filter)((connectionState) => [
14155
14421
  "connected",
14156
14422
  "disconnected",
14157
14423
  "failed"
@@ -14164,7 +14430,7 @@ var WebRTCVertoManager = class extends VertoManager {
14164
14430
  if (event.member_id) this.setSelfIdIfNull(event.member_id);
14165
14431
  });
14166
14432
  this.subscribeTo(this.vertoMedia$, (event) => {
14167
- logger$10.debug("[WebRTCManager] Received Verto media event (early media SDP):", event);
14433
+ logger$11.debug("[WebRTCManager] Received Verto media event (early media SDP):", event);
14168
14434
  this._signalingStatus$.next("ringing");
14169
14435
  const { sdp, callID } = event;
14170
14436
  this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
@@ -14173,7 +14439,7 @@ var WebRTCVertoManager = class extends VertoManager {
14173
14439
  });
14174
14440
  });
14175
14441
  this.subscribeTo(this.vertoAnswer$, (event) => {
14176
- logger$10.debug("[WebRTCManager] Received Verto answer event:", event);
14442
+ logger$11.debug("[WebRTCManager] Received Verto answer event:", event);
14177
14443
  this._signalingStatus$.next("connecting");
14178
14444
  const { sdp, callID } = event;
14179
14445
  this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
@@ -14182,7 +14448,7 @@ var WebRTCVertoManager = class extends VertoManager {
14182
14448
  });
14183
14449
  });
14184
14450
  this.subscribeTo(this.vertoMediaParams$, (event) => {
14185
- logger$10.debug("[WebRTCManager] Received Verto mediaParams event:", event);
14451
+ logger$11.debug("[WebRTCManager] Received Verto mediaParams event:", event);
14186
14452
  const { mediaParams, callID } = event;
14187
14453
  const rtcPeerConnController = this._rtcPeerConnectionsMap.get(callID);
14188
14454
  const { audio, video } = mediaParams;
@@ -14206,13 +14472,13 @@ var WebRTCVertoManager = class extends VertoManager {
14206
14472
  */
14207
14473
  setNodeIdIfNull(nodeId) {
14208
14474
  if (!this._nodeId$.value && nodeId) {
14209
- logger$10.debug(`[WebRTCManager] Early node_id set: ${nodeId}`);
14475
+ logger$11.debug(`[WebRTCManager] Early node_id set: ${nodeId}`);
14210
14476
  this._nodeId$.next(nodeId);
14211
14477
  }
14212
14478
  }
14213
14479
  setSelfIdIfNull(selfId) {
14214
14480
  if (!this._selfId$.value && selfId) {
14215
- logger$10.debug(`[WebRTCManager] Early selfId set: ${selfId}`);
14481
+ logger$11.debug(`[WebRTCManager] Early selfId set: ${selfId}`);
14216
14482
  this._selfId$.next(selfId);
14217
14483
  }
14218
14484
  }
@@ -14221,7 +14487,7 @@ var WebRTCVertoManager = class extends VertoManager {
14221
14487
  const vertoPongMessage = VertoPong({ ...vertoPing });
14222
14488
  await this.executeVerto(vertoPongMessage);
14223
14489
  } catch (error) {
14224
- logger$10.warn("[WebRTCManager] Call might disconnect, error sending Verto pong:", error);
14490
+ logger$11.warn("[WebRTCManager] Call might disconnect, error sending Verto pong:", error);
14225
14491
  this.onError?.(new VertoPongError(error));
14226
14492
  }
14227
14493
  }
@@ -14231,7 +14497,7 @@ var WebRTCVertoManager = class extends VertoManager {
14231
14497
  if (audio) await this.mainPeerConnection.updateSendersConstraints("audio", audio);
14232
14498
  if (video) await this.mainPeerConnection.updateSendersConstraints("video", video);
14233
14499
  } catch (error) {
14234
- logger$10.warn("[WebRTCManager] Error updating media constraints:", error);
14500
+ logger$11.warn("[WebRTCManager] Error updating media constraints:", error);
14235
14501
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14236
14502
  throw error;
14237
14503
  }
@@ -14240,25 +14506,25 @@ var WebRTCVertoManager = class extends VertoManager {
14240
14506
  return this._selfId$.value;
14241
14507
  }
14242
14508
  get callJoinedEvent$() {
14243
- return this.webRtcCallSession.callEvent$.pipe((0, import_cjs$10.filter)(isCallJoinedPayload), (0, import_cjs$10.takeUntil)(this.destroyed$));
14509
+ return this.webRtcCallSession.callEvent$.pipe((0, import_cjs$11.filter)(isCallJoinedPayload), (0, import_cjs$11.takeUntil)(this.destroyed$));
14244
14510
  }
14245
14511
  get vertoMedia$() {
14246
- return this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$));
14512
+ return this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$));
14247
14513
  }
14248
14514
  get vertoAnswer$() {
14249
- return this.cachedObservable("vertoAnswer$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAnswerInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14515
+ return this.cachedObservable("vertoAnswer$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAnswerInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14250
14516
  }
14251
14517
  get vertoMediaParams$() {
14252
- return this.cachedObservable("vertoMediaParams$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaParamsInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14518
+ return this.cachedObservable("vertoMediaParams$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaParamsInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14253
14519
  }
14254
14520
  get vertoBye$() {
14255
- return this.cachedObservable("vertoBye$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoByeMessage, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14521
+ return this.cachedObservable("vertoBye$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoByeMessage, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14256
14522
  }
14257
14523
  get vertoAttach$() {
14258
- return this.cachedObservable("vertoAttach$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAttachMessage, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14524
+ return this.cachedObservable("vertoAttach$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAttachMessage, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14259
14525
  }
14260
14526
  get vertoPing$() {
14261
- return this.cachedObservable("vertoPing$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoPingInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14527
+ return this.cachedObservable("vertoPing$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoPingInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14262
14528
  }
14263
14529
  async executeVerto(message, optionals = {}) {
14264
14530
  const webrtcVertoMessage = WebrtcVerto({
@@ -14296,7 +14562,7 @@ var WebRTCVertoManager = class extends VertoManager {
14296
14562
  default:
14297
14563
  }
14298
14564
  } catch (error) {
14299
- logger$10.error(`[WebRTCManager] Error sending Verto ${vertoMethod}:`, error);
14565
+ logger$11.error(`[WebRTCManager] Error sending Verto ${vertoMethod}:`, error);
14300
14566
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14301
14567
  }
14302
14568
  }
@@ -14310,7 +14576,7 @@ var WebRTCVertoManager = class extends VertoManager {
14310
14576
  sdp
14311
14577
  });
14312
14578
  } catch (error) {
14313
- logger$10.warn("[WebRTCManager] Error processing modify response:", error);
14579
+ logger$11.warn("[WebRTCManager] Error processing modify response:", error);
14314
14580
  const modifyError = error instanceof Error ? error : new Error(String(error), { cause: error });
14315
14581
  this.onError?.(modifyError);
14316
14582
  }
@@ -14322,7 +14588,7 @@ var WebRTCVertoManager = class extends VertoManager {
14322
14588
  this._nodeId$.next(getValueFrom(response, "result.node_id") ?? null);
14323
14589
  const memberId = getValueFrom(response, "result.result.result.memberID") ?? null;
14324
14590
  const callId = getValueFrom(response, "result.result.result.callID") ?? null;
14325
- logger$10.debug("[WebRTCManager] Verto invite response:", {
14591
+ logger$11.debug("[WebRTCManager] Verto invite response:", {
14326
14592
  callId,
14327
14593
  memberId,
14328
14594
  response
@@ -14331,10 +14597,10 @@ var WebRTCVertoManager = class extends VertoManager {
14331
14597
  rtcPeerConnController.setMemberId(memberId);
14332
14598
  if (callId) this.webRtcCallSession.addCallId(callId);
14333
14599
  this.attachManager.attach(this.webRtcCallSession);
14334
- logger$10.info("[WebRTCManager] Verto invite successful");
14335
- logger$10.debug(`[WebRTCManager] nodeid: ${this._nodeId$.value}, selfId: ${this._selfId$.value}`);
14600
+ logger$11.info("[WebRTCManager] Verto invite successful");
14601
+ logger$11.debug(`[WebRTCManager] nodeid: ${this._nodeId$.value}, selfId: ${this._selfId$.value}`);
14336
14602
  } else {
14337
- logger$10.error("[WebRTCManager] Verto invite failed:", response);
14603
+ logger$11.error("[WebRTCManager] Verto invite failed:", response);
14338
14604
  const inviteError = response.error ? new JSONRPCError(response.error.code, response.error.message, response.error.data) : /* @__PURE__ */ new Error("Verto invite failed: unexpected response");
14339
14605
  this.onError?.(inviteError);
14340
14606
  }
@@ -14376,17 +14642,17 @@ var WebRTCVertoManager = class extends VertoManager {
14376
14642
  if (options.initOffer) this.handleInboundAnswer(rtcPeerConnController);
14377
14643
  }
14378
14644
  async handleInboundAnswer(rtcPeerConnController) {
14379
- logger$10.debug("[WebRTCManager] Waiting for inbound call to be accepted or rejected");
14380
- const vertoByeOrAccepted = await (0, import_cjs$10.firstValueFrom)((0, import_cjs$10.race)(this.vertoBye$, this.webRtcCallSession.answered$).pipe((0, import_cjs$10.takeUntil)(this.destroyed$))).catch(() => null);
14645
+ logger$11.debug("[WebRTCManager] Waiting for inbound call to be accepted or rejected");
14646
+ const vertoByeOrAccepted = await (0, import_cjs$11.firstValueFrom)((0, import_cjs$11.race)(this.vertoBye$, this.webRtcCallSession.answered$).pipe((0, import_cjs$11.takeUntil)(this.destroyed$))).catch(() => null);
14381
14647
  if (vertoByeOrAccepted === null) {
14382
- logger$10.debug("[WebRTCManager] Inbound answer handler aborted (destroyed).");
14648
+ logger$11.debug("[WebRTCManager] Inbound answer handler aborted (destroyed).");
14383
14649
  return;
14384
14650
  }
14385
14651
  if (isVertoByeMessage(vertoByeOrAccepted)) {
14386
- logger$10.info("[WebRTCManager] Inbound call ended by remote before answer.");
14652
+ logger$11.info("[WebRTCManager] Inbound call ended by remote before answer.");
14387
14653
  this.callSession?.destroy();
14388
14654
  } else if (!vertoByeOrAccepted) {
14389
- logger$10.info("[WebRTCManager] Inbound call rejected by user.");
14655
+ logger$11.info("[WebRTCManager] Inbound call rejected by user.");
14390
14656
  try {
14391
14657
  await this.bye("USER_BUSY");
14392
14658
  } finally {
@@ -14394,19 +14660,19 @@ var WebRTCVertoManager = class extends VertoManager {
14394
14660
  this.callSession?.destroy();
14395
14661
  }
14396
14662
  } else {
14397
- logger$10.debug("[WebRTCManager] Inbound call accepted, creating SDP answer");
14663
+ logger$11.debug("[WebRTCManager] Inbound call accepted, creating SDP answer");
14398
14664
  const answerOptions = this.webRtcCallSession.answerMediaOptions;
14399
14665
  try {
14400
14666
  await rtcPeerConnController.acceptInbound(answerOptions);
14401
14667
  } catch (error) {
14402
- logger$10.error("[WebRTCManager] Error creating inbound answer:", error);
14668
+ logger$11.error("[WebRTCManager] Error creating inbound answer:", error);
14403
14669
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14404
14670
  }
14405
14671
  }
14406
14672
  }
14407
14673
  setupVertoAttachHandler() {
14408
14674
  this.subscribeTo(this.vertoAttach$, async (vertoAttach) => {
14409
- logger$10.debug("[WebRTCManager] Received Verto attach event:", vertoAttach);
14675
+ logger$11.debug("[WebRTCManager] Received Verto attach event:", vertoAttach);
14410
14676
  const { callID } = vertoAttach;
14411
14677
  await this.attachManager.attach({
14412
14678
  id: callID,
@@ -14420,12 +14686,12 @@ var WebRTCVertoManager = class extends VertoManager {
14420
14686
  });
14421
14687
  }
14422
14688
  initObservables(rtcPeerConnController) {
14423
- this.mediaDirections$ = rtcPeerConnController.connectionState$.pipe((0, import_cjs$10.filter)((state) => state === "connected"), (0, import_cjs$10.map)(() => rtcPeerConnController.mediaDirections), (0, import_cjs$10.startWith)(rtcPeerConnController.mediaDirections), (0, import_cjs$10.takeUntil)(this.destroyed$));
14424
- this.localStream$ = rtcPeerConnController.localStream$.pipe(filterNull(), (0, import_cjs$10.takeUntil)(this.destroyed$));
14425
- this.remoteStream$ = rtcPeerConnController.remoteStream$.pipe(filterNull(), (0, import_cjs$10.takeUntil)(this.destroyed$));
14689
+ this.mediaDirections$ = rtcPeerConnController.connectionState$.pipe((0, import_cjs$11.filter)((state) => state === "connected"), (0, import_cjs$11.map)(() => rtcPeerConnController.mediaDirections), (0, import_cjs$11.startWith)(rtcPeerConnController.mediaDirections), (0, import_cjs$11.takeUntil)(this.destroyed$));
14690
+ this.localStream$ = rtcPeerConnController.localStream$.pipe(filterNull(), (0, import_cjs$11.takeUntil)(this.destroyed$));
14691
+ this.remoteStream$ = rtcPeerConnController.remoteStream$.pipe(filterNull(), (0, import_cjs$11.takeUntil)(this.destroyed$));
14426
14692
  }
14427
14693
  setupLocalDescriptionHandler(rtcPeerConnController) {
14428
- this.subscribeTo(rtcPeerConnController.localDescription$.pipe((0, import_cjs$10.filter)((description) => description !== null), (0, import_cjs$10.takeUntil)(this.destroyed$)), (description) => {
14694
+ this.subscribeTo(rtcPeerConnController.localDescription$.pipe((0, import_cjs$11.filter)((description) => description !== null), (0, import_cjs$11.takeUntil)(this.destroyed$)), (description) => {
14429
14695
  const { type, sdp } = description;
14430
14696
  const dialogParams = this.dialogParams(rtcPeerConnController);
14431
14697
  const initial = !rtcPeerConnController.firstSDPExchangeCompleted;
@@ -14474,13 +14740,13 @@ var WebRTCVertoManager = class extends VertoManager {
14474
14740
  };
14475
14741
  }
14476
14742
  async sendLocalDescriptionOnceAccepted(vertoMessageRequest, rtcPeerConnectionController) {
14477
- logger$10.debug("[WebRTCManager] Waiting for call to be accepted or ended before sending answer");
14478
- const vertoByeOrAccepted = await (0, import_cjs$10.firstValueFrom)((0, import_cjs$10.race)(this.vertoBye$, this.webRtcCallSession.answered$));
14743
+ logger$11.debug("[WebRTCManager] Waiting for call to be accepted or ended before sending answer");
14744
+ const vertoByeOrAccepted = await (0, import_cjs$11.firstValueFrom)((0, import_cjs$11.race)(this.vertoBye$, this.webRtcCallSession.answered$));
14479
14745
  if (isVertoByeMessage(vertoByeOrAccepted)) {
14480
- logger$10.info("[WebRTCManager] Call ended before answer was sent.");
14746
+ logger$11.info("[WebRTCManager] Call ended before answer was sent.");
14481
14747
  this.callSession?.destroy();
14482
14748
  } else if (!vertoByeOrAccepted) {
14483
- logger$10.info("[WebRTCManager] Call was not accepted, sending verto.bye.");
14749
+ logger$11.info("[WebRTCManager] Call was not accepted, sending verto.bye.");
14484
14750
  try {
14485
14751
  await this.bye("USER_BUSY");
14486
14752
  } finally {
@@ -14488,14 +14754,14 @@ var WebRTCVertoManager = class extends VertoManager {
14488
14754
  this.callSession?.destroy();
14489
14755
  }
14490
14756
  } else {
14491
- logger$10.debug("[WebRTCManager] Call accepted, sending answer");
14757
+ logger$11.debug("[WebRTCManager] Call accepted, sending answer");
14492
14758
  try {
14493
14759
  this._signalingStatus$.next("connecting");
14494
14760
  await this.sendLocalDescription(vertoMessageRequest, rtcPeerConnectionController);
14495
14761
  await rtcPeerConnectionController.updateAnswerStatus({ status: "sent" });
14496
14762
  await this.attachManager.attach(this.webRtcCallSession);
14497
14763
  } catch (error) {
14498
- logger$10.error("[WebRTCManager] Error sending Verto answer:", error);
14764
+ logger$11.error("[WebRTCManager] Error sending Verto answer:", error);
14499
14765
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14500
14766
  await rtcPeerConnectionController.updateAnswerStatus({ status: "failed" });
14501
14767
  }
@@ -14584,12 +14850,12 @@ var WebRTCVertoManager = class extends VertoManager {
14584
14850
  this.subscribeTo(rtcPeerConnController.errors$, (error) => {
14585
14851
  this.onError?.(error);
14586
14852
  });
14587
- await (0, import_cjs$10.firstValueFrom)(rtcPeerConnController.connectionState$.pipe((0, import_cjs$10.filter)((state) => state === "connected"), (0, import_cjs$10.take)(1), (0, import_cjs$10.timeout)(this._screenShareTimeoutMs)));
14853
+ await (0, import_cjs$11.firstValueFrom)(rtcPeerConnController.connectionState$.pipe((0, import_cjs$11.filter)((state) => state === "connected"), (0, import_cjs$11.take)(1), (0, import_cjs$11.timeout)(this._screenShareTimeoutMs)));
14588
14854
  this._screenShareStatus$.next("started");
14589
- logger$10.info("[WebRTCManager] Screen share started successfully.");
14855
+ logger$11.info("[WebRTCManager] Screen share started successfully.");
14590
14856
  return rtcPeerConnController.id;
14591
14857
  } catch (error) {
14592
- logger$10.warn("[WebRTCManager] Error initializing additional peer connection:", error);
14858
+ logger$11.warn("[WebRTCManager] Error initializing additional peer connection:", error);
14593
14859
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14594
14860
  if (rtcPeerConnController) rtcPeerConnController.destroy();
14595
14861
  this._screenShareStatus$.next("none");
@@ -14608,9 +14874,9 @@ var WebRTCVertoManager = class extends VertoManager {
14608
14874
  if (removeTrack) return this.mainPeerConnection.stopTrackSender(removeTrack, { updateTransceiverDirection: true });
14609
14875
  }
14610
14876
  async removeScreenMedia() {
14611
- if (!["starting", "started"].includes(this._screenShareStatus$.value)) logger$10.warn("[WebRTCManager] No active screen share to stop.");
14877
+ if (!["starting", "started"].includes(this._screenShareStatus$.value)) logger$11.warn("[WebRTCManager] No active screen share to stop.");
14612
14878
  if (!this._screenShareId) {
14613
- logger$10.debug("[WebRTCManager] No screen share peer connection found.");
14879
+ logger$11.debug("[WebRTCManager] No screen share peer connection found.");
14614
14880
  return;
14615
14881
  }
14616
14882
  this._screenShareStatus$.next("stopping");
@@ -14639,7 +14905,7 @@ var WebRTCVertoManager = class extends VertoManager {
14639
14905
  dialogParams: this.dialogParams(rtcPeerConnController)
14640
14906
  }));
14641
14907
  } catch (error) {
14642
- logger$10.warn("[WebRTCManager] Call might already be disconnected, error sending Verto bye:", error);
14908
+ logger$11.warn("[WebRTCManager] Call might already be disconnected, error sending Verto bye:", error);
14643
14909
  throw error;
14644
14910
  }
14645
14911
  }
@@ -14657,7 +14923,7 @@ var WebRTCVertoManager = class extends VertoManager {
14657
14923
  try {
14658
14924
  await this.executeVerto(vertoInfoMessage);
14659
14925
  } catch (error) {
14660
- logger$10.warn("[WebRTCManager] Error sending DTMF digits:", error);
14926
+ logger$11.warn("[WebRTCManager] Error sending DTMF digits:", error);
14661
14927
  throw error;
14662
14928
  }
14663
14929
  }
@@ -14668,10 +14934,10 @@ var WebRTCVertoManager = class extends VertoManager {
14668
14934
  action: "transfer"
14669
14935
  });
14670
14936
  try {
14671
- logger$10.debug("[WebRTCManager] Transferring call with options:", options);
14937
+ logger$11.debug("[WebRTCManager] Transferring call with options:", options);
14672
14938
  await this.executeVerto(message);
14673
14939
  } catch (error) {
14674
- logger$10.error("[WebRTCManager] Error transferring call:", error);
14940
+ logger$11.error("[WebRTCManager] Error transferring call:", error);
14675
14941
  throw error;
14676
14942
  }
14677
14943
  }
@@ -14713,8 +14979,8 @@ var ParticipantFactory = class {
14713
14979
 
14714
14980
  //#endregion
14715
14981
  //#region src/core/entities/Call.ts
14716
- var import_cjs$9 = require_cjs();
14717
- const logger$9 = getLogger();
14982
+ var import_cjs$10 = require_cjs();
14983
+ const logger$10 = getLogger();
14718
14984
  const fromDestinationParams = (destination) => {
14719
14985
  if (!destination) return {};
14720
14986
  try {
@@ -14725,7 +14991,7 @@ const fromDestinationParams = (destination) => {
14725
14991
  });
14726
14992
  return params;
14727
14993
  } catch (error) {
14728
- logger$9.warn(`Failed to parse destination URI: ${destination}`, error);
14994
+ logger$10.warn(`Failed to parse destination URI: ${destination}`, error);
14729
14995
  return {};
14730
14996
  }
14731
14997
  };
@@ -14793,7 +15059,7 @@ var WebRTCCall = class extends Destroyable {
14793
15059
  }
14794
15060
  /** Observable of the address associated with this call. */
14795
15061
  get address$() {
14796
- return this.deferEmission((0, import_cjs$9.from)([this.address])).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15062
+ return this.deferEmission((0, import_cjs$10.from)([this.address])).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14797
15063
  }
14798
15064
  /** Display name of the caller. */
14799
15065
  get fromName() {
@@ -14872,7 +15138,7 @@ var WebRTCCall = class extends Destroyable {
14872
15138
  }
14873
15139
  /** Observable of layout layer positions for all participants. */
14874
15140
  get layoutLayers$() {
14875
- return this.deferEmission(this.callEventsManager.layoutLayers$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15141
+ return this.deferEmission(this.callEventsManager.layoutLayers$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14876
15142
  }
14877
15143
  /** Current snapshot of layout layers. */
14878
15144
  get layoutLayers() {
@@ -14900,7 +15166,7 @@ var WebRTCCall = class extends Destroyable {
14900
15166
  if (isJSONRPCErrorResponse(response)) throw new JSONRPCError(parseInt(response.result?.code ?? "0"), `Error response from method ${method}: ${response.result?.code} ${response.result?.message}`, void 0, void 0, request.id);
14901
15167
  return response;
14902
15168
  } catch (error) {
14903
- logger$9.error(`[Call] Error executing method ${method} with params`, params, error);
15169
+ logger$10.error(`[Call] Error executing method ${method} with params`, params, error);
14904
15170
  throw error;
14905
15171
  }
14906
15172
  }
@@ -14927,45 +15193,45 @@ var WebRTCCall = class extends Destroyable {
14927
15193
  }
14928
15194
  /** Observable of the current call status (e.g. `'ringing'`, `'connected'`). */
14929
15195
  get status$() {
14930
- return this.publicCachedObservable("status$", () => (0, import_cjs$9.merge)(this._status$.asObservable(), this.vertoManager.signalingStatus$).pipe((0, import_cjs$9.distinctUntilChanged)(), (0, import_cjs$9.tap)((status) => {
15196
+ return this.publicCachedObservable("status$", () => (0, import_cjs$10.merge)(this._status$.asObservable(), this.vertoManager.signalingStatus$).pipe((0, import_cjs$10.distinctUntilChanged)(), (0, import_cjs$10.tap)((status) => {
14931
15197
  this._lastMergedStatus = status;
14932
15198
  })));
14933
15199
  }
14934
15200
  /** Observable of the participants list, emits on join/leave/update. */
14935
15201
  get participants$() {
14936
- return this.deferEmission(this.callEventsManager.participants$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15202
+ return this.deferEmission(this.callEventsManager.participants$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14937
15203
  }
14938
15204
  /** Observable of the local (self) participant. */
14939
15205
  get self$() {
14940
- return this.deferEmission(this.callEventsManager.self$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15206
+ return this.deferEmission(this.callEventsManager.self$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14941
15207
  }
14942
15208
  /** Observable indicating whether the call is being recorded. */
14943
15209
  get recording$() {
14944
- return this.deferEmission(this.callEventsManager.recording$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15210
+ return this.deferEmission(this.callEventsManager.recording$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14945
15211
  }
14946
15212
  /** Observable indicating whether the call is being streamed. */
14947
15213
  get streaming$() {
14948
- return this.deferEmission(this.callEventsManager.streaming$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15214
+ return this.deferEmission(this.callEventsManager.streaming$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14949
15215
  }
14950
15216
  /** Observable indicating whether raise-hand priority is active. */
14951
15217
  get raiseHandPriority$() {
14952
- return this.deferEmission(this.callEventsManager.raiseHandPriority$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15218
+ return this.deferEmission(this.callEventsManager.raiseHandPriority$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14953
15219
  }
14954
15220
  /** Observable indicating whether the call room is locked. */
14955
15221
  get locked$() {
14956
- return this.deferEmission(this.callEventsManager.locked$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15222
+ return this.deferEmission(this.callEventsManager.locked$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14957
15223
  }
14958
15224
  /** Observable of custom metadata associated with the call. */
14959
15225
  get meta$() {
14960
- return this.deferEmission(this.callEventsManager.meta$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15226
+ return this.deferEmission(this.callEventsManager.meta$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14961
15227
  }
14962
15228
  /** Observable of the call's capability flags. */
14963
15229
  get capabilities$() {
14964
- return this.deferEmission(this.callEventsManager.capabilities$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15230
+ return this.deferEmission(this.callEventsManager.capabilities$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14965
15231
  }
14966
15232
  /** Observable of the current layout name. */
14967
15233
  get layout$() {
14968
- return this.deferEmission(this.callEventsManager.layout$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15234
+ return this.deferEmission(this.callEventsManager.layout$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14969
15235
  }
14970
15236
  /** Current call status. */
14971
15237
  get status() {
@@ -14997,7 +15263,7 @@ var WebRTCCall = class extends Destroyable {
14997
15263
  }
14998
15264
  /** Observable of available layout names. */
14999
15265
  get layouts$() {
15000
- return this.deferEmission(this.callEventsManager.layouts$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15266
+ return this.deferEmission(this.callEventsManager.layouts$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15001
15267
  }
15002
15268
  /** Current snapshot of available layout names. */
15003
15269
  get layouts() {
@@ -15005,7 +15271,7 @@ var WebRTCCall = class extends Destroyable {
15005
15271
  }
15006
15272
  /** Observable of the local media stream (camera/microphone). */
15007
15273
  get localStream$() {
15008
- return this.deferEmission(this.vertoManager.localStream$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15274
+ return this.deferEmission(this.vertoManager.localStream$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15009
15275
  }
15010
15276
  /** Current local media stream, or `null` if not available. */
15011
15277
  get localStream() {
@@ -15013,7 +15279,7 @@ var WebRTCCall = class extends Destroyable {
15013
15279
  }
15014
15280
  /** Observable of the remote media stream from the far end. */
15015
15281
  get remoteStream$() {
15016
- return this.deferEmission(this.vertoManager.remoteStream$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15282
+ return this.deferEmission(this.vertoManager.remoteStream$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15017
15283
  }
15018
15284
  /** Current remote media stream, or `null` if not available. */
15019
15285
  get remoteStream() {
@@ -15041,14 +15307,14 @@ var WebRTCCall = class extends Destroyable {
15041
15307
  }
15042
15308
  /** Observable of the current audio/video send/receive directions. */
15043
15309
  get mediaDirections$() {
15044
- return this.deferEmission(this.vertoManager.mediaDirections$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15310
+ return this.deferEmission(this.vertoManager.mediaDirections$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15045
15311
  }
15046
15312
  /** Current audio/video send/receive directions. */
15047
15313
  get mediaDirections() {
15048
15314
  return this.vertoManager.mediaDirections;
15049
15315
  }
15050
15316
  get participantsId$() {
15051
- return this.cachedObservable("participantsId$", () => this.participants$.pipe((0, import_cjs$9.map)((participants) => participants.map((participant) => participant.id))));
15317
+ return this.cachedObservable("participantsId$", () => this.participants$.pipe((0, import_cjs$10.map)((participants) => participants.map((participant) => participant.id))));
15052
15318
  }
15053
15319
  /**
15054
15320
  * Executes a raw JSON-RPC request on the client session.
@@ -15081,46 +15347,48 @@ var WebRTCCall = class extends Destroyable {
15081
15347
  }
15082
15348
  isCallSessionEvent(event) {
15083
15349
  try {
15084
- logger$9.debug("[Call] Checking if event is for this call session:", event);
15350
+ logger$10.debug("[Call] Checking if event is for this call session:", event);
15085
15351
  const callId = getValueFrom(event, "params.params.callID") ?? getValueFrom(event, "params.call_id");
15086
15352
  const roomSessionId = getValueFrom(event, "params.room_session_id");
15087
- logger$9.debug(`[Call] Extracted session identifiers callID: ${callId} and roomSessionID: ${roomSessionId} from event:`);
15353
+ logger$10.debug(`[Call] Extracted session identifiers callID: ${callId} and roomSessionID: ${roomSessionId} from event:`);
15088
15354
  return callId === this.id || !!callId && this.callEventsManager.isCallIdValid(callId) || !!roomSessionId && this.callEventsManager.isRoomSessionIdValid(roomSessionId);
15089
15355
  } catch (error) {
15090
- logger$9.error("[Call] Error checking if event is for this call session:", error);
15356
+ logger$10.error("[Call] Error checking if event is for this call session:", error);
15091
15357
  return false;
15092
15358
  }
15093
15359
  }
15094
15360
  get callSessionEvents$() {
15095
- return this.cachedObservable("callSessionEvents$", () => this.clientSession.signalingEvent$.pipe((0, import_cjs$9.filter)((event) => this.isCallSessionEvent(event)), (0, import_cjs$9.tap)((event) => logger$9.debug("[Call] Received call session event:", event)), (0, import_cjs$9.takeUntil)(this.destroyed$), (0, import_cjs$9.share)()));
15361
+ return this.cachedObservable("callSessionEvents$", () => this.clientSession.signalingEvent$.pipe((0, import_cjs$10.filter)((event) => this.isCallSessionEvent(event)), (0, import_cjs$10.tap)((event) => {
15362
+ logger$10.debug("[Call] Received call session event:", event);
15363
+ }), (0, import_cjs$10.takeUntil)(this.destroyed$), (0, import_cjs$10.share)()));
15096
15364
  }
15097
15365
  /** Observable of call-updated events. */
15098
15366
  get callUpdated$() {
15099
- return this.publicCachedObservable("callUpdated$", () => this.callSessionEvents$.pipe(filterAs(isCallUpdatedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15367
+ return this.publicCachedObservable("callUpdated$", () => this.callSessionEvents$.pipe(filterAs(isCallUpdatedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15100
15368
  }
15101
15369
  /** Observable of member-joined events, emitted when a remote participant joins the call. */
15102
15370
  get memberJoined$() {
15103
- return this.publicCachedObservable("memberJoined$", () => this.callSessionEvents$.pipe(filterAs(isMemberJoinedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15371
+ return this.publicCachedObservable("memberJoined$", () => this.callSessionEvents$.pipe(filterAs(isMemberJoinedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15104
15372
  }
15105
15373
  /** Observable of member-left events, emitted when a participant leaves the call. */
15106
15374
  get memberLeft$() {
15107
- return this.publicCachedObservable("memberLeft$", () => this.callSessionEvents$.pipe(filterAs(isMemberLeftMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15375
+ return this.publicCachedObservable("memberLeft$", () => this.callSessionEvents$.pipe(filterAs(isMemberLeftMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15108
15376
  }
15109
15377
  /** Observable of member-updated events (mute, volume, etc.). */
15110
15378
  get memberUpdated$() {
15111
- return this.publicCachedObservable("memberUpdated$", () => this.callSessionEvents$.pipe(filterAs(isMemberUpdatedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15379
+ return this.publicCachedObservable("memberUpdated$", () => this.callSessionEvents$.pipe(filterAs(isMemberUpdatedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15112
15380
  }
15113
15381
  /** Observable of member-talking events (speech start/stop). */
15114
15382
  get memberTalking$() {
15115
- return this.publicCachedObservable("memberTalking$", () => this.callSessionEvents$.pipe(filterAs(isMemberTalkingMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15383
+ return this.publicCachedObservable("memberTalking$", () => this.callSessionEvents$.pipe(filterAs(isMemberTalkingMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15116
15384
  }
15117
15385
  /** Observable of call state-change events. */
15118
15386
  get callStates$() {
15119
- return this.publicCachedObservable("callStates$", () => this.callSessionEvents$.pipe(filterAs(isCallStateMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15387
+ return this.publicCachedObservable("callStates$", () => this.callSessionEvents$.pipe(filterAs(isCallStateMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15120
15388
  }
15121
15389
  /** Observable of layout-changed events. */
15122
15390
  get layoutUpdates$() {
15123
- return this.publicCachedObservable("layoutUpdates$", () => this.callSessionEvents$.pipe(filterAs(isLayoutChangedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15391
+ return this.publicCachedObservable("layoutUpdates$", () => this.callSessionEvents$.pipe(filterAs(isLayoutChangedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15124
15392
  }
15125
15393
  /** Underlying `RTCPeerConnection`, for advanced use cases. */
15126
15394
  get rtcPeerConnection() {
@@ -15128,15 +15396,15 @@ var WebRTCCall = class extends Destroyable {
15128
15396
  }
15129
15397
  /** Observable of raw signaling events as plain objects. */
15130
15398
  get signalingEvent$() {
15131
- return this.publicCachedObservable("signalingEvent$", () => this.callEvent$.pipe((0, import_cjs$9.map)((event) => JSON.parse(JSON.stringify(event)))));
15399
+ return this.publicCachedObservable("signalingEvent$", () => this.callEvent$.pipe((0, import_cjs$10.map)((event) => JSON.parse(JSON.stringify(event)))));
15132
15400
  }
15133
15401
  /** Observable of WebRTC-specific signaling messages. */
15134
15402
  get webrtcMessages$() {
15135
- return this.cachedObservable("webrtcMessages$", () => this.callSessionEvents$.pipe(filterAs(isWebrtcMessageMetadata, "params"), (0, import_cjs$9.tap)((event) => logger$9.debug("[Call] Event is a WebRTC message event:", event)), (0, import_cjs$9.takeUntil)(this.destroyed$), (0, import_cjs$9.share)()));
15403
+ return this.cachedObservable("webrtcMessages$", () => this.callSessionEvents$.pipe(filterAs(isWebrtcMessageMetadata, "params"), (0, import_cjs$10.tap)((event) => logger$10.debug("[Call] Event is a WebRTC message event:", event)), (0, import_cjs$10.takeUntil)(this.destroyed$), (0, import_cjs$10.share)()));
15136
15404
  }
15137
15405
  /** Observable of call-level signaling events. */
15138
15406
  get callEvent$() {
15139
- return this.cachedObservable("callEvent$", () => this.callSessionEvents$.pipe(filterAs(isSignalwireCallMetadata, "params"), (0, import_cjs$9.tap)((event) => logger$9.debug("[Call] Event is a call event:", event)), (0, import_cjs$9.takeUntil)(this.destroyed$), (0, import_cjs$9.share)()));
15407
+ return this.cachedObservable("callEvent$", () => this.callSessionEvents$.pipe(filterAs(isSignalwireCallMetadata, "params"), (0, import_cjs$10.tap)((event) => logger$10.debug("[Call] Event is a call event:", event)), (0, import_cjs$10.takeUntil)(this.destroyed$), (0, import_cjs$10.share)()));
15140
15408
  }
15141
15409
  /** Observable of layout-changed signaling events. */
15142
15410
  get layoutEvent$() {
@@ -15227,7 +15495,7 @@ var WebRTCCall = class extends Destroyable {
15227
15495
  */
15228
15496
  async setLayout(layout, positions) {
15229
15497
  if (!this.layouts.includes(layout)) throw new InvalidParams(`Layout ${layout} is not available in the current call layouts: ${this.layouts.join(", ")}`);
15230
- const selfId = await (0, import_cjs$9.firstValueFrom)(this.selfId$.pipe((0, import_cjs$9.filter)((id) => id !== null)));
15498
+ const selfId = await (0, import_cjs$10.firstValueFrom)(this.selfId$.pipe((0, import_cjs$10.filter)((id) => id !== null)));
15231
15499
  await this.executeMethod(selfId, "call.layout.set", {
15232
15500
  layout,
15233
15501
  positions
@@ -15311,8 +15579,8 @@ var CallFactory = class {
15311
15579
 
15312
15580
  //#endregion
15313
15581
  //#region src/behaviors/Collection.ts
15314
- var import_cjs$8 = require_cjs();
15315
- const logger$8 = getLogger();
15582
+ var import_cjs$9 = require_cjs();
15583
+ const logger$9 = getLogger();
15316
15584
  var Fetcher = class {
15317
15585
  constructor(endpoint, params, http) {
15318
15586
  this.endpoint = endpoint;
@@ -15336,7 +15604,7 @@ var Fetcher = class {
15336
15604
  this.hasMore = !!this.nextUrl;
15337
15605
  return result.data.filter(this.filter).map(this.mapper);
15338
15606
  }
15339
- logger$8.error("Failed to fetch entity");
15607
+ logger$9.error("Failed to fetch entity");
15340
15608
  return [];
15341
15609
  }
15342
15610
  async id(v) {
@@ -15368,10 +15636,10 @@ var EntityCollection = class extends Destroyable {
15368
15636
  this.values$.next(Array.from(this.collectionData.values()));
15369
15637
  };
15370
15638
  this._hasMore$ = this.createBehaviorSubject(true);
15371
- this._destroy$ = new import_cjs$8.Subject();
15639
+ this._destroy$ = new import_cjs$9.Subject();
15372
15640
  this.updateSubscription = this.update$.subscribe(this.upsertData);
15373
15641
  this.loading$.next(false);
15374
- this.hasMore$ = (0, import_cjs$8.defer)(() => (0, import_cjs$8.from)(this.init())).pipe((0, import_cjs$8.switchMap)(() => this._hasMore$), (0, import_cjs$8.distinctUntilChanged)(), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.takeUntil)(this._destroy$));
15642
+ this.hasMore$ = (0, import_cjs$9.defer)(() => (0, import_cjs$9.from)(this.init())).pipe((0, import_cjs$9.switchMap)(() => this._hasMore$), (0, import_cjs$9.distinctUntilChanged)(), (0, import_cjs$9.shareReplay)(1), (0, import_cjs$9.takeUntil)(this._destroy$));
15375
15643
  }
15376
15644
  get loading() {
15377
15645
  return this.loading$.value;
@@ -15380,7 +15648,7 @@ var EntityCollection = class extends Destroyable {
15380
15648
  return this.fetchController.hasMore ?? true;
15381
15649
  }
15382
15650
  get updated$() {
15383
- return this.cachedObservable("updated$", () => this.loading$.pipe((0, import_cjs$8.distinctUntilChanged)(), (0, import_cjs$8.skip)(1), (0, import_cjs$8.filter)((loading) => !loading), (0, import_cjs$8.map)(() => void 0), (0, import_cjs$8.takeUntil)(this._destroy$)));
15651
+ return this.cachedObservable("updated$", () => this.loading$.pipe((0, import_cjs$9.distinctUntilChanged)(), (0, import_cjs$9.skip)(1), (0, import_cjs$9.filter)((loading) => !loading), (0, import_cjs$9.map)(() => void 0), (0, import_cjs$9.takeUntil)(this._destroy$)));
15384
15652
  }
15385
15653
  get values() {
15386
15654
  return Array.from(this.collectionData.values());
@@ -15399,7 +15667,7 @@ var EntityCollection = class extends Destroyable {
15399
15667
  this._hasMore$.next(this.fetchController.hasMore ?? false);
15400
15668
  this.loading$.next(false);
15401
15669
  } catch (error) {
15402
- logger$8.error(`Failed to fetch initial collection data`, error);
15670
+ logger$9.error(`Failed to fetch initial collection data`, error);
15403
15671
  this._hasMore$.next(this.fetchController.hasMore ?? false);
15404
15672
  this.loading$.next(false);
15405
15673
  this.onError?.(new CollectionFetchError("fetchMore", error));
@@ -15413,14 +15681,14 @@ var EntityCollection = class extends Destroyable {
15413
15681
  if (data) this.upsertData(data);
15414
15682
  return data;
15415
15683
  } catch (error) {
15416
- logger$8.error(`Failed to fetch data for (${String(key)}:${String(value)}) :`, error);
15684
+ logger$9.error(`Failed to fetch data for (${String(key)}:${String(value)}) :`, error);
15417
15685
  this.loading$.next(false);
15418
15686
  this.onError?.(new CollectionFetchError(`tryFetch(${String(key)})`, error));
15419
15687
  }
15420
15688
  }
15421
15689
  get$(id) {
15422
15690
  if (!this.observablesRegistry.has(id)) {
15423
- this.observablesRegistry.set(id, new import_cjs$8.ReplaySubject(1));
15691
+ this.observablesRegistry.set(id, new import_cjs$9.ReplaySubject(1));
15424
15692
  const data = this.collectionData.get(id);
15425
15693
  if (data) this.observablesRegistry.get(id)?.next(data);
15426
15694
  else this.tryFetch("id", id);
@@ -15443,9 +15711,9 @@ var EntityCollection = class extends Destroyable {
15443
15711
  }
15444
15712
  };
15445
15713
  var EntityCollectionTransformed = class {
15446
- constructor(originalCollection, filter$13 = (i) => !!i, mapper = (item) => item) {
15714
+ constructor(originalCollection, filter$14 = (i) => !!i, mapper = (item) => item) {
15447
15715
  this.originalCollection = originalCollection;
15448
- this.filter = filter$13;
15716
+ this.filter = filter$14;
15449
15717
  this.mapper = mapper;
15450
15718
  }
15451
15719
  get loading$() {
@@ -15464,15 +15732,15 @@ var EntityCollectionTransformed = class {
15464
15732
  return this.originalCollection.values.filter(this.filter).map(this.mapper);
15465
15733
  }
15466
15734
  get values$() {
15467
- return this._values$ ??= this.originalCollection.values$.pipe((0, import_cjs$8.map)((values) => values.filter(this.filter).map(this.mapper)));
15735
+ return this._values$ ??= this.originalCollection.values$.pipe((0, import_cjs$9.map)((values) => values.filter(this.filter).map(this.mapper)));
15468
15736
  }
15469
15737
  get$(id) {
15470
15738
  const original$ = this.originalCollection.get$(id);
15471
- return !original$ ? original$ : original$.pipe((0, import_cjs$8.pipe)((0, import_cjs$8.filter)(this.filter), (0, import_cjs$8.map)(this.mapper)));
15739
+ return !original$ ? original$ : original$.pipe((0, import_cjs$9.pipe)((0, import_cjs$9.filter)(this.filter), (0, import_cjs$9.map)(this.mapper)));
15472
15740
  }
15473
15741
  async find$(key, value) {
15474
15742
  const original$ = await this.originalCollection.find$(key, value);
15475
- return !original$ ? original$ : original$.pipe((0, import_cjs$8.pipe)((0, import_cjs$8.filter)(this.filter), (0, import_cjs$8.map)(this.mapper)));
15743
+ return !original$ ? original$ : original$.pipe((0, import_cjs$9.pipe)((0, import_cjs$9.filter)(this.filter), (0, import_cjs$9.map)(this.mapper)));
15476
15744
  }
15477
15745
  loadMore() {
15478
15746
  this.originalCollection.loadMore();
@@ -15484,7 +15752,7 @@ var EntityCollectionTransformed = class {
15484
15752
 
15485
15753
  //#endregion
15486
15754
  //#region src/core/entities/Address.ts
15487
- var import_cjs$7 = require_cjs();
15755
+ var import_cjs$8 = require_cjs();
15488
15756
  /**
15489
15757
  * Represents a contact or room in the directory.
15490
15758
  *
@@ -15502,8 +15770,8 @@ var Address = class extends Destroyable {
15502
15770
  if (this._conversationMessages.hasMore) this._conversationMessages.loadMore();
15503
15771
  return this._conversationMessages;
15504
15772
  };
15505
- this.textMessages$ = (0, import_cjs$7.defer)(this.initConversationMessages).pipe((0, import_cjs$7.map)(() => this.textMessage), (0, import_cjs$7.shareReplay)(1), (0, import_cjs$7.takeUntil)(this.destroyed$));
15506
- this.history$ = (0, import_cjs$7.defer)(this.initConversationMessages).pipe((0, import_cjs$7.map)(() => this.history), (0, import_cjs$7.shareReplay)(1), (0, import_cjs$7.takeUntil)(this.destroyed$));
15773
+ this.textMessages$ = (0, import_cjs$8.defer)(this.initConversationMessages).pipe((0, import_cjs$8.map)(() => this.textMessage), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.takeUntil)(this.destroyed$));
15774
+ this.history$ = (0, import_cjs$8.defer)(this.initConversationMessages).pipe((0, import_cjs$8.map)(() => this.history), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.takeUntil)(this.destroyed$));
15507
15775
  this._state$ = this.createBehaviorSubject(null);
15508
15776
  }
15509
15777
  /** @internal */
@@ -15538,7 +15806,7 @@ var Address = class extends Destroyable {
15538
15806
  }
15539
15807
  /** Observable of the human-readable display name. */
15540
15808
  get displayName$() {
15541
- return this.cachedObservable("displayName$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.map)((state) => state.display_name), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15809
+ return this.cachedObservable("displayName$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.map)((state) => state.display_name), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15542
15810
  }
15543
15811
  /** Human-readable display name. */
15544
15812
  get displayName() {
@@ -15547,7 +15815,7 @@ var Address = class extends Destroyable {
15547
15815
  }
15548
15816
  /** Observable of the preview image URL. */
15549
15817
  get previewUrl$() {
15550
- return this.cachedObservable("previewUrl$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.map)((state) => state.preview_url), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15818
+ return this.cachedObservable("previewUrl$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.map)((state) => state.preview_url), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15551
15819
  }
15552
15820
  /** Preview image URL. */
15553
15821
  get previewUrl() {
@@ -15556,7 +15824,7 @@ var Address = class extends Destroyable {
15556
15824
  }
15557
15825
  /** Observable of the cover image URL. */
15558
15826
  get coverUrl$() {
15559
- return this.cachedObservable("coverUrl$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.shareReplay)(1), (0, import_cjs$7.map)((state) => state.cover_url), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15827
+ return this.cachedObservable("coverUrl$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.map)((state) => state.cover_url), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15560
15828
  }
15561
15829
  /** Cover image URL. */
15562
15830
  get coverUrl() {
@@ -15565,7 +15833,7 @@ var Address = class extends Destroyable {
15565
15833
  }
15566
15834
  /** Observable of the underlying resource ID. */
15567
15835
  get resourceId$() {
15568
- return this.cachedObservable("resourceId$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.shareReplay)(1), (0, import_cjs$7.map)((state) => state.resource_id), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15836
+ return this.cachedObservable("resourceId$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.map)((state) => state.resource_id), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15569
15837
  }
15570
15838
  /** Underlying resource ID. */
15571
15839
  get resourceId() {
@@ -15574,7 +15842,7 @@ var Address = class extends Destroyable {
15574
15842
  }
15575
15843
  /** Observable of the resource type (e.g. `'room'`, `'subscriber'`). */
15576
15844
  get type$() {
15577
- return this.cachedObservable("type$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.shareReplay)(1), (0, import_cjs$7.map)((state) => state.type), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15845
+ return this.cachedObservable("type$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.map)((state) => state.type), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15578
15846
  }
15579
15847
  /** Resource type (e.g. `'room'`, `'subscriber'`). */
15580
15848
  get type() {
@@ -15583,7 +15851,7 @@ var Address = class extends Destroyable {
15583
15851
  }
15584
15852
  /** Observable of available communication channels (audio, video, messaging). */
15585
15853
  get channels$() {
15586
- return this.cachedObservable("channels$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.shareReplay)(1), (0, import_cjs$7.map)((state) => state.channels), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15854
+ return this.cachedObservable("channels$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.map)((state) => state.channels), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15587
15855
  }
15588
15856
  /** Available communication channels. */
15589
15857
  get channels() {
@@ -15597,7 +15865,7 @@ var Address = class extends Destroyable {
15597
15865
  }
15598
15866
  /** Observable indicating whether the address (room) is locked. */
15599
15867
  get locked$() {
15600
- return this.cachedObservable("locked$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.shareReplay)(1), (0, import_cjs$7.map)((state) => state.locked), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15868
+ return this.cachedObservable("locked$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.shareReplay)(1), (0, import_cjs$8.map)((state) => state.locked), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15601
15869
  }
15602
15870
  /**
15603
15871
  * Sends a text message to this address.
@@ -15663,14 +15931,14 @@ var Address = class extends Destroyable {
15663
15931
 
15664
15932
  //#endregion
15665
15933
  //#region src/core/utils.ts
15666
- var import_cjs$6 = require_cjs();
15667
- const logger$7 = getLogger();
15934
+ var import_cjs$7 = require_cjs();
15935
+ const logger$8 = getLogger();
15668
15936
  const isRPCConnectResult = (e) => {
15669
- logger$7.debug("isRPCConnectResult check:", e);
15937
+ logger$8.debug("isRPCConnectResult check:", e);
15670
15938
  if (!e || typeof e !== "object") return false;
15671
15939
  const result = e;
15672
15940
  const is = typeof result.identity === "string" && typeof result.protocol === "string" && typeof result.authorization === "object" && typeof result.authorization.jti === "string" && typeof result.authorization.project_id === "string" && typeof result.authorization.fabric_subscriber === "object";
15673
- logger$7.debug("isRPCConnectResult check result:", is);
15941
+ logger$8.debug("isRPCConnectResult check result:", is);
15674
15942
  return is;
15675
15943
  };
15676
15944
  var PendingRPC = class PendingRPC {
@@ -15679,7 +15947,7 @@ var PendingRPC = class PendingRPC {
15679
15947
  }
15680
15948
  constructor(request, responses$, options) {
15681
15949
  this.id = v4_default();
15682
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}: method:${request.method}] Creating PendingRPC`);
15950
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}: method:${request.method}] Creating PendingRPC`);
15683
15951
  this.request = request;
15684
15952
  const timeoutMs = options?.timeoutMs ?? PendingRPC.defaultTimeoutMs;
15685
15953
  const signal = options?.signal;
@@ -15689,38 +15957,38 @@ var PendingRPC = class PendingRPC {
15689
15957
  return;
15690
15958
  }
15691
15959
  let isSettled = false;
15692
- const subscription = (0, import_cjs$6.race)(responses$.pipe((0, import_cjs$6.filter)((result) => result.id === request.id), (0, import_cjs$6.take)(1)), new import_cjs$6.Observable((subscriber) => {
15693
- const timer$1 = setTimeout(() => {
15960
+ const subscription = (0, import_cjs$7.race)(responses$.pipe((0, import_cjs$7.filter)((result) => result.id === request.id), (0, import_cjs$7.take)(1)), new import_cjs$7.Observable((subscriber) => {
15961
+ const timer$2 = setTimeout(() => {
15694
15962
  subscriber.error(new RPCTimeoutError(request.id, timeoutMs));
15695
15963
  }, timeoutMs);
15696
- return () => clearTimeout(timer$1);
15697
- }), signal ? new import_cjs$6.Observable((subscriber) => {
15964
+ return () => clearTimeout(timer$2);
15965
+ }), signal ? new import_cjs$7.Observable((subscriber) => {
15698
15966
  const abortHandler = () => {
15699
15967
  subscriber.error(new DOMException("The operation was aborted", "AbortError"));
15700
15968
  };
15701
15969
  signal.addEventListener("abort", abortHandler);
15702
15970
  return () => signal.removeEventListener("abort", abortHandler);
15703
- }) : import_cjs$6.NEVER).subscribe({
15971
+ }) : import_cjs$7.NEVER).subscribe({
15704
15972
  next: (response) => {
15705
15973
  isSettled = true;
15706
15974
  if (response.error) {
15707
15975
  const rpcError = new JSONRPCError(response.error.code, response.error.message, response.error.data, void 0, request.id);
15708
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with RPC error:`, rpcError);
15976
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with RPC error:`, rpcError);
15709
15977
  reject(rpcError);
15710
15978
  } else {
15711
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Resolving promise with response:`, response);
15979
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Resolving promise with response:`, response);
15712
15980
  resolve(response);
15713
15981
  }
15714
15982
  subscription.unsubscribe();
15715
15983
  },
15716
15984
  error: (error) => {
15717
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with error:`, error);
15985
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with error:`, error);
15718
15986
  isSettled = true;
15719
15987
  reject(error);
15720
15988
  subscription.unsubscribe();
15721
15989
  },
15722
15990
  complete: () => {
15723
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Observable completed`);
15991
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Observable completed`);
15724
15992
  if (!isSettled) reject(new RPCTimeoutError(request.id, timeoutMs));
15725
15993
  subscription.unsubscribe();
15726
15994
  }
@@ -15740,8 +16008,8 @@ var PendingRPC = class PendingRPC {
15740
16008
 
15741
16009
  //#endregion
15742
16010
  //#region src/managers/ClientSessionManager.ts
15743
- var import_cjs$5 = require_cjs();
15744
- const logger$6 = getLogger();
16011
+ var import_cjs$6 = require_cjs();
16012
+ const logger$7 = getLogger();
15745
16013
  const getAddressSearchURI = (options) => {
15746
16014
  const to = options.to?.split("?")[0];
15747
16015
  const from$7 = options.from?.startsWith("subscriber://") ? options.from.replace("subscriber://", "") : options.from;
@@ -15750,13 +16018,14 @@ const getAddressSearchURI = (options) => {
15750
16018
  return name;
15751
16019
  };
15752
16020
  var ClientSessionManager = class extends Destroyable {
15753
- constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider) {
16021
+ constructor(getCredential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider, dpopManager) {
15754
16022
  super();
15755
- this.credential = credential;
16023
+ this.getCredential = getCredential;
15756
16024
  this.transport = transport;
15757
16025
  this.storage = storage;
15758
16026
  this.authorizationStateKey = authorizationStateKey;
15759
16027
  this.attachManager = attachManager;
16028
+ this.dpopManager = dpopManager;
15760
16029
  this.callCreateTimeout = 6e3;
15761
16030
  this.agent = `signalwire-typescript-sdk/1.0.0`;
15762
16031
  this.eventAcks = true;
@@ -15769,15 +16038,16 @@ var ClientSessionManager = class extends Destroyable {
15769
16038
  this._authorization$ = this.createBehaviorSubject(void 0);
15770
16039
  this._errors$ = this.createReplaySubject(1);
15771
16040
  this._authenticated$ = this.createBehaviorSubject(false);
16041
+ this._clientBound = false;
15772
16042
  this._subscriberInfo$ = this.createBehaviorSubject(null);
15773
16043
  this._calls$ = this.createBehaviorSubject({});
15774
16044
  this._iceServers$ = this.createBehaviorSubject([]);
15775
16045
  attachManager.setSession(this);
15776
16046
  this.callFactory = new CallFactory(this, deviceController, attachManager, webRTCApiProvider);
15777
- this.initialized$ = (0, import_cjs$5.defer)(() => (0, import_cjs$5.from)(this.init())).pipe((0, import_cjs$5.shareReplay)(1), (0, import_cjs$5.takeUntil)(this.destroyed$));
16047
+ this.initialized$ = (0, import_cjs$6.defer)(() => (0, import_cjs$6.from)(this.init())).pipe((0, import_cjs$6.shareReplay)(1), (0, import_cjs$6.takeUntil)(this.destroyed$));
15778
16048
  }
15779
16049
  get incomingCalls$() {
15780
- return this.cachedObservable("incomingCalls$", () => this.calls$.pipe((0, import_cjs$5.map)((calls) => calls.filter((call) => call.direction === "inbound"))));
16050
+ return this.cachedObservable("incomingCalls$", () => this.calls$.pipe((0, import_cjs$6.map)((calls) => calls.filter((call) => call.direction === "inbound"))));
15781
16051
  }
15782
16052
  get incomingCalls() {
15783
16053
  return Object.values(this._calls$.value).filter((call) => call.direction === "inbound");
@@ -15789,7 +16059,7 @@ var ClientSessionManager = class extends Destroyable {
15789
16059
  return this._subscriberInfo$.value;
15790
16060
  }
15791
16061
  get calls$() {
15792
- return this.cachedObservable("calls$", () => this._calls$.pipe((0, import_cjs$5.map)((calls) => Object.values(calls))));
16062
+ return this.cachedObservable("calls$", () => this._calls$.pipe((0, import_cjs$6.map)((calls) => Object.values(calls))));
15793
16063
  }
15794
16064
  get calls() {
15795
16065
  return Object.values(this._calls$.value);
@@ -15813,6 +16083,15 @@ var ClientSessionManager = class extends Destroyable {
15813
16083
  return this._authenticated$.value;
15814
16084
  }
15815
16085
  /**
16086
+ * Whether this session is client-bound (using a Client Bound SAT).
16087
+ * When client-bound, DPoP proof creation failures are treated as
16088
+ * authentication errors rather than silently degraded.
16089
+ * @internal
16090
+ */
16091
+ get clientBound() {
16092
+ return this._clientBound;
16093
+ }
16094
+ /**
15816
16095
  * Set the directory instance
15817
16096
  * Called by SignalWire after directory is created
15818
16097
  * @internal
@@ -15824,7 +16103,7 @@ var ClientSessionManager = class extends Destroyable {
15824
16103
  try {
15825
16104
  return await this.transport.execute(request, options);
15826
16105
  } catch (error) {
15827
- logger$6.debug("[Session] Execute Error", error);
16106
+ logger$7.debug("[Session] Execute Error", error);
15828
16107
  this._errors$.next(error instanceof Error ? error : new Error(String(error), { cause: error }));
15829
16108
  throw error;
15830
16109
  }
@@ -15838,32 +16117,31 @@ var ClientSessionManager = class extends Destroyable {
15838
16117
  return true;
15839
16118
  }
15840
16119
  setupMessageHandlers() {
15841
- logger$6.debug("[Session] Setting up message handlers");
16120
+ logger$7.debug("[Session] Setting up message handlers");
15842
16121
  this.subscribeTo(this.authStateEvent$, async (authStateEvent) => {
15843
- logger$6.debug("[Session] Authorization state event received:", authStateEvent);
16122
+ logger$7.debug("[Session] Authorization state event received:", authStateEvent);
15844
16123
  try {
15845
16124
  await this.updateAuthorizationStateInStorage(authStateEvent.authorization_state);
15846
16125
  } catch (error) {
15847
- logger$6.error("[Session] Failed to handle authorization state update:", error);
16126
+ logger$7.error("[Session] Failed to handle authorization state update:", error);
15848
16127
  this._errors$.next(new AuthStateHandlerError(error));
15849
16128
  }
15850
16129
  });
15851
- this.subscribeTo(this.transport.connectionStatus$.pipe((0, import_cjs$5.filter)((status) => status === "connected")), async () => {
15852
- try {
15853
- logger$6.debug("[Session] Connection established, initiating authentication");
15854
- await this.authenticate();
15855
- } catch (error) {
16130
+ this.subscribeTo(this.transport.connectionStatus$.pipe((0, import_cjs$6.filter)((status) => status === "connected"), (0, import_cjs$6.exhaustMap)(() => {
16131
+ logger$7.debug("[Session] Connection established, initiating authentication");
16132
+ return (0, import_cjs$6.from)(this.authenticate()).pipe((0, import_cjs$6.catchError)((error) => {
15856
16133
  this.handleAuthenticationError(error).catch((err) => {
15857
- logger$6.error("[Session] Error handling authentication failure:", err);
16134
+ logger$7.error("[Session] Error handling authentication failure:", err);
15858
16135
  });
15859
- }
15860
- });
16136
+ return import_cjs$6.EMPTY;
16137
+ }));
16138
+ })), void 0);
15861
16139
  this.subscribeTo(this.vertoInvite$, async (invite) => {
15862
- logger$6.debug("[Session] Verto invite received:", invite);
16140
+ logger$7.debug("[Session] Verto invite received:", invite);
15863
16141
  try {
15864
16142
  await this.createInboundCall(invite);
15865
16143
  } catch (error) {
15866
- logger$6.error("[Session] Error handling Verto invite:", error);
16144
+ logger$7.error("[Session] Error handling Verto invite:", error);
15867
16145
  this._errors$.next(new VertoInviteHandlerError(error));
15868
16146
  }
15869
16147
  });
@@ -15873,42 +16151,42 @@ var ClientSessionManager = class extends Destroyable {
15873
16151
  const storedState = await this.storage.getItem(this.authorizationStateKey);
15874
16152
  this.authorizationState$.next(storedState ?? void 0);
15875
16153
  } catch (error) {
15876
- logger$6.error("Failed to retrieve authorization state from storage:", error);
16154
+ logger$7.error("Failed to retrieve authorization state from storage:", error);
15877
16155
  this.authorizationState$.next(void 0);
15878
16156
  }
15879
16157
  }
15880
16158
  async updateAuthorizationStateInStorage(authorizationState) {
15881
16159
  if (!authorizationState) {
15882
- logger$6.debug("[Session] Removing authorization state from storage");
16160
+ logger$7.debug("[Session] Removing authorization state from storage");
15883
16161
  try {
15884
16162
  await this.storage.removeItem(this.authorizationStateKey);
15885
16163
  } catch (error) {
15886
- logger$6.error("Failed to remove authorization state from storage:", error);
16164
+ logger$7.error("Failed to remove authorization state from storage:", error);
15887
16165
  throw error;
15888
16166
  }
15889
16167
  return;
15890
16168
  }
15891
16169
  try {
15892
- logger$6.debug("[Session] Updating authorization state in storage");
16170
+ logger$7.debug("[Session] Updating authorization state in storage");
15893
16171
  await this.storage.setItem(this.authorizationStateKey, authorizationState);
15894
16172
  this.authorizationState$.next(authorizationState);
15895
16173
  } catch (error) {
15896
- logger$6.error("Failed to retrieve authorization state from storage:", error);
16174
+ logger$7.error("Failed to retrieve authorization state from storage:", error);
15897
16175
  throw error;
15898
16176
  }
15899
16177
  }
15900
16178
  get authStateEvent$() {
15901
- return this.cachedObservable("authStateEvent$", () => this.signalingEvent$.pipe((0, import_cjs$5.tap)((msg) => {
15902
- logger$6.debug("[Session] Received incoming message:", msg);
15903
- }), filterAs(isSignalwireAuthorizationStateMetadata, "params"), (0, import_cjs$5.tap)((event) => {
15904
- logger$6.debug("[Session] Authorization state event received:", event.authorization_state);
16179
+ return this.cachedObservable("authStateEvent$", () => this.signalingEvent$.pipe((0, import_cjs$6.tap)((msg) => {
16180
+ logger$7.debug("[Session] Received incoming message:", msg);
16181
+ }), filterAs(isSignalwireAuthorizationStateMetadata, "params"), (0, import_cjs$6.tap)((event) => {
16182
+ logger$7.debug("[Session] Authorization state event received:", event.authorization_state);
15905
16183
  })));
15906
16184
  }
15907
16185
  get signalingEvent$() {
15908
- return this.cachedObservable("signalingEvent$", () => this.transport.incomingEvent$.pipe(filterAs(isSignalwireRequest, "params"), (0, import_cjs$5.share)()));
16186
+ return this.cachedObservable("signalingEvent$", () => this.transport.incomingEvent$.pipe(filterAs(isSignalwireRequest, "params"), (0, import_cjs$6.share)()));
15909
16187
  }
15910
16188
  get vertoInvite$() {
15911
- return this.cachedObservable("vertoInvite$", () => this.signalingEvent$.pipe((0, import_cjs$5.filter)(isWebrtcMessageMetadata), (0, import_cjs$5.filter)((event) => isVertoInviteMessage(event.params)), (0, import_cjs$5.map)((event) => ({
16189
+ return this.cachedObservable("vertoInvite$", () => this.signalingEvent$.pipe((0, import_cjs$6.filter)(isWebrtcMessageMetadata), (0, import_cjs$6.filter)((event) => isVertoInviteMessage(event.params)), (0, import_cjs$6.map)((event) => ({
15912
16190
  node_id: event.node_id,
15913
16191
  ...event.params.params
15914
16192
  }))));
@@ -15923,86 +16201,118 @@ var ClientSessionManager = class extends Destroyable {
15923
16201
  return [];
15924
16202
  }
15925
16203
  get authentication() {
15926
- if (!this.credential.token) throw new DependencyError("Credential token is undefined");
15927
- return { jwt_token: this.credential.token };
16204
+ const credential = this.getCredential();
16205
+ if (!credential.token) throw new DependencyError("Credential token is undefined");
16206
+ return { jwt_token: credential.token };
15928
16207
  }
15929
16208
  async connect() {
15930
- await (0, import_cjs$5.firstValueFrom)(this.initialized$);
16209
+ await (0, import_cjs$6.firstValueFrom)(this.initialized$);
15931
16210
  await this.transport.connect();
15932
16211
  }
15933
16212
  async handleAuthenticationError(error) {
15934
- logger$6.error("Authentication error:", error);
16213
+ logger$7.error("Authentication error:", error);
15935
16214
  this._errors$.next(error);
15936
- if (error.message === "Requester validation failed") try {
15937
- await this.cleanupStoredConnectionParams();
15938
- } catch (error$1) {
15939
- logger$6.error("Failed to cleanup stored connection params:", error$1);
15940
- } finally {
15941
- this.transport.reconnect();
16215
+ const isRecoverableAuthError = error instanceof JSONRPCError && (error.code === RPC_ERROR_REQUESTER_VALIDATION_FAILED || error.code === RPC_ERROR_INVALID_PARAMS || error.code === RPC_ERROR_AUTHENTICATION_FAILED);
16216
+ const hasStoredState = this._authorization$.value !== void 0;
16217
+ if (isRecoverableAuthError && hasStoredState) {
16218
+ logger$7.debug("[Session] Recoverable auth error — cleaning up stored state and reconnecting fresh");
16219
+ try {
16220
+ await this.cleanupStoredConnectionParams();
16221
+ } catch (cleanupError) {
16222
+ logger$7.error("Failed to cleanup stored connection params:", cleanupError);
16223
+ } finally {
16224
+ this.transport.reconnect();
16225
+ }
15942
16226
  }
15943
16227
  }
15944
16228
  async cleanupStoredConnectionParams() {
15945
16229
  await this.transport.setProtocol(void 0);
15946
16230
  await this.updateAuthorizationStateInStorage(void 0);
16231
+ this._authorization$.next(void 0);
15947
16232
  await this.attachManager.detachAll();
15948
16233
  }
15949
16234
  async updateAuthState(authorization_state) {
15950
16235
  try {
15951
16236
  await this.storage.setItem(this.authorizationStateKey, authorization_state);
15952
16237
  } catch (error) {
15953
- logger$6.error("Failed to update authorization state in storage:", error);
16238
+ logger$7.error("Failed to update authorization state in storage:", error);
15954
16239
  this._errors$.next(new AuthStateHandlerError(error));
15955
16240
  }
15956
16241
  }
15957
- async reauthenticate(token) {
15958
- logger$6.debug("[Session] Re-authenticating session");
16242
+ async reauthenticate(token, dpopToken, options) {
16243
+ logger$7.debug("[Session] Re-authenticating session");
15959
16244
  try {
16245
+ let resolvedDpopToken = dpopToken;
16246
+ if (!resolvedDpopToken && this.dpopManager?.initialized) try {
16247
+ resolvedDpopToken = await this.dpopManager.createRpcProof({ method: "signalwire.reauthenticate" });
16248
+ } catch (error) {
16249
+ if (this._clientBound) throw error;
16250
+ logger$7.warn("[Session] Failed to create DPoP proof for reauthenticate:", error);
16251
+ }
15960
16252
  const request = RPCReauthenticate({
15961
16253
  project: this._authorization$.value?.project_id ?? "",
15962
- jwt_token: token
16254
+ jwt_token: token,
16255
+ ...resolvedDpopToken ? { dpop_token: resolvedDpopToken } : {}
15963
16256
  });
15964
- await (0, import_cjs$5.lastValueFrom)((0, import_cjs$5.from)(this.transport.execute(request)).pipe(throwOnRPCError(), (0, import_cjs$5.take)(1), (0, import_cjs$5.catchError)((err) => {
15965
- logger$6.error("[Session] Re-authentication RPC failed:", err);
16257
+ await (0, import_cjs$6.lastValueFrom)((0, import_cjs$6.from)(this.transport.execute(request)).pipe(throwOnRPCError(), (0, import_cjs$6.take)(1), (0, import_cjs$6.catchError)((err) => {
16258
+ logger$7.error("[Session] Re-authentication RPC failed:", err);
15966
16259
  throw err;
15967
16260
  })));
15968
- logger$6.debug("[Session] Re-authentication successful, updating stored auth state");
16261
+ if (options?.clientBound) this._clientBound = true;
16262
+ logger$7.debug("[Session] Re-authentication successful, updating stored auth state");
15969
16263
  } catch (error) {
15970
- logger$6.error("[Session] Re-authentication failed:", error);
16264
+ logger$7.error("[Session] Re-authentication failed:", error);
15971
16265
  this._errors$.next(new AuthStateHandlerError(error));
15972
16266
  throw error;
15973
16267
  }
15974
16268
  }
15975
16269
  async authenticate() {
15976
- logger$6.debug("[Session] Starting authentication process");
15977
- const params = {
15978
- authentication: this.authentication,
15979
- version: this.connectVersion,
15980
- agent: this.agent,
15981
- contexts: this.contexts,
15982
- eventing: this.eventing,
15983
- topics: this.topics,
15984
- event_acks: this.eventAcks
15985
- };
15986
- const persistedParams = await (0, import_cjs$5.firstValueFrom)((0, import_cjs$5.combineLatest)({
16270
+ logger$7.debug("[Session] Starting authentication process");
16271
+ const persistedParams = await (0, import_cjs$6.firstValueFrom)((0, import_cjs$6.combineLatest)({
15987
16272
  protocol: this.transport.protocol$,
15988
16273
  authorization_state: this.authorizationState$
15989
- }).pipe((0, import_cjs$5.take)(1)));
15990
- logger$6.debug("[Session] Persisted params:\n", {
16274
+ }).pipe((0, import_cjs$6.take)(1)));
16275
+ logger$7.debug("[Session] Persisted params:\n", {
15991
16276
  protocol: persistedParams.protocol,
15992
16277
  authStateLength: persistedParams.authorization_state?.length
15993
16278
  });
16279
+ this.transport.resetSessionEpoch();
16280
+ const hasReconnectState = persistedParams.authorization_state && persistedParams.protocol;
16281
+ const storedToken = this.getCredential().token;
16282
+ const isReconnect = hasReconnectState && storedToken;
16283
+ let dpopToken;
16284
+ if (isReconnect) logger$7.debug("[Session] Reconnecting with stored jwt_token + authorization_state");
16285
+ else if (this.onBeforeReconnect && this._clientBound) {
16286
+ logger$7.debug("[Session] Refreshing credentials before fresh connect");
16287
+ await this.onBeforeReconnect();
16288
+ }
16289
+ if (this.dpopManager?.initialized) try {
16290
+ dpopToken = await this.dpopManager.createRpcProof({ method: "signalwire.connect" });
16291
+ } catch (error) {
16292
+ if (this._clientBound) throw error;
16293
+ logger$7.warn("[Session] Failed to create DPoP proof for connect, proceeding without:", error);
16294
+ }
15994
16295
  const rpcConnectRequest = RPCConnect({
15995
- ...params,
15996
- ...persistedParams
16296
+ authentication: isReconnect ? { jwt_token: storedToken } : this.authentication,
16297
+ version: this.connectVersion,
16298
+ agent: this.agent,
16299
+ contexts: this.contexts,
16300
+ eventing: this.eventing,
16301
+ topics: this.topics,
16302
+ event_acks: this.eventAcks,
16303
+ ...dpopToken ? { dpop_token: dpopToken } : {},
16304
+ ...isReconnect ? {
16305
+ authorization_state: persistedParams.authorization_state,
16306
+ protocol: persistedParams.protocol
16307
+ } : {}
15997
16308
  });
15998
- this.transport.resetSessionEpoch();
15999
- const response = await (0, import_cjs$5.lastValueFrom)((0, import_cjs$5.from)(this.transport.execute(rpcConnectRequest)).pipe(throwOnRPCError(), (0, import_cjs$5.map)((res) => res.result), (0, import_cjs$5.filter)(isRPCConnectResult), (0, import_cjs$5.tap)(() => {
16000
- logger$6.debug("[Session] Response passed filter, processing authentication result");
16001
- }), (0, import_cjs$5.take)(1), (0, import_cjs$5.catchError)((err) => {
16002
- logger$6.error("[Session] Authentication RPC failed:", err);
16309
+ const response = await (0, import_cjs$6.lastValueFrom)((0, import_cjs$6.from)(this.transport.execute(rpcConnectRequest)).pipe(throwOnRPCError(), (0, import_cjs$6.map)((res) => res.result), (0, import_cjs$6.filter)(isRPCConnectResult), (0, import_cjs$6.tap)(() => {
16310
+ logger$7.debug("[Session] Response passed filter, processing authentication result");
16311
+ }), (0, import_cjs$6.take)(1), (0, import_cjs$6.catchError)((err) => {
16312
+ logger$7.error("[Session] Authentication RPC failed:", err);
16003
16313
  throw err;
16004
16314
  })));
16005
- logger$6.debug("[Session] Processing authentication result:", {
16315
+ logger$7.debug("[Session] Processing authentication result:", {
16006
16316
  hasProtocol: !!response.protocol,
16007
16317
  hasAuthorization: !!response.authorization,
16008
16318
  hasIceServers: !!response.ice_servers
@@ -16011,7 +16321,7 @@ var ClientSessionManager = class extends Destroyable {
16011
16321
  this._authorization$.next(response.authorization);
16012
16322
  this._iceServers$.next(response.ice_servers ?? []);
16013
16323
  this._authenticated$.next(true);
16014
- logger$6.debug("[Session] Authentication completed successfully");
16324
+ logger$7.debug("[Session] Authentication completed successfully");
16015
16325
  }
16016
16326
  async disconnect() {
16017
16327
  this.transport.disconnect();
@@ -16030,7 +16340,7 @@ var ClientSessionManager = class extends Destroyable {
16030
16340
  displayDirection: invite.display_direction,
16031
16341
  userVariables: invite.userVariables
16032
16342
  });
16033
- await (0, import_cjs$5.firstValueFrom)(callSession.status$);
16343
+ await (0, import_cjs$6.firstValueFrom)(callSession.status$);
16034
16344
  this._calls$.next({
16035
16345
  [`${callSession.id}`]: callSession,
16036
16346
  ...this._calls$.value
@@ -16044,16 +16354,16 @@ var ClientSessionManager = class extends Destroyable {
16044
16354
  to: destinationURI,
16045
16355
  ...options
16046
16356
  });
16047
- await (0, import_cjs$5.firstValueFrom)((0, import_cjs$5.race)(callSession.selfId$.pipe((0, import_cjs$5.filter)((id) => Boolean(id)), (0, import_cjs$5.take)(1), (0, import_cjs$5.timeout)(this.callCreateTimeout)), callSession.errors$.pipe((0, import_cjs$5.take)(1), (0, import_cjs$5.switchMap)((callError) => (0, import_cjs$5.throwError)(() => callError.error)))));
16357
+ await (0, import_cjs$6.firstValueFrom)((0, import_cjs$6.race)(callSession.selfId$.pipe((0, import_cjs$6.filter)((id) => Boolean(id)), (0, import_cjs$6.take)(1), (0, import_cjs$6.timeout)(this.callCreateTimeout)), callSession.errors$.pipe((0, import_cjs$6.take)(1), (0, import_cjs$6.switchMap)((callError) => (0, import_cjs$6.throwError)(() => callError.error)))));
16048
16358
  this._calls$.next({
16049
16359
  [`${callSession.id}`]: callSession,
16050
16360
  ...this._calls$.value
16051
16361
  });
16052
16362
  return callSession;
16053
16363
  } catch (error) {
16054
- logger$6.error("[Session] Error creating outbound call:", error);
16364
+ logger$7.error("[Session] Error creating outbound call:", error);
16055
16365
  callSession?.destroy();
16056
- const callError = new CallCreateError(error instanceof import_cjs$5.TimeoutError ? "Call create timeout" : "Call creation failed", error, "outbound");
16366
+ const callError = new CallCreateError(error instanceof import_cjs$6.TimeoutError ? "Call create timeout" : "Call creation failed", error, "outbound");
16057
16367
  this._errors$.next(callError);
16058
16368
  throw callError;
16059
16369
  }
@@ -16068,17 +16378,17 @@ var ClientSessionManager = class extends Destroyable {
16068
16378
  if (!addressId) throw new DependencyError(`Address name: ${addressURI} not found`);
16069
16379
  address = this._directory.get(addressId);
16070
16380
  if (!address) throw new DependencyError(`Address ID: ${addressId} not found`);
16071
- } catch (error) {
16072
- logger$6.warn(`[Session] Directory lookup failed for ${addressURI}, proceeding with raw URI`);
16381
+ } catch {
16382
+ logger$7.warn(`[Session] Directory lookup failed for ${addressURI}, proceeding with raw URI`);
16073
16383
  }
16074
16384
  const callSession = this.callFactory.createCall(address, { ...options });
16075
- callSession.status$.pipe((0, import_cjs$5.filter)((status) => status === "destroyed"), (0, import_cjs$5.take)(1)).subscribe(() => {
16385
+ callSession.status$.pipe((0, import_cjs$6.filter)((status) => status === "destroyed"), (0, import_cjs$6.take)(1)).subscribe(() => {
16076
16386
  const { [`${callSession.id}`]: _, ...remainingCalls } = this._calls$.value;
16077
16387
  this._calls$.next(remainingCalls);
16078
16388
  });
16079
16389
  return callSession;
16080
16390
  } catch (error) {
16081
- logger$6.error("[Session] Error creating call session:", error);
16391
+ logger$7.error("[Session] Error creating call session:", error);
16082
16392
  throw new CallCreateError("Call create error", error, options.initOffer ? "inbound" : "outbound");
16083
16393
  }
16084
16394
  }
@@ -16126,8 +16436,8 @@ const isString = (obj) => typeof obj === "string";
16126
16436
 
16127
16437
  //#endregion
16128
16438
  //#region src/managers/ConversationsManager.ts
16129
- var import_cjs$4 = require_cjs();
16130
- const logger$5 = getLogger();
16439
+ var import_cjs$5 = require_cjs();
16440
+ const logger$6 = getLogger();
16131
16441
  var ConversationMessagesFetcher = class extends Fetcher {
16132
16442
  constructor(groupId, http) {
16133
16443
  super(`/api/fabric/conversations/${groupId}/messages`, "page_size=100", http);
@@ -16167,13 +16477,13 @@ var ConversationsManager = class {
16167
16477
  }
16168
16478
  throw new ConversationError("Join Failed - Unexpected response");
16169
16479
  } catch (error) {
16170
- logger$5.error("[ConversationsManager] Failed to join conversation:", error);
16480
+ logger$6.error("[ConversationsManager] Failed to join conversation:", error);
16171
16481
  throw error;
16172
16482
  }
16173
16483
  }
16174
16484
  async getConversationMessageCollection(addressId) {
16175
16485
  const groupId = this.groupIds.get(addressId) ?? await this.join(addressId);
16176
- return Promise.resolve(new ConversationMessageCollection(groupId, this.clientSession.signalingEvent$.pipe(filterAs(isConversationMessageMetadata, "params"), (0, import_cjs$4.tap)((event) => logger$5.debug("[ConversationsManager ] Conversation Event:", event)), (0, import_cjs$4.map)((params) => ({ ...params }))), this.http, this.onError));
16486
+ return Promise.resolve(new ConversationMessageCollection(groupId, this.clientSession.signalingEvent$.pipe(filterAs(isConversationMessageMetadata, "params"), (0, import_cjs$5.tap)((event) => logger$6.debug("[ConversationsManager ] Conversation Event:", event)), (0, import_cjs$5.map)((params) => ({ ...params }))), this.http, this.onError));
16177
16487
  }
16178
16488
  async sendText(text, destinationAddressId) {
16179
16489
  const groupId = this.groupIds.get(destinationAddressId) ?? await this.join(destinationAddressId);
@@ -16190,9 +16500,209 @@ var ConversationsManager = class {
16190
16500
  })).ok) return;
16191
16501
  throw new ConversationError("Send Text Failed - Unexpected response");
16192
16502
  } catch (error) {
16193
- logger$5.error("[ConversationsManager] Failed to send text message:", error);
16503
+ logger$6.error("[ConversationsManager] Failed to send text message:", error);
16504
+ }
16505
+ }
16506
+ };
16507
+
16508
+ //#endregion
16509
+ //#region src/managers/DeviceTokenManager.ts
16510
+ var import_cjs$4 = require_cjs();
16511
+ const logger$5 = getLogger();
16512
+ /**
16513
+ * Resolves the token expiry timestamp (epoch seconds) using a 3-tier priority chain:
16514
+ * 1. `data.expires_at` — server-provided absolute timestamp
16515
+ * 2. `data.expires_in` — server-provided relative lifetime
16516
+ * 3. Fallback to `DEVICE_TOKEN_DEFAULT_EXPIRE_IN` with a warning
16517
+ */
16518
+ function resolveExpiresAt(data) {
16519
+ if (data.expires_at) return data.expires_at;
16520
+ if (data.expires_in) return Math.floor(Date.now() / 1e3) + data.expires_in;
16521
+ logger$5.warn("[DeviceToken] Could not determine token expiry, using default");
16522
+ return Math.floor(Date.now() / 1e3) + DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
16523
+ }
16524
+ /**
16525
+ * Resolves the token TTL in seconds from a fresh response.
16526
+ * Called at token receive time so `expires_at - now` reflects the original lifetime.
16527
+ *
16528
+ * 1. `data.expires_in` — server-provided TTL directly
16529
+ * 2. `data.expires_at - now` — derive TTL from absolute timestamp
16530
+ * 3. Fallback to `DEVICE_TOKEN_DEFAULT_EXPIRE_IN`
16531
+ */
16532
+ function resolveExpireIn(data) {
16533
+ if (data.expires_in) return data.expires_in;
16534
+ if (data.expires_at) return Math.max(data.expires_at - Math.floor(Date.now() / 1e3), 1);
16535
+ return DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
16536
+ }
16537
+ /**
16538
+ * Manages the Client Bound SAT lifecycle: activation, token exchange,
16539
+ * reauthentication, and automatic refresh scheduling.
16540
+ *
16541
+ * Extends {@link Destroyable} for automatic RxJS subscription and subject cleanup.
16542
+ * Uses a reactive pipeline (`BehaviorSubject` + `switchMap(timer())`) instead of
16543
+ * raw `setTimeout` for refresh scheduling.
16544
+ */
16545
+ var DeviceTokenManager = class extends Destroyable {
16546
+ constructor(dpopManager, http, errorHandler, getCredential) {
16547
+ super();
16548
+ this.dpopManager = dpopManager;
16549
+ this.http = http;
16550
+ this.errorHandler = errorHandler;
16551
+ this.getCredential = getCredential;
16552
+ this._currentToken$ = this.createBehaviorSubject(null);
16553
+ this._refreshInProgress = false;
16554
+ this._effectiveExpireIn = DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
16555
+ this.subscribeTo(this._currentToken$.pipe((0, import_cjs$4.filter)(Boolean), (0, import_cjs$4.switchMap)((tokenData) => {
16556
+ const expiresAt = resolveExpiresAt(tokenData);
16557
+ const refreshIn = Math.max(expiresAt * 1e3 - Date.now() - DEVICE_TOKEN_REFRESH_BUFFER_MS, 1e3);
16558
+ logger$5.debug(`[DeviceToken] Scheduling Client Bound SAT refresh in ${refreshIn}ms`);
16559
+ return (0, import_cjs$4.timer)(refreshIn);
16560
+ })), () => {
16561
+ this.executeRefresh();
16562
+ });
16563
+ }
16564
+ /**
16565
+ * Activates the Client Bound SAT flow when the subscriber's token has
16566
+ * `sat:refresh` scope.
16567
+ *
16568
+ * Steps:
16569
+ * 1. Check subscriber's `sat_claims` for `sat:refresh` scope
16570
+ * 2. Call `/api/fabric/subscriber/devices/token` with a DPoP proof
16571
+ * 3. Reauthenticate the session with the Client Bound SAT + DPoP proof
16572
+ * 4. Emit token to trigger the reactive refresh pipeline
16573
+ */
16574
+ async activate(subscriber, session, updateCredential) {
16575
+ const { satClaims } = subscriber;
16576
+ if (!satClaims?.scope?.includes(SAT_REFRESH_SCOPE)) {
16577
+ logger$5.debug("[DeviceToken] No sat:refresh scope, skipping Client Bound SAT activation");
16578
+ return;
16579
+ }
16580
+ this._session = session;
16581
+ this._updateCredential = updateCredential;
16582
+ try {
16583
+ const tokenData = await this.obtainToken();
16584
+ if (!tokenData.expires_at && !tokenData.expires_in && satClaims.expires_at) tokenData.expires_at = satClaims.expires_at;
16585
+ this._effectiveExpireIn = resolveExpireIn(tokenData);
16586
+ const rpcProof = await this.dpopManager.createRpcProof({ method: "signalwire.reauthenticate" });
16587
+ await session.reauthenticate(tokenData.token, rpcProof, { clientBound: true });
16588
+ updateCredential({ token: tokenData.token });
16589
+ logger$5.info("[DeviceToken] Client Bound SAT activated successfully");
16590
+ this._currentToken$.next(tokenData);
16591
+ } catch (error) {
16592
+ logger$5.error("[DeviceToken] Failed to activate Client Bound SAT:", error);
16593
+ this.errorHandler(new DPoPInitError(error, "Failed to activate Client Bound SAT"));
16194
16594
  }
16195
16595
  }
16596
+ /**
16597
+ * Obtains a Client Bound SAT from `/api/fabric/subscriber/devices/token`.
16598
+ * Returns the full {@link DeviceTokenResponse} including expiry metadata.
16599
+ */
16600
+ async obtainToken() {
16601
+ const dpopProof = await this.dpopManager.createHttpProof({
16602
+ method: "POST",
16603
+ uri: DEVICE_TOKEN_ENDPOINT
16604
+ });
16605
+ const response = await this.http.request({
16606
+ url: DEVICE_TOKEN_ENDPOINT,
16607
+ ...POST_PARAMS,
16608
+ body: JSON.stringify({
16609
+ dpop_token: dpopProof,
16610
+ expire_in: DEVICE_TOKEN_DEFAULT_EXPIRE_IN
16611
+ })
16612
+ });
16613
+ if (!response.ok || !response.body) throw new DeviceTokenError(`Failed to obtain device token: ${response.status} ${response.statusText}`);
16614
+ const data = JSON.parse(response.body);
16615
+ if (!data.token) throw new DeviceTokenError("Device token response missing token field");
16616
+ return data;
16617
+ }
16618
+ /**
16619
+ * Refreshes the Client Bound SAT via `/api/fabric/subscriber/devices/refresh`.
16620
+ *
16621
+ * Creates a fresh DPoP proof, calls the refresh endpoint, reauthenticates
16622
+ * the WebSocket session, and returns the new token data (scheduling is
16623
+ * handled by the reactive pipeline).
16624
+ */
16625
+ async refreshToken(session, currentToken, updateCredential) {
16626
+ logger$5.debug("[DeviceToken] Refreshing Client Bound SAT");
16627
+ const dpopProof = await this.dpopManager.createHttpProof({
16628
+ method: "POST",
16629
+ uri: DEVICE_REFRESH_ENDPOINT,
16630
+ accessToken: currentToken
16631
+ });
16632
+ const response = await this.http.request({
16633
+ url: DEVICE_REFRESH_ENDPOINT,
16634
+ ...POST_PARAMS,
16635
+ body: JSON.stringify({
16636
+ dpop_token: dpopProof,
16637
+ expire_in: this._effectiveExpireIn
16638
+ })
16639
+ });
16640
+ if (!response.ok || !response.body) throw new TokenRefreshError(`Failed to refresh device token: ${response.status} ${response.statusText}`);
16641
+ const data = JSON.parse(response.body);
16642
+ if (!data.token) throw new TokenRefreshError("Device token refresh response missing token field");
16643
+ if (!data.expires_at && !data.expires_in) data.expires_in = this._effectiveExpireIn;
16644
+ this._effectiveExpireIn = resolveExpireIn(data);
16645
+ const rpcProof = await this.dpopManager.createRpcProof({ method: "signalwire.reauthenticate" });
16646
+ await session.reauthenticate(data.token, rpcProof);
16647
+ updateCredential({ token: data.token });
16648
+ logger$5.info("[DeviceToken] Client Bound SAT refreshed successfully");
16649
+ return data;
16650
+ }
16651
+ /**
16652
+ * Executes a refresh with retry and exponential backoff.
16653
+ * On success, emits to `_currentToken$` to schedule the next refresh.
16654
+ * On all retries exhausted, emits to `errorHandler`.
16655
+ */
16656
+ async executeRefresh() {
16657
+ if (this._refreshInProgress) {
16658
+ logger$5.debug("[DeviceToken] Refresh already in progress, skipping");
16659
+ return;
16660
+ }
16661
+ const session = this._session;
16662
+ const updateCredential = this._updateCredential;
16663
+ if (!session || !updateCredential) {
16664
+ logger$5.warn("[DeviceToken] Cannot refresh: session or updateCredential not set");
16665
+ return;
16666
+ }
16667
+ if (!session.authenticated) {
16668
+ logger$5.debug("[DeviceToken] Session not authenticated, deferring refresh");
16669
+ return;
16670
+ }
16671
+ this._refreshInProgress = true;
16672
+ try {
16673
+ const currentToken = this.getCredential().token;
16674
+ if (!currentToken) throw new TokenRefreshError("No current token available for refresh");
16675
+ const newTokenData = await this.retryRefresh(session, currentToken, updateCredential);
16676
+ this._currentToken$.next(newTokenData);
16677
+ } catch (error) {
16678
+ logger$5.error("[DeviceToken] Automatic Client Bound SAT refresh failed:", error);
16679
+ this.errorHandler(error instanceof TokenRefreshError ? error : new TokenRefreshError("Automatic token refresh failed", error));
16680
+ } finally {
16681
+ this._refreshInProgress = false;
16682
+ }
16683
+ }
16684
+ /**
16685
+ * Retries `refreshToken()` up to `DEVICE_TOKEN_REFRESH_MAX_RETRIES` times
16686
+ * with exponential backoff (1s, 2s, 4s).
16687
+ */
16688
+ async retryRefresh(session, currentToken, updateCredential) {
16689
+ let lastError;
16690
+ for (let attempt = 0; attempt < DEVICE_TOKEN_REFRESH_MAX_RETRIES; attempt++) try {
16691
+ return await this.refreshToken(session, currentToken, updateCredential);
16692
+ } catch (error) {
16693
+ lastError = error;
16694
+ if (attempt < DEVICE_TOKEN_REFRESH_MAX_RETRIES - 1) {
16695
+ const delay$1 = DEVICE_TOKEN_REFRESH_RETRY_BASE_MS * Math.pow(2, attempt);
16696
+ logger$5.warn(`[DeviceToken] Refresh attempt ${attempt + 1} failed, retrying in ${delay$1}ms`);
16697
+ await new Promise((resolve) => setTimeout(resolve, delay$1));
16698
+ }
16699
+ }
16700
+ throw lastError instanceof Error ? lastError : new TokenRefreshError("All refresh retries exhausted", lastError);
16701
+ }
16702
+ /** Cleans up the manager, cancelling the reactive pipeline and all subscriptions. */
16703
+ destroy() {
16704
+ super.destroy();
16705
+ }
16196
16706
  };
16197
16707
 
16198
16708
  //#endregion
@@ -16363,6 +16873,10 @@ var WebSocketController = class WebSocketController extends Destroyable {
16363
16873
  this.outgoingMessages$ = outgoingMessages$;
16364
16874
  this.messageQueue = [];
16365
16875
  this.shouldReconnect = false;
16876
+ this.boundHandleOpen = () => this.handleOpen();
16877
+ this.boundHandleClose = (event) => this.handleClose(event);
16878
+ this.boundHandleError = () => this.handleError();
16879
+ this.boundHandleMessage = (event) => this.handleMessage(event);
16366
16880
  this._status$ = this.createBehaviorSubject("disconnected");
16367
16881
  this._incomingMessages$ = this.createSubject();
16368
16882
  this._errors$ = this.createReplaySubject(1);
@@ -16418,6 +16932,7 @@ var WebSocketController = class WebSocketController extends Destroyable {
16418
16932
  }
16419
16933
  createWebSocket() {
16420
16934
  try {
16935
+ this.closeExistingSocket();
16421
16936
  this.socket = new this.WebSocketConstructor(this.endpoint);
16422
16937
  this.setupWebSocketListeners();
16423
16938
  this.startConnectionTimeout();
@@ -16427,12 +16942,33 @@ var WebSocketController = class WebSocketController extends Destroyable {
16427
16942
  this.handleConnectionError();
16428
16943
  }
16429
16944
  }
16945
+ /**
16946
+ * Closes the existing socket and removes its event listeners to prevent
16947
+ * phantom 'open'/'close' events from firing on the orphaned socket.
16948
+ */
16949
+ closeExistingSocket() {
16950
+ if (!this.socket) return;
16951
+ const oldSocket = this.socket;
16952
+ this.socket = void 0;
16953
+ this.removeWebSocketListeners(oldSocket);
16954
+ try {
16955
+ oldSocket.close();
16956
+ } catch {}
16957
+ }
16430
16958
  setupWebSocketListeners() {
16431
16959
  if (!this.socket) return;
16432
- this.socket.addEventListener("open", () => this.handleOpen());
16433
- this.socket.addEventListener("close", (event) => this.handleClose(event));
16434
- this.socket.addEventListener("error", () => this.handleError());
16435
- this.socket.addEventListener("message", (event) => this.handleMessage(event));
16960
+ this.socket.addEventListener("open", this.boundHandleOpen);
16961
+ this.socket.addEventListener("close", this.boundHandleClose);
16962
+ this.socket.addEventListener("error", this.boundHandleError);
16963
+ this.socket.addEventListener("message", this.boundHandleMessage);
16964
+ }
16965
+ removeWebSocketListeners(socket) {
16966
+ try {
16967
+ socket.removeEventListener("open", this.boundHandleOpen);
16968
+ socket.removeEventListener("close", this.boundHandleClose);
16969
+ socket.removeEventListener("error", this.boundHandleError);
16970
+ socket.removeEventListener("message", this.boundHandleMessage);
16971
+ } catch {}
16436
16972
  }
16437
16973
  handleOpen() {
16438
16974
  this.clearConnectionTimeout();
@@ -16779,6 +17315,7 @@ var SignalWire = class extends Destroyable {
16779
17315
  this._errors$ = this.createReplaySubject(1);
16780
17316
  this._options = {};
16781
17317
  this._deps = new DependencyContainer();
17318
+ this._credentialProvider = credentialProvider;
16782
17319
  this._options = {
16783
17320
  ...PreferencesContainer.instance.defaultSignalWireOptions,
16784
17321
  ...options
@@ -16802,8 +17339,25 @@ var SignalWire = class extends Destroyable {
16802
17339
  this._errors$.next(error instanceof Error ? error : new Error(String(error), { cause: error }));
16803
17340
  });
16804
17341
  }
17342
+ /**
17343
+ * Initializes DPoP if not already set up. Returns the fingerprint on success.
17344
+ */
17345
+ async initDPoP() {
17346
+ if (this._dpopManager?.initialized) return this._dpopManager.fingerprint;
17347
+ try {
17348
+ this._dpopManager = new CryptoController();
17349
+ const fingerprint = await this._dpopManager.init();
17350
+ logger$1.debug("[SignalWire] DPoP initialized, fingerprint available");
17351
+ return fingerprint;
17352
+ } catch (error) {
17353
+ logger$1.warn("[SignalWire] DPoP initialization failed, proceeding without DPoP:", error);
17354
+ this._dpopManager = void 0;
17355
+ return;
17356
+ }
17357
+ }
16805
17358
  async validateCredentials(credentialProvider, credentials) {
16806
- const _credentials = credentials ?? await credentialProvider.authenticate();
17359
+ const fingerprint = await this.initDPoP();
17360
+ const _credentials = credentials ?? await credentialProvider.authenticate(fingerprint ? { fingerprint } : void 0);
16807
17361
  if (_credentials.token) try {
16808
17362
  const decodeHeader = jwtDecode(_credentials.token, { header: true });
16809
17363
  this._deps.ch = decodeHeader.ch;
@@ -16926,12 +17480,53 @@ var SignalWire = class extends Destroyable {
16926
17480
  };
16927
17481
  this._transport = new TransportManager(this._deps.storage, this._deps.protocolKey, this._deps.WebSocket, PreferencesContainer.instance.relayHost ?? this._deps.relayHost, errorHandler);
16928
17482
  this._attachManager = new AttachManager(this._deps.storage, this._deps.deviceController, PreferencesContainer.instance.reconnectCallsTimeout, this._deps.attachedCallsKey);
16929
- this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager, this._deps.webRTCApiProvider);
17483
+ this._clientSession = new ClientSessionManager(() => this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager, this._deps.webRTCApiProvider, this._dpopManager);
16930
17484
  this._publicSession = new ClientSessionWrapper(this._clientSession);
17485
+ this._clientSession.onBeforeReconnect = async () => {
17486
+ if (!this._credentialProvider) return;
17487
+ try {
17488
+ const fingerprint = this._dpopManager?.initialized ? this._dpopManager.fingerprint : void 0;
17489
+ logger$1.debug("[SignalWire] Credential expired, refreshing before reconnect");
17490
+ const newCredentials = await this._credentialProvider.authenticate(fingerprint ? { fingerprint } : void 0);
17491
+ this._deps.credential = newCredentials;
17492
+ logger$1.debug("[SignalWire] Credential refreshed successfully for reconnect");
17493
+ } catch (error) {
17494
+ logger$1.error("[SignalWire] Failed to refresh credentials for reconnect:", error);
17495
+ }
17496
+ };
16931
17497
  this.subscribeTo(this._clientSession.errors$, (error) => {
16932
17498
  this._errors$.next(error);
16933
17499
  });
16934
17500
  await this._clientSession.connect();
17501
+ if (this._dpopManager?.initialized) {
17502
+ if (this._refreshTimerId) {
17503
+ clearTimeout(this._refreshTimerId);
17504
+ this._refreshTimerId = void 0;
17505
+ logger$1.debug("[SignalWire] Developer refresh disabled — Client Bound SAT activation starting");
17506
+ }
17507
+ this._deviceTokenManager = new DeviceTokenManager(this._dpopManager, this._deps.http, (error) => this._errors$.next(error), () => this._deps.credential);
17508
+ await this._deviceTokenManager.activate(this._deps.subscriber, this._clientSession, (cred) => {
17509
+ this._deps.credential = {
17510
+ ...this._deps.credential,
17511
+ ...cred
17512
+ };
17513
+ });
17514
+ this.subscribeTo(this._clientSession.authenticated$.pipe((0, import_cjs.skip)(1), (0, import_cjs.filter)(Boolean)), () => {
17515
+ logger$1.debug("[SignalWire] Re-activating Client Bound SAT after reconnect");
17516
+ this._deviceTokenManager?.activate(this._deps.subscriber, this._clientSession, (cred) => {
17517
+ this._deps.credential = {
17518
+ ...this._deps.credential,
17519
+ ...cred
17520
+ };
17521
+ });
17522
+ logger$1.debug("[SignalWire] Re-registering subscriber after reconnect");
17523
+ this.register().then(() => {
17524
+ logger$1.debug("[SignalWire] Subscriber re-registered successfully after reconnect");
17525
+ }).catch((error) => {
17526
+ logger$1.error("[SignalWire] Re-registration failed after reconnect:", error);
17527
+ });
17528
+ });
17529
+ }
16935
17530
  const conversationManager = new ConversationsManager(this._clientSession, this._deps.http, () => this._deps.getSubscriberFromAddressId(), errorHandler);
16936
17531
  const directory = new DirectoryManager(this._deps.http, this._clientSession, conversationManager, errorHandler);
16937
17532
  this._directory$.next(directory);
@@ -17209,6 +17804,8 @@ var SignalWire = class extends Destroyable {
17209
17804
  clearTimeout(this._refreshTimerId);
17210
17805
  this._refreshTimerId = void 0;
17211
17806
  }
17807
+ this._deviceTokenManager?.destroy();
17808
+ this._dpopManager?.destroy();
17212
17809
  super.destroy();
17213
17810
  }
17214
17811
  };
@@ -17348,5 +17945,5 @@ emitReadyEvent();
17348
17945
  if (typeof process === "undefined") globalThis.process = { env: { NODE_ENV: "production" } };
17349
17946
 
17350
17947
  //#endregion
17351
- export { Address, CallCreateError, ClientPreferences, CollectionFetchError, InvalidCredentialsError, MediaTrackError, MessageParseError, Participant, SelfCapabilities, SelfParticipant, SignalWire, StaticCredentialProvider, Subscriber, UnexpectedError, VertoPongError, WebRTCCall, embeddableCall, isSelfParticipant, ready, version };
17948
+ export { Address, CallCreateError, ClientPreferences, CollectionFetchError, DPoPInitError, DeviceTokenError, InvalidCredentialsError, MediaTrackError, MessageParseError, Participant, SelfCapabilities, SelfParticipant, SignalWire, StaticCredentialProvider, Subscriber, TokenRefreshError, UnexpectedError, VertoPongError, WebRTCCall, embeddableCall, isSelfParticipant, ready, version };
17352
17949
  //# sourceMappingURL=browser.mjs.map