Prevent individual queries from racing with batch queries
useAuthor and useEventStats were firing individual queries simultaneously with the batch hooks (useAuthors, useBatchEventStats), causing a flood of concurrent relay subscriptions. Each NoteCard's useAuthor created its own kind:0 query even though useAuthors in Feed.tsx was about to fetch the same data in a single batched query. Fix: Use useIsFetching to detect when a batch query is in-flight and disable individual queries until the batch completes. The batch seeds individual cache entries, so useAuthor/useEventStats resolve instantly from cache without ever firing their own relay queries. On pages without batch queries (PostDetailPage, NotificationsPage, etc.), batchFetching === 0 immediately, so individual hooks fire normally. Co-authored-by: shakespeare.diy <assistant@shakespeare.diy>
This commit is contained in:
@@ -1,10 +1,14 @@
|
||||
import { type NostrEvent, type NostrMetadata, NSchema as n } from '@nostrify/nostrify';
|
||||
import { useNostr } from '@nostrify/react';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { useQuery, useIsFetching } from '@tanstack/react-query';
|
||||
|
||||
export function useAuthor(pubkey: string | undefined) {
|
||||
const { nostr } = useNostr();
|
||||
|
||||
// If a batch author query (useAuthors) is currently in-flight, wait for
|
||||
// it to finish and seed our cache instead of firing an individual query.
|
||||
const batchFetching = useIsFetching({ queryKey: ['authors'] });
|
||||
|
||||
return useQuery<{ event?: NostrEvent; metadata?: NostrMetadata }>({
|
||||
queryKey: ['author', pubkey ?? ''],
|
||||
queryFn: async ({ signal }) => {
|
||||
@@ -30,5 +34,8 @@ export function useAuthor(pubkey: string | undefined) {
|
||||
},
|
||||
staleTime: 5 * 60 * 1000, // Keep cached data fresh for 5 minutes
|
||||
retry: 1,
|
||||
// Don't fire this individual query while a batch is in progress —
|
||||
// the batch will seed our cache entry when it completes.
|
||||
enabled: !!pubkey && batchFetching === 0,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { useNostr } from '@nostrify/react';
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { useQuery, useQueryClient, useIsFetching } from '@tanstack/react-query';
|
||||
import type { NostrEvent } from '@nostrify/nostrify';
|
||||
|
||||
export interface TrendingTag {
|
||||
@@ -181,6 +181,10 @@ function computeStats(eventId: string, events: NostrEvent[]): EventStats {
|
||||
export function useEventStats(eventId: string | undefined) {
|
||||
const { nostr } = useNostr();
|
||||
|
||||
// If a batch stats query (useBatchEventStats) is currently in-flight, wait
|
||||
// for it to finish and seed our cache instead of firing an individual query.
|
||||
const batchFetching = useIsFetching({ queryKey: ['batch-event-stats'] });
|
||||
|
||||
return useQuery({
|
||||
queryKey: ['event-stats', eventId ?? ''],
|
||||
queryFn: async ({ signal }) => {
|
||||
@@ -199,7 +203,7 @@ export function useEventStats(eventId: string | undefined) {
|
||||
|
||||
return computeStats(eventId, events);
|
||||
},
|
||||
enabled: !!eventId,
|
||||
enabled: !!eventId && batchFetching === 0,
|
||||
staleTime: 60 * 1000,
|
||||
placeholderData: (prev) => prev,
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user