@@ -35,13 +35,14 @@ export const useWatchedQuery = <RowType = unknown>(
3535 }
3636
3737 const [ watchedQuery , setWatchedQuery ] = React . useState ( createWatchedQuery ) ;
38- const updatingPromise = React . useRef < Promise < void > | null > ( ) ;
38+ const disposePendingUpdateListener = React . useRef < ( ) => void | null > ( null ) ;
3939
4040 React . useEffect ( ( ) => {
4141 watchedQuery ?. close ( ) ;
4242 setWatchedQuery ( createWatchedQuery ) ;
4343
4444 return ( ) => {
45+ disposePendingUpdateListener . current ?.( ) ;
4546 watchedQuery ?. close ( ) ;
4647 } ;
4748 } , [ powerSync , active ] ) ;
@@ -55,33 +56,30 @@ export const useWatchedQuery = <RowType = unknown>(
5556 * as soon as the query has been updated. This prevents a result flow where e.g. the hook:
5657 * - already returned a result: isLoading, isFetching are both false
5758 * - the query is updated, but the state is still isFetching=false from the previous state
58- * We override the isFetching status while the `updateSettings` method is running (if we report `isFetching`).
59- * The query could change multiple times while settings are being updated. In order to cater for this, we
60- * track the latest update operation promise.
59+ * We override the isFetching status while the `updateSettings` method is running (if we report `isFetching`),
60+ * we override this value just until the `updateSettings` method itself will update the `isFetching` status.
61+ * We achieve this by registering a `settingsWillUpdate` listener on the `WatchedQuery`. This will fire
62+ * just before the `isFetching` status is updated.
6163 */
6264 if ( queryChanged ) {
6365 // Keep track of this pending operation
64- let pendingUpdate = watchedQuery ?. updateSettings ( {
66+ watchedQuery ?. updateSettings ( {
6567 query,
6668 throttleMs : hookOptions . throttleMs ,
6769 reportFetching : hookOptions . reportFetching
6870 } ) ;
69-
70- // Keep track of the latest pending update operation
71- updatingPromise . current = pendingUpdate ;
72-
73- // Clear the latest pending update operation when the latest
74- // operation has completed.
75- pendingUpdate ?. then ( ( ) => {
76- // Only clear if this iteration was the latest iteration
77- if ( pendingUpdate == updatingPromise . current ) {
78- updatingPromise . current = null ;
71+ // This could have been called multiple times, clear any old listeners.
72+ disposePendingUpdateListener . current ?.( ) ;
73+ disposePendingUpdateListener . current = watchedQuery ?. registerListener ( {
74+ settingsWillUpdate : ( ) => {
75+ // We'll use the fact that we have a listener at all as an indication
76+ disposePendingUpdateListener . current ?.( ) ;
77+ disposePendingUpdateListener . current = null ;
7978 }
8079 } ) ;
8180 }
8281
83- const shouldReportCurrentlyFetching = ( hookOptions . reportFetching ?? true ) && ! ! updatingPromise . current ;
84-
82+ const shouldReportCurrentlyFetching = ( hookOptions . reportFetching ?? true ) && ! ! disposePendingUpdateListener . current ;
8583 const result = useNullableWatchedQuerySubscription ( watchedQuery ) ;
8684 return {
8785 ...result ,
0 commit comments