@defcomm/meetingsdk 0.1.8 → 0.1.9

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/index.mjs CHANGED
@@ -372,6 +372,8 @@ var SFUClient = class {
372
372
  this.maxReconnectAttempts = 8;
373
373
  this.reconnectBaseMs = 750;
374
374
  this.joinWaiter = null;
375
+ this.transportRecoveryInProgress = false;
376
+ this.transportRecoveryTimer = null;
375
377
  this.pendingIce = {
376
378
  publisher: [],
377
379
  subscriber: []
@@ -980,17 +982,73 @@ var SFUClient = class {
980
982
  if (event.candidate) this.sendCandidate("subscriber", event.candidate);
981
983
  };
982
984
  this.publisher.onconnectionstatechange = () => {
983
- const state = this.publisher?.connectionState;
985
+ const publisher = this.publisher;
986
+ if (!publisher) return;
987
+ const state = publisher.connectionState;
988
+ console.debug("[SFU] Publisher connection state", {
989
+ connectionState: publisher.connectionState,
990
+ iceConnectionState: publisher.iceConnectionState,
991
+ iceGatheringState: publisher.iceGatheringState,
992
+ signalingState: publisher.signalingState
993
+ });
984
994
  if (state === "failed") {
985
- this.onError(new Error("Publisher PeerConnection failed"));
995
+ const error = new Error("Publisher PeerConnection failed");
996
+ this.onError({
997
+ code: "SFU_ERROR",
998
+ message: error.message,
999
+ raw: error,
1000
+ recoverable: true,
1001
+ roomId: this.room,
1002
+ participantId: this.currentParticipantId,
1003
+ peer: "publisher",
1004
+ connectionState: publisher.connectionState,
1005
+ iceConnectionState: publisher.iceConnectionState
1006
+ });
1007
+ this.recoverWebRTC("publisher_failed");
986
1008
  }
987
1009
  };
988
1010
  this.subscriber.onconnectionstatechange = () => {
989
- const state = this.subscriber?.connectionState;
1011
+ const subscriber = this.subscriber;
1012
+ if (!subscriber) return;
1013
+ const state = subscriber.connectionState;
1014
+ console.debug("[SFU] Subscriber connection state", {
1015
+ connectionState: subscriber.connectionState,
1016
+ iceConnectionState: subscriber.iceConnectionState,
1017
+ iceGatheringState: subscriber.iceGatheringState,
1018
+ signalingState: subscriber.signalingState
1019
+ });
990
1020
  if (state === "failed") {
991
- this.onError(new Error("Subscriber PeerConnection failed"));
1021
+ const error = new Error("Subscriber PeerConnection failed");
1022
+ this.onError({
1023
+ code: "SFU_ERROR",
1024
+ message: error.message,
1025
+ raw: error,
1026
+ recoverable: true,
1027
+ roomId: this.room,
1028
+ participantId: this.currentParticipantId,
1029
+ peer: "subscriber",
1030
+ connectionState: subscriber.connectionState,
1031
+ iceConnectionState: subscriber.iceConnectionState
1032
+ });
1033
+ this.recoverWebRTC("subscriber_failed");
992
1034
  }
993
1035
  };
1036
+ this.publisher.oniceconnectionstatechange = () => {
1037
+ const publisher = this.publisher;
1038
+ if (!publisher) return;
1039
+ console.debug("[SFU] Publisher ICE state", {
1040
+ iceConnectionState: publisher.iceConnectionState,
1041
+ connectionState: publisher.connectionState
1042
+ });
1043
+ };
1044
+ this.subscriber.oniceconnectionstatechange = () => {
1045
+ const subscriber = this.subscriber;
1046
+ if (!subscriber) return;
1047
+ console.debug("[SFU] Subscriber ICE state", {
1048
+ iceConnectionState: subscriber.iceConnectionState,
1049
+ connectionState: subscriber.connectionState
1050
+ });
1051
+ };
994
1052
  this.subscriber.ontrack = (event) => {
995
1053
  void this.handleRemoteTrack(event);
996
1054
  };
@@ -1596,6 +1654,44 @@ var SFUClient = class {
1596
1654
  } catch {
1597
1655
  }
1598
1656
  }
1657
+ recoverWebRTC(reason) {
1658
+ if (this.intentionalClose) return;
1659
+ if (this.transportRecoveryInProgress) {
1660
+ console.debug("[SFU] WebRTC recovery already in progress", {
1661
+ reason
1662
+ });
1663
+ return;
1664
+ }
1665
+ this.transportRecoveryInProgress = true;
1666
+ console.warn("[SFU] WebRTC transport failed; starting recovery", {
1667
+ reason,
1668
+ publisherState: this.publisher?.connectionState,
1669
+ publisherIceState: this.publisher?.iceConnectionState,
1670
+ subscriberState: this.subscriber?.connectionState,
1671
+ subscriberIceState: this.subscriber?.iceConnectionState
1672
+ });
1673
+ this.setState("reconnecting");
1674
+ this.transportRecoveryTimer = setTimeout(() => {
1675
+ this.transportRecoveryTimer = null;
1676
+ if (this.intentionalClose) {
1677
+ this.transportRecoveryInProgress = false;
1678
+ return;
1679
+ }
1680
+ const ws = this.ws;
1681
+ if (ws && ws.readyState === WebSocket.OPEN) {
1682
+ try {
1683
+ ws.close(4e3, "webrtc_recovery");
1684
+ } catch (error) {
1685
+ console.warn("[SFU] Failed to close WebSocket for recovery", error);
1686
+ this.transportRecoveryInProgress = false;
1687
+ this.scheduleReconnect();
1688
+ }
1689
+ return;
1690
+ }
1691
+ this.transportRecoveryInProgress = false;
1692
+ this.scheduleReconnect();
1693
+ }, 250);
1694
+ }
1599
1695
  };
1600
1696
 
1601
1697
  // src/core/VideoCore.ts