@@ -17,6 +17,14 @@ const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 30878;
1717// Graceful shutdown handler
1818async function gracefulShutdown ( signal : string ) : Promise < void > {
1919 console . log ( `\n🛑 Received ${ signal } , shutting down gracefully...` ) ;
20+
21+ // Stop re-broadcast interval
22+ if ( rebroadcastInterval ) {
23+ clearInterval ( rebroadcastInterval ) ;
24+ rebroadcastInterval = null ;
25+ console . log ( '✅ Re-broadcast interval stopped' ) ;
26+ }
27+
2028 console . log ( '✅ Gun relay server shutdown complete' ) ;
2129 process . exit ( 0 ) ;
2230}
@@ -26,11 +34,59 @@ process.on('SIGTERM', () => gracefulShutdown('SIGTERM'));
2634process . on ( 'SIGINT' , ( ) => gracefulShutdown ( 'SIGINT' ) ) ;
2735process . on ( 'SIGUSR2' , ( ) => gracefulShutdown ( 'SIGUSR2' ) ) ; // For nodemon
2836
37+ // Store data for re-broadcasting
38+ const storedData = new Map < string , Record < string , unknown > > ( ) ;
39+ let rebroadcastInterval : ReturnType < typeof setInterval > | null = null ;
40+
41+ /**
42+ * Store data for re-broadcasting
43+ */
44+ function storeData ( namespace : string , key : string , data : Record < string , unknown > ) : void {
45+ const dataKey = `${ namespace } /${ key } ` ;
46+ if ( data && typeof data === 'object' && Object . keys ( data ) . filter ( k => k !== '_' ) . length > 0 ) {
47+ storedData . set ( dataKey , { ...data } ) ;
48+ console . log ( `💾 Stored data for re-broadcasting: ${ dataKey } ` ) ;
49+ } else if ( data === null || data === undefined ) {
50+ storedData . delete ( dataKey ) ;
51+ console . log ( `🗑️ Removed data from re-broadcast store: ${ dataKey } ` ) ;
52+ }
53+ }
54+
55+ /**
56+ * Re-broadcast all stored data
57+ */
58+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
59+ function rebroadcastStoredData ( gun : any ) : void {
60+ const timestamp = new Date ( ) . toISOString ( ) ;
61+ console . log ( `📡 [${ timestamp } ] Re-broadcasting ${ storedData . size } stored entries...` ) ;
62+
63+ storedData . forEach ( ( data , dataKey ) => {
64+ const [ namespace , key ] = dataKey . split ( '/' , 2 ) ;
65+ if ( namespace && key ) {
66+ try {
67+ // Update lastSeen timestamp for host data
68+ const rebroadcastData = { ...data } ;
69+ if ( rebroadcastData . storeId && rebroadcastData . lastSeen ) {
70+ rebroadcastData . lastSeen = Date . now ( ) ;
71+ }
72+
73+ // Use gun as any to bypass TypeScript issues with dynamic property access
74+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
75+ ( gun as any ) . get ( namespace ) . get ( key ) . put ( rebroadcastData ) ;
76+ console . log ( `🔄 Re-broadcasted: ${ namespace } /${ key } ` ) ;
77+ } catch ( error ) {
78+ console . warn ( `⚠️ Failed to re-broadcast ${ dataKey } :` , error ) ;
79+ }
80+ }
81+ } ) ;
82+ }
83+
2984async function startRelay ( ) : Promise < void > {
3085 console . log ( '🚀 Starting Gun relay server...' ) ;
3186 console . log ( `📡 Port: ${ PORT } ` ) ;
3287 console . log ( '🔗 WebRTC enabled with mesh networking for peer-to-peer connections' ) ;
33- console . log ( '📊 This relay serves as discovery point only - data flows peer-to-peer' ) ;
88+ console . log ( '📊 This relay serves as discovery point with periodic re-broadcasting' ) ;
89+ console . log ( '🔄 Re-broadcasting stored data every 5 seconds' ) ;
3490 console . log ( '📝 Logging enabled for:' ) ;
3591 console . log ( ' • TCP connections and disconnections' ) ;
3692 console . log ( ' • Gun.js peer connections (hi/bye events)' ) ;
@@ -142,6 +198,9 @@ async function startRelay(): Promise<void> {
142198 hasData : ! ! data ,
143199 dataKeys : data ? Object . keys ( data ) . filter ( k => k !== '_' ) : [ ]
144200 } ) ;
201+
202+ // Store data for re-broadcasting
203+ storeData ( 'dig-nat-tools' , key , data ) ;
145204 }
146205 } ) ;
147206
@@ -154,6 +213,9 @@ async function startRelay(): Promise<void> {
154213 hasData : ! ! data ,
155214 dataKeys : data ? Object . keys ( data ) . filter ( k => k !== '_' ) : [ ]
156215 } ) ;
216+
217+ // Store data for re-broadcasting
218+ storeData ( 'dig-nat-tools-test' , key , data ) ;
157219 }
158220 } ) ;
159221
@@ -192,6 +254,14 @@ async function startRelay(): Promise<void> {
192254
193255 console . log ( '✅ Gun.js database initialized with comprehensive logging' ) ;
194256
257+ // Start re-broadcasting interval
258+ console . log ( '🔄 Starting re-broadcast interval (every 5 seconds)...' ) ;
259+ rebroadcastInterval = setInterval ( ( ) => {
260+ rebroadcastStoredData ( gun ) ;
261+ } , 5000 ) ; // Re-broadcast every 5 seconds
262+
263+ console . log ( '✅ Re-broadcast interval started' ) ;
264+
195265 // Handle server errors
196266 server . on ( 'error' , ( error ) => {
197267 console . error ( '❌ Server error:' , error ) ;
0 commit comments