@@ -2,7 +2,7 @@ import * as commonSdk from '@powersync/common';
2
2
import { PowerSyncDatabase } from '@powersync/web' ;
3
3
import flushPromises from 'flush-promises' ;
4
4
import { describe , expect , it , onTestFinished , vi } from 'vitest' ;
5
- import { isProxy , isRef , ref } from 'vue' ;
5
+ import { computed , isProxy , isRef , ref , watchEffect } from 'vue' ;
6
6
import { createPowerSyncPlugin } from '../src/composables/powerSync' ;
7
7
import { useQuery } from '../src/composables/useQuery' ;
8
8
import { useWatchedQuerySubscription } from '../src/composables/useWatchedQuerySubscription' ;
@@ -233,4 +233,94 @@ describe('useQuery', () => {
233
233
'PowerSync failed to fetch data: You cannot pass parameters to a compiled query.'
234
234
) ;
235
235
} ) ;
236
+
237
+ it ( 'should handle dependent query parameter changes with correct state transitions' , async ( ) => {
238
+ const db = openPowerSync ( ) ;
239
+
240
+ await db . execute ( /* sql */ `
241
+ INSERT INTO
242
+ lists (id, name)
243
+ VALUES
244
+ (uuid (), 'item1')
245
+ ` ) ;
246
+
247
+ // Track state transitions
248
+ const stateTransitions : Array < {
249
+ param : string | number ;
250
+ dataLength : number ;
251
+ isFetching : boolean ;
252
+ isLoading : boolean ;
253
+ } > = [ ] ;
254
+
255
+ const [ state ] = withPowerSyncSetup ( ( ) => {
256
+ // First query that provides the parameter - starts with 0, then returns 1
257
+ const paramQuery = useQuery ( 'SELECT 1 as result;' , [ ] ) ;
258
+ const param = computed ( ( ) => paramQuery . data . value ?. [ 0 ] ?. result ?? 0 ) ;
259
+
260
+ // Second query that depends on the first query's result
261
+ const dataQuery = useQuery (
262
+ computed ( ( ) => 'SELECT * FROM lists LIMIT ?' ) ,
263
+ computed ( ( ) => [ param . value ] )
264
+ ) ;
265
+
266
+ // Track state changes
267
+ watchEffect ( ( ) => {
268
+ const currentState = {
269
+ param : param . value ,
270
+ dataLength : dataQuery . data . value ?. length || 0 ,
271
+ isFetching : dataQuery . isFetching . value ,
272
+ isLoading : dataQuery . isLoading . value
273
+ } ;
274
+ stateTransitions . push ( currentState ) ;
275
+ } ) ;
276
+
277
+ return {
278
+ paramData : paramQuery . data ,
279
+ data : dataQuery . data ,
280
+ isFetching : dataQuery . isFetching ,
281
+ isLoading : dataQuery . isLoading ,
282
+ param
283
+ } ;
284
+ } ) ;
285
+
286
+ // Wait for final state
287
+ await vi . waitFor (
288
+ ( ) => {
289
+ expect ( state . isLoading . value ) . toEqual ( false ) ;
290
+ expect ( state . isFetching . value ) . toEqual ( false ) ;
291
+ expect ( state . data . value ?. length ) . toEqual ( 1 ) ;
292
+ expect ( state . paramData . value [ 0 ] . result ) . toEqual ( 1 ) ;
293
+ } ,
294
+ { timeout : 1000 }
295
+ ) ;
296
+
297
+ // Find the index where param changes from 0 to 1
298
+ let beforeParamChangeIndex = 0 ;
299
+ for ( const transition of stateTransitions ) {
300
+ if ( transition . param === 1 ) {
301
+ beforeParamChangeIndex = stateTransitions . indexOf ( transition ) - 1 ;
302
+ break ;
303
+ }
304
+ }
305
+ const initialState = stateTransitions [ beforeParamChangeIndex ] ;
306
+ expect ( initialState ) . toBeDefined ( ) ;
307
+ expect ( initialState ?. param ) . toEqual ( 0 ) ;
308
+ expect ( initialState ?. dataLength ) . toEqual ( 0 ) ;
309
+ expect ( initialState ?. isFetching ) . toEqual ( true ) ;
310
+ expect ( initialState ?. isLoading ) . toEqual ( true ) ;
311
+
312
+ const paramChangedState = stateTransitions [ beforeParamChangeIndex + 1 ] ;
313
+ expect ( paramChangedState ) . toBeDefined ( ) ;
314
+ expect ( paramChangedState ?. param ) . toEqual ( 1 ) ;
315
+ expect ( paramChangedState ?. dataLength ) . toEqual ( 0 ) ;
316
+ expect ( paramChangedState ?. isFetching ) . toEqual ( true ) ;
317
+ expect ( paramChangedState ?. isLoading ) . toEqual ( true ) ;
318
+
319
+ const finalState = stateTransitions [ beforeParamChangeIndex + 2 ] ;
320
+ expect ( finalState ) . toBeDefined ( ) ;
321
+ expect ( finalState . param ) . toEqual ( 1 ) ;
322
+ expect ( finalState . dataLength ) . toEqual ( 1 ) ;
323
+ expect ( finalState . isFetching ) . toEqual ( false ) ;
324
+ expect ( finalState . isLoading ) . toEqual ( false ) ;
325
+ } ) ;
236
326
} ) ;
0 commit comments