vg-x07df 1.9.5 → 1.10.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/dist/index.cjs CHANGED
@@ -1913,6 +1913,14 @@ var callParticipantAddedSchema = zod.z.object({
1913
1913
  var callParticipantKickedSchema = zod.z.object({
1914
1914
  callId: zod.z.string(),
1915
1915
  participantId: zod.z.string(),
1916
+ userId: zod.z.string(),
1917
+ reason: zod.z.string().optional()
1918
+ }).strict();
1919
+ var callParticipantLeftSchema = zod.z.object({
1920
+ callId: zod.z.string(),
1921
+ userId: zod.z.string(),
1922
+ participantId: zod.z.string(),
1923
+ leftAt: zod.z.string(),
1916
1924
  reason: zod.z.string().optional()
1917
1925
  }).strict();
1918
1926
  var callReadySchema = zod.z.object({
@@ -2272,8 +2280,14 @@ var CallParticipantKickedHandler = class extends BaseSocketHandler {
2272
2280
  participantId: data.participantId,
2273
2281
  reason: data.reason
2274
2282
  });
2283
+ this.updateStore((state) => {
2284
+ if (data.userId && state.outgoingInvites[data.userId]) {
2285
+ delete state.outgoingInvites[data.userId];
2286
+ }
2287
+ });
2275
2288
  this.logger.debug("Participant kicked from call", {
2276
- participantId: data.participantId
2289
+ participantId: data.participantId,
2290
+ userId: data.userId
2277
2291
  });
2278
2292
  }
2279
2293
  };
@@ -2480,6 +2494,12 @@ var InviteMissedHandler = class extends BaseSocketHandler {
2480
2494
  userId: data.userId
2481
2495
  });
