@@ -6,6 +6,7 @@ import pDefer from 'p-defer';
66import { beforeEach , describe , expect , it , onTestFinished , vi } from 'vitest' ;
77import { PowerSyncContext } from '../src/hooks/PowerSyncContext' ;
88import { useQuery } from '../src/hooks/watched/useQuery' ;
9+ import { useWatchedQuerySubscription } from '../src/hooks/watched/useWatchedQuerySubscription' ;
910export const openPowerSync = ( ) => {
1011 const db = new PowerSyncDatabase ( {
1112 database : { dbFilename : 'test.db' } ,
@@ -224,7 +225,7 @@ describe('useQuery', () => {
224225 const deferred = pDefer ( ) ;
225226
226227 const baseGetAll = db . getAll ;
227- const getSpy = vi . spyOn ( db , 'getAll' ) . mockImplementation ( async ( sql , params ) => {
228+ vi . spyOn ( db , 'getAll' ) . mockImplementation ( async ( sql , params ) => {
228229 // Allow pausing this call in order to test isFetching
229230 await deferred . promise ;
230231 return baseGetAll . call ( db , sql , params ) ;
@@ -255,5 +256,56 @@ describe('useQuery', () => {
255256 expect ( data == result . current . data ) . toEqual ( true ) ;
256257 } ) ;
257258
259+ it ( 'should use an existing WatchedQuery instance' , async ( ) => {
260+ const db = openPowerSync ( ) ;
261+
262+ // This query can be instantiated once and reused.
263+ // The query retains it's state and will not re-fetch the data unless the result changes.
264+ // This is useful for queries that are used in multiple components.
265+ const listsQuery = db . incrementalWatch ( {
266+ watch : {
267+ placeholderData : [ ] ,
268+ query : {
269+ compile : ( ) => ( {
270+ sql : `SELECT * FROM lists` ,
271+ parameters : [ ]
272+ } ) ,
273+ execute : ( { sql, parameters } ) => db . getAll ( sql , parameters )
274+ }
275+ }
276+ } ) ;
277+
278+ const wrapper = ( { children } ) => < PowerSyncContext . Provider value = { db } > { children } </ PowerSyncContext . Provider > ;
279+ const { result } = renderHook ( ( ) => useWatchedQuerySubscription ( listsQuery ) , {
280+ wrapper
281+ } ) ;
282+
283+ expect ( result . current . isLoading ) . toEqual ( true ) ;
284+
285+ await waitFor (
286+ async ( ) => {
287+ const { current } = result ;
288+ expect ( current . isLoading ) . toEqual ( false ) ;
289+ } ,
290+ { timeout : 500 , interval : 100 }
291+ ) ;
292+
293+ // This should trigger an update
294+ await db . execute ( 'INSERT INTO lists(id, name) VALUES (uuid(), ?)' , [ 'aname' ] ) ;
295+
296+ await waitFor (
297+ async ( ) => {
298+ const { current } = result ;
299+ expect ( current . data . length ) . toEqual ( 1 ) ;
300+ } ,
301+ { timeout : 500 , interval : 100 }
302+ ) ;
303+
304+ // now use the same query again, the result should be available immediately
305+ const { result : newResult } = renderHook ( ( ) => useWatchedQuerySubscription ( listsQuery ) , { wrapper } ) ;
306+ expect ( newResult . current . isLoading ) . toEqual ( false ) ;
307+ expect ( newResult . current . data . length ) . toEqual ( 1 ) ;
308+ } ) ;
309+
258310 // TODO: Add tests for powersync.onChangeWithCallback path
259311} ) ;
0 commit comments