@@ -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,56 @@ 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 ) ;
1244+ flushPendingErrorsAndWarningsAfterDelayTimeoutID = null ;
12321245 }
1246+ }
1247+
1248+ function flushPendingErrorsAndWarningsAfterDelay ( ) {
1249+ clearPendingErrorsAndWarningsAfterDelay ( ) ;
12331250
12341251 flushPendingErrorsAndWarningsAfterDelayTimeoutID = setTimeout ( ( ) => {
12351252 flushPendingErrorsAndWarningsAfterDelayTimeoutID = null ;
12361253
12371254 if ( pendingOperations . length > 0 ) {
1238- // On the off chance that somethign else has pushed pending operations,
1255+ // On the off chance that something else has pushed pending operations,
12391256 // we should bail on warnings; it's probably not safe to push midway.
12401257 return ;
12411258 }
12421259
12431260 recordPendingErrorsAndWarnings ( ) ;
12441261
12451262 if ( pendingOperations . length === 0 ) {
1246- // No warnings or errors to flush.
1263+ // No warnings or errors to flush; we can bail out early here too .
12471264 return ;
12481265 }
12491266
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
1259-
1260- // Fill in the rest of the operations.
1267+ // We can create a smaller operations array than flushPendingEvents()
1268+ // because we only need to flush warning and error counts.
1269+ // Only a few pieces of fixed information are required up front.
1270+ const operations : OperationsArray = new Array (
1271+ 3 + pendingOperations . length ,
1272+ ) ;
1273+ operations [ 0 ] = rendererID ;
1274+ operations [ 1 ] = currentRootID ;
1275+ operations [ 2 ] = 0 ; // String table size
12611276 for ( let j = 0 ; j < pendingOperations . length ; j ++ ) {
1262- operations [ i + j ] = pendingOperations [ j ] ;
1277+ operations [ 3 + j ] = pendingOperations [ j ] ;
12631278 }
12641279
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- }
1280+ flushOrQueueOperations ( operations ) ;
12771281
12781282 pendingOperations . length = 0 ;
12791283 } , 1000 ) ;
@@ -1291,10 +1295,7 @@ export function attach(
12911295 }
12921296
12931297 function recordPendingErrorsAndWarnings ( ) {
1294- if ( flushPendingErrorsAndWarningsAfterDelayTimeoutID !== null ) {
1295- clearTimeout ( flushPendingErrorsAndWarningsAfterDelayTimeoutID ) ;
1296- flushPendingErrorsAndWarningsAfterDelayTimeoutID = null ;
1297- }
1298+ clearPendingErrorsAndWarningsAfterDelay ( ) ;
12981299
12991300 fibersWithChangedErrorOrWarningCounts . forEach ( fiberID => {
13001301 const fiber = idToFiberMap . get ( fiberID ) ;
@@ -1385,7 +1386,7 @@ export function attach(
13851386 // Which in turn enables fiber props, states, and hooks to be inspected.
13861387 let i = 0 ;
13871388 operations [ i ++ ] = rendererID ;
1388- operations [ i ++ ] = currentRootID ; // Use this ID in case the root was unmounted!
1389+ operations [ i ++ ] = currentRootID ;
13891390
13901391 // Now fill in the string table.
13911392 // [stringTableLength, str1Length, ...str1, str2Length, ...str2, ...]
@@ -1432,18 +1433,9 @@ export function attach(
14321433 i += pendingOperations . length ;
14331434
14341435 // 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- }
1436+ flushOrQueueOperations ( operations ) ;
14461437
1438+ // Reset all of the pending state now that we've told the frontend about it.
14471439 pendingOperations . length = 0 ;
14481440 pendingRealUnmountedIDs . length = 0 ;
14491441 pendingSimulatedUnmountedIDs . length = 0 ;
0 commit comments