@@ -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,51 @@ 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+ const queue = this . notifyQueue
110+ this . notifyQueue = [ ]
111+ queue . forEach ( notify => {
112+ notify ( )
113+ } )
114+ } )
115+ } )
116+ }
117+ }
118+
119+ scheduleNotification ( notify : NotifyCallback ) : void {
120+ if ( this . notifyTransactions ) {
121+ this . notifyQueue . push ( notify )
122+ } else {
123+ scheduleMicrotask ( ( ) => {
124+ notify ( )
125+ } )
126+ }
85127 }
86128
87129 notifyGlobalListeners ( query ?: Query < any , any > ) {
@@ -91,7 +133,9 @@ export class QueryCache {
91133 )
92134
93135 this . globalListeners . forEach ( listener => {
94- listener ( this , query )
136+ this . scheduleNotification ( ( ) => {
137+ listener ( this , query )
138+ } )
95139 } )
96140 }
97141
@@ -195,17 +239,18 @@ export class QueryCache {
195239 options || { }
196240
197241 try {
198- await Promise . all (
199- this . getQueries ( predicate , options ) . map ( query => {
200- const enabled = query . isEnabled ( )
242+ const promises : Promise < unknown > [ ] = [ ]
201243
244+ this . batchNotifications ( ( ) => {
245+ this . getQueries ( predicate , options ) . forEach ( query => {
246+ const enabled = query . isEnabled ( )
202247 if ( ( enabled && refetchActive ) || ( ! enabled && refetchInactive ) ) {
203- return query . fetch ( )
248+ promises . push ( query . fetch ( ) )
204249 }
205-
206- return undefined
207250 } )
208- )
251+ } )
252+
253+ await Promise . all ( promises )
209254 } catch ( err ) {
210255 if ( throwOnError ) {
211256 throw err
@@ -363,8 +408,10 @@ export function makeQueryCache(config?: QueryCacheConfig) {
363408export function onVisibilityOrOnlineChange ( type : 'focus' | 'online' ) {
364409 if ( isDocumentVisible ( ) && isOnline ( ) ) {
365410 queryCaches . forEach ( queryCache => {
366- queryCache . getQueries ( ) . forEach ( query => {
367- query . onInteraction ( type )
411+ queryCache . batchNotifications ( ( ) => {
412+ queryCache . getQueries ( ) . forEach ( query => {
413+ query . onInteraction ( type )
414+ } )
368415 } )
369416 } )
370417 }
0 commit comments