@afosecure/meetingsdk 1.0.7

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/react/useLocalParticipant.tsx","../src/react/MeetingProvider.tsx","../src/config/ws.ts","../src/core/MeetingState.ts","../src/core/VideoCore.ts","../src/react/useMeetingStore.ts","../src/react/useMeeting.ts","../src/react/useParticipants.ts","../src/react/useRemoteMedia.ts"],"sourcesContent":["export { useLocalParticipant } from \"./react/useLocalParticipant\";\r\n\r\n// Core exports\r\nexport { VideoSDKCore } from \"./core/VideoCore\";\r\nexport { MeetingState } from \"./core/MeetingState\";\r\nexport type { Participant, ChatInput } from \"./types/meeting\";\r\n\r\n// React hooks and components\r\nexport { MeetingProvider, useMeetingContext } from \"./react/MeetingProvider\";\r\nexport { useMeeting } from \"./react/useMeeting\";\r\nexport { useParticipants } from \"./react/useParticipants\";\r\nexport { useRemoteMedia } from \"./react/useRemoteMedia\";\r\n","import { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport { useMeetingContext } from \"./MeetingProvider\";\r\nimport { Participant } from \"../types/meeting\";\r\n\r\nexport const useLocalParticipant = () => {\r\n const { sdk } = useMeetingContext();\r\n\r\n // Guard the initial state to ensure it matches Participant | null\r\n const [localParticipant, setLocalParticipant] = useState<Participant | null>(\r\n () => {\r\n const current = sdk.state.localParticipant;\r\n return current && current.id ? (current as Participant) : null;\r\n },\r\n );\r\n\r\n useEffect(() => {\r\n const unsubscribe = sdk.state.subscribe(\"localParticipant\", () => {\r\n const current = sdk.state.localParticipant;\r\n\r\n // Safe Type-Guard: Only update if the object has a finalized id\r\n if (current && current.id) {\r\n setLocalParticipant({ ...current } as Participant);\r\n } else {\r\n setLocalParticipant(null);\r\n }\r\n });\r\n\r\n return unsubscribe;\r\n }, [sdk]);\r\n\r\n const lastStreamRef = useRef<MediaStream | null>(null);\r\n\r\n const videoRef = useCallback(\r\n (video: HTMLVideoElement | null) => {\r\n if (!video) return;\r\n\r\n const stream = localParticipant?.media?.stream;\r\n if (!stream) return;\r\n\r\n if (lastStreamRef.current === stream) return;\r\n lastStreamRef.current = stream;\r\n\r\n video.srcObject = stream;\r\n video.autoplay = true;\r\n video.playsInline = true;\r\n video.muted = true;\r\n\r\n video.play().catch((err) => {\r\n console.warn(`Autoplay failed for local view:`, err);\r\n });\r\n },\r\n [localParticipant?.media?.stream],\r\n );\r\n\r\n return {\r\n participant: localParticipant,\r\n videoRef,\r\n };\r\n};\r\n","import React, { createContext, useContext, useMemo, useRef } from \"react\";\r\nimport { VideoSDKCore } from \"../core/VideoCore\";\r\nimport {\r\n ChatInput,\r\n ChatMessage,\r\n MeetingConfig,\r\n Participant,\r\n PubSubTopic,\r\n} from \"../types/meeting\";\r\nimport { useMeetingStore } from \"./useMeetingStore\";\r\n\r\ntype PubSubHandle = {\r\n messages: ChatMessage[];\r\n publish: (input: ChatInput) => void;\r\n};\r\n\r\ntype MeetingContextValue = {\r\n sdk: VideoSDKCore;\r\n\r\n join: (config: MeetingConfig) => Promise<void>;\r\n leave: () => void;\r\n\r\n toggleMic: () => void;\r\n toggleCam: () => void;\r\n\r\n startScreenShare: () => Promise<MediaStream>;\r\n stopScreenShare: () => void;\r\n\r\n sendMessage: (input: ChatInput) => void;\r\n\r\n meetingId: string | null;\r\n localParticipant: Participant | null;\r\n participants: Map<string, Participant>;\r\n messages: ChatMessage[];\r\n presenterId: string | null;\r\n usePubSub: (topic: PubSubTopic) => PubSubHandle;\r\n onError: (cb: (err: any) => void) => () => void;\r\n};\r\n\r\nconst MeetingContext = createContext<MeetingContextValue | null>(null);\r\n\r\nexport const MeetingProvider = ({\r\n config,\r\n children,\r\n}: {\r\n config: MeetingConfig;\r\n children: React.ReactNode;\r\n}) => {\r\n const sdkRef = useRef<VideoSDKCore | null>(null);\r\n const errorListeners = useRef(new Set<(err: any) => void>());\r\n if (!sdkRef.current) {\r\n sdkRef.current = new VideoSDKCore({\r\n onError: (err) => {\r\n errorListeners.current.forEach((fn) => fn(err));\r\n },\r\n });\r\n }\r\n\r\n const sdk = sdkRef.current;\r\n const presenterId = useMeetingStore(\r\n sdk.state,\r\n \"presenter\",\r\n (s) => s.presenterId,\r\n );\r\n const participants = useMeetingStore(\r\n sdk.state,\r\n \"participants\",\r\n (s) => s.participants,\r\n );\r\n const localParticipant = useMeetingStore(\r\n sdk.state,\r\n \"localParticipant\",\r\n (s) => s.localParticipant,\r\n );\r\n const messages = useMeetingStore(sdk.state, \"chat\", (s) =>\r\n s.getChatMessages(),\r\n );\r\n\r\n const value = useMemo<MeetingContextValue>(() => {\r\n if (!sdkRef.current) {\r\n sdkRef.current = new VideoSDKCore({\r\n onError: (err) => {\r\n errorListeners.current.forEach((fn) => fn(err));\r\n },\r\n });\r\n }\r\n\r\n return {\r\n sdk,\r\n\r\n join: (joinConfig: MeetingConfig) =>\r\n sdk.joinMeeting({\r\n ...config,\r\n ...joinConfig,\r\n }),\r\n leave: () => sdk.disconnect(),\r\n toggleMic: sdk.toggleMic.bind(sdk),\r\n toggleCam: sdk.toggleCam.bind(sdk),\r\n startScreenShare: sdk.startScreenShare.bind(sdk),\r\n stopScreenShare: sdk.stopScreenShare.bind(sdk),\r\n sendMessage: sdk.sendChatMessage.bind(sdk),\r\n\r\n meetingId: sdk.getMeetingId(),\r\n localParticipant,\r\n participants,\r\n messages,\r\n presenterId,\r\n usePubSub: (topic: PubSubTopic) => {\r\n if (topic !== \"SECURE_CHAT\") {\r\n throw new Error(`Unsupported PubSub argument: \"${topic}\"`);\r\n }\r\n return {\r\n messages: sdk.state.getChatMessages(),\r\n publish: sdk.sendChatMessage.bind(sdk),\r\n };\r\n },\r\n onError: (cb: (err: any) => void) => {\r\n errorListeners.current.add(cb);\r\n\r\n return () => {\r\n errorListeners.current.delete(cb);\r\n };\r\n },\r\n };\r\n }, [config, sdk, localParticipant, participants, messages, presenterId]);\r\n\r\n return (\r\n <MeetingContext.Provider value={value}>{children}</MeetingContext.Provider>\r\n );\r\n};\r\n\r\nexport const useMeetingContext = () => {\r\n const ctx = useContext(MeetingContext);\r\n if (!ctx)\r\n throw new Error(\"useMeetingContext must be used inside <MeetingProvider>\");\r\n return ctx;\r\n};\r\n","export const SDK_CONFIG = {\r\n wsUrl: \"wss://rust-video-server-sfyf.onrender.com/ws\",\r\n};\r\n","import {\r\n ChatMessage,\r\n Listener,\r\n Participant,\r\n ParticipantMedia,\r\n StateScope,\r\n} from \"../types/meeting\";\r\n\r\ntype LocalParticipantPatch = {\r\n id?: string;\r\n name?: string;\r\n media?: Partial<ParticipantMedia>;\r\n};\r\n\r\nexport class MeetingState {\r\n participants = new Map<string, Participant>();\r\n localParticipant: Participant | null = null;\r\n localStream: MediaStream | null = null;\r\n chatMessages = new Map<string, ChatMessage>();\r\n presenterId: string | null = null;\r\n\r\n private listeners = new Map<StateScope, Set<Listener>>();\r\n\r\n // ---- reactive system ----\r\n\r\n subscribe(scope: StateScope, fn: Listener): () => void {\r\n if (!this.listeners.has(scope)) {\r\n this.listeners.set(scope, new Set());\r\n }\r\n this.listeners.get(scope)!.add(fn);\r\n\r\n return () => {\r\n this.listeners.get(scope)?.delete(fn);\r\n };\r\n }\r\n\r\n notify(scope: StateScope) {\r\n this.listeners.get(scope)?.forEach((fn) => fn());\r\n }\r\n\r\n setPresenterId(id: string | null) {\r\n if (this.presenterId === id) return;\r\n this.presenterId = id;\r\n this.notify(\"presenter\");\r\n this.notify(\"participants\");\r\n }\r\n\r\n // ---- participants ----\r\n\r\n addParticipant(p: Participant) {\r\n if (this.participants.has(p.id)) return false;\r\n // Fix: Immutable Map update\r\n const next = new Map(this.participants);\r\n next.set(p.id, p);\r\n this.participants = next;\r\n\r\n this.notify(\"participants\");\r\n return true;\r\n }\r\n\r\n removeParticipant(id: string) {\r\n // Fix: Immutable Map update\r\n const next = new Map(this.participants);\r\n next.delete(id);\r\n this.participants = next;\r\n\r\n this.notify(\"participants\");\r\n }\r\n\r\n updateParticipantMedia(\r\n id: string,\r\n patch: Partial<NonNullable<Participant[\"media\"]>>,\r\n ) {\r\n const p = this.participants.get(id);\r\n if (!p) return;\r\n\r\n const updated: Participant = {\r\n ...p,\r\n media: {\r\n stream: null,\r\n screenStream: undefined,\r\n cameraTrack: undefined,\r\n screenTrack: undefined,\r\n audioTrack: undefined,\r\n micEnabled: true,\r\n camEnabled: true,\r\n isScreenSharing: false,\r\n ...p.media, // preserve existing media items if they happen to exist\r\n ...patch, // apply the incoming stream updates\r\n },\r\n };\r\n\r\n // Keep your clean immutable map update\r\n const next = new Map(this.participants);\r\n next.set(id, updated);\r\n this.participants = next;\r\n\r\n this.notify(`participant:${id}`);\r\n this.notify(\"participants\");\r\n }\r\n\r\n updateLocalParticipant(patch: LocalParticipantPatch) {\r\n const prev = this.localParticipant;\r\n\r\n if (!prev) {\r\n this.localParticipant = {\r\n id: patch.id ?? \"\",\r\n name: patch.name ?? \"\",\r\n media: {\r\n stream: patch.media?.stream ?? null, // ◄ FIX: Capture the stream from the patch here\r\n screenStream: patch.media?.screenStream,\r\n cameraTrack: patch.media?.cameraTrack,\r\n screenTrack: patch.media?.screenTrack,\r\n audioTrack: patch.media?.audioTrack,\r\n micEnabled: patch.media?.micEnabled ?? true,\r\n camEnabled: patch.media?.camEnabled ?? true,\r\n isScreenSharing: patch.media?.isScreenSharing ?? false,\r\n },\r\n };\r\n\r\n this.notify(\"localParticipant\");\r\n return;\r\n }\r\n\r\n const prevMedia = prev.media ?? {\r\n stream: null,\r\n screenStream: undefined,\r\n cameraTrack: undefined,\r\n screenTrack: undefined,\r\n audioTrack: undefined,\r\n micEnabled: true,\r\n camEnabled: true,\r\n isScreenSharing: false,\r\n };\r\n\r\n const nextMedia: ParticipantMedia = {\r\n stream: patch.media?.stream ?? prevMedia.stream,\r\n screenStream: patch.media?.screenStream ?? prevMedia.screenStream,\r\n cameraTrack: patch.media?.cameraTrack ?? prevMedia.cameraTrack,\r\n screenTrack: patch.media?.screenTrack ?? prevMedia.screenTrack,\r\n audioTrack: patch.media?.audioTrack ?? prevMedia.audioTrack,\r\n micEnabled: patch.media?.micEnabled ?? prevMedia.micEnabled,\r\n camEnabled: patch.media?.camEnabled ?? prevMedia.camEnabled,\r\n isScreenSharing:\r\n patch.media?.isScreenSharing ?? prevMedia.isScreenSharing,\r\n };\r\n\r\n this.localParticipant = {\r\n ...prev,\r\n id: patch.id ?? prev.id,\r\n name: patch.name ?? prev.name,\r\n media: nextMedia,\r\n };\r\n\r\n this.notify(\"localParticipant\");\r\n }\r\n\r\n // ---- chat ----\r\n\r\n addChatMessage(msg: ChatMessage) {\r\n this.chatMessages.set(msg.id, msg);\r\n this.notify(\"chat\");\r\n }\r\n\r\n getChatMessages() {\r\n return Array.from(this.chatMessages.values()).sort(\r\n (a, b) => a.timestamp - b.timestamp,\r\n );\r\n }\r\n\r\n clearChat() {\r\n this.chatMessages.clear();\r\n this.notify(\"chat\");\r\n }\r\n\r\n // ---- helpers ----\r\n\r\n getParticipants() {\r\n return Array.from(this.participants.values());\r\n }\r\n\r\n getParticipant(id: string) {\r\n return this.participants.get(id) ?? null;\r\n }\r\n\r\n resetRemoteState() {\r\n this.participants.clear();\r\n this.chatMessages.clear();\r\n this.presenterId = null;\r\n this.notify(\"participants\");\r\n this.notify(\"chat\");\r\n this.notify(\"presenter\");\r\n }\r\n}\r\n","import { SDK_CONFIG } from \"../config/ws\";\r\nimport {\r\n ChatInput,\r\n ChatMessage,\r\n Events,\r\n MeetingConfig,\r\n SDKError,\r\n} from \"../types/meeting\";\r\nimport { MeetingState } from \"./MeetingState\";\r\n\r\nexport class VideoSDKCore {\r\n private ws: WebSocket | null = null;\r\n private peers: Record<string, RTCPeerConnection> = {};\r\n private initiators = new Set<string>();\r\n\r\n private myId: string;\r\n private roomId: string | null = null;\r\n private localStream: MediaStream | null = null;\r\n private screenStream: MediaStream | null = null;\r\n private isScreenSharing = false;\r\n private screenSenders: Record<string, RTCRtpSender[]> = {};\r\n\r\n private pingInterval: any = null;\r\n private pendingIceCandidates: Record<string, RTCIceCandidateInit[]> = {};\r\n private reconnectAttempts = 0;\r\n private reconnectTimer?: number;\r\n private participantName = \"\";\r\n public readonly state: MeetingState;\r\n private joinResolver?: () => void;\r\n private joinRejecter?: (e: any) => void;\r\n private emitError(\r\n code: string,\r\n message: string,\r\n raw?: any,\r\n recoverable = true,\r\n ) {\r\n const err: SDKError = {\r\n code,\r\n message,\r\n raw,\r\n roomId: this.roomId,\r\n userId: this.myId,\r\n recoverable,\r\n };\r\n\r\n this.events.onError?.(err);\r\n\r\n this.joinRejecter?.(err);\r\n this.joinRejecter = undefined;\r\n\r\n console.error(\"[MeetingSDK Error]\", err);\r\n }\r\n\r\n constructor(\r\n private events: Events = {},\r\n private url: string = SDK_CONFIG.wsUrl,\r\n ) {\r\n this.state = new MeetingState();\r\n this.events = events;\r\n this.url = url;\r\n\r\n this.myId = localStorage.getItem(\"vsdk_id\") || crypto.randomUUID();\r\n\r\n localStorage.setItem(\"vsdk_id\", this.myId);\r\n }\r\n\r\n // ---------------- STREAM ----------------\r\n async initLocal(video: HTMLVideoElement, name: string) {\r\n this.participantName = name;\r\n\r\n if (!this.localStream) {\r\n this.localStream = await navigator.mediaDevices.getUserMedia({\r\n video: true,\r\n audio: true,\r\n });\r\n }\r\n\r\n video.srcObject = this.localStream;\r\n\r\n // Fix: Supply mandatory fields to satisfy the Participant type constraint\r\n this.state.updateLocalParticipant({\r\n id: this.myId,\r\n name: this.participantName,\r\n media: {\r\n stream: this.localStream,\r\n micEnabled: true,\r\n camEnabled: true,\r\n isScreenSharing: false,\r\n },\r\n });\r\n\r\n this.state.localStream = this.localStream;\r\n }\r\n\r\n // ---------------- CONNECT ----------------\r\n async connect(roomId: string, name: string) {\r\n this.roomId = roomId;\r\n\r\n this.reset();\r\n\r\n return new Promise<void>((resolve, reject) => {\r\n this.joinResolver = resolve;\r\n this.joinRejecter = reject;\r\n this.ws = new WebSocket(this.url);\r\n\r\n this.ws.onopen = () => {\r\n this.send({\r\n type: \"JOIN\",\r\n room_id: roomId,\r\n user_id: this.myId,\r\n sender_name: name,\r\n });\r\n };\r\n\r\n this.ws.onerror = (err) => {\r\n this.emitError(\"WS_ERROR\", \"WebSocket encountered an error\", err, true);\r\n };\r\n\r\n this.ws.onclose = (e) => {\r\n this.emitError(\r\n \"WS_CLOSED\",\r\n `Connection closed (${e.code}) ${e.reason || \"\"}`,\r\n e,\r\n true,\r\n );\r\n\r\n // If join never resolved, fail the promise\r\n this.joinRejecter?.({\r\n code: \"WS_CLOSED\",\r\n message: \"Connection closed before join completed\",\r\n raw: e,\r\n });\r\n\r\n this.joinRejecter = undefined;\r\n\r\n this.scheduleReconnect();\r\n };\r\n\r\n this.ws.onmessage = async (e) => {\r\n await this.handle(JSON.parse(e.data));\r\n };\r\n });\r\n }\r\n\r\n async joinMeeting(config: MeetingConfig) {\r\n const { roomId, name, audioMuted = false, videoMuted = false } = config;\r\n\r\n if (!roomId || !name) {\r\n throw new Error(\"roomId and name are required to join meeting\");\r\n }\r\n\r\n this.participantName = name;\r\n\r\n // Reuse existing stream if initLocal already configured it\r\n if (!this.localStream) {\r\n this.localStream = await navigator.mediaDevices.getUserMedia({\r\n video: true,\r\n audio: true,\r\n });\r\n }\r\n\r\n this.localStream.getAudioTracks().forEach((t) => {\r\n t.enabled = !audioMuted;\r\n });\r\n this.localStream.getVideoTracks().forEach((t) => {\r\n t.enabled = !videoMuted;\r\n });\r\n\r\n this.state.updateLocalParticipant({\r\n id: this.myId,\r\n name: this.participantName,\r\n media: {\r\n stream: this.localStream,\r\n micEnabled: !audioMuted,\r\n camEnabled: !videoMuted,\r\n isScreenSharing: false,\r\n },\r\n });\r\n\r\n this.state.localStream = this.localStream;\r\n\r\n await this.connect(roomId, name);\r\n }\r\n\r\n /** Expose the roomId without making it fully public */\r\n getMeetingId(): string | null {\r\n return this.roomId;\r\n }\r\n\r\n toggleMic() {\r\n const mediaState = this.state.localParticipant?.media;\r\n if (!mediaState) return;\r\n\r\n // Flip the state tracked in localParticipant.media\r\n const nextEnabled = !mediaState.micEnabled;\r\n\r\n // Mirror the state change down to the actual hardware tracks\r\n this.localStream\r\n ?.getAudioTracks()\r\n .forEach((t) => (t.enabled = nextEnabled));\r\n\r\n // Update state layer\r\n this.state.updateLocalParticipant({\r\n id: this.myId,\r\n name: this.participantName,\r\n media: {\r\n ...mediaState,\r\n micEnabled: nextEnabled,\r\n },\r\n });\r\n\r\n // Notify peers\r\n this.send({\r\n type: \"MEDIA_STATE\",\r\n kind: \"audio\",\r\n enabled: nextEnabled,\r\n });\r\n }\r\n\r\n toggleCam() {\r\n const mediaState = this.state.localParticipant?.media;\r\n if (!mediaState) return;\r\n\r\n // Flip the state tracked in localParticipant.media\r\n const nextEnabled = !mediaState.camEnabled;\r\n\r\n // Mirror the state change down to the actual hardware tracks\r\n this.localStream\r\n ?.getVideoTracks()\r\n .forEach((t) => (t.enabled = nextEnabled));\r\n\r\n // Update state layer\r\n this.state.updateLocalParticipant({\r\n id: this.myId,\r\n name: this.participantName,\r\n media: {\r\n ...mediaState,\r\n camEnabled: nextEnabled,\r\n },\r\n });\r\n\r\n // Notify peers\r\n this.send({\r\n type: \"MEDIA_STATE\",\r\n kind: \"video\",\r\n enabled: nextEnabled,\r\n });\r\n }\r\n\r\n private scheduleReconnect() {\r\n if (!this.roomId) return;\r\n\r\n const delay = Math.min(1000 * Math.pow(2, this.reconnectAttempts), 30000);\r\n\r\n clearTimeout(this.reconnectTimer);\r\n\r\n this.reconnectTimer = window.setTimeout(async () => {\r\n try {\r\n await this.connect(this.roomId!, this.participantName);\r\n\r\n this.reconnectAttempts = 0;\r\n } catch {\r\n this.reconnectAttempts++;\r\n this.scheduleReconnect();\r\n }\r\n }, delay);\r\n }\r\n\r\n private startHeartbeat() {\r\n this.stopHeartbeat();\r\n\r\n this.pingInterval = setInterval(() => {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) return;\r\n\r\n this.send({\r\n type: \"PING\",\r\n client_ts: Date.now(),\r\n });\r\n }, 20000); // every 20s\r\n }\r\n private stopHeartbeat() {\r\n if (this.pingInterval) {\r\n clearInterval(this.pingInterval);\r\n this.pingInterval = null;\r\n }\r\n }\r\n\r\n // ---------------- RESET ----------------\r\n private reset() {\r\n Object.values(this.peers).forEach((pc) => pc.close());\r\n\r\n this.peers = {};\r\n this.initiators.clear();\r\n this.pendingIceCandidates = {};\r\n\r\n this.state.resetRemoteState();\r\n }\r\n\r\n // ---------------- HANDLE SIGNALS ----------------\r\n private async handle(msg: any) {\r\n if (msg.sender === this.myId) return;\r\n\r\n switch (msg.type) {\r\n case \"EXISTING_USERS\":\r\n if (msg.presenterId) {\r\n this.state.setPresenterId(msg.presenterId);\r\n\r\n // Trigger your event so the UI knows to render the stage\r\n this.events.onScreenShareStarted?.(msg.presenterId, null!);\r\n }\r\n\r\n for (const p of msg.participants || []) {\r\n if (!p?.id || p.id === this.myId) continue;\r\n this.state.addParticipant(p);\r\n this.events.onUserJoined?.(p);\r\n await this.createOffer(p.id);\r\n }\r\n break;\r\n\r\n case \"JOINED\": {\r\n this.startHeartbeat();\r\n this.joinResolver?.();\r\n this.joinResolver = undefined;\r\n this.joinRejecter = undefined;\r\n break;\r\n }\r\n case \"USER_JOINED\": {\r\n const p = msg.participant;\r\n\r\n if (!p?.id || p.id === this.myId) return;\r\n\r\n this.state.addParticipant(p);\r\n\r\n this.events.onUserJoined?.(p);\r\n\r\n break;\r\n }\r\n\r\n case \"OFFER\":\r\n await this.handleOffer(msg.payload, msg.sender);\r\n break;\r\n\r\n case \"ANSWER\": {\r\n const pc = this.peers[msg.sender];\r\n if (!pc) return;\r\n\r\n if (pc.signalingState !== \"have-local-offer\") {\r\n console.warn(\"Ignoring invalid answer:\", pc.signalingState);\r\n return;\r\n }\r\n\r\n await pc.setRemoteDescription({\r\n type: \"answer\",\r\n sdp: msg.payload,\r\n });\r\n\r\n // CRITICAL WEBRTC FIX: Flush cached ICE paths now that remoteDescription is set!\r\n await this.flushIce(msg.sender, pc);\r\n\r\n break;\r\n }\r\n\r\n case \"ICE\": {\r\n const candidate = JSON.parse(msg.payload);\r\n\r\n let pc = this.peers[msg.sender];\r\n\r\n if (!pc) {\r\n this.pendingIceCandidates[msg.sender] ??= [];\r\n this.pendingIceCandidates[msg.sender].push(candidate);\r\n break;\r\n }\r\n\r\n if (!pc.remoteDescription) {\r\n this.pendingIceCandidates[msg.sender] ??= [];\r\n this.pendingIceCandidates[msg.sender].push(candidate);\r\n break;\r\n }\r\n\r\n try {\r\n await pc.addIceCandidate(candidate);\r\n } catch (err) {\r\n console.warn(\"ICE error:\", err);\r\n }\r\n\r\n break;\r\n }\r\n\r\n case \"USER_LEFT\":\r\n const peerId = msg.participant.id;\r\n this.closePeer(peerId);\r\n\r\n this.state.removeParticipant(peerId);\r\n\r\n this.events.onUserLeft?.(peerId);\r\n\r\n break;\r\n\r\n case \"MEDIA_STATE_CHANGE\": {\r\n const peerId = msg.peerId;\r\n const { kind, enabled } = msg;\r\n\r\n // 1. Sync the app state layer for UI rendering components\r\n if (kind === \"audio\") {\r\n this.state.updateParticipantMedia(peerId, { micEnabled: enabled });\r\n this.events.onMicToggled?.(peerId, enabled);\r\n } else if (kind === \"video\") {\r\n this.state.updateParticipantMedia(peerId, { camEnabled: enabled });\r\n this.events.onCamToggled?.(peerId, enabled);\r\n }\r\n\r\n break;\r\n }\r\n\r\n case \"CHAT_MESSAGE\": {\r\n const newMsg = msg.data;\r\n\r\n if (newMsg.sender_id === this.myId) break; // already added optimistically\r\n this.state.addChatMessage({\r\n id: newMsg.id,\r\n text: newMsg.message,\r\n sender_id: newMsg.sender_id,\r\n sender_name: newMsg.sender_name,\r\n timestamp: new Date(newMsg.timestamp).getTime(),\r\n target: newMsg.target,\r\n });\r\n\r\n this.events.onChatMessage?.(msg);\r\n break;\r\n }\r\n case \"SCREEN_SHARE_START\": {\r\n const peerId = msg.peerId;\r\n\r\n this.state.updateParticipantMedia(peerId, {\r\n isScreenSharing: true,\r\n remoteScreenStreamId: msg.stream_id,\r\n });\r\n\r\n if (!this.state.presenterId) {\r\n this.state.setPresenterId(peerId);\r\n }\r\n\r\n // Fix: Use screenStream instead of the regular camera stream\r\n const screenStream =\r\n this.state.getParticipant(peerId)?.media?.screenStream;\r\n\r\n this.events.onScreenShareStarted?.(peerId, screenStream || null!);\r\n break;\r\n }\r\n\r\n case \"SCREEN_SHARE_STOP\": {\r\n const peerId = msg.peerId;\r\n this.state.updateParticipantMedia(peerId, { isScreenSharing: false });\r\n if (this.state.presenterId === peerId) {\r\n this.state.setPresenterId(null);\r\n }\r\n this.events.onScreenShareStopped?.(peerId);\r\n break;\r\n }\r\n case \"ERROR\": {\r\n const fatal = msg?.fatal === true;\r\n\r\n this.emitError(\r\n \"WS_ERROR\",\r\n msg?.message || \"Unknown error\",\r\n msg,\r\n !fatal,\r\n );\r\n\r\n if (fatal) {\r\n this.disconnect();\r\n }\r\n\r\n return;\r\n }\r\n }\r\n }\r\n\r\n // ---------------- PEER ----------------\r\n private createPeer(id: string) {\r\n if (!this.localStream) throw new Error(\"No local stream\");\r\n\r\n const pc = new RTCPeerConnection({\r\n iceServers: [\r\n {\r\n urls: [\r\n \"stun:stun.l.google.com:19302\",\r\n \"stun:stun1.l.google.com:19302\",\r\n ],\r\n },\r\n ],\r\n });\r\n\r\n pc.ontrack = (event) => {\r\n const incomingStream = event.streams[0];\r\n const participant = this.state.getParticipant(id);\r\n\r\n const isScreenStream =\r\n incomingStream.id === participant?.media?.remoteScreenStreamId;\r\n\r\n if (isScreenStream) {\r\n const videoTrack =\r\n event.track.kind === \"video\"\r\n ? event.track\r\n : incomingStream.getVideoTracks()[0] ||\r\n participant?.media?.screenTrack;\r\n\r\n this.state.updateParticipantMedia(id, {\r\n screenStream: incomingStream,\r\n screenTrack: videoTrack,\r\n\r\n isScreenSharing: true,\r\n });\r\n\r\n // CRITICAL FIX: Late joiners never get SCREEN_SHARE_START.\r\n // We must set the presenter ID here if it isn't set, otherwise the grid won't render the stage.\r\n if (!this.state.presenterId) {\r\n this.state.setPresenterId(id);\r\n }\r\n\r\n this.events.onScreenShareStarted?.(id, incomingStream);\r\n } else {\r\n this.state.updateParticipantMedia(id, {\r\n stream: incomingStream,\r\n cameraTrack: incomingStream.getVideoTracks()[0],\r\n });\r\n this.events.onTrack?.(incomingStream, id);\r\n }\r\n };\r\n\r\n pc.onicecandidate = (e) => {\r\n if (!e.candidate) return;\r\n this.send({\r\n type: \"ICE\",\r\n payload: JSON.stringify(e.candidate),\r\n sender: this.myId,\r\n target: id,\r\n });\r\n };\r\n\r\n pc.onconnectionstatechange = () => {\r\n if (pc.connectionState === \"failed\") {\r\n try {\r\n pc.restartIce();\r\n } catch {}\r\n }\r\n };\r\n\r\n this.localStream.getTracks().forEach((track) => {\r\n pc.addTrack(track, this.localStream!);\r\n });\r\n\r\n if (this.isScreenSharing && this.screenStream) {\r\n this.screenSenders[id] = [];\r\n this.screenStream.getTracks().forEach((track) => {\r\n const sender = pc.addTrack(track, this.screenStream!);\r\n this.screenSenders[id].push(sender);\r\n });\r\n }\r\n\r\n return pc;\r\n }\r\n\r\n // ---------------- OFFER ----------------\r\n private async createOffer(id: string, isRenegotiation = false) {\r\n // Only apply the initial glare gate if this is not a track renegotiation\r\n if (!isRenegotiation && this.initiators.has(id)) return;\r\n\r\n if (!isRenegotiation) {\r\n this.initiators.add(id);\r\n }\r\n\r\n if (!this.peers[id]) {\r\n this.peers[id] = this.createPeer(id);\r\n }\r\n\r\n const pc = this.peers[id];\r\n\r\n if (pc.signalingState !== \"stable\") {\r\n return;\r\n }\r\n\r\n const offer = await pc.createOffer();\r\n await pc.setLocalDescription(offer);\r\n\r\n this.send({\r\n type: \"OFFER\",\r\n payload: offer.sdp,\r\n sender: this.myId,\r\n target: id,\r\n });\r\n }\r\n\r\n // ---------------- ANSWER ----------------\r\n private async handleOffer(sdp: string, id: string) {\r\n if (!this.peers[id]) {\r\n this.peers[id] = this.createPeer(id);\r\n }\r\n\r\n const pc = this.peers[id];\r\n\r\n await pc.setRemoteDescription({\r\n type: \"offer\",\r\n sdp,\r\n });\r\n\r\n const pending = this.pendingIceCandidates[id] || [];\r\n\r\n for (const candidate of pending) {\r\n try {\r\n await pc.addIceCandidate(candidate);\r\n } catch (err) {\r\n console.warn(err);\r\n }\r\n }\r\n\r\n delete this.pendingIceCandidates[id];\r\n\r\n const answer = await pc.createAnswer();\r\n\r\n await pc.setLocalDescription(answer);\r\n await this.flushIce(id, pc);\r\n\r\n this.send({\r\n type: \"ANSWER\",\r\n payload: answer.sdp,\r\n sender: this.myId,\r\n target: id,\r\n });\r\n }\r\n\r\n // ---------------- CLEANUP ----------------\r\n private closePeer(id: string) {\r\n const pc = this.peers[id];\r\n\r\n if (!pc) return;\r\n\r\n pc.ontrack = null;\r\n pc.onicecandidate = null;\r\n pc.onconnectionstatechange = null;\r\n\r\n pc.close();\r\n\r\n delete this.peers[id];\r\n\r\n this.initiators.delete(id);\r\n\r\n this.state.removeParticipant(id);\r\n }\r\n\r\n async startScreenShare() {\r\n if (this.state.presenterId && this.state.presenterId !== this.myId) {\r\n throw new Error(\"Another user is already sharing their screen.\");\r\n }\r\n\r\n this.screenStream = await navigator.mediaDevices.getDisplayMedia({\r\n video: true,\r\n audio: true,\r\n });\r\n\r\n this.isScreenSharing = true;\r\n\r\n this.state.updateLocalParticipant({\r\n media: {\r\n isScreenSharing: true,\r\n screenStream: this.screenStream,\r\n },\r\n });\r\n\r\n this.state.setPresenterId(this.myId);\r\n // Handle the user clicking browser's built-in \"Stop Sharing\" button\r\n this.screenStream.getVideoTracks()[0].onended = () => {\r\n this.stopScreenShare();\r\n };\r\n\r\n Object.entries(this.peers).forEach(([peerId, pc]) => {\r\n this.screenSenders[peerId] = [];\r\n this.screenStream!.getTracks().forEach((track) => {\r\n const sender = pc.addTrack(track, this.screenStream!);\r\n this.screenSenders[peerId].push(sender);\r\n });\r\n\r\n // Renegotiate peer connection descriptors to notify remote side of new track footprint\r\n this.createOffer(peerId, true);\r\n });\r\n\r\n this.send({\r\n type: \"SCREEN_SHARE_START\",\r\n sender: this.myId,\r\n room_id: this.roomId,\r\n stream_id: this.screenStream.id.replace(/[{}]/g, \"\"),\r\n });\r\n\r\n return this.screenStream;\r\n }\r\n\r\n stopScreenShare() {\r\n if (!this.screenStream) return;\r\n\r\n this.screenStream.getTracks().forEach((t) => t.stop());\r\n\r\n // Remove tracks cleanly from WebRTC channel pathways across your peers\r\n Object.entries(this.peers).forEach(([peerId, pc]) => {\r\n const senders = this.screenSenders[peerId] || [];\r\n senders.forEach((sender) => {\r\n try {\r\n pc.removeTrack(sender);\r\n } catch (err) {\r\n console.warn(err);\r\n }\r\n });\r\n delete this.screenSenders[peerId];\r\n\r\n // Renegotiate layout expectations to scale down stream bounds\r\n this.createOffer(peerId, true);\r\n });\r\n\r\n this.screenStream = null;\r\n this.isScreenSharing = false;\r\n\r\n this.state.updateLocalParticipant({\r\n media: {\r\n isScreenSharing: false,\r\n screenStream: null,\r\n screenTrack: undefined,\r\n },\r\n });\r\n\r\n if (this.state.presenterId === this.myId) {\r\n this.state.setPresenterId(null);\r\n }\r\n\r\n this.send({\r\n type: \"SCREEN_SHARE_STOP\",\r\n sender: this.myId,\r\n room_id: this.roomId,\r\n });\r\n }\r\n\r\n sendChatMessage(payload: ChatInput) {\r\n if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {\r\n console.warn(\"WS not connected\");\r\n return;\r\n }\r\n\r\n if (!this.roomId) {\r\n console.warn(\"No roomId set\");\r\n return;\r\n }\r\n\r\n const isPrivate = !!payload?.target;\r\n\r\n const senderName = this.state.localParticipant?.name || \"Anonymous\";\r\n\r\n const msg: ChatMessage = {\r\n id: crypto.randomUUID(),\r\n sender_id: this.myId,\r\n sender_name: senderName,\r\n text: payload.message.trim(),\r\n timestamp: Date.now(),\r\n reply_to: payload.reply_to ?? null,\r\n target: payload.target ?? null,\r\n };\r\n\r\n // optimistic UI update\r\n this.state.addChatMessage(msg);\r\n\r\n // send protocol payload (clean + consistent)\r\n this.send({\r\n type: \"CHAT_MESSAGE\",\r\n message: payload.message.trim(),\r\n user_id: this.myId,\r\n sender_name: senderName,\r\n room_id: this.roomId,\r\n target: isPrivate ? (payload.target ?? null) : null,\r\n reply_to: payload.reply_to ?? null,\r\n\r\n client_ts: Date.now(),\r\n });\r\n }\r\n\r\n disconnect() {\r\n this.stopScreenShare();\r\n\r\n Object.values(this.peers).forEach((pc) => pc.close());\r\n this.peers = {};\r\n this.initiators.clear();\r\n\r\n this.stopHeartbeat();\r\n\r\n if (this.ws) {\r\n this.ws.close();\r\n this.ws = null;\r\n }\r\n\r\n if (this.localStream) {\r\n this.localStream.getTracks().forEach((track) => track.stop());\r\n this.localStream = null;\r\n }\r\n\r\n this.roomId = null;\r\n\r\n // Clear and notify\r\n this.state.localParticipant = null;\r\n this.state.notify(\"localParticipant\");\r\n\r\n this.state.participants.clear();\r\n this.state.notify(\"participants\");\r\n\r\n this.state.clearChat();\r\n this.state.setPresenterId(null);\r\n }\r\n\r\n private async flushIce(id: string, pc: RTCPeerConnection) {\r\n const pending = this.pendingIceCandidates[id];\r\n if (!pending?.length) return;\r\n\r\n for (const candidate of pending) {\r\n try {\r\n await pc.addIceCandidate(candidate);\r\n } catch (e) {\r\n console.warn(\"ICE flush error\", e);\r\n }\r\n }\r\n\r\n delete this.pendingIceCandidates[id];\r\n }\r\n\r\n private send(msg: any) {\r\n this.ws?.send(JSON.stringify(msg));\r\n }\r\n}\r\n","import { useEffect, useState } from \"react\";\r\nimport { StateScope } from \"../types/meeting\";\r\nimport { MeetingState } from \"../core/MeetingState\";\r\n\r\nexport function useMeetingStore<T>(\r\n stateManager: MeetingState,\r\n scope: StateScope,\r\n selector: (state: MeetingState) => T,\r\n): T {\r\n const [state, setState] = useState(() => selector(stateManager));\r\n\r\n useEffect(() => {\r\n // Update local react state whenever the SDK notifies this scope\r\n const unsubscribe = stateManager.subscribe(scope, () => {\r\n setState(selector(stateManager));\r\n });\r\n\r\n return unsubscribe;\r\n }, [stateManager, scope, selector]);\r\n\r\n return state;\r\n}\r\n","import { useEffect } from \"react\";\r\nimport { useMeetingContext } from \"./MeetingProvider\";\r\n\r\nexport const useMeeting = (handlers?: { onError?: (err: any) => void }) => {\r\n const ctx = useMeetingContext();\r\n\r\n useEffect(() => {\r\n if (!handlers?.onError) return;\r\n\r\n const unsubscribe = ctx.onError(handlers.onError);\r\n return unsubscribe;\r\n }, [handlers?.onError]);\r\n\r\n return ctx;\r\n};\r\n","import { useEffect, useState } from \"react\";\r\nimport { useMeetingContext } from \"./MeetingProvider\";\r\nimport { Participant } from \"../types/meeting\";\r\n\r\nexport const useParticipants = () => {\r\n const { sdk } = useMeetingContext();\r\n\r\n const [participants, setParticipants] = useState<Participant[]>(() =>\r\n sdk.state.getParticipants(),\r\n );\r\n\r\n useEffect(() => {\r\n const update = () => {\r\n setParticipants(sdk.state.getParticipants());\r\n };\r\n\r\n update();\r\n\r\n const unsub = sdk.state.subscribe(\"participants\", update);\r\n\r\n return unsub;\r\n }, [sdk]);\r\n\r\n return participants;\r\n};\r\n","import { useEffect, useRef, useState } from \"react\";\r\nimport { useMeetingContext } from \"./MeetingProvider\";\r\nimport { Participant } from \"../types/meeting\";\r\n\r\nexport const useRemoteMedia = (participantId: string) => {\r\n const { sdk } = useMeetingContext();\r\n\r\n // Create refs to access the DOM elements directly\r\n const videoRef = useRef<HTMLVideoElement>(null);\r\n const audioRef = useRef<HTMLAudioElement>(null);\r\n\r\n const [participant, setParticipant] = useState<Participant | null>(\r\n () => sdk.state.getParticipant(participantId) || null,\r\n );\r\n\r\n // Sync state from SDK to React\r\n useEffect(() => {\r\n const unsub = sdk.state.subscribe(`participant:${participantId}`, () => {\r\n const updated = sdk.state.getParticipant(participantId);\r\n if (updated) {\r\n setParticipant({ ...updated });\r\n }\r\n });\r\n return unsub;\r\n }, [participantId, sdk]);\r\n\r\n // Handle stream attachment whenever the stream changes\r\n useEffect(() => {\r\n const stream = participant?.media?.stream;\r\n\r\n if (stream) {\r\n if (videoRef.current && videoRef.current.srcObject !== stream) {\r\n videoRef.current.srcObject = stream;\r\n }\r\n if (audioRef.current && audioRef.current.srcObject !== stream) {\r\n audioRef.current.srcObject = stream;\r\n }\r\n }\r\n }, [participant?.media?.stream]);\r\n\r\n return {\r\n videoRef,\r\n audioRef,\r\n isCamActive: !!participant?.media?.camEnabled,\r\n isMicEnabled: !!participant?.media?.micEnabled,\r\n };\r\n};\r\n"],"mappings":"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","names":["import_react","import_react","peerId","import_react","import_react","import_react"]}