@@ -158,3 +158,97 @@ export function useHostPeerSession<T>(
158158
159159 return [ partnerState , myState , setMyState , isConnected , myID ] ;
160160}
161+
162+ // Hook usage:
163+
164+ // const [peerStates, myState, setMyState, myID, numConnections, error] = useHostMultiPeerSession<StateInterface>()
165+ interface PeerDataPair < T > {
166+ id : string ;
167+ data : T ;
168+ }
169+
170+ export function useHostMultiPeerSession < T > ( initialState : T ) : [ PeerDataPair < T > [ ] , T , ( state : T ) => void , string , number , string ?] {
171+ const [ peerStates , setPeerStates ] = useState < PeerDataPair < T > [ ] > ( [ ] ) ;
172+ const [ myState , setMyState ] = useState < T > ( initialState ) ;
173+ const [ myID , setMyID ] = useState ( '' ) ;
174+ const [ error , setError ] = useState < string > ( ) ;
175+ const [ peer , setPeer ] = useState < any > ( ) ;
176+ const conns = peer ?. connections . length ;
177+ const [ _numConnections , setNumConnections ] = useState ( conns ) ; // used to force a re-render when the number of connections changes, actual value is not used as peer object has a connections property
178+
179+
180+
181+ useEffect (
182+ ( ) => {
183+ const shouldGetNewID = myID === '' ;
184+ const IDToUse = shouldGetNewID ? generateID ( ) : myID ;
185+ console . log ( `IDToUse: ${ IDToUse } ` ) ;
186+
187+ if ( peer && ! shouldGetNewID ) {
188+ return ;
189+ } else {
190+ if ( peer && shouldGetNewID ) {
191+ peer . destroy ( ) ;
192+ }
193+
194+ import ( 'peerjs' ) . then ( ( { default : Peer } ) => {
195+ const peer = new Peer ( IDToUse ) ;
196+ setPeer ( peer ) ;
197+ peer . on ( 'open' , ( id ) => {
198+ setMyID ( id ) ;
199+ peer . on ( 'connection' , ( conn ) => {
200+ {
201+ /*@ts -ignore*/ }
202+ conn . on ( 'data' , ( data : T ) => {
203+ setPeerStates ( ( prev ) => {
204+ const newState = [ ...prev ] ;
205+ const index = newState . findIndex ( ( p ) => p . id === conn . peer ) ;
206+ if ( index === - 1 ) {
207+ newState . push ( { id : conn . peer , data } ) ;
208+ } else {
209+ newState [ index ] = { id : conn . peer , data } ;
210+ }
211+ return newState ;
212+ } ) ;
213+ } ) ;
214+
215+ setNumConnections ( ( prev : number ) => prev + 1 ) ;
216+ } ) ;
217+ } ) ;
218+ peer . on ( 'error' , ( err ) => {
219+ console . error ( err ) ;
220+ setError ( err . message ) ;
221+ } ) ;
222+
223+ peer . on ( 'close' , ( ) => {
224+ setNumConnections ( 0 ) ;
225+ } ) ;
226+
227+ peer . on ( 'disconnected' , ( ) => {
228+ setNumConnections ( 0 ) ;
229+ } ) ;
230+ } ) ;
231+ }
232+ } ,
233+ // eslint-disable-next-line react-hooks/exhaustive-deps
234+ [ myID , conns ]
235+ ) ;
236+
237+ const connections = Object . values ( peer ?. connections || { } ) ;
238+
239+ useEffect ( ( ) => {
240+ if ( myState && connections ) {
241+ connections . forEach ( ( conn : any ) => {
242+ if ( conn && conn [ 0 ] ) {
243+ conn [ 0 ] . send ( myState ) ;
244+ } else {
245+ setNumConnections ( ( prev : number ) => prev - 1 ) ;
246+ }
247+ } ) ;
248+ }
249+ }
250+ // eslint-disable-next-line react-hooks/exhaustive-deps
251+ , [ myState , connections , connections . length ] ) ;
252+
253+ return [ peerStates , myState , setMyState , myID , conns , error ] ;
254+ }
0 commit comments