WebRTCPeerProvider component in FilePizza codebase.
In this article, we will review WebRTCPeerProvider component in FilePizza codebase. FilePizza allows peer-to-peer file transfers in your browser. WebRTCProvider.tsx file This file, WebRTCProvider.tsx, has 102 LOC at the time of writing this article Context const WebRTCContext = React.createContext(null) This Provider component uses Context. useWebRTCPeer export const useWebRTCPeer = (): WebRTCPeerValue => { const value = useContext(WebRTCContext) if (value === null) { throw new Error('useWebRTC must be used within a WebRTCProvider') } return value } This just checks if useWebRTC is used within a WebRTCProvider and throws an error. getOrCreateGlobalPeer let globalPeer: Peer | null = null async function getOrCreateGlobalPeer(): Promise { if (!globalPeer) { const response = await fetch('/api/ice', { method: 'POST', }) const { iceServers } = await response.json() console.log('[WebRTCProvider] ICE servers:', iceServers) globalPeer = new Peer({ debug: 3, config: { iceServers, }, }) } if globalPeer is null, an API call is made to api/ice and a new Peer instance is created. Peer? what is that? import Peer from 'peerjs' Read more about Peerjs. if (globalPeer.id) { return globalPeer } await new Promise((resolve) => { const listener = (id: string) => { console.log('[WebRTCProvider] Peer ID:', id) globalPeer?.off('open', listener) resolve() } globalPeer?.on('open', listener) }) return globalPeer If globalPeer.id exists, globalPeer is returned. On “open” event, listener is called and resolve() is called inside the Promise. off removes the listener and finally globalPeer is removed. WebRTCPeerProvider export default function WebRTCPeerProvider({ children, }: { children?: React.ReactNode }): JSX.Element { const [peerValue, setPeerValue] = useState(globalPeer) const [isStopped, setIsStopped] = useState(false) const [error, setError] = useState(null) const stop = useCallback(() => { console.log('[WebRTCProvider] Stopping peer') globalPeer?.destroy() globalPeer = null setPeerValue(null) setIsStopped(true) }, []) useEffect(() => { getOrCreateGlobalPeer().then(setPeerValue).catch(setError) }, []) const value = useMemo(() => ({ peer: peerValue!, stop }), [peerValue, stop]) if (error) { return } if (isStopped) { return } if (!peerValue) { return } return ( {children} ) } It has different scenarios handled. I like that isStopped returns Fragments. About me: Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos. I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com My Github — https://github.com/ramu-narasinga My website — https://ramunarasinga.com My Youtube channel — https://www.youtube.com/@thinkthroo Learning platform — https://thinkthroo.com Codebase Architecture — https://app.thinkthroo.com/architecture Best practices — https://app.thinkthroo.com/best-practices Production-grade projects — https://app.thinkthroo.com/production-grade-projects References: https://github.com/kern/filepizza/blob/main/src/components/WebRTCProvider.tsx#L64 https://file.pizza/ https://github.com/kern/filepizza/blob/main/src/components/WebRTCProvider.tsx#L32

In this article, we will review WebRTCPeerProvider component in FilePizza codebase. FilePizza allows peer-to-peer file transfers in your browser.
WebRTCProvider.tsx file
This file, WebRTCProvider.tsx, has 102 LOC at the time of writing this article
Context
const WebRTCContext = React.createContext(null)
This Provider component uses Context.
useWebRTCPeer
export const useWebRTCPeer = (): WebRTCPeerValue => {
const value = useContext(WebRTCContext)
if (value === null) {
throw new Error('useWebRTC must be used within a WebRTCProvider')
}
return value
}
This just checks if useWebRTC is used within a WebRTCProvider and throws an error.
getOrCreateGlobalPeer
let globalPeer: Peer | null = null
async function getOrCreateGlobalPeer(): Promise {
if (!globalPeer) {
const response = await fetch('/api/ice', {
method: 'POST',
})
const { iceServers } = await response.json()
console.log('[WebRTCProvider] ICE servers:', iceServers)
globalPeer = new Peer({
debug: 3,
config: {
iceServers,
},
})
}
if globalPeer is null, an API call is made to api/ice
and a new Peer instance is created. Peer? what is that?
import Peer from 'peerjs'
Read more about Peerjs.
if (globalPeer.id) {
return globalPeer
}
await new Promise((resolve) => {
const listener = (id: string) => {
console.log('[WebRTCProvider] Peer ID:', id)
globalPeer?.off('open', listener)
resolve()
}
globalPeer?.on('open', listener)
})
return globalPeer
If globalPeer.id exists, globalPeer is returned. On “open” event, listener is called and resolve() is called inside the Promise. off removes the listener and finally globalPeer is removed.
WebRTCPeerProvider
export default function WebRTCPeerProvider({
children,
}: {
children?: React.ReactNode
}): JSX.Element {
const [peerValue, setPeerValue] = useState(globalPeer)
const [isStopped, setIsStopped] = useState(false)
const [error, setError] = useState(null)
const stop = useCallback(() => {
console.log('[WebRTCProvider] Stopping peer')
globalPeer?.destroy()
globalPeer = null
setPeerValue(null)
setIsStopped(true)
}, [])
useEffect(() => {
getOrCreateGlobalPeer().then(setPeerValue).catch(setError)
}, [])
const value = useMemo(() => ({ peer: peerValue!, stop }), [peerValue, stop])
if (error) {
return
}
if (isStopped) {
return <>>
}
if (!peerValue) {
return
}
return (
{children}
)
}
It has different scenarios handled. I like that isStopped returns Fragments.
About me:
Hey, my name is Ramu Narasinga. I study large open-source projects and create content about their codebase architecture and best practices, sharing it through articles, videos.
I am open to work on interesting projects. Send me an email at ramu.narasinga@gmail.com
My Github — https://github.com/ramu-narasinga
My website — https://ramunarasinga.com
My Youtube channel — https://www.youtube.com/@thinkthroo
Learning platform — https://thinkthroo.com
Codebase Architecture — https://app.thinkthroo.com/architecture
Best practices — https://app.thinkthroo.com/best-practices
Production-grade projects — https://app.thinkthroo.com/production-grade-projects