From 400e60107fd71fd7f7d90f3e8aec54abb7c7816d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20G=C3=B3mez?= Date: Tue, 17 Mar 2026 10:25:25 +0100 Subject: [PATCH] fix: don't transition away from eose state --- src/hooks/useReqTimelineEnhanced.ts | 3 +- src/lib/req-state-machine.test.ts | 48 +++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/src/hooks/useReqTimelineEnhanced.ts b/src/hooks/useReqTimelineEnhanced.ts index cda3c4e..dec9321 100644 --- a/src/hooks/useReqTimelineEnhanced.ts +++ b/src/hooks/useReqTimelineEnhanced.ts @@ -271,7 +271,8 @@ export function useReqTimelineEnhanced( // Update existing relay state next.set(url, { ...state, - subscriptionState: "receiving", + subscriptionState: + state.subscriptionState === "eose" ? "eose" : "receiving", eventCount: state.eventCount + 1, firstEventAt: state.firstEventAt ?? now, lastEventAt: now, diff --git a/src/lib/req-state-machine.test.ts b/src/lib/req-state-machine.test.ts index cbe13c9..00fa7b8 100644 --- a/src/lib/req-state-machine.test.ts +++ b/src/lib/req-state-machine.test.ts @@ -503,6 +503,54 @@ describe("deriveOverallState", () => { expect(state.eoseCount).toBe(1); }); + it("should return live when all relays at eose with post-EOSE streaming events", () => { + const now = Date.now(); + const relays = new Map([ + [ + "wss://relay1.com", + { + url: "wss://relay1.com", + connectionState: "connected", + subscriptionState: "eose", + eventCount: 42, + eoseAt: now - 5000, + firstEventAt: now - 10000, + lastEventAt: now - 100, + }, + ], + [ + "wss://relay2.com", + { + url: "wss://relay2.com", + connectionState: "connected", + subscriptionState: "eose", + eventCount: 28, + eoseAt: now - 3000, + firstEventAt: now - 8000, + lastEventAt: now - 200, + }, + ], + [ + "wss://relay3.com", + { + url: "wss://relay3.com", + connectionState: "connected", + subscriptionState: "eose", + eventCount: 15, + eoseAt: now - 2000, + firstEventAt: now - 6000, + lastEventAt: now - 500, + }, + ], + ]); + const state = deriveOverallState(relays, true, true, queryStartedAt); + expect(state.status).toBe("live"); + expect(state.eoseCount).toBe(3); + expect(state.connectedCount).toBe(3); + expect(state.hasActiveRelays).toBe(true); + expect(state.hasReceivedEvents).toBe(true); + }); + it("NEW: Mix of EOSE and errors, all terminal", () => { const relays = new Map([ [