UNPKG

@rtcio/react

Version:

A wrapper around the @rtcio/core library for React integration

91 lines 3.92 kB
import { jsx as _jsx } from "react/jsx-runtime"; import { RTC, } from "@rtcio/core"; import { createContext, useEffect, useMemo, useRef, useState, } from "react"; import { option } from "@dbidwell94/ts-utils"; export const p2pContext = createContext(null); export default function P2PProvider({ roomName, signaler, children, dataTimeoutMs, iceServers, maxChunkSizeBytes, pollSignalerInterval, }) { const memoSignaler = useMemo(() => signaler, []); const memoIce = useMemo(() => iceServers, []); const memoDataTimeout = useMemo(() => dataTimeoutMs, []); const memoDataSize = useMemo(() => maxChunkSizeBytes, []); const peers = useRef(new Map()); const signalerPeers = useRef(new Set()); const [signalPeersUpdated, setSignalPeersUpdated] = useState(false); const [peerIds, setPeerIds] = useState([]); const [rtc, setRtc] = useState(option.none()); useEffect(() => { if (rtc.isNone()) return; const { rtc: manager } = rtc.value; let interval = option.none(); const onPeersHandler = new AbortController(); if (pollSignalerInterval) { interval = option.some(setInterval(() => { const roomPeers = new Set(manager.getRoomPeers()); let peersUpdated = false; // first, check to see if a new peer joined for (const peerId of roomPeers) { if (!signalerPeers.current.has(peerId)) { signalerPeers.current.add(peerId); peersUpdated = true; } } // now check to see if a peer disconnected for (const peerId of signalerPeers.current) { if (!roomPeers.has(peerId)) { peersUpdated = true; signalerPeers.current.delete(peerId); } } if (peersUpdated) { setSignalPeersUpdated((val) => !val); } }, pollSignalerInterval)); } else { manager.on("signalPeerConnected", (newPeer) => { signalerPeers.current.add(newPeer); setSignalPeersUpdated((val) => !val); }, onPeersHandler.signal); manager.on("signalPeerDisconnected", (peerId) => { signalerPeers.current.delete(peerId); setSignalPeersUpdated((val) => !val); }, onPeersHandler.signal); } return () => { interval.inspect((handle) => clearTimeout(handle)); onPeersHandler.abort(); }; }, [pollSignalerInterval, rtc]); useEffect(() => { const rtcInstance = new RTC({ roomName, signaler: memoSignaler, dataTimeoutMs: memoDataTimeout, iceServers: memoIce, maxChunkSizeBytes: memoDataSize, }); rtcInstance.connectToRoom().then((res) => { if (res.isError()) { return; } rtcInstance.on("connected", (peer) => { peers.current.set(peer.id, peer); setPeerIds((current) => [...current, peer.id]); peer.on("connectionClosed", (peerId) => { setPeerIds((current) => current.filter((id) => id !== peerId)); peers.current.delete(peerId); }); }); setRtc(option.some({ rtc: rtcInstance, myId: res.value })); }); return () => { rtcInstance.close(); }; }, [roomName]); const memoSignalPeers = useMemo(() => { return Array.from(signalerPeers.current); }, [signalPeersUpdated]); return (_jsx(p2pContext.Provider, { value: { rtc, peerIds, peers, signalerPeers: memoSignalPeers }, children: children })); } //# sourceMappingURL=Provider.js.map