@@ -93,6 +93,35 @@ describe('stream hooks', () => {
9393 await waitFor ( ( ) => expect ( result . current . data ) . toHaveLength ( 1 ) , { timeout : 1000 , interval : 100 } ) ;
9494 } ) ;
9595
96+ it ( 'useQuery returns complete result shape during stream sync transition' , async ( ) => {
97+ const allResults : any [ ] = [ ] ;
98+
99+ const { result } = renderHook (
100+ ( ) => {
101+ const queryResult = useQuery ( 'SELECT 1' , [ ] , { streams : [ { name : 'a' , waitForStream : true } ] } ) ;
102+ allResults . push ( { ...queryResult } ) ;
103+ return queryResult ;
104+ } ,
105+ { wrapper : testWrapper }
106+ ) ;
107+
108+ // Initial state should be loading
109+ expect ( result . current ) . toMatchObject ( { isLoading : true } ) ;
110+ await waitFor ( ( ) => expect ( currentStreams ( ) ) . toHaveLength ( 1 ) , { timeout : 1000 , interval : 100 } ) ;
111+
112+ // Trigger sync — this causes streamsHaveSynced to transition to true
113+ db . currentStatus = _testStatus ;
114+ db . iterateListeners ( ( l ) => l . statusChanged ?.( _testStatus ) ) ;
115+
116+ // Wait for the query to eventually resolve
117+ await waitFor ( ( ) => expect ( result . current . data ) . toHaveLength ( 1 ) , { timeout : 1000 , interval : 100 } ) ;
118+
119+ // Every intermediate render result should have the complete shape
120+ for ( const r of allResults ) {
121+ expect ( r ) . toMatchObject ( { data : expect . any ( Array ) , isLoading : expect . any ( Boolean ) , isFetching : expect . any ( Boolean ) } ) ;
122+ }
123+ } ) ;
124+
96125 it ( 'useQuery not waiting on stream' , async ( ) => {
97126 // By default, it should still run the query immediately instead of waiting for the stream to resolve.
98127 const { result } = renderHook ( ( ) => useQuery ( 'SELECT 1' , [ ] , { streams : [ { name : 'a' } ] } ) , {
@@ -177,3 +206,4 @@ const _testStatus = new SyncStatus({
177206 ]
178207 }
179208} ) ;
209+
0 commit comments