@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.
@@ -4144,7 +4144,7 @@ var require_timer = /* @__PURE__ */ __commonJSMin(((exports) => {
4144
4144
  var async_1$11 = require_async();
4145
4145
  var isScheduler_1 = require_isScheduler();
4146
4146
  var isDate_1$1 = require_isDate();
4147
- function timer(dueTime, intervalOrScheduler, scheduler) {
4147
+ function timer$1(dueTime, intervalOrScheduler, scheduler) {
4148
4148
  if (dueTime === void 0) dueTime = 0;
4149
4149
  if (scheduler === void 0) scheduler = async_1$11.async;
4150
4150
  var intervalDuration = -1;
@@ -4163,7 +4163,7 @@ var require_timer = /* @__PURE__ */ __commonJSMin(((exports) => {
4163
4163
  }, due);
4164
4164
  });
4165
4165
  }
4166
- exports.timer = timer;
4166
+ exports.timer = timer$1;
4167
4167
  }));
4168
4168
 
4169
4169
  //#endregion
@@ -4297,7 +4297,7 @@ var require_filter = /* @__PURE__ */ __commonJSMin(((exports) => {
4297
4297
  exports.filter = void 0;
4298
4298
  var lift_1$62 = require_lift();
4299
4299
  var OperatorSubscriber_1$49 = require_OperatorSubscriber();
4300
- function filter$12(predicate, thisArg) {
4300
+ function filter$13(predicate, thisArg) {
4301
4301
  return lift_1$62.operate(function(source, subscriber) {
4302
4302
  var index = 0;
4303
4303
  source.subscribe(OperatorSubscriber_1$49.createOperatorSubscriber(subscriber, function(value) {
@@ -4305,7 +4305,7 @@ var require_filter = /* @__PURE__ */ __commonJSMin(((exports) => {
4305
4305
  }));
4306
4306
  });
4307
4307
  }
4308
- exports.filter = filter$12;
4308
+ exports.filter = filter$13;
4309
4309
  }));
4310
4310
 
4311
4311
  //#endregion
@@ -5631,9 +5631,9 @@ var require_exhaustMap = /* @__PURE__ */ __commonJSMin(((exports) => {
5631
5631
  var innerFrom_1$16 = require_innerFrom();
5632
5632
  var lift_1$39 = require_lift();
5633
5633
  var OperatorSubscriber_1$28 = require_OperatorSubscriber();
5634
- function exhaustMap$1(project, resultSelector) {
5634
+ function exhaustMap$2(project, resultSelector) {
5635
5635
  if (resultSelector) return function(source) {
5636
- return source.pipe(exhaustMap$1(function(a, i) {
5636
+ return source.pipe(exhaustMap$2(function(a, i) {
5637
5637
  return innerFrom_1$16.innerFrom(project(a, i)).pipe(map_1$4.map(function(b, ii) {
5638
5638
  return resultSelector(a, b, i, ii);
5639
5639
  }));
@@ -5657,7 +5657,7 @@ var require_exhaustMap = /* @__PURE__ */ __commonJSMin(((exports) => {
5657
5657
  }));
5658
5658
  });
5659
5659
  }
5660
- exports.exhaustMap = exhaustMap$1;
5660
+ exports.exhaustMap = exhaustMap$2;
5661
5661
  }));
5662
5662
 
5663
5663
  //#endregion
@@ -6829,12 +6829,12 @@ var require_skip = /* @__PURE__ */ __commonJSMin(((exports) => {
6829
6829
  Object.defineProperty(exports, "__esModule", { value: true });
6830
6830
  exports.skip = void 0;
6831
6831
  var filter_1$3 = require_filter();
6832
- function skip$2(count$1) {
6832
+ function skip$3(count$1) {
6833
6833
  return filter_1$3.filter(function(_, index) {
6834
6834
  return count$1 <= index;
6835
6835
  });
6836
6836
  }
6837
- exports.skip = skip$2;
6837
+ exports.skip = skip$3;
6838
6838
  }));
6839
6839
 
6840
6840
  //#endregion
@@ -6938,7 +6938,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6938
6938
  var innerFrom_1$6 = require_innerFrom();
6939
6939
  var lift_1$13 = require_lift();
6940
6940
  var OperatorSubscriber_1$11 = require_OperatorSubscriber();
6941
- function switchMap$4(project, resultSelector) {
6941
+ function switchMap$5(project, resultSelector) {
6942
6942
  return lift_1$13.operate(function(source, subscriber) {
6943
6943
  var innerSubscriber = null;
6944
6944
  var index = 0;
@@ -6962,7 +6962,7 @@ var require_switchMap = /* @__PURE__ */ __commonJSMin(((exports) => {
6962
6962
  }));
6963
6963
  });
6964
6964
  }
6965
- exports.switchMap = switchMap$4;
6965
+ exports.switchMap = switchMap$5;
6966
6966
  }));
6967
6967
 
6968
6968
  //#endregion
@@ -8937,12 +8937,12 @@ var require_cjs = /* @__PURE__ */ __commonJSMin(((exports) => {
8937
8937
 
8938
8938
  //#endregion
8939
8939
  //#region src/behaviors/Destroyable.ts
8940
- var import_cjs$22 = require_cjs();
8940
+ var import_cjs$23 = require_cjs();
8941
8941
  var Destroyable = class {
8942
8942
  constructor() {
8943
8943
  this.subscriptions = [];
8944
8944
  this.subjects = [];
8945
- this._destroyed$ = new import_cjs$22.Subject();
8945
+ this._destroyed$ = new import_cjs$23.Subject();
8946
8946
  }
8947
8947
  destroy() {
8948
8948
  this._observableCache?.clear();
@@ -8978,7 +8978,7 @@ var Destroyable = class {
8978
8978
  this._observableCache ??= /* @__PURE__ */ new Map();
8979
8979
  let cached = this._observableCache.get(publicKey);
8980
8980
  if (!cached) {
8981
- cached = factory().pipe((0, import_cjs$22.observeOn)(import_cjs$22.asapScheduler));
8981
+ cached = factory().pipe((0, import_cjs$23.observeOn)(import_cjs$23.asapScheduler));
8982
8982
  this._observableCache.set(publicKey, cached);
8983
8983
  }
8984
8984
  return cached;
@@ -8992,29 +8992,29 @@ var Destroyable = class {
8992
8992
  * Do NOT use for observables consumed internally by the SDK.
8993
8993
  */
8994
8994
  deferEmission(observable) {
8995
- return observable.pipe((0, import_cjs$22.observeOn)(import_cjs$22.asapScheduler));
8995
+ return observable.pipe((0, import_cjs$23.observeOn)(import_cjs$23.asapScheduler));
8996
8996
  }
8997
8997
  subscribeTo(observable, observerOrNext) {
8998
8998
  const subscription = observable.subscribe(observerOrNext);
8999
8999
  this.subscriptions.push(subscription);
9000
9000
  }
9001
9001
  createSubject() {
9002
- const subject = new import_cjs$22.Subject();
9002
+ const subject = new import_cjs$23.Subject();
9003
9003
  this.subjects.push(subject);
9004
9004
  return subject;
9005
9005
  }
9006
9006
  createReplaySubject(bufferSize, windowTime$1) {
9007
- const subject = new import_cjs$22.ReplaySubject(bufferSize, windowTime$1);
9007
+ const subject = new import_cjs$23.ReplaySubject(bufferSize, windowTime$1);
9008
9008
  this.subjects.push(subject);
9009
9009
  return subject;
9010
9010
  }
9011
9011
  createBehaviorSubject(initialValue) {
9012
- const subject = new import_cjs$22.BehaviorSubject(initialValue);
9012
+ const subject = new import_cjs$23.BehaviorSubject(initialValue);
9013
9013
  this.subjects.push(subject);
9014
9014
  return subject;
9015
9015
  }
9016
9016
  get $() {
9017
- 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)));
9017
+ 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)));
9018
9018
  }
9019
9019
  /**
9020
9020
  * Observable that emits when the instance is destroyed
@@ -9223,6 +9223,27 @@ var MediaTrackError = class extends Error {
9223
9223
  this.name = "MediaTrackError";
9224
9224
  }
9225
9225
  };
9226
+ var DPoPInitError = class extends Error {
9227
+ constructor(originalError, message = "Failed to initialize DPoP key pair") {
9228
+ super(message, { cause: originalError instanceof Error ? originalError : void 0 });
9229
+ this.originalError = originalError;
9230
+ this.name = "DPoPInitError";
9231
+ }
9232
+ };
9233
+ var DeviceTokenError = class extends Error {
9234
+ constructor(message, originalError) {
9235
+ super(message, { cause: originalError instanceof Error ? originalError : void 0 });
9236
+ this.originalError = originalError;
9237
+ this.name = "DeviceTokenError";
9238
+ }
9239
+ };
9240
+ var TokenRefreshError = class extends Error {
9241
+ constructor(message, originalError) {
9242
+ super(message, { cause: originalError instanceof Error ? originalError : void 0 });
9243
+ this.originalError = originalError;
9244
+ this.name = "TokenRefreshError";
9245
+ }
9246
+ };
9226
9247
 
9227
9248
  //#endregion
9228
9249
  //#region ../../node_modules/loglevel/lib/loglevel.js
@@ -9405,9 +9426,9 @@ var require_loglevel = /* @__PURE__ */ __commonJSMin(((exports, module) => {
9405
9426
  defaultLogger$1 = new Logger();
9406
9427
  defaultLogger$1.getLogger = function getLogger$1(name) {
9407
9428
  if (typeof name !== "symbol" && typeof name !== "string" || name === "") throw new TypeError("You must supply a name when creating a logger.");
9408
- var logger$22 = _loggersByName[name];
9409
- if (!logger$22) logger$22 = _loggersByName[name] = new Logger(name, defaultLogger$1.methodFactory);
9410
- return logger$22;
9429
+ var logger$24 = _loggersByName[name];
9430
+ if (!logger$24) logger$24 = _loggersByName[name] = new Logger(name, defaultLogger$1.methodFactory);
9431
+ return logger$24;
9411
9432
  };
9412
9433
  var _log = typeof window !== undefinedType ? window.log : void 0;
9413
9434
  defaultLogger$1.noConflict = function() {
@@ -9447,15 +9468,15 @@ const shouldStringify = (payload) => {
9447
9468
  return true;
9448
9469
  };
9449
9470
  const wsTraffic = ({ type, payload }) => {
9450
- const logger$22 = getLoggerInstance();
9471
+ const logger$24 = getLoggerInstance();
9451
9472
  const { logWsTraffic } = debugOptions ?? {};
9452
9473
  if (!logWsTraffic) return;
9453
9474
  const msg = shouldStringify(payload) ? JSON.stringify(payload, null, 2) : payload;
9454
- return logger$22.debug(`${type.toUpperCase()}: \n`, msg, "\n");
9475
+ return logger$24.debug(`${type.toUpperCase()}: \n`, msg, "\n");
9455
9476
  };
9456
9477
  const getLogger = () => {
9457
- const logger$22 = getLoggerInstance();
9458
- return new Proxy(logger$22, { get(target, prop, receiver) {
9478
+ const logger$24 = getLoggerInstance();
9479
+ return new Proxy(logger$24, { get(target, prop, receiver) {
9459
9480
  if (prop === "wsTraffic") return wsTraffic;
9460
9481
  return Reflect.get(target, prop, receiver);
9461
9482
  } });
@@ -9504,8 +9525,8 @@ const asyncRetry = async ({ asyncCallable, maxRetries: retries = DEFAULT_MAX_RET
9504
9525
 
9505
9526
  //#endregion
9506
9527
  //#region src/controllers/HTTPRequestController.ts
9507
- var import_cjs$21 = require_cjs();
9508
- const logger$21 = getLogger();
9528
+ var import_cjs$22 = require_cjs();
9529
+ const logger$23 = getLogger();
9509
9530
  const GET_PARAMS = {
9510
9531
  method: "GET",
9511
9532
  headers: { Accept: "application/json" }
@@ -9530,12 +9551,19 @@ var HTTPRequestController = class HTTPRequestController {
9530
9551
  static {
9531
9552
  this.defaultRequestTimeoutMs = 3e4;
9532
9553
  }
9533
- constructor(baseURL, credential, options = {}) {
9554
+ static {
9555
+ this.SENSITIVE_BODY_FIELDS = new Set([
9556
+ "dpop_token",
9557
+ "token",
9558
+ "jwt_token"
9559
+ ]);
9560
+ }
9561
+ constructor(baseURL, getCredential, options = {}) {
9534
9562
  this.baseURL = baseURL;
9535
- this.credential = credential;
9536
- this._responses$ = new import_cjs$21.Subject();
9537
- this._errors$ = new import_cjs$21.Subject();
9538
- this._status$ = new import_cjs$21.BehaviorSubject("idle");
9563
+ this.getCredential = getCredential;
9564
+ this._responses$ = new import_cjs$22.Subject();
9565
+ this._errors$ = new import_cjs$22.Subject();
9566
+ this._status$ = new import_cjs$22.BehaviorSubject("idle");
9539
9567
  this.maxRetries = options.maxRetries ?? HTTPRequestController.defaultMaxRetries;
9540
9568
  this.retryDelayMin = options.retryDelayMin ?? HTTPRequestController.defaultRetryDelayMinMs;
9541
9569
  this.retryDelayMax = options.retryDelayMax ?? HTTPRequestController.defaultRetryDelayMaxMs;
@@ -9561,7 +9589,7 @@ var HTTPRequestController = class HTTPRequestController {
9561
9589
  this._responses$.next(response);
9562
9590
  return response;
9563
9591
  } catch (error) {
9564
- logger$21.error("[HTTPRequestController] Request error:", error);
9592
+ logger$23.error("[HTTPRequestController] Request error:", error);
9565
9593
  this._status$.next("error");
9566
9594
  const err = error instanceof Error ? error : new Error("HTTP request failed", { cause: error });
9567
9595
  this._errors$.next(err);
@@ -9588,14 +9616,14 @@ var HTTPRequestController = class HTTPRequestController {
9588
9616
  const url = this.buildURL(request.url);
9589
9617
  const headers = this.buildHeaders(request.headers);
9590
9618
  const timeout$4 = request.timeout ?? this.requestTimeout;
9591
- logger$21.debug("[HTTPRequestController] Executing request:", {
9619
+ logger$23.debug("[HTTPRequestController] Executing request:", {
9592
9620
  method: request.method,
9593
9621
  url,
9594
9622
  headers: Object.keys(headers).reduce((acc, key) => {
9595
9623
  acc[key] = key === "Authorization" ? `${headers[key].substring(0, 20)}...` : headers[key];
9596
9624
  return acc;
9597
9625
  }, {}),
9598
- body: request.body
9626
+ body: this.sanitizeBody(request.body)
9599
9627
  });
9600
9628
  const controller = new AbortController();
9601
9629
  const timeoutId = setTimeout(() => controller.abort(), timeout$4);
@@ -9608,7 +9636,7 @@ var HTTPRequestController = class HTTPRequestController {
9608
9636
  });
9609
9637
  clearTimeout(timeoutId);
9610
9638
  const httpResponse = await this.convertResponse(response);
9611
- logger$21.debug("[HTTPRequestController] Response received:", {
9639
+ logger$23.debug("[HTTPRequestController] Response received:", {
9612
9640
  status: response.status,
9613
9641
  statusText: response.statusText,
9614
9642
  headers: [...response.headers.entries()],
@@ -9618,7 +9646,7 @@ var HTTPRequestController = class HTTPRequestController {
9618
9646
  } catch (error) {
9619
9647
  clearTimeout(timeoutId);
9620
9648
  if (error instanceof Error && error.name === "AbortError") throw new RequestTimeoutError(`Request timeout after ${timeout$4}ms`, { cause: error });
9621
- logger$21.error("[HTTPRequestController] Request failed:", error);
9649
+ logger$23.error("[HTTPRequestController] Request failed:", error);
9622
9650
  throw error;
9623
9651
  }
9624
9652
  }
@@ -9629,12 +9657,26 @@ var HTTPRequestController = class HTTPRequestController {
9629
9657
  }
9630
9658
  buildHeaders(requestHeaders) {
9631
9659
  const headers = { ...requestHeaders ?? {} };
9632
- if (this.credential.token) {
9633
- headers.Authorization = `Bearer ${this.credential.token}`;
9634
- logger$21.debug("[HTTPRequestController] Using Bearer token auth, token length:", this.credential.token.length);
9635
- } else logger$21.warn("[HTTPRequestController] No credentials available for authentication");
9660
+ const credential = this.getCredential();
9661
+ if (credential.token) {
9662
+ headers.Authorization = `Bearer ${credential.token}`;
9663
+ logger$23.debug("[HTTPRequestController] Using Bearer token auth, token length:", credential.token.length);
9664
+ } else logger$23.warn("[HTTPRequestController] No credentials available for authentication");
9636
9665
  return headers;
9637
9666
  }
9667
+ /**
9668
+ * Sanitizes a request body for debug logging by masking sensitive fields.
9669
+ */
9670
+ sanitizeBody(body) {
9671
+ if (!body || typeof body !== "string") return body ? "(non-string body)" : void 0;
9672
+ try {
9673
+ const sanitized = { ...JSON.parse(body) };
9674
+ 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]`;
9675
+ return JSON.stringify(sanitized);
9676
+ } catch {
9677
+ return body.length > 200 ? `${body.substring(0, 200)}...` : body;
9678
+ }
9679
+ }
9638
9680
  async convertResponse(response) {
9639
9681
  const headers = {};
9640
9682
  response.headers.forEach((value, key) => {
@@ -9664,6 +9706,25 @@ const DEFAULT_RECONNECT_DELAY_MAX_MS = 3e3;
9664
9706
  const DEFAULT_DEVICE_DEBOUNCE_TIME_MS = 1500;
9665
9707
  const DEFAULT_DEVICE_POLLING_INTERVAL_MS = 0;
9666
9708
  const PREFERENCES_STORAGE_KEY = "sw:preferences";
9709
+ /** Scope value that enables automatic token refresh. */
9710
+ const SAT_REFRESH_SCOPE = "sat:refresh";
9711
+ /** API endpoints for device token operations. */
9712
+ const DEVICE_TOKEN_ENDPOINT = "/api/fabric/subscriber/devices/token";
9713
+ const DEVICE_REFRESH_ENDPOINT = "/api/fabric/subscriber/devices/refresh";
9714
+ /** Default device token TTL in seconds (15 minutes). */
9715
+ const DEVICE_TOKEN_DEFAULT_EXPIRE_IN = 900;
9716
+ /** Buffer time in milliseconds before expiry to trigger refresh. */
9717
+ const DEVICE_TOKEN_REFRESH_BUFFER_MS = 3e4;
9718
+ /** Maximum retry attempts for device token refresh on transient failure. */
9719
+ const DEVICE_TOKEN_REFRESH_MAX_RETRIES = 3;
9720
+ /** Base delay in milliseconds for exponential backoff on refresh retry. */
9721
+ const DEVICE_TOKEN_REFRESH_RETRY_BASE_MS = 1e3;
9722
+ /** JSON-RPC error code for requester validation failure (corrupted auth state). */
9723
+ const RPC_ERROR_REQUESTER_VALIDATION_FAILED = -32003;
9724
+ /** JSON-RPC error code for invalid params (e.g., missing authentication block). */
9725
+ const RPC_ERROR_INVALID_PARAMS = -32602;
9726
+ /** JSON-RPC error code for authentication failure (invalid token, missing DPoP, etc.). */
9727
+ const RPC_ERROR_AUTHENTICATION_FAILED = -32002;
9667
9728
 
9668
9729
  //#endregion
9669
9730
  //#region src/utils/time.ts
@@ -9676,7 +9737,7 @@ function fromMsToSec(milliseconds) {
9676
9737
 
9677
9738
  //#endregion
9678
9739
  //#region src/containers/PreferencesContainer.ts
9679
- const logger$20 = getLogger();
9740
+ const logger$22 = getLogger();
9680
9741
  var PreferencesContainer = class PreferencesContainer {
9681
9742
  static get instance() {
9682
9743
  this._instance ??= new PreferencesContainer();
@@ -9970,7 +10031,7 @@ var ClientPreferences = class {
9970
10031
  if (!this._storage) return;
9971
10032
  const data = collectStoredPreferences();
9972
10033
  this._storage.setItem(PREFERENCES_STORAGE_KEY, data, "local").catch((error) => {
9973
- logger$20.error(`[ClientPreferences] Failed to save preferences: ${String(error)}`);
10034
+ logger$22.error(`[ClientPreferences] Failed to save preferences: ${String(error)}`);
9974
10035
  });
9975
10036
  }
9976
10037
  /** Loads preferences from storage and applies them to the container. */
@@ -9979,15 +10040,15 @@ var ClientPreferences = class {
9979
10040
  this._storage.getItem(PREFERENCES_STORAGE_KEY, "local").then((stored) => {
9980
10041
  if (stored) applyStoredPreferences(stored);
9981
10042
  }).catch((error) => {
9982
- logger$20.error(`[ClientPreferences] Failed to load preferences: ${String(error)}`);
10043
+ logger$22.error(`[ClientPreferences] Failed to load preferences: ${String(error)}`);
9983
10044
  });
9984
10045
  }
9985
10046
  };
9986
10047
 
9987
10048
  //#endregion
9988
10049
  //#region src/controllers/NavigatorDeviceController.ts
9989
- var import_cjs$20 = require_cjs();
9990
- const logger$19 = getLogger();
10050
+ var import_cjs$21 = require_cjs();
10051
+ const logger$21 = getLogger();
9991
10052
  const initialDevicesState = {
9992
10053
  audioinput: [],
9993
10054
  audiooutput: [],
@@ -10008,7 +10069,7 @@ var NavigatorDeviceController = class extends Destroyable {
10008
10069
  super();
10009
10070
  this.webRTCApiProvider = webRTCApiProvider;
10010
10071
  this.deviceChangeHandler = () => {
10011
- logger$19.debug("[DeviceController] Device change detected");
10072
+ logger$21.debug("[DeviceController] Device change detected");
10012
10073
  this.enumerateDevices();
10013
10074
  };
10014
10075
  this._devicesState$ = this.createBehaviorSubject(initialDevicesState);
@@ -10030,25 +10091,25 @@ var NavigatorDeviceController = class extends Destroyable {
10030
10091
  return {};
10031
10092
  }
10032
10093
  get errors$() {
10033
- return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$20.takeUntil)(this.destroyed$)));
10094
+ return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$21.takeUntil)(this.destroyed$)));
10034
10095
  }
10035
10096
  get audioInputDevices$() {
10036
- 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$)));
10097
+ 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$)));
10037
10098
  }
10038
10099
  get audioOutputDevices$() {
10039
- 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$)));
10100
+ 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$)));
10040
10101
  }
10041
10102
  get videoInputDevices$() {
10042
- 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$)));
10103
+ 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$)));
10043
10104
  }
10044
10105
  get selectedAudioInputDevice$() {
10045
- 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))));
10106
+ 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))));
10046
10107
  }
10047
10108
  get selectedAudioOutputDevice$() {
10048
- 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))));
10109
+ 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))));
10049
10110
  }
10050
10111
  get selectedVideoInputDevice$() {
10051
- 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))));
10112
+ 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))));
10052
10113
  }
10053
10114
  get selectedAudioInputDevice() {
10054
10115
  return this._selectedDevicesState$.value.audioinput;
@@ -10075,7 +10136,7 @@ var NavigatorDeviceController = class extends Destroyable {
10075
10136
  });
10076
10137
  }
10077
10138
  selectVideoInputDevice(device) {
10078
- logger$19.debug("[DeviceController] Setting selected video input device:", device);
10139
+ logger$21.debug("[DeviceController] Setting selected video input device:", device);
10079
10140
  this._selectedDevicesState$.next({
10080
10141
  ...this._selectedDevicesState$.value,
10081
10142
  videoinput: device
@@ -10088,7 +10149,7 @@ var NavigatorDeviceController = class extends Destroyable {
10088
10149
  });
10089
10150
  }
10090
10151
  init() {
10091
- this.subscribeTo(this._devicesState$.pipe((0, import_cjs$20.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10152
+ this.subscribeTo(this._devicesState$.pipe((0, import_cjs$21.debounceTime)(PreferencesContainer.instance.deviceDebounceTime)), (devicesState) => {
10092
10153
  const currentSelected = this._selectedDevicesState$.value;
10093
10154
  const newAudioInput = selectDevice(devicesState.audioinput, currentSelected.audioinput, PreferencesContainer.instance.preferredAudioInput);
10094
10155
  const newAudioOutput = selectDevice(devicesState.audiooutput, currentSelected.audiooutput, PreferencesContainer.instance.preferredAudioOutput);
@@ -10104,8 +10165,8 @@ var NavigatorDeviceController = class extends Destroyable {
10104
10165
  enableDeviceMonitoring() {
10105
10166
  this.disableDeviceMonitoring();
10106
10167
  this.webRTCApiProvider.mediaDevices.addEventListener("devicechange", this.deviceChangeHandler);
10107
- if (PreferencesContainer.instance.devicePollingInterval > 0) this._devicesPoolingSubscription = (0, import_cjs$20.interval)(PreferencesContainer.instance.devicePollingInterval).subscribe(() => {
10108
- logger$19.debug("[DeviceController] Polling devices due to interval");
10168
+ if (PreferencesContainer.instance.devicePollingInterval > 0) this._devicesPoolingSubscription = (0, import_cjs$21.interval)(PreferencesContainer.instance.devicePollingInterval).subscribe(() => {
10169
+ logger$21.debug("[DeviceController] Polling devices due to interval");
10109
10170
  this.enumerateDevices();
10110
10171
  });
10111
10172
  this.enumerateDevices();
@@ -10128,13 +10189,13 @@ var NavigatorDeviceController = class extends Destroyable {
10128
10189
  videoinput: []
10129
10190
  });
10130
10191
  this._devicesState$.next(devicesByKind);
10131
- logger$19.debug("[DeviceController] Devices enumerated:", {
10192
+ logger$21.debug("[DeviceController] Devices enumerated:", {
10132
10193
  audioInputs: devicesByKind.audioinput.length,
10133
10194
  audioOutputs: devicesByKind.audiooutput.length,
10134
10195
  videoInputs: devicesByKind.videoinput.length
10135
10196
  });
10136
10197
  } catch (error) {
10137
- logger$19.error("[DeviceController] Failed to enumerate devices:", error);
10198
+ logger$21.error("[DeviceController] Failed to enumerate devices:", error);
10138
10199
  this._errors$.next(error);
10139
10200
  }
10140
10201
  }
@@ -10150,7 +10211,7 @@ var NavigatorDeviceController = class extends Destroyable {
10150
10211
  stream.getTracks().forEach((t) => t.stop());
10151
10212
  return capabilities;
10152
10213
  } catch (error) {
10153
- logger$19.error("[DeviceController] Failed to get device capabilities:", error);
10214
+ logger$21.error("[DeviceController] Failed to get device capabilities:", error);
10154
10215
  this._errors$.next(error);
10155
10216
  throw error;
10156
10217
  }
@@ -10297,7 +10358,7 @@ var DependencyContainer = class {
10297
10358
  return this._storageManager;
10298
10359
  }
10299
10360
  get http() {
10300
- this._httpRequestController ??= new HTTPRequestController(this._baseURL, this._credential);
10361
+ this._httpRequestController ??= new HTTPRequestController(this._baseURL, () => this._credential);
10301
10362
  return this._httpRequestController;
10302
10363
  }
10303
10364
  get conversationManager() {
@@ -10353,7 +10414,6 @@ var DependencyContainer = class {
10353
10414
  }
10354
10415
  set credential(credential) {
10355
10416
  this._credential = credential;
10356
- this._httpRequestController = void 0;
10357
10417
  }
10358
10418
  set storageImpl(storageImpl) {
10359
10419
  this._storageImpl = storageImpl;
@@ -10366,24 +10426,206 @@ var DependencyContainer = class {
10366
10426
  this._host = ch.substring(0, firstDot);
10367
10427
  this._domain = ch.substring(firstDot + 1);
10368
10428
  }
10429
+ this._baseURL = this.apiHost;
10430
+ this._httpRequestController = void 0;
10369
10431
  }
10370
10432
  get relayHost() {
10371
10433
  return `wss://${this._host ?? "puc"}.${this._domain ?? "signalwire.com"}`;
10372
10434
  }
10373
10435
  get apiHost() {
10374
- return `https://${this._host ?? "fabric"}.${this._domain ?? "signalwire.com"}`;
10436
+ return `https://fabric.${this._domain ?? "signalwire.com"}`;
10437
+ }
10438
+ };
10439
+
10440
+ //#endregion
10441
+ //#region src/controllers/CryptoController.ts
10442
+ const logger$20 = getLogger();
10443
+ /**
10444
+ * Base64url-encodes an ArrayBuffer (no padding, URL-safe).
10445
+ */
10446
+ const base64url = (buffer$1) => {
10447
+ const bytes = new Uint8Array(buffer$1);
10448
+ let binary = "";
10449
+ for (const byte of bytes) binary += String.fromCharCode(byte);
10450
+ return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
10451
+ };
10452
+ /**
10453
+ * Base64url-encodes a UTF-8 string.
10454
+ */
10455
+ const base64urlEncode = (str) => {
10456
+ return base64url(new TextEncoder().encode(str).buffer);
10457
+ };
10458
+ /**
10459
+ * Computes the JWK Thumbprint per RFC 7638.
10460
+ *
10461
+ * Only supports RSA keys — the canonical JSON uses lexicographic member ordering: { e, kty, n }.
10462
+ * The thumbprint is SHA-256 of the canonical JSON, base64url-encoded.
10463
+ *
10464
+ * @throws {Error} If the JWK is not an RSA key.
10465
+ */
10466
+ const computeJwkThumbprint = async (jwk) => {
10467
+ if (jwk.kty !== "RSA") throw new Error(`Unsupported key type for JWK Thumbprint: ${jwk.kty}. Only RSA is supported.`);
10468
+ const canonical = JSON.stringify({
10469
+ e: jwk.e,
10470
+ kty: jwk.kty,
10471
+ n: jwk.n
10472
+ });
10473
+ return base64url(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(canonical)));
10474
+ };
10475
+ /**
10476
+ * Controls DPoP (Demonstrating Proof-of-Possession) cryptographic operations.
10477
+ *
10478
+ * Generates an ephemeral RSA-2048 key pair where the private key is
10479
+ * non-extractable, computes the JWK Thumbprint (RFC 7638) as the fingerprint,
10480
+ * and creates signed DPoP proof JWTs for both HTTP API requests and
10481
+ * WebSocket RPC calls.
10482
+ *
10483
+ * @example
10484
+ * ```typescript
10485
+ * const crypto = new CryptoController();
10486
+ * await crypto.init();
10487
+ *
10488
+ * // Get fingerprint for SAT issuance
10489
+ * const fingerprint = crypto.fingerprint;
10490
+ *
10491
+ * // Create proof for HTTP endpoint
10492
+ * const httpProof = await crypto.createHttpProof({
10493
+ * method: 'POST',
10494
+ * uri: '/api/fabric/subscriber/devices/token'
10495
+ * });
10496
+ *
10497
+ * // Create proof for RPC call
10498
+ * const rpcProof = await crypto.createRpcProof({
10499
+ * method: 'signalwire.connect'
10500
+ * });
10501
+ * ```
10502
+ */
10503
+ var CryptoController = class {
10504
+ constructor() {
10505
+ this._keyPair = null;
10506
+ this._publicJwk = null;
10507
+ this._fingerprint = null;
10508
+ this._initialized = false;
10509
+ }
10510
+ /**
10511
+ * Generates the ephemeral RSA key pair and computes the fingerprint.
10512
+ *
10513
+ * Must be called before any other method. The private key is generated
10514
+ * as non-extractable to prevent accidental exposure.
10515
+ *
10516
+ * @returns The JWK Thumbprint (fingerprint) for the generated key.
10517
+ */
10518
+ async init() {
10519
+ if (this._initialized) return this.fingerprint;
10520
+ logger$20.debug("[DPoP] Generating ephemeral RSA key pair");
10521
+ this._keyPair = await crypto.subtle.generateKey({
10522
+ name: "RSASSA-PKCS1-v1_5",
10523
+ modulusLength: 2048,
10524
+ publicExponent: new Uint8Array([
10525
+ 1,
10526
+ 0,
10527
+ 1
10528
+ ]),
10529
+ hash: "SHA-256"
10530
+ }, false, ["sign", "verify"]);
10531
+ this._publicJwk = await crypto.subtle.exportKey("jwk", this._keyPair.publicKey);
10532
+ this._fingerprint = await computeJwkThumbprint(this._publicJwk);
10533
+ this._initialized = true;
10534
+ logger$20.debug("[DPoP] Key pair generated, fingerprint computed");
10535
+ return this._fingerprint;
10536
+ }
10537
+ /**
10538
+ * The JWK Thumbprint (RFC 7638) of the public key.
10539
+ * Used as the `fingerprint` parameter when requesting scoped SATs.
10540
+ *
10541
+ * @throws {DPoPInitError} If {@link init} has not been called.
10542
+ */
10543
+ get fingerprint() {
10544
+ if (!this._fingerprint) throw new DPoPInitError("CryptoController not initialized. Call init() first.");
10545
+ return this._fingerprint;
10546
+ }
10547
+ /**
10548
+ * Whether the controller has been initialized with a key pair.
10549
+ */
10550
+ get initialized() {
10551
+ return this._initialized;
10552
+ }
10553
+ /**
10554
+ * Creates a DPoP proof JWT for an HTTP API request.
10555
+ *
10556
+ * Used for Prime API endpoints like `/api/fabric/subscriber/devices/token`
10557
+ * and `/api/fabric/subscriber/devices/refresh`.
10558
+ *
10559
+ * @param params - HTTP method and URI for the proof.
10560
+ * @returns Signed DPoP proof JWT string.
10561
+ */
10562
+ async createHttpProof(params) {
10563
+ const payload = {
10564
+ jti: crypto.randomUUID(),
10565
+ htm: params.method,
10566
+ htu: params.uri,
10567
+ iat: Math.floor(Date.now() / 1e3)
10568
+ };
10569
+ if (params.accessToken) payload.ath = base64url(await crypto.subtle.digest("SHA-256", new TextEncoder().encode(params.accessToken)));
10570
+ return this.signProof(payload);
10571
+ }
10572
+ /**
10573
+ * Creates a DPoP proof JWT for a WebSocket RPC call.
10574
+ *
10575
+ * Used for switchblade RPC methods like `signalwire.connect` and
10576
+ * `signalwire.reauthenticate`.
10577
+ *
10578
+ * @param params - RPC method name for the proof.
10579
+ * @returns Signed DPoP proof JWT string.
10580
+ */
10581
+ async createRpcProof(params) {
10582
+ const payload = {
10583
+ jti: crypto.randomUUID(),
10584
+ rpc: "request",
10585
+ mth: params.method,
10586
+ iat: Math.floor(Date.now() / 1e3)
10587
+ };
10588
+ return this.signProof(payload);
10589
+ }
10590
+ /**
10591
+ * Releases the key pair references.
10592
+ * After calling destroy, the controller must be re-initialized to be used again.
10593
+ */
10594
+ destroy() {
10595
+ this._keyPair = null;
10596
+ this._publicJwk = null;
10597
+ this._fingerprint = null;
10598
+ this._initialized = false;
10599
+ logger$20.debug("[DPoP] Controller destroyed");
10600
+ }
10601
+ get publicJwk() {
10602
+ if (!this._publicJwk) throw new DPoPInitError("CryptoController not initialized. Call init() first.");
10603
+ return this._publicJwk;
10604
+ }
10605
+ get privateKey() {
10606
+ if (!this._keyPair) throw new DPoPInitError("CryptoController not initialized. Call init() first.");
10607
+ return this._keyPair.privateKey;
10608
+ }
10609
+ async signProof(payload) {
10610
+ const header = {
10611
+ typ: "dpop+jwt",
10612
+ alg: "RS256",
10613
+ jwk: this.publicJwk
10614
+ };
10615
+ const signingInput = `${base64urlEncode(JSON.stringify(header))}.${base64urlEncode(JSON.stringify(payload))}`;
10616
+ return `${signingInput}.${base64url(await crypto.subtle.sign("RSASSA-PKCS1-v1_5", this.privateKey, new TextEncoder().encode(signingInput)))}`;
10375
10617
  }
10376
10618
  };
10377
10619
 
10378
10620
  //#endregion
10379
10621
  //#region src/behaviors/Fetchable.ts
10380
- var import_cjs$19 = require_cjs();
10622
+ var import_cjs$20 = require_cjs();
10381
10623
  var Fetchable = class extends Destroyable {
10382
10624
  constructor(fromPath, http) {
10383
10625
  super();
10384
10626
  this.fromPath = fromPath;
10385
10627
  this.http = http;
10386
- 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$));
10628
+ 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$));
10387
10629
  }
10388
10630
  async fetch() {
10389
10631
  const response = await this.http.request({
@@ -10429,6 +10671,7 @@ var Subscriber = class extends Fetchable {
10429
10671
  scopes: data.app_settings.scopes
10430
10672
  } : void 0;
10431
10673
  this.addresses = data.fabric_addresses;
10674
+ this.satClaims = data.sat_claims;
10432
10675
  }
10433
10676
  };
10434
10677
 
@@ -10514,10 +10757,14 @@ const RPCConnect = (params) => {
10514
10757
 
10515
10758
  //#endregion
10516
10759
  //#region src/core/RPCMessages/RPCReauthenticate.ts
10517
- const RPCReauthenticate = (authentication) => {
10760
+ const RPCReauthenticate = (params) => {
10761
+ const { dpop_token, ...authFields } = params;
10518
10762
  return buildRPCRequest({
10519
10763
  method: "signalwire.reauthenticate",
10520
- params: { authentication }
10764
+ params: {
10765
+ authentication: authFields,
10766
+ ...dpop_token ? { dpop_token } : {}
10767
+ }
10521
10768
  });
10522
10769
  };
10523
10770
 
@@ -10613,7 +10860,7 @@ const RPCEventAckResponse = (id) => makeRPCResponse({
10613
10860
 
10614
10861
  //#endregion
10615
10862
  //#region src/managers/AttachManager.ts
10616
- const logger$18 = getLogger();
10863
+ const logger$19 = getLogger();
10617
10864
  var AttachManager = class {
10618
10865
  constructor(storage, deviceController, reconnectCallsTimeout, attachKey) {
10619
10866
  this.storage = storage;
@@ -10635,7 +10882,7 @@ var AttachManager = class {
10635
10882
  try {
10636
10883
  return await this.storage.getItem(this.attachKey) ?? {};
10637
10884
  } catch (error) {
10638
- logger$18.warn("[AttachManager] Failed to retrieve attached calls from storage", error);
10885
+ logger$19.warn("[AttachManager] Failed to retrieve attached calls from storage", error);
10639
10886
  return {};
10640
10887
  }
10641
10888
  }
@@ -10643,12 +10890,12 @@ var AttachManager = class {
10643
10890
  try {
10644
10891
  await this.storage.setItem(this.attachKey, attached);
10645
10892
  } catch (error) {
10646
- logger$18.warn("[AttachManager] Failed to write attached calls to storage", error);
10893
+ logger$19.warn("[AttachManager] Failed to write attached calls to storage", error);
10647
10894
  }
10648
10895
  }
10649
10896
  async attach(call) {
10650
10897
  if (!call.to) {
10651
- logger$18.warn("[AttachManager] Skip attach for calls with no destination");
10898
+ logger$19.warn("[AttachManager] Skip attach for calls with no destination");
10652
10899
  return;
10653
10900
  }
10654
10901
  const attachment = {
@@ -11571,7 +11818,7 @@ var require_operators = /* @__PURE__ */ __commonJSMin(((exports) => {
11571
11818
  //#endregion
11572
11819
  //#region src/operators/filterNull.ts
11573
11820
  var import_operators$1 = require_operators();
11574
- var import_cjs$18 = require_cjs();
11821
+ var import_cjs$19 = require_cjs();
11575
11822
  /**
11576
11823
  * RxJS operator that filters out `null` and `undefined` values with type narrowing.
11577
11824
  *
@@ -11583,7 +11830,7 @@ var import_cjs$18 = require_cjs();
11583
11830
  * ```
11584
11831
  */
11585
11832
  function filterNull() {
11586
- return (0, import_cjs$18.filter)((value) => value != null);
11833
+ return (0, import_cjs$19.filter)((value) => value != null);
11587
11834
  }
11588
11835
 
11589
11836
  //#endregion
@@ -11711,7 +11958,7 @@ function computeCapabilities(capabilities) {
11711
11958
 
11712
11959
  //#endregion
11713
11960
  //#region src/core/capabilities/SelfCapabilities.ts
11714
- var import_cjs$17 = require_cjs();
11961
+ var import_cjs$18 = require_cjs();
11715
11962
  /**
11716
11963
  * SelfCapabilities manages the capability state for the self participant.
11717
11964
  *
@@ -11747,7 +11994,7 @@ var SelfCapabilities = class extends Destroyable {
11747
11994
  }
11748
11995
  /** Observable for self member capabilities */
11749
11996
  get self$() {
11750
- return this.cachedObservable("self$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.self), (0, import_cjs$17.distinctUntilChanged)()));
11997
+ return this.cachedObservable("self$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.self), (0, import_cjs$18.distinctUntilChanged)()));
11751
11998
  }
11752
11999
  /** Current self member capabilities */
11753
12000
  get self() {
@@ -11755,7 +12002,7 @@ var SelfCapabilities = class extends Destroyable {
11755
12002
  }
11756
12003
  /** Observable for other member capabilities */
11757
12004
  get member$() {
11758
- return this.cachedObservable("member$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.member), (0, import_cjs$17.distinctUntilChanged)()));
12005
+ return this.cachedObservable("member$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.member), (0, import_cjs$18.distinctUntilChanged)()));
11759
12006
  }
11760
12007
  /** Current other member capabilities */
11761
12008
  get member() {
@@ -11763,7 +12010,7 @@ var SelfCapabilities = class extends Destroyable {
11763
12010
  }
11764
12011
  /** Observable for end call capability */
11765
12012
  get end$() {
11766
- return this.cachedObservable("end$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.end), (0, import_cjs$17.distinctUntilChanged)()));
12013
+ return this.cachedObservable("end$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.end), (0, import_cjs$18.distinctUntilChanged)()));
11767
12014
  }
11768
12015
  /** Current end call capability */
11769
12016
  get end() {
@@ -11771,7 +12018,7 @@ var SelfCapabilities = class extends Destroyable {
11771
12018
  }
11772
12019
  /** Observable for set layout capability */
11773
12020
  get setLayout$() {
11774
- return this.cachedObservable("setLayout$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.setLayout), (0, import_cjs$17.distinctUntilChanged)()));
12021
+ return this.cachedObservable("setLayout$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.setLayout), (0, import_cjs$18.distinctUntilChanged)()));
11775
12022
  }
11776
12023
  /** Current set layout capability */
11777
12024
  get setLayout() {
@@ -11779,7 +12026,7 @@ var SelfCapabilities = class extends Destroyable {
11779
12026
  }
11780
12027
  /** Observable for send digit capability */
11781
12028
  get sendDigit$() {
11782
- return this.cachedObservable("sendDigit$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.sendDigit), (0, import_cjs$17.distinctUntilChanged)()));
12029
+ return this.cachedObservable("sendDigit$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.sendDigit), (0, import_cjs$18.distinctUntilChanged)()));
11783
12030
  }
11784
12031
  /** Current send digit capability */
11785
12032
  get sendDigit() {
@@ -11787,7 +12034,7 @@ var SelfCapabilities = class extends Destroyable {
11787
12034
  }
11788
12035
  /** Observable for vmuted hide capability */
11789
12036
  get vmutedHide$() {
11790
- return this.cachedObservable("vmutedHide$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.vmutedHide), (0, import_cjs$17.distinctUntilChanged)()));
12037
+ return this.cachedObservable("vmutedHide$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.vmutedHide), (0, import_cjs$18.distinctUntilChanged)()));
11791
12038
  }
11792
12039
  /** Current vmuted hide capability */
11793
12040
  get vmutedHide() {
@@ -11795,7 +12042,7 @@ var SelfCapabilities = class extends Destroyable {
11795
12042
  }
11796
12043
  /** Observable for lock capability */
11797
12044
  get lock$() {
11798
- return this.cachedObservable("lock$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.lock), (0, import_cjs$17.distinctUntilChanged)()));
12045
+ return this.cachedObservable("lock$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.lock), (0, import_cjs$18.distinctUntilChanged)()));
11799
12046
  }
11800
12047
  /** Current lock capability */
11801
12048
  get lock() {
@@ -11803,7 +12050,7 @@ var SelfCapabilities = class extends Destroyable {
11803
12050
  }
11804
12051
  /** Observable for device capability */
11805
12052
  get device$() {
11806
- return this.cachedObservable("device$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.device), (0, import_cjs$17.distinctUntilChanged)()));
12053
+ return this.cachedObservable("device$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.device), (0, import_cjs$18.distinctUntilChanged)()));
11807
12054
  }
11808
12055
  /** Current device capability */
11809
12056
  get device() {
@@ -11811,7 +12058,7 @@ var SelfCapabilities = class extends Destroyable {
11811
12058
  }
11812
12059
  /** Observable for screenshare capability */
11813
12060
  get screenshare$() {
11814
- return this.cachedObservable("screenshare$", () => this._state$.pipe((0, import_cjs$17.map)((state) => state.screenshare), (0, import_cjs$17.distinctUntilChanged)()));
12061
+ return this.cachedObservable("screenshare$", () => this._state$.pipe((0, import_cjs$18.map)((state) => state.screenshare), (0, import_cjs$18.distinctUntilChanged)()));
11815
12062
  }
11816
12063
  /** Current screenshare capability */
11817
12064
  get screenshare() {
@@ -11838,7 +12085,7 @@ function toggleHandraiseMethod(is) {
11838
12085
 
11839
12086
  //#endregion
11840
12087
  //#region src/core/entities/Participant.ts
11841
- const logger$17 = getLogger();
12088
+ const logger$18 = getLogger();
11842
12089
  const initialState = {};
11843
12090
  /**
11844
12091
  * Represents a participant in a call.
@@ -12181,7 +12428,7 @@ var SelfParticipant = class extends Participant {
12181
12428
  try {
12182
12429
  await this.vertoManager.addScreenMedia();
12183
12430
  } catch (error) {
12184
- logger$17.error("[Participant.startScreenShare] Screen share error:", error);
12431
+ logger$18.error("[Participant.startScreenShare] Screen share error:", error);
12185
12432
  }
12186
12433
  }
12187
12434
  /** Observable of the current screen share status. */
@@ -12201,7 +12448,7 @@ var SelfParticipant = class extends Participant {
12201
12448
  try {
12202
12449
  await this.vertoManager.addInputDevice(options);
12203
12450
  } catch (error) {
12204
- logger$17.error("[Participant.startScreenShare] Screen share error:", error);
12451
+ logger$18.error("[Participant.startScreenShare] Screen share error:", error);
12205
12452
  }
12206
12453
  }
12207
12454
  /** Removes an additional media input device by ID. */
@@ -12262,7 +12509,7 @@ var SelfParticipant = class extends Participant {
12262
12509
  try {
12263
12510
  await super.mute();
12264
12511
  } catch (error) {
12265
- logger$17.warn("[Participant.toggleAudioInput] Server Error while muting audio input, proceeding with local toggle anyway", error);
12512
+ logger$18.warn("[Participant.toggleAudioInput] Server Error while muting audio input, proceeding with local toggle anyway", error);
12266
12513
  } finally {
12267
12514
  this.vertoManager.muteMainAudioInputDevice();
12268
12515
  }
@@ -12272,7 +12519,7 @@ var SelfParticipant = class extends Participant {
12272
12519
  try {
12273
12520
  await super.unmute();
12274
12521
  } catch (error) {
12275
- logger$17.warn("[Participant.toggleAudioInput] Server Error while unmuting audio input, proceeding with local toggle anyway", error);
12522
+ logger$18.warn("[Participant.toggleAudioInput] Server Error while unmuting audio input, proceeding with local toggle anyway", error);
12276
12523
  } finally {
12277
12524
  await this.vertoManager.unmuteMainAudioInputDevice();
12278
12525
  }
@@ -12282,7 +12529,7 @@ var SelfParticipant = class extends Participant {
12282
12529
  try {
12283
12530
  await super.muteVideo();
12284
12531
  } catch (error) {
12285
- logger$17.warn("[Participant.toggleVideoInput] Server Error while muting video input, proceeding with local toggle anyway", error);
12532
+ logger$18.warn("[Participant.toggleVideoInput] Server Error while muting video input, proceeding with local toggle anyway", error);
12286
12533
  } finally {
12287
12534
  this.vertoManager.muteMainVideoInputDevice();
12288
12535
  }
@@ -12292,7 +12539,7 @@ var SelfParticipant = class extends Participant {
12292
12539
  try {
12293
12540
  await super.unmuteVideo();
12294
12541
  } catch (error) {
12295
- logger$17.warn("[Participant.toggleVideoInput] Server Error while unmuting video input, proceeding with local toggle anyway", error);
12542
+ logger$18.warn("[Participant.toggleVideoInput] Server Error while unmuting video input, proceeding with local toggle anyway", error);
12296
12543
  } finally {
12297
12544
  await this.vertoManager.unmuteMainVideoInputDevice();
12298
12545
  }
@@ -12323,6 +12570,7 @@ function isJSONRPCErrorResponse(value) {
12323
12570
 
12324
12571
  //#endregion
12325
12572
  //#region src/core/RPCMessages/guards/events.guards.ts
12573
+ /** @internal @packageDocumentation */
12326
12574
  /**
12327
12575
  * Factory function to create Request-level type guards.
12328
12576
  */
@@ -12346,6 +12594,7 @@ const isCallUpdatedRequest = createEventRequestGuard("call.updated");
12346
12594
  const isCallStateRequest = createEventRequestGuard("call.state");
12347
12595
  const isCallPlayRequest = createEventRequestGuard("call.play");
12348
12596
  const isCallConnectRequest = createEventRequestGuard("call.connect");
12597
+ const isRoomUpdatedRequest = createEventRequestGuard("room.updated");
12349
12598
  const isMemberUpdatedRequest = createEventRequestGuard("member.updated");
12350
12599
  const isMemberJoinedRequest = createEventRequestGuard("member.joined");
12351
12600
  const isMemberLeftRequest = createEventRequestGuard("member.left");
@@ -12357,7 +12606,7 @@ function isSignalwireMetadata(value) {
12357
12606
  return isObject(value) && hasProperty(value, "event_type") && typeof value.event_type === "string" && hasProperty(value, "params");
12358
12607
  }
12359
12608
  function isSignalwireCallMetadata(value) {
12360
- 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));
12609
+ 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));
12361
12610
  }
12362
12611
  const isSignalwireAuthorizationStateMetadata = createEventMetadataGuard("signalwire.authorization.state");
12363
12612
  const isWebrtcMessageMetadata = createEventMetadataGuard("webrtc.message");
@@ -12367,6 +12616,7 @@ const isCallUpdatedMetadata = createEventMetadataGuard("call.updated");
12367
12616
  const isCallStateMetadata = createEventMetadataGuard("call.state");
12368
12617
  const isCallPlayMetadata = createEventMetadataGuard("call.play");
12369
12618
  const isCallConnectMetadata = createEventMetadataGuard("call.connect");
12619
+ const isRoomUpdatedMetadata = createEventMetadataGuard("room.updated");
12370
12620
  const isMemberUpdatedMetadata = createEventMetadataGuard("member.updated");
12371
12621
  const isMemberJoinedMetadata = createEventMetadataGuard("member.joined");
12372
12622
  const isMemberLeftMetadata = createEventMetadataGuard("member.left");
@@ -12393,7 +12643,7 @@ const getValueFrom = (obj, path, defaultValue) => {
12393
12643
 
12394
12644
  //#endregion
12395
12645
  //#region src/operators/filterEventAs.ts
12396
- var import_cjs$16 = require_cjs();
12646
+ var import_cjs$17 = require_cjs();
12397
12647
  var import_operators = require_operators();
12398
12648
  /**
12399
12649
  * RxJS operator that filters events based on a predicate and maps matching events.
@@ -12427,7 +12677,7 @@ var import_operators = require_operators();
12427
12677
  * ```
12428
12678
  */
12429
12679
  function ifIsMap(predicate, mapFn) {
12430
- return (0, import_cjs$16.pipe)((0, import_operators.filter)(predicate), (0, import_operators.map)(mapFn));
12680
+ return (0, import_cjs$17.pipe)((0, import_operators.filter)(predicate), (0, import_operators.map)(mapFn));
12431
12681
  }
12432
12682
  /**
12433
12683
  * Generic RxJS operator that filters events using a type guard and extracts a property.
@@ -12469,39 +12719,40 @@ function ifIsMap(predicate, mapFn) {
12469
12719
  * ```
12470
12720
  */
12471
12721
  function filterAs(predicate, resultPath) {
12472
- return (0, import_cjs$16.pipe)(ifIsMap(predicate, (event) => {
12722
+ return (0, import_cjs$17.pipe)(ifIsMap(predicate, (event) => {
12473
12723
  return getValueFrom(event, resultPath);
12474
12724
  }), (0, import_operators.filter)((value) => value !== void 0));
12475
12725
  }
12476
12726
 
12477
12727
  //#endregion
12478
12728
  //#region src/operators/throwOnRPCError.ts
12479
- var import_cjs$15 = require_cjs();
12480
- const logger$16 = getLogger();
12729
+ var import_cjs$16 = require_cjs();
12730
+ const logger$17 = getLogger();
12481
12731
  /**
12482
12732
  * RxJS operator that throws a {@link JSONRPCError} when the RPC response contains an error.
12483
12733
  * Passes successful responses through unchanged.
12484
12734
  */
12485
12735
  function throwOnRPCError() {
12486
- return (0, import_cjs$15.map)((response) => {
12736
+ return (0, import_cjs$16.map)((response) => {
12487
12737
  if (response.error) {
12488
- logger$16.error("[throwOnRPCError] RPC error response:", {
12738
+ logger$17.error("[throwOnRPCError] RPC error response:", {
12489
12739
  code: response.error.code,
12490
12740
  message: response.error.message,
12491
12741
  data: response.error.data
12492
12742
  });
12493
12743
  throw new JSONRPCError(response.error.code, response.error.message, response.error.data);
12494
12744
  }
12495
- logger$16.debug("[throwOnRPCError] RPC successful response:", response);
12745
+ logger$17.debug("[throwOnRPCError] RPC successful response:", response);
12496
12746
  return response;
12497
12747
  });
12498
12748
  }
12499
12749
 
12500
12750
  //#endregion
12501
12751
  //#region src/managers/CallEventsManager.ts
12502
- var import_cjs$14 = require_cjs();
12503
- const logger$15 = getLogger();
12752
+ var import_cjs$15 = require_cjs();
12753
+ const logger$16 = getLogger();
12504
12754
  const initialSessionState = {};
12755
+ /** @internal */
12505
12756
  var CallEventsManager = class extends Destroyable {
12506
12757
  constructor(webRtcCallSession, options = {}) {
12507
12758
  super();
@@ -12515,7 +12766,7 @@ var CallEventsManager = class extends Destroyable {
12515
12766
  this.initSubscriptions();
12516
12767
  }
12517
12768
  get participants$() {
12518
- return this.cachedObservable("participants$", () => this._participants$.asObservable().pipe((0, import_cjs$14.map)((participantsRecord) => Object.values(participantsRecord))));
12769
+ return this.cachedObservable("participants$", () => this._participants$.asObservable().pipe((0, import_cjs$15.map)((participantsRecord) => Object.values(participantsRecord))));
12519
12770
  }
12520
12771
  get participants() {
12521
12772
  return Object.values(this._participants$.value);
@@ -12533,40 +12784,40 @@ var CallEventsManager = class extends Destroyable {
12533
12784
  return this.callIds.has(callId);
12534
12785
  }
12535
12786
  get recording$() {
12536
- return this.cachedObservable("recording$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.recording), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12787
+ return this.cachedObservable("recording$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.recording), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12537
12788
  }
12538
12789
  get recordings$() {
12539
- return this.cachedObservable("recordings$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.recordings), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12790
+ return this.cachedObservable("recordings$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.recordings), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12540
12791
  }
12541
12792
  get streaming$() {
12542
- return this.cachedObservable("streaming$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.streaming), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12793
+ return this.cachedObservable("streaming$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.streaming), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12543
12794
  }
12544
12795
  get streams$() {
12545
- return this.cachedObservable("streams$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.streams), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12796
+ return this.cachedObservable("streams$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.streams), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12546
12797
  }
12547
12798
  get playbacks$() {
12548
- return this.cachedObservable("playbacks$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.playbacks), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12799
+ return this.cachedObservable("playbacks$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.playbacks), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12549
12800
  }
12550
12801
  get raiseHandPriority$() {
12551
- return this.cachedObservable("raiseHandPriority$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.prioritize_handraise), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12802
+ return this.cachedObservable("raiseHandPriority$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.prioritize_handraise), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12552
12803
  }
12553
12804
  get locked$() {
12554
- return this.cachedObservable("locked$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.locked), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12805
+ return this.cachedObservable("locked$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.locked), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12555
12806
  }
12556
12807
  get meta$() {
12557
- return this.cachedObservable("meta$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.meta), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12808
+ return this.cachedObservable("meta$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.meta), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12558
12809
  }
12559
12810
  get capabilities$() {
12560
- return this.cachedObservable("capabilities$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.capabilities), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12811
+ return this.cachedObservable("capabilities$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.capabilities), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12561
12812
  }
12562
12813
  get layout$() {
12563
- return this.cachedObservable("layout$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.layout_name), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12814
+ return this.cachedObservable("layout$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.layout_name), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12564
12815
  }
12565
12816
  get layouts$() {
12566
- return this.cachedObservable("layouts$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.layouts), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12817
+ return this.cachedObservable("layouts$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.layouts), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12567
12818
  }
12568
12819
  get layoutLayers$() {
12569
- return this.cachedObservable("layoutLayers$", () => this._sessionState$.pipe((0, import_cjs$14.map)((state) => state.layout_layers), (0, import_cjs$14.distinctUntilChanged)(), filterNull()));
12820
+ return this.cachedObservable("layoutLayers$", () => this._sessionState$.pipe((0, import_cjs$15.map)((state) => state.layout_layers), (0, import_cjs$15.distinctUntilChanged)(), filterNull()));
12570
12821
  }
12571
12822
  get self() {
12572
12823
  return this._self$.value;
@@ -12603,7 +12854,7 @@ var CallEventsManager = class extends Destroyable {
12603
12854
  }
12604
12855
  initSubscriptions() {
12605
12856
  this.subscribeTo(this.callJoinedEvent$, (callJoinedEvent) => {
12606
- logger$15.debug("[CallEventsManager] Handling call.joined event for call/session IDs:", {
12857
+ logger$16.debug("[CallEventsManager] Handling call.joined event for call/session IDs:", {
12607
12858
  callId: callJoinedEvent.call_id,
12608
12859
  roomSessionId: callJoinedEvent.room_session_id
12609
12860
  });
@@ -12630,19 +12881,34 @@ var CallEventsManager = class extends Destroyable {
12630
12881
  if (this._self$.value?.capabilities.setLayout) this.updateLayouts();
12631
12882
  });
12632
12883
  this.subscribeTo(this.memberUpdates$, (member) => {
12633
- logger$15.debug("[CallEventsManager] Handling member update event for member ID:", member);
12884
+ logger$16.debug("[CallEventsManager] Handling member update event for member ID:", member);
12634
12885
  this.upsertParticipant(member);
12635
12886
  });
12636
12887
  this.subscribeTo(this.webRtcCallSession.memberLeft$, (memberLeftEvent) => {
12637
- logger$15.debug("[CallEventsManager] Handling member.left event for member ID:", memberLeftEvent.member.member_id);
12888
+ logger$16.debug("[CallEventsManager] Handling member.left event for member ID:", memberLeftEvent.member.member_id);
12638
12889
  const participants = { ...this._participants$.value };
12639
12890
  if (memberLeftEvent.member.member_id in participants) {
12640
12891
  delete participants[memberLeftEvent.member.member_id];
12641
12892
  this._participants$.next(participants);
12642
- } else logger$15.warn(`[CallEventsManager] Received member.left event for unknown member ID: ${memberLeftEvent.member.member_id}`);
12893
+ } else logger$16.warn(`[CallEventsManager] Received member.left event for unknown member ID: ${memberLeftEvent.member.member_id}`);
12894
+ });
12895
+ this.subscribeTo(this.webRtcCallSession.callUpdated$, (callUpdatedEvent) => {
12896
+ logger$16.debug("[CallEventsManager] Handling call.updated event:", callUpdatedEvent);
12897
+ const roomSession = callUpdatedEvent.room_session;
12898
+ this._sessionState$.next({
12899
+ ...this._sessionState$.value,
12900
+ recording: roomSession.recording,
12901
+ recordings: roomSession.recordings,
12902
+ streaming: roomSession.streaming,
12903
+ streams: roomSession.streams,
12904
+ playbacks: roomSession.playbacks,
12905
+ prioritize_handraise: roomSession.prioritize_handraise,
12906
+ locked: roomSession.locked,
12907
+ meta: roomSession.meta
12908
+ });
12643
12909
  });
12644
12910
  this.subscribeTo(this.layoutChangedEvent$, (layoutChangedEvent) => {
12645
- logger$15.debug("[CallEventsManager] Handling layout.changed event:", layoutChangedEvent);
12911
+ logger$16.debug("[CallEventsManager] Handling layout.changed event:", layoutChangedEvent);
12646
12912
  this._sessionState$.next({
12647
12913
  ...this._sessionState$.value,
12648
12914
  layout_name: layoutChangedEvent.id,
@@ -12652,7 +12918,7 @@ var CallEventsManager = class extends Destroyable {
12652
12918
  });
12653
12919
  }
12654
12920
  updateParticipantPositions(layoutChangedEvent) {
12655
- 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.");
12921
+ 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.");
12656
12922
  layoutChangedEvent.layers.filter((layer) => Boolean(layer.member_id)).map((layer) => {
12657
12923
  if (!layer.member_id) throw new DependencyError("Layer member_id is required");
12658
12924
  this._participants$.value[layer.member_id].upnext({ position: layer });
@@ -12673,7 +12939,7 @@ var CallEventsManager = class extends Destroyable {
12673
12939
  layouts: response.result.layouts
12674
12940
  });
12675
12941
  }).catch((error) => {
12676
- logger$15.error("[CallEventsManager] Error fetching layouts:", error);
12942
+ logger$16.error("[CallEventsManager] Error fetching layouts:", error);
12677
12943
  });
12678
12944
  }
12679
12945
  updateParticipants(members) {
@@ -12689,7 +12955,7 @@ var CallEventsManager = class extends Destroyable {
12689
12955
  }
12690
12956
  const participant = this._participants$.value[member.member_id];
12691
12957
  const oldValue = participant.value;
12692
- logger$15.debug("[CallEventsManager] Updating participant:", member.member_id, {
12958
+ logger$16.debug("[CallEventsManager] Updating participant:", member.member_id, {
12693
12959
  oldValue,
12694
12960
  newValue: member
12695
12961
  });
@@ -12701,18 +12967,18 @@ var CallEventsManager = class extends Destroyable {
12701
12967
  this._participants$.next(this._participants$.value);
12702
12968
  }
12703
12969
  get callJoinedEvent$() {
12704
- return this.cachedObservable("callJoinedEvent$", () => this.webRtcCallSession.callEvent$.pipe((0, import_cjs$14.filter)(isCallJoinedPayload), (0, import_cjs$14.tap)((event) => {
12705
- logger$15.debug("[CallEventsManager] Call joined event:", event);
12970
+ return this.cachedObservable("callJoinedEvent$", () => this.webRtcCallSession.callEvent$.pipe((0, import_cjs$15.filter)(isCallJoinedPayload), (0, import_cjs$15.tap)((event) => {
12971
+ logger$16.debug("[CallEventsManager] Call joined event:", event);
12706
12972
  })));
12707
12973
  }
12708
12974
  get layoutChangedEvent$() {
12709
- return this.cachedObservable("layoutChangedEvent$", () => this.webRtcCallSession.callEvent$.pipe(filterAs(isLayoutChangedPayload, "layout"), (0, import_cjs$14.tap)((event) => {
12710
- logger$15.debug("[CallEventsManager] Layout changed event:", event);
12975
+ return this.cachedObservable("layoutChangedEvent$", () => this.webRtcCallSession.callEvent$.pipe(filterAs(isLayoutChangedPayload, "layout"), (0, import_cjs$15.tap)((event) => {
12976
+ logger$16.debug("[CallEventsManager] Layout changed event:", event);
12711
12977
  })));
12712
12978
  }
12713
12979
  get memberUpdates$() {
12714
- 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) => {
12715
- logger$15.debug("[CallEventsManager] Member update event:", event);
12980
+ 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) => {
12981
+ logger$16.debug("[CallEventsManager] Member update event:", event);
12716
12982
  })));
12717
12983
  }
12718
12984
  destroy() {
@@ -12820,8 +13086,8 @@ function isValidLocalDescription(sdp) {
12820
13086
 
12821
13087
  //#endregion
12822
13088
  //#region src/controllers/ICEGatheringController.ts
12823
- var import_cjs$13 = require_cjs();
12824
- const logger$14 = getLogger();
13089
+ var import_cjs$14 = require_cjs();
13090
+ const logger$15 = getLogger();
12825
13091
  var ICEGatheringController = class extends Destroyable {
12826
13092
  constructor(peerConnection, peerConnectionControllerNegotiating$, options = {}) {
12827
13093
  super();
@@ -12829,23 +13095,23 @@ var ICEGatheringController = class extends Destroyable {
12829
13095
  this.peerConnectionControllerNegotiating$ = peerConnectionControllerNegotiating$;
12830
13096
  this.onicegatheringstatechangeHandler = () => {
12831
13097
  const { iceGatheringState } = this.peerConnection;
12832
- logger$14.debug(`[ICEGatheringController] ICE gathering state changed to: ${iceGatheringState}`);
13098
+ logger$15.debug(`[ICEGatheringController] ICE gathering state changed to: ${iceGatheringState}`);
12833
13099
  if (iceGatheringState === "gathering") this._iceCandidatesState.next({
12834
13100
  state: "gathering",
12835
13101
  validSDP: false
12836
13102
  });
12837
13103
  };
12838
13104
  this.onicecandidateHandler = (event) => {
12839
- logger$14.debug("[ICEGatheringController] ICE candidate event received:", event.candidate);
13105
+ logger$15.debug("[ICEGatheringController] ICE candidate event received:", event.candidate);
12840
13106
  this.removeTimer("iceCandidateTimer");
12841
13107
  if (event.candidate) this.iceCandidateTimer = setTimeout(() => {
12842
13108
  if (this.peerConnection.iceGatheringState !== "complete") {
12843
- logger$14.warn("[ICEGatheringController] ICE candidate timeout, using current SDP");
13109
+ logger$15.warn("[ICEGatheringController] ICE candidate timeout, using current SDP");
12844
13110
  this.handleICECandidateTimeout();
12845
13111
  }
12846
13112
  }, this.iceCandidateTimeout);
12847
13113
  else {
12848
- logger$14.debug("[ICEGatheringController] ICE gathering completed: null candidate received");
13114
+ logger$15.debug("[ICEGatheringController] ICE gathering completed: null candidate received");
12849
13115
  this.removeTimer("iceGatheringTimer");
12850
13116
  this.handleICEGatheringComplete();
12851
13117
  }
@@ -12858,12 +13124,12 @@ var ICEGatheringController = class extends Destroyable {
12858
13124
  this.iceGatheringTimeout = options.iceGatheringTimeout ?? DEFAULT_ICE_GATHERING_TIMEOUT_MS;
12859
13125
  this.relayOnly = options.relayOnly ?? false;
12860
13126
  this.setupEventListeners();
12861
- this.subscribeTo(this.peerConnectionControllerNegotiating$.pipe((0, import_cjs$13.filter)((isNegotiating) => isNegotiating)), (isNegotiating) => {
13127
+ this.subscribeTo(this.peerConnectionControllerNegotiating$.pipe((0, import_cjs$14.filter)((isNegotiating) => isNegotiating)), (isNegotiating) => {
12862
13128
  if (isNegotiating) {
12863
13129
  this.setupEventListeners();
12864
13130
  this.iceGatheringTimer = setTimeout(() => {
12865
13131
  if (this.peerConnection.iceGatheringState !== "complete") {
12866
- logger$14.warn("[ICEGatheringController] ICE gathering timeout, using current SDP");
13132
+ logger$15.warn("[ICEGatheringController] ICE gathering timeout, using current SDP");
12867
13133
  this.handleICEGatheringTimeout();
12868
13134
  }
12869
13135
  }, this.iceGatheringTimeout);
@@ -12877,7 +13143,7 @@ var ICEGatheringController = class extends Destroyable {
12877
13143
  this.peerConnection.addEventListener("icegatheringstatechange", this.onicegatheringstatechangeHandler);
12878
13144
  }
12879
13145
  get iceCandidatesState$() {
12880
- 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));
13146
+ 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));
12881
13147
  }
12882
13148
  get hasValidLocalDescriptionSDP() {
12883
13149
  const sdp = this.peerConnection.localDescription?.sdp;
@@ -12890,9 +13156,9 @@ var ICEGatheringController = class extends Destroyable {
12890
13156
  this.relayOnly = value;
12891
13157
  }
12892
13158
  handleICEGatheringComplete() {
12893
- logger$14.debug("[ICEGatheringController] Handling ICE gathering complete");
12894
- logger$14.debug(`[ICEGatheringController] Checking ICE gathering state: ${this.peerConnection.iceGatheringState}`);
12895
- logger$14.debug("[ICEGatheringController] ICE gathering complete");
13159
+ logger$15.debug("[ICEGatheringController] Handling ICE gathering complete");
13160
+ logger$15.debug(`[ICEGatheringController] Checking ICE gathering state: ${this.peerConnection.iceGatheringState}`);
13161
+ logger$15.debug("[ICEGatheringController] ICE gathering complete");
12896
13162
  this._iceCandidatesState.next({
12897
13163
  state: "complete",
12898
13164
  validSDP: this.hasValidLocalDescriptionSDP
@@ -12908,21 +13174,21 @@ var ICEGatheringController = class extends Destroyable {
12908
13174
  this.removeTimer("iceGatheringTimer");
12909
13175
  const validSDP = this.hasValidLocalDescriptionSDP;
12910
13176
  if (validSDP) {
12911
- logger$14.debug("[ICEGatheringController] Local SDP is valid");
13177
+ logger$15.debug("[ICEGatheringController] Local SDP is valid");
12912
13178
  this._iceCandidatesState.next({
12913
13179
  state: "timeout",
12914
13180
  validSDP
12915
13181
  });
12916
13182
  this.stopGathering();
12917
- } else logger$14.debug("### ICE gathering timeout\n", this.peerConnection.localDescription?.sdp);
13183
+ } else logger$15.debug("### ICE gathering timeout\n", this.peerConnection.localDescription?.sdp);
12918
13184
  }
12919
13185
  handleICECandidateTimeout() {
12920
13186
  if (this.iceCandidateTimer) this.removeTimer("iceCandidateTimer");
12921
- logger$14.warn("[ICEGatheringController] ICE candidate timeout");
13187
+ logger$15.warn("[ICEGatheringController] ICE candidate timeout");
12922
13188
  const validSDP = this.hasValidLocalDescriptionSDP;
12923
13189
  if (!validSDP && !this.relayOnly) this.restartICEGatheringWithRelayOnly();
12924
13190
  else {
12925
- logger$14.debug("[ICEGatheringController] Using current SDP due to ICE candidate timeout");
13191
+ logger$15.debug("[ICEGatheringController] Using current SDP due to ICE candidate timeout");
12926
13192
  this._iceCandidatesState.next({
12927
13193
  state: "timeout",
12928
13194
  validSDP
@@ -12931,7 +13197,7 @@ var ICEGatheringController = class extends Destroyable {
12931
13197
  }
12932
13198
  }
12933
13199
  restartICEGatheringWithRelayOnly() {
12934
- logger$14.debug("[ICEGatheringController] Restarting ICE gathering with relay-only candidates");
13200
+ logger$15.debug("[ICEGatheringController] Restarting ICE gathering with relay-only candidates");
12935
13201
  this.relayOnly = true;
12936
13202
  this.peerConnection.setConfiguration({
12937
13203
  ...this.peerConnection.getConfiguration(),
@@ -12939,14 +13205,14 @@ var ICEGatheringController = class extends Destroyable {
12939
13205
  });
12940
13206
  if (!(this.peerConnection.connectionState === "connected")) this.peerConnection.restartIce();
12941
13207
  }
12942
- removeTimer(timer$1) {
12943
- if (this[timer$1]) {
12944
- clearTimeout(this[timer$1]);
12945
- this[timer$1] = void 0;
13208
+ removeTimer(timer$2) {
13209
+ if (this[timer$2]) {
13210
+ clearTimeout(this[timer$2]);
13211
+ this[timer$2] = void 0;
12946
13212
  }
12947
13213
  }
12948
13214
  clearAllTimers() {
12949
- logger$14.debug("[ICEGatheringController] Clearing all timers");
13215
+ logger$15.debug("[ICEGatheringController] Clearing all timers");
12950
13216
  this.removeTimer("iceGatheringTimer");
12951
13217
  this.removeTimer("iceCandidateTimer");
12952
13218
  }
@@ -12955,7 +13221,7 @@ var ICEGatheringController = class extends Destroyable {
12955
13221
  this.peerConnection.removeEventListener("icecandidate", this.onicecandidateHandler);
12956
13222
  }
12957
13223
  destroy() {
12958
- logger$14.debug("[ICEGatheringController] Destroying ICEGatheringController");
13224
+ logger$15.debug("[ICEGatheringController] Destroying ICEGatheringController");
12959
13225
  this.clearAllTimers();
12960
13226
  this.removeEventListeners();
12961
13227
  super.destroy();
@@ -12964,8 +13230,8 @@ var ICEGatheringController = class extends Destroyable {
12964
13230
 
12965
13231
  //#endregion
12966
13232
  //#region src/controllers/LocalStreamController.ts
12967
- var import_cjs$12 = require_cjs();
12968
- const logger$13 = getLogger();
13233
+ var import_cjs$13 = require_cjs();
13234
+ const logger$14 = getLogger();
12969
13235
  var LocalStreamController = class extends Destroyable {
12970
13236
  constructor(options) {
12971
13237
  super();
@@ -12979,16 +13245,16 @@ var LocalStreamController = class extends Destroyable {
12979
13245
  this._mediaTrackEnded$ = this.createSubject();
12980
13246
  }
12981
13247
  get localStream$() {
12982
- return this._localStream$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13248
+ return this._localStream$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12983
13249
  }
12984
13250
  get localAudioTracks$() {
12985
- return this._localAudioTracks$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13251
+ return this._localAudioTracks$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12986
13252
  }
12987
13253
  get localVideoTracks$() {
12988
- return this._localVideoTracks$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13254
+ return this._localVideoTracks$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12989
13255
  }
12990
13256
  get mediaTrackEnded$() {
12991
- return this._mediaTrackEnded$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$));
13257
+ return this._mediaTrackEnded$.asObservable().pipe((0, import_cjs$13.takeUntil)(this.destroyed$));
12992
13258
  }
12993
13259
  get localStream() {
12994
13260
  return this._localStream$.value;
@@ -13003,26 +13269,26 @@ var LocalStreamController = class extends Destroyable {
13003
13269
  * Build the local media stream based on the provided options.
13004
13270
  */
13005
13271
  async buildLocalStream() {
13006
- logger$13.debug("[LocalStreamController] Building local media stream.");
13272
+ logger$14.debug("[LocalStreamController] Building local media stream.");
13007
13273
  let stream;
13008
13274
  if (this.options.inputAudioStream ?? this.options.inputVideoStream) {
13009
13275
  const tracks = [...this.options.inputAudioStream?.getTracks() ?? [], ...this.options.inputVideoStream?.getTracks() ?? []];
13010
13276
  stream = new MediaStream(tracks);
13011
13277
  } else if (this.options.propose === "screenshare") {
13012
- logger$13.debug("[LocalStreamController] Requesting display media for screen sharing with audio:", Boolean(this.options.inputAudioDeviceConstraints));
13278
+ logger$14.debug("[LocalStreamController] Requesting display media for screen sharing with audio:", Boolean(this.options.inputAudioDeviceConstraints));
13013
13279
  stream = await this.options.getDisplayMedia({
13014
13280
  video: true,
13015
13281
  audio: Boolean(this.options.inputAudioDeviceConstraints)
13016
13282
  });
13017
- logger$13.debug("[LocalStreamController] Screen share media obtained:", stream);
13283
+ logger$14.debug("[LocalStreamController] Screen share media obtained:", stream);
13018
13284
  } else {
13019
13285
  const constraints = {
13020
13286
  audio: this.options.inputAudioDeviceConstraints,
13021
13287
  video: this.options.inputVideoDeviceConstraints
13022
13288
  };
13023
- logger$13.debug("[LocalStreamController] Requesting user media with constraints:", constraints);
13289
+ logger$14.debug("[LocalStreamController] Requesting user media with constraints:", constraints);
13024
13290
  stream = await this.options.getUserMedia(constraints);
13025
- logger$13.debug("[LocalStreamController] User media obtained:", stream);
13291
+ logger$14.debug("[LocalStreamController] User media obtained:", stream);
13026
13292
  }
13027
13293
  this._localStream$.next(stream);
13028
13294
  return stream;
@@ -13039,7 +13305,7 @@ var LocalStreamController = class extends Destroyable {
13039
13305
  this._localStream$.next(localStream);
13040
13306
  if (track.kind === "video") this._localVideoTracks$.next(localStream.getVideoTracks());
13041
13307
  else this._localAudioTracks$.next(localStream.getAudioTracks());
13042
- logger$13.debug(`[LocalStreamController] ${track.kind} track added:`, track.id);
13308
+ logger$14.debug(`[LocalStreamController] ${track.kind} track added:`, track.id);
13043
13309
  return localStream;
13044
13310
  }
13045
13311
  /**
@@ -13051,7 +13317,7 @@ var LocalStreamController = class extends Destroyable {
13051
13317
  const stream = this._localStream$.value;
13052
13318
  const track = stream?.getTracks().find((t) => t.id === trackId);
13053
13319
  if (!track) {
13054
- logger$13.debug(`[LocalStreamController] track not found: ${trackId}`);
13320
+ logger$14.debug(`[LocalStreamController] track not found: ${trackId}`);
13055
13321
  return;
13056
13322
  }
13057
13323
  track.removeEventListener("ended", this.mediaTrackEndedHandler);
@@ -13060,7 +13326,7 @@ var LocalStreamController = class extends Destroyable {
13060
13326
  this._localStream$.next(stream);
13061
13327
  if (track.kind === "video") this._localVideoTracks$.next(stream?.getVideoTracks() ?? []);
13062
13328
  else this._localAudioTracks$.next(stream?.getAudioTracks() ?? []);
13063
- logger$13.debug(`[LocalStreamController] ${track.kind} track removed:`, trackId);
13329
+ logger$14.debug(`[LocalStreamController] ${track.kind} track removed:`, trackId);
13064
13330
  return track;
13065
13331
  }
13066
13332
  /**
@@ -13095,7 +13361,7 @@ var LocalStreamController = class extends Destroyable {
13095
13361
  */
13096
13362
  stopAllTracks() {
13097
13363
  this._localStream$.value?.getTracks().forEach((track) => {
13098
- logger$13.debug(`[LocalStreamController] Stopping local track: ${track.kind}`);
13364
+ logger$14.debug(`[LocalStreamController] Stopping local track: ${track.kind}`);
13099
13365
  track.removeEventListener("ended", this.mediaTrackEndedHandler);
13100
13366
  track.stop();
13101
13367
  });
@@ -13111,7 +13377,7 @@ var LocalStreamController = class extends Destroyable {
13111
13377
 
13112
13378
  //#endregion
13113
13379
  //#region src/controllers/TransceiverController.ts
13114
- const logger$12 = getLogger();
13380
+ const logger$13 = getLogger();
13115
13381
  const getDirection = (send, recv) => {
13116
13382
  if (send && recv) return "sendrecv";
13117
13383
  else if (send && !recv) return "sendonly";
@@ -13213,7 +13479,7 @@ var TransceiverController = class extends Destroyable {
13213
13479
  sendEncodings: isAudio ? void 0 : this.sendEncodings,
13214
13480
  streams: direction === "recvonly" ? void 0 : [localStream]
13215
13481
  };
13216
- logger$12.debug(`[TransceiverController] Setting up transceiver sender for local ${track.kind} track:`, {
13482
+ logger$13.debug(`[TransceiverController] Setting up transceiver sender for local ${track.kind} track:`, {
13217
13483
  transceiver,
13218
13484
  transceiverParams
13219
13485
  });
@@ -13221,11 +13487,11 @@ var TransceiverController = class extends Destroyable {
13221
13487
  await transceiver.sender.replaceTrack(track);
13222
13488
  transceiver.direction = transceiverParams.direction;
13223
13489
  if (transceiverParams.streams?.some((stream) => Boolean(stream))) {
13224
- logger$12.debug(`[TransceiverController] Setting streams for transceiver sender for local ${track.kind} track:`, transceiverParams.streams);
13490
+ logger$13.debug(`[TransceiverController] Setting streams for transceiver sender for local ${track.kind} track:`, transceiverParams.streams);
13225
13491
  transceiver.sender.setStreams(...transceiverParams.streams);
13226
13492
  }
13227
13493
  } else {
13228
- logger$12.debug(`[TransceiverController] Adding new transceiver for local ${track.kind} track:`, track.id);
13494
+ logger$13.debug(`[TransceiverController] Adding new transceiver for local ${track.kind} track:`, track.id);
13229
13495
  this.peerConnection.addTransceiver(track, transceiverParams);
13230
13496
  }
13231
13497
  }
@@ -13239,13 +13505,13 @@ var TransceiverController = class extends Destroyable {
13239
13505
  if (options.updateTransceiverDirection) transceiver.direction = "inactive";
13240
13506
  }
13241
13507
  } catch (error) {
13242
- logger$12.error("[TransceiverController] stopTrackSender error", kind, error);
13508
+ logger$13.error("[TransceiverController] stopTrackSender error", kind, error);
13243
13509
  this.options.onError?.(new MediaTrackError("stopTrackSender", kind, error));
13244
13510
  }
13245
13511
  }
13246
13512
  async restoreTrackSender(kind) {
13247
13513
  try {
13248
- logger$12.debug("[TransceiverController] restoreTrackSender called", kind);
13514
+ logger$13.debug("[TransceiverController] restoreTrackSender called", kind);
13249
13515
  const constraints = {};
13250
13516
  const transceivers = this.transceiverByKind(kind);
13251
13517
  for (const transceiver of transceivers) {
@@ -13255,23 +13521,23 @@ var TransceiverController = class extends Destroyable {
13255
13521
  if (trackKind === "audio" || trackKind === "video") constraints[trackKind] = this.getConstraintsFor(trackKind);
13256
13522
  }
13257
13523
  }
13258
- logger$12.debug("[TransceiverController] restoreTrackSender constraints:", constraints);
13524
+ logger$13.debug("[TransceiverController] restoreTrackSender constraints:", constraints);
13259
13525
  if (Object.keys(constraints).length === 0) {
13260
- logger$12.warn("[TransceiverController] restoreTrackSender: no tracks need restoration", kind);
13526
+ logger$13.warn("[TransceiverController] restoreTrackSender: no tracks need restoration", kind);
13261
13527
  return;
13262
13528
  }
13263
13529
  const newTracks = (await this.options.getUserMedia(constraints)).getTracks();
13264
- logger$12.debug("[TransceiverController] restoreTrackSender new tracks:", newTracks);
13530
+ logger$13.debug("[TransceiverController] restoreTrackSender new tracks:", newTracks);
13265
13531
  for (const newTrack of newTracks) {
13266
13532
  this.options.localStreamController.addTrack(newTrack);
13267
13533
  const trackKind = newTrack.kind;
13268
13534
  const transceiverOfKind = this.transceiverByKind(trackKind)[0];
13269
13535
  transceiverOfKind.direction = trackKind === "audio" ? this.audioDirection : this.videoDirection;
13270
- logger$12.debug("[TransceiverController] restoreTrackSender setting direction for", trackKind, transceiverOfKind.direction);
13536
+ logger$13.debug("[TransceiverController] restoreTrackSender setting direction for", trackKind, transceiverOfKind.direction);
13271
13537
  await transceiverOfKind.sender.replaceTrack(newTrack);
13272
13538
  }
13273
13539
  } catch (error) {
13274
- logger$12.error("[TransceiverController] restoreTrackSender error", kind, error);
13540
+ logger$13.error("[TransceiverController] restoreTrackSender error", kind, error);
13275
13541
  this.options.onError?.(new MediaTrackError("restoreTrackSender", kind, error));
13276
13542
  }
13277
13543
  }
@@ -13312,10 +13578,10 @@ var TransceiverController = class extends Destroyable {
13312
13578
  };
13313
13579
  try {
13314
13580
  await track.applyConstraints(constraintsToApply);
13315
- logger$12.debug(`[TransceiverController] Updated ${kind} sender constraints:`, constraintsToApply);
13316
- logger$12.debug(`[TransceiverController] Updated ${kind} sender constraints:`, track.getConstraints());
13581
+ logger$13.debug(`[TransceiverController] Updated ${kind} sender constraints:`, constraintsToApply);
13582
+ logger$13.debug(`[TransceiverController] Updated ${kind} sender constraints:`, track.getConstraints());
13317
13583
  } catch (error) {
13318
- logger$12.warn(`[TransceiverController] Failed to apply constraints to ${kind} track ${track.id}:`, error);
13584
+ logger$13.warn(`[TransceiverController] Failed to apply constraints to ${kind} track ${track.id}:`, error);
13319
13585
  this.options.onError?.(new MediaTrackError("updateSendersConstraints", kind, error));
13320
13586
  }
13321
13587
  }
@@ -13349,60 +13615,60 @@ var TransceiverController = class extends Destroyable {
13349
13615
 
13350
13616
  //#endregion
13351
13617
  //#region src/controllers/RTCPeerConnectionController.ts
13352
- var import_cjs$11 = require_cjs();
13353
- const logger$11 = getLogger();
13618
+ var import_cjs$12 = require_cjs();
13619
+ const logger$12 = getLogger();
13354
13620
  var RTCPeerConnectionController = class extends Destroyable {
13355
13621
  constructor(options = {}, remoteSessionDescription, deviceController) {
13356
13622
  super();
13357
13623
  this.options = options;
13358
13624
  this.firstSDPExchangeCompleted = false;
13359
13625
  this.negotiationNeeded$ = this.createSubject();
13360
- 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)(() => {
13626
+ 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)(() => {
13361
13627
  this.negotiationEnded();
13362
- }), (0, import_cjs$11.filter)(() => this.shouldEmitLocalDescription), (0, import_cjs$11.map)(() => this.peerConnection?.localDescription), filterNull(), (0, import_cjs$11.tap)((desc) => {
13628
+ }), (0, import_cjs$12.filter)(() => this.shouldEmitLocalDescription), (0, import_cjs$12.map)(() => this.peerConnection?.localDescription), filterNull(), (0, import_cjs$12.tap)((desc) => {
13363
13629
  if (desc.type === "answer") this._type = "offer";
13364
- }))), (0, import_cjs$11.shareReplay)(1), (0, import_cjs$11.takeUntil)(this.destroyed$));
13630
+ }))), (0, import_cjs$12.shareReplay)(1), (0, import_cjs$12.takeUntil)(this.destroyed$));
13365
13631
  this.connectionTimeout = 3e3;
13366
13632
  this.oniceconnectionstatechangeHandler = () => {
13367
13633
  if (this.peerConnection) {
13368
13634
  const { iceConnectionState } = this.peerConnection;
13369
- logger$11.debug(`[RTCPeerConnectionController] ICE connection state changed to: ${iceConnectionState}`);
13635
+ logger$12.debug(`[RTCPeerConnectionController] ICE connection state changed to: ${iceConnectionState}`);
13370
13636
  this._iceConnectionState$.next(this.peerConnection.iceConnectionState);
13371
13637
  }
13372
13638
  };
13373
13639
  this.onconnectionstatechangeHandler = () => {
13374
13640
  if (this.peerConnection) {
13375
13641
  const { connectionState } = this.peerConnection;
13376
- logger$11.debug(`[RTCPeerConnectionController] Connection state changed to: ${connectionState}`);
13642
+ logger$12.debug(`[RTCPeerConnectionController] Connection state changed to: ${connectionState}`);
13377
13643
  if (connectionState === "connected") this.removeConnectionTimer();
13378
13644
  this._connectionState$.next(this.peerConnection.connectionState);
13379
13645
  }
13380
13646
  };
13381
13647
  this.onsignalingstatechangeHandler = () => {
13382
- logger$11.debug(`[RTCPeerConnectionController] Signaling state changed to: ${this.peerConnection?.signalingState}`);
13648
+ logger$12.debug(`[RTCPeerConnectionController] Signaling state changed to: ${this.peerConnection?.signalingState}`);
13383
13649
  };
13384
13650
  this.onicegatheringstatechangeHandler = () => {
13385
13651
  if (this.peerConnection) this._iceGatheringState$.next(this.peerConnection.iceGatheringState);
13386
13652
  };
13387
13653
  this.onnegotiationneededHandler = (event) => {
13388
- logger$11.debug("[RTCPeerConnectionController] Negotiation needed event received.", event);
13654
+ logger$12.debug("[RTCPeerConnectionController] Negotiation needed event received.", event);
13389
13655
  this.negotiationNeeded$.next();
13390
13656
  };
13391
13657
  this.updateSelectedInputDevice = async (kind, deviceInfo) => {
13392
13658
  try {
13393
13659
  const { localStream } = this;
13394
13660
  if (!localStream) {
13395
- logger$11.warn("[RTCPeerConnectionController] No local stream available to update input device.");
13661
+ logger$12.warn("[RTCPeerConnectionController] No local stream available to update input device.");
13396
13662
  return;
13397
13663
  }
13398
- logger$11.debug(`[RTCPeerConnectionController] Updating selected ${kind} input device:`, localStream.getTracks());
13664
+ logger$12.debug(`[RTCPeerConnectionController] Updating selected ${kind} input device:`, localStream.getTracks());
13399
13665
  const track = localStream.getTracks().find((track$1) => track$1.kind === kind);
13400
13666
  if (track) {
13401
13667
  this.transceiverController?.stopTrackSender(kind);
13402
13668
  this.localStream?.removeTrack(track);
13403
- logger$11.debug(`[RTCPeerConnectionController] Stopped existing ${kind} track: ${track.id}`, localStream.getTracks());
13669
+ logger$12.debug(`[RTCPeerConnectionController] Stopped existing ${kind} track: ${track.id}`, localStream.getTracks());
13404
13670
  if (!deviceInfo) {
13405
- logger$11.debug(`[RTCPeerConnectionController] ${kind} input device selected: none`);
13671
+ logger$12.debug(`[RTCPeerConnectionController] ${kind} input device selected: none`);
13406
13672
  return;
13407
13673
  }
13408
13674
  const streamTrack = (await this.getUserMedia({ [kind]: {
@@ -13410,15 +13676,15 @@ var RTCPeerConnectionController = class extends Destroyable {
13410
13676
  ...this.deviceController.deviceInfoToConstraints(deviceInfo)
13411
13677
  } })).getTracks().find((t) => t.kind === kind);
13412
13678
  if (streamTrack) {
13413
- logger$11.debug(`[RTCPeerConnectionController] Adding new ${kind} track: ${streamTrack.id}`);
13679
+ logger$12.debug(`[RTCPeerConnectionController] Adding new ${kind} track: ${streamTrack.id}`);
13414
13680
  this.localStream?.addTrack(streamTrack);
13415
13681
  await this.transceiverController?.replaceSenderTrack(kind, streamTrack);
13416
- logger$11.debug(`[RTCPeerConnectionController] Added new ${kind} track: ${streamTrack.id}`, this.localStream?.getTracks());
13682
+ logger$12.debug(`[RTCPeerConnectionController] Added new ${kind} track: ${streamTrack.id}`, this.localStream?.getTracks());
13417
13683
  }
13418
13684
  }
13419
- logger$11.debug(`[RTCPeerConnectionController] ${kind} input device selected:`, deviceInfo?.label);
13685
+ logger$12.debug(`[RTCPeerConnectionController] ${kind} input device selected:`, deviceInfo?.label);
13420
13686
  } catch (error) {
13421
- logger$11.error(`[RTCPeerConnectionController] Failed to select ${kind} input device:`, error);
13687
+ logger$12.error(`[RTCPeerConnectionController] Failed to select ${kind} input device:`, error);
13422
13688
  this._errors$.next(error);
13423
13689
  throw error;
13424
13690
  }
@@ -13504,43 +13770,43 @@ var RTCPeerConnectionController = class extends Destroyable {
13504
13770
  };
13505
13771
  }
13506
13772
  get iceGatheringState$() {
13507
- return this.cachedObservable("iceGatheringState$", () => this._iceGatheringState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13773
+ return this.cachedObservable("iceGatheringState$", () => this._iceGatheringState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13508
13774
  }
13509
13775
  get mediaTrackEnded$() {
13510
- return this.cachedObservable("mediaTrackEnded$", () => this.localStreamController.mediaTrackEnded$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13776
+ return this.cachedObservable("mediaTrackEnded$", () => this.localStreamController.mediaTrackEnded$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13511
13777
  }
13512
13778
  get errors$() {
13513
- return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13779
+ return this.cachedObservable("errors$", () => this._errors$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13514
13780
  }
13515
13781
  get iceCandidates$() {
13516
- return this.cachedObservable("iceCandidates$", () => this._iceCandidates$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13782
+ return this.cachedObservable("iceCandidates$", () => this._iceCandidates$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13517
13783
  }
13518
13784
  get initialized$() {
13519
- return this.cachedObservable("initialized$", () => this._initialized$.asObservable().pipe((0, import_cjs$11.filter)((initialized) => initialized), (0, import_cjs$11.takeUntil)(this.destroyed$)));
13785
+ return this.cachedObservable("initialized$", () => this._initialized$.asObservable().pipe((0, import_cjs$12.filter)((initialized) => initialized), (0, import_cjs$12.takeUntil)(this.destroyed$)));
13520
13786
  }
13521
13787
  get remoteDescription$() {
13522
- return this.cachedObservable("remoteDescription$", () => this._remoteDescription$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13788
+ return this.cachedObservable("remoteDescription$", () => this._remoteDescription$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13523
13789
  }
13524
13790
  get localStream$() {
13525
- return this.cachedObservable("localStream$", () => this.localStreamController.localStream$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13791
+ return this.cachedObservable("localStream$", () => this.localStreamController.localStream$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13526
13792
  }
13527
13793
  get remoteStream$() {
13528
- return this.cachedObservable("remoteStream$", () => this._remoteStream$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13794
+ return this.cachedObservable("remoteStream$", () => this._remoteStream$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13529
13795
  }
13530
13796
  get localAudioTracks$() {
13531
- return this.cachedObservable("localAudioTracks$", () => this.localStreamController.localAudioTracks$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13797
+ return this.cachedObservable("localAudioTracks$", () => this.localStreamController.localAudioTracks$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13532
13798
  }
13533
13799
  get localVideoTracks$() {
13534
- return this.cachedObservable("localVideoTracks$", () => this.localStreamController.localVideoTracks$.pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13800
+ return this.cachedObservable("localVideoTracks$", () => this.localStreamController.localVideoTracks$.pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13535
13801
  }
13536
13802
  get iceConnectionState$() {
13537
- return this.cachedObservable("iceConnectionState$", () => this._iceConnectionState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13803
+ return this.cachedObservable("iceConnectionState$", () => this._iceConnectionState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13538
13804
  }
13539
13805
  get connectionState$() {
13540
- return this.cachedObservable("connectionState$", () => this._connectionState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13806
+ return this.cachedObservable("connectionState$", () => this._connectionState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13541
13807
  }
13542
13808
  get signalingState$() {
13543
- return this.cachedObservable("signalingState$", () => this._signalingState$.asObservable().pipe((0, import_cjs$11.takeUntil)(this.destroyed$)));
13809
+ return this.cachedObservable("signalingState$", () => this._signalingState$.asObservable().pipe((0, import_cjs$12.takeUntil)(this.destroyed$)));
13544
13810
  }
13545
13811
  get type() {
13546
13812
  return this._type;
@@ -13645,17 +13911,17 @@ var RTCPeerConnectionController = class extends Destroyable {
13645
13911
  async doInit() {
13646
13912
  try {
13647
13913
  this.setupPeerConnection();
13648
- this.subscribeTo(this.negotiationNeeded$.pipe((0, import_cjs$11.auditTime)(0), (0, import_cjs$11.exhaustMap)(async () => this.startNegotiation())), {
13914
+ this.subscribeTo(this.negotiationNeeded$.pipe((0, import_cjs$12.auditTime)(0), (0, import_cjs$12.exhaustMap)(async () => this.startNegotiation())), {
13649
13915
  next: () => {
13650
- logger$11.debug("[RTCPeerConnectionController] Start Negotiation completed successfully");
13916
+ logger$12.debug("[RTCPeerConnectionController] Start Negotiation completed successfully");
13651
13917
  },
13652
13918
  error: (error) => {
13653
- logger$11.error("[RTCPeerConnectionController] Start Negotiation error:", error);
13919
+ logger$12.error("[RTCPeerConnectionController] Start Negotiation error:", error);
13654
13920
  this._errors$.next(error);
13655
13921
  }
13656
13922
  });
13657
- 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]) => {
13658
- logger$11.debug(`[RTCPeerConnectionController] Selected input device changed for:`, {
13923
+ 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]) => {
13924
+ logger$12.debug(`[RTCPeerConnectionController] Selected input device changed for:`, {
13659
13925
  kind,
13660
13926
  deviceInfo
13661
13927
  });
@@ -13672,7 +13938,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13672
13938
  this._initialized$.next(true);
13673
13939
  }
13674
13940
  } catch (error) {
13675
- logger$11.error("[RTCPeerConnectionController] Initialization error:", error);
13941
+ logger$12.error("[RTCPeerConnectionController] Initialization error:", error);
13676
13942
  this._errors$.next(error);
13677
13943
  this.destroy();
13678
13944
  }
@@ -13704,22 +13970,22 @@ var RTCPeerConnectionController = class extends Destroyable {
13704
13970
  }
13705
13971
  async startNegotiation() {
13706
13972
  if (this.isNegotiating) {
13707
- logger$11.debug("[RTCPeerConnectionController] Negotiation already in progress, skipping.");
13973
+ logger$12.debug("[RTCPeerConnectionController] Negotiation already in progress, skipping.");
13708
13974
  return;
13709
13975
  }
13710
13976
  this.setupEventListeners();
13711
13977
  if (this.type === "answer") {
13712
- logger$11.debug("[RTCPeerConnectionController] This is an answer type still, skipping offer creation.");
13978
+ logger$12.debug("[RTCPeerConnectionController] This is an answer type still, skipping offer creation.");
13713
13979
  return;
13714
13980
  }
13715
13981
  this._isNegotiating$.next(true);
13716
- logger$11.debug("[RTCPeerConnectionController] Starting negotiation.");
13982
+ logger$12.debug("[RTCPeerConnectionController] Starting negotiation.");
13717
13983
  try {
13718
13984
  const { offerOptions } = this;
13719
- logger$11.debug("[RTCPeerConnectionController] Creating offer with options:", offerOptions);
13985
+ logger$12.debug("[RTCPeerConnectionController] Creating offer with options:", offerOptions);
13720
13986
  await this.createOffer(offerOptions);
13721
13987
  } catch (error) {
13722
- logger$11.error("[RTCPeerConnectionController] Error during negotiation:", error);
13988
+ logger$12.error("[RTCPeerConnectionController] Error during negotiation:", error);
13723
13989
  this._errors$.next(error);
13724
13990
  }
13725
13991
  }
@@ -13735,14 +14001,14 @@ var RTCPeerConnectionController = class extends Destroyable {
13735
14001
  let readyToConnect = status !== "failed";
13736
14002
  try {
13737
14003
  if (status === "received" && sdp) {
13738
- logger$11.debug("[RTCPeerConnectionController] Received answer SDP:", sdp);
14004
+ logger$12.debug("[RTCPeerConnectionController] Received answer SDP:", sdp);
13739
14005
  await this._setRemoteDescription({
13740
14006
  type: "answer",
13741
14007
  sdp
13742
14008
  });
13743
14009
  }
13744
14010
  } catch (error) {
13745
- logger$11.error("[RTCPeerConnectionController] Error updating answer status:", error);
14011
+ logger$12.error("[RTCPeerConnectionController] Error updating answer status:", error);
13746
14012
  this._errors$.next(error);
13747
14013
  readyToConnect = false;
13748
14014
  } finally {
@@ -13761,7 +14027,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13761
14027
  await this.handleOfferReceived();
13762
14028
  break;
13763
14029
  case "failed":
13764
- logger$11.error("[RTCPeerConnectionController] Offer failed to be processed by remote.");
14030
+ logger$12.error("[RTCPeerConnectionController] Offer failed to be processed by remote.");
13765
14031
  break;
13766
14032
  case "sent":
13767
14033
  default:
@@ -13793,7 +14059,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13793
14059
  }
13794
14060
  await this.setupLocalTracks();
13795
14061
  const { answerOptions } = this;
13796
- logger$11.debug("[RTCPeerConnectionController] Creating inbound answer with options:", answerOptions);
14062
+ logger$12.debug("[RTCPeerConnectionController] Creating inbound answer with options:", answerOptions);
13797
14063
  await this.createAnswer(answerOptions);
13798
14064
  }
13799
14065
  async handleOfferReceived() {
@@ -13801,7 +14067,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13801
14067
  this._isNegotiating$.next(true);
13802
14068
  await this._setRemoteDescription(this.sdpInit);
13803
14069
  const { answerOptions } = this;
13804
- logger$11.debug("[RTCPeerConnectionController] Creating answer with options:", answerOptions);
14070
+ logger$12.debug("[RTCPeerConnectionController] Creating answer with options:", answerOptions);
13805
14071
  await this.createAnswer(answerOptions);
13806
14072
  }
13807
14073
  readyToConnect() {
@@ -13809,7 +14075,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13809
14075
  this.connectionTimer = setTimeout(() => {
13810
14076
  this.removeConnectionTimer();
13811
14077
  if (this.peerConnection?.connectionState !== "connected") {
13812
- logger$11.debug("[RTCPeerConnectionController] Connection timeout, restarting ICE gathering with relay only.");
14078
+ logger$12.debug("[RTCPeerConnectionController] Connection timeout, restarting ICE gathering with relay only.");
13813
14079
  this.iceGatheringController.restartICEGatheringWithRelayOnly();
13814
14080
  }
13815
14081
  }, this.connectionTimeout);
@@ -13869,13 +14135,13 @@ var RTCPeerConnectionController = class extends Destroyable {
13869
14135
  await this.setupRemoteTracks();
13870
14136
  }
13871
14137
  async setupLocalTracks() {
13872
- logger$11.debug("[RTCPeerConnectionController] Setting up local tracks/transceivers.");
14138
+ logger$12.debug("[RTCPeerConnectionController] Setting up local tracks/transceivers.");
13873
14139
  const localStream = this.localStream ?? await this.localStreamController.buildLocalStream();
13874
14140
  if (this.transceiverController?.useAddStream ?? false) {
13875
- logger$11.warn("[RTCPeerConnectionController] Using deprecated addStream API to add local stream.");
14141
+ logger$12.warn("[RTCPeerConnectionController] Using deprecated addStream API to add local stream.");
13876
14142
  this.peerConnection?.addStream(localStream);
13877
14143
  if (!this.isNegotiating) {
13878
- logger$11.debug("[RTCPeerConnectionController] Forcing negotiationneeded after local tracks setup.");
14144
+ logger$12.debug("[RTCPeerConnectionController] Forcing negotiationneeded after local tracks setup.");
13879
14145
  this.negotiationNeeded$.next();
13880
14146
  }
13881
14147
  return;
@@ -13891,7 +14157,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13891
14157
  const transceivers = (kind === "audio" ? this.transceiverController?.audioTransceivers : this.transceiverController?.videoTransceivers) ?? [];
13892
14158
  await this.transceiverController?.setupTransceiverSender(track, localStream, transceivers[index]);
13893
14159
  } else {
13894
- logger$11.debug(`[RTCPeerConnectionController] Using addTrack for local ${kind} track:`, track.id);
14160
+ logger$12.debug(`[RTCPeerConnectionController] Using addTrack for local ${kind} track:`, track.id);
13895
14161
  this.peerConnection?.addTrack(track, localStream);
13896
14162
  }
13897
14163
  }
@@ -13908,7 +14174,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13908
14174
  async setupRemoteTracks() {
13909
14175
  if (!this.peerConnection) throw new DependencyError("RTCPeerConnection is not initialized");
13910
14176
  this.peerConnection.ontrack = (event) => {
13911
- logger$11.debug("[RTCPeerConnectionController] Remote track received:", event.track.kind);
14177
+ logger$12.debug("[RTCPeerConnectionController] Remote track received:", event.track.kind);
13912
14178
  if (event.streams[0]) this._remoteStream$.next(event.streams[0]);
13913
14179
  else {
13914
14180
  const existingTracks = this._remoteStream$.value?.getTracks() ?? [];
@@ -13934,9 +14200,9 @@ var RTCPeerConnectionController = class extends Destroyable {
13934
14200
  try {
13935
14201
  const localStream = this.localStreamController.addTrack(track);
13936
14202
  this.peerConnection.addTrack(track, localStream);
13937
- logger$11.debug(`[RTCPeerConnectionController] ${track.kind} track added:`, track.id);
14203
+ logger$12.debug(`[RTCPeerConnectionController] ${track.kind} track added:`, track.id);
13938
14204
  } catch (error) {
13939
- logger$11.error(`[RTCPeerConnectionController] Failed to add ${track.kind} track:`, error);
14205
+ logger$12.error(`[RTCPeerConnectionController] Failed to add ${track.kind} track:`, error);
13940
14206
  this._errors$.next(error);
13941
14207
  throw error;
13942
14208
  }
@@ -13953,15 +14219,15 @@ var RTCPeerConnectionController = class extends Destroyable {
13953
14219
  }
13954
14220
  const sender = this.peerConnection.getSenders().find((sender$1) => sender$1.track?.id === trackId);
13955
14221
  if (!sender) {
13956
- logger$11.debug(`[RTCPeerConnectionController] track not found: ${trackId}`);
14222
+ logger$12.debug(`[RTCPeerConnectionController] track not found: ${trackId}`);
13957
14223
  return;
13958
14224
  }
13959
14225
  try {
13960
14226
  this.peerConnection.removeTrack(sender);
13961
14227
  this.localStreamController.removeTrack(trackId);
13962
- logger$11.debug(`[RTCPeerConnectionController] ${sender.track?.kind} track removed:`, trackId);
14228
+ logger$12.debug(`[RTCPeerConnectionController] ${sender.track?.kind} track removed:`, trackId);
13963
14229
  } catch (error) {
13964
- logger$11.error(`[RTCPeerConnectionController] Failed to remove ${sender.track?.kind} track:`, error);
14230
+ logger$12.error(`[RTCPeerConnectionController] Failed to remove ${sender.track?.kind} track:`, error);
13965
14231
  this._errors$.next(error);
13966
14232
  throw error;
13967
14233
  }
@@ -13984,7 +14250,7 @@ var RTCPeerConnectionController = class extends Destroyable {
13984
14250
  * Completes all observables to prevent memory leaks.
13985
14251
  */
13986
14252
  destroy() {
13987
- logger$11.debug(`[RTCPeerConnectionController] Destroying RTCPeerConnectionController. ${this.propose}`);
14253
+ logger$12.debug(`[RTCPeerConnectionController] Destroying RTCPeerConnectionController. ${this.propose}`);
13988
14254
  this.removeConnectionTimer();
13989
14255
  this._iceGatheringController?.destroy();
13990
14256
  this.localStreamController.destroy();
@@ -14008,7 +14274,7 @@ var RTCPeerConnectionController = class extends Destroyable {
14008
14274
  }
14009
14275
  stopRemoteTracks() {
14010
14276
  this._remoteStream$.value?.getTracks().forEach((track) => {
14011
- logger$11.debug(`[RTCPeerConnectionController] Stopping remote track: ${track.kind}`);
14277
+ logger$12.debug(`[RTCPeerConnectionController] Stopping remote track: ${track.kind}`);
14012
14278
  track.stop();
14013
14279
  });
14014
14280
  }
@@ -14025,7 +14291,7 @@ var RTCPeerConnectionController = class extends Destroyable {
14025
14291
  ...params,
14026
14292
  sdp: finalRemote
14027
14293
  };
14028
- logger$11.debug("[RTCPeerConnectionController] Setting remote description:", answer);
14294
+ logger$12.debug("[RTCPeerConnectionController] Setting remote description:", answer);
14029
14295
  return this.peerConnection.setRemoteDescription(answer);
14030
14296
  }
14031
14297
  };
@@ -14063,8 +14329,8 @@ function isVertoPingInnerParams(value) {
14063
14329
 
14064
14330
  //#endregion
14065
14331
  //#region src/managers/VertoManager.ts
14066
- var import_cjs$10 = require_cjs();
14067
- const logger$10 = getLogger();
14332
+ var import_cjs$11 = require_cjs();
14333
+ const logger$11 = getLogger();
14068
14334
  var VertoManager = class extends Destroyable {
14069
14335
  constructor(callSession) {
14070
14336
  super();
@@ -14102,7 +14368,7 @@ var WebRTCVertoManager = class extends VertoManager {
14102
14368
  try {
14103
14369
  await this.executeVerto(vertoModifyMessage);
14104
14370
  } catch (error) {
14105
- logger$10.warn("[WebRTCManager] Call might already be disconnected, error sending Verto hold:", error);
14371
+ logger$11.warn("[WebRTCManager] Call might already be disconnected, error sending Verto hold:", error);
14106
14372
  throw error;
14107
14373
  }
14108
14374
  }
@@ -14115,7 +14381,7 @@ var WebRTCVertoManager = class extends VertoManager {
14115
14381
  try {
14116
14382
  await this.executeVerto(vertoModifyMessage);
14117
14383
  } catch (error) {
14118
- logger$10.warn("[WebRTCManager] Call might already be disconnected, error sending Verto unhold:", error);
14384
+ logger$11.warn("[WebRTCManager] Call might already be disconnected, error sending Verto unhold:", error);
14119
14385
  throw error;
14120
14386
  }
14121
14387
  }
@@ -14155,7 +14421,7 @@ var WebRTCVertoManager = class extends VertoManager {
14155
14421
  return rtcPeerConnection;
14156
14422
  }
14157
14423
  get signalingStatus$() {
14158
- return this.cachedObservable("signalingStatus$", () => (0, import_cjs$10.merge)(this._signalingStatus$.pipe(filterNull()), this.mainPeerConnection.connectionState$.pipe((0, import_cjs$10.filter)((connectionState) => [
14424
+ return this.cachedObservable("signalingStatus$", () => (0, import_cjs$11.merge)(this._signalingStatus$.pipe(filterNull()), this.mainPeerConnection.connectionState$.pipe((0, import_cjs$11.filter)((connectionState) => [
14159
14425
  "connected",
14160
14426
  "disconnected",
14161
14427
  "failed"
@@ -14168,7 +14434,7 @@ var WebRTCVertoManager = class extends VertoManager {
14168
14434
  if (event.member_id) this.setSelfIdIfNull(event.member_id);
14169
14435
  });
14170
14436
  this.subscribeTo(this.vertoMedia$, (event) => {
14171
- logger$10.debug("[WebRTCManager] Received Verto media event (early media SDP):", event);
14437
+ logger$11.debug("[WebRTCManager] Received Verto media event (early media SDP):", event);
14172
14438
  this._signalingStatus$.next("ringing");
14173
14439
  const { sdp, callID } = event;
14174
14440
  this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
@@ -14177,7 +14443,7 @@ var WebRTCVertoManager = class extends VertoManager {
14177
14443
  });
14178
14444
  });
14179
14445
  this.subscribeTo(this.vertoAnswer$, (event) => {
14180
- logger$10.debug("[WebRTCManager] Received Verto answer event:", event);
14446
+ logger$11.debug("[WebRTCManager] Received Verto answer event:", event);
14181
14447
  this._signalingStatus$.next("connecting");
14182
14448
  const { sdp, callID } = event;
14183
14449
  this._rtcPeerConnectionsMap.get(callID)?.updateAnswerStatus({
@@ -14186,7 +14452,7 @@ var WebRTCVertoManager = class extends VertoManager {
14186
14452
  });
14187
14453
  });
14188
14454
  this.subscribeTo(this.vertoMediaParams$, (event) => {
14189
- logger$10.debug("[WebRTCManager] Received Verto mediaParams event:", event);
14455
+ logger$11.debug("[WebRTCManager] Received Verto mediaParams event:", event);
14190
14456
  const { mediaParams, callID } = event;
14191
14457
  const rtcPeerConnController = this._rtcPeerConnectionsMap.get(callID);
14192
14458
  const { audio, video } = mediaParams;
@@ -14210,13 +14476,13 @@ var WebRTCVertoManager = class extends VertoManager {
14210
14476
  */
14211
14477
  setNodeIdIfNull(nodeId) {
14212
14478
  if (!this._nodeId$.value && nodeId) {
14213
- logger$10.debug(`[WebRTCManager] Early node_id set: ${nodeId}`);
14479
+ logger$11.debug(`[WebRTCManager] Early node_id set: ${nodeId}`);
14214
14480
  this._nodeId$.next(nodeId);
14215
14481
  }
14216
14482
  }
14217
14483
  setSelfIdIfNull(selfId) {
14218
14484
  if (!this._selfId$.value && selfId) {
14219
- logger$10.debug(`[WebRTCManager] Early selfId set: ${selfId}`);
14485
+ logger$11.debug(`[WebRTCManager] Early selfId set: ${selfId}`);
14220
14486
  this._selfId$.next(selfId);
14221
14487
  }
14222
14488
  }
@@ -14225,7 +14491,7 @@ var WebRTCVertoManager = class extends VertoManager {
14225
14491
  const vertoPongMessage = VertoPong({ ...vertoPing });
14226
14492
  await this.executeVerto(vertoPongMessage);
14227
14493
  } catch (error) {
14228
- logger$10.warn("[WebRTCManager] Call might disconnect, error sending Verto pong:", error);
14494
+ logger$11.warn("[WebRTCManager] Call might disconnect, error sending Verto pong:", error);
14229
14495
  this.onError?.(new VertoPongError(error));
14230
14496
  }
14231
14497
  }
@@ -14235,7 +14501,7 @@ var WebRTCVertoManager = class extends VertoManager {
14235
14501
  if (audio) await this.mainPeerConnection.updateSendersConstraints("audio", audio);
14236
14502
  if (video) await this.mainPeerConnection.updateSendersConstraints("video", video);
14237
14503
  } catch (error) {
14238
- logger$10.warn("[WebRTCManager] Error updating media constraints:", error);
14504
+ logger$11.warn("[WebRTCManager] Error updating media constraints:", error);
14239
14505
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14240
14506
  throw error;
14241
14507
  }
@@ -14244,25 +14510,25 @@ var WebRTCVertoManager = class extends VertoManager {
14244
14510
  return this._selfId$.value;
14245
14511
  }
14246
14512
  get callJoinedEvent$() {
14247
- return this.webRtcCallSession.callEvent$.pipe((0, import_cjs$10.filter)(isCallJoinedPayload), (0, import_cjs$10.takeUntil)(this.destroyed$));
14513
+ return this.webRtcCallSession.callEvent$.pipe((0, import_cjs$11.filter)(isCallJoinedPayload), (0, import_cjs$11.takeUntil)(this.destroyed$));
14248
14514
  }
14249
14515
  get vertoMedia$() {
14250
- return this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$));
14516
+ return this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$));
14251
14517
  }
14252
14518
  get vertoAnswer$() {
14253
- return this.cachedObservable("vertoAnswer$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAnswerInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14519
+ return this.cachedObservable("vertoAnswer$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAnswerInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14254
14520
  }
14255
14521
  get vertoMediaParams$() {
14256
- return this.cachedObservable("vertoMediaParams$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaParamsInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14522
+ return this.cachedObservable("vertoMediaParams$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoMediaParamsInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14257
14523
  }
14258
14524
  get vertoBye$() {
14259
- return this.cachedObservable("vertoBye$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoByeMessage, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14525
+ return this.cachedObservable("vertoBye$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoByeMessage, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14260
14526
  }
14261
14527
  get vertoAttach$() {
14262
- return this.cachedObservable("vertoAttach$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAttachMessage, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14528
+ return this.cachedObservable("vertoAttach$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoAttachMessage, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14263
14529
  }
14264
14530
  get vertoPing$() {
14265
- return this.cachedObservable("vertoPing$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoPingInnerParams, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
14531
+ return this.cachedObservable("vertoPing$", () => this.webRtcCallSession.webrtcMessages$.pipe(filterAs(isVertoPingInnerParams, "params"), (0, import_cjs$11.takeUntil)(this.destroyed$)));
14266
14532
  }
14267
14533
  async executeVerto(message, optionals = {}) {
14268
14534
  const webrtcVertoMessage = WebrtcVerto({
@@ -14300,7 +14566,7 @@ var WebRTCVertoManager = class extends VertoManager {
14300
14566
  default:
14301
14567
  }
14302
14568
  } catch (error) {
14303
- logger$10.error(`[WebRTCManager] Error sending Verto ${vertoMethod}:`, error);
14569
+ logger$11.error(`[WebRTCManager] Error sending Verto ${vertoMethod}:`, error);
14304
14570
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14305
14571
  }
14306
14572
  }
@@ -14314,7 +14580,7 @@ var WebRTCVertoManager = class extends VertoManager {
14314
14580
  sdp
14315
14581
  });
14316
14582
  } catch (error) {
14317
- logger$10.warn("[WebRTCManager] Error processing modify response:", error);
14583
+ logger$11.warn("[WebRTCManager] Error processing modify response:", error);
14318
14584
  const modifyError = error instanceof Error ? error : new Error(String(error), { cause: error });
14319
14585
  this.onError?.(modifyError);
14320
14586
  }
@@ -14326,7 +14592,7 @@ var WebRTCVertoManager = class extends VertoManager {
14326
14592
  this._nodeId$.next(getValueFrom(response, "result.node_id") ?? null);
14327
14593
  const memberId = getValueFrom(response, "result.result.result.memberID") ?? null;
14328
14594
  const callId = getValueFrom(response, "result.result.result.callID") ?? null;
14329
- logger$10.debug("[WebRTCManager] Verto invite response:", {
14595
+ logger$11.debug("[WebRTCManager] Verto invite response:", {
14330
14596
  callId,
14331
14597
  memberId,
14332
14598
  response
@@ -14335,10 +14601,10 @@ var WebRTCVertoManager = class extends VertoManager {
14335
14601
  rtcPeerConnController.setMemberId(memberId);
14336
14602
  if (callId) this.webRtcCallSession.addCallId(callId);
14337
14603
  this.attachManager.attach(this.webRtcCallSession);
14338
- logger$10.info("[WebRTCManager] Verto invite successful");
14339
- logger$10.debug(`[WebRTCManager] nodeid: ${this._nodeId$.value}, selfId: ${this._selfId$.value}`);
14604
+ logger$11.info("[WebRTCManager] Verto invite successful");
14605
+ logger$11.debug(`[WebRTCManager] nodeid: ${this._nodeId$.value}, selfId: ${this._selfId$.value}`);
14340
14606
  } else {
14341
- logger$10.error("[WebRTCManager] Verto invite failed:", response);
14607
+ logger$11.error("[WebRTCManager] Verto invite failed:", response);
14342
14608
  const inviteError = response.error ? new JSONRPCError(response.error.code, response.error.message, response.error.data) : /* @__PURE__ */ new Error("Verto invite failed: unexpected response");
14343
14609
  this.onError?.(inviteError);
14344
14610
  }
@@ -14380,17 +14646,17 @@ var WebRTCVertoManager = class extends VertoManager {
14380
14646
  if (options.initOffer) this.handleInboundAnswer(rtcPeerConnController);
14381
14647
  }
14382
14648
  async handleInboundAnswer(rtcPeerConnController) {
14383
- logger$10.debug("[WebRTCManager] Waiting for inbound call to be accepted or rejected");
14384
- 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);
14649
+ logger$11.debug("[WebRTCManager] Waiting for inbound call to be accepted or rejected");
14650
+ 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);
14385
14651
  if (vertoByeOrAccepted === null) {
14386
- logger$10.debug("[WebRTCManager] Inbound answer handler aborted (destroyed).");
14652
+ logger$11.debug("[WebRTCManager] Inbound answer handler aborted (destroyed).");
14387
14653
  return;
14388
14654
  }
14389
14655
  if (isVertoByeMessage(vertoByeOrAccepted)) {
14390
- logger$10.info("[WebRTCManager] Inbound call ended by remote before answer.");
14656
+ logger$11.info("[WebRTCManager] Inbound call ended by remote before answer.");
14391
14657
  this.callSession?.destroy();
14392
14658
  } else if (!vertoByeOrAccepted) {
14393
- logger$10.info("[WebRTCManager] Inbound call rejected by user.");
14659
+ logger$11.info("[WebRTCManager] Inbound call rejected by user.");
14394
14660
  try {
14395
14661
  await this.bye("USER_BUSY");
14396
14662
  } finally {
@@ -14398,19 +14664,19 @@ var WebRTCVertoManager = class extends VertoManager {
14398
14664
  this.callSession?.destroy();
14399
14665
  }
14400
14666
  } else {
14401
- logger$10.debug("[WebRTCManager] Inbound call accepted, creating SDP answer");
14667
+ logger$11.debug("[WebRTCManager] Inbound call accepted, creating SDP answer");
14402
14668
  const answerOptions = this.webRtcCallSession.answerMediaOptions;
14403
14669
  try {
14404
14670
  await rtcPeerConnController.acceptInbound(answerOptions);
14405
14671
  } catch (error) {
14406
- logger$10.error("[WebRTCManager] Error creating inbound answer:", error);
14672
+ logger$11.error("[WebRTCManager] Error creating inbound answer:", error);
14407
14673
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14408
14674
  }
14409
14675
  }
14410
14676
  }
14411
14677
  setupVertoAttachHandler() {
14412
14678
  this.subscribeTo(this.vertoAttach$, async (vertoAttach) => {
14413
- logger$10.debug("[WebRTCManager] Received Verto attach event:", vertoAttach);
14679
+ logger$11.debug("[WebRTCManager] Received Verto attach event:", vertoAttach);
14414
14680
  const { callID } = vertoAttach;
14415
14681
  await this.attachManager.attach({
14416
14682
  id: callID,
@@ -14424,12 +14690,12 @@ var WebRTCVertoManager = class extends VertoManager {
14424
14690
  });
14425
14691
  }
14426
14692
  initObservables(rtcPeerConnController) {
14427
- 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$));
14428
- this.localStream$ = rtcPeerConnController.localStream$.pipe(filterNull(), (0, import_cjs$10.takeUntil)(this.destroyed$));
14429
- this.remoteStream$ = rtcPeerConnController.remoteStream$.pipe(filterNull(), (0, import_cjs$10.takeUntil)(this.destroyed$));
14693
+ 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$));
14694
+ this.localStream$ = rtcPeerConnController.localStream$.pipe(filterNull(), (0, import_cjs$11.takeUntil)(this.destroyed$));
14695
+ this.remoteStream$ = rtcPeerConnController.remoteStream$.pipe(filterNull(), (0, import_cjs$11.takeUntil)(this.destroyed$));
14430
14696
  }
14431
14697
  setupLocalDescriptionHandler(rtcPeerConnController) {
14432
- this.subscribeTo(rtcPeerConnController.localDescription$.pipe((0, import_cjs$10.filter)((description) => description !== null), (0, import_cjs$10.takeUntil)(this.destroyed$)), (description) => {
14698
+ this.subscribeTo(rtcPeerConnController.localDescription$.pipe((0, import_cjs$11.filter)((description) => description !== null), (0, import_cjs$11.takeUntil)(this.destroyed$)), (description) => {
14433
14699
  const { type, sdp } = description;
14434
14700
  const dialogParams = this.dialogParams(rtcPeerConnController);
14435
14701
  const initial = !rtcPeerConnController.firstSDPExchangeCompleted;
@@ -14478,13 +14744,13 @@ var WebRTCVertoManager = class extends VertoManager {
14478
14744
  };
14479
14745
  }
14480
14746
  async sendLocalDescriptionOnceAccepted(vertoMessageRequest, rtcPeerConnectionController) {
14481
- logger$10.debug("[WebRTCManager] Waiting for call to be accepted or ended before sending answer");
14482
- const vertoByeOrAccepted = await (0, import_cjs$10.firstValueFrom)((0, import_cjs$10.race)(this.vertoBye$, this.webRtcCallSession.answered$));
14747
+ logger$11.debug("[WebRTCManager] Waiting for call to be accepted or ended before sending answer");
14748
+ const vertoByeOrAccepted = await (0, import_cjs$11.firstValueFrom)((0, import_cjs$11.race)(this.vertoBye$, this.webRtcCallSession.answered$));
14483
14749
  if (isVertoByeMessage(vertoByeOrAccepted)) {
14484
- logger$10.info("[WebRTCManager] Call ended before answer was sent.");
14750
+ logger$11.info("[WebRTCManager] Call ended before answer was sent.");
14485
14751
  this.callSession?.destroy();
14486
14752
  } else if (!vertoByeOrAccepted) {
14487
- logger$10.info("[WebRTCManager] Call was not accepted, sending verto.bye.");
14753
+ logger$11.info("[WebRTCManager] Call was not accepted, sending verto.bye.");
14488
14754
  try {
14489
14755
  await this.bye("USER_BUSY");
14490
14756
  } finally {
@@ -14492,14 +14758,14 @@ var WebRTCVertoManager = class extends VertoManager {
14492
14758
  this.callSession?.destroy();
14493
14759
  }
14494
14760
  } else {
14495
- logger$10.debug("[WebRTCManager] Call accepted, sending answer");
14761
+ logger$11.debug("[WebRTCManager] Call accepted, sending answer");
14496
14762
  try {
14497
14763
  this._signalingStatus$.next("connecting");
14498
14764
  await this.sendLocalDescription(vertoMessageRequest, rtcPeerConnectionController);
14499
14765
  await rtcPeerConnectionController.updateAnswerStatus({ status: "sent" });
14500
14766
  await this.attachManager.attach(this.webRtcCallSession);
14501
14767
  } catch (error) {
14502
- logger$10.error("[WebRTCManager] Error sending Verto answer:", error);
14768
+ logger$11.error("[WebRTCManager] Error sending Verto answer:", error);
14503
14769
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14504
14770
  await rtcPeerConnectionController.updateAnswerStatus({ status: "failed" });
14505
14771
  }
@@ -14588,12 +14854,12 @@ var WebRTCVertoManager = class extends VertoManager {
14588
14854
  this.subscribeTo(rtcPeerConnController.errors$, (error) => {
14589
14855
  this.onError?.(error);
14590
14856
  });
14591
- 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)));
14857
+ 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)));
14592
14858
  this._screenShareStatus$.next("started");
14593
- logger$10.info("[WebRTCManager] Screen share started successfully.");
14859
+ logger$11.info("[WebRTCManager] Screen share started successfully.");
14594
14860
  return rtcPeerConnController.id;
14595
14861
  } catch (error) {
14596
- logger$10.warn("[WebRTCManager] Error initializing additional peer connection:", error);
14862
+ logger$11.warn("[WebRTCManager] Error initializing additional peer connection:", error);
14597
14863
  this.onError?.(error instanceof Error ? error : new Error(String(error), { cause: error }));
14598
14864
  if (rtcPeerConnController) rtcPeerConnController.destroy();
14599
14865
  this._screenShareStatus$.next("none");
@@ -14612,9 +14878,9 @@ var WebRTCVertoManager = class extends VertoManager {
14612
14878
  if (removeTrack) return this.mainPeerConnection.stopTrackSender(removeTrack, { updateTransceiverDirection: true });
14613
14879
  }
14614
14880
  async removeScreenMedia() {
14615
- if (!["starting", "started"].includes(this._screenShareStatus$.value)) logger$10.warn("[WebRTCManager] No active screen share to stop.");
14881
+ if (!["starting", "started"].includes(this._screenShareStatus$.value)) logger$11.warn("[WebRTCManager] No active screen share to stop.");
14616
14882
  if (!this._screenShareId) {
14617
- logger$10.debug("[WebRTCManager] No screen share peer connection found.");
14883
+ logger$11.debug("[WebRTCManager] No screen share peer connection found.");
14618
14884
  return;
14619
14885
  }
14620
14886
  this._screenShareStatus$.next("stopping");
@@ -14643,7 +14909,7 @@ var WebRTCVertoManager = class extends VertoManager {
14643
14909
  dialogParams: this.dialogParams(rtcPeerConnController)
14644
14910
  }));
14645
14911
  } catch (error) {
14646
- logger$10.warn("[WebRTCManager] Call might already be disconnected, error sending Verto bye:", error);
14912
+ logger$11.warn("[WebRTCManager] Call might already be disconnected, error sending Verto bye:", error);
14647
14913
  throw error;
14648
14914
  }
14649
14915
  }
@@ -14661,7 +14927,7 @@ var WebRTCVertoManager = class extends VertoManager {
14661
14927
  try {
14662
14928
  await this.executeVerto(vertoInfoMessage);
14663
14929
  } catch (error) {
14664
- logger$10.warn("[WebRTCManager] Error sending DTMF digits:", error);
14930
+ logger$11.warn("[WebRTCManager] Error sending DTMF digits:", error);
14665
14931
  throw error;
14666
14932
  }
14667
14933
  }
@@ -14672,10 +14938,10 @@ var WebRTCVertoManager = class extends VertoManager {
14672
14938
  action: "transfer"
14673
14939
  });
14674
14940
  try {
14675
- logger$10.debug("[WebRTCManager] Transferring call with options:", options);
14941
+ logger$11.debug("[WebRTCManager] Transferring call with options:", options);
14676
14942
  await this.executeVerto(message);
14677
14943
  } catch (error) {
14678
- logger$10.error("[WebRTCManager] Error transferring call:", error);
14944
+ logger$11.error("[WebRTCManager] Error transferring call:", error);
14679
14945
  throw error;
14680
14946
  }
14681
14947
  }
@@ -14717,8 +14983,8 @@ var ParticipantFactory = class {
14717
14983
 
14718
14984
  //#endregion
14719
14985
  //#region src/core/entities/Call.ts
14720
- var import_cjs$9 = require_cjs();
14721
- const logger$9 = getLogger();
14986
+ var import_cjs$10 = require_cjs();
14987
+ const logger$10 = getLogger();
14722
14988
  const fromDestinationParams = (destination) => {
14723
14989
  if (!destination) return {};
14724
14990
  try {
@@ -14729,7 +14995,7 @@ const fromDestinationParams = (destination) => {
14729
14995
  });
14730
14996
  return params;
14731
14997
  } catch (error) {
14732
- logger$9.warn(`Failed to parse destination URI: ${destination}`, error);
14998
+ logger$10.warn(`Failed to parse destination URI: ${destination}`, error);
14733
14999
  return {};
14734
15000
  }
14735
15001
  };
@@ -14797,7 +15063,7 @@ var WebRTCCall = class extends Destroyable {
14797
15063
  }
14798
15064
  /** Observable of the address associated with this call. */
14799
15065
  get address$() {
14800
- return this.deferEmission((0, import_cjs$9.from)([this.address])).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15066
+ return this.deferEmission((0, import_cjs$10.from)([this.address])).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14801
15067
  }
14802
15068
  /** Display name of the caller. */
14803
15069
  get fromName() {
@@ -14876,7 +15142,7 @@ var WebRTCCall = class extends Destroyable {
14876
15142
  }
14877
15143
  /** Observable of layout layer positions for all participants. */
14878
15144
  get layoutLayers$() {
14879
- return this.deferEmission(this.callEventsManager.layoutLayers$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15145
+ return this.deferEmission(this.callEventsManager.layoutLayers$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14880
15146
  }
14881
15147
  /** Current snapshot of layout layers. */
14882
15148
  get layoutLayers() {
@@ -14904,7 +15170,7 @@ var WebRTCCall = class extends Destroyable {
14904
15170
  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);
14905
15171
  return response;
14906
15172
  } catch (error) {
14907
- logger$9.error(`[Call] Error executing method ${method} with params`, params, error);
15173
+ logger$10.error(`[Call] Error executing method ${method} with params`, params, error);
14908
15174
  throw error;
14909
15175
  }
14910
15176
  }
@@ -14931,45 +15197,45 @@ var WebRTCCall = class extends Destroyable {
14931
15197
  }
14932
15198
  /** Observable of the current call status (e.g. `'ringing'`, `'connected'`). */
14933
15199
  get status$() {
14934
- 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) => {
15200
+ 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) => {
14935
15201
  this._lastMergedStatus = status;
14936
15202
  })));
14937
15203
  }
14938
15204
  /** Observable of the participants list, emits on join/leave/update. */
14939
15205
  get participants$() {
14940
- return this.deferEmission(this.callEventsManager.participants$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15206
+ return this.deferEmission(this.callEventsManager.participants$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14941
15207
  }
14942
15208
  /** Observable of the local (self) participant. */
14943
15209
  get self$() {
14944
- return this.deferEmission(this.callEventsManager.self$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15210
+ return this.deferEmission(this.callEventsManager.self$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14945
15211
  }
14946
15212
  /** Observable indicating whether the call is being recorded. */
14947
15213
  get recording$() {
14948
- return this.deferEmission(this.callEventsManager.recording$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15214
+ return this.deferEmission(this.callEventsManager.recording$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14949
15215
  }
14950
15216
  /** Observable indicating whether the call is being streamed. */
14951
15217
  get streaming$() {
14952
- return this.deferEmission(this.callEventsManager.streaming$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15218
+ return this.deferEmission(this.callEventsManager.streaming$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14953
15219
  }
14954
15220
  /** Observable indicating whether raise-hand priority is active. */
14955
15221
  get raiseHandPriority$() {
14956
- return this.deferEmission(this.callEventsManager.raiseHandPriority$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15222
+ return this.deferEmission(this.callEventsManager.raiseHandPriority$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14957
15223
  }
14958
15224
  /** Observable indicating whether the call room is locked. */
14959
15225
  get locked$() {
14960
- return this.deferEmission(this.callEventsManager.locked$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15226
+ return this.deferEmission(this.callEventsManager.locked$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14961
15227
  }
14962
15228
  /** Observable of custom metadata associated with the call. */
14963
15229
  get meta$() {
14964
- return this.deferEmission(this.callEventsManager.meta$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15230
+ return this.deferEmission(this.callEventsManager.meta$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14965
15231
  }
14966
15232
  /** Observable of the call's capability flags. */
14967
15233
  get capabilities$() {
14968
- return this.deferEmission(this.callEventsManager.capabilities$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15234
+ return this.deferEmission(this.callEventsManager.capabilities$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14969
15235
  }
14970
15236
  /** Observable of the current layout name. */
14971
15237
  get layout$() {
14972
- return this.deferEmission(this.callEventsManager.layout$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15238
+ return this.deferEmission(this.callEventsManager.layout$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
14973
15239
  }
14974
15240
  /** Current call status. */
14975
15241
  get status() {
@@ -15001,7 +15267,7 @@ var WebRTCCall = class extends Destroyable {
15001
15267
  }
15002
15268
  /** Observable of available layout names. */
15003
15269
  get layouts$() {
15004
- return this.deferEmission(this.callEventsManager.layouts$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15270
+ return this.deferEmission(this.callEventsManager.layouts$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15005
15271
  }
15006
15272
  /** Current snapshot of available layout names. */
15007
15273
  get layouts() {
@@ -15009,7 +15275,7 @@ var WebRTCCall = class extends Destroyable {
15009
15275
  }
15010
15276
  /** Observable of the local media stream (camera/microphone). */
15011
15277
  get localStream$() {
15012
- return this.deferEmission(this.vertoManager.localStream$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15278
+ return this.deferEmission(this.vertoManager.localStream$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15013
15279
  }
15014
15280
  /** Current local media stream, or `null` if not available. */
15015
15281
  get localStream() {
@@ -15017,7 +15283,7 @@ var WebRTCCall = class extends Destroyable {
15017
15283
  }
15018
15284
  /** Observable of the remote media stream from the far end. */
15019
15285
  get remoteStream$() {
15020
- return this.deferEmission(this.vertoManager.remoteStream$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15286
+ return this.deferEmission(this.vertoManager.remoteStream$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15021
15287
  }
15022
15288
  /** Current remote media stream, or `null` if not available. */
15023
15289
  get remoteStream() {
@@ -15045,14 +15311,14 @@ var WebRTCCall = class extends Destroyable {
15045
15311
  }
15046
15312
  /** Observable of the current audio/video send/receive directions. */
15047
15313
  get mediaDirections$() {
15048
- return this.deferEmission(this.vertoManager.mediaDirections$).pipe((0, import_cjs$9.takeUntil)(this._destroyed$));
15314
+ return this.deferEmission(this.vertoManager.mediaDirections$).pipe((0, import_cjs$10.takeUntil)(this._destroyed$));
15049
15315
  }
15050
15316
  /** Current audio/video send/receive directions. */
15051
15317
  get mediaDirections() {
15052
15318
  return this.vertoManager.mediaDirections;
15053
15319
  }
15054
15320
  get participantsId$() {
15055
- return this.cachedObservable("participantsId$", () => this.participants$.pipe((0, import_cjs$9.map)((participants) => participants.map((participant) => participant.id))));
15321
+ return this.cachedObservable("participantsId$", () => this.participants$.pipe((0, import_cjs$10.map)((participants) => participants.map((participant) => participant.id))));
15056
15322
  }
15057
15323
  /**
15058
15324
  * Executes a raw JSON-RPC request on the client session.
@@ -15085,46 +15351,48 @@ var WebRTCCall = class extends Destroyable {
15085
15351
  }
15086
15352
  isCallSessionEvent(event) {
15087
15353
  try {
15088
- logger$9.debug("[Call] Checking if event is for this call session:", event);
15354
+ logger$10.debug("[Call] Checking if event is for this call session:", event);
15089
15355
  const callId = getValueFrom(event, "params.params.callID") ?? getValueFrom(event, "params.call_id");
15090
15356
  const roomSessionId = getValueFrom(event, "params.room_session_id");
15091
- logger$9.debug(`[Call] Extracted session identifiers callID: ${callId} and roomSessionID: ${roomSessionId} from event:`);
15357
+ logger$10.debug(`[Call] Extracted session identifiers callID: ${callId} and roomSessionID: ${roomSessionId} from event:`);
15092
15358
  return callId === this.id || !!callId && this.callEventsManager.isCallIdValid(callId) || !!roomSessionId && this.callEventsManager.isRoomSessionIdValid(roomSessionId);
15093
15359
  } catch (error) {
15094
- logger$9.error("[Call] Error checking if event is for this call session:", error);
15360
+ logger$10.error("[Call] Error checking if event is for this call session:", error);
15095
15361
  return false;
15096
15362
  }
15097
15363
  }
15098
15364
  get callSessionEvents$() {
15099
- 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)()));
15365
+ return this.cachedObservable("callSessionEvents$", () => this.clientSession.signalingEvent$.pipe((0, import_cjs$10.filter)((event) => this.isCallSessionEvent(event)), (0, import_cjs$10.tap)((event) => {
15366
+ logger$10.debug("[Call] Received call session event:", event);
15367
+ }), (0, import_cjs$10.takeUntil)(this.destroyed$), (0, import_cjs$10.share)()));
15100
15368
  }
15101
15369
  /** Observable of call-updated events. */
15102
15370
  get callUpdated$() {
15103
- return this.publicCachedObservable("callUpdated$", () => this.callSessionEvents$.pipe(filterAs(isCallUpdatedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15371
+ return this.publicCachedObservable("callUpdated$", () => this.callSessionEvents$.pipe(filterAs(isCallUpdatedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15104
15372
  }
15105
15373
  /** Observable of member-joined events, emitted when a remote participant joins the call. */
15106
15374
  get memberJoined$() {
15107
- return this.publicCachedObservable("memberJoined$", () => this.callSessionEvents$.pipe(filterAs(isMemberJoinedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15375
+ return this.publicCachedObservable("memberJoined$", () => this.callSessionEvents$.pipe(filterAs(isMemberJoinedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15108
15376
  }
15109
15377
  /** Observable of member-left events, emitted when a participant leaves the call. */
15110
15378
  get memberLeft$() {
15111
- return this.publicCachedObservable("memberLeft$", () => this.callSessionEvents$.pipe(filterAs(isMemberLeftMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15379
+ return this.publicCachedObservable("memberLeft$", () => this.callSessionEvents$.pipe(filterAs(isMemberLeftMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15112
15380
  }
15113
15381
  /** Observable of member-updated events (mute, volume, etc.). */
15114
15382
  get memberUpdated$() {
15115
- return this.publicCachedObservable("memberUpdated$", () => this.callSessionEvents$.pipe(filterAs(isMemberUpdatedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15383
+ return this.publicCachedObservable("memberUpdated$", () => this.callSessionEvents$.pipe(filterAs(isMemberUpdatedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15116
15384
  }
15117
15385
  /** Observable of member-talking events (speech start/stop). */
15118
15386
  get memberTalking$() {
15119
- return this.publicCachedObservable("memberTalking$", () => this.callSessionEvents$.pipe(filterAs(isMemberTalkingMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15387
+ return this.publicCachedObservable("memberTalking$", () => this.callSessionEvents$.pipe(filterAs(isMemberTalkingMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15120
15388
  }
15121
15389
  /** Observable of call state-change events. */
15122
15390
  get callStates$() {
15123
- return this.publicCachedObservable("callStates$", () => this.callSessionEvents$.pipe(filterAs(isCallStateMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15391
+ return this.publicCachedObservable("callStates$", () => this.callSessionEvents$.pipe(filterAs(isCallStateMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15124
15392
  }
15125
15393
  /** Observable of layout-changed events. */
15126
15394
  get layoutUpdates$() {
15127
- return this.publicCachedObservable("layoutUpdates$", () => this.callSessionEvents$.pipe(filterAs(isLayoutChangedMetadata, "params"), (0, import_cjs$9.takeUntil)(this.destroyed$)));
15395
+ return this.publicCachedObservable("layoutUpdates$", () => this.callSessionEvents$.pipe(filterAs(isLayoutChangedMetadata, "params"), (0, import_cjs$10.takeUntil)(this.destroyed$)));
15128
15396
  }
15129
15397
  /** Underlying `RTCPeerConnection`, for advanced use cases. */
15130
15398
  get rtcPeerConnection() {
@@ -15132,15 +15400,15 @@ var WebRTCCall = class extends Destroyable {
15132
15400
  }
15133
15401
  /** Observable of raw signaling events as plain objects. */
15134
15402
  get signalingEvent$() {
15135
- return this.publicCachedObservable("signalingEvent$", () => this.callEvent$.pipe((0, import_cjs$9.map)((event) => JSON.parse(JSON.stringify(event)))));
15403
+ return this.publicCachedObservable("signalingEvent$", () => this.callEvent$.pipe((0, import_cjs$10.map)((event) => JSON.parse(JSON.stringify(event)))));
15136
15404
  }
15137
15405
  /** Observable of WebRTC-specific signaling messages. */
15138
15406
  get webrtcMessages$() {
15139
- 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)()));
15407
+ 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)()));
15140
15408
  }
15141
15409
  /** Observable of call-level signaling events. */
15142
15410
  get callEvent$() {
15143
- 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)()));
15411
+ 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)()));
15144
15412
  }
15145
15413
  /** Observable of layout-changed signaling events. */
15146
15414
  get layoutEvent$() {
@@ -15231,7 +15499,7 @@ var WebRTCCall = class extends Destroyable {
15231
15499
  */
15232
15500
  async setLayout(layout, positions) {
15233
15501
  if (!this.layouts.includes(layout)) throw new InvalidParams(`Layout ${layout} is not available in the current call layouts: ${this.layouts.join(", ")}`);
15234
- const selfId = await (0, import_cjs$9.firstValueFrom)(this.selfId$.pipe((0, import_cjs$9.filter)((id) => id !== null)));
15502
+ const selfId = await (0, import_cjs$10.firstValueFrom)(this.selfId$.pipe((0, import_cjs$10.filter)((id) => id !== null)));
15235
15503
  await this.executeMethod(selfId, "call.layout.set", {
15236
15504
  layout,
15237
15505
  positions
@@ -15315,8 +15583,8 @@ var CallFactory = class {
15315
15583
 
15316
15584
  //#endregion
15317
15585
  //#region src/behaviors/Collection.ts
15318
- var import_cjs$8 = require_cjs();
15319
- const logger$8 = getLogger();
15586
+ var import_cjs$9 = require_cjs();
15587
+ const logger$9 = getLogger();
15320
15588
  var Fetcher = class {
15321
15589
  constructor(endpoint, params, http) {
15322
15590
  this.endpoint = endpoint;
@@ -15340,7 +15608,7 @@ var Fetcher = class {
15340
15608
  this.hasMore = !!this.nextUrl;
15341
15609
  return result.data.filter(this.filter).map(this.mapper);
15342
15610
  }
15343
- logger$8.error("Failed to fetch entity");
15611
+ logger$9.error("Failed to fetch entity");
15344
15612
  return [];
15345
15613
  }
15346
15614
  async id(v) {
@@ -15372,10 +15640,10 @@ var EntityCollection = class extends Destroyable {
15372
15640
  this.values$.next(Array.from(this.collectionData.values()));
15373
15641
  };
15374
15642
  this._hasMore$ = this.createBehaviorSubject(true);
15375
- this._destroy$ = new import_cjs$8.Subject();
15643
+ this._destroy$ = new import_cjs$9.Subject();
15376
15644
  this.updateSubscription = this.update$.subscribe(this.upsertData);
15377
15645
  this.loading$.next(false);
15378
- 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$));
15646
+ 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$));
15379
15647
  }
15380
15648
  get loading() {
15381
15649
  return this.loading$.value;
@@ -15384,7 +15652,7 @@ var EntityCollection = class extends Destroyable {
15384
15652
  return this.fetchController.hasMore ?? true;
15385
15653
  }
15386
15654
  get updated$() {
15387
- 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$)));
15655
+ 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$)));
15388
15656
  }
15389
15657
  get values() {
15390
15658
  return Array.from(this.collectionData.values());
@@ -15403,7 +15671,7 @@ var EntityCollection = class extends Destroyable {
15403
15671
  this._hasMore$.next(this.fetchController.hasMore ?? false);
15404
15672
  this.loading$.next(false);
15405
15673
  } catch (error) {
15406
- logger$8.error(`Failed to fetch initial collection data`, error);
15674
+ logger$9.error(`Failed to fetch initial collection data`, error);
15407
15675
  this._hasMore$.next(this.fetchController.hasMore ?? false);
15408
15676
  this.loading$.next(false);
15409
15677
  this.onError?.(new CollectionFetchError("fetchMore", error));
@@ -15417,14 +15685,14 @@ var EntityCollection = class extends Destroyable {
15417
15685
  if (data) this.upsertData(data);
15418
15686
  return data;
15419
15687
  } catch (error) {
15420
- logger$8.error(`Failed to fetch data for (${String(key)}:${String(value)}) :`, error);
15688
+ logger$9.error(`Failed to fetch data for (${String(key)}:${String(value)}) :`, error);
15421
15689
  this.loading$.next(false);
15422
15690
  this.onError?.(new CollectionFetchError(`tryFetch(${String(key)})`, error));
15423
15691
  }
15424
15692
  }
15425
15693
  get$(id) {
15426
15694
  if (!this.observablesRegistry.has(id)) {
15427
- this.observablesRegistry.set(id, new import_cjs$8.ReplaySubject(1));
15695
+ this.observablesRegistry.set(id, new import_cjs$9.ReplaySubject(1));
15428
15696
  const data = this.collectionData.get(id);
15429
15697
  if (data) this.observablesRegistry.get(id)?.next(data);
15430
15698
  else this.tryFetch("id", id);
@@ -15447,9 +15715,9 @@ var EntityCollection = class extends Destroyable {
15447
15715
  }
15448
15716
  };
15449
15717
  var EntityCollectionTransformed = class {
15450
- constructor(originalCollection, filter$13 = (i) => !!i, mapper = (item) => item) {
15718
+ constructor(originalCollection, filter$14 = (i) => !!i, mapper = (item) => item) {
15451
15719
  this.originalCollection = originalCollection;
15452
- this.filter = filter$13;
15720
+ this.filter = filter$14;
15453
15721
  this.mapper = mapper;
15454
15722
  }
15455
15723
  get loading$() {
@@ -15468,15 +15736,15 @@ var EntityCollectionTransformed = class {
15468
15736
  return this.originalCollection.values.filter(this.filter).map(this.mapper);
15469
15737
  }
15470
15738
  get values$() {
15471
- return this._values$ ??= this.originalCollection.values$.pipe((0, import_cjs$8.map)((values) => values.filter(this.filter).map(this.mapper)));
15739
+ return this._values$ ??= this.originalCollection.values$.pipe((0, import_cjs$9.map)((values) => values.filter(this.filter).map(this.mapper)));
15472
15740
  }
15473
15741
  get$(id) {
15474
15742
  const original$ = this.originalCollection.get$(id);
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
  async find$(key, value) {
15478
15746
  const original$ = await this.originalCollection.find$(key, value);
15479
- return !original$ ? original$ : original$.pipe((0, import_cjs$8.pipe)((0, import_cjs$8.filter)(this.filter), (0, import_cjs$8.map)(this.mapper)));
15747
+ return !original$ ? original$ : original$.pipe((0, import_cjs$9.pipe)((0, import_cjs$9.filter)(this.filter), (0, import_cjs$9.map)(this.mapper)));
15480
15748
  }
15481
15749
  loadMore() {
15482
15750
  this.originalCollection.loadMore();
@@ -15488,7 +15756,7 @@ var EntityCollectionTransformed = class {
15488
15756
 
15489
15757
  //#endregion
15490
15758
  //#region src/core/entities/Address.ts
15491
- var import_cjs$7 = require_cjs();
15759
+ var import_cjs$8 = require_cjs();
15492
15760
  /**
15493
15761
  * Represents a contact or room in the directory.
15494
15762
  *
@@ -15506,8 +15774,8 @@ var Address = class extends Destroyable {
15506
15774
  if (this._conversationMessages.hasMore) this._conversationMessages.loadMore();
15507
15775
  return this._conversationMessages;
15508
15776
  };
15509
- 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$));
15510
- 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$));
15777
+ 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$));
15778
+ 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$));
15511
15779
  this._state$ = this.createBehaviorSubject(null);
15512
15780
  }
15513
15781
  /** @internal */
@@ -15542,7 +15810,7 @@ var Address = class extends Destroyable {
15542
15810
  }
15543
15811
  /** Observable of the human-readable display name. */
15544
15812
  get displayName$() {
15545
- return this.cachedObservable("displayName$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.map)((state) => state.display_name), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15813
+ return this.cachedObservable("displayName$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.map)((state) => state.display_name), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15546
15814
  }
15547
15815
  /** Human-readable display name. */
15548
15816
  get displayName() {
@@ -15551,7 +15819,7 @@ var Address = class extends Destroyable {
15551
15819
  }
15552
15820
  /** Observable of the preview image URL. */
15553
15821
  get previewUrl$() {
15554
- return this.cachedObservable("previewUrl$", () => this._state$.pipe(filterNull(), (0, import_cjs$7.map)((state) => state.preview_url), (0, import_cjs$7.takeUntil)(this.destroyed$)));
15822
+ return this.cachedObservable("previewUrl$", () => this._state$.pipe(filterNull(), (0, import_cjs$8.map)((state) => state.preview_url), (0, import_cjs$8.takeUntil)(this.destroyed$)));
15555
15823
  }
15556
15824
  /** Preview image URL. */
15557
15825
  get previewUrl() {
@@ -15560,7 +15828,7 @@ var Address = class extends Destroyable {
15560
15828
  }
15561
15829
  /** Observable of the cover image URL. */
15562
15830
  get coverUrl$() {
15563
- 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$)));
15831
+ 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$)));
15564
15832
  }
15565
15833
  /** Cover image URL. */
15566
15834
  get coverUrl() {
@@ -15569,7 +15837,7 @@ var Address = class extends Destroyable {
15569
15837
  }
15570
15838
  /** Observable of the underlying resource ID. */
15571
15839
  get resourceId$() {
15572
- 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$)));
15840
+ 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$)));
15573
15841
  }
15574
15842
  /** Underlying resource ID. */
15575
15843
  get resourceId() {
@@ -15578,7 +15846,7 @@ var Address = class extends Destroyable {
15578
15846
  }
15579
15847
  /** Observable of the resource type (e.g. `'room'`, `'subscriber'`). */
15580
15848
  get type$() {
15581
- 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$)));
15849
+ 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$)));
15582
15850
  }
15583
15851
  /** Resource type (e.g. `'room'`, `'subscriber'`). */
15584
15852
  get type() {
@@ -15587,7 +15855,7 @@ var Address = class extends Destroyable {
15587
15855
  }
15588
15856
  /** Observable of available communication channels (audio, video, messaging). */
15589
15857
  get channels$() {
15590
- 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$)));
15858
+ 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$)));
15591
15859
  }
15592
15860
  /** Available communication channels. */
15593
15861
  get channels() {
@@ -15601,7 +15869,7 @@ var Address = class extends Destroyable {
15601
15869
  }
15602
15870
  /** Observable indicating whether the address (room) is locked. */
15603
15871
  get locked$() {
15604
- 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$)));
15872
+ 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$)));
15605
15873
  }
15606
15874
  /**
15607
15875
  * Sends a text message to this address.
@@ -15667,14 +15935,14 @@ var Address = class extends Destroyable {
15667
15935
 
15668
15936
  //#endregion
15669
15937
  //#region src/core/utils.ts
15670
- var import_cjs$6 = require_cjs();
15671
- const logger$7 = getLogger();
15938
+ var import_cjs$7 = require_cjs();
15939
+ const logger$8 = getLogger();
15672
15940
  const isRPCConnectResult = (e) => {
15673
- logger$7.debug("isRPCConnectResult check:", e);
15941
+ logger$8.debug("isRPCConnectResult check:", e);
15674
15942
  if (!e || typeof e !== "object") return false;
15675
15943
  const result = e;
15676
15944
  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";
15677
- logger$7.debug("isRPCConnectResult check result:", is);
15945
+ logger$8.debug("isRPCConnectResult check result:", is);
15678
15946
  return is;
15679
15947
  };
15680
15948
  var PendingRPC = class PendingRPC {
@@ -15683,7 +15951,7 @@ var PendingRPC = class PendingRPC {
15683
15951
  }
15684
15952
  constructor(request, responses$, options) {
15685
15953
  this.id = v4_default();
15686
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}: method:${request.method}] Creating PendingRPC`);
15954
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}: method:${request.method}] Creating PendingRPC`);
15687
15955
  this.request = request;
15688
15956
  const timeoutMs = options?.timeoutMs ?? PendingRPC.defaultTimeoutMs;
15689
15957
  const signal = options?.signal;
@@ -15693,38 +15961,38 @@ var PendingRPC = class PendingRPC {
15693
15961
  return;
15694
15962
  }
15695
15963
  let isSettled = false;
15696
- 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) => {
15697
- const timer$1 = setTimeout(() => {
15964
+ 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) => {
15965
+ const timer$2 = setTimeout(() => {
15698
15966
  subscriber.error(new RPCTimeoutError(request.id, timeoutMs));
15699
15967
  }, timeoutMs);
15700
- return () => clearTimeout(timer$1);
15701
- }), signal ? new import_cjs$6.Observable((subscriber) => {
15968
+ return () => clearTimeout(timer$2);
15969
+ }), signal ? new import_cjs$7.Observable((subscriber) => {
15702
15970
  const abortHandler = () => {
15703
15971
  subscriber.error(new DOMException("The operation was aborted", "AbortError"));
15704
15972
  };
15705
15973
  signal.addEventListener("abort", abortHandler);
15706
15974
  return () => signal.removeEventListener("abort", abortHandler);
15707
- }) : import_cjs$6.NEVER).subscribe({
15975
+ }) : import_cjs$7.NEVER).subscribe({
15708
15976
  next: (response) => {
15709
15977
  isSettled = true;
15710
15978
  if (response.error) {
15711
15979
  const rpcError = new JSONRPCError(response.error.code, response.error.message, response.error.data, void 0, request.id);
15712
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with RPC error:`, rpcError);
15980
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with RPC error:`, rpcError);
15713
15981
  reject(rpcError);
15714
15982
  } else {
15715
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Resolving promise with response:`, response);
15983
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Resolving promise with response:`, response);
15716
15984
  resolve(response);
15717
15985
  }
15718
15986
  subscription.unsubscribe();
15719
15987
  },
15720
15988
  error: (error) => {
15721
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with error:`, error);
15989
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Rejecting promise with error:`, error);
15722
15990
  isSettled = true;
15723
15991
  reject(error);
15724
15992
  subscription.unsubscribe();
15725
15993
  },
15726
15994
  complete: () => {
15727
- logger$7.debug(`[PendingRPC(${this.id}) request:${request.id}] Observable completed`);
15995
+ logger$8.debug(`[PendingRPC(${this.id}) request:${request.id}] Observable completed`);
15728
15996
  if (!isSettled) reject(new RPCTimeoutError(request.id, timeoutMs));
15729
15997
  subscription.unsubscribe();
15730
15998
  }
@@ -15744,8 +16012,8 @@ var PendingRPC = class PendingRPC {
15744
16012
 
15745
16013
  //#endregion
15746
16014
  //#region src/managers/ClientSessionManager.ts
15747
- var import_cjs$5 = require_cjs();
15748
- const logger$6 = getLogger();
16015
+ var import_cjs$6 = require_cjs();
16016
+ const logger$7 = getLogger();
15749
16017
  const getAddressSearchURI = (options) => {
15750
16018
  const to = options.to?.split("?")[0];
15751
16019
  const from$7 = options.from?.startsWith("subscriber://") ? options.from.replace("subscriber://", "") : options.from;
@@ -15754,13 +16022,14 @@ const getAddressSearchURI = (options) => {
15754
16022
  return name;
15755
16023
  };
15756
16024
  var ClientSessionManager = class extends Destroyable {
15757
- constructor(credential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider) {
16025
+ constructor(getCredential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider, dpopManager) {
15758
16026
  super();
15759
- this.credential = credential;
16027
+ this.getCredential = getCredential;
15760
16028
  this.transport = transport;
15761
16029
  this.storage = storage;
15762
16030
  this.authorizationStateKey = authorizationStateKey;
15763
16031
  this.attachManager = attachManager;
16032
+ this.dpopManager = dpopManager;
15764
16033
  this.callCreateTimeout = 6e3;
15765
16034
  this.agent = `signalwire-typescript-sdk/1.0.0`;
15766
16035
  this.eventAcks = true;
@@ -15773,15 +16042,16 @@ var ClientSessionManager = class extends Destroyable {
15773
16042
  this._authorization$ = this.createBehaviorSubject(void 0);
15774
16043
  this._errors$ = this.createReplaySubject(1);
15775
16044
  this._authenticated$ = this.createBehaviorSubject(false);
16045
+ this._clientBound = false;
15776
16046
  this._subscriberInfo$ = this.createBehaviorSubject(null);
15777
16047
  this._calls$ = this.createBehaviorSubject({});
15778
16048
  this._iceServers$ = this.createBehaviorSubject([]);
15779
16049
  attachManager.setSession(this);
15780
16050
  this.callFactory = new CallFactory(this, deviceController, attachManager, webRTCApiProvider);
15781
- 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$));
16051
+ 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$));
15782
16052
  }
15783
16053
  get incomingCalls$() {
15784
- return this.cachedObservable("incomingCalls$", () => this.calls$.pipe((0, import_cjs$5.map)((calls) => calls.filter((call) => call.direction === "inbound"))));
16054
+ return this.cachedObservable("incomingCalls$", () => this.calls$.pipe((0, import_cjs$6.map)((calls) => calls.filter((call) => call.direction === "inbound"))));
15785
16055
  }
15786
16056
  get incomingCalls() {
15787
16057
  return Object.values(this._calls$.value).filter((call) => call.direction === "inbound");
@@ -15793,7 +16063,7 @@ var ClientSessionManager = class extends Destroyable {
15793
16063
  return this._subscriberInfo$.value;
15794
16064
  }
15795
16065
  get calls$() {
15796
- return this.cachedObservable("calls$", () => this._calls$.pipe((0, import_cjs$5.map)((calls) => Object.values(calls))));
16066
+ return this.cachedObservable("calls$", () => this._calls$.pipe((0, import_cjs$6.map)((calls) => Object.values(calls))));
15797
16067
  }
15798
16068
  get calls() {
15799
16069
  return Object.values(this._calls$.value);
@@ -15817,6 +16087,15 @@ var ClientSessionManager = class extends Destroyable {
15817
16087
  return this._authenticated$.value;
15818
16088
  }
15819
16089
  /**
16090
+ * Whether this session is client-bound (using a Client Bound SAT).
16091
+ * When client-bound, DPoP proof creation failures are treated as
16092
+ * authentication errors rather than silently degraded.
16093
+ * @internal
16094
+ */
16095
+ get clientBound() {
16096
+ return this._clientBound;
16097
+ }
16098
+ /**
15820
16099
  * Set the directory instance
15821
16100
  * Called by SignalWire after directory is created
15822
16101
  * @internal
@@ -15828,7 +16107,7 @@ var ClientSessionManager = class extends Destroyable {
15828
16107
  try {
15829
16108
  return await this.transport.execute(request, options);
15830
16109
  } catch (error) {
15831
- logger$6.debug("[Session] Execute Error", error);
16110
+ logger$7.debug("[Session] Execute Error", error);
15832
16111
  this._errors$.next(error instanceof Error ? error : new Error(String(error), { cause: error }));
15833
16112
  throw error;
15834
16113
  }
@@ -15842,32 +16121,31 @@ var ClientSessionManager = class extends Destroyable {
15842
16121
  return true;
15843
16122
  }
15844
16123
  setupMessageHandlers() {
15845
- logger$6.debug("[Session] Setting up message handlers");
16124
+ logger$7.debug("[Session] Setting up message handlers");
15846
16125
  this.subscribeTo(this.authStateEvent$, async (authStateEvent) => {
15847
- logger$6.debug("[Session] Authorization state event received:", authStateEvent);
16126
+ logger$7.debug("[Session] Authorization state event received:", authStateEvent);
15848
16127
  try {
15849
16128
  await this.updateAuthorizationStateInStorage(authStateEvent.authorization_state);
15850
16129
  } catch (error) {
15851
- logger$6.error("[Session] Failed to handle authorization state update:", error);
16130
+ logger$7.error("[Session] Failed to handle authorization state update:", error);
15852
16131
  this._errors$.next(new AuthStateHandlerError(error));
15853
16132
  }
15854
16133
  });
15855
- this.subscribeTo(this.transport.connectionStatus$.pipe((0, import_cjs$5.filter)((status) => status === "connected")), async () => {
15856
- try {
15857
- logger$6.debug("[Session] Connection established, initiating authentication");
15858
- await this.authenticate();
15859
- } catch (error) {
16134
+ this.subscribeTo(this.transport.connectionStatus$.pipe((0, import_cjs$6.filter)((status) => status === "connected"), (0, import_cjs$6.exhaustMap)(() => {
16135
+ logger$7.debug("[Session] Connection established, initiating authentication");
16136
+ return (0, import_cjs$6.from)(this.authenticate()).pipe((0, import_cjs$6.catchError)((error) => {
15860
16137
  this.handleAuthenticationError(error).catch((err) => {
15861
- logger$6.error("[Session] Error handling authentication failure:", err);
16138
+ logger$7.error("[Session] Error handling authentication failure:", err);
15862
16139
  });
15863
- }
15864
- });
16140
+ return import_cjs$6.EMPTY;
16141
+ }));
16142
+ })), void 0);
15865
16143
  this.subscribeTo(this.vertoInvite$, async (invite) => {
15866
- logger$6.debug("[Session] Verto invite received:", invite);
16144
+ logger$7.debug("[Session] Verto invite received:", invite);
15867
16145
  try {
15868
16146
  await this.createInboundCall(invite);
15869
16147
  } catch (error) {
15870
- logger$6.error("[Session] Error handling Verto invite:", error);
16148
+ logger$7.error("[Session] Error handling Verto invite:", error);
15871
16149
  this._errors$.next(new VertoInviteHandlerError(error));
15872
16150
  }
15873
16151
  });
@@ -15877,42 +16155,42 @@ var ClientSessionManager = class extends Destroyable {
15877
16155
  const storedState = await this.storage.getItem(this.authorizationStateKey);
15878
16156
  this.authorizationState$.next(storedState ?? void 0);
15879
16157
  } catch (error) {
15880
- logger$6.error("Failed to retrieve authorization state from storage:", error);
16158
+ logger$7.error("Failed to retrieve authorization state from storage:", error);
15881
16159
  this.authorizationState$.next(void 0);
15882
16160
  }
15883
16161
  }
15884
16162
  async updateAuthorizationStateInStorage(authorizationState) {
15885
16163
  if (!authorizationState) {
15886
- logger$6.debug("[Session] Removing authorization state from storage");
16164
+ logger$7.debug("[Session] Removing authorization state from storage");
15887
16165
  try {
15888
16166
  await this.storage.removeItem(this.authorizationStateKey);
15889
16167
  } catch (error) {
15890
- logger$6.error("Failed to remove authorization state from storage:", error);
16168
+ logger$7.error("Failed to remove authorization state from storage:", error);
15891
16169
  throw error;
15892
16170
  }
15893
16171
  return;
15894
16172
  }
15895
16173
  try {
15896
- logger$6.debug("[Session] Updating authorization state in storage");
16174
+ logger$7.debug("[Session] Updating authorization state in storage");
15897
16175
  await this.storage.setItem(this.authorizationStateKey, authorizationState);
15898
16176
  this.authorizationState$.next(authorizationState);
15899
16177
  } catch (error) {
15900
- logger$6.error("Failed to retrieve authorization state from storage:", error);
16178
+ logger$7.error("Failed to retrieve authorization state from storage:", error);
15901
16179
  throw error;
15902
16180
  }
15903
16181
  }
15904
16182
  get authStateEvent$() {
15905
- return this.cachedObservable("authStateEvent$", () => this.signalingEvent$.pipe((0, import_cjs$5.tap)((msg) => {
15906
- logger$6.debug("[Session] Received incoming message:", msg);
15907
- }), filterAs(isSignalwireAuthorizationStateMetadata, "params"), (0, import_cjs$5.tap)((event) => {
15908
- logger$6.debug("[Session] Authorization state event received:", event.authorization_state);
16183
+ return this.cachedObservable("authStateEvent$", () => this.signalingEvent$.pipe((0, import_cjs$6.tap)((msg) => {
16184
+ logger$7.debug("[Session] Received incoming message:", msg);
16185
+ }), filterAs(isSignalwireAuthorizationStateMetadata, "params"), (0, import_cjs$6.tap)((event) => {
16186
+ logger$7.debug("[Session] Authorization state event received:", event.authorization_state);
15909
16187
  })));
15910
16188
  }
15911
16189
  get signalingEvent$() {
15912
- return this.cachedObservable("signalingEvent$", () => this.transport.incomingEvent$.pipe(filterAs(isSignalwireRequest, "params"), (0, import_cjs$5.share)()));
16190
+ return this.cachedObservable("signalingEvent$", () => this.transport.incomingEvent$.pipe(filterAs(isSignalwireRequest, "params"), (0, import_cjs$6.share)()));
15913
16191
  }
15914
16192
  get vertoInvite$() {
15915
- 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) => ({
16193
+ 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) => ({
15916
16194
  node_id: event.node_id,
15917
16195
  ...event.params.params
15918
16196
  }))));
@@ -15927,86 +16205,118 @@ var ClientSessionManager = class extends Destroyable {
15927
16205
  return [];
15928
16206
  }
15929
16207
  get authentication() {
15930
- if (!this.credential.token) throw new DependencyError("Credential token is undefined");
15931
- return { jwt_token: this.credential.token };
16208
+ const credential = this.getCredential();
16209
+ if (!credential.token) throw new DependencyError("Credential token is undefined");
16210
+ return { jwt_token: credential.token };
15932
16211
  }
15933
16212
  async connect() {
15934
- await (0, import_cjs$5.firstValueFrom)(this.initialized$);
16213
+ await (0, import_cjs$6.firstValueFrom)(this.initialized$);
15935
16214
  await this.transport.connect();
15936
16215
  }
15937
16216
  async handleAuthenticationError(error) {
15938
- logger$6.error("Authentication error:", error);
16217
+ logger$7.error("Authentication error:", error);
15939
16218
  this._errors$.next(error);
15940
- if (error.message === "Requester validation failed") try {
15941
- await this.cleanupStoredConnectionParams();
15942
- } catch (error$1) {
15943
- logger$6.error("Failed to cleanup stored connection params:", error$1);
15944
- } finally {
15945
- this.transport.reconnect();
16219
+ const isRecoverableAuthError = error instanceof JSONRPCError && (error.code === RPC_ERROR_REQUESTER_VALIDATION_FAILED || error.code === RPC_ERROR_INVALID_PARAMS || error.code === RPC_ERROR_AUTHENTICATION_FAILED);
16220
+ const hasStoredState = this._authorization$.value !== void 0;
16221
+ if (isRecoverableAuthError && hasStoredState) {
16222
+ logger$7.debug("[Session] Recoverable auth error — cleaning up stored state and reconnecting fresh");
16223
+ try {
16224
+ await this.cleanupStoredConnectionParams();
16225
+ } catch (cleanupError) {
16226
+ logger$7.error("Failed to cleanup stored connection params:", cleanupError);
16227
+ } finally {
16228
+ this.transport.reconnect();
16229
+ }
15946
16230
  }
15947
16231
  }
15948
16232
  async cleanupStoredConnectionParams() {
15949
16233
  await this.transport.setProtocol(void 0);
15950
16234
  await this.updateAuthorizationStateInStorage(void 0);
16235
+ this._authorization$.next(void 0);
15951
16236
  await this.attachManager.detachAll();
15952
16237
  }
15953
16238
  async updateAuthState(authorization_state) {
15954
16239
  try {
15955
16240
  await this.storage.setItem(this.authorizationStateKey, authorization_state);
15956
16241
  } catch (error) {
15957
- logger$6.error("Failed to update authorization state in storage:", error);
16242
+ logger$7.error("Failed to update authorization state in storage:", error);
15958
16243
  this._errors$.next(new AuthStateHandlerError(error));
15959
16244
  }
15960
16245
  }
15961
- async reauthenticate(token) {
15962
- logger$6.debug("[Session] Re-authenticating session");
16246
+ async reauthenticate(token, dpopToken, options) {
16247
+ logger$7.debug("[Session] Re-authenticating session");
15963
16248
  try {
16249
+ let resolvedDpopToken = dpopToken;
16250
+ if (!resolvedDpopToken && this.dpopManager?.initialized) try {
16251
+ resolvedDpopToken = await this.dpopManager.createRpcProof({ method: "signalwire.reauthenticate" });
16252
+ } catch (error) {
16253
+ if (this._clientBound) throw error;
16254
+ logger$7.warn("[Session] Failed to create DPoP proof for reauthenticate:", error);
16255
+ }
15964
16256
  const request = RPCReauthenticate({
15965
16257
  project: this._authorization$.value?.project_id ?? "",
15966
- jwt_token: token
16258
+ jwt_token: token,
16259
+ ...resolvedDpopToken ? { dpop_token: resolvedDpopToken } : {}
15967
16260
  });
15968
- 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) => {
15969
- logger$6.error("[Session] Re-authentication RPC failed:", err);
16261
+ 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) => {
16262
+ logger$7.error("[Session] Re-authentication RPC failed:", err);
15970
16263
  throw err;
15971
16264
  })));
15972
- logger$6.debug("[Session] Re-authentication successful, updating stored auth state");
16265
+ if (options?.clientBound) this._clientBound = true;
16266
+ logger$7.debug("[Session] Re-authentication successful, updating stored auth state");
15973
16267
  } catch (error) {
15974
- logger$6.error("[Session] Re-authentication failed:", error);
16268
+ logger$7.error("[Session] Re-authentication failed:", error);
15975
16269
  this._errors$.next(new AuthStateHandlerError(error));
15976
16270
  throw error;
15977
16271
  }
15978
16272
  }
15979
16273
  async authenticate() {
15980
- logger$6.debug("[Session] Starting authentication process");
15981
- const params = {
15982
- authentication: this.authentication,
15983
- version: this.connectVersion,
15984
- agent: this.agent,
15985
- contexts: this.contexts,
15986
- eventing: this.eventing,
15987
- topics: this.topics,
15988
- event_acks: this.eventAcks
15989
- };
15990
- const persistedParams = await (0, import_cjs$5.firstValueFrom)((0, import_cjs$5.combineLatest)({
16274
+ logger$7.debug("[Session] Starting authentication process");
16275
+ const persistedParams = await (0, import_cjs$6.firstValueFrom)((0, import_cjs$6.combineLatest)({
15991
16276
  protocol: this.transport.protocol$,
15992
16277
  authorization_state: this.authorizationState$
15993
- }).pipe((0, import_cjs$5.take)(1)));
15994
- logger$6.debug("[Session] Persisted params:\n", {
16278
+ }).pipe((0, import_cjs$6.take)(1)));
16279
+ logger$7.debug("[Session] Persisted params:\n", {
15995
16280
  protocol: persistedParams.protocol,
15996
16281
  authStateLength: persistedParams.authorization_state?.length
15997
16282
  });
16283
+ this.transport.resetSessionEpoch();
16284
+ const hasReconnectState = persistedParams.authorization_state && persistedParams.protocol;
16285
+ const storedToken = this.getCredential().token;
16286
+ const isReconnect = hasReconnectState && storedToken;
16287
+ let dpopToken;
16288
+ if (isReconnect) logger$7.debug("[Session] Reconnecting with stored jwt_token + authorization_state");
16289
+ else if (this.onBeforeReconnect && this._clientBound) {
16290
+ logger$7.debug("[Session] Refreshing credentials before fresh connect");
16291
+ await this.onBeforeReconnect();
16292
+ }
16293
+ if (this.dpopManager?.initialized) try {
16294
+ dpopToken = await this.dpopManager.createRpcProof({ method: "signalwire.connect" });
16295
+ } catch (error) {
16296
+ if (this._clientBound) throw error;
16297
+ logger$7.warn("[Session] Failed to create DPoP proof for connect, proceeding without:", error);
16298
+ }
15998
16299
  const rpcConnectRequest = RPCConnect({
15999
- ...params,
16000
- ...persistedParams
16300
+ authentication: isReconnect ? { jwt_token: storedToken } : this.authentication,
16301
+ version: this.connectVersion,
16302
+ agent: this.agent,
16303
+ contexts: this.contexts,
16304
+ eventing: this.eventing,
16305
+ topics: this.topics,
16306
+ event_acks: this.eventAcks,
16307
+ ...dpopToken ? { dpop_token: dpopToken } : {},
16308
+ ...isReconnect ? {
16309
+ authorization_state: persistedParams.authorization_state,
16310
+ protocol: persistedParams.protocol
16311
+ } : {}
16001
16312
  });
16002
- this.transport.resetSessionEpoch();
16003
- 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)(() => {
16004
- logger$6.debug("[Session] Response passed filter, processing authentication result");
16005
- }), (0, import_cjs$5.take)(1), (0, import_cjs$5.catchError)((err) => {
16006
- logger$6.error("[Session] Authentication RPC failed:", err);
16313
+ 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)(() => {
16314
+ logger$7.debug("[Session] Response passed filter, processing authentication result");
16315
+ }), (0, import_cjs$6.take)(1), (0, import_cjs$6.catchError)((err) => {
16316
+ logger$7.error("[Session] Authentication RPC failed:", err);
16007
16317
  throw err;
16008
16318
  })));
16009
- logger$6.debug("[Session] Processing authentication result:", {
16319
+ logger$7.debug("[Session] Processing authentication result:", {
16010
16320
  hasProtocol: !!response.protocol,
16011
16321
  hasAuthorization: !!response.authorization,
16012
16322
  hasIceServers: !!response.ice_servers
@@ -16015,7 +16325,7 @@ var ClientSessionManager = class extends Destroyable {
16015
16325
  this._authorization$.next(response.authorization);
16016
16326
  this._iceServers$.next(response.ice_servers ?? []);
16017
16327
  this._authenticated$.next(true);
16018
- logger$6.debug("[Session] Authentication completed successfully");
16328
+ logger$7.debug("[Session] Authentication completed successfully");
16019
16329
  }
16020
16330
  async disconnect() {
16021
16331
  this.transport.disconnect();
@@ -16034,7 +16344,7 @@ var ClientSessionManager = class extends Destroyable {
16034
16344
  displayDirection: invite.display_direction,
16035
16345
  userVariables: invite.userVariables
16036
16346
  });
16037
- await (0, import_cjs$5.firstValueFrom)(callSession.status$);
16347
+ await (0, import_cjs$6.firstValueFrom)(callSession.status$);
16038
16348
  this._calls$.next({
16039
16349
  [`${callSession.id}`]: callSession,
16040
16350
  ...this._calls$.value
@@ -16048,16 +16358,16 @@ var ClientSessionManager = class extends Destroyable {
16048
16358
  to: destinationURI,
16049
16359
  ...options
16050
16360
  });
16051
- 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)))));
16361
+ 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)))));
16052
16362
  this._calls$.next({
16053
16363
  [`${callSession.id}`]: callSession,
16054
16364
  ...this._calls$.value
16055
16365
  });
16056
16366
  return callSession;
16057
16367
  } catch (error) {
16058
- logger$6.error("[Session] Error creating outbound call:", error);
16368
+ logger$7.error("[Session] Error creating outbound call:", error);
16059
16369
  callSession?.destroy();
16060
- const callError = new CallCreateError(error instanceof import_cjs$5.TimeoutError ? "Call create timeout" : "Call creation failed", error, "outbound");
16370
+ const callError = new CallCreateError(error instanceof import_cjs$6.TimeoutError ? "Call create timeout" : "Call creation failed", error, "outbound");
16061
16371
  this._errors$.next(callError);
16062
16372
  throw callError;
16063
16373
  }
@@ -16072,17 +16382,17 @@ var ClientSessionManager = class extends Destroyable {
16072
16382
  if (!addressId) throw new DependencyError(`Address name: ${addressURI} not found`);
16073
16383
  address = this._directory.get(addressId);
16074
16384
  if (!address) throw new DependencyError(`Address ID: ${addressId} not found`);
16075
- } catch (error) {
16076
- logger$6.warn(`[Session] Directory lookup failed for ${addressURI}, proceeding with raw URI`);
16385
+ } catch {
16386
+ logger$7.warn(`[Session] Directory lookup failed for ${addressURI}, proceeding with raw URI`);
16077
16387
  }
16078
16388
  const callSession = this.callFactory.createCall(address, { ...options });
16079
- callSession.status$.pipe((0, import_cjs$5.filter)((status) => status === "destroyed"), (0, import_cjs$5.take)(1)).subscribe(() => {
16389
+ callSession.status$.pipe((0, import_cjs$6.filter)((status) => status === "destroyed"), (0, import_cjs$6.take)(1)).subscribe(() => {
16080
16390
  const { [`${callSession.id}`]: _, ...remainingCalls } = this._calls$.value;
16081
16391
  this._calls$.next(remainingCalls);
16082
16392
  });
16083
16393
  return callSession;
16084
16394
  } catch (error) {
16085
- logger$6.error("[Session] Error creating call session:", error);
16395
+ logger$7.error("[Session] Error creating call session:", error);
16086
16396
  throw new CallCreateError("Call create error", error, options.initOffer ? "inbound" : "outbound");
16087
16397
  }
16088
16398
  }
@@ -16130,8 +16440,8 @@ const isString = (obj) => typeof obj === "string";
16130
16440
 
16131
16441
  //#endregion
16132
16442
  //#region src/managers/ConversationsManager.ts
16133
- var import_cjs$4 = require_cjs();
16134
- const logger$5 = getLogger();
16443
+ var import_cjs$5 = require_cjs();
16444
+ const logger$6 = getLogger();
16135
16445
  var ConversationMessagesFetcher = class extends Fetcher {
16136
16446
  constructor(groupId, http) {
16137
16447
  super(`/api/fabric/conversations/${groupId}/messages`, "page_size=100", http);
@@ -16171,13 +16481,13 @@ var ConversationsManager = class {
16171
16481
  }
16172
16482
  throw new ConversationError("Join Failed - Unexpected response");
16173
16483
  } catch (error) {
16174
- logger$5.error("[ConversationsManager] Failed to join conversation:", error);
16484
+ logger$6.error("[ConversationsManager] Failed to join conversation:", error);
16175
16485
  throw error;
16176
16486
  }
16177
16487
  }
16178
16488
  async getConversationMessageCollection(addressId) {
16179
16489
  const groupId = this.groupIds.get(addressId) ?? await this.join(addressId);
16180
- 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));
16490
+ 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));
16181
16491
  }
16182
16492
  async sendText(text, destinationAddressId) {
16183
16493
  const groupId = this.groupIds.get(destinationAddressId) ?? await this.join(destinationAddressId);
@@ -16194,9 +16504,209 @@ var ConversationsManager = class {
16194
16504
  })).ok) return;
16195
16505
  throw new ConversationError("Send Text Failed - Unexpected response");
16196
16506
  } catch (error) {
16197
- logger$5.error("[ConversationsManager] Failed to send text message:", error);
16507
+ logger$6.error("[ConversationsManager] Failed to send text message:", error);
16508
+ }
16509
+ }
16510
+ };
16511
+
16512
+ //#endregion
16513
+ //#region src/managers/DeviceTokenManager.ts
16514
+ var import_cjs$4 = require_cjs();
16515
+ const logger$5 = getLogger();
16516
+ /**
16517
+ * Resolves the token expiry timestamp (epoch seconds) using a 3-tier priority chain:
16518
+ * 1. `data.expires_at` — server-provided absolute timestamp
16519
+ * 2. `data.expires_in` — server-provided relative lifetime
16520
+ * 3. Fallback to `DEVICE_TOKEN_DEFAULT_EXPIRE_IN` with a warning
16521
+ */
16522
+ function resolveExpiresAt(data) {
16523
+ if (data.expires_at) return data.expires_at;
16524
+ if (data.expires_in) return Math.floor(Date.now() / 1e3) + data.expires_in;
16525
+ logger$5.warn("[DeviceToken] Could not determine token expiry, using default");
16526
+ return Math.floor(Date.now() / 1e3) + DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
16527
+ }
16528
+ /**
16529
+ * Resolves the token TTL in seconds from a fresh response.
16530
+ * Called at token receive time so `expires_at - now` reflects the original lifetime.
16531
+ *
16532
+ * 1. `data.expires_in` — server-provided TTL directly
16533
+ * 2. `data.expires_at - now` — derive TTL from absolute timestamp
16534
+ * 3. Fallback to `DEVICE_TOKEN_DEFAULT_EXPIRE_IN`
16535
+ */
16536
+ function resolveExpireIn(data) {
16537
+ if (data.expires_in) return data.expires_in;
16538
+ if (data.expires_at) return Math.max(data.expires_at - Math.floor(Date.now() / 1e3), 1);
16539
+ return DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
16540
+ }
16541
+ /**
16542
+ * Manages the Client Bound SAT lifecycle: activation, token exchange,
16543
+ * reauthentication, and automatic refresh scheduling.
16544
+ *
16545
+ * Extends {@link Destroyable} for automatic RxJS subscription and subject cleanup.
16546
+ * Uses a reactive pipeline (`BehaviorSubject` + `switchMap(timer())`) instead of
16547
+ * raw `setTimeout` for refresh scheduling.
16548
+ */
16549
+ var DeviceTokenManager = class extends Destroyable {
16550
+ constructor(dpopManager, http, errorHandler, getCredential) {
16551
+ super();
16552
+ this.dpopManager = dpopManager;
16553
+ this.http = http;
16554
+ this.errorHandler = errorHandler;
16555
+ this.getCredential = getCredential;
16556
+ this._currentToken$ = this.createBehaviorSubject(null);
16557
+ this._refreshInProgress = false;
16558
+ this._effectiveExpireIn = DEVICE_TOKEN_DEFAULT_EXPIRE_IN;
16559
+ this.subscribeTo(this._currentToken$.pipe((0, import_cjs$4.filter)(Boolean), (0, import_cjs$4.switchMap)((tokenData) => {
16560
+ const expiresAt = resolveExpiresAt(tokenData);
16561
+ const refreshIn = Math.max(expiresAt * 1e3 - Date.now() - DEVICE_TOKEN_REFRESH_BUFFER_MS, 1e3);
16562
+ logger$5.debug(`[DeviceToken] Scheduling Client Bound SAT refresh in ${refreshIn}ms`);
16563
+ return (0, import_cjs$4.timer)(refreshIn);
16564
+ })), () => {
16565
+ this.executeRefresh();
16566
+ });
16567
+ }
16568
+ /**
16569
+ * Activates the Client Bound SAT flow when the subscriber's token has
16570
+ * `sat:refresh` scope.
16571
+ *
16572
+ * Steps:
16573
+ * 1. Check subscriber's `sat_claims` for `sat:refresh` scope
16574
+ * 2. Call `/api/fabric/subscriber/devices/token` with a DPoP proof
16575
+ * 3. Reauthenticate the session with the Client Bound SAT + DPoP proof
16576
+ * 4. Emit token to trigger the reactive refresh pipeline
16577
+ */
16578
+ async activate(subscriber, session, updateCredential) {
16579
+ const { satClaims } = subscriber;
16580
+ if (!satClaims?.scope?.includes(SAT_REFRESH_SCOPE)) {
16581
+ logger$5.debug("[DeviceToken] No sat:refresh scope, skipping Client Bound SAT activation");
16582
+ return;
16583
+ }
16584
+ this._session = session;
16585
+ this._updateCredential = updateCredential;
16586
+ try {
16587
+ const tokenData = await this.obtainToken();
16588
+ if (!tokenData.expires_at && !tokenData.expires_in && satClaims.expires_at) tokenData.expires_at = satClaims.expires_at;
16589
+ this._effectiveExpireIn = resolveExpireIn(tokenData);
16590
+ const rpcProof = await this.dpopManager.createRpcProof({ method: "signalwire.reauthenticate" });
16591
+ await session.reauthenticate(tokenData.token, rpcProof, { clientBound: true });
16592
+ updateCredential({ token: tokenData.token });
16593
+ logger$5.info("[DeviceToken] Client Bound SAT activated successfully");
16594
+ this._currentToken$.next(tokenData);
16595
+ } catch (error) {
16596
+ logger$5.error("[DeviceToken] Failed to activate Client Bound SAT:", error);
16597
+ this.errorHandler(new DPoPInitError(error, "Failed to activate Client Bound SAT"));
16198
16598
  }
16199
16599
  }
16600
+ /**
16601
+ * Obtains a Client Bound SAT from `/api/fabric/subscriber/devices/token`.
16602
+ * Returns the full {@link DeviceTokenResponse} including expiry metadata.
16603
+ */
16604
+ async obtainToken() {
16605
+ const dpopProof = await this.dpopManager.createHttpProof({
16606
+ method: "POST",
16607
+ uri: DEVICE_TOKEN_ENDPOINT
16608
+ });
16609
+ const response = await this.http.request({
16610
+ url: DEVICE_TOKEN_ENDPOINT,
16611
+ ...POST_PARAMS,
16612
+ body: JSON.stringify({
16613
+ dpop_token: dpopProof,
16614
+ expire_in: DEVICE_TOKEN_DEFAULT_EXPIRE_IN
16615
+ })
16616
+ });
16617
+ if (!response.ok || !response.body) throw new DeviceTokenError(`Failed to obtain device token: ${response.status} ${response.statusText}`);
16618
+ const data = JSON.parse(response.body);
16619
+ if (!data.token) throw new DeviceTokenError("Device token response missing token field");
16620
+ return data;
16621
+ }
16622
+ /**
16623
+ * Refreshes the Client Bound SAT via `/api/fabric/subscriber/devices/refresh`.
16624
+ *
16625
+ * Creates a fresh DPoP proof, calls the refresh endpoint, reauthenticates
16626
+ * the WebSocket session, and returns the new token data (scheduling is
16627
+ * handled by the reactive pipeline).
16628
+ */
16629
+ async refreshToken(session, currentToken, updateCredential) {
16630
+ logger$5.debug("[DeviceToken] Refreshing Client Bound SAT");
16631
+ const dpopProof = await this.dpopManager.createHttpProof({
16632
+ method: "POST",
16633
+ uri: DEVICE_REFRESH_ENDPOINT,
16634
+ accessToken: currentToken
16635
+ });
16636
+ const response = await this.http.request({
16637
+ url: DEVICE_REFRESH_ENDPOINT,
16638
+ ...POST_PARAMS,
16639
+ body: JSON.stringify({
16640
+ dpop_token: dpopProof,
16641
+ expire_in: this._effectiveExpireIn
16642
+ })
16643
+ });
16644
+ if (!response.ok || !response.body) throw new TokenRefreshError(`Failed to refresh device token: ${response.status} ${response.statusText}`);
16645
+ const data = JSON.parse(response.body);
16646
+ if (!data.token) throw new TokenRefreshError("Device token refresh response missing token field");
16647
+ if (!data.expires_at && !data.expires_in) data.expires_in = this._effectiveExpireIn;
16648
+ this._effectiveExpireIn = resolveExpireIn(data);
16649
+ const rpcProof = await this.dpopManager.createRpcProof({ method: "signalwire.reauthenticate" });
16650
+ await session.reauthenticate(data.token, rpcProof);
16651
+ updateCredential({ token: data.token });
16652
+ logger$5.info("[DeviceToken] Client Bound SAT refreshed successfully");
16653
+ return data;
16654
+ }
16655
+ /**
16656
+ * Executes a refresh with retry and exponential backoff.
16657
+ * On success, emits to `_currentToken$` to schedule the next refresh.
16658
+ * On all retries exhausted, emits to `errorHandler`.
16659
+ */
16660
+ async executeRefresh() {
16661
+ if (this._refreshInProgress) {
16662
+ logger$5.debug("[DeviceToken] Refresh already in progress, skipping");
16663
+ return;
16664
+ }
16665
+ const session = this._session;
16666
+ const updateCredential = this._updateCredential;
16667
+ if (!session || !updateCredential) {
16668
+ logger$5.warn("[DeviceToken] Cannot refresh: session or updateCredential not set");
16669
+ return;
16670
+ }
16671
+ if (!session.authenticated) {
16672
+ logger$5.debug("[DeviceToken] Session not authenticated, deferring refresh");
16673
+ return;
16674
+ }
16675
+ this._refreshInProgress = true;
16676
+ try {
16677
+ const currentToken = this.getCredential().token;
16678
+ if (!currentToken) throw new TokenRefreshError("No current token available for refresh");
16679
+ const newTokenData = await this.retryRefresh(session, currentToken, updateCredential);
16680
+ this._currentToken$.next(newTokenData);
16681
+ } catch (error) {
16682
+ logger$5.error("[DeviceToken] Automatic Client Bound SAT refresh failed:", error);
16683
+ this.errorHandler(error instanceof TokenRefreshError ? error : new TokenRefreshError("Automatic token refresh failed", error));
16684
+ } finally {
16685
+ this._refreshInProgress = false;
16686
+ }
16687
+ }
16688
+ /**
16689
+ * Retries `refreshToken()` up to `DEVICE_TOKEN_REFRESH_MAX_RETRIES` times
16690
+ * with exponential backoff (1s, 2s, 4s).
16691
+ */
16692
+ async retryRefresh(session, currentToken, updateCredential) {
16693
+ let lastError;
16694
+ for (let attempt = 0; attempt < DEVICE_TOKEN_REFRESH_MAX_RETRIES; attempt++) try {
16695
+ return await this.refreshToken(session, currentToken, updateCredential);
16696
+ } catch (error) {
16697
+ lastError = error;
16698
+ if (attempt < DEVICE_TOKEN_REFRESH_MAX_RETRIES - 1) {
16699
+ const delay$1 = DEVICE_TOKEN_REFRESH_RETRY_BASE_MS * Math.pow(2, attempt);
16700
+ logger$5.warn(`[DeviceToken] Refresh attempt ${attempt + 1} failed, retrying in ${delay$1}ms`);
16701
+ await new Promise((resolve) => setTimeout(resolve, delay$1));
16702
+ }
16703
+ }
16704
+ throw lastError instanceof Error ? lastError : new TokenRefreshError("All refresh retries exhausted", lastError);
16705
+ }
16706
+ /** Cleans up the manager, cancelling the reactive pipeline and all subscriptions. */
16707
+ destroy() {
16708
+ super.destroy();
16709
+ }
16200
16710
  };
16201
16711
 
16202
16712
  //#endregion
@@ -16367,6 +16877,10 @@ var WebSocketController = class WebSocketController extends Destroyable {
16367
16877
  this.outgoingMessages$ = outgoingMessages$;
16368
16878
  this.messageQueue = [];
16369
16879
  this.shouldReconnect = false;
16880
+ this.boundHandleOpen = () => this.handleOpen();
16881
+ this.boundHandleClose = (event) => this.handleClose(event);
16882
+ this.boundHandleError = () => this.handleError();
16883
+ this.boundHandleMessage = (event) => this.handleMessage(event);
16370
16884
  this._status$ = this.createBehaviorSubject("disconnected");
16371
16885
  this._incomingMessages$ = this.createSubject();
16372
16886
  this._errors$ = this.createReplaySubject(1);
@@ -16422,6 +16936,7 @@ var WebSocketController = class WebSocketController extends Destroyable {
16422
16936
  }
16423
16937
  createWebSocket() {
16424
16938
  try {
16939
+ this.closeExistingSocket();
16425
16940
  this.socket = new this.WebSocketConstructor(this.endpoint);
16426
16941
  this.setupWebSocketListeners();
16427
16942
  this.startConnectionTimeout();
@@ -16431,12 +16946,33 @@ var WebSocketController = class WebSocketController extends Destroyable {
16431
16946
  this.handleConnectionError();
16432
16947
  }
16433
16948
  }
16949
+ /**
16950
+ * Closes the existing socket and removes its event listeners to prevent
16951
+ * phantom 'open'/'close' events from firing on the orphaned socket.
16952
+ */
16953
+ closeExistingSocket() {
16954
+ if (!this.socket) return;
16955
+ const oldSocket = this.socket;
16956
+ this.socket = void 0;
16957
+ this.removeWebSocketListeners(oldSocket);
16958
+ try {
16959
+ oldSocket.close();
16960
+ } catch {}
16961
+ }
16434
16962
  setupWebSocketListeners() {
16435
16963
  if (!this.socket) return;
16436
- this.socket.addEventListener("open", () => this.handleOpen());
16437
- this.socket.addEventListener("close", (event) => this.handleClose(event));
16438
- this.socket.addEventListener("error", () => this.handleError());
16439
- this.socket.addEventListener("message", (event) => this.handleMessage(event));
16964
+ this.socket.addEventListener("open", this.boundHandleOpen);
16965
+ this.socket.addEventListener("close", this.boundHandleClose);
16966
+ this.socket.addEventListener("error", this.boundHandleError);
16967
+ this.socket.addEventListener("message", this.boundHandleMessage);
16968
+ }
16969
+ removeWebSocketListeners(socket) {
16970
+ try {
16971
+ socket.removeEventListener("open", this.boundHandleOpen);
16972
+ socket.removeEventListener("close", this.boundHandleClose);
16973
+ socket.removeEventListener("error", this.boundHandleError);
16974
+ socket.removeEventListener("message", this.boundHandleMessage);
16975
+ } catch {}
16440
16976
  }
16441
16977
  handleOpen() {
16442
16978
  this.clearConnectionTimeout();
@@ -16783,6 +17319,7 @@ var SignalWire = class extends Destroyable {
16783
17319
  this._errors$ = this.createReplaySubject(1);
16784
17320
  this._options = {};
16785
17321
  this._deps = new DependencyContainer();
17322
+ this._credentialProvider = credentialProvider;
16786
17323
  this._options = {
16787
17324
  ...PreferencesContainer.instance.defaultSignalWireOptions,
16788
17325
  ...options
@@ -16806,8 +17343,25 @@ var SignalWire = class extends Destroyable {
16806
17343
  this._errors$.next(error instanceof Error ? error : new Error(String(error), { cause: error }));
16807
17344
  });
16808
17345
  }
17346
+ /**
17347
+ * Initializes DPoP if not already set up. Returns the fingerprint on success.
17348
+ */
17349
+ async initDPoP() {
17350
+ if (this._dpopManager?.initialized) return this._dpopManager.fingerprint;
17351
+ try {
17352
+ this._dpopManager = new CryptoController();
17353
+ const fingerprint = await this._dpopManager.init();
17354
+ logger$1.debug("[SignalWire] DPoP initialized, fingerprint available");
17355
+ return fingerprint;
17356
+ } catch (error) {
17357
+ logger$1.warn("[SignalWire] DPoP initialization failed, proceeding without DPoP:", error);
17358
+ this._dpopManager = void 0;
17359
+ return;
17360
+ }
17361
+ }
16809
17362
  async validateCredentials(credentialProvider, credentials) {
16810
- const _credentials = credentials ?? await credentialProvider.authenticate();
17363
+ const fingerprint = await this.initDPoP();
17364
+ const _credentials = credentials ?? await credentialProvider.authenticate(fingerprint ? { fingerprint } : void 0);
16811
17365
  if (_credentials.token) try {
16812
17366
  const decodeHeader = jwtDecode(_credentials.token, { header: true });
16813
17367
  this._deps.ch = decodeHeader.ch;
@@ -16930,12 +17484,53 @@ var SignalWire = class extends Destroyable {
16930
17484
  };
16931
17485
  this._transport = new TransportManager(this._deps.storage, this._deps.protocolKey, this._deps.WebSocket, PreferencesContainer.instance.relayHost ?? this._deps.relayHost, errorHandler);
16932
17486
  this._attachManager = new AttachManager(this._deps.storage, this._deps.deviceController, PreferencesContainer.instance.reconnectCallsTimeout, this._deps.attachedCallsKey);
16933
- this._clientSession = new ClientSessionManager(this._deps.credential, this._transport, this._deps.storage, this._deps.authorizationStateKey, this._deps.deviceController, this._attachManager, this._deps.webRTCApiProvider);
17487
+ 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);
16934
17488
  this._publicSession = new ClientSessionWrapper(this._clientSession);
17489
+ this._clientSession.onBeforeReconnect = async () => {
17490
+ if (!this._credentialProvider) return;
17491
+ try {
17492
+ const fingerprint = this._dpopManager?.initialized ? this._dpopManager.fingerprint : void 0;
17493
+ logger$1.debug("[SignalWire] Credential expired, refreshing before reconnect");
17494
+ const newCredentials = await this._credentialProvider.authenticate(fingerprint ? { fingerprint } : void 0);
17495
+ this._deps.credential = newCredentials;
17496
+ logger$1.debug("[SignalWire] Credential refreshed successfully for reconnect");
17497
+ } catch (error) {
17498
+ logger$1.error("[SignalWire] Failed to refresh credentials for reconnect:", error);
17499
+ }
17500
+ };
16935
17501
  this.subscribeTo(this._clientSession.errors$, (error) => {
16936
17502
  this._errors$.next(error);
16937
17503
  });
16938
17504
  await this._clientSession.connect();
17505
+ if (this._dpopManager?.initialized) {
17506
+ if (this._refreshTimerId) {
17507
+ clearTimeout(this._refreshTimerId);
17508
+ this._refreshTimerId = void 0;
17509
+ logger$1.debug("[SignalWire] Developer refresh disabled — Client Bound SAT activation starting");
17510
+ }
17511
+ this._deviceTokenManager = new DeviceTokenManager(this._dpopManager, this._deps.http, (error) => this._errors$.next(error), () => this._deps.credential);
17512
+ await this._deviceTokenManager.activate(this._deps.subscriber, this._clientSession, (cred) => {
17513
+ this._deps.credential = {
17514
+ ...this._deps.credential,
17515
+ ...cred
17516
+ };
17517
+ });
17518
+ this.subscribeTo(this._clientSession.authenticated$.pipe((0, import_cjs.skip)(1), (0, import_cjs.filter)(Boolean)), () => {
17519
+ logger$1.debug("[SignalWire] Re-activating Client Bound SAT after reconnect");
17520
+ this._deviceTokenManager?.activate(this._deps.subscriber, this._clientSession, (cred) => {
17521
+ this._deps.credential = {
17522
+ ...this._deps.credential,
17523
+ ...cred
17524
+ };
17525
+ });
17526
+ logger$1.debug("[SignalWire] Re-registering subscriber after reconnect");
17527
+ this.register().then(() => {
17528
+ logger$1.debug("[SignalWire] Subscriber re-registered successfully after reconnect");
17529
+ }).catch((error) => {
17530
+ logger$1.error("[SignalWire] Re-registration failed after reconnect:", error);
17531
+ });
17532
+ });
17533
+ }
16939
17534
  const conversationManager = new ConversationsManager(this._clientSession, this._deps.http, () => this._deps.getSubscriberFromAddressId(), errorHandler);
16940
17535
  const directory = new DirectoryManager(this._deps.http, this._clientSession, conversationManager, errorHandler);
16941
17536
  this._directory$.next(directory);
@@ -17213,6 +17808,8 @@ var SignalWire = class extends Destroyable {
17213
17808
  clearTimeout(this._refreshTimerId);
17214
17809
  this._refreshTimerId = void 0;
17215
17810
  }
17811
+ this._deviceTokenManager?.destroy();
17812
+ this._dpopManager?.destroy();
17216
17813
  super.destroy();
17217
17814
  }
17218
17815
  };
@@ -17356,6 +17953,8 @@ exports.Address = Address;
17356
17953
  exports.CallCreateError = CallCreateError;
17357
17954
  exports.ClientPreferences = ClientPreferences;
17358
17955
  exports.CollectionFetchError = CollectionFetchError;
17956
+ exports.DPoPInitError = DPoPInitError;
17957
+ exports.DeviceTokenError = DeviceTokenError;
17359
17958
  exports.InvalidCredentialsError = InvalidCredentialsError;
17360
17959
  exports.MediaTrackError = MediaTrackError;
17361
17960
  exports.MessageParseError = MessageParseError;
@@ -17365,6 +17964,7 @@ exports.SelfParticipant = SelfParticipant;
17365
17964
  exports.SignalWire = SignalWire;
17366
17965
  exports.StaticCredentialProvider = StaticCredentialProvider;
17367
17966
  exports.Subscriber = Subscriber;
17967
+ exports.TokenRefreshError = TokenRefreshError;
17368
17968
  exports.UnexpectedError = UnexpectedError;
17369
17969
  exports.VertoPongError = VertoPongError;
17370
17970
  exports.WebRTCCall = WebRTCCall;