fix(nostr-client): restore subscriptions and availability on relay reconnect
When a relay reconnects after a disconnect, all active subscriptions (including Lightning.Pub RPC listener) are now re-established on the new relay instance. Previously subscriptions were lost permanently. Also publishes availability broadcast immediately on reconnect instead of waiting up to 5 minutes for the next heartbeat. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
ea72623cde
commit
b6521c4788
2 changed files with 41 additions and 0 deletions
|
|
@ -116,6 +116,12 @@ export function useAvailabilityBroadcast(options: UseAvailabilityBroadcastOption
|
|||
// Publish immediately on setup
|
||||
publish(computeSnapshot())
|
||||
|
||||
// Re-publish immediately when relay reconnects (don't wait for next heartbeat)
|
||||
nostrClient.on('connect', () => {
|
||||
console.log('[Availability] Relay reconnected, publishing immediately')
|
||||
publish(computeSnapshot())
|
||||
})
|
||||
|
||||
function stop() {
|
||||
clearInterval(heartbeatInterval)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ export class NostrClient {
|
|||
}
|
||||
}
|
||||
|
||||
// Re-establish all active subscriptions on the new relay connection
|
||||
this.resubscribeOnRelay(connection)
|
||||
|
||||
this.emitEvent('connect', { relay: url })
|
||||
} catch (error) {
|
||||
connection.state = 'error'
|
||||
|
|
@ -175,6 +178,38 @@ export class NostrClient {
|
|||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-establish all active subscriptions on a reconnected relay.
|
||||
* When a relay drops and reconnects, the old Relay instance is gone —
|
||||
* subscriptions need to be recreated on the new instance.
|
||||
*/
|
||||
private resubscribeOnRelay(connection: RelayConnection): void {
|
||||
if (!connection.relay) return
|
||||
|
||||
for (const [id, sub] of this.subscriptions) {
|
||||
try {
|
||||
const relaySub = connection.relay.subscribe(sub.filters, {
|
||||
onevent: (event: Event) => {
|
||||
sub.options.onEvent(event)
|
||||
this.emitEvent('event', { relay: connection.config.url, event })
|
||||
},
|
||||
oneose: () => {
|
||||
sub.options.onEose?.()
|
||||
},
|
||||
})
|
||||
// Append to the existing close chain so unsubscribe() cleans up both
|
||||
const prevClose = sub.close
|
||||
sub.close = () => {
|
||||
prevClose()
|
||||
relaySub.close()
|
||||
}
|
||||
console.log(`[Nostr] Restored subscription ${id} on ${connection.config.url}`)
|
||||
} catch (e) {
|
||||
console.warn(`[Nostr] Failed to restore subscription ${id} on ${connection.config.url}:`, e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule a reconnection attempt
|
||||
*/
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue