Skip to content

Commit 3873692

Browse files
committed
fix(react-hooks): throttle useSession cursor updates and restart on io change
1 parent ddc3d53 commit 3873692

1 file changed

Lines changed: 18 additions & 3 deletions

File tree

packages/react-hooks/src/hooks/useSession.ts

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ export function useSession<TRecord = unknown>(
275275
return () => {
276276
stop();
277277
};
278-
}, [sessionIdOrExternalId, stop, options?.enabled, requestSubscription]);
278+
}, [sessionIdOrExternalId, io, stop, options?.enabled, requestSubscription]);
279279

280280
return { records: records ?? initialRecordsFallback, lastEventId, lastControl, error, stop };
281281
}
@@ -296,13 +296,25 @@ async function processSessionStream<TRecord>(
296296
lastEventId?: string,
297297
throttleInMs?: number
298298
) {
299+
// Published with the throttled record flush, so consumers re-render once per
300+
// batch instead of once per record.
301+
let lastSeenEventId: string | undefined;
302+
let publishedEventId: string | undefined;
303+
304+
const publishLastEventId = () => {
305+
if (lastSeenEventId !== publishedEventId) {
306+
publishedEventId = lastSeenEventId;
307+
setLastEventId(lastSeenEventId);
308+
}
309+
};
310+
299311
try {
300312
const stream = await apiClient.subscribeToSessionStream<TRecord>(sessionIdOrExternalId, io, {
301313
signal: abortControllerRef.current?.signal,
302314
timeoutInSeconds,
303315
lastEventId,
304316
onPart: (part) => {
305-
setLastEventId(part.id);
317+
lastSeenEventId = part.id;
306318
onRecord(part);
307319
},
308320
onControl: (event) => {
@@ -314,14 +326,17 @@ async function processSessionStream<TRecord>(
314326
// Throttle the records
315327
const recordsQueue = createThrottledQueue<TRecord>(async (newRecords) => {
316328
mutateRecordsData([...existingRecordsRef.current, ...newRecords]);
329+
publishLastEventId();
317330
}, throttleInMs);
318331

319332
for await (const record of stream) {
320333
recordsQueue.add(record);
321334
}
322335

323-
// The last batch can be smaller than the throttle window, so flush it.
336+
// The last batch can be smaller than the throttle window, so flush it. The
337+
// cursor is published even when that batch is empty (control records only).
324338
await recordsQueue.flush();
339+
publishLastEventId();
325340
} catch (err) {
326341
if ((err as any).name === "AbortError") {
327342
return;

0 commit comments

Comments
 (0)