@defcomm/meetingsdk 0.4.9 → 0.5.1

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
@@ -279,6 +279,9 @@ var MeetingState = class {
279
279
  this.localParticipant = {
280
280
  id: patch.id ?? "",
281
281
  name: patch.name ?? "",
282
+ isHost: patch.isHost ?? false,
283
+ isModerator: patch.isModerator ?? false,
284
+ permissions: patch.permissions,
282
285
  media: {
283
286
  stream: patch.media?.stream ?? null,
284
287
  // ◄ FIX: Capture the stream from the patch here
@@ -318,6 +321,9 @@ var MeetingState = class {
318
321
  ...prev,
319
322
  id: patch.id ?? prev.id,
320
323
  name: patch.name ?? prev.name,
324
+ isHost: patch.isHost ?? prev.isHost,
325
+ isModerator: patch.isModerator ?? prev.isModerator,
326
+ permissions: patch.permissions ?? prev.permissions,
321
327
  media: nextMedia
322
328
  };
323
329
  this.notify("localParticipant");
@@ -446,6 +452,12 @@ var SFUClient = class {
446
452
  });
447
453
  this.onJoinRequested = options.onJoinRequested || (() => {
448
454
  });
455
+ this.onJoinRequestCanceled = options.onJoinRequestCanceled || (() => {
456
+ });
457
+ this.onParticipantRemoved = options.onParticipantRemoved || (() => {
458
+ });
459
+ this.onParticipantPermissionsChanged = options.onParticipantPermissionsChanged || (() => {
460
+ });
449
461
  this.onScreenShareStarted = options.onScreenShareStarted || (() => {
450
462
  });
451
463
  this.onScreenShareStopped = options.onScreenShareStopped || (() => {
@@ -813,6 +825,38 @@ var SFUClient = class {
813
825
  this.onJoinRequested(payload.request || payload);
814
826
  break;
815
827
  }
828
+ case "join_request_canceled": {
829
+ this.onJoinRequestCanceled(payload.request_id || message.request_id);
830
+ break;
831
+ }
832
+ case "participant_removed": {
833
+ const participantId = payload.participant_id;
834
+ if (!participantId) break;
835
+ const removedBy = payload.removed_by || "";
836
+ this.participants.delete(participantId);
837
+ this.removeRemoteParticipant(participantId);
838
+ if (participantId === this.currentParticipantId) {
839
+ this.intentionalClose = true;
840
+ this.pendingJoinRequestId = null;
841
+ this.setState("disconnected");
842
+ try {
843
+ this.ws?.close();
844
+ } catch {
845
+ }
846
+ }
847
+ this.onParticipantRemoved(participantId, removedBy);
848
+ break;
849
+ }
850
+ case "participant_permissions_changed": {
851
+ const participantId = payload.participant_id;
852
+ if (!participantId) break;
853
+ const participant = this.participants.get(participantId);
854
+ if (participant) {
855
+ this.participants.set(participantId, { ...participant, permissions: payload.permissions });
856
+ }
857
+ this.onParticipantPermissionsChanged(participantId, payload.permissions);
858
+ break;
859
+ }
816
860
  case "publish_answer": {
817
861
  if (!this.publisher) break;
818
862
  await this.publisher.setRemoteDescription({
@@ -1716,6 +1760,40 @@ var SFUClient = class {
1716
1760
  throw new Error("SFU signaling is not connected");
1717
1761
  }
1718
1762
  }
1763
+ async cancelJoinRequest(requestId) {
1764
+ const id = requestId || this.pendingJoinRequestId;
1765
+ if (!id) return;
1766
+ if (!this.send({ type: "cancel_join_request", payload: { request_id: id } })) {
1767
+ throw new Error("SFU signaling is not connected");
1768
+ }
1769
+ this.pendingJoinRequestId = null;
1770
+ }
1771
+ async muteAllAudio() {
1772
+ if (!this.send({ type: "mute_all_audio" })) throw new Error("SFU signaling is not connected");
1773
+ }
1774
+ async unmuteAllAudio() {
1775
+ if (!this.send({ type: "unmute_all_audio" })) throw new Error("SFU signaling is not connected");
1776
+ }
1777
+ async removeParticipant(participantId) {
1778
+ if (!participantId) throw new Error("participantId is required");
1779
+ if (!this.send({ type: "remove_participant", payload: { participant_id: participantId } })) {
1780
+ throw new Error("SFU signaling is not connected");
1781
+ }
1782
+ }
1783
+ async getModerators(roomCode) {
1784
+ return this.request(`${this.apiBase}/rooms/${encodeURIComponent(roomCode)}/moderators`);
1785
+ }
1786
+ async addModerator(roomCode, userId) {
1787
+ return this.request(`${this.apiBase}/rooms/${encodeURIComponent(roomCode)}/moderators`, {
1788
+ method: "POST",
1789
+ body: JSON.stringify({ user_id: userId })
1790
+ });
1791
+ }
1792
+ async removeModerator(roomCode, userId) {
1793
+ return this.request(`${this.apiBase}/rooms/${encodeURIComponent(roomCode)}/moderators/${encodeURIComponent(userId)}`, {
1794
+ method: "DELETE"
1795
+ });
1796
+ }
1719
1797
  isSocketOpen() {
1720
1798
  return this.ws?.readyState === WebSocket.OPEN;
1721
1799
  }
@@ -2240,6 +2318,30 @@ var VideoSDKCore = class {
2240
2318
  onReaction: (reaction) => {
2241
2319
  this.events.onReaction?.(reaction);
2242
2320
  },
2321
+ onJoinRequestCanceled: (requestId) => {
2322
+ this.events.onJoinRequestCanceled?.(requestId);
2323
+ },
2324
+ onParticipantRemoved: (participantId, removedBy) => {
2325
+ if (participantId === this.myId) {
2326
+ this.intentionalDisconnect = true;
2327
+ this.events.onUserLeft?.(participantId);
2328
+ try {
2329
+ this.localStream?.getTracks().forEach((track) => track.enabled = false);
2330
+ } catch {
2331
+ }
2332
+ } else {
2333
+ this.cleanupRemoteParticipant(participantId);
2334
+ this.state.removeParticipant(participantId);
2335
+ this.events.onUserLeft?.(participantId);
2336
+ }
2337
+ this.events.onParticipantRemoved?.(participantId, removedBy);
2338
+ },
2339
+ onParticipantPermissionsChanged: (participantId, permissions) => {
2340
+ if (participantId === this.myId) {
2341
+ const current = this.state.localParticipant;
2342
+ this.state.updateLocalParticipant({ id: this.myId, name: this.participantName, isHost: current?.isHost, isModerator: Boolean(permissions?.moderate), permissions });
2343
+ }
2344
+ },
2243
2345
  onJoinRequested: (request) => {
2244
2346
  const requestId = request?.request_id || request?.requestId;
2245
2347
  const participantId = request?.user_id || request?.participantId;
@@ -2263,6 +2365,8 @@ var VideoSDKCore = class {
2263
2365
  this.state.addParticipant({
2264
2366
  id: pid,
2265
2367
  name: pname,
2368
+ isModerator: Boolean(participant?.permissions?.moderate),
2369
+ permissions: participant?.permissions,
2266
2370
  connectionState: "connected",
2267
2371
  media: {
2268
2372
  micEnabled: true,
@@ -2309,7 +2413,18 @@ var VideoSDKCore = class {
2309
2413
  },
2310
2414
  // TRACKS
2311
2415
  onParticipantMediaState: (participantId, audioMuted, videoMuted) => {
2312
- if (participantId === this.myId) return;
2416
+ if (participantId === this.myId) {
2417
+ this.localStream?.getAudioTracks().forEach((track) => track.enabled = !audioMuted);
2418
+ this.localStream?.getVideoTracks().forEach((track) => track.enabled = !videoMuted);
2419
+ this.state.updateLocalParticipant({
2420
+ id: this.myId,
2421
+ name: this.participantName,
2422
+ media: { micEnabled: !audioMuted, camEnabled: !videoMuted }
2423
+ });
2424
+ this.events.onMuteStateChanged?.(participantId, "audio", audioMuted);
2425
+ this.events.onMuteStateChanged?.(participantId, "video", videoMuted);
2426
+ return;
2427
+ }
2313
2428
  const participant = this.state.getParticipant(participantId);
2314
2429
  if (!participant) return;
2315
2430
  this.state.updateParticipantMedia(participantId, {
@@ -2579,6 +2694,30 @@ var VideoSDKCore = class {
2579
2694
  }
2580
2695
  return this.sfuClient.rejectJoinRequest(requestId, reason);
2581
2696
  }
2697
+ async cancelJoinRequest(requestId) {
2698
+ return this.sfuClient?.cancelJoinRequest(requestId);
2699
+ }
2700
+ async muteAllAudio() {
2701
+ if (!this.sfuClient) throw new Error("SFU client is not connected");
2702
+ return this.sfuClient.muteAllAudio();
2703
+ }
2704
+ async unmuteAllAudio() {
2705
+ if (!this.sfuClient) throw new Error("SFU client is not connected");
2706
+ return this.sfuClient.unmuteAllAudio();
2707
+ }
2708
+ async removeParticipant(participantId) {
2709
+ if (!this.sfuClient) throw new Error("SFU client is not connected");
2710
+ return this.sfuClient.removeParticipant(participantId);
2711
+ }
2712
+ async getModerators(roomCode) {
2713
+ return this.sfuClient?.getModerators(roomCode);
2714
+ }
2715
+ async addModerator(roomCode, userId) {
2716
+ return this.sfuClient?.addModerator(roomCode, userId);
2717
+ }
2718
+ async removeModerator(roomCode, userId) {
2719
+ return this.sfuClient?.removeModerator(roomCode, userId);
2720
+ }
2582
2721
  // MEDIA CONTROL
2583
2722
  toggleMic() {
2584
2723
  const mediaState = this.state.localParticipant?.media;
@@ -2809,6 +2948,9 @@ var MeetingProvider = ({
2809
2948
  const entryResponseListeners = useRef(
2810
2949
  /* @__PURE__ */ new Set()
2811
2950
  );
2951
+ const joinRequestCanceledListeners = useRef(/* @__PURE__ */ new Set());
2952
+ const participantRemovedListeners = useRef(/* @__PURE__ */ new Set());
2953
+ const participantPermissionsChangedListeners = useRef(/* @__PURE__ */ new Set());
2812
2954
  const meetingLeftListeners = useRef(/* @__PURE__ */ new Set());
2813
2955
  const trackStateListeners = useRef(/* @__PURE__ */ new Set());
2814
2956
  const recordingStartedListeners = useRef(/* @__PURE__ */ new Set());
@@ -2840,6 +2982,15 @@ var MeetingProvider = ({
2840
2982
  onEntryResponded: (p, d) => {
2841
2983
  entryResponseListeners.current.forEach((fn) => fn(p, d));
2842
2984
  },
2985
+ onJoinRequestCanceled: (requestId) => {
2986
+ joinRequestCanceledListeners.current.forEach((fn) => fn(requestId));
2987
+ },
2988
+ onParticipantRemoved: (participantId, removedBy) => {
2989
+ participantRemovedListeners.current.forEach((fn) => fn(participantId, removedBy));
2990
+ },
2991
+ onParticipantPermissionsChanged: (participantId, permissions) => {
2992
+ participantPermissionsChangedListeners.current.forEach((fn) => fn(participantId, permissions));
2993
+ },
2843
2994
  onMeetingLeft: () => {
2844
2995
  meetingLeftListeners.current.forEach((fn) => fn());
2845
2996
  },
@@ -3000,6 +3151,13 @@ var MeetingProvider = ({
3000
3151
  },
3001
3152
  approveJoinRequest: sdk.approveJoinRequest.bind(sdk),
3002
3153
  rejectJoinRequest: sdk.rejectJoinRequest.bind(sdk),
3154
+ cancelJoinRequest: sdk.cancelJoinRequest.bind(sdk),
3155
+ muteAllAudio: sdk.muteAllAudio.bind(sdk),
3156
+ unmuteAllAudio: sdk.unmuteAllAudio.bind(sdk),
3157
+ removeParticipant: sdk.removeParticipant.bind(sdk),
3158
+ getModerators: sdk.getModerators.bind(sdk),
3159
+ addModerator: sdk.addModerator.bind(sdk),
3160
+ removeModerator: sdk.removeModerator.bind(sdk),
3003
3161
  startRecording: sdk.startRecording.bind(sdk),
3004
3162
  stopRecording: sdk.stopRecording.bind(sdk),
3005
3163
  getRecordingStatus: sdk.getRecordingStatus.bind(sdk),
@@ -3021,6 +3179,24 @@ var MeetingProvider = ({
3021
3179
  entryResponseListeners.current.delete(cb);
3022
3180
  };
3023
3181
  },
3182
+ onJoinRequestCanceled: (cb) => {
3183
+ joinRequestCanceledListeners.current.add(cb);
3184
+ return () => {
3185
+ joinRequestCanceledListeners.current.delete(cb);
3186
+ };
3187
+ },
3188
+ onParticipantRemoved: (cb) => {
3189
+ participantRemovedListeners.current.add(cb);
3190
+ return () => {
3191
+ participantRemovedListeners.current.delete(cb);
3192
+ };
3193
+ },
3194
+ onParticipantPermissionsChanged: (cb) => {
3195
+ participantPermissionsChangedListeners.current.add(cb);
3196
+ return () => {
3197
+ participantPermissionsChangedListeners.current.delete(cb);
3198
+ };
3199
+ },
3024
3200
  onMeetingLeft: (cb) => {
3025
3201
  meetingLeftListeners.current.add(cb);
3026
3202
  return () => {
@@ -3139,6 +3315,18 @@ var useMeeting = (handlers) => {
3139
3315
  if (!handlers?.onEntryResponded) return;
3140
3316
  return ctx.onEntryResponded(handlers.onEntryResponded);
3141
3317
  }, [handlers?.onEntryResponded]);
3318
+ useEffect3(() => {
3319
+ if (!handlers?.onJoinRequestCanceled) return;
3320
+ return ctx.onJoinRequestCanceled(handlers.onJoinRequestCanceled);
3321
+ }, [handlers?.onJoinRequestCanceled]);
3322
+ useEffect3(() => {
3323
+ if (!handlers?.onParticipantRemoved) return;
3324
+ return ctx.onParticipantRemoved(handlers.onParticipantRemoved);
3325
+ }, [handlers?.onParticipantRemoved]);
3326
+ useEffect3(() => {
3327
+ if (!handlers?.onParticipantPermissionsChanged) return;
3328
+ return ctx.onParticipantPermissionsChanged(handlers.onParticipantPermissionsChanged);
3329
+ }, [handlers?.onParticipantPermissionsChanged]);
3142
3330
  useEffect3(() => {
3143
3331
  if (!handlers?.onMeetingLeft) return;
3144
3332
  return ctx.onMeetingLeft(handlers.onMeetingLeft);