From 16889a9e30ac4dfb536934d456dbac797b3e39f0 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 22 Dec 2025 22:24:39 +0000 Subject: [PATCH] refactor: auto-generate subscription ID in useReqTimelineEnhanced Remove the manual `id` parameter from useReqTimelineEnhanced and generate it automatically from the filter, relays, and stream option. This prevents bugs where the ID doesn't match the actual query parameters. Benefits: - Simpler API - one less parameter to pass - Impossible to create ID/filter mismatches - ID always perfectly reflects what's being queried - More maintainable and less error-prone The subscription ID is now generated as: `req-${JSON.stringify(filters)}-${relays.join(",")}-${stream}` This ensures the subscription re-triggers when any of these values change, which is exactly when we want to re-subscribe. Updated call site in ReqViewer.tsx to use the new API. --- src/components/ReqViewer.tsx | 10 ++++------ src/hooks/useReqTimelineEnhanced.ts | 11 ++++++++--- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/components/ReqViewer.tsx b/src/components/ReqViewer.tsx index 2b5d6d2..21de869 100644 --- a/src/components/ReqViewer.tsx +++ b/src/components/ReqViewer.tsx @@ -760,12 +760,10 @@ export default function ReqViewer({ eoseReceived, relayStates: reqRelayStates, overallState, - } = useReqTimelineEnhanced( - `req-${JSON.stringify(resolvedFilter)}-${closeOnEose}`, - resolvedFilter, - normalizedRelays, - { limit: resolvedFilter.limit || 50, stream }, - ); + } = useReqTimelineEnhanced(resolvedFilter, normalizedRelays, { + limit: resolvedFilter.limit || 50, + stream, + }); const [showQuery, setShowQuery] = useState(false); const [showExportDialog, setShowExportDialog] = useState(false); diff --git a/src/hooks/useReqTimelineEnhanced.ts b/src/hooks/useReqTimelineEnhanced.ts index 9da1414..c266419 100644 --- a/src/hooks/useReqTimelineEnhanced.ts +++ b/src/hooks/useReqTimelineEnhanced.ts @@ -36,14 +36,13 @@ interface UseReqTimelineEnhancedReturn { * - Syncs connection state from RelayStateManager * - Tracks events per relay via event._relay metadata * - Derives overall state from individual relay states + * - Generates subscription ID automatically from filters, relays, and options * - * @param id - Unique identifier for this timeline (for caching) * @param filters - Nostr filter(s) * @param relays - Array of relay URLs * @param options - Stream mode, limit, etc. */ export function useReqTimelineEnhanced( - id: string, filters: Filter | Filter[], relays: string[], options: UseReqTimelineEnhancedOptions = { limit: 50 }, @@ -85,6 +84,12 @@ export function useReqTimelineEnhanced( const stableFilters = useStableValue(filters); const stableRelays = useStableArray(relays); + // Generate stable subscription ID from parameters + // This ensures re-subscription when filters, relays, or stream mode changes + const subscriptionId = useMemo(() => { + return `req-${JSON.stringify(stableFilters)}-${stableRelays.join(",")}-${stream}`; + }, [stableFilters, stableRelays, stream]); + // Initialize relay states when relays change useEffect(() => { queryStartedAt.current = Date.now(); @@ -317,7 +322,7 @@ export function useReqTimelineEnhanced( return () => { subscriptions.forEach((sub) => sub.unsubscribe()); }; - }, [id, stableFilters, stableRelays, limit, stream, eventStore]); + }, [subscriptionId, limit, eventStore]); // Derive overall state from individual relay states const overallState = useMemo(() => {