@@ -681,19 +681,20 @@ function elapse(ms: number): Promise<unknown> {
681681 return vi . isFakeTimers ( ) ? vi . advanceTimersByTimeAsync ( ms ) : sleep ( ms )
682682}
683683
684+ /** Far under one read per fake millisecond, and room for the odd unrelated read. */
685+ const MAX_IDLE_CHAT_READS = 50
686+
684687/**
685- * How many zero-delay timers run while `ms` passes on the fake clock. Delivery
686- * waking on a delay that is already over runs back to back, a pass per tick, so a
687- * surface with nothing due must schedule none .
688+ * How many times the surface reads the cached chat while `ms` passes on the fake
689+ * clock. Every delivery pass reads it, so delivery waking on a delay already over
690+ * shows as a read per tick, where a surface with nothing due reads next to nothing .
688691 */
689- async function zeroDelayTimersDuring ( ms : number ) : Promise < number > {
690- const schedule = vi . spyOn ( globalThis , 'setTimeout ' )
692+ async function chatReadsDuring ( ms : number ) : Promise < number > {
693+ const read = vi . spyOn ( queryClient , 'getQueryData ' )
691694 await act ( async ( ) => {
692695 await vi . advanceTimersByTimeAsync ( ms )
693696 } )
694- const count = schedule . mock . calls . filter ( ( [ , delay ] ) => ! delay ) . length
695- schedule . mockRestore ( )
696- return count
697+ return read . mock . calls . length
697698}
698699
699700/** Lets everything already due run: answered requests, their handlers, what those schedule. */
@@ -2595,7 +2596,7 @@ describe('useChat remount send recovery', () => {
25952596 expect ( message ?. delivery ) . toBe ( 'failed' )
25962597 const attempts = state . postBodies . length
25972598
2598- expect ( await zeroDelayTimersDuring ( 5_000 ) ) . toBe ( 0 )
2599+ expect ( await chatReadsDuring ( 5_000 ) ) . toBeLessThan ( MAX_IDLE_CHAT_READS )
25992600 expect ( state . postBodies ) . toHaveLength ( attempts )
26002601 } finally {
26012602 vi . useRealTimers ( )
@@ -2618,11 +2619,13 @@ describe('useChat remount send recovery', () => {
26182619
26192620 /* Another tab's turn shows up in the chat before this message's retry delay ends. */
26202621 const fetchUnreachable = globalThis . fetch
2621- vi . stubGlobal ( 'fetch' , async ( input : RequestInfo | URL , init ?: RequestInit ) =>
2622- String ( input ) . includes ( '/api/mothership/chat/stream' )
2623- ? Response . json ( { success : true , events : [ ] , status : 'active' } )
2624- : fetchUnreachable ( input , init )
2625- )
2622+ vi . stubGlobal ( 'fetch' , async ( input : RequestInfo | URL , init ?: RequestInit ) => {
2623+ if ( ! String ( input ) . includes ( '/api/mothership/chat/stream' ) ) {
2624+ return fetchUnreachable ( input , init )
2625+ }
2626+ await sleep ( 50 )
2627+ return Response . json ( { success : true , events : [ ] , status : 'active' } )
2628+ } )
26262629 const running = { ...history , activeStreamId : 'run-in-another-tab' }
26272630 mockRequestJson . mockImplementation ( ( ) => Promise . resolve ( { chat : running } ) )
26282631 await act ( async ( ) => {
@@ -2632,8 +2635,9 @@ describe('useChat remount send recovery', () => {
26322635 expect ( view . getResult ( ) . isReconnecting || view . getResult ( ) . isSending ) . toBe ( true )
26332636
26342637 await act ( async ( ) => vi . advanceTimersByTimeAsync ( 5_000 ) )
2635- expect ( await zeroDelayTimersDuring ( 2_000 ) ) . toBe ( 0 )
2638+ expect ( await chatReadsDuring ( 2_000 ) ) . toBeLessThan ( MAX_IDLE_CHAT_READS )
26362639 expect ( state . postBodies ) . toHaveLength ( 1 )
2640+ view . unmount ( )
26372641 } finally {
26382642 vi . useRealTimers ( )
26392643 }
@@ -4686,7 +4690,7 @@ describe('useChat remount send recovery', () => {
46864690 await waitFor ( ( ) => state . steerBodies . length === 3 , 20_000 )
46874691 await act ( async ( ) => vi . advanceTimersByTimeAsync ( 10 ) )
46884692
4689- expect ( await zeroDelayTimersDuring ( 5_000 ) ) . toBe ( 0 )
4693+ expect ( await chatReadsDuring ( 5_000 ) ) . toBeLessThan ( MAX_IDLE_CHAT_READS )
46904694 expect ( state . postBodies ) . toHaveLength ( 1 )
46914695 } finally {
46924696 vi . useRealTimers ( )
0 commit comments