@defcomm/meetingsdk 0.4.0 → 0.4.2

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
@@ -144,6 +144,7 @@ interface VideoSDKCoreOptions {
144
144
  onChatMessage?: (message: ChatMessage) => void;
145
145
  onMuteStateChanged?: (peerId: string, kind: "audio" | "video", muted: boolean) => void;
146
146
  }
147
+ type SFUConnectionState = "idle" | "connecting" | "joining" | "waiting_approval" | "connected" | "reconnecting" | "leaving" | "disconnected";
147
148
 
148
149
  declare const useLocalParticipant: () => {
149
150
  participant: Participant | null;
@@ -246,7 +247,7 @@ declare class VideoSDKCore {
246
247
  * successful join/resume. A transient WebSocket close therefore does NOT
247
248
  * destroy the local MediaStream or immediately declare the participant gone.
248
249
  */
249
- type SFUConnectionState = "idle" | "connecting" | "joining" | "waiting_approval" | "connected" | "reconnecting" | "leaving" | "disconnected";
250
+
250
251
  interface TrackInfo {
251
252
  track_id: string;
252
253
  participant_id: string;
@@ -263,209 +264,6 @@ interface ParticipantInfo {
263
264
  display_name?: string;
264
265
  [key: string]: any;
265
266
  }
266
- interface JoinPendingInfo {
267
- request_id: string;
268
- room_code?: string;
269
- message?: string;
270
- }
271
- interface SFUClientOptions {
272
- apiBase?: string;
273
- wsBase?: string;
274
- participantId?: string;
275
- onStateChange?: (state: SFUConnectionState) => void;
276
- onParticipantJoined?: (participant: ParticipantInfo) => void;
277
- onParticipantLeft?: (participant: string | ParticipantInfo) => void;
278
- onParticipantPresence?: (participantId: string, presence: string) => void;
279
- onTrackPublished?: (track: TrackInfo) => void;
280
- onTrackUnpublished?: (track: TrackInfo) => void;
281
- onRemoteTrack?: (track: MediaStreamTrack, stream: MediaStream, metadata: TrackInfo) => void;
282
- onConnected?: (payload: any, resumed: boolean) => void;
283
- onDisconnected?: () => void;
284
- onReconnecting?: (attempt: number) => void;
285
- onJoinPending?: (info: JoinPendingInfo) => void;
286
- onJoinApproved?: (requestId: string) => void;
287
- onJoinRejected?: (requestId: string, reason?: string) => void;
288
- onJoinRequested?: (request: any) => void;
289
- onScreenShareStarted?: (participantId: string, track?: TrackInfo) => void;
290
- onScreenShareStopped?: (participantId: string, trackId?: string) => void;
291
- onTrackStateChanged?: (track: TrackInfo) => void;
292
- onRecordingStarted?: (recording: {
293
- recording_id: string;
294
- started_at: string;
295
- }) => void;
296
- onRecordingStopped?: (recording: {
297
- recording_id: string;
298
- stopped_at: string;
299
- }) => void;
300
- onError?: (error: any) => void;
301
- onChatMessage?: (message: any) => void;
302
- onReaction?: (reaction: any) => void;
303
- onRoomUpdate?: (data: any) => void;
304
- onParticipantMediaState?: (participantId: string, audioMuted: boolean, videoMuted: boolean) => void;
305
- autoSubscribe?: boolean;
306
- }
307
- declare class SFUClient {
308
- private apiBase;
309
- private wsBase;
310
- private participantId;
311
- private ws;
312
- private publisher;
313
- private subscriber;
314
- private localStream;
315
- private screenStream;
316
- private videoSender;
317
- private audioSender;
318
- private screenSender;
319
- private audioTransceiver;
320
- private cameraTransceiver;
321
- private screenTransceiver;
322
- private iceServers;
323
- private requestId;
324
- private publisherRevision;
325
- private screenShareGeneration;
326
- private currentParticipantId;
327
- private token;
328
- private room;
329
- private resumeToken;
330
- private pendingJoinRequestId;
331
- private joinOptions;
332
- private state;
333
- private intentionalClose;
334
- private leaveAcknowledged;
335
- private joiningWithResume;
336
- private desiredAudioMuted;
337
- private desiredVideoMuted;
338
- private reconnectTimer;
339
- private reconnectAttempt;
340
- private maxReconnectAttempts;
341
- private reconnectBaseMs;
342
- private joinWaiter;
343
- private transportRecoveryInProgress;
344
- private transportRecoveryTimer;
345
- private pendingIce;
346
- private subscriberNegotiating;
347
- private offerQueue;
348
- private subscriptionQueue;
349
- private subscriptionRunning;
350
- private subscriptionWaiters;
351
- private subscribedTracks;
352
- private trackMetadata;
353
- private participants;
354
- private remoteStreams;
355
- private remoteScreenStreams;
356
- private trackToParticipant;
357
- private trackToSource;
358
- private localTrackIds;
359
- private subscriberStatsTimer;
360
- private onStateChange;
361
- private onParticipantJoined;
362
- private onParticipantLeft;
363
- private onParticipantPresence;
364
- private onTrackPublished;
365
- private onTrackUnpublished;
366
- private onRemoteTrack;
367
- private onConnected;
368
- private onDisconnected;
369
- private onReconnecting;
370
- private onJoinPending;
371
- private onJoinApproved;
372
- private onJoinRejected;
373
- private onJoinRequested;
374
- private onScreenShareStarted;
375
- private onScreenShareStopped;
376
- private onTrackStateChanged;
377
- private onRecordingStarted;
378
- private onRecordingStopped;
379
- private onError;
380
- private onChatMessage;
381
- private onReaction;
382
- private onRoomUpdate;
383
- private onParticipantMediaState;
384
- private autoSubscribe;
385
- constructor(options?: SFUClientOptions);
386
- private heartbeatTimer;
387
- private startHeartbeat;
388
- private stopHeartbeat;
389
- private createId;
390
- private resumeStorageKey;
391
- private loadResumeToken;
392
- private saveResumeToken;
393
- private clearResumeToken;
394
- private setState;
395
- getConnectionState(): SFUConnectionState;
396
- getParticipantId(): string | null;
397
- getResumeToken(): string | null;
398
- getLocalStream(): MediaStream | null;
399
- getScreenStream(): MediaStream | null;
400
- getRemoteScreenStream(participantId: string): MediaStream | null;
401
- setLocalStream(stream: MediaStream | null): void;
402
- private nextRequestId;
403
- private request;
404
- createRoom(input: {
405
- name: string;
406
- description?: string;
407
- capacity?: number;
408
- is_private?: boolean;
409
- }): Promise<any>;
410
- getRoom(roomCode: string): Promise<any>;
411
- deleteRoom(roomCode: string): Promise<any>;
412
- getToken(roomCode: string, options?: {
413
- displayName?: string;
414
- avatarUrl?: string;
415
- participantId?: string;
416
- audioMuted?: boolean;
417
- videoMuted?: boolean;
418
- }): Promise<void>;
419
- private refreshAccessToken;
420
- private connect;
421
- private openWebSocket;
422
- private scheduleReconnect;
423
- private failJoin;
424
- private resolveJoin;
425
- private handleServerMessage;
426
- private onRoomStateReconciled;
427
- private rememberTrack;
428
- private handleJoined;
429
- private initializePeerConnections;
430
- private handleRemoteTrack;
431
- private normalizeRemoteTrackId;
432
- private resolveRemoteTrackMetadata;
433
- private sendCandidate;
434
- private handleIce;
435
- private flushPendingIce;
436
- private processOfferQueue;
437
- private subscribe;
438
- private subscribeMultiple;
439
- private processSubscriptionQueue;
440
- publish({ audio, video }?: {
441
- audio?: boolean | undefined;
442
- video?: boolean | undefined;
443
- }): Promise<MediaStream>;
444
- private publishExistingTracks;
445
- shareScreen(): Promise<MediaStream | null>;
446
- stopScreenShare(): Promise<void>;
447
- muteAudio(muted: boolean): void;
448
- muteVideo(muted: boolean): void;
449
- sendChatMessage(input: {
450
- message: string;
451
- reply_to?: any;
452
- target?: string | null;
453
- }): boolean;
454
- startRecording(): Promise<void>;
455
- stopRecording(): Promise<void>;
456
- getRecordingStatus(): Promise<any>;
457
- approveJoinRequest(requestId: string): Promise<void>;
458
- rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
459
- private isSocketOpen;
460
- private send;
461
- sendReaction(reaction: string): void;
462
- private removeRemoteParticipant;
463
- leave(): Promise<void>;
464
- private closePeerConnectionsOnly;
465
- private cleanupAll;
466
- private logSubscriberVideoStats;
467
- private recoverWebRTC;
468
- }
469
267
 
470
268
  type PubSubHandle = {
471
269
  messages: ChatMessage[];
@@ -513,6 +311,7 @@ type MeetingContextValue = {
513
311
  onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
514
312
  onRecordingStopped: (cb: (recording: any) => void) => () => void;
515
313
  onReaction: (cb: (reaction: Reaction) => void) => () => void;
314
+ onConnectionStateChanged: (cb: (state: SFUConnectionState) => void) => () => void;
516
315
  onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
517
316
  };
518
317
  declare const MeetingProvider: ({ config, children, }: {
@@ -531,6 +330,7 @@ declare const useMeeting: (handlers?: {
531
330
  onRecordingStopped?: (recording: any) => void;
532
331
  onReaction?: (reaction: any) => void;
533
332
  onActiveSpeakersChanged?: (participantIds: string[]) => void;
333
+ onConnectionStateChanged?: (state: SFUConnectionState) => void;
534
334
  }) => {
535
335
  join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
536
336
  leave: () => void;
@@ -575,6 +375,7 @@ declare const useMeeting: (handlers?: {
575
375
  onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
576
376
  onRecordingStopped: (cb: (recording: any) => void) => () => void;
577
377
  onReaction: (cb: (reaction: Reaction) => void) => () => void;
378
+ onConnectionStateChanged: (cb: (state: SFUConnectionState) => void) => () => void;
578
379
  onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
579
380
  };
580
381
 
@@ -655,4 +456,4 @@ declare class ActiveSpeakerDetector {
655
456
  destroy(): Promise<void>;
656
457
  }
657
458
 
658
- export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
459
+ export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
package/dist/index.d.ts CHANGED
@@ -144,6 +144,7 @@ interface VideoSDKCoreOptions {
144
144
  onChatMessage?: (message: ChatMessage) => void;
145
145
  onMuteStateChanged?: (peerId: string, kind: "audio" | "video", muted: boolean) => void;
146
146
  }
147
+ type SFUConnectionState = "idle" | "connecting" | "joining" | "waiting_approval" | "connected" | "reconnecting" | "leaving" | "disconnected";
147
148
 
148
149
  declare const useLocalParticipant: () => {
149
150
  participant: Participant | null;
@@ -246,7 +247,7 @@ declare class VideoSDKCore {
246
247
  * successful join/resume. A transient WebSocket close therefore does NOT
247
248
  * destroy the local MediaStream or immediately declare the participant gone.
248
249
  */
249
- type SFUConnectionState = "idle" | "connecting" | "joining" | "waiting_approval" | "connected" | "reconnecting" | "leaving" | "disconnected";
250
+
250
251
  interface TrackInfo {
251
252
  track_id: string;
252
253
  participant_id: string;
@@ -263,209 +264,6 @@ interface ParticipantInfo {
263
264
  display_name?: string;
264
265
  [key: string]: any;
265
266
  }
266
- interface JoinPendingInfo {
267
- request_id: string;
268
- room_code?: string;
269
- message?: string;
270
- }
271
- interface SFUClientOptions {
272
- apiBase?: string;
273
- wsBase?: string;
274
- participantId?: string;
275
- onStateChange?: (state: SFUConnectionState) => void;
276
- onParticipantJoined?: (participant: ParticipantInfo) => void;
277
- onParticipantLeft?: (participant: string | ParticipantInfo) => void;
278
- onParticipantPresence?: (participantId: string, presence: string) => void;
279
- onTrackPublished?: (track: TrackInfo) => void;
280
- onTrackUnpublished?: (track: TrackInfo) => void;
281
- onRemoteTrack?: (track: MediaStreamTrack, stream: MediaStream, metadata: TrackInfo) => void;
282
- onConnected?: (payload: any, resumed: boolean) => void;
283
- onDisconnected?: () => void;
284
- onReconnecting?: (attempt: number) => void;
285
- onJoinPending?: (info: JoinPendingInfo) => void;
286
- onJoinApproved?: (requestId: string) => void;
287
- onJoinRejected?: (requestId: string, reason?: string) => void;
288
- onJoinRequested?: (request: any) => void;
289
- onScreenShareStarted?: (participantId: string, track?: TrackInfo) => void;
290
- onScreenShareStopped?: (participantId: string, trackId?: string) => void;
291
- onTrackStateChanged?: (track: TrackInfo) => void;
292
- onRecordingStarted?: (recording: {
293
- recording_id: string;
294
- started_at: string;
295
- }) => void;
296
- onRecordingStopped?: (recording: {
297
- recording_id: string;
298
- stopped_at: string;
299
- }) => void;
300
- onError?: (error: any) => void;
301
- onChatMessage?: (message: any) => void;
302
- onReaction?: (reaction: any) => void;
303
- onRoomUpdate?: (data: any) => void;
304
- onParticipantMediaState?: (participantId: string, audioMuted: boolean, videoMuted: boolean) => void;
305
- autoSubscribe?: boolean;
306
- }
307
- declare class SFUClient {
308
- private apiBase;
309
- private wsBase;
310
- private participantId;
311
- private ws;
312
- private publisher;
313
- private subscriber;
314
- private localStream;
315
- private screenStream;
316
- private videoSender;
317
- private audioSender;
318
- private screenSender;
319
- private audioTransceiver;
320
- private cameraTransceiver;
321
- private screenTransceiver;
322
- private iceServers;
323
- private requestId;
324
- private publisherRevision;
325
- private screenShareGeneration;
326
- private currentParticipantId;
327
- private token;
328
- private room;
329
- private resumeToken;
330
- private pendingJoinRequestId;
331
- private joinOptions;
332
- private state;
333
- private intentionalClose;
334
- private leaveAcknowledged;
335
- private joiningWithResume;
336
- private desiredAudioMuted;
337
- private desiredVideoMuted;
338
- private reconnectTimer;
339
- private reconnectAttempt;
340
- private maxReconnectAttempts;
341
- private reconnectBaseMs;
342
- private joinWaiter;
343
- private transportRecoveryInProgress;
344
- private transportRecoveryTimer;
345
- private pendingIce;
346
- private subscriberNegotiating;
347
- private offerQueue;
348
- private subscriptionQueue;
349
- private subscriptionRunning;
350
- private subscriptionWaiters;
351
- private subscribedTracks;
352
- private trackMetadata;
353
- private participants;
354
- private remoteStreams;
355
- private remoteScreenStreams;
356
- private trackToParticipant;
357
- private trackToSource;
358
- private localTrackIds;
359
- private subscriberStatsTimer;
360
- private onStateChange;
361
- private onParticipantJoined;
362
- private onParticipantLeft;
363
- private onParticipantPresence;
364
- private onTrackPublished;
365
- private onTrackUnpublished;
366
- private onRemoteTrack;
367
- private onConnected;
368
- private onDisconnected;
369
- private onReconnecting;
370
- private onJoinPending;
371
- private onJoinApproved;
372
- private onJoinRejected;
373
- private onJoinRequested;
374
- private onScreenShareStarted;
375
- private onScreenShareStopped;
376
- private onTrackStateChanged;
377
- private onRecordingStarted;
378
- private onRecordingStopped;
379
- private onError;
380
- private onChatMessage;
381
- private onReaction;
382
- private onRoomUpdate;
383
- private onParticipantMediaState;
384
- private autoSubscribe;
385
- constructor(options?: SFUClientOptions);
386
- private heartbeatTimer;
387
- private startHeartbeat;
388
- private stopHeartbeat;
389
- private createId;
390
- private resumeStorageKey;
391
- private loadResumeToken;
392
- private saveResumeToken;
393
- private clearResumeToken;
394
- private setState;
395
- getConnectionState(): SFUConnectionState;
396
- getParticipantId(): string | null;
397
- getResumeToken(): string | null;
398
- getLocalStream(): MediaStream | null;
399
- getScreenStream(): MediaStream | null;
400
- getRemoteScreenStream(participantId: string): MediaStream | null;
401
- setLocalStream(stream: MediaStream | null): void;
402
- private nextRequestId;
403
- private request;
404
- createRoom(input: {
405
- name: string;
406
- description?: string;
407
- capacity?: number;
408
- is_private?: boolean;
409
- }): Promise<any>;
410
- getRoom(roomCode: string): Promise<any>;
411
- deleteRoom(roomCode: string): Promise<any>;
412
- getToken(roomCode: string, options?: {
413
- displayName?: string;
414
- avatarUrl?: string;
415
- participantId?: string;
416
- audioMuted?: boolean;
417
- videoMuted?: boolean;
418
- }): Promise<void>;
419
- private refreshAccessToken;
420
- private connect;
421
- private openWebSocket;
422
- private scheduleReconnect;
423
- private failJoin;
424
- private resolveJoin;
425
- private handleServerMessage;
426
- private onRoomStateReconciled;
427
- private rememberTrack;
428
- private handleJoined;
429
- private initializePeerConnections;
430
- private handleRemoteTrack;
431
- private normalizeRemoteTrackId;
432
- private resolveRemoteTrackMetadata;
433
- private sendCandidate;
434
- private handleIce;
435
- private flushPendingIce;
436
- private processOfferQueue;
437
- private subscribe;
438
- private subscribeMultiple;
439
- private processSubscriptionQueue;
440
- publish({ audio, video }?: {
441
- audio?: boolean | undefined;
442
- video?: boolean | undefined;
443
- }): Promise<MediaStream>;
444
- private publishExistingTracks;
445
- shareScreen(): Promise<MediaStream | null>;
446
- stopScreenShare(): Promise<void>;
447
- muteAudio(muted: boolean): void;
448
- muteVideo(muted: boolean): void;
449
- sendChatMessage(input: {
450
- message: string;
451
- reply_to?: any;
452
- target?: string | null;
453
- }): boolean;
454
- startRecording(): Promise<void>;
455
- stopRecording(): Promise<void>;
456
- getRecordingStatus(): Promise<any>;
457
- approveJoinRequest(requestId: string): Promise<void>;
458
- rejectJoinRequest(requestId: string, reason?: string): Promise<void>;
459
- private isSocketOpen;
460
- private send;
461
- sendReaction(reaction: string): void;
462
- private removeRemoteParticipant;
463
- leave(): Promise<void>;
464
- private closePeerConnectionsOnly;
465
- private cleanupAll;
466
- private logSubscriberVideoStats;
467
- private recoverWebRTC;
468
- }
469
267
 
470
268
  type PubSubHandle = {
471
269
  messages: ChatMessage[];
@@ -513,6 +311,7 @@ type MeetingContextValue = {
513
311
  onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
514
312
  onRecordingStopped: (cb: (recording: any) => void) => () => void;
515
313
  onReaction: (cb: (reaction: Reaction) => void) => () => void;
314
+ onConnectionStateChanged: (cb: (state: SFUConnectionState) => void) => () => void;
516
315
  onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
517
316
  };
518
317
  declare const MeetingProvider: ({ config, children, }: {
@@ -531,6 +330,7 @@ declare const useMeeting: (handlers?: {
531
330
  onRecordingStopped?: (recording: any) => void;
532
331
  onReaction?: (reaction: any) => void;
533
332
  onActiveSpeakersChanged?: (participantIds: string[]) => void;
333
+ onConnectionStateChanged?: (state: SFUConnectionState) => void;
534
334
  }) => {
535
335
  join: (config?: Omit<MeetingConfig, "participantId">) => Promise<void>;
536
336
  leave: () => void;
@@ -575,6 +375,7 @@ declare const useMeeting: (handlers?: {
575
375
  onRecordingStarted: (cb: (recording: Recording) => void) => () => void;
576
376
  onRecordingStopped: (cb: (recording: any) => void) => () => void;
577
377
  onReaction: (cb: (reaction: Reaction) => void) => () => void;
378
+ onConnectionStateChanged: (cb: (state: SFUConnectionState) => void) => () => void;
578
379
  onActiveSpeakersChanged: (cb: (participantIds: string[]) => void) => () => void;
579
380
  };
580
381
 
@@ -655,4 +456,4 @@ declare class ActiveSpeakerDetector {
655
456
  destroy(): Promise<void>;
656
457
  }
657
458
 
658
- export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, SFUClient, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
459
+ export { ActiveSpeakerDetector, type ChatInput, type MeetingConfig, MeetingProvider, MeetingState, type Participant, type ParticipantInfo, type Reaction, type RecordingInfo, type SFUConnectionState, type TrackInfo, VideoSDKCore, useLocalParticipant, useMeeting, useMeetingContext, useMeetingPreview, useParticipants, useRemoteMedia };
package/dist/index.js CHANGED
@@ -23,7 +23,6 @@ __export(index_exports, {
23
23
  ActiveSpeakerDetector: () => ActiveSpeakerDetector,
24
24
  MeetingProvider: () => MeetingProvider,
25
25
  MeetingState: () => MeetingState,
26
- SFUClient: () => SFUClient,
27
26
  VideoSDKCore: () => VideoSDKCore,
28
27
  useLocalParticipant: () => useLocalParticipant,
29
28
  useMeeting: () => useMeeting,
@@ -2816,6 +2815,9 @@ var MeetingProvider = ({
2816
2815
  const activeSpeakerListeners = (0, import_react2.useRef)(
2817
2816
  /* @__PURE__ */ new Set()
2818
2817
  );
2818
+ const connectionStateListeners = (0, import_react2.useRef)(
2819
+ /* @__PURE__ */ new Set()
2820
+ );
2819
2821
  if (!sdkRef.current) {
2820
2822
  sdkRef.current = new VideoSDKCore(
2821
2823
  {
@@ -2845,6 +2847,11 @@ var MeetingProvider = ({
2845
2847
  },
2846
2848
  onReaction: (reaction) => {
2847
2849
  reactionListeners.current.forEach((fn) => fn(reaction));
2850
+ },
2851
+ onConnectionStateChanged: (state) => {
2852
+ connectionStateListeners.current.forEach(
2853
+ (fn) => fn(state)
2854
+ );
2848
2855
  }
2849
2856
  }
2850
2857
  );
@@ -2954,6 +2961,12 @@ var MeetingProvider = ({
2954
2961
  reactionListeners.current.add(cb);
2955
2962
  return () => reactionListeners.current.delete(cb);
2956
2963
  },
2964
+ onConnectionStateChanged: (cb) => {
2965
+ connectionStateListeners.current.add(cb);
2966
+ return () => {
2967
+ connectionStateListeners.current.delete(cb);
2968
+ };
2969
+ },
2957
2970
  onActiveSpeakersChanged: (cb) => {
2958
2971
  activeSpeakerListeners.current.add(cb);
2959
2972
  return () => {
@@ -3059,6 +3072,10 @@ var useMeeting = (handlers) => {
3059
3072
  if (!handlers?.onRecordingStopped) return;
3060
3073
  return ctx.onRecordingStopped(handlers.onRecordingStopped);
3061
3074
  }, [handlers?.onRecordingStopped]);
3075
+ (0, import_react4.useEffect)(() => {
3076
+ if (!handlers?.onConnectionStateChanged) return;
3077
+ return ctx.onConnectionStateChanged(handlers.onConnectionStateChanged);
3078
+ }, [handlers?.onConnectionStateChanged]);
3062
3079
  (0, import_react4.useEffect)(() => {
3063
3080
  if (!handlers?.onReaction) return;
3064
3081
  return ctx.onReaction(handlers.onReaction);
@@ -3200,7 +3217,6 @@ function useMeetingPreview(roomId, participantId) {
3200
3217
  ActiveSpeakerDetector,
3201
3218
  MeetingProvider,
3202
3219
  MeetingState,
3203
- SFUClient,
3204
3220
  VideoSDKCore,
3205
3221
  useLocalParticipant,
3206
3222
  useMeeting,