From ab59e3b2444a5a369a6b3ca4bf6421bf919fd3ac Mon Sep 17 00:00:00 2001 From: Silberengel Date: Mon, 6 Oct 2025 21:30:35 +0200 Subject: [PATCH] tried to expand fetching --- src/components/Embedded/EmbeddedNote.tsx | 33 ++++++++++++++-- src/constants.ts | 11 +++--- src/services/client.service.ts | 48 +++++++++++++++++++++++- 3 files changed, 83 insertions(+), 9 deletions(-) diff --git a/src/components/Embedded/EmbeddedNote.tsx b/src/components/Embedded/EmbeddedNote.tsx index a2b9576..d80090e 100644 --- a/src/components/Embedded/EmbeddedNote.tsx +++ b/src/components/Embedded/EmbeddedNote.tsx @@ -1,25 +1,52 @@ import { Skeleton } from '@/components/ui/skeleton' import { useFetchEvent } from '@/hooks' import { cn } from '@/lib/utils' +import client from '@/services/client.service' import { useTranslation } from 'react-i18next' +import { useEffect, useState } from 'react' +import { Event } from 'nostr-tools' import ClientSelect from '../ClientSelect' import MainNoteCard from '../NoteCard/MainNoteCard' export function EmbeddedNote({ noteId, className }: { noteId: string; className?: string }) { const { event, isFetching } = useFetchEvent(noteId) + const [retryEvent, setRetryEvent] = useState(undefined) + const [isRetrying, setIsRetrying] = useState(false) - if (isFetching) { + // If the first fetch fails, try a force retry with the four-tier system + useEffect(() => { + if (!isFetching && !event && !isRetrying) { + setIsRetrying(true) + client.fetchEventForceRetry(noteId) + .then((retryResult) => { + if (retryResult) { + setRetryEvent(retryResult) + } + }) + .catch((error) => { + console.warn('Force retry failed for event:', noteId, error) + }) + .finally(() => { + setIsRetrying(false) + }) + } + }, [isFetching, event, noteId, isRetrying]) + + const finalEvent = event || retryEvent + const finalIsFetching = isFetching || isRetrying + + if (finalIsFetching) { return } - if (!event) { + if (!finalEvent) { return } return ( diff --git a/src/constants.ts b/src/constants.ts index 6698963..1cce013 100644 --- a/src/constants.ts +++ b/src/constants.ts @@ -65,8 +65,7 @@ export const BIG_RELAY_URLS = [ 'wss://nostr.land', 'wss://nostr.wine/', 'wss://nostr.sovbit.host/', - 'wss://nostr21.com', - 'wss://thecitadel.nostr1.com/' + 'wss://nostr21.com' ] // Optimized relay list for read operations (includes aggregator) @@ -79,10 +78,12 @@ export const FAST_READ_RELAY_URLS = [ // Optimized relay list for write operations (no aggregator since it's read-only) export const FAST_WRITE_RELAY_URLS = [ - 'wss://damus.io/', - 'wss://primal.net/', + 'wss://relay.damus.io/', + 'wss://relay.primal.net/', 'wss://freelay.sovbit.host/', - 'wss://thecitadel.nostr1.com/' + 'wss://thecitadel.nostr1.com/', + 'wss://nos.lol/', + 'wss://nostr.mom' ] export const SEARCHABLE_RELAY_URLS = [ diff --git a/src/services/client.service.ts b/src/services/client.service.ts index 53a7056..42fe356 100644 --- a/src/services/client.service.ts +++ b/src/services/client.service.ts @@ -896,6 +896,26 @@ class ClientService extends EventTarget { return this.eventDataLoader.load(id) } + // Force retry fetching an event by clearing its cache + async fetchEventForceRetry(id: string): Promise { + // Clear the cache for this specific event + this.eventCacheMap.delete(id) + + // Also clear from replaceable event cache if it's a replaceable event + if (!/^[0-9a-f]{64}$/.test(id)) { + const { type, data } = nip19.decode(id) + if (type === 'naddr') { + const coordinate = getReplaceableCoordinate(data.kind, data.pubkey, data.identifier) + if (coordinate) { + this.replaceableEventCacheMap.delete(coordinate) + } + } + } + + // Now fetch with a fresh attempt + return this._fetchEvent(id) + } + async fetchTrendingNotes() { if (this.trendingNotesCache) { return this.trendingNotesCache @@ -941,12 +961,38 @@ class ClientService extends EventTarget { } private async fetchEventById(relayUrls: string[], id: string): Promise { + // First try the big relays const event = await this.fetchEventFromBigRelaysDataloader.load(id) if (event) { return event } - return this.tryHarderToFetchEvent(relayUrls, { ids: [id], limit: 1 }, true) + // Then try the relays where this event was originally seen + const seenOnRelays = this.getSeenEventRelayUrls(id) + if (seenOnRelays.length > 0) { + const seenOnEvent = await this.tryHarderToFetchEvent(seenOnRelays, { ids: [id], limit: 1 }, true) + if (seenOnEvent) { + return seenOnEvent + } + } + + // Third, try the provided relay URLs + if (relayUrls.length > 0) { + const providedEvent = await this.tryHarderToFetchEvent(relayUrls, { ids: [id], limit: 1 }, true) + if (providedEvent) { + return providedEvent + } + } + + // Finally, try all available relays as a last resort + const allAvailableRelays = Array.from(new Set([ + ...FAST_READ_RELAY_URLS, + ...FAST_WRITE_RELAY_URLS, + ...seenOnRelays, + ...relayUrls + ])) + + return this.tryHarderToFetchEvent(allAvailableRelays, { ids: [id], limit: 1 }, true) } private async _fetchEvent(id: string): Promise {