@@ -54,10 +54,30 @@ const sampleUsers: Array<User> = [
54
54
55
55
// Mock the ShapeStream module
56
56
const mockSubscribe = vi . fn ( )
57
+ const mockRequestSnapshot = vi . fn ( )
57
58
const mockStream = {
58
59
subscribe : mockSubscribe ,
60
+ requestSnapshot : ( ...args : any ) => {
61
+ mockRequestSnapshot ( ...args )
62
+ const results = mockRequestSnapshot . mock . results
63
+ const lastResult = results [ results . length - 1 ] ! . value
64
+
65
+ const subscribers = mockSubscribe . mock . calls . map ( args => args [ 0 ] )
66
+ subscribers . forEach ( subscriber => subscriber ( lastResult . data . map ( ( row : any ) => ( {
67
+ type : `insert` ,
68
+ value : row . value ,
69
+ key : row . key ,
70
+ } ) ) ) )
71
+ }
59
72
}
60
73
74
+ // Mock the requestSnapshot method
75
+ // to return an empty array of data
76
+ // since most tests don't use it
77
+ mockRequestSnapshot . mockResolvedValue ( {
78
+ data : [ ]
79
+ } )
80
+
61
81
vi . mock ( `@electric-sql/client` , async ( ) => {
62
82
const actual = await vi . importActual ( `@electric-sql/client` )
63
83
return {
@@ -338,4 +358,99 @@ describe.each([
338
358
expect ( testElectricCollection . status ) . toBe ( `ready` )
339
359
expect ( liveQuery . status ) . toBe ( `ready` )
340
360
} )
361
+
362
+ if ( autoIndex === `eager` ) {
363
+ it . only ( `should load more data via requestSnapshot when creating live query with higher limit` , async ( ) => {
364
+ // Reset mocks
365
+ vi . clearAllMocks ( )
366
+ mockRequestSnapshot . mockResolvedValue ( {
367
+ data : [
368
+ { key :
5 , value :
{ id :
5 , name :
`Eve` , age :
30 , email :
`[email protected] ` , active :
true } } ,
369
+ { key :
6 , value :
{ id :
6 , name :
`Frank` , age :
35 , email :
`[email protected] ` , active :
true } } ,
370
+ ] ,
371
+ } )
372
+
373
+ // Initial sync with limited data
374
+ simulateInitialSync ( )
375
+ expect ( electricCollection . status ) . toBe ( `ready` )
376
+ expect ( electricCollection . size ) . toBe ( 4 )
377
+ expect ( mockRequestSnapshot ) . toHaveBeenCalledTimes ( 0 )
378
+
379
+ // Create first live query with limit of 2
380
+ const limitedLiveQuery = createLiveQueryCollection ( {
381
+ id : `limited-users-live-query` ,
382
+ startSync : true ,
383
+ query : ( q ) =>
384
+ q
385
+ . from ( { user : electricCollection } )
386
+ . where ( ( { user } ) => eq ( user . active , true ) )
387
+ . select ( ( { user } ) => ( {
388
+ id : user . id ,
389
+ name : user . name ,
390
+ active : user . active ,
391
+ age : user . age ,
392
+ } ) )
393
+ . orderBy ( ( { user } ) => user . age , `asc` )
394
+ . limit ( 2 ) ,
395
+ } )
396
+
397
+ expect ( limitedLiveQuery . status ) . toBe ( `ready` )
398
+ expect ( limitedLiveQuery . size ) . toBe ( 2 ) // Only first 2 active users
399
+ expect ( mockRequestSnapshot ) . toHaveBeenCalledTimes ( 1 )
400
+
401
+ const callArgs = ( index : number ) => mockRequestSnapshot . mock . calls [ index ] ?. [ 0 ]
402
+ expect ( callArgs ( 0 ) ) . toMatchObject ( {
403
+ params : { "1" : "true" } ,
404
+ where : "active = $1" ,
405
+ orderBy : "age NULLS FIRST" ,
406
+ limit : 2 ,
407
+ } )
408
+
409
+ // Create second live query with higher limit of 5
410
+ const expandedLiveQuery = createLiveQueryCollection ( {
411
+ id : `expanded-users-live-query` ,
412
+ startSync : true ,
413
+ query : ( q ) =>
414
+ q
415
+ . from ( { user : electricCollection } )
416
+ . where ( ( { user } ) => eq ( user . active , true ) )
417
+ . select ( ( { user } ) => ( {
418
+ id : user . id ,
419
+ name : user . name ,
420
+ active : user . active ,
421
+ } ) )
422
+ . orderBy ( ( { user } ) => user . age , `asc` )
423
+ . limit ( 6 ) ,
424
+ } )
425
+
426
+ // Wait for the live query to process
427
+ await new Promise ( ( resolve ) => setTimeout ( resolve , 0 ) )
428
+
429
+ // Verify that requestSnapshot was called with the correct parameters
430
+ expect ( mockRequestSnapshot ) . toHaveBeenCalledTimes ( 3 )
431
+
432
+ // Check that first it requested a limit of 6 users
433
+ expect ( callArgs ( 1 ) ) . toMatchObject ( {
434
+ params : { "1" : "true" } ,
435
+ where : "active = $1" ,
436
+ orderBy : "age NULLS FIRST" ,
437
+ limit : 6 ,
438
+ } )
439
+
440
+ // After this initial snapshot for the new live query it receives all 3 users from the local collection
441
+ // so it still needs 3 more users to reach the limit of 6 so it requests 3 more to the sync layer
442
+ expect ( callArgs ( 2 ) ) . toMatchObject ( {
443
+ params : { "1" : "true" , "2" : "25" } ,
444
+ where : "active = $1 AND age > $2" ,
445
+ orderBy : "age NULLS FIRST" ,
446
+ limit : 3 ,
447
+ } )
448
+
449
+ // The sync layer won't provide any more users so the DB is exhausted and it stops (i.e. doesn't request more)
450
+
451
+ // The expanded live query should now have more data
452
+ expect ( expandedLiveQuery . status ) . toBe ( `ready` )
453
+ expect ( expandedLiveQuery . size ) . toBe ( 5 ) // Alice, Bob, Dave from initial + Eve and Frank from additional data
454
+ } )
455
+ }
341
456
} )
0 commit comments