@@ -58,7 +58,14 @@ export class GunRegistry {
5858 // { urls: 'stun:stun2.l.google.com:19302' }
5959 // ]
6060 // },
61- // localStorage: options.localStorage ?? true,
61+ webrtc : options . webrtc || {
62+ iceServers : [
63+ { urls : 'stun:stun.l.google.com:19302' } ,
64+ { urls : 'stun:stun1.l.google.com:19302' } ,
65+ { urls : 'stun:stun2.l.google.com:19302' }
66+ ]
67+ } ,
68+ localStorage : options . localStorage ?? true ,
6269 } ;
6370
6471 this . initializeGun ( ) ;
@@ -68,10 +75,14 @@ export class GunRegistry {
6875 try {
6976 this . gun = Gun ( {
7077 peers : this . options . peers ,
71- file : undefined , // Disable local file storage (must be string or undefined)
72- localStorage : false , // Use option or default to false
73- radisk : false , // Disable radisk storage
74- axe : false ,
78+ rtc : this . options . webrtc || {
79+ iceServers : [
80+ { urls : 'stun:stun.l.google.com:19302' } ,
81+ { urls : 'stun:stun1.l.google.com:19302' } ,
82+ { urls : 'stun:stun2.l.google.com:19302' }
83+ ]
84+ } ,
85+ localStorage : this . options . localStorage ?? true
7586 } ) ;
7687 this . isGunAvailable = true ;
7788 console . log ( "Gun.js registry initialized with WebRTC and mesh networking" ) ;
@@ -324,4 +335,104 @@ export class GunRegistry {
324335 } ) ;
325336 } ) ;
326337 }
338+
339+ /**
340+ * Unregister a host from the Gun.js registry
341+ */
342+ public async unregister ( storeId : string ) : Promise < void > {
343+ if ( ! this . isGunAvailable || ! this . gun ) {
344+ throw new Error ( "Gun.js registry not available" ) ;
345+ }
346+
347+ if ( ! storeId ) {
348+ throw new Error ( "StoreId is required for unregistration" ) ;
349+ }
350+
351+ try {
352+ const hostRef = this . gun
353+ . get ( this . options . namespace ! )
354+ . get ( storeId ) ;
355+
356+ // Clear all host data by setting to null
357+ hostRef . put ( null ) ;
358+
359+ console . log ( `✅ [GunRegistry] Successfully unregistered host: ${ storeId } ` ) ;
360+ } catch ( error ) {
361+ console . error ( `❌ [GunRegistry] Failed to unregister host ${ storeId } :` , error ) ;
362+ throw error ;
363+ }
364+ }
365+
366+ /**
367+ * Send a signaling message to a peer (for WebRTC negotiation)
368+ */
369+ public async sendSignalingMessage ( targetPeer : string , message : Record < string , unknown > ) : Promise < void > {
370+ if ( ! this . isGunAvailable || ! this . gun ) {
371+ throw new Error ( "Gun.js registry not available" ) ;
372+ }
373+
374+ if ( ! targetPeer ) {
375+ throw new Error ( "Target peer ID is required" ) ;
376+ }
377+
378+ try {
379+ const signalRef = this . gun
380+ . get ( this . options . namespace ! )
381+ . get ( 'signaling' )
382+ . get ( targetPeer ) ;
383+
384+ const signalData = {
385+ ...message ,
386+ timestamp : Date . now ( )
387+ } ;
388+
389+ signalRef . put ( signalData ) ;
390+ console . log ( `📡 [GunRegistry] Sent signaling message to ${ targetPeer } ` ) ;
391+ } catch ( error ) {
392+ console . error ( `❌ [GunRegistry] Failed to send signaling message to ${ targetPeer } :` , error ) ;
393+ throw error ;
394+ }
395+ }
396+
397+ /**
398+ * Listen for signaling messages for this peer
399+ */
400+ public onSignalingMessage ( peerId : string , callback : ( message : Record < string , unknown > ) => void ) : void {
401+ if ( ! this . isGunAvailable || ! this . gun ) {
402+ console . warn ( 'Gun.js not available, signaling will not work' ) ;
403+ return ;
404+ }
405+
406+ if ( ! peerId ) {
407+ throw new Error ( "Peer ID is required" ) ;
408+ }
409+
410+ try {
411+ const signalRef = this . gun
412+ . get ( this . options . namespace ! )
413+ . get ( 'signaling' )
414+ . get ( peerId ) ;
415+
416+ signalRef . on ( ( data : Record < string , unknown > ) => {
417+ if ( data && typeof data === 'object' && ! Array . isArray ( data ) ) {
418+ // Filter out Gun.js metadata
419+ const messageData = Object . keys ( data )
420+ . filter ( key => key !== '_' )
421+ . reduce ( ( obj , key ) => {
422+ obj [ key ] = data [ key ] ;
423+ return obj ;
424+ } , { } as Record < string , unknown > ) ;
425+
426+ if ( Object . keys ( messageData ) . length > 0 ) {
427+ callback ( messageData ) ;
428+ }
429+ }
430+ } ) ;
431+
432+ console . log ( `🎧 [GunRegistry] Listening for signaling messages for peer: ${ peerId } ` ) ;
433+ } catch ( error ) {
434+ console . error ( `❌ [GunRegistry] Failed to set up signaling listener for ${ peerId } :` , error ) ;
435+ throw error ;
436+ }
437+ }
327438}
0 commit comments