@signalwire/js 4.0.0-rc.3 → 4.0.0-rc.5
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 +131 -13
- package/dist/browser.mjs.map +1 -1
- package/dist/browser.umd.js +131 -13
- package/dist/browser.umd.js.map +1 -1
- package/dist/index.cjs +114 -8
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +23 -0
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +23 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +114 -8
- package/dist/index.mjs.map +1 -1
- package/dist/operators/index.cjs +1 -1
- package/dist/operators/index.mjs +1 -1
- package/dist/{operators-BVxi3KpN.mjs → operators-CTNnvDcG.mjs} +14 -2
- package/dist/operators-CTNnvDcG.mjs.map +1 -0
- package/dist/{operators-BJ6QW1VP.cjs → operators-IoitK-As.cjs} +25 -1
- package/dist/operators-IoitK-As.cjs.map +1 -0
- package/package.json +1 -1
- package/dist/operators-BJ6QW1VP.cjs.map +0 -1
- package/dist/operators-BVxi3KpN.mjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_operators = require('./operators-
|
|
1
|
+
const require_operators = require('./operators-IoitK-As.cjs');
|
|
2
2
|
let jwt_decode = require("jwt-decode");
|
|
3
3
|
let rxjs = require("rxjs");
|
|
4
4
|
let uuid = require("uuid");
|
|
@@ -2589,6 +2589,12 @@ const RPCReauthenticate = (params) => {
|
|
|
2589
2589
|
|
|
2590
2590
|
//#endregion
|
|
2591
2591
|
//#region src/core/RPCMessages/RPCPing.ts
|
|
2592
|
+
const RPCPing = () => {
|
|
2593
|
+
return buildRPCRequest({
|
|
2594
|
+
method: "signalwire.ping",
|
|
2595
|
+
params: { timestamp: Date.now() / 1e3 }
|
|
2596
|
+
});
|
|
2597
|
+
};
|
|
2592
2598
|
const RPCPingResponse = (id, timestamp) => {
|
|
2593
2599
|
return makeRPCResponse({
|
|
2594
2600
|
id,
|
|
@@ -6451,6 +6457,7 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
6451
6457
|
this._signalingStatus$ = this.createReplaySubject(1);
|
|
6452
6458
|
this._screenShareStatus$ = this.createBehaviorSubject("none");
|
|
6453
6459
|
this._rtcPeerConnectionsMap = /* @__PURE__ */ new Map();
|
|
6460
|
+
this._lastVertoPings = /* @__PURE__ */ new Map();
|
|
6454
6461
|
this._legErrors$ = this.createSubject();
|
|
6455
6462
|
this._nodeId$ = this.createBehaviorSubject(options.nodeId ?? null);
|
|
6456
6463
|
this.onError = options.onError;
|
|
@@ -6566,9 +6573,13 @@ var WebRTCVertoManager = class extends VertoManager {
|
|
|
6566
6573
|
this.applyServerMediaParams(rtcPeerConnController, audio, video);
|
|
6567
6574
|
});
|
|
6568
6575
|
this.subscribeTo(this.vertoPing$, (vertoPing) => {
|
|
6576
|
+
this._lastVertoPings.set(vertoPing.callID, vertoPing);
|
|
6569
6577
|
this.attachManager.refresh(this.buildAttachableCall());
|
|
6570
6578
|
this.sendVertoPong(vertoPing);
|
|
6571
6579
|
});
|
|
6580
|
+
this.subscribeTo(this.webRtcCallSession.clientSession.authenticated$.pipe((0, rxjs.skip)(1), (0, rxjs.filter)(Boolean)), () => {
|
|
6581
|
+
this._lastVertoPings.forEach((vertoPing) => void this.sendVertoPong(vertoPing));
|
|
6582
|
+
});
|
|
6572
6583
|
}
|
|
6573
6584
|
/**
|
|
6574
6585
|
* An auxiliary-leg failure must never destroy the call; main-leg and
|
|
@@ -9908,6 +9919,8 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
9908
9919
|
this._errors$ = this.createReplaySubject(1);
|
|
9909
9920
|
this._authState$ = this.createBehaviorSubject({ kind: "unauthenticated" });
|
|
9910
9921
|
this._wasClientBound = false;
|
|
9922
|
+
this._lastFreshConnectReminted = false;
|
|
9923
|
+
this._remintBeforeNextFreshConnect = false;
|
|
9911
9924
|
this._userInfo$ = this.createBehaviorSubject(null);
|
|
9912
9925
|
this._calls$ = this.createBehaviorSubject({});
|
|
9913
9926
|
this._iceServers$ = this.createBehaviorSubject([]);
|
|
@@ -10103,13 +10116,27 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
10103
10116
|
await (0, rxjs.firstValueFrom)(this.authenticated$.pipe((0, rxjs.takeUntil)(this.destroyed$), (0, rxjs.filter)(Boolean), (0, rxjs.take)(1), (0, rxjs.timeout)({ first: 15e3 })));
|
|
10104
10117
|
}
|
|
10105
10118
|
async handleAuthenticationError(error) {
|
|
10119
|
+
if (error instanceof require_operators.TransportConnectionError) {
|
|
10120
|
+
logger$9.debug("[Session] Socket closed during authentication, waiting for reconnect");
|
|
10121
|
+
return;
|
|
10122
|
+
}
|
|
10106
10123
|
logger$9.error("Authentication error:", error);
|
|
10107
10124
|
const isRecoverableAuthError$1 = error instanceof require_operators.JSONRPCError && (error.code === require_operators.RPC_ERROR_REQUESTER_VALIDATION_FAILED || error.code === require_operators.RPC_ERROR_INVALID_PARAMS || error.code === require_operators.RPC_ERROR_AUTHENTICATION_FAILED);
|
|
10108
10125
|
const hasStoredState = await (0, rxjs.firstValueFrom)(this.authorizationState$.pipe((0, rxjs.take)(1))) !== void 0;
|
|
10109
10126
|
if (isRecoverableAuthError$1 && hasStoredState) {
|
|
10110
10127
|
logger$9.debug("[Session] Recoverable auth error — cleaning up stored state and reconnecting fresh");
|
|
10111
10128
|
await this.discardResumeStateAndReconnect();
|
|
10112
|
-
} else this.
|
|
10129
|
+
} else if (isRecoverableAuthError$1 && this.onBeforeReconnect && !this._lastFreshConnectReminted) {
|
|
10130
|
+
logger$9.debug("[Session] Fresh connect refused — re-minting the credential and retrying once");
|
|
10131
|
+
this._remintBeforeNextFreshConnect = true;
|
|
10132
|
+
this.transport.reconnect();
|
|
10133
|
+
} else {
|
|
10134
|
+
this._errors$.next(error);
|
|
10135
|
+
if (isRecoverableAuthError$1) {
|
|
10136
|
+
this.transport.disconnect();
|
|
10137
|
+
this.onAuthenticationRejected?.();
|
|
10138
|
+
}
|
|
10139
|
+
}
|
|
10113
10140
|
}
|
|
10114
10141
|
/**
|
|
10115
10142
|
* Clear the resume state (authorization_state + protocol) and ask the
|
|
@@ -10201,6 +10228,7 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
10201
10228
|
}
|
|
10202
10229
|
async authenticate() {
|
|
10203
10230
|
logger$9.debug("[Session] Starting authentication process");
|
|
10231
|
+
this._lastFreshConnectReminted = false;
|
|
10204
10232
|
const persistedParams = await (0, rxjs.firstValueFrom)((0, rxjs.combineLatest)({
|
|
10205
10233
|
protocol: this.transport.protocol$,
|
|
10206
10234
|
authorization_state: this.authorizationState$
|
|
@@ -10217,8 +10245,11 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
10217
10245
|
else {
|
|
10218
10246
|
const credential = this.getCredential();
|
|
10219
10247
|
const credentialExpired = credential.expiry_at !== void 0 && credential.expiry_at <= Date.now() + require_operators.CREDENTIAL_EXPIRY_SKEW_MS;
|
|
10220
|
-
|
|
10248
|
+
const remint = this.clientBound || credentialExpired || this._remintBeforeNextFreshConnect;
|
|
10249
|
+
this._remintBeforeNextFreshConnect = false;
|
|
10250
|
+
if (this.onBeforeReconnect && remint) {
|
|
10221
10251
|
logger$9.debug("[Session] Refreshing credentials before fresh connect");
|
|
10252
|
+
this._lastFreshConnectReminted = true;
|
|
10222
10253
|
await this.onBeforeReconnect();
|
|
10223
10254
|
}
|
|
10224
10255
|
}
|
|
@@ -10242,7 +10273,9 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
10242
10273
|
protocol: persistedParams.protocol
|
|
10243
10274
|
} : {}
|
|
10244
10275
|
});
|
|
10245
|
-
|
|
10276
|
+
if (this.transport.connectionStatus !== "connected") throw new require_operators.TransportConnectionError("WebSocket closed during authentication");
|
|
10277
|
+
const socketClosed$ = this.transport.connectionStatus$.pipe((0, rxjs.skip)(1), (0, rxjs.filter)((status) => status === "reconnecting" || status === "disconnected"), (0, rxjs.take)(1), (0, rxjs.switchMap)(() => (0, rxjs.throwError)(() => new require_operators.TransportConnectionError("WebSocket closed during authentication"))));
|
|
10278
|
+
const response = await (0, rxjs.lastValueFrom)((0, rxjs.race)((0, rxjs.from)(this.transport.execute(rpcConnectRequest)), socketClosed$).pipe(require_operators.throwOnRPCError(), (0, rxjs.map)((res) => res.result), (0, rxjs.filter)(isRPCConnectResult), (0, rxjs.tap)(() => {
|
|
10246
10279
|
logger$9.debug("[Session] Response passed filter, processing authentication result");
|
|
10247
10280
|
}), (0, rxjs.take)(1), (0, rxjs.catchError)((err) => {
|
|
10248
10281
|
logger$9.error("[Session] Authentication RPC failed:", err);
|
|
@@ -10257,6 +10290,7 @@ var ClientSessionManager = class extends Destroyable {
|
|
|
10257
10290
|
this._authorization$.next(response.authorization);
|
|
10258
10291
|
if (response.authorization.cnf?.jkt) this._wasClientBound = true;
|
|
10259
10292
|
this._iceServers$.next(response.ice_servers ?? []);
|
|
10293
|
+
this.transport.setAuthenticated();
|
|
10260
10294
|
this._authState$.next({ kind: "authenticated" });
|
|
10261
10295
|
logger$9.debug("[Session] Authentication completed successfully");
|
|
10262
10296
|
}
|
|
@@ -11449,6 +11483,7 @@ var WebSocketController = class WebSocketController extends Destroyable {
|
|
|
11449
11483
|
}
|
|
11450
11484
|
handleClose(_event) {
|
|
11451
11485
|
this.clearConnectionTimeout();
|
|
11486
|
+
this.messageQueue = [];
|
|
11452
11487
|
if (this.shouldReconnect) {
|
|
11453
11488
|
this._status$.next("reconnecting");
|
|
11454
11489
|
this.scheduleReconnection();
|
|
@@ -11518,6 +11553,9 @@ var WebSocketController = class WebSocketController extends Destroyable {
|
|
|
11518
11553
|
function isSignalwirePingRequest(value) {
|
|
11519
11554
|
return isJSONRPCRequest(value) && value.method === "signalwire.ping";
|
|
11520
11555
|
}
|
|
11556
|
+
function isSignalwireConnectRequest(value) {
|
|
11557
|
+
return isJSONRPCRequest(value) && value.method === "signalwire.connect";
|
|
11558
|
+
}
|
|
11521
11559
|
|
|
11522
11560
|
//#endregion
|
|
11523
11561
|
//#region src/managers/TransportManager.ts
|
|
@@ -11531,6 +11569,10 @@ var TransportManager = class extends Destroyable {
|
|
|
11531
11569
|
this.protocol$ = this.createReplaySubject(1);
|
|
11532
11570
|
this.isConnecting = false;
|
|
11533
11571
|
this.isConnected = false;
|
|
11572
|
+
this.socketStatus = "disconnected";
|
|
11573
|
+
this.sessionAuthenticated = false;
|
|
11574
|
+
this.heldRequests = [];
|
|
11575
|
+
this.serverPingWatch = 0;
|
|
11534
11576
|
this.ackEvent = () => {
|
|
11535
11577
|
return (0, rxjs.tap)((message) => {
|
|
11536
11578
|
if (isSignalwireRequest(message)) try {
|
|
@@ -11546,6 +11588,7 @@ var TransportManager = class extends Destroyable {
|
|
|
11546
11588
|
if (isSignalwirePingRequest(message)) {
|
|
11547
11589
|
try {
|
|
11548
11590
|
logger$2.debug("[Transport] Received ping, sending pong", { pingId: message.id });
|
|
11591
|
+
if (this.sessionAuthenticated) this.armServerPingWatchdog();
|
|
11549
11592
|
this.send(RPCPingResponse(message.id));
|
|
11550
11593
|
} catch (error) {
|
|
11551
11594
|
logger$2.error("[Transport] Failed to send ping response:", error);
|
|
@@ -11583,6 +11626,14 @@ var TransportManager = class extends Destroyable {
|
|
|
11583
11626
|
this.subscribeTo(this._webSocketConnections.errors$, (error) => {
|
|
11584
11627
|
this.onError?.(error);
|
|
11585
11628
|
});
|
|
11629
|
+
this.subscribeTo(this._webSocketConnections.status$, (status) => {
|
|
11630
|
+
this.socketStatus = status;
|
|
11631
|
+
if (status !== "connected") {
|
|
11632
|
+
this.sessionAuthenticated = false;
|
|
11633
|
+
this.clearServerPingWatchdog();
|
|
11634
|
+
}
|
|
11635
|
+
if (status === "disconnected") this.heldRequests = [];
|
|
11636
|
+
});
|
|
11586
11637
|
this.initialized$ = (0, rxjs.defer)(() => (0, rxjs.from)(this._init())).pipe((0, rxjs.shareReplay)(1), (0, rxjs.takeUntil)(this.destroyed$));
|
|
11587
11638
|
this._jsonRPCMessage$ = this._webSocketConnections.incomingMessages$.pipe((0, rxjs.map)((event) => {
|
|
11588
11639
|
try {
|
|
@@ -11611,6 +11662,9 @@ var TransportManager = class extends Destroyable {
|
|
|
11611
11662
|
get connectionStatus$() {
|
|
11612
11663
|
return this._webSocketConnections.status$;
|
|
11613
11664
|
}
|
|
11665
|
+
get connectionStatus() {
|
|
11666
|
+
return this.socketStatus;
|
|
11667
|
+
}
|
|
11614
11668
|
async connect() {
|
|
11615
11669
|
if (this.isConnecting || this.isConnected) {
|
|
11616
11670
|
logger$2.warn("[Transport] Already connecting or connected");
|
|
@@ -11655,16 +11709,45 @@ var TransportManager = class extends Destroyable {
|
|
|
11655
11709
|
}
|
|
11656
11710
|
async execute(request, options) {
|
|
11657
11711
|
this.send(request);
|
|
11658
|
-
|
|
11712
|
+
const pending = new PendingRPC(request, this._jsonRPCResponse$, options).promise;
|
|
11713
|
+
pending.catch(() => {
|
|
11714
|
+
this.heldRequests = this.heldRequests.filter((held) => held.id !== request.id);
|
|
11715
|
+
});
|
|
11716
|
+
return pending;
|
|
11659
11717
|
}
|
|
11660
11718
|
send(message) {
|
|
11661
11719
|
const payload = JSON.stringify(message);
|
|
11720
|
+
if (isJSONRPCResponse(message)) {
|
|
11721
|
+
if (this.socketStatus !== "connected") {
|
|
11722
|
+
logger$2.debug("[Transport] Dropping response while disconnected", { id: message.id });
|
|
11723
|
+
return;
|
|
11724
|
+
}
|
|
11725
|
+
} else if (!this.sessionAuthenticated && !isSignalwireConnectRequest(message)) {
|
|
11726
|
+
this.heldRequests.push({
|
|
11727
|
+
id: message.id,
|
|
11728
|
+
payload
|
|
11729
|
+
});
|
|
11730
|
+
return;
|
|
11731
|
+
}
|
|
11662
11732
|
this._outgoingMessages$.next(payload);
|
|
11663
11733
|
}
|
|
11734
|
+
/**
|
|
11735
|
+
* Called by the session when signalwire.connect succeeds on the current
|
|
11736
|
+
* socket. Sends the requests held since the socket opened, in order.
|
|
11737
|
+
*/
|
|
11738
|
+
setAuthenticated() {
|
|
11739
|
+
if (this.socketStatus !== "connected") return;
|
|
11740
|
+
this.sessionAuthenticated = true;
|
|
11741
|
+
this.armServerPingWatchdog();
|
|
11742
|
+
const held = this.heldRequests;
|
|
11743
|
+
this.heldRequests = [];
|
|
11744
|
+
held.forEach(({ payload }) => this._outgoingMessages$.next(payload));
|
|
11745
|
+
}
|
|
11664
11746
|
disconnect() {
|
|
11665
11747
|
logger$2.debug("[Transport] Disconnecting");
|
|
11666
11748
|
this.isConnected = false;
|
|
11667
11749
|
this.isConnecting = false;
|
|
11750
|
+
this.clearServerPingWatchdog();
|
|
11668
11751
|
this._webSocketConnections.disconnect();
|
|
11669
11752
|
}
|
|
11670
11753
|
destroy() {
|
|
@@ -11673,6 +11756,28 @@ var TransportManager = class extends Destroyable {
|
|
|
11673
11756
|
super.destroy();
|
|
11674
11757
|
this._webSocketConnections.destroy();
|
|
11675
11758
|
}
|
|
11759
|
+
armServerPingWatchdog() {
|
|
11760
|
+
this.clearServerPingWatchdog();
|
|
11761
|
+
const watch = this.serverPingWatch;
|
|
11762
|
+
this.serverPingTimer = setTimeout(() => void this.probeServer(watch), require_operators.SERVER_PING_TIMEOUT_MS);
|
|
11763
|
+
}
|
|
11764
|
+
/** Bumps the watch so a probe still in flight no longer acts on its result. */
|
|
11765
|
+
clearServerPingWatchdog() {
|
|
11766
|
+
clearTimeout(this.serverPingTimer);
|
|
11767
|
+
this.serverPingTimer = void 0;
|
|
11768
|
+
this.serverPingWatch += 1;
|
|
11769
|
+
}
|
|
11770
|
+
async probeServer(watch) {
|
|
11771
|
+
logger$2.debug(`[Transport] No signalwire.ping for ${require_operators.SERVER_PING_TIMEOUT_MS}ms, probing the server`);
|
|
11772
|
+
try {
|
|
11773
|
+
await this.execute(RPCPing(), { timeoutMs: require_operators.SERVER_PING_PROBE_TIMEOUT_MS });
|
|
11774
|
+
if (watch === this.serverPingWatch) this.armServerPingWatchdog();
|
|
11775
|
+
} catch (error) {
|
|
11776
|
+
if (watch !== this.serverPingWatch) return;
|
|
11777
|
+
logger$2.warn("[Transport] Server did not answer the ping probe, replacing the socket", error);
|
|
11778
|
+
this.reconnect();
|
|
11779
|
+
}
|
|
11780
|
+
}
|
|
11676
11781
|
async _loadProtocolFromStorage() {
|
|
11677
11782
|
try {
|
|
11678
11783
|
const storedProtocol = await this.storage.getItem(this.protocolKey);
|
|
@@ -12198,6 +12303,7 @@ var SignalWire = class extends Destroyable {
|
|
|
12198
12303
|
this.persistClientBoundMarker(Boolean(authorization?.cnf?.jkt));
|
|
12199
12304
|
});
|
|
12200
12305
|
await this._clientSession.connect();
|
|
12306
|
+
this._clientSession.onAuthenticationRejected = () => void this.disconnect();
|
|
12201
12307
|
await this._refreshCoordinator?.activate(this._deps.user, this._clientSession);
|
|
12202
12308
|
this.subscribeTo(this._clientSession.authenticated$.pipe((0, rxjs.skip)(1), (0, rxjs.filter)(Boolean)), async () => {
|
|
12203
12309
|
try {
|
|
@@ -12377,7 +12483,7 @@ var SignalWire = class extends Destroyable {
|
|
|
12377
12483
|
logger$1.warn("[SignalWire] Failed to initialize VisibilityController:", error);
|
|
12378
12484
|
}
|
|
12379
12485
|
try {
|
|
12380
|
-
this._diagnosticsCollector = new DiagnosticsCollector({ sdkVersion: "4.0.0-rc.
|
|
12486
|
+
this._diagnosticsCollector = new DiagnosticsCollector({ sdkVersion: "4.0.0-rc.5" });
|
|
12381
12487
|
} catch (error) {
|
|
12382
12488
|
logger$1.warn("[SignalWire] Failed to initialize DiagnosticsCollector:", error);
|
|
12383
12489
|
}
|
|
@@ -12931,7 +13037,7 @@ var StaticCredentialProvider = class {
|
|
|
12931
13037
|
/**
|
|
12932
13038
|
* Library version from package.json, injected at build time.
|
|
12933
13039
|
*/
|
|
12934
|
-
const version = "4.0.0-rc.
|
|
13040
|
+
const version = "4.0.0-rc.5";
|
|
12935
13041
|
/**
|
|
12936
13042
|
* Flag indicating the library has been loaded and is ready to use.
|
|
12937
13043
|
* For UMD builds: `window.SignalWire.ready`
|
|
@@ -12953,7 +13059,7 @@ const ready = true;
|
|
|
12953
13059
|
*/
|
|
12954
13060
|
const emitReadyEvent = () => {
|
|
12955
13061
|
if (typeof window !== "undefined") {
|
|
12956
|
-
const event = new CustomEvent("signalwire:js:ready", { detail: { version: "4.0.0-rc.
|
|
13062
|
+
const event = new CustomEvent("signalwire:js:ready", { detail: { version: "4.0.0-rc.5" } });
|
|
12957
13063
|
window.dispatchEvent(event);
|
|
12958
13064
|
}
|
|
12959
13065
|
};
|