@@ -2,11 +2,13 @@ import {
22 Updater ,
33 deepIncludes ,
44 functionalUpdate ,
5+ getBatchedUpdates ,
56 getQueryArgs ,
67 isDocumentVisible ,
7- isPlainObject ,
88 isOnline ,
9+ isPlainObject ,
910 isServer ,
11+ scheduleMicrotask ,
1012} from './utils'
1113import { getResolvedQueryConfig } from './config'
1214import { Query } from './query'
@@ -66,6 +68,8 @@ type QueryCacheListener = (
6668 query ?: Query < unknown , unknown >
6769) => void
6870
71+ type NotifyCallback = ( ) => void
72+
6973// CLASS
7074
7175export class QueryCache {
@@ -75,13 +79,50 @@ export class QueryCache {
7579 private globalListeners : QueryCacheListener [ ]
7680 private queries : QueryHashMap
7781 private queriesArray : Query < any , any > [ ]
82+ private notifyQueue : NotifyCallback [ ]
83+ private notifyTransactions : number
7884
7985 constructor ( config ?: QueryCacheConfig ) {
8086 this . config = config || { }
8187 this . globalListeners = [ ]
8288 this . queries = { }
8389 this . queriesArray = [ ]
8490 this . isFetching = 0
91+ this . notifyQueue = [ ]
92+ this . notifyTransactions = 0
93+ }
94+
95+ batchNotifications ( callback : ( ) => void ) : void {
96+ this . notifyTransactions ++
97+ callback ( )
98+ this . notifyTransactions --
99+ if ( ! this . notifyTransactions ) {
100+ this . executeNotifications ( )
101+ }
102+ }
103+
104+ executeNotifications ( ) : void {
105+ if ( this . notifyQueue . length ) {
106+ scheduleMicrotask ( ( ) => {
107+ const batchedUpdates = getBatchedUpdates ( )
108+ batchedUpdates ( ( ) => {
109+ this . notifyQueue . forEach ( notify => {
110+ notify ( )
111+ } )
112+ this . notifyQueue = [ ]
113+ } )
114+ } )
115+ }
116+ }
117+
118+ scheduleNotification ( notify : NotifyCallback ) : void {
119+ if ( this . notifyTransactions ) {
120+ this . notifyQueue . push ( notify )
121+ } else {
122+ scheduleMicrotask ( ( ) => {
123+ notify ( )
124+ } )
125+ }
85126 }
86127
87128 notifyGlobalListeners ( query ?: Query < any , any > ) {
@@ -91,7 +132,9 @@ export class QueryCache {
91132 )
92133
93134 this . globalListeners . forEach ( listener => {
94- listener ( this , query )
135+ this . scheduleNotification ( ( ) => {
136+ listener ( this , query )
137+ } )
95138 } )
96139 }
97140
@@ -195,17 +238,18 @@ export class QueryCache {
195238 options || { }
196239
197240 try {
198- await Promise . all (
199- this . getQueries ( predicate , options ) . map ( query => {
200- const enabled = query . isEnabled ( )
241+ const promises : Promise < unknown > [ ] = [ ]
201242
243+ this . batchNotifications ( ( ) => {
244+ this . getQueries ( predicate , options ) . forEach ( query => {
245+ const enabled = query . isEnabled ( )
202246 if ( ( enabled && refetchActive ) || ( ! enabled && refetchInactive ) ) {
203- return query . fetch ( )
247+ promises . push ( query . fetch ( ) )
204248 }
205-
206- return undefined
207249 } )
208- )
250+ } )
251+
252+ await Promise . all ( promises )
209253 } catch ( err ) {
210254 if ( throwOnError ) {
211255 throw err
@@ -363,8 +407,10 @@ export function makeQueryCache(config?: QueryCacheConfig) {
363407export function onVisibilityOrOnlineChange ( type : 'focus' | 'online' ) {
364408 if ( isDocumentVisible ( ) && isOnline ( ) ) {
365409 queryCaches . forEach ( queryCache => {
366- queryCache . getQueries ( ) . forEach ( query => {
367- query . onInteraction ( type )
410+ queryCache . batchNotifications ( ( ) => {
411+ queryCache . getQueries ( ) . forEach ( query => {
412+ query . onInteraction ( type )
413+ } )
368414 } )
369415 } )
370416 }
0 commit comments