@defcomm/meetingsdk 0.2.2 → 0.2.3
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 +11 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.js +137 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +137 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -392,6 +392,8 @@ var SFUClient = class {
|
|
|
392
392
|
this.trackToSource = /* @__PURE__ */ new Map();
|
|
393
393
|
this.localTrackIds = /* @__PURE__ */ new Map();
|
|
394
394
|
this.subscriberStatsTimer = null;
|
|
395
|
+
this.roomSyncTimer = null;
|
|
396
|
+
this.roomSyncInFlight = false;
|
|
395
397
|
this.heartbeatTimer = null;
|
|
396
398
|
this.apiBase = options.apiBase || "https://api.example.com/api";
|
|
397
399
|
this.wsBase = options.wsBase || "wss://api.example.com/ws";
|
|
@@ -434,6 +436,8 @@ var SFUClient = class {
|
|
|
434
436
|
});
|
|
435
437
|
this.onRecordingStopped = options.onRecordingStopped || (() => {
|
|
436
438
|
});
|
|
439
|
+
this.onRoomState = options.onRoomState || (() => {
|
|
440
|
+
});
|
|
437
441
|
this.onError = options.onError || console.error;
|
|
438
442
|
this.autoSubscribe = options.autoSubscribe !== false;
|
|
439
443
|
}
|
|
@@ -455,6 +459,29 @@ var SFUClient = class {
|
|
|
455
459
|
this.heartbeatTimer = null;
|
|
456
460
|
}
|
|
457
461
|
}
|
|
462
|
+
startRoomStateSync() {
|
|
463
|
+
this.stopRoomStateSync();
|
|
464
|
+
this.roomSyncTimer = setInterval(() => {
|
|
465
|
+
if (this.state !== "connected") return;
|
|
466
|
+
void this.syncRoomState();
|
|
467
|
+
}, 5e3);
|
|
468
|
+
}
|
|
469
|
+
stopRoomStateSync() {
|
|
470
|
+
if (this.roomSyncTimer) {
|
|
471
|
+
clearInterval(this.roomSyncTimer);
|
|
472
|
+
this.roomSyncTimer = null;
|
|
473
|
+
}
|
|
474
|
+
this.roomSyncInFlight = false;
|
|
475
|
+
}
|
|
476
|
+
async syncRoomState() {
|
|
477
|
+
if (this.roomSyncInFlight || !this.isSocketOpen()) return;
|
|
478
|
+
this.roomSyncInFlight = true;
|
|
479
|
+
try {
|
|
480
|
+
this.send({ type: "sync_room_state" });
|
|
481
|
+
} finally {
|
|
482
|
+
this.roomSyncInFlight = false;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
458
485
|
createId() {
|
|
459
486
|
return typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `id_${Math.random().toString(36).slice(2)}_${Date.now()}`;
|
|
460
487
|
}
|
|
@@ -877,6 +904,10 @@ var SFUClient = class {
|
|
|
877
904
|
case "subscription_updated": {
|
|
878
905
|
break;
|
|
879
906
|
}
|
|
907
|
+
case "room_state": {
|
|
908
|
+
await this.applyRoomState(payload);
|
|
909
|
+
break;
|
|
910
|
+
}
|
|
880
911
|
case "recording_started": {
|
|
881
912
|
this.onRecordingStarted({
|
|
882
913
|
recording_id: payload.recording_id,
|
|
@@ -942,6 +973,72 @@ var SFUClient = class {
|
|
|
942
973
|
console.debug("[SFU] Ignoring unknown server message", message);
|
|
943
974
|
}
|
|
944
975
|
}
|
|
976
|
+
async applyRoomState(payload) {
|
|
977
|
+
const nextParticipants = /* @__PURE__ */ new Map();
|
|
978
|
+
for (const participant of payload.participants || []) {
|
|
979
|
+
const id = participant?.participant_id;
|
|
980
|
+
if (!id) continue;
|
|
981
|
+
nextParticipants.set(id, participant);
|
|
982
|
+
}
|
|
983
|
+
for (const [id] of this.participants) {
|
|
984
|
+
if (id === this.currentParticipantId) continue;
|
|
985
|
+
if (!nextParticipants.has(id)) {
|
|
986
|
+
this.participants.delete(id);
|
|
987
|
+
this.removeRemoteParticipant(id);
|
|
988
|
+
this.onParticipantLeft(id);
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
for (const [id, participant] of nextParticipants) {
|
|
992
|
+
if (id === this.currentParticipantId) continue;
|
|
993
|
+
const existed = this.participants.has(id);
|
|
994
|
+
this.participants.set(id, participant);
|
|
995
|
+
if (!existed) {
|
|
996
|
+
this.onParticipantJoined(participant);
|
|
997
|
+
}
|
|
998
|
+
const sharing = Boolean(participant.screen_sharing);
|
|
999
|
+
const screenTrackId = participant.screen_track_id ? String(participant.screen_track_id) : void 0;
|
|
1000
|
+
if (sharing) {
|
|
1001
|
+
const track = screenTrackId ? (payload.tracks || []).find(
|
|
1002
|
+
(candidate) => String(candidate.track_id) === screenTrackId
|
|
1003
|
+
) : void 0;
|
|
1004
|
+
this.onScreenShareStarted(id, track);
|
|
1005
|
+
} else if (this.remoteScreenStreams.has(id)) {
|
|
1006
|
+
this.remoteScreenStreams.get(id)?.getTracks().forEach((track) => track.stop());
|
|
1007
|
+
this.remoteScreenStreams.delete(id);
|
|
1008
|
+
this.onScreenShareStopped(id, screenTrackId);
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
const nextTracks = /* @__PURE__ */ new Map();
|
|
1012
|
+
for (const track of payload.tracks || []) {
|
|
1013
|
+
if (track?.track_id) nextTracks.set(String(track.track_id), track);
|
|
1014
|
+
}
|
|
1015
|
+
for (const [trackId, existing] of this.trackMetadata) {
|
|
1016
|
+
if (!nextTracks.has(trackId)) {
|
|
1017
|
+
this.trackMetadata.delete(trackId);
|
|
1018
|
+
this.trackToParticipant.delete(trackId);
|
|
1019
|
+
this.trackToSource.delete(trackId);
|
|
1020
|
+
this.subscribedTracks.delete(trackId);
|
|
1021
|
+
for (const [source, localId] of this.localTrackIds) {
|
|
1022
|
+
if (localId === trackId) this.localTrackIds.delete(source);
|
|
1023
|
+
}
|
|
1024
|
+
if (existing.participant_id !== this.currentParticipantId) {
|
|
1025
|
+
this.onTrackUnpublished(existing);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
for (const track of nextTracks.values()) {
|
|
1030
|
+
this.rememberTrack(track);
|
|
1031
|
+
}
|
|
1032
|
+
if (this.autoSubscribe) {
|
|
1033
|
+
const missing = [...nextTracks.values()].filter(
|
|
1034
|
+
(track) => track.participant_id !== this.currentParticipantId && !this.subscribedTracks.has(track.track_id)
|
|
1035
|
+
).map((track) => track.track_id);
|
|
1036
|
+
if (missing.length) {
|
|
1037
|
+
await this.subscribeMultiple(missing);
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
this.onRoomState(payload);
|
|
1041
|
+
}
|
|
945
1042
|
rememberTrack(track) {
|
|
946
1043
|
this.trackMetadata.set(track.track_id, track);
|
|
947
1044
|
this.trackToParticipant.set(track.track_id, track.participant_id);
|
|
@@ -971,8 +1068,15 @@ var SFUClient = class {
|
|
|
971
1068
|
for (const track of payload.tracks || []) {
|
|
972
1069
|
if (track?.track_id) this.rememberTrack(track);
|
|
973
1070
|
}
|
|
1071
|
+
if (payload.recording) {
|
|
1072
|
+
this.onRecordingStarted({
|
|
1073
|
+
recording_id: payload.recording.recording_id,
|
|
1074
|
+
started_at: payload.recording.started_at
|
|
1075
|
+
});
|
|
1076
|
+
}
|
|
974
1077
|
await this.initializePeerConnections();
|
|
975
1078
|
this.setState("connected");
|
|
1079
|
+
this.startRoomStateSync();
|
|
976
1080
|
this.onConnected(payload, resumed);
|
|
977
1081
|
for (const participant of this.participants.values()) {
|
|
978
1082
|
if (participant.participant_id !== this.currentParticipantId) {
|
|
@@ -1527,6 +1631,7 @@ var SFUClient = class {
|
|
|
1527
1631
|
}
|
|
1528
1632
|
async leave() {
|
|
1529
1633
|
this.stopHeartbeat();
|
|
1634
|
+
this.stopRoomStateSync();
|
|
1530
1635
|
this.intentionalClose = true;
|
|
1531
1636
|
this.setState("leaving");
|
|
1532
1637
|
if (this.reconnectTimer) {
|
|
@@ -1914,6 +2019,30 @@ var VideoSDKCore = class {
|
|
|
1914
2019
|
name: this.participantName
|
|
1915
2020
|
});
|
|
1916
2021
|
},
|
|
2022
|
+
onRoomState: (roomState) => {
|
|
2023
|
+
for (const participant of roomState?.participants || []) {
|
|
2024
|
+
const pid = participant?.participant_id;
|
|
2025
|
+
if (!pid || pid === this.myId) continue;
|
|
2026
|
+
const current = this.state.getParticipant(pid);
|
|
2027
|
+
if (!current) continue;
|
|
2028
|
+
if (participant.screen_sharing) {
|
|
2029
|
+
this.state.updateParticipantMedia(pid, {
|
|
2030
|
+
isScreenSharing: true,
|
|
2031
|
+
screenStream: current.media?.screenStream ?? null
|
|
2032
|
+
});
|
|
2033
|
+
} else if (current.media?.isScreenSharing) {
|
|
2034
|
+
const screen = this.remoteScreenStreams.get(pid);
|
|
2035
|
+
screen?.getTracks().forEach((track) => track.stop());
|
|
2036
|
+
this.remoteScreenStreams.delete(pid);
|
|
2037
|
+
this.state.updateParticipantMedia(pid, {
|
|
2038
|
+
isScreenSharing: false,
|
|
2039
|
+
screenStream: null,
|
|
2040
|
+
screenTrack: void 0
|
|
2041
|
+
});
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
this.events.onRoomUpdate?.(roomState);
|
|
2045
|
+
},
|
|
1917
2046
|
onDisconnected: () => {
|
|
1918
2047
|
console.log("[SFU] Signaling WebSocket disconnected; reconnecting");
|
|
1919
2048
|
},
|
|
@@ -2473,6 +2602,7 @@ var MeetingProvider = ({
|
|
|
2473
2602
|
/* @__PURE__ */ new Set()
|
|
2474
2603
|
);
|
|
2475
2604
|
const meetingLeftListeners = useRef(/* @__PURE__ */ new Set());
|
|
2605
|
+
const roomUpdateListeners = useRef(/* @__PURE__ */ new Set());
|
|
2476
2606
|
const trackStateListeners = useRef(/* @__PURE__ */ new Set());
|
|
2477
2607
|
const recordingStartedListeners = useRef(/* @__PURE__ */ new Set());
|
|
2478
2608
|
const recordingStoppedListeners = useRef(/* @__PURE__ */ new Set());
|
|
@@ -2497,6 +2627,9 @@ var MeetingProvider = ({
|
|
|
2497
2627
|
onMeetingLeft: () => {
|
|
2498
2628
|
meetingLeftListeners.current.forEach((fn) => fn());
|
|
2499
2629
|
},
|
|
2630
|
+
onRoomUpdate: (data) => {
|
|
2631
|
+
roomUpdateListeners.current.forEach((fn) => fn(data));
|
|
2632
|
+
},
|
|
2500
2633
|
onTrackStateChanged: (track) => {
|
|
2501
2634
|
trackStateListeners.current.forEach((fn) => fn(track));
|
|
2502
2635
|
},
|
|
@@ -2595,6 +2728,10 @@ var MeetingProvider = ({
|
|
|
2595
2728
|
meetingLeftListeners.current.delete(cb);
|
|
2596
2729
|
};
|
|
2597
2730
|
},
|
|
2731
|
+
onRoomUpdate: (cb) => {
|
|
2732
|
+
roomUpdateListeners.current.add(cb);
|
|
2733
|
+
return () => roomUpdateListeners.current.delete(cb);
|
|
2734
|
+
},
|
|
2598
2735
|
onTrackStateChanged: (cb) => {
|
|
2599
2736
|
trackStateListeners.current.add(cb);
|
|
2600
2737
|
return () => trackStateListeners.current.delete(cb);
|