@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.d.mts CHANGED
@@ -316,6 +316,8 @@ declare class SFUClient {
316
316
  private maxReconnectAttempts;
317
317
  private reconnectBaseMs;
318
318
  private joinWaiter;
319
+ private transportRecoveryInProgress;
320
+ private transportRecoveryTimer;
319
321
  private pendingIce;
320
322
  private subscriberNegotiating;
321
323
  private offerQueue;
@@ -421,6 +423,7 @@ declare class SFUClient {
421
423
  private closePeerConnectionsOnly;
422
424
  private cleanupAll;
423
425
  private logSubscriberVideoStats;
426
+ private recoverWebRTC;
424
427
  }
425
428
 
426
429
  type PubSubHandle = {
package/dist/index.d.ts CHANGED
@@ -316,6 +316,8 @@ declare class SFUClient {
316
316
  private maxReconnectAttempts;
317
317
  private reconnectBaseMs;
318
318
  private joinWaiter;
319
+ private transportRecoveryInProgress;
320
+ private transportRecoveryTimer;
319
321
  private pendingIce;
320
322
  private subscriberNegotiating;
321
323
  private offerQueue;
@@ -421,6 +423,7 @@ declare class SFUClient {
421
423
  private closePeerConnectionsOnly;
422
424
  private cleanupAll;
423
425
  private logSubscriberVideoStats;
426
+ private recoverWebRTC;
424
427
  }
425
428
 
426
429
  type PubSubHandle = {
package/dist/index.js CHANGED
@@ -408,6 +408,8 @@ var SFUClient = class {
408
408
  this.maxReconnectAttempts = 8;
409
409
  this.reconnectBaseMs = 750;
410
410
  this.joinWaiter = null;
411
+ this.transportRecoveryInProgress = false;
412
+ this.transportRecoveryTimer = null;
411
413
  this.pendingIce = {
412
414
  publisher: [],
413
415
  subscriber: []
@@ -1016,17 +1018,73 @@ var SFUClient = class {
1016
1018
  if (event.candidate) this.sendCandidate("subscriber", event.candidate);
1017
1019
  };
1018
1020
  this.publisher.onconnectionstatechange = () => {
1019
- const state = this.publisher?.connectionState;
1021
+ const publisher = this.publisher;
1022
+ if (!publisher) return;
1023
+ const state = publisher.connectionState;
1024
+ console.debug("[SFU] Publisher connection state", {
1025
+ connectionState: publisher.connectionState,
1026
+ iceConnectionState: publisher.iceConnectionState,
1027
+ iceGatheringState: publisher.iceGatheringState,
1028
+ signalingState: publisher.signalingState
1029
+ });
1020
1030
  if (state === "failed") {
1021
- this.onError(new Error("Publisher PeerConnection failed"));
1031
+ const error = new Error("Publisher PeerConnection failed");
1032
+ this.onError({
1033
+ code: "SFU_ERROR",
1034
+ message: error.message,
1035
+ raw: error,
1036
+ recoverable: true,
1037
+ roomId: this.room,
1038
+ participantId: this.currentParticipantId,
1039
+ peer: "publisher",
1040
+ connectionState: publisher.connectionState,
1041
+ iceConnectionState: publisher.iceConnectionState
1042
+ });
1043
+ this.recoverWebRTC("publisher_failed");
1022
1044
  }
1023
1045
  };
1024
1046
  this.subscriber.onconnectionstatechange = () => {
1025
- const state = this.subscriber?.connectionState;
1047
+ const subscriber = this.subscriber;
1048
+ if (!subscriber) return;
1049
+ const state = subscriber.connectionState;
1050
+ console.debug("[SFU] Subscriber connection state", {
1051
+ connectionState: subscriber.connectionState,
1052
+ iceConnectionState: subscriber.iceConnectionState,
1053
+ iceGatheringState: subscriber.iceGatheringState,
1054
+ signalingState: subscriber.signalingState
1055
+ });
1026
1056
  if (state === "failed") {
1027
- this.onError(new Error("Subscriber PeerConnection failed"));
1057
+ const error = new Error("Subscriber PeerConnection failed");
1058
+ this.onError({
1059
+ code: "SFU_ERROR",
1060
+ message: error.message,
1061
+ raw: error,
1062
+ recoverable: true,
1063
+ roomId: this.room,
1064
+ participantId: this.currentParticipantId,
1065
+ peer: "subscriber",
1066
+ connectionState: subscriber.connectionState,
1067
+ iceConnectionState: subscriber.iceConnectionState
1068
+ });
1069
+ this.recoverWebRTC("subscriber_failed");
1028
1070
  }
1029
1071
  };
1072
+ this.publisher.oniceconnectionstatechange = () => {
1073
+ const publisher = this.publisher;
1074
+ if (!publisher) return;
1075
+ console.debug("[SFU] Publisher ICE state", {
1076
+ iceConnectionState: publisher.iceConnectionState,
1077
+ connectionState: publisher.connectionState
1078
+ });
1079
+ };
1080
+ this.subscriber.oniceconnectionstatechange = () => {
1081
+ const subscriber = this.subscriber;
1082
+ if (!subscriber) return;
1083
+ console.debug("[SFU] Subscriber ICE state", {
1084
+ iceConnectionState: subscriber.iceConnectionState,
1085
+ connectionState: subscriber.connectionState
1086
+ });
1087
+ };
1030
1088
  this.subscriber.ontrack = (event) => {
1031
1089
  void this.handleRemoteTrack(event);
1032
1090
  };
@@ -1632,6 +1690,44 @@ var SFUClient = class {
1632
1690
  } catch {
1633
1691
  }
1634
1692
  }
1693
+ recoverWebRTC(reason) {
1694
+ if (this.intentionalClose) return;
1695
+ if (this.transportRecoveryInProgress) {
1696
+ console.debug("[SFU] WebRTC recovery already in progress", {
1697
+ reason
1698
+ });
1699
+ return;
1700
+ }
1701
+ this.transportRecoveryInProgress = true;
1702
+ console.warn("[SFU] WebRTC transport failed; starting recovery", {
1703
+ reason,
1704
+ publisherState: this.publisher?.connectionState,
1705
+ publisherIceState: this.publisher?.iceConnectionState,
1706
+ subscriberState: this.subscriber?.connectionState,
1707
+ subscriberIceState: this.subscriber?.iceConnectionState
1708
+ });
1709
+ this.setState("reconnecting");
1710
+ this.transportRecoveryTimer = setTimeout(() => {
1711
+ this.transportRecoveryTimer = null;
1712
+ if (this.intentionalClose) {
1713
+ this.transportRecoveryInProgress = false;
1714
+ return;
1715
+ }
1716
+ const ws = this.ws;
1717
+ if (ws && ws.readyState === WebSocket.OPEN) {
1718
+ try {
1719
+ ws.close(4e3, "webrtc_recovery");
1720
+ } catch (error) {
1721
+ console.warn("[SFU] Failed to close WebSocket for recovery", error);
1722
+ this.transportRecoveryInProgress = false;
1723
+ this.scheduleReconnect();
1724
+ }
1725
+ return;
1726
+ }
1727
+ this.transportRecoveryInProgress = false;
1728
+ this.scheduleReconnect();
1729
+ }, 250);
1730
+ }
1635
1731
  };
1636
1732
 
1637
1733
  // src/core/VideoCore.ts