@@ -631,7 +631,8 @@ export function attach(
631631 // In this case, we should wait until the rest of the passive effects have run,
632632 // but we shouldn't wait until the next commit because that might be a long time.
633633 // This would also cause "tearing" between an inspected Component and the tree view.
634- // Then again we don't want to flush too soon because rendering might stil be going on.
634+ // Then again we don't want to flush too soon because this could be an error during async rendering.
635+ // Use a debounce technique to ensure that we'll eventually flush.
635636 flushPendingErrorsAndWarningsAfterDelay ( ) ;
636637 }
637638
@@ -1205,10 +1206,12 @@ export function attach(
12051206 }
12061207 }
12071208
1208- const pendingOperations : Array < number > = [ ] ;
1209+ type OperationsArray = Array < number > ;
1210+
1211+ const pendingOperations : OperationsArray = [ ] ;
12091212 const pendingRealUnmountedIDs : Array < number > = [ ] ;
12101213 const pendingSimulatedUnmountedIDs : Array < number > = [ ] ;
1211- let pendingOperationsQueue : Array < Array < number > > | null = [ ] ;
1214+ let pendingOperationsQueue : Array < OperationsArray > | null = [ ] ;
12121215 const pendingStringTable : Map < string , number > = new Map ( ) ;
12131216 let pendingStringTableLength : number = 0 ;
12141217 let pendingUnmountedRootID : number | null = null ;
@@ -1225,55 +1228,57 @@ export function attach(
12251228 pendingOperations . push ( op ) ;
12261229 }
12271230
1231+ function flushOrQueueOperations ( operations : OperationsArray ) : void {
1232+ if ( pendingOperationsQueue !== null ) {
1233+ pendingOperationsQueue . push ( operations ) ;
1234+ } else {
1235+ hook . emit ( 'operations' , operations ) ;
1236+ }
1237+ }
1238+
12281239 let flushPendingErrorsAndWarningsAfterDelayTimeoutID = null ;
1229- function flushPendingErrorsAndWarningsAfterDelay ( ) {
1240+
1241+ function clearPendingErrorsAndWarningsAfterDelay ( ) {
12301242 if ( flushPendingErrorsAndWarningsAfterDelayTimeoutID !== null ) {
12311243 clearTimeout ( flushPendingErrorsAndWarningsAfterDelayTimeoutID ) ;
12321244 }
1245+ }
1246+
1247+ function flushPendingErrorsAndWarningsAfterDelay ( ) {
1248+ clearPendingErrorsAndWarningsAfterDelay ( ) ;
12331249
12341250 flushPendingErrorsAndWarningsAfterDelayTimeoutID = setTimeout ( ( ) => {
12351251 flushPendingErrorsAndWarningsAfterDelayTimeoutID = null ;
12361252
12371253 if ( pendingOperations . length > 0 ) {
1238- // On the off chance that somethign else has pushed pending operations,
1254+ // On the off chance that something else has pushed pending operations,
12391255 // we should bail on warnings; it's probably not safe to push midway.
12401256 return ;
12411257 }
12421258
12431259 recordPendingErrorsAndWarnings ( ) ;
12441260
12451261 if ( pendingOperations . length === 0 ) {
1246- // No warnings or errors to flush.
1262+ // No warnings or errors to flush; we can bail out early here too .
12471263 return ;
12481264 }
12491265
1250- const operations = new Array ( 2 + 1 + pendingOperations . length ) ;
1251-
1252- // Identify which renderer this update is coming from .
1253- // This enables roots to be mapped to renderers,
1254- // Which in turn enables fiber props, states, and hooks to be inspected.
1255- let i = 0 ;
1256- operations [ i ++ ] = rendererID ;
1257- operations [ i ++ ] = currentRootID ; // Use this ID in case the root was unmounted!
1258- operations [ i ++ ] = 0 ; // String table size
1266+ // We can create a smaller operations array than flushPendingEvents()
1267+ // because we only need to flush warning and error counts.
1268+ // Only a few pieces of fixed information are required up front .
1269+ const operations : OperationsArray = new Array (
1270+ 3 + pendingOperations . length ,
1271+ ) ;
1272+ operations [ 0 ] = rendererID ;
1273+ operations [ 1 ] = currentRootID ; // Use this ID in case the root was unmounted!
1274+ operations [ 2 ] = 0 ; // String table size
12591275
12601276 // Fill in the rest of the operations.
12611277 for ( let j = 0 ; j < pendingOperations . length ; j ++ ) {
1262- operations [ i + j ] = pendingOperations [ j ] ;
1278+ operations [ 3 + j ] = pendingOperations [ j ] ;
12631279 }
12641280
1265- // Let the frontend know about tree operations.
1266- // The first value in this array will identify which root it corresponds to,
1267- // so we do no longer need to dispatch a separate root-committed event.
1268- if ( pendingOperationsQueue !== null ) {
1269- // Until the frontend has been connected, store the tree operations.
1270- // This will let us avoid walking the tree later when the frontend connects,
1271- // and it enables the Profiler's reload-and-profile functionality to work as well.
1272- pendingOperationsQueue . push ( operations ) ;
1273- } else {
1274- // If we've already connected to the frontend, just pass the operations through.
1275- hook . emit ( 'operations' , operations ) ;
1276- }
1281+ flushOrQueueOperations ( operations ) ;
12771282
12781283 pendingOperations . length = 0 ;
12791284 } , 1000 ) ;
@@ -1291,10 +1296,7 @@ export function attach(
12911296 }
12921297
12931298 function recordPendingErrorsAndWarnings ( ) {
1294- if ( flushPendingErrorsAndWarningsAfterDelayTimeoutID !== null ) {
1295- clearTimeout ( flushPendingErrorsAndWarningsAfterDelayTimeoutID ) ;
1296- flushPendingErrorsAndWarningsAfterDelayTimeoutID = null ;
1297- }
1299+ clearPendingErrorsAndWarningsAfterDelay ( ) ;
12981300
12991301 fibersWithChangedErrorOrWarningCounts . forEach ( fiberID => {
13001302 const fiber = idToFiberMap . get ( fiberID ) ;
@@ -1432,18 +1434,9 @@ export function attach(
14321434 i += pendingOperations . length ;
14331435
14341436 // Let the frontend know about tree operations.
1435- // The first value in this array will identify which root it corresponds to,
1436- // so we do no longer need to dispatch a separate root-committed event.
1437- if ( pendingOperationsQueue !== null ) {
1438- // Until the frontend has been connected, store the tree operations.
1439- // This will let us avoid walking the tree later when the frontend connects,
1440- // and it enables the Profiler's reload-and-profile functionality to work as well.
1441- pendingOperationsQueue . push ( operations ) ;
1442- } else {
1443- // If we've already connected to the frontend, just pass the operations through.
1444- hook . emit ( 'operations' , operations ) ;
1445- }
1437+ flushOrQueueOperations ( operations ) ;
14461438
1439+ // Reset all of the pending state now that we've told the frontend about it.
14471440 pendingOperations . length = 0 ;
14481441 pendingRealUnmountedIDs . length = 0 ;
14491442 pendingSimulatedUnmountedIDs . length = 0 ;
0 commit comments