@defcomm/meetingsdk 0.6.7 → 0.6.8

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
@@ -11,6 +11,7 @@ type Events = {
11
11
  onUserJoined?: (p: Participant) => void;
12
12
  /** Fired when a remote participant permanently joins the meeting. */
13
13
  onParticipantJoined?: (p: Participant) => void;
14
+ onParticipantPresence?: (participantId: string, presence: string) => void;
14
15
  onEntryRequested?: (req: EntryRequest) => void;
15
16
  onEntryResponded?: (payload: {
16
17
  participantId: string;
@@ -285,6 +286,12 @@ declare class MeetingState {
285
286
  clearRecording(): void;
286
287
  setNetworkQuality(quality: NetworkQuality | null): void;
287
288
  addParticipant(p: Participant): boolean;
289
+ /**
290
+ * Reconcile a participant received from a room snapshot without emitting a
291
+ * lifecycle/join event. Snapshot data is authoritative for current room
292
+ * membership, including after a reconnect/resume.
293
+ */
294
+ upsertParticipantSnapshot(p: Participant): void;
288
295
  removeParticipant(id: string): void;
289
296
  updateParticipantMedia(id: string, patch: Partial<NonNullable<Participant["media"]>>): void;
290
297
  updateLocalParticipant(patch: LocalParticipantPatch): void;
@@ -468,6 +475,7 @@ type MeetingContextValue = {
468
475
  onNetworkQuality: (cb: (quality: NetworkQuality) => void) => () => void;
469
476
  onChatMessage: (cb: (message: ChatMessage) => void) => () => void;
470
477
  onParticipantJoined: (cb: (participant: Participant) => void) => () => void;
478
+ onParticipantPresence: (cb: (participantId: string, presence: string) => void) => () => void;
471
479
  onParticipantLeft: (cb: (participant: Participant) => void) => () => void;
472
480
  };
473
481
  declare const MeetingProvider: ({ config, children, }: {
@@ -564,6 +572,7 @@ declare const useMeeting: (handlers?: {
564
572
  onNetworkQuality: (cb: (quality: NetworkQuality) => void) => () => void;
565
573
  onChatMessage: (cb: (message: ChatMessage) => void) => () => void;
566
574
  onParticipantJoined: (cb: (participant: Participant) => void) => () => void;
575
+ onParticipantPresence: (cb: (participantId: string, presence: string) => void) => () => void;
567
576
  onParticipantLeft: (cb: (participant: Participant) => void) => () => void;
568
577
  };
569
578
 
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ type Events = {
11
11
  onUserJoined?: (p: Participant) => void;
12
12
  /** Fired when a remote participant permanently joins the meeting. */
13
13
  onParticipantJoined?: (p: Participant) => void;
14
+ onParticipantPresence?: (participantId: string, presence: string) => void;
14
15
  onEntryRequested?: (req: EntryRequest) => void;
15
16
  onEntryResponded?: (payload: {
16
17
  participantId: string;
@@ -285,6 +286,12 @@ declare class MeetingState {
285
286
  clearRecording(): void;
286
287
  setNetworkQuality(quality: NetworkQuality | null): void;
287
288
  addParticipant(p: Participant): boolean;
289
+ /**
290
+ * Reconcile a participant received from a room snapshot without emitting a
291
+ * lifecycle/join event. Snapshot data is authoritative for current room
292
+ * membership, including after a reconnect/resume.
293
+ */
294
+ upsertParticipantSnapshot(p: Participant): void;
288
295
  removeParticipant(id: string): void;
289
296
  updateParticipantMedia(id: string, patch: Partial<NonNullable<Participant["media"]>>): void;
290
297
  updateLocalParticipant(patch: LocalParticipantPatch): void;
@@ -468,6 +475,7 @@ type MeetingContextValue = {
468
475
  onNetworkQuality: (cb: (quality: NetworkQuality) => void) => () => void;
469
476
  onChatMessage: (cb: (message: ChatMessage) => void) => () => void;
470
477
  onParticipantJoined: (cb: (participant: Participant) => void) => () => void;
478
+ onParticipantPresence: (cb: (participantId: string, presence: string) => void) => () => void;
471
479
  onParticipantLeft: (cb: (participant: Participant) => void) => () => void;
472
480
  };
473
481
  declare const MeetingProvider: ({ config, children, }: {
@@ -564,6 +572,7 @@ declare const useMeeting: (handlers?: {
564
572
  onNetworkQuality: (cb: (quality: NetworkQuality) => void) => () => void;
565
573
  onChatMessage: (cb: (message: ChatMessage) => void) => () => void;
566
574
  onParticipantJoined: (cb: (participant: Participant) => void) => () => void;
575
+ onParticipantPresence: (cb: (participantId: string, presence: string) => void) => () => void;
567
576
  onParticipantLeft: (cb: (participant: Participant) => void) => () => void;
568
577
  };
569
578
 
package/dist/index.js CHANGED
@@ -279,6 +279,36 @@ var MeetingState = class {
279
279
  this.notify("participants");
280
280
  return true;
281
281
  }
282
+ /**
283
+ * Reconcile a participant received from a room snapshot without emitting a
284
+ * lifecycle/join event. Snapshot data is authoritative for current room
285
+ * membership, including after a reconnect/resume.
286
+ */
287
+ upsertParticipantSnapshot(p) {
288
+ if (!p?.id) return;
289
+ const current = this.participants.get(p.id);
290
+ const updated = {
291
+ ...current ?? {},
292
+ ...p,
293
+ media: {
294
+ stream: current?.media?.stream ?? null,
295
+ screenStream: current?.media?.screenStream,
296
+ cameraTrack: current?.media?.cameraTrack,
297
+ screenTrack: current?.media?.screenTrack,
298
+ audioTrack: current?.media?.audioTrack,
299
+ micEnabled: current?.media?.micEnabled ?? !(p.media?.micEnabled === false),
300
+ camEnabled: current?.media?.camEnabled ?? !(p.media?.camEnabled === false),
301
+ isScreenSharing: current?.media?.isScreenSharing ?? false,
302
+ ...current?.media,
303
+ ...p.media
304
+ }
305
+ };
306
+ const next = new Map(this.participants);
307
+ next.set(p.id, updated);
308
+ this.participants = next;
309
+ this.notify(`participant:${p.id}`);
310
+ this.notify("participants");
311
+ }
282
312
  removeParticipant(id) {
283
313
  const next = new Map(this.participants);
284
314
  next.delete(id);
@@ -1243,7 +1273,6 @@ var SFUClient = class {
1243
1273
  }
1244
1274
  for (const participant of this.participants.values()) {
1245
1275
  if (participant.participant_id !== this.currentParticipantId) {
1246
- this.onParticipantJoined(participant);
1247
1276
  this.onParticipantPresence(
1248
1277
  participant.participant_id,
1249
1278
  String(participant.presence || "connected")
@@ -2528,6 +2557,36 @@ var VideoSDKCore = class {
2528
2557
  },
2529
2558
  onRoomUpdate: (payload) => {
2530
2559
  const participants = payload?.participants || [];
2560
+ const snapshotParticipantIds = /* @__PURE__ */ new Set();
2561
+ for (const participant of participants) {
2562
+ const pid = participant?.participant_id;
2563
+ if (!pid || pid === this.myId) continue;
2564
+ snapshotParticipantIds.add(pid);
2565
+ const current = this.state.getParticipant(pid);
2566
+ const name = participant?.user_metadata?.name || participant?.display_name || current?.name || "Participant";
2567
+ this.state.upsertParticipantSnapshot({
2568
+ id: pid,
2569
+ name,
2570
+ isModerator: Boolean(participant?.permissions?.moderate),
2571
+ isHost: Boolean(
2572
+ participant?.is_host ?? participant?.isHost ?? participant?.permissions?.host
2573
+ ),
2574
+ handRaised: Boolean(participant?.hand_raised),
2575
+ permissions: participant?.permissions,
2576
+ connectionState: participant?.presence === "reconnecting" ? "reconnecting" : participant?.presence === "disconnected" ? "disconnected" : "connected",
2577
+ media: {
2578
+ ...current?.media || {},
2579
+ micEnabled: !Boolean(participant?.audio_muted),
2580
+ camEnabled: !Boolean(participant?.video_muted),
2581
+ isScreenSharing: Boolean(participant?.screen_sharing)
2582
+ }
2583
+ });
2584
+ }
2585
+ for (const [pid] of this.state.participants) {
2586
+ if (pid === this.myId || snapshotParticipantIds.has(pid)) continue;
2587
+ this.cleanupRemoteParticipant(pid);
2588
+ this.state.removeParticipant(pid);
2589
+ }
2531
2590
  const local = participants.find(
2532
2591
  (p) => p?.participant_id === this.myId
2533
2592
  );
@@ -3341,6 +3400,9 @@ var MeetingProvider = ({
3341
3400
  const participantJoinedListeners = (0, import_react2.useRef)(
3342
3401
  /* @__PURE__ */ new Set()
3343
3402
  );
3403
+ const participantPresenceListeners = (0, import_react2.useRef)(
3404
+ /* @__PURE__ */ new Set()
3405
+ );
3344
3406
  const participantLeftListeners = (0, import_react2.useRef)(
3345
3407
  /* @__PURE__ */ new Set()
3346
3408
  );
@@ -3429,7 +3491,9 @@ var MeetingProvider = ({
3429
3491
  pubSubListeners.current.get("REACTION")?.forEach((fn) => fn(message));
3430
3492
  },
3431
3493
  onHandRaised: (participantId, raised) => {
3432
- handRaisedListeners.current.forEach((fn) => fn(participantId, raised));
3494
+ handRaisedListeners.current.forEach(
3495
+ (fn) => fn(participantId, raised)
3496
+ );
3433
3497
  },
3434
3498
  onNetworkQuality: (quality) => {
3435
3499
  networkQualityListeners.current.forEach((fn) => fn(quality));
@@ -3442,6 +3506,11 @@ var MeetingProvider = ({
3442
3506
  onParticipantJoined: (participant) => {
3443
3507
  participantJoinedListeners.current.forEach((fn) => fn(participant));
3444
3508
  },
3509
+ onParticipantPresence: (participantId, presence) => {
3510
+ participantPresenceListeners.current.forEach(
3511
+ (fn) => fn(participantId, presence)
3512
+ );
3513
+ },
3445
3514
  onParticipantLeft: (participant) => {
3446
3515
  participantLeftListeners.current.forEach((fn) => fn(participant));
3447
3516
  }
@@ -3654,6 +3723,10 @@ var MeetingProvider = ({
3654
3723
  participantJoinedListeners.current.add(cb);
3655
3724
  return () => participantJoinedListeners.current.delete(cb);
3656
3725
  },
3726
+ onParticipantPresence: (cb) => {
3727
+ participantPresenceListeners.current.add(cb);
3728
+ return () => participantPresenceListeners.current.delete(cb);
3729
+ },
3657
3730
  onChatMessage: (cb) => {
3658
3731
  chatMessageListeners.current.add(cb);
3659
3732
  return () => chatMessageListeners.current.delete(cb);