@defcomm/meetingsdk 0.1.8 → 0.2.0
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 +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +110 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +110 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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: []
|
|
@@ -390,6 +392,7 @@ var SFUClient = class {
|
|
|
390
392
|
this.trackToSource = /* @__PURE__ */ new Map();
|
|
391
393
|
this.localTrackIds = /* @__PURE__ */ new Map();
|
|
392
394
|
this.subscriberStatsTimer = null;
|
|
395
|
+
this.heartbeatTimer = null;
|
|
393
396
|
this.apiBase = options.apiBase || "https://api.example.com/api";
|
|
394
397
|
this.wsBase = options.wsBase || "wss://api.example.com/ws";
|
|
395
398
|
this.participantId = options.participantId || this.createId();
|
|
@@ -434,6 +437,24 @@ var SFUClient = class {
|
|
|
434
437
|
this.onError = options.onError || console.error;
|
|
435
438
|
this.autoSubscribe = options.autoSubscribe !== false;
|
|
436
439
|
}
|
|
440
|
+
startHeartbeat() {
|
|
441
|
+
this.stopHeartbeat();
|
|
442
|
+
this.heartbeatTimer = setInterval(() => {
|
|
443
|
+
if (this.ws?.readyState !== WebSocket.OPEN) return;
|
|
444
|
+
this.send({
|
|
445
|
+
type: "ping",
|
|
446
|
+
payload: {
|
|
447
|
+
nonce: crypto.randomUUID()
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}, 1e4);
|
|
451
|
+
}
|
|
452
|
+
stopHeartbeat() {
|
|
453
|
+
if (this.heartbeatTimer) {
|
|
454
|
+
clearInterval(this.heartbeatTimer);
|
|
455
|
+
this.heartbeatTimer = null;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
437
458
|
createId() {
|
|
438
459
|
return typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `id_${Math.random().toString(36).slice(2)}_${Date.now()}`;
|
|
439
460
|
}
|
|
@@ -594,6 +615,7 @@ var SFUClient = class {
|
|
|
594
615
|
);
|
|
595
616
|
this.ws = ws;
|
|
596
617
|
ws.onopen = () => {
|
|
618
|
+
this.startHeartbeat();
|
|
597
619
|
this.setState("joining");
|
|
598
620
|
this.joiningWithResume = Boolean(this.resumeToken);
|
|
599
621
|
const joinPayload = {
|
|
@@ -617,6 +639,7 @@ var SFUClient = class {
|
|
|
617
639
|
this.onError(event);
|
|
618
640
|
};
|
|
619
641
|
ws.onclose = () => {
|
|
642
|
+
this.stopHeartbeat();
|
|
620
643
|
if (this.ws !== ws) return;
|
|
621
644
|
this.ws = null;
|
|
622
645
|
if (this.intentionalClose || this.state === "leaving") {
|
|
@@ -898,11 +921,21 @@ var SFUClient = class {
|
|
|
898
921
|
break;
|
|
899
922
|
}
|
|
900
923
|
case "error": {
|
|
901
|
-
const
|
|
902
|
-
this.
|
|
924
|
+
const message2 = payload.message || "SFU signaling error";
|
|
925
|
+
if (this.state === "reconnecting" && message2.includes("participant session is stale")) {
|
|
926
|
+
console.debug(
|
|
927
|
+
"[SFU] Ignoring stale-session error during recovery",
|
|
928
|
+
message2
|
|
929
|
+
);
|
|
930
|
+
return;
|
|
931
|
+
}
|
|
932
|
+
const error = new Error(message2);
|
|
903
933
|
if (this.state === "joining" || this.state === "waiting_approval") {
|
|
934
|
+
this.onError(error);
|
|
904
935
|
this.failJoin(error);
|
|
936
|
+
return;
|
|
905
937
|
}
|
|
938
|
+
this.onError(error);
|
|
906
939
|
break;
|
|
907
940
|
}
|
|
908
941
|
default:
|
|
@@ -980,17 +1013,49 @@ var SFUClient = class {
|
|
|
980
1013
|
if (event.candidate) this.sendCandidate("subscriber", event.candidate);
|
|
981
1014
|
};
|
|
982
1015
|
this.publisher.onconnectionstatechange = () => {
|
|
983
|
-
const
|
|
1016
|
+
const publisher = this.publisher;
|
|
1017
|
+
if (!publisher) return;
|
|
1018
|
+
const state = publisher.connectionState;
|
|
1019
|
+
console.debug("[SFU] Publisher connection state", {
|
|
1020
|
+
connectionState: publisher.connectionState,
|
|
1021
|
+
iceConnectionState: publisher.iceConnectionState,
|
|
1022
|
+
iceGatheringState: publisher.iceGatheringState,
|
|
1023
|
+
signalingState: publisher.signalingState
|
|
1024
|
+
});
|
|
984
1025
|
if (state === "failed") {
|
|
985
|
-
this.
|
|
1026
|
+
this.recoverWebRTC("publisher_failed");
|
|
986
1027
|
}
|
|
987
1028
|
};
|
|
988
1029
|
this.subscriber.onconnectionstatechange = () => {
|
|
989
|
-
const
|
|
1030
|
+
const subscriber = this.subscriber;
|
|
1031
|
+
if (!subscriber) return;
|
|
1032
|
+
const state = subscriber.connectionState;
|
|
1033
|
+
console.debug("[SFU] Subscriber connection state", {
|
|
1034
|
+
connectionState: subscriber.connectionState,
|
|
1035
|
+
iceConnectionState: subscriber.iceConnectionState,
|
|
1036
|
+
iceGatheringState: subscriber.iceGatheringState,
|
|
1037
|
+
signalingState: subscriber.signalingState
|
|
1038
|
+
});
|
|
990
1039
|
if (state === "failed") {
|
|
991
|
-
this.
|
|
1040
|
+
this.recoverWebRTC("subscriber_failed");
|
|
992
1041
|
}
|
|
993
1042
|
};
|
|
1043
|
+
this.publisher.oniceconnectionstatechange = () => {
|
|
1044
|
+
const publisher = this.publisher;
|
|
1045
|
+
if (!publisher) return;
|
|
1046
|
+
console.debug("[SFU] Publisher ICE state", {
|
|
1047
|
+
iceConnectionState: publisher.iceConnectionState,
|
|
1048
|
+
connectionState: publisher.connectionState
|
|
1049
|
+
});
|
|
1050
|
+
};
|
|
1051
|
+
this.subscriber.oniceconnectionstatechange = () => {
|
|
1052
|
+
const subscriber = this.subscriber;
|
|
1053
|
+
if (!subscriber) return;
|
|
1054
|
+
console.debug("[SFU] Subscriber ICE state", {
|
|
1055
|
+
iceConnectionState: subscriber.iceConnectionState,
|
|
1056
|
+
connectionState: subscriber.connectionState
|
|
1057
|
+
});
|
|
1058
|
+
};
|
|
994
1059
|
this.subscriber.ontrack = (event) => {
|
|
995
1060
|
void this.handleRemoteTrack(event);
|
|
996
1061
|
};
|
|
@@ -1461,6 +1526,7 @@ var SFUClient = class {
|
|
|
1461
1526
|
}
|
|
1462
1527
|
}
|
|
1463
1528
|
async leave() {
|
|
1529
|
+
this.stopHeartbeat();
|
|
1464
1530
|
this.intentionalClose = true;
|
|
1465
1531
|
this.setState("leaving");
|
|
1466
1532
|
if (this.reconnectTimer) {
|
|
@@ -1596,6 +1662,44 @@ var SFUClient = class {
|
|
|
1596
1662
|
} catch {
|
|
1597
1663
|
}
|
|
1598
1664
|
}
|
|
1665
|
+
recoverWebRTC(reason) {
|
|
1666
|
+
if (this.intentionalClose) return;
|
|
1667
|
+
if (this.transportRecoveryInProgress) {
|
|
1668
|
+
console.debug("[SFU] WebRTC recovery already in progress", {
|
|
1669
|
+
reason
|
|
1670
|
+
});
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
this.transportRecoveryInProgress = true;
|
|
1674
|
+
console.warn("[SFU] WebRTC transport failed; starting recovery", {
|
|
1675
|
+
reason,
|
|
1676
|
+
publisherState: this.publisher?.connectionState,
|
|
1677
|
+
publisherIceState: this.publisher?.iceConnectionState,
|
|
1678
|
+
subscriberState: this.subscriber?.connectionState,
|
|
1679
|
+
subscriberIceState: this.subscriber?.iceConnectionState
|
|
1680
|
+
});
|
|
1681
|
+
this.setState("reconnecting");
|
|
1682
|
+
this.transportRecoveryTimer = setTimeout(() => {
|
|
1683
|
+
this.transportRecoveryTimer = null;
|
|
1684
|
+
if (this.intentionalClose) {
|
|
1685
|
+
this.transportRecoveryInProgress = false;
|
|
1686
|
+
return;
|
|
1687
|
+
}
|
|
1688
|
+
const ws = this.ws;
|
|
1689
|
+
if (ws && ws.readyState === WebSocket.OPEN) {
|
|
1690
|
+
try {
|
|
1691
|
+
ws.close(4e3, "webrtc_recovery");
|
|
1692
|
+
} catch (error) {
|
|
1693
|
+
console.warn("[SFU] Failed to close WebSocket for recovery", error);
|
|
1694
|
+
this.transportRecoveryInProgress = false;
|
|
1695
|
+
this.scheduleReconnect();
|
|
1696
|
+
}
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1699
|
+
this.transportRecoveryInProgress = false;
|
|
1700
|
+
this.scheduleReconnect();
|
|
1701
|
+
}, 250);
|
|
1702
|
+
}
|
|
1599
1703
|
};
|
|
1600
1704
|
|
|
1601
1705
|
// src/core/VideoCore.ts
|