@defcomm/meetingsdk 0.1.5 → 0.1.6

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/README.md CHANGED
@@ -974,7 +974,7 @@ type SDKError = {
974
974
  code: string;
975
975
  message: string;
976
976
  roomId?: string | null;
977
- userId?: string;
977
+ participantId?: string;
978
978
  raw?: any;
979
979
  recoverable?: boolean;
980
980
  };
package/dist/index.d.mts CHANGED
@@ -83,7 +83,7 @@ type ChatInput = {
83
83
  };
84
84
  type MeetingConfig = {
85
85
  roomId: string;
86
- userId?: string;
86
+ participantId: string;
87
87
  name: string;
88
88
  audioMuted?: boolean;
89
89
  videoMuted?: boolean;
@@ -101,14 +101,14 @@ type SDKError = {
101
101
  code: string;
102
102
  message: string;
103
103
  roomId?: string | null;
104
- userId?: string;
104
+ participantId?: string;
105
105
  raw?: any;
106
106
  recoverable?: boolean;
107
107
  };
108
108
  type EntryDecision = "approved" | "rejected";
109
109
  type EntryRequest = {
110
110
  requestId: string;
111
- userId: string;
111
+ participantId: string;
112
112
  name: string;
113
113
  };
114
114
  interface TrackDescriptor {
@@ -121,6 +121,16 @@ interface Recording {
121
121
  started_at?: string;
122
122
  recording_id?: string;
123
123
  }
124
+ interface VideoSDKCoreOptions {
125
+ participantId: string;
126
+ onError?: (error: any) => void;
127
+ onEntryRequested?: (request: any) => void;
128
+ onEntryResponded?: (payload: any, decision?: any) => void;
129
+ onMeetingLeft?: () => void;
130
+ onTrackStateChanged?: (track: any) => void;
131
+ onRecordingStarted?: (recording: any) => void;
132
+ onRecordingStopped?: (recording: any) => void;
133
+ }
124
134
 
125
135
  declare const useLocalParticipant: () => {
126
136
  participant: Participant | null;
@@ -175,7 +185,7 @@ declare class VideoSDKCore {
175
185
  private joinPromise;
176
186
  private disconnectPromise;
177
187
  private emitError;
178
- constructor(events?: Events, apiBase?: string, wsBase?: string);
188
+ constructor(options: VideoSDKCoreOptions, events?: Events, apiBase?: string, wsBase?: string);
179
189
  initLocal(video: HTMLVideoElement, name: string): Promise<void>;
180
190
  private updateLocalMedia;
181
191
  createRoom(input: {
@@ -186,7 +196,7 @@ declare class VideoSDKCore {
186
196
  }): Promise<any>;
187
197
  getRoom(roomCode: string): Promise<any>;
188
198
  deleteRoom(roomCode: string): Promise<any>;
189
- joinMeeting(config: MeetingConfig): Promise<void>;
199
+ joinMeeting(config: Omit<MeetingConfig, "participantId">): Promise<void>;
190
200
  private connect;
191
201
  private handleSFUState;
192
202
  private handleRemoteTrack;
@@ -244,7 +254,7 @@ interface JoinPendingInfo {
244
254
  interface SFUClientOptions {
245
255
  apiBase?: string;
246
256
  wsBase?: string;
247
- userId?: string;
257
+ participantId?: string;
248
258
  onStateChange?: (state: SFUConnectionState) => void;
249
259
  onParticipantJoined?: (participant: ParticipantInfo) => void;
250
260
  onParticipantLeft?: (participant: string | ParticipantInfo) => void;
@@ -276,7 +286,7 @@ interface SFUClientOptions {
276
286
  declare class SFUClient {
277
287
  private apiBase;
278
288
  private wsBase;
279
- private userId;
289
+ private participantId;
280
290
  private ws;
281
291
  private publisher;
282
292
  private subscriber;
@@ -368,7 +378,7 @@ declare class SFUClient {
368
378
  getToken(roomCode: string, options?: {
369
379
  displayName?: string;
370
380
  avatarUrl?: string;
371
- userId?: string;
381
+ participantId?: string;
372
382
  }): Promise<void>;
373
383
  private refreshAccessToken;
374
384
  private connect;
@@ -554,7 +564,7 @@ type LiveRoomState = {
554
564
  * Preview therefore uses the authoritative REST room endpoint and polls it.
555
565
  * Live participant/media state begins after JOIN over the SFU WebSocket.
556
566
  */
557
- declare function useMeetingPreview(roomId: string, userId: string): {
567
+ declare function useMeetingPreview(roomId: string, participantId: string): {
558
568
  room: LiveRoomState | null;
559
569
  isConnected: boolean;
560
570
  isLoading: boolean;
package/dist/index.d.ts CHANGED
@@ -83,7 +83,7 @@ type ChatInput = {
83
83
  };
84
84
  type MeetingConfig = {
85
85
  roomId: string;
86
- userId?: string;
86
+ participantId: string;
87
87
  name: string;
88
88
  audioMuted?: boolean;
89
89
  videoMuted?: boolean;
@@ -101,14 +101,14 @@ type SDKError = {
101
101
  code: string;
102
102
  message: string;
103
103
  roomId?: string | null;
104
- userId?: string;
104
+ participantId?: string;
105
105
  raw?: any;
106
106
  recoverable?: boolean;
107
107
  };
108
108
  type EntryDecision = "approved" | "rejected";
109
109
  type EntryRequest = {
110
110
  requestId: string;
111
- userId: string;
111
+ participantId: string;
112
112
  name: string;
113
113
  };
114
114
  interface TrackDescriptor {
@@ -121,6 +121,16 @@ interface Recording {
121
121
  started_at?: string;
122
122
  recording_id?: string;
123
123
  }
124
+ interface VideoSDKCoreOptions {
125
+ participantId: string;
126
+ onError?: (error: any) => void;
127
+ onEntryRequested?: (request: any) => void;
128
+ onEntryResponded?: (payload: any, decision?: any) => void;
129
+ onMeetingLeft?: () => void;
130
+ onTrackStateChanged?: (track: any) => void;
131
+ onRecordingStarted?: (recording: any) => void;
132
+ onRecordingStopped?: (recording: any) => void;
133
+ }
124
134
 
125
135
  declare const useLocalParticipant: () => {
126
136
  participant: Participant | null;
@@ -175,7 +185,7 @@ declare class VideoSDKCore {
175
185
  private joinPromise;
176
186
  private disconnectPromise;
177
187
  private emitError;
178
- constructor(events?: Events, apiBase?: string, wsBase?: string);
188
+ constructor(options: VideoSDKCoreOptions, events?: Events, apiBase?: string, wsBase?: string);
179
189
  initLocal(video: HTMLVideoElement, name: string): Promise<void>;
180
190
  private updateLocalMedia;
181
191
  createRoom(input: {
@@ -186,7 +196,7 @@ declare class VideoSDKCore {
186
196
  }): Promise<any>;
187
197
  getRoom(roomCode: string): Promise<any>;
188
198
  deleteRoom(roomCode: string): Promise<any>;
189
- joinMeeting(config: MeetingConfig): Promise<void>;
199
+ joinMeeting(config: Omit<MeetingConfig, "participantId">): Promise<void>;
190
200
  private connect;
191
201
  private handleSFUState;
192
202
  private handleRemoteTrack;
@@ -244,7 +254,7 @@ interface JoinPendingInfo {
244
254
  interface SFUClientOptions {
245
255
  apiBase?: string;
246
256
  wsBase?: string;
247
- userId?: string;
257
+ participantId?: string;
248
258
  onStateChange?: (state: SFUConnectionState) => void;
249
259
  onParticipantJoined?: (participant: ParticipantInfo) => void;
250
260
  onParticipantLeft?: (participant: string | ParticipantInfo) => void;
@@ -276,7 +286,7 @@ interface SFUClientOptions {
276
286
  declare class SFUClient {
277
287
  private apiBase;
278
288
  private wsBase;
279
- private userId;
289
+ private participantId;
280
290
  private ws;
281
291
  private publisher;
282
292
  private subscriber;
@@ -368,7 +378,7 @@ declare class SFUClient {
368
378
  getToken(roomCode: string, options?: {
369
379
  displayName?: string;
370
380
  avatarUrl?: string;
371
- userId?: string;
381
+ participantId?: string;
372
382
  }): Promise<void>;
373
383
  private refreshAccessToken;
374
384
  private connect;
@@ -554,7 +564,7 @@ type LiveRoomState = {
554
564
  * Preview therefore uses the authoritative REST room endpoint and polls it.
555
565
  * Live participant/media state begins after JOIN over the SFU WebSocket.
556
566
  */
557
- declare function useMeetingPreview(roomId: string, userId: string): {
567
+ declare function useMeetingPreview(roomId: string, participantId: string): {
558
568
  room: LiveRoomState | null;
559
569
  isConnected: boolean;
560
570
  isLoading: boolean;
package/dist/index.js CHANGED
@@ -428,7 +428,7 @@ var SFUClient = class {
428
428
  this.subscriberStatsTimer = null;
429
429
  this.apiBase = options.apiBase || "https://api.example.com/api";
430
430
  this.wsBase = options.wsBase || "wss://api.example.com/ws";
431
- this.userId = options.userId || this.createId();
431
+ this.participantId = options.participantId || this.createId();
432
432
  this.onStateChange = options.onStateChange || (() => {
433
433
  });
434
434
  this.onParticipantJoined = options.onParticipantJoined || (() => {
@@ -549,12 +549,17 @@ var SFUClient = class {
549
549
  });
550
550
  }
551
551
  async getRoom(roomCode) {
552
- return this.request(`${this.apiBase}/rooms/${encodeURIComponent(roomCode)}`);
552
+ return this.request(
553
+ `${this.apiBase}/rooms/${encodeURIComponent(roomCode)}`
554
+ );
553
555
  }
554
556
  async deleteRoom(roomCode) {
555
- return this.request(`${this.apiBase}/rooms/${encodeURIComponent(roomCode)}`, {
556
- method: "DELETE"
557
- });
557
+ return this.request(
558
+ `${this.apiBase}/rooms/${encodeURIComponent(roomCode)}`,
559
+ {
560
+ method: "DELETE"
561
+ }
562
+ );
558
563
  }
559
564
  async getToken(roomCode, options = {}) {
560
565
  const nextRoom = roomCode.trim();
@@ -566,7 +571,7 @@ var SFUClient = class {
566
571
  displayName: options.displayName,
567
572
  avatarUrl: options.avatarUrl
568
573
  };
569
- if (options.userId) this.userId = options.userId;
574
+ if (options.participantId) this.participantId = options.participantId;
570
575
  if (!this.resumeToken) {
571
576
  this.resumeToken = this.loadResumeToken(this.room);
572
577
  }
@@ -574,7 +579,7 @@ var SFUClient = class {
574
579
  method: "POST",
575
580
  body: JSON.stringify({
576
581
  room_code: this.room,
577
- user_id: this.userId,
582
+ user_id: this.participantId,
578
583
  display_name: options.displayName,
579
584
  avatar_url: options.avatarUrl
580
585
  })
@@ -589,7 +594,7 @@ var SFUClient = class {
589
594
  method: "POST",
590
595
  body: JSON.stringify({
591
596
  room_code: this.room,
592
- user_id: this.userId,
597
+ user_id: this.participantId,
593
598
  display_name: this.joinOptions.displayName,
594
599
  avatar_url: this.joinOptions.avatarUrl
595
600
  })
@@ -792,7 +797,8 @@ var SFUClient = class {
792
797
  case "participant_joined": {
793
798
  const participant = payload.participant || payload;
794
799
  const participantId = participant?.participant_id || payload.participant_id;
795
- if (!participantId || participantId === this.currentParticipantId) break;
800
+ if (!participantId || participantId === this.currentParticipantId)
801
+ break;
796
802
  if (participant) this.participants.set(participantId, participant);
797
803
  this.onParticipantJoined(participant);
798
804
  break;
@@ -822,14 +828,21 @@ var SFUClient = class {
822
828
  if (track.source === "audio") {
823
829
  this.localTrackIds.set("audio", track.track_id);
824
830
  const muted = !(this.localStream?.getAudioTracks()[0]?.enabled ?? true);
825
- this.send({ type: "track_state", payload: { track_id: track.track_id, muted } });
831
+ this.send({
832
+ type: "track_state",
833
+ payload: { track_id: track.track_id, muted }
834
+ });
826
835
  }
827
836
  if (track.source === "camera") {
828
837
  this.localTrackIds.set("camera", track.track_id);
829
838
  const muted = !(this.localStream?.getVideoTracks()[0]?.enabled ?? true);
830
- this.send({ type: "track_state", payload: { track_id: track.track_id, muted } });
839
+ this.send({
840
+ type: "track_state",
841
+ payload: { track_id: track.track_id, muted }
842
+ });
831
843
  }
832
- if (track.source === "screen") this.localTrackIds.set("screen", track.track_id);
844
+ if (track.source === "screen")
845
+ this.localTrackIds.set("screen", track.track_id);
833
846
  break;
834
847
  }
835
848
  this.onTrackPublished(track);
@@ -1060,10 +1073,7 @@ var SFUClient = class {
1060
1073
  }
1061
1074
  if (screenStream?.getTracks().length === 0) {
1062
1075
  this.remoteScreenStreams.delete(participantId);
1063
- this.onScreenShareStopped(
1064
- participantId,
1065
- metadata.track_id
1066
- );
1076
+ this.onScreenShareStopped(participantId, metadata.track_id);
1067
1077
  }
1068
1078
  };
1069
1079
  this.onScreenShareStarted(participantId, metadata);
@@ -1150,7 +1160,9 @@ var SFUClient = class {
1150
1160
  try {
1151
1161
  await pc.addIceCandidate(candidate);
1152
1162
  } catch (error) {
1153
- this.onError(new Error(`Failed to add ${peer} ICE candidate: ${String(error)}`));
1163
+ this.onError(
1164
+ new Error(`Failed to add ${peer} ICE candidate: ${String(error)}`)
1165
+ );
1154
1166
  }
1155
1167
  }
1156
1168
  async flushPendingIce(peer) {
@@ -1162,7 +1174,11 @@ var SFUClient = class {
1162
1174
  try {
1163
1175
  await pc.addIceCandidate(candidate);
1164
1176
  } catch (error) {
1165
- this.onError(new Error(`Failed to add queued ${peer} ICE candidate: ${String(error)}`));
1177
+ this.onError(
1178
+ new Error(
1179
+ `Failed to add queued ${peer} ICE candidate: ${String(error)}`
1180
+ )
1181
+ );
1166
1182
  }
1167
1183
  }
1168
1184
  }
@@ -1192,7 +1208,9 @@ var SFUClient = class {
1192
1208
  } catch (error) {
1193
1209
  const waiters = this.subscriptionWaiters.splice(0);
1194
1210
  waiters.forEach((w) => w.reject(error));
1195
- this.onError(new Error(`Failed to process subscriber offer: ${String(error)}`));
1211
+ this.onError(
1212
+ new Error(`Failed to process subscriber offer: ${String(error)}`)
1213
+ );
1196
1214
  } finally {
1197
1215
  this.subscriberNegotiating = false;
1198
1216
  }
@@ -1240,9 +1258,13 @@ var SFUClient = class {
1240
1258
  }
1241
1259
  }
1242
1260
  async publish({ audio = true, video = true } = {}) {
1243
- if (!this.publisher) throw new Error("Publisher PeerConnection is not initialized");
1261
+ if (!this.publisher)
1262
+ throw new Error("Publisher PeerConnection is not initialized");
1244
1263
  if (!this.localStream) {
1245
- this.localStream = await navigator.mediaDevices.getUserMedia({ audio, video });
1264
+ this.localStream = await navigator.mediaDevices.getUserMedia({
1265
+ audio,
1266
+ video
1267
+ });
1246
1268
  }
1247
1269
  await this.publishExistingTracks(audio, video);
1248
1270
  return this.localStream;
@@ -1255,9 +1277,13 @@ var SFUClient = class {
1255
1277
  const audioTrack = this.localStream.getAudioTracks().find((track) => track.readyState === "live");
1256
1278
  const cameraTrack = this.localStream.getVideoTracks().find((track) => track.readyState === "live");
1257
1279
  const screenTrack = this.screenStream?.getVideoTracks().find((track) => track.readyState === "live");
1258
- await this.audioSender?.replaceTrack(audio && audioTrack ? audioTrack : null);
1280
+ await this.audioSender?.replaceTrack(
1281
+ audio && audioTrack ? audioTrack : null
1282
+ );
1259
1283
  this.audioTransceiver.direction = audio && audioTrack ? "sendonly" : "inactive";
1260
- await this.videoSender?.replaceTrack(video && cameraTrack ? cameraTrack : null);
1284
+ await this.videoSender?.replaceTrack(
1285
+ video && cameraTrack ? cameraTrack : null
1286
+ );
1261
1287
  this.cameraTransceiver.direction = video && cameraTrack ? "sendonly" : "inactive";
1262
1288
  await this.screenSender?.replaceTrack(screenTrack || null);
1263
1289
  this.screenTransceiver.direction = screenTrack ? "sendonly" : "inactive";
@@ -1430,7 +1456,10 @@ var SFUClient = class {
1430
1456
  }
1431
1457
  async rejectJoinRequest(requestId, reason) {
1432
1458
  if (!requestId) throw new Error("requestId is required");
1433
- if (!this.send({ type: "reject_join", payload: { request_id: requestId, reason } })) {
1459
+ if (!this.send({
1460
+ type: "reject_join",
1461
+ payload: { request_id: requestId, reason }
1462
+ })) {
1434
1463
  throw new Error("SFU signaling is not connected");
1435
1464
  }
1436
1465
  }
@@ -1499,10 +1528,14 @@ var SFUClient = class {
1499
1528
  }
1500
1529
  setTimeout(check, 25);
1501
1530
  };
1502
- ws.addEventListener("close", () => {
1503
- clearTimeout(timeout);
1504
- finish();
1505
- }, { once: true });
1531
+ ws.addEventListener(
1532
+ "close",
1533
+ () => {
1534
+ clearTimeout(timeout);
1535
+ finish();
1536
+ },
1537
+ { once: true }
1538
+ );
1506
1539
  this.send({ type: "leave" });
1507
1540
  check();
1508
1541
  });
@@ -1581,7 +1614,8 @@ var SFUClient = class {
1581
1614
  }
1582
1615
  }
1583
1616
  async logSubscriberVideoStats() {
1584
- if (!this.subscriber || this.subscriber.connectionState === "closed") return;
1617
+ if (!this.subscriber || this.subscriber.connectionState === "closed")
1618
+ return;
1585
1619
  try {
1586
1620
  const stats = await this.subscriber.getStats();
1587
1621
  stats.forEach((report) => {
@@ -1602,7 +1636,7 @@ var SFUClient = class {
1602
1636
 
1603
1637
  // src/core/VideoCore.ts
1604
1638
  var VideoSDKCore = class {
1605
- constructor(events = {}, apiBase = SDK_CONFIG.apiBase, wsBase = SDK_CONFIG.wsBase) {
1639
+ constructor(options, events = {}, apiBase = SDK_CONFIG.apiBase, wsBase = SDK_CONFIG.wsBase) {
1606
1640
  this.events = events;
1607
1641
  this.apiBase = apiBase;
1608
1642
  this.wsBase = wsBase;
@@ -1628,18 +1662,7 @@ var VideoSDKCore = class {
1628
1662
  this.events.onActiveSpeakersChanged?.(participantIds);
1629
1663
  }
1630
1664
  });
1631
- let storedId = null;
1632
- try {
1633
- storedId = typeof localStorage !== "undefined" ? localStorage.getItem("defcomm:participant_id") : null;
1634
- } catch {
1635
- }
1636
- this.myId = storedId || (typeof crypto !== "undefined" && crypto.randomUUID ? crypto.randomUUID() : `user_${Date.now()}`);
1637
- try {
1638
- if (typeof localStorage !== "undefined") {
1639
- localStorage.setItem("defcomm:participant_id", this.myId);
1640
- }
1641
- } catch {
1642
- }
1665
+ this.myId = options.participantId;
1643
1666
  }
1644
1667
  emitError(code, message, raw, recoverable = true) {
1645
1668
  const err = {
@@ -1647,7 +1670,7 @@ var VideoSDKCore = class {
1647
1670
  message,
1648
1671
  raw,
1649
1672
  roomId: this.room.id,
1650
- userId: this.myId,
1673
+ participantId: this.myId,
1651
1674
  recoverable
1652
1675
  };
1653
1676
  this.events.onError?.(err);
@@ -1707,7 +1730,7 @@ var VideoSDKCore = class {
1707
1730
  const client = this.sfuClient ?? new SFUClient({
1708
1731
  apiBase: this.apiBase,
1709
1732
  wsBase: this.wsBase,
1710
- userId: this.myId
1733
+ participantId: this.myId
1711
1734
  });
1712
1735
  return client.createRoom(input);
1713
1736
  }
@@ -1715,7 +1738,7 @@ var VideoSDKCore = class {
1715
1738
  const client = this.sfuClient ?? new SFUClient({
1716
1739
  apiBase: this.apiBase,
1717
1740
  wsBase: this.wsBase,
1718
- userId: this.myId
1741
+ participantId: this.myId
1719
1742
  });
1720
1743
  return client.getRoom(roomCode);
1721
1744
  }
@@ -1723,29 +1746,23 @@ var VideoSDKCore = class {
1723
1746
  const client = this.sfuClient ?? new SFUClient({
1724
1747
  apiBase: this.apiBase,
1725
1748
  wsBase: this.wsBase,
1726
- userId: this.myId
1749
+ participantId: this.myId
1727
1750
  });
1728
1751
  return client.deleteRoom(roomCode);
1729
1752
  }
1730
1753
  // JOIN
1731
1754
  async joinMeeting(config) {
1732
- const {
1733
- roomId,
1734
- name,
1735
- audioMuted = false,
1736
- videoMuted = false,
1737
- userId
1738
- } = config;
1755
+ const { roomId, name, audioMuted = false, videoMuted = false } = config;
1739
1756
  if (!roomId || !name) {
1740
1757
  throw new Error("roomId and name are required to join meeting");
1741
1758
  }
1742
- if (userId) {
1743
- this.myId = userId;
1759
+ if (!this.myId) {
1760
+ throw new Error("participantId is required");
1744
1761
  }
1745
1762
  if (this.sfuClient && this.room.id === roomId && this.sfuClient.getConnectionState() === "connected") {
1746
1763
  console.info("[SDK] Already connected; duplicate join ignored", {
1747
1764
  roomId,
1748
- userId: this.myId
1765
+ participantId: this.myId
1749
1766
  });
1750
1767
  return;
1751
1768
  }
@@ -1754,7 +1771,7 @@ var VideoSDKCore = class {
1754
1771
  "[SDK] Join already in progress; waiting for existing join",
1755
1772
  {
1756
1773
  roomId,
1757
- userId: this.myId
1774
+ participantId: this.myId
1758
1775
  }
1759
1776
  );
1760
1777
  return this.joinPromise;
@@ -1816,7 +1833,7 @@ var VideoSDKCore = class {
1816
1833
  const client = new SFUClient({
1817
1834
  apiBase: this.apiBase,
1818
1835
  wsBase: this.wsBase,
1819
- userId: this.myId,
1836
+ participantId: this.myId,
1820
1837
  autoSubscribe: true,
1821
1838
  // CONNECTION STATE
1822
1839
  onStateChange: (state) => {
@@ -1840,7 +1857,7 @@ var VideoSDKCore = class {
1840
1857
  console.log("[SFU] Join request pending", info);
1841
1858
  this.events.onEntryRequested?.({
1842
1859
  requestId: info.request_id,
1843
- userId: this.myId,
1860
+ participantId: this.myId,
1844
1861
  name: this.participantName
1845
1862
  });
1846
1863
  },
@@ -1877,14 +1894,14 @@ var VideoSDKCore = class {
1877
1894
  },
1878
1895
  onJoinRequested: (request) => {
1879
1896
  const requestId = request?.request_id || request?.requestId;
1880
- const userId = request?.user_id || request?.userId;
1897
+ const participantId = request?.user_id || request?.participantId;
1881
1898
  const nameValue = request?.user_metadata?.name || request?.display_name || request?.name || "Participant";
1882
- if (!requestId || !userId) {
1899
+ if (!requestId || !participantId) {
1883
1900
  return;
1884
1901
  }
1885
1902
  this.events.onEntryRequested?.({
1886
1903
  requestId,
1887
- userId,
1904
+ participantId,
1888
1905
  name: nameValue
1889
1906
  });
1890
1907
  },
@@ -2058,6 +2075,10 @@ var VideoSDKCore = class {
2058
2075
  // ERROR
2059
2076
  onError: (error) => {
2060
2077
  console.error("[SFU] Error:", error);
2078
+ if (error?.code === "request_failed" || error?.code === "authorization") {
2079
+ this.emitError("PERMISSION_DENIED", error.message, error, false);
2080
+ return;
2081
+ }
2061
2082
  this.emitError(
2062
2083
  "SFU_ERROR",
2063
2084
  error?.message || String(error),
@@ -2070,7 +2091,7 @@ var VideoSDKCore = class {
2070
2091
  client.setLocalStream(this.localStream);
2071
2092
  await client.getToken(roomId, {
2072
2093
  displayName: name,
2073
- userId: this.myId
2094
+ participantId: this.myId
2074
2095
  });
2075
2096
  }
2076
2097
  // SFU STATE
@@ -2392,6 +2413,7 @@ var MeetingProvider = ({
2392
2413
  );
2393
2414
  if (!sdkRef.current) {
2394
2415
  sdkRef.current = new VideoSDKCore({
2416
+ participantId: config.participantId,
2395
2417
  onError: (err) => errorListeners.current.forEach((fn) => fn(err)),
2396
2418
  onEntryRequested: (req) => entryRequestListeners.current.forEach((fn) => fn(req)),
2397
2419
  onEntryResponded: (p, d) => entryResponseListeners.current.forEach((fn) => fn(p, d)),
@@ -2428,13 +2450,6 @@ var MeetingProvider = ({
2428
2450
  (s) => s.getChatMessages()
2429
2451
  );
2430
2452
  const value = (0, import_react2.useMemo)(() => {
2431
- if (!sdkRef.current) {
2432
- sdkRef.current = new VideoSDKCore({
2433
- onError: (err) => {
2434
- errorListeners.current.forEach((fn) => fn(err));
2435
- }
2436
- });
2437
- }
2438
2453
  return {
2439
2454
  sdk,
2440
2455
  join: (joinConfig) => sdk.joinMeeting({
@@ -2666,7 +2681,7 @@ var useRemoteMedia = (participantId) => {
2666
2681
 
2667
2682
  // src/react/useMeetingPreview.ts
2668
2683
  var import_react7 = require("react");
2669
- function useMeetingPreview(roomId, userId) {
2684
+ function useMeetingPreview(roomId, participantId) {
2670
2685
  const [room, setRoom] = (0, import_react7.useState)(null);
2671
2686
  const [error, setError] = (0, import_react7.useState)(null);
2672
2687
  const [isConnected, setIsConnected] = (0, import_react7.useState)(false);
@@ -2725,7 +2740,7 @@ function useMeetingPreview(roomId, userId) {
2725
2740
  stopped = true;
2726
2741
  if (timer) clearTimeout(timer);
2727
2742
  };
2728
- }, [roomId, userId]);
2743
+ }, [roomId, participantId]);
2729
2744
  return {
2730
2745
  room,
2731
2746
  isConnected,