Skip to content

Commit a27e4ae

Browse files
acartineclaude
andcommitted
fix(beats): skip streaming progress UI on background refetches
When the query cache already has data, background refetches now silently swap results instead of re-triggering the progress bar, skeleton rows, and fade-in animations every 10 seconds. Streaming progress UI only activates on initial load (empty cache). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 2ee40fb commit a27e4ae

File tree

1 file changed

+29
-3
lines changed

1 file changed

+29
-3
lines changed

src/app/beats/use-beats-query.ts

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ export function useBeatsQuery(
104104
beatsView, signal, queryKey,
105105
setQueryData: (updater) =>
106106
queryClient.setQueryData(queryKey, updater),
107+
getQueryData: () =>
108+
queryClient.getQueryData<QueryData>(queryKey),
107109
onStreamStart: streaming.onStreamStart,
108110
onRepoLoaded: streaming.onRepoLoaded,
109111
onStreamComplete: streaming.onStreamComplete,
@@ -195,22 +197,24 @@ interface StreamingFetchArgs {
195197
signal: AbortSignal;
196198
queryKey: readonly unknown[];
197199
setQueryData: SetQueryData;
200+
getQueryData: () => QueryData | undefined;
198201
onStreamStart: (total: number) => void;
199202
onRepoLoaded: (repo: string) => void;
200203
onStreamComplete: () => void;
201204
}
202205

203206
/**
204207
* For `scope=all`, use NDJSON streaming to show per-repo
205-
* results incrementally. For other scopes, fall back to
206-
* the standard non-streaming fetch.
208+
* results incrementally on **initial load** (empty cache).
209+
* Background refetches with populated cache skip the
210+
* streaming UI and silently swap the final result.
207211
*/
208212
async function fetchBeatsWithStreaming(
209213
args: StreamingFetchArgs,
210214
): Promise<QueryData> {
211215
const {
212216
params, scope, registeredRepos,
213-
beatsView, signal, setQueryData,
217+
beatsView, signal, setQueryData, getQueryData,
214218
onStreamStart, onRepoLoaded, onStreamComplete,
215219
} = args;
216220

@@ -228,6 +232,28 @@ async function fetchBeatsWithStreaming(
228232
return result;
229233
}
230234

235+
/* Background refresh: cache already has data, so skip
236+
streaming progress UI to avoid the 10s flicker. */
237+
const cached = getQueryData();
238+
const isBackgroundRefresh =
239+
cached?.ok && (cached.data?.length ?? 0) > 0;
240+
241+
if (isBackgroundRefresh) {
242+
const result = await withClientPerfSpan(
243+
"query", "beats:list-stream",
244+
() => fetchBeatsForScopeStreaming(params, scope, {
245+
signal,
246+
onRepoChunk: () => { /* silent */ },
247+
}),
248+
() => ({
249+
meta: { beatsView, params, scope: scope.key },
250+
}),
251+
);
252+
throwIfDegraded(result);
253+
return result;
254+
}
255+
256+
/* Initial load: show per-repo progress. */
231257
onStreamStart(registeredRepos.length);
232258

233259
const result = await withClientPerfSpan(

0 commit comments

Comments
 (0)