Seed event cache from feed items so useEvent resolves instantly

This commit is contained in:
Alex Gleason
2026-02-21 14:20:53 -06:00
parent cd2bceb805
commit 13fc22fae4
2 changed files with 19 additions and 9 deletions
+4 -5
View File
@@ -52,19 +52,18 @@ export function useEvent(eventId: string | undefined, relays?: string[], authorH
return useQuery<NostrEvent | null>({
queryKey: ['event', eventId ?? ''],
queryFn: async ({ signal }) => {
queryFn: async () => {
if (!eventId) return null;
const querySignal = AbortSignal.any([signal, AbortSignal.timeout(5000)]);
const filter: NostrFilter[] = [{ ids: [eventId], limit: 1 }];
// 1. Query the user's configured relays first
const events = await nostr.query(filter, { signal: querySignal });
const events = await nostr.query(filter, { signal: AbortSignal.timeout(1000) });
if (events.length > 0) return events[0];
// 2. If not found and we have relay hints, try those relays directly
if (relays && relays.length > 0) {
try {
const hintSignal = AbortSignal.any([signal, AbortSignal.timeout(5000)]);
const hintSignal = AbortSignal.timeout(1000);
const hintEvents = await nostr.group(relays).query(filter, { signal: hintSignal });
if (hintEvents.length > 0) return hintEvents[0];
} catch {
@@ -75,7 +74,7 @@ export function useEvent(eventId: string | undefined, relays?: string[], authorH
// 3. Last resort: if we have the author's pubkey, fetch their NIP-65 relay
// list and try their write relays (where they publish content)
if (authorHint) {
const found = await queryAuthorRelays(nostr, authorHint, filter, signal);
const found = await queryAuthorRelays(nostr, authorHint, filter, AbortSignal.timeout(1000));
if (found) return found;
}
+15 -4
View File
@@ -133,6 +133,15 @@ export function useFeed(tab: 'follows' | 'global' | 'communities') {
return [...pubkeys];
}
/** Seed the `['event', id]` query cache with events we already have in hand. */
function cacheEvents(items: FeedItem[]): void {
for (const { event } of items) {
if (!queryClient.getQueryData(['event', event.id])) {
queryClient.setQueryData(['event', event.id], event);
}
}
}
/**
* Fetch kind 0 metadata for the given pubkeys and seed each into the
* individual `['author', pubkey]` query cache so that subsequent
@@ -286,8 +295,8 @@ export function useFeed(tab: 'follows' | 'global' | 'communities') {
const dedupedItems = Array.from(seen.values()).sort((a, b) => b.sortTimestamp - a.sortTimestamp);
// Cache kind 0 for any remaining authors and mentioned pubkeys
// not already covered by the NIP-05 metadata fetch above.
// Seed event and author caches so downstream hooks resolve instantly.
cacheEvents(dedupedItems);
await fetchAndCacheAuthors(collectPubkeys(dedupedItems));
return { items: dedupedItems, oldestQueryTimestamp };
@@ -368,7 +377,8 @@ export function useFeed(tab: 'follows' | 'global' | 'communities') {
const dedupedItems = Array.from(seen.values()).sort((a, b) => b.sortTimestamp - a.sortTimestamp);
// Fetch and cache kind 0 profiles for all authors and mentioned pubkeys
// Seed event and author caches so downstream hooks resolve instantly.
cacheEvents(dedupedItems);
await fetchAndCacheAuthors(collectPubkeys(dedupedItems));
return { items: dedupedItems, oldestQueryTimestamp };
@@ -397,7 +407,8 @@ export function useFeed(tab: 'follows' | 'global' | 'communities') {
.sort((a, b) => b.created_at - a.created_at)
.map((ev) => ({ event: ev, sortTimestamp: ev.created_at }));
// Fetch and cache kind 0 profiles for all authors and mentioned pubkeys
// Seed event and author caches so downstream hooks resolve instantly.
cacheEvents(items);
await fetchAndCacheAuthors(collectPubkeys(items));
return { items, oldestQueryTimestamp };