@@ -54,10 +54,30 @@ const sampleUsers: Array<User> = [
5454
5555// Mock the ShapeStream module
5656const mockSubscribe = vi . fn ( )
57+ const mockRequestSnapshot = vi . fn ( )
5758const mockStream = {
5859 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+ }
5972}
6073
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+
6181vi . mock ( `@electric-sql/client` , async ( ) => {
6282 const actual = await vi . importActual ( `@electric-sql/client` )
6383 return {
@@ -338,4 +358,99 @@ describe.each([
338358 expect ( testElectricCollection . status ) . toBe ( `ready` )
339359 expect ( liveQuery . status ) . toBe ( `ready` )
340360 } )
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+ }
341456} )
0 commit comments