From e7c05b2c52a6284cfc20e093116c263a1ca85c60 Mon Sep 17 00:00:00 2001 From: Gigi Date: Thu, 9 Oct 2025 14:08:37 +0100 Subject: [PATCH] feat: keep local relay connections alive in flight mode - Add persistent keep-alive subscription for local relays - Prevents disconnection when no other subscriptions are active - Uses minimal subscription (kinds: [0], limit: 0) to keep connection open - Properly cleans up subscription on app unmount - Resolves issue where local relays disconnect after idle period in flight mode --- src/App.tsx | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/App.tsx b/src/App.tsx index cc0927d9..1ed71949 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -118,6 +118,22 @@ function App() { console.log('Created relay group with', RELAYS.length, 'relays (including local)') console.log('Relay URLs:', RELAYS) + // Keep local relay connections alive indefinitely by creating a persistent subscription + // This prevents disconnection in flight mode when no other subscriptions are active + const localRelays = RELAYS.filter(url => url.includes('localhost') || url.includes('127.0.0.1')) + if (localRelays.length > 0) { + // Create a minimal subscription that never completes to keep connections alive + const keepAliveSub = pool.subscription(localRelays, { kinds: [0], limit: 0 }).subscribe({ + next: () => {}, // No-op, we don't care about events + error: (err) => console.warn('Keep-alive subscription error:', err) + }) + console.log('🔗 Created keep-alive subscription for', localRelays.length, 'local relay(s)') + + // Store subscription for cleanup + // eslint-disable-next-line @typescript-eslint/no-explicit-any + ;(pool as any)._keepAliveSubscription = keepAliveSub + } + // Attach address/replaceable loaders so ProfileModel can fetch profiles const addressLoader = createAddressLoader(pool, { eventStore: store, @@ -134,6 +150,12 @@ function App() { return () => { accountsSub.unsubscribe() activeSub.unsubscribe() + // Clean up keep-alive subscription if it exists + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if ((pool as any)._keepAliveSubscription) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (pool as any)._keepAliveSubscription.unsubscribe() + } } }