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