2482
2496
  if (currentState.session?.id !== data.callId) {
2497
+ this.logger.warn("Invite missed ignored due to session mismatch", {
2498
+ eventCallId: data.callId,
2499
+ sessionCallId: currentState.session?.id,
2500
+ hasSession: !!currentState.session,
2501
+ outgoingInviteKeys: Object.keys(currentState.outgoingInvites || {})
2502
+ });
2483
2503
  pushStaleEventError("call:inviteMissed", "callId mismatch", {
2484
2504
  eventCallId: data.callId,
2485
2505
  sessionCallId: currentState.session?.id
@@ -2615,6 +2635,42 @@ var ParticipantAddedHandler = class extends BaseSocketHandler {
2615
2635
  }
2616
2636
  };
2617
2637
 
2638
+ // src/core/socketio/handlers/participant-left.handler.ts
2639
+ var ParticipantLeftHandler = class extends BaseSocketHandler {
2640
+ constructor() {
2641
+ super(...arguments);
2642
+ this.eventName = "call:participantLeft";
2643
+ this.schema = callParticipantLeftSchema;
2644
+ }
2645
+ handle(data) {
2646
+ const currentState = rtcStore.getState();
2647
+ this.logger.info("Participant left call", {
2648
+ callId: data.callId,
2649
+ userId: data.userId,
2650
+ participantId: data.participantId
2651
+ });
2652
+ if (currentState.session?.id !== data.callId) {
2653
+ pushStaleEventError("call:participantLeft", "callId mismatch", {
2654
+ eventCallId: data.callId,
2655
+ sessionCallId: currentState.session?.id
2656
+ });
2657
+ this.logger.warn("Ignoring participant left for different call", {
2658
+ callId: data.callId
2659
+ });
2660
+ return;
2661
+ }
2662
+ this.updateStore((state) => {
2663
+ if (state.outgoingInvites[data.userId]) {
2664
+ state.outgoingInvites[data.userId].status = "left";
2665
+ this.logger.info("Outgoing invite marked as left", {
2666
+ userId: data.userId,
2667
+ callId: data.callId
2668
+ });
2669
+ }
2670
+ });
2671
+ }
2672
+ };
2673
+
2618
2674
  // src/core/socketio/handlers/participant-profiles.handler.ts
2619
2675
  var ParticipantProfilesHandler = class extends BaseSocketHandler {
2620
2676
  constructor() {
@@ -2792,6 +2848,7 @@ var SocketHandlerRegistry = class {
2792
2848
  new InviteCancelledHandler(this.options),
2793
2849
  // Participant management
2794
2850
  new ParticipantAddedHandler(this.options),
2851
+ new ParticipantLeftHandler(this.options),
2795
2852
  new CallParticipantKickedHandler(this.options),
2796
2853
  // Profile hydration
2797
2854
  new ParticipantProfilesHandler(this.options),
@@ -3630,6 +3687,10 @@ var LiveKitRoomManager = class {
3630
3687
  this.detach();
3631
3688
  rtcStore.getState().reset();
3632
3689
  profileCache.getState().clear();
3690
+ recordingStore.getState().clear();
3691
+ useChatStore.getState().clearChat();
3692
+ useSpotlightStore.getState().clear();
3693
+ useRaiseHandStore.getState().clear();
3633
3694
  }
3634
3695
  };
3635
3696
 
@@ -3976,7 +4037,8 @@ function createPresenceService(config, deps) {
3976
4037
  if (userIds.length === 0) {
3977
4038
  return [];
3978
4039
  }
3979
- const cacheKey = [...userIds].sort().join(",");
4040
+ const uniqueUserIds = Array.from(new Set(userIds));
4041
+ const cacheKey = [...uniqueUserIds].sort().join(",");
3980
4042
  const existing = inFlight.get(cacheKey);
3981
4043
  if (existing) {
3982
4044
  logger7.debug("Reusing in-flight request", { cacheKey });
@@ -3984,7 +4046,7 @@ function createPresenceService(config, deps) {
3984
4046
  }
3985
4047
  const fetchPromise = (async () => {
3986
4048
  try {
3987
- const response = await signalPresence.queryPresence(userIds);
4049
+ const response = await signalPresence.queryPresence(uniqueUserIds);
3988
4050
  return response.presence.map((p) => ({
3989
4051
  userId: p.userId,
3990
4052
  status: p.status,
@@ -5011,56 +5073,105 @@ var useScreenShare = () => {
5011
5073
  handleStopScreenShare
5012
5074
  };
5013
5075
  };
5014
- function usePresence(userId) {
5076
+ function usePresence(userId, options) {
5015
5077
  const sdk = useSdk();
5016
5078
  const [presence, setPresence] = React.useState();
5017
5079
  const [isLoading, setIsLoading] = React.useState(false);
5080
+ const [error, setError] = React.useState(null);
5081
+ const isMountedRef = React.useRef(true);
5018
5082
  const refetch = React.useCallback(async () => {
5019
5083
  if (!userId) return;
5020
5084
  setIsLoading(true);
5085
+ setError(null);
5021
5086
  try {
5022
5087
  const result = await sdk.presence.getPresence(userId);
5023
- setPresence(result);
5088
+ if (isMountedRef.current) {
5089
+ setPresence(result);
5090
+ }
5091
+ } catch (err) {
5092
+ if (isMountedRef.current) {
5093
+ setError(err);
5094
+ }
5024
5095
  } finally {
5025
- setIsLoading(false);
5096
+ if (isMountedRef.current) {
5097
+ setIsLoading(false);
5098
+ }
5026
5099
  }
5027
5100
  }, [sdk, userId]);
5028
5101
  React.useEffect(() => {
5029
5102
  refetch();
5030
5103
  }, [refetch]);
5104
+ React.useEffect(() => {
5105
+ if (!options?.pollIntervalMs) return;
5106
+ const id = setInterval(refetch, options.pollIntervalMs);
5107
+ return () => clearInterval(id);
5108
+ }, [options?.pollIntervalMs, refetch]);
5109
+ React.useEffect(() => {
5110
+ return () => {
5111
+ isMountedRef.current = false;
5112
+ };
5113
+ }, []);
5031
5114
  return {
5032
5115
  presence,
5033
5116
  status: presence?.status,
5117
+ resolvedStatus: error ? "unknown" : presence?.status,
5034
5118
  isLoading,
5119
+ error,
5035
5120
  refetch
5036
5121
  };
5037
5122
  }
5038
- function usePresenceMany(userIds) {
5123
+ function usePresenceMany(userIds, options) {
5039
5124
  const sdk = useSdk();
5040
5125
  const [presences, setPresences] = React.useState(
5041
5126
  /* @__PURE__ */ new Map()
5042
5127
  );
5043
5128
  const [isLoading, setIsLoading] = React.useState(false);
5129
+ const [error, setError] = React.useState(null);
5130
+ const isMountedRef = React.useRef(true);
5044
5131
  const refetch = React.useCallback(async () => {
5045
5132
  if (userIds.length === 0) return;
5046
5133
  setIsLoading(true);
5134
+ setError(null);
5047
5135
  try {
5048
5136
  const results = await sdk.presence.queryPresence(userIds);
5049
5137
  const map = /* @__PURE__ */ new Map();
5050
5138
  for (const p of results) {
5051
5139
  map.set(p.userId, p);
5052
5140
  }
5053
- setPresences(map);
5141
+ if (isMountedRef.current) {
5142
+ setPresences(map);
5143
+ }
5144
+ } catch (err) {
5145
+ if (isMountedRef.current) {
5146
+ setError(err);
5147
+ }
5054
5148
  } finally {
5055
- setIsLoading(false);
5149
+ if (isMountedRef.current) {
5150
+ setIsLoading(false);
5151
+ }
5056
5152
  }
5057
5153
  }, [sdk, userIds]);
5058
5154
  React.useEffect(() => {
5059
5155
  refetch();
5060
5156
  }, [refetch]);
5157
+ React.useEffect(() => {
5158
+ if (!options?.pollIntervalMs) return;
5159
+ const id = setInterval(refetch, options.pollIntervalMs);
5160
+ return () => clearInterval(id);
5161
+ }, [options?.pollIntervalMs, refetch]);
5162
+ React.useEffect(() => {
5163
+ return () => {
5164
+ isMountedRef.current = false;
5165
+ };
5166
+ }, []);
5061
5167
  return {
5062
5168
  presences,
5063
5169
  isLoading,
5170
+ error,
5171
+ getStatus: (userId) => {
5172
+ if (error) return "unknown";
5173
+ return presences.get(userId)?.status;
5174
+ },
5064
5175
  refetch
5065
5176
  };
5066
5177
  }
@@ -5172,6 +5283,7 @@ exports.callInviteMissedSchema = callInviteMissedSchema;
5172
5283
  exports.callInviteSchema = callInviteSchema;
5173
5284
  exports.callParticipantAddedSchema = callParticipantAddedSchema;
5174
5285
  exports.callParticipantKickedSchema = callParticipantKickedSchema;
5286
+ exports.callParticipantLeftSchema = callParticipantLeftSchema;
5175
5287
  exports.callReadySchema = callReadySchema;
5176
5288
  exports.callRecordingStartedSchema = callRecordingStartedSchema;
5177
5289
  exports.callRecordingStoppedSchema = callRecordingStoppedSchema;