@signalwire/js 4.0.0-dev-20260326210326 → 4.0.0-dev-20260401154549
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/browser.mjs +1057 -460
- package/dist/browser.mjs.map +1 -1
- package/dist/browser.umd.js +1059 -459
- package/dist/browser.umd.js.map +1 -1
- package/dist/index.cjs +851 -273
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +223 -10
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +223 -10
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +848 -273
- package/dist/index.mjs.map +1 -1
- package/dist/operators/index.cjs +1 -1
- package/dist/operators/index.mjs +1 -1
- package/dist/{operators-mm21prWr.cjs → operators-DuprVgnV.cjs} +40 -1
- package/dist/operators-DuprVgnV.cjs.map +1 -0
- package/dist/{operators-uT_fb8ba.mjs → operators-MaKNoyky.mjs} +23 -2
- package/dist/operators-MaKNoyky.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/operators-mm21prWr.cjs.map +0 -1
- package/dist/operators-uT_fb8ba.mjs.map +0 -1
package/dist/browser.umd.js
CHANGED
|
@@ -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$
|
|
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$
|
|
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$
|
|
5634
|
+
function exhaustMap$2(project, resultSelector) {
|
|
5635
5635
|
if (resultSelector) return function(source) {
|
|
5636
|
-
return source.pipe(exhaustMap$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
9409
|
-
if (!logger$
|
|
9410
|
-
return logger$
|
|
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$
|
|
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$
|
|
9475
|
+
return logger$24.debug(`${type.toUpperCase()}: \n`, msg, "\n");
|
|
9455
9476
|
};
|
|
9456
9477
|
const getLogger = () => {
|
|
9457
|
-
const logger$
|
|
9458
|
-
return new Proxy(logger$
|
|
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$
|
|
9508
|
-
const logger$
|
|
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
|
-
|
|
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.
|
|
9536
|
-
this._responses$ = new import_cjs$
|
|
9537
|
-
this._errors$ = new import_cjs$
|
|
9538
|
-
this._status$ = new import_cjs$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
-
|
|
9633
|
-
|
|
9634
|
-
|
|
9635
|
-
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
9990
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
10108
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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
|
|
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$
|
|
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$
|
|
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 = (
|
|
10760
|
+
const RPCReauthenticate = (params) => {
|
|
10761
|
+
const { dpop_token, ...authFields } = params;
|
|
10518
10762
|
return buildRPCRequest({
|
|
10519
10763
|
method: "signalwire.reauthenticate",
|
|
10520
|
-
params: {
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
12480
|
-
const logger$
|
|
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$
|
|
12736
|
+
return (0, import_cjs$16.map)((response) => {
|
|
12487
12737
|
if (response.error) {
|
|
12488
|
-
logger$
|
|
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$
|
|
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$
|
|
12503
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
12705
|
-
logger$
|
|
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$
|
|
12710
|
-
logger$
|
|
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$
|
|
12715
|
-
logger$
|
|
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$
|
|
12824
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
12894
|
-
logger$
|
|
12895
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
12943
|
-
if (this[timer$
|
|
12944
|
-
clearTimeout(this[timer$
|
|
12945
|
-
this[timer$
|
|
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$
|
|
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$
|
|
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$
|
|
12968
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
13289
|
+
logger$14.debug("[LocalStreamController] Requesting user media with constraints:", constraints);
|
|
13024
13290
|
stream = await this.options.getUserMedia(constraints);
|
|
13025
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
13524
|
+
logger$13.debug("[TransceiverController] restoreTrackSender constraints:", constraints);
|
|
13259
13525
|
if (Object.keys(constraints).length === 0) {
|
|
13260
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
13316
|
-
logger$
|
|
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$
|
|
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$
|
|
13353
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
13661
|
+
logger$12.warn("[RTCPeerConnectionController] No local stream available to update input device.");
|
|
13396
13662
|
return;
|
|
13397
13663
|
}
|
|
13398
|
-
logger$
|
|
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$
|
|
13669
|
+
logger$12.debug(`[RTCPeerConnectionController] Stopped existing ${kind} track: ${track.id}`, localStream.getTracks());
|
|
13404
13670
|
if (!deviceInfo) {
|
|
13405
|
-
logger$
|
|
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$
|
|
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$
|
|
13682
|
+
logger$12.debug(`[RTCPeerConnectionController] Added new ${kind} track: ${streamTrack.id}`, this.localStream?.getTracks());
|
|
13417
13683
|
}
|
|
13418
13684
|
}
|
|
13419
|
-
logger$
|
|
13685
|
+
logger$12.debug(`[RTCPeerConnectionController] ${kind} input device selected:`, deviceInfo?.label);
|
|
13420
13686
|
} catch (error) {
|
|
13421
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
13916
|
+
logger$12.debug("[RTCPeerConnectionController] Start Negotiation completed successfully");
|
|
13651
13917
|
},
|
|
13652
13918
|
error: (error) => {
|
|
13653
|
-
logger$
|
|
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$
|
|
13658
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
13982
|
+
logger$12.debug("[RTCPeerConnectionController] Starting negotiation.");
|
|
13717
13983
|
try {
|
|
13718
13984
|
const { offerOptions } = this;
|
|
13719
|
-
logger$
|
|
13985
|
+
logger$12.debug("[RTCPeerConnectionController] Creating offer with options:", offerOptions);
|
|
13720
13986
|
await this.createOffer(offerOptions);
|
|
13721
13987
|
} catch (error) {
|
|
13722
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
14203
|
+
logger$12.debug(`[RTCPeerConnectionController] ${track.kind} track added:`, track.id);
|
|
13938
14204
|
} catch (error) {
|
|
13939
|
-
logger$
|
|
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$
|
|
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$
|
|
14228
|
+
logger$12.debug(`[RTCPeerConnectionController] ${sender.track?.kind} track removed:`, trackId);
|
|
13963
14229
|
} catch (error) {
|
|
13964
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
14067
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
14339
|
-
logger$
|
|
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$
|
|
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$
|
|
14384
|
-
const vertoByeOrAccepted = await (0, import_cjs$
|
|
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$
|
|
14652
|
+
logger$11.debug("[WebRTCManager] Inbound answer handler aborted (destroyed).");
|
|
14387
14653
|
return;
|
|
14388
14654
|
}
|
|
14389
14655
|
if (isVertoByeMessage(vertoByeOrAccepted)) {
|
|
14390
|
-
logger$
|
|
14656
|
+
logger$11.info("[WebRTCManager] Inbound call ended by remote before answer.");
|
|
14391
14657
|
this.callSession?.destroy();
|
|
14392
14658
|
} else if (!vertoByeOrAccepted) {
|
|
14393
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
14428
|
-
this.localStream$ = rtcPeerConnController.localStream$.pipe(filterNull(), (0, import_cjs$
|
|
14429
|
-
this.remoteStream$ = rtcPeerConnController.remoteStream$.pipe(filterNull(), (0, import_cjs$
|
|
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$
|
|
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$
|
|
14482
|
-
const vertoByeOrAccepted = await (0, import_cjs$
|
|
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$
|
|
14750
|
+
logger$11.info("[WebRTCManager] Call ended before answer was sent.");
|
|
14485
14751
|
this.callSession?.destroy();
|
|
14486
14752
|
} else if (!vertoByeOrAccepted) {
|
|
14487
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
14859
|
+
logger$11.info("[WebRTCManager] Screen share started successfully.");
|
|
14594
14860
|
return rtcPeerConnController.id;
|
|
14595
14861
|
} catch (error) {
|
|
14596
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
14941
|
+
logger$11.debug("[WebRTCManager] Transferring call with options:", options);
|
|
14676
14942
|
await this.executeVerto(message);
|
|
14677
14943
|
} catch (error) {
|
|
14678
|
-
logger$
|
|
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$
|
|
14721
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
15319
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
15718
|
+
constructor(originalCollection, filter$14 = (i) => !!i, mapper = (item) => item) {
|
|
15451
15719
|
this.originalCollection = originalCollection;
|
|
15452
|
-
this.filter = filter$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
15510
|
-
this.history$ = (0, import_cjs$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
15671
|
-
const logger$
|
|
15938
|
+
var import_cjs$7 = require_cjs();
|
|
15939
|
+
const logger$8 = getLogger();
|
|
15672
15940
|
const isRPCConnectResult = (e) => {
|
|
15673
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
15697
|
-
const timer$
|
|
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$
|
|
15701
|
-
}), signal ? new import_cjs$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
15748
|
-
const logger$
|
|
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(
|
|
16025
|
+
constructor(getCredential, transport, storage, authorizationStateKey, deviceController, attachManager, webRTCApiProvider, dpopManager) {
|
|
15758
16026
|
super();
|
|
15759
|
-
this.
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
16124
|
+
logger$7.debug("[Session] Setting up message handlers");
|
|
15846
16125
|
this.subscribeTo(this.authStateEvent$, async (authStateEvent) => {
|
|
15847
|
-
logger$
|
|
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$
|
|
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$
|
|
15856
|
-
|
|
15857
|
-
|
|
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$
|
|
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$
|
|
16144
|
+
logger$7.debug("[Session] Verto invite received:", invite);
|
|
15867
16145
|
try {
|
|
15868
16146
|
await this.createInboundCall(invite);
|
|
15869
16147
|
} catch (error) {
|
|
15870
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
15906
|
-
logger$
|
|
15907
|
-
}), filterAs(isSignalwireAuthorizationStateMetadata, "params"), (0, import_cjs$
|
|
15908
|
-
logger$
|
|
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$
|
|
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$
|
|
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
|
-
|
|
15931
|
-
|
|
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$
|
|
16213
|
+
await (0, import_cjs$6.firstValueFrom)(this.initialized$);
|
|
15935
16214
|
await this.transport.connect();
|
|
15936
16215
|
}
|
|
15937
16216
|
async handleAuthenticationError(error) {
|
|
15938
|
-
logger$
|
|
16217
|
+
logger$7.error("Authentication error:", error);
|
|
15939
16218
|
this._errors$.next(error);
|
|
15940
|
-
|
|
15941
|
-
|
|
15942
|
-
|
|
15943
|
-
logger$
|
|
15944
|
-
|
|
15945
|
-
|
|
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$
|
|
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$
|
|
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$
|
|
15969
|
-
logger$
|
|
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
|
-
|
|
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$
|
|
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$
|
|
15981
|
-
const
|
|
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$
|
|
15994
|
-
logger$
|
|
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
|
-
|
|
16000
|
-
|
|
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.
|
|
16003
|
-
|
|
16004
|
-
|
|
16005
|
-
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
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$
|
|
16368
|
+
logger$7.error("[Session] Error creating outbound call:", error);
|
|
16059
16369
|
callSession?.destroy();
|
|
16060
|
-
const callError = new CallCreateError(error instanceof import_cjs$
|
|
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
|
|
16076
|
-
logger$
|
|
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$
|
|
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$
|
|
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$
|
|
16134
|
-
const logger$
|
|
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$
|
|
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$
|
|
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$
|
|
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",
|
|
16437
|
-
this.socket.addEventListener("close",
|
|
16438
|
-
this.socket.addEventListener("error",
|
|
16439
|
-
this.socket.addEventListener("message",
|
|
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
|
|
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;
|