Best JavaScript code snippet using playwright-internal
ReactFiberWorkLoop.old.js
Source:ReactFiberWorkLoop.old.js  
...161      lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);162    }163    return lane;164  }165  function requestRetryLane(fiber) {166    // This is a fork of `requestUpdateLane` designed specifically for Suspense167    // "retries" â a special update that attempts to flip a Suspense boundary168    // from its placeholder state to its primary/resolved state.169    // Special cases170    var mode = fiber.mode;171    if ((mode & BlockingMode) === NoMode) {172      return SyncLane;173    } else if ((mode & ConcurrentMode) === NoMode) {174      return getCurrentPriorityLevel() === ImmediatePriority$1 ? SyncLane : SyncBatchedLane;175    } // See `requestUpdateLane` for explanation of `currentEventWipLanes`176    if (currentEventWipLanes === NoLanes) {177      currentEventWipLanes = workInProgressRootIncludedLanes;178    }179    return findRetryLane(currentEventWipLanes);180  }181  function scheduleUpdateOnFiber(fiber, lane, eventTime) {182    checkForNestedUpdates();183    warnAboutRenderPhaseUpdatesInDEV(fiber);184    var root = markUpdateLaneFromFiberToRoot(fiber, lane);185    if (root === null) {186      warnAboutUpdateOnUnmountedFiberInDEV(fiber);187      return null;188    } // Mark that the root has a pending update.189    markRootUpdated(root, lane, eventTime);190    if (root === workInProgressRoot) {191      // Received an update to a tree that's in the middle of rendering. Mark192      // that there was an interleaved update work on this root. Unless the193      // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render194      // phase update. In that case, we don't treat render phase updates as if195      // they were interleaved, for backwards compat reasons.196      {197        workInProgressRootUpdatedLanes = mergeLanes(workInProgressRootUpdatedLanes, lane);198      }199      if (workInProgressRootExitStatus === RootSuspendedWithDelay) {200        // The root already suspended with a delay, which means this render201        // definitely won't finish. Since we have a new update, let's mark it as202        // suspended now, right before marking the incoming update. This has the203        // effect of interrupting the current render and switching to the update.204        // TODO: Make sure this doesn't override pings that happen while we've205        // already started rendering.206        markRootSuspended$1(root, workInProgressRootRenderLanes);207      }208    } // TODO: requestUpdateLanePriority also reads the priority. Pass the209    // priority as an argument to that function and this one.210    var priorityLevel = getCurrentPriorityLevel();211    if (lane === SyncLane) {212      if ( // Check if we're inside unbatchedUpdates213      (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering214      (executionContext & (RenderContext | CommitContext)) === NoContext) {215        // Register pending interactions on the root to avoid losing traced interaction data.216        schedulePendingInteractions(root, lane); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed217        // root inside of batchedUpdates should be synchronous, but layout updates218        // should be deferred until the end of the batch.219        performSyncWorkOnRoot(root);220      } else {221        ensureRootIsScheduled(root, eventTime);222        schedulePendingInteractions(root, lane);223        if (executionContext === NoContext) {224          // Flush the synchronous work now, unless we're already working or inside225          // a batch. This is intentionally inside scheduleUpdateOnFiber instead of226          // scheduleCallbackForFiber to preserve the ability to schedule a callback227          // without immediately flushing it. We only do this for user-initiated228          // updates, to preserve historical behavior of legacy mode.229          resetRenderTimer();230          flushSyncCallbackQueue();231        }232      }233    } else {234      // Schedule a discrete update but only if it's not Sync.235      if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered236      // discrete, even inside a discrete event.237      priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority$1)) {238        // This is the result of a discrete event. Track the lowest priority239        // discrete update per root so we can flush them early, if needed.240        if (rootsWithPendingDiscreteUpdates === null) {241          rootsWithPendingDiscreteUpdates = new Set([root]);242        } else {243          rootsWithPendingDiscreteUpdates.add(root);244        }245      } // Schedule other updates after in case the callback is sync.246      ensureRootIsScheduled(root, eventTime);247      schedulePendingInteractions(root, lane);248    } // We use this when assigning a lane for a transition inside249    // `requestUpdateLane`. We assume it's the same as the root being updated,250    // since in the common case of a single root app it probably is. If it's not251    // the same root, then it's not a huge deal, we just might batch more stuff252    // together more than necessary.253    mostRecentlyUpdatedRoot = root;254  } // This is split into a separate function so we can mark a fiber with pending255  // work without treating it as a typical update that originates from an event;256  // e.g. retrying a Suspense boundary isn't an update, but it does schedule work257  // on a fiber.258  function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {259    // Update the source fiber's lanes260    sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);261    var alternate = sourceFiber.alternate;262    if (alternate !== null) {263      alternate.lanes = mergeLanes(alternate.lanes, lane);264    }265    {266      if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {267        warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);268      }269    } // Walk the parent path to the root and update the child expiration time.270    var node = sourceFiber;271    var parent = sourceFiber.return;272    while (parent !== null) {273      parent.childLanes = mergeLanes(parent.childLanes, lane);274      alternate = parent.alternate;275      if (alternate !== null) {276        alternate.childLanes = mergeLanes(alternate.childLanes, lane);277      } else {278        {279          if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {280            warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);281          }282        }283      }284      node = parent;285      parent = parent.return;286    }287    if (node.tag === HostRoot) {288      var root = node.stateNode;289      return root;290    } else {291      return null;292    }293  } // Use this function to schedule a task for a root. There's only one task per294  // root; if a task was already scheduled, we'll check to make sure the priority295  // of the existing task is the same as the priority of the next level that the296  // root has work on. This function is called on every update, and right before297  // exiting a task.298  function ensureRootIsScheduled(root, currentTime) {299    var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as300    // expired so we know to work on those next.301    markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.302    var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes); // This returns the priority level computed during the `getNextLanes` call.303    var newCallbackPriority = returnNextLanesPriority();304    if (nextLanes === NoLanes) {305      // Special case: There's nothing to work on.306      if (existingCallbackNode !== null) {307        cancelCallback(existingCallbackNode);308        root.callbackNode = null;309        root.callbackPriority = NoLanePriority;310      }311      return;312    } // Check if there's an existing task. We may be able to reuse it.313    if (existingCallbackNode !== null) {314      var existingCallbackPriority = root.callbackPriority;315      if (existingCallbackPriority === newCallbackPriority) {316        // The priority hasn't changed. We can reuse the existing task. Exit.317        return;318      } // The priority changed. Cancel the existing callback. We'll schedule a new319      // one below.320      cancelCallback(existingCallbackNode);321    } // Schedule a new callback.322    var newCallbackNode;323    if (newCallbackPriority === SyncLanePriority) {324      // Special case: Sync React callbacks are scheduled on a special325      // internal queue326      newCallbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));327    } else if (newCallbackPriority === SyncBatchedLanePriority) {328      newCallbackNode = scheduleCallback(ImmediatePriority$1, performSyncWorkOnRoot.bind(null, root));329    } else {330      var schedulerPriorityLevel = lanePriorityToSchedulerPriority(newCallbackPriority);331      newCallbackNode = scheduleCallback(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));332    }333    root.callbackPriority = newCallbackPriority;334    root.callbackNode = newCallbackNode;335  } // This is the entry point for every concurrent task, i.e. anything that336  // goes through Scheduler.337  function performConcurrentWorkOnRoot(root) {338    // Since we know we're in a React event, we can clear the current339    // event time. The next update will compute a new event time.340    currentEventTime = NoTimestamp;341    currentEventWipLanes = NoLanes;342    currentEventPendingLanes = NoLanes;343    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {344      {345        throw Error( "Should not already be working." );346      }347    } // Flush any pending passive effects before deciding which lanes to work on,348    // in case they schedule additional work.349    var originalCallbackNode = root.callbackNode;350    var didFlushPassiveEffects = flushPassiveEffects();351    if (didFlushPassiveEffects) {352      // Something in the passive effect phase may have canceled the current task.353      // Check if the task node for this root was changed.354      if (root.callbackNode !== originalCallbackNode) {355        // The current task was canceled. Exit. We don't need to call356        // `ensureRootIsScheduled` because the check above implies either that357        // there's a new task, or that there's no remaining work on this root.358        return null;359      }360    } // Determine the next expiration time to work on, using the fields stored361    // on the root.362    var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);363    if (lanes === NoLanes) {364      // Defensive coding. This is never expected to happen.365      return null;366    }367    var exitStatus = renderRootConcurrent(root, lanes);368    if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {369      // The render included lanes that were updated during the render phase.370      // For example, when unhiding a hidden tree, we include all the lanes371      // that were previously skipped when the tree was hidden. That set of372      // lanes is a superset of the lanes we started rendering with.373      //374      // So we'll throw out the current work and restart.375      prepareFreshStack(root, NoLanes);376    } else if (exitStatus !== RootIncomplete) {377      if (exitStatus === RootErrored) {378        executionContext |= RetryAfterError; // If an error occurred during hydration,379        // discard server response and fall back to client side render.380        if (root.hydrate) {381          root.hydrate = false;382          clearContainer(root.containerInfo);383        } // If something threw an error, try rendering one more time. We'll render384        // synchronously to block concurrent data mutations, and we'll includes385        // all pending updates are included. If it still fails after the second386        // attempt, we'll give up and commit the resulting tree.387        lanes = getLanesToRetrySynchronouslyOnError(root);388        if (lanes !== NoLanes) {389          exitStatus = renderRootSync(root, lanes);390        }391      }392      if (exitStatus === RootFatalErrored) {393        var fatalError = workInProgressRootFatalError;394        prepareFreshStack(root, NoLanes);395        markRootSuspended$1(root, lanes);396        ensureRootIsScheduled(root, now());397        throw fatalError;398      } // We now have a consistent tree. The next step is either to commit it,399      // or, if something suspended, wait to commit it after a timeout.400      var finishedWork = root.current.alternate;401      root.finishedWork = finishedWork;402      root.finishedLanes = lanes;403      finishConcurrentRender(root, exitStatus, lanes);404    }405    ensureRootIsScheduled(root, now());406    if (root.callbackNode === originalCallbackNode) {407      // The task node scheduled for this root is the same one that's408      // currently executed. Need to return a continuation.409      return performConcurrentWorkOnRoot.bind(null, root);410    }411    return null;412  }413  function finishConcurrentRender(root, exitStatus, lanes) {414    switch (exitStatus) {415      case RootIncomplete:416      case RootFatalErrored:417        {418          {419            {420              throw Error( "Root did not complete. This is a bug in React." );421            }422          }423        }424      // Flow knows about invariant, so it complains if I add a break425      // statement, but eslint doesn't know about invariant, so it complains426      // if I do. eslint-disable-next-line no-fallthrough427      case RootErrored:428        {429          // We should have already attempted to retry this tree. If we reached430          // this point, it errored again. Commit it.431          commitRoot(root);432          break;433        }434      case RootSuspended:435        {436          markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we437          // should immediately commit it or wait a bit.438          if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope439          !shouldForceFlushFallbacksInDEV()) {440            // This render only included retries, no updates. Throttle committing441            // retries so that we don't show too many loading states too quickly.442            var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.443            if (msUntilTimeout > 10) {444              var nextLanes = getNextLanes(root, NoLanes);445              if (nextLanes !== NoLanes) {446                // There's additional work on this root.447                break;448              }449              var suspendedLanes = root.suspendedLanes;450              if (!isSubsetOfLanes(suspendedLanes, lanes)) {451                // We should prefer to render the fallback of at the last452                // suspended level. Ping the last suspended level to try453                // rendering it again.454                // FIXME: What if the suspended lanes are Idle? Should not restart.455                var eventTime = requestEventTime();456                markRootPinged(root, suspendedLanes);457                break;458              } // The render is suspended, it hasn't timed out, and there's no459              // lower priority work to do. Instead of committing the fallback460              // immediately, wait for more data to arrive.461              root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);462              break;463            }464          } // The work expired. Commit immediately.465          commitRoot(root);466          break;467        }468      case RootSuspendedWithDelay:469        {470          markRootSuspended$1(root, lanes);471          if (includesOnlyTransitions(lanes)) {472            // This is a transition, so we should exit without committing a473            // placeholder and without scheduling a timeout. Delay indefinitely474            // until we receive more data.475            break;476          }477          if (!shouldForceFlushFallbacksInDEV()) {478            // This is not a transition, but we did trigger an avoided state.479            // Schedule a placeholder to display after a short delay, using the Just480            // Noticeable Difference.481            // TODO: Is the JND optimization worth the added complexity? If this is482            // the only reason we track the event time, then probably not.483            // Consider removing.484            var mostRecentEventTime = getMostRecentEventTime(root, lanes);485            var eventTimeMs = mostRecentEventTime;486            var timeElapsedMs = now() - eventTimeMs;487            var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.488            if (_msUntilTimeout > 10) {489              // Instead of committing the fallback immediately, wait for more data490              // to arrive.491              root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);492              break;493            }494          } // Commit the placeholder.495          commitRoot(root);496          break;497        }498      case RootCompleted:499        {500          // The work completed. Ready to commit.501          commitRoot(root);502          break;503        }504      default:505        {506          {507            {508              throw Error( "Unknown root exit status." );509            }510          }511        }512    }513  }514  function markRootSuspended$1(root, suspendedLanes) {515    // When suspending, we should always exclude lanes that were pinged or (more516    // rarely, since we try to avoid it) updated during the render phase.517    // TODO: Lol maybe there's a better way to factor this besides this518    // obnoxiously named function :)519    suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);520    suspendedLanes = removeLanes(suspendedLanes, workInProgressRootUpdatedLanes);521    markRootSuspended(root, suspendedLanes);522  } // This is the entry point for synchronous tasks that don't go523  // through Scheduler524  function performSyncWorkOnRoot(root) {525    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {526      {527        throw Error( "Should not already be working." );528      }529    }530    flushPassiveEffects();531    var lanes;532    var exitStatus;533    if (root === workInProgressRoot && includesSomeLane(root.expiredLanes, workInProgressRootRenderLanes)) {534      // There's a partial tree, and at least one of its lanes has expired. Finish535      // rendering it before rendering the rest of the expired work.536      lanes = workInProgressRootRenderLanes;537      exitStatus = renderRootSync(root, lanes);538      if (includesSomeLane(workInProgressRootIncludedLanes, workInProgressRootUpdatedLanes)) {539        // The render included lanes that were updated during the render phase.540        // For example, when unhiding a hidden tree, we include all the lanes541        // that were previously skipped when the tree was hidden. That set of542        // lanes is a superset of the lanes we started rendering with.543        //544        // Note that this only happens when part of the tree is rendered545        // concurrently. If the whole tree is rendered synchronously, then there546        // are no interleaved events.547        lanes = getNextLanes(root, lanes);548        exitStatus = renderRootSync(root, lanes);549      }550    } else {551      lanes = getNextLanes(root, NoLanes);552      exitStatus = renderRootSync(root, lanes);553    }554    if (root.tag !== LegacyRoot && exitStatus === RootErrored) {555      executionContext |= RetryAfterError; // If an error occurred during hydration,556      // discard server response and fall back to client side render.557      if (root.hydrate) {558        root.hydrate = false;559        clearContainer(root.containerInfo);560      } // If something threw an error, try rendering one more time. We'll render561      // synchronously to block concurrent data mutations, and we'll includes562      // all pending updates are included. If it still fails after the second563      // attempt, we'll give up and commit the resulting tree.564      lanes = getLanesToRetrySynchronouslyOnError(root);565      if (lanes !== NoLanes) {566        exitStatus = renderRootSync(root, lanes);567      }568    }569    if (exitStatus === RootFatalErrored) {570      var fatalError = workInProgressRootFatalError;571      prepareFreshStack(root, NoLanes);572      markRootSuspended$1(root, lanes);573      ensureRootIsScheduled(root, now());574      throw fatalError;575    } // We now have a consistent tree. Because this is a sync render, we576    // will commit it even if something suspended.577    var finishedWork = root.current.alternate;578    root.finishedWork = finishedWork;579    root.finishedLanes = lanes;580    commitRoot(root); // Before exiting, make sure there's a callback scheduled for the next581    // pending level.582    ensureRootIsScheduled(root, now());583    return null;584  }585  function flushRoot(root, lanes) {586    markRootExpired(root, lanes);587    ensureRootIsScheduled(root, now());588    if ((executionContext & (RenderContext | CommitContext)) === NoContext) {589      resetRenderTimer();590      flushSyncCallbackQueue();591    }592  }593  function getExecutionContext() {594    return executionContext;595  }596  // flush reactäºä»¶597  function flushDiscreteUpdates() {598    // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.599    // However, `act` uses `batchedUpdates`, so there's no way to distinguish600    // those two cases. Need to fix this before exposing flushDiscreteUpdates601    // as a public API.602    if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {603      {604        if ((executionContext & RenderContext) !== NoContext) {605          error('unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');606        }607      } // We're already rendering, so we can't synchronously flush pending work.608      // This is probably a nested event dispatch triggered by a lifecycle/effect,609      // like `el.focus()`. Exit.610      return;611    }612    flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that613    // they fire before the next serial event.614    flushPassiveEffects();615  }616  function flushPendingDiscreteUpdates() {617    if (rootsWithPendingDiscreteUpdates !== null) {618      // For each root with pending discrete updates, schedule a callback to619      // immediately flush them.620      var roots = rootsWithPendingDiscreteUpdates;621      rootsWithPendingDiscreteUpdates = null;622      roots.forEach(function (root) {623        markDiscreteUpdatesExpired(root);624        ensureRootIsScheduled(root, now());625      });626    } // Now flush the immediate queue.627    flushSyncCallbackQueue();628  }629  function batchedUpdates$1(fn, a) {630    var prevExecutionContext = executionContext;631    executionContext |= BatchedContext;632    try {633      return fn(a);634    } finally {635      executionContext = prevExecutionContext;636      if (executionContext === NoContext) {637        // Flush the immediate callbacks that were scheduled during this batch638        resetRenderTimer();639        flushSyncCallbackQueue();640      }641    }642  }643  function batchedEventUpdates$1(fn, a) {644    var prevExecutionContext = executionContext;645    executionContext |= EventContext;646    try {647      return fn(a);648    } finally {649      executionContext = prevExecutionContext;650      if (executionContext === NoContext) {651        // Flush the immediate callbacks that were scheduled during this batch652        resetRenderTimer();653        flushSyncCallbackQueue();654      }655    }656  }657  function discreteUpdates$1(fn, a, b, c, d) {658    var prevExecutionContext = executionContext;659    executionContext |= DiscreteEventContext;660    {661      try {662        return runWithPriority$1(UserBlockingPriority$2, fn.bind(null, a, b, c, d));663      } finally {664        executionContext = prevExecutionContext;665        if (executionContext === NoContext) {666          // Flush the immediate callbacks that were scheduled during this batch667          resetRenderTimer();668          flushSyncCallbackQueue();669        }670      }671    }672  }673  // 鿹鿴æ°674  function unbatchedUpdates(fn, a) {675    var prevExecutionContext = executionContext;676    executionContext &= ~BatchedContext;677    executionContext |= LegacyUnbatchedContext;678    try {679      return fn(a);680    } finally {681      executionContext = prevExecutionContext;682      if (executionContext === NoContext) {683        // Flush the immediate callbacks that were scheduled during this batch684        resetRenderTimer();685        flushSyncCallbackQueue();686      }687    }688  }689  function flushSync(fn, a) {690    var prevExecutionContext = executionContext;691    if ((prevExecutionContext & (RenderContext | CommitContext)) !== NoContext) {692      {693        error('flushSync was called from inside a lifecycle method. React cannot ' + 'flush when React is already rendering. Consider moving this call to ' + 'a scheduler task or micro task.');694      }695      return fn(a);696    }697    executionContext |= BatchedContext;698    {699      try {700        if (fn) {701          return runWithPriority$1(ImmediatePriority$1, fn.bind(null, a));702        } else {703          return undefined;704        }705      } finally {706        executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.707        // Note that this will happen even if batchedUpdates is higher up708        // the stack.709        flushSyncCallbackQueue();710      }711    }712  }713  function flushControlled(fn) {714    var prevExecutionContext = executionContext;715    executionContext |= BatchedContext;716    {717      try {718        runWithPriority$1(ImmediatePriority$1, fn);719      } finally {720        executionContext = prevExecutionContext;721        if (executionContext === NoContext) {722          // Flush the immediate callbacks that were scheduled during this batch723          resetRenderTimer();724          flushSyncCallbackQueue();725        }726      }727    }728  }729  function pushRenderLanes(fiber, lanes) {730    push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);731    subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);732    workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);733  }734  function popRenderLanes(fiber) {735    subtreeRenderLanes = subtreeRenderLanesCursor.current;736    pop(subtreeRenderLanesCursor, fiber);737  }738  function prepareFreshStack(root, lanes) {739    root.finishedWork = null;740    root.finishedLanes = NoLanes;741    var timeoutHandle = root.timeoutHandle;742    if (timeoutHandle !== noTimeout) {743      // The root previous suspended and scheduled a timeout to commit a fallback744      // state. Now that we have additional work, cancel the timeout.745      root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above746      cancelTimeout(timeoutHandle);747    }748    if (workInProgress !== null) {749      var interruptedWork = workInProgress.return;750      while (interruptedWork !== null) {751        unwindInterruptedWork(interruptedWork);752        interruptedWork = interruptedWork.return;753      }754    }755    workInProgressRoot = root;756    workInProgress = createWorkInProgress(root.current, null);757    workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;758    workInProgressRootExitStatus = RootIncomplete;759    workInProgressRootFatalError = null;760    workInProgressRootSkippedLanes = NoLanes;761    workInProgressRootUpdatedLanes = NoLanes;762    workInProgressRootPingedLanes = NoLanes;763    {764      spawnedWorkDuringRender = null;765    }766    {767      ReactStrictModeWarnings.discardPendingWarnings();768    }769  }770  function handleError(root, thrownValue) {771    do {772      var erroredWork = workInProgress;773      try {774        // Reset module-level state that was set during the render phase.775        resetContextDependencies();776        resetHooksAfterThrow();777        resetCurrentFiber(); // TODO: I found and added this missing line while investigating a778        // separate issue. Write a regression test using string refs.779        ReactCurrentOwner$2.current = null;780        if (erroredWork === null || erroredWork.return === null) {781          // Expected to be working on a non-root fiber. This is a fatal error782          // because there's no ancestor that can handle it; the root is783          // supposed to capture all errors that weren't caught by an error784          // boundary.785          workInProgressRootExitStatus = RootFatalErrored;786          workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next787          // sibling, or the parent if there are no siblings. But since the root788          // has no siblings nor a parent, we set it to null. Usually this is789          // handled by `completeUnitOfWork` or `unwindWork`, but since we're790          // intentionally not calling those, we need set it here.791          // TODO: Consider calling `unwindWork` to pop the contexts.792          workInProgress = null;793          return;794        }795        if (enableProfilerTimer && erroredWork.mode & ProfileMode) {796          // Record the time spent rendering before an error was thrown. This797          // avoids inaccurate Profiler durations in the case of a798          // suspended render.799          stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);800        }801        throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);802        completeUnitOfWork(erroredWork);803      } catch (yetAnotherThrownValue) {804        // Something in the return path also threw.805        thrownValue = yetAnotherThrownValue;806        if (workInProgress === erroredWork && erroredWork !== null) {807          // If this boundary has already errored, then we had trouble processing808          // the error. Bubble it to the next boundary.809          erroredWork = erroredWork.return;810          workInProgress = erroredWork;811        } else {812          erroredWork = workInProgress;813        }814        continue;815      } // Return to the normal work loop.816      return;817    } while (true);818  }819  function pushDispatcher() {820    var prevDispatcher = ReactCurrentDispatcher$2.current;821    ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;822    if (prevDispatcher === null) {823      // The React isomorphic package does not include a default dispatcher.824      // Instead the first renderer will lazily attach one, in order to give825      // nicer error messages.826      return ContextOnlyDispatcher;827    } else {828      return prevDispatcher;829    }830  }831  function popDispatcher(prevDispatcher) {832    ReactCurrentDispatcher$2.current = prevDispatcher;833  }834  function pushInteractions(root) {835    {836      var prevInteractions = __interactionsRef.current;837      __interactionsRef.current = root.memoizedInteractions;838      return prevInteractions;839    }840  }841  function popInteractions(prevInteractions) {842    {843      __interactionsRef.current = prevInteractions;844    }845  }846  function markCommitTimeOfFallback() {847    globalMostRecentFallbackTime = now();848  }849  function markSkippedUpdateLanes(lane) {850    workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);851  }852  function renderDidSuspend() {853    if (workInProgressRootExitStatus === RootIncomplete) {854      workInProgressRootExitStatus = RootSuspended;855    }856  }857  function renderDidSuspendDelayIfPossible() {858    if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {859      workInProgressRootExitStatus = RootSuspendedWithDelay;860    } // Check if there are updates that we skipped tree that might have unblocked861    // this render.862    if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootUpdatedLanes))) {863      // Mark the current render as suspended so that we switch to working on864      // the updates that were skipped. Usually we only suspend at the end of865      // the render phase.866      // TODO: We should probably always mark the root as suspended immediately867      // (inside this function), since by suspending at the end of the render868      // phase introduces a potential mistake where we suspend lanes that were869      // pinged or updated while we were rendering.870      markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);871    }872  }873  function renderDidError() {874    if (workInProgressRootExitStatus !== RootCompleted) {875      workInProgressRootExitStatus = RootErrored;876    }877  } // Called during render to determine if anything has suspended.878  // Returns false if we're not sure.879  function renderHasNotSuspendedYet() {880    // If something errored or completed, we can't really be sure,881    // so those are false.882    return workInProgressRootExitStatus === RootIncomplete;883  }884  function renderRootSync(root, lanes) {885    var prevExecutionContext = executionContext;886    executionContext |= RenderContext;887    var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack888    // and prepare a fresh one. Otherwise we'll continue where we left off.889    if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {890      prepareFreshStack(root, lanes);891      startWorkOnPendingInteractions(root, lanes);892    }893    var prevInteractions = pushInteractions(root);894    {895      markRenderStarted(lanes);896    }897    do {898      try {899        workLoopSync();900        break;901      } catch (thrownValue) {902        handleError(root, thrownValue);903      }904    } while (true);905    resetContextDependencies();906    {907      popInteractions(prevInteractions);908    }909    executionContext = prevExecutionContext;910    popDispatcher(prevDispatcher);911    if (workInProgress !== null) {912      // This is a sync render, so we should have finished the whole tree.913      {914        {915          throw Error( "Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue." );916        }917      }918    }919    {920      markRenderStopped();921    } // Set this to null to indicate there's no in-progress render.922    workInProgressRoot = null;923    workInProgressRootRenderLanes = NoLanes;924    return workInProgressRootExitStatus;925  } // The work loop is an extremely hot path. Tell Closure not to inline it.926  /** @noinline */927  function workLoopSync() {928    // Already timed out, so perform work without checking if we need to yield.929    while (workInProgress !== null) {930      performUnitOfWork(workInProgress);931    }932  }933  function renderRootConcurrent(root, lanes) {934    var prevExecutionContext = executionContext;935    executionContext |= RenderContext;936    var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack937    // and prepare a fresh one. Otherwise we'll continue where we left off.938    if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {939      resetRenderTimer();940      prepareFreshStack(root, lanes);941      startWorkOnPendingInteractions(root, lanes);942    }943    var prevInteractions = pushInteractions(root);944    {945      markRenderStarted(lanes);946    }947    do {948      try {949        workLoopConcurrent();950        break;951      } catch (thrownValue) {952        handleError(root, thrownValue);953      }954    } while (true);955    resetContextDependencies();956    {957      popInteractions(prevInteractions);958    }959    popDispatcher(prevDispatcher);960    executionContext = prevExecutionContext;961    if (workInProgress !== null) {962      // Still work remaining.963      {964        markRenderYielded();965      }966      return RootIncomplete;967    } else {968      // Completed the tree.969      {970        markRenderStopped();971      } // Set this to null to indicate there's no in-progress render.972      workInProgressRoot = null;973      workInProgressRootRenderLanes = NoLanes; // Return the final exit status.974      return workInProgressRootExitStatus;975    }976  }977  /** @noinline */978  function workLoopConcurrent() {979    // Perform work until Scheduler asks us to yield980    while (workInProgress !== null && !shouldYield()) {981      performUnitOfWork(workInProgress);982    }983  }984  function performUnitOfWork(unitOfWork) {985    // The current, flushed, state of this fiber is the alternate. Ideally986    // nothing should rely on this, but relying on it here means that we don't987    // need an additional field on the work in progress.988    var current = unitOfWork.alternate;989    setCurrentFiber(unitOfWork);990    var next;991    if ( (unitOfWork.mode & ProfileMode) !== NoMode) {992      startProfilerTimer(unitOfWork);993      next = beginWork$1(current, unitOfWork, subtreeRenderLanes);994      stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);995    } else {996      next = beginWork$1(current, unitOfWork, subtreeRenderLanes);997    }998    resetCurrentFiber();999    unitOfWork.memoizedProps = unitOfWork.pendingProps;1000    if (next === null) {1001      // If this doesn't spawn new work, complete the current work.1002      completeUnitOfWork(unitOfWork);1003    } else {1004      workInProgress = next;1005    }1006    ReactCurrentOwner$2.current = null;1007  }1008  function completeUnitOfWork(unitOfWork) {1009    // Attempt to complete the current unit of work, then move to the next1010    // sibling. If there are no more siblings, return to the parent fiber.1011    var completedWork = unitOfWork;1012    do {1013      // The current, flushed, state of this fiber is the alternate. Ideally1014      // nothing should rely on this, but relying on it here means that we don't1015      // need an additional field on the work in progress.1016      var current = completedWork.alternate;1017      var returnFiber = completedWork.return; // Check if the work completed or if something threw.1018      if ((completedWork.flags & Incomplete) === NoFlags) {1019        setCurrentFiber(completedWork);1020        var next = void 0;1021        if ( (completedWork.mode & ProfileMode) === NoMode) {1022          next = completeWork(current, completedWork, subtreeRenderLanes);1023        } else {1024          startProfilerTimer(completedWork);1025          next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.1026          stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);1027        }1028        resetCurrentFiber();1029        if (next !== null) {1030          // Completing this fiber spawned new work. Work on that next.1031          workInProgress = next;1032          return;1033        }1034        resetChildLanes(completedWork);1035        if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete1036        (returnFiber.flags & Incomplete) === NoFlags) {1037          // Append all the effects of the subtree and this fiber onto the effect1038          // list of the parent. The completion order of the children affects the1039          // side-effect order.1040          if (returnFiber.firstEffect === null) {1041            returnFiber.firstEffect = completedWork.firstEffect;1042          }1043          if (completedWork.lastEffect !== null) {1044            if (returnFiber.lastEffect !== null) {1045              returnFiber.lastEffect.nextEffect = completedWork.firstEffect;1046            }1047            returnFiber.lastEffect = completedWork.lastEffect;1048          } // If this fiber had side-effects, we append it AFTER the children's1049          // side-effects. We can perform certain side-effects earlier if needed,1050          // by doing multiple passes over the effect list. We don't want to1051          // schedule our own side-effect on our own list because if end up1052          // reusing children we'll schedule this effect onto itself since we're1053          // at the end.1054          var flags = completedWork.flags; // Skip both NoWork and PerformedWork tags when creating the effect1055          // list. PerformedWork effect is read by React DevTools but shouldn't be1056          // committed.1057          if (flags > PerformedWork) {1058            if (returnFiber.lastEffect !== null) {1059              returnFiber.lastEffect.nextEffect = completedWork;1060            } else {1061              returnFiber.firstEffect = completedWork;1062            }1063            returnFiber.lastEffect = completedWork;1064          }1065        }1066      } else {1067        // This fiber did not complete because something threw. Pop values off1068        // the stack without entering the complete phase. If this is a boundary,1069        // capture values if possible.1070        var _next = unwindWork(completedWork); // Because this fiber did not complete, don't reset its expiration time.1071        if (_next !== null) {1072          // If completing this work spawned new work, do that next. We'll come1073          // back here again.1074          // Since we're restarting, remove anything that is not a host effect1075          // from the effect tag.1076          _next.flags &= HostEffectMask;1077          workInProgress = _next;1078          return;1079        }1080        if ( (completedWork.mode & ProfileMode) !== NoMode) {1081          // Record the render duration for the fiber that errored.1082          stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.1083          var actualDuration = completedWork.actualDuration;1084          var child = completedWork.child;1085          while (child !== null) {1086            actualDuration += child.actualDuration;1087            child = child.sibling;1088          }1089          completedWork.actualDuration = actualDuration;1090        }1091        if (returnFiber !== null) {1092          // Mark the parent fiber as incomplete and clear its effect list.1093          returnFiber.firstEffect = returnFiber.lastEffect = null;1094          returnFiber.flags |= Incomplete;1095        }1096      }1097      var siblingFiber = completedWork.sibling;1098      if (siblingFiber !== null) {1099        // If there is more work to do in this returnFiber, do that next.1100        workInProgress = siblingFiber;1101        return;1102      } // Otherwise, return to the parent1103      completedWork = returnFiber; // Update the next thing we're working on in case something throws.1104      workInProgress = completedWork;1105    } while (completedWork !== null); // We've reached the root.1106    if (workInProgressRootExitStatus === RootIncomplete) {1107      workInProgressRootExitStatus = RootCompleted;1108    }1109  }1110  function resetChildLanes(completedWork) {1111    if ( // TODO: Move this check out of the hot path by moving `resetChildLanes`1112    // to switch statement in `completeWork`.1113    (completedWork.tag === LegacyHiddenComponent || completedWork.tag === OffscreenComponent) && completedWork.memoizedState !== null && !includesSomeLane(subtreeRenderLanes, OffscreenLane) && (completedWork.mode & ConcurrentMode) !== NoLanes) {1114      // The children of this component are hidden. Don't bubble their1115      // expiration times.1116      return;1117    }1118    var newChildLanes = NoLanes; // Bubble up the earliest expiration time.1119    if ( (completedWork.mode & ProfileMode) !== NoMode) {1120      // In profiling mode, resetChildExpirationTime is also used to reset1121      // profiler durations.1122      var actualDuration = completedWork.actualDuration;1123      var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will1124      // only be updated if work is done on the fiber (i.e. it doesn't bailout).1125      // When work is done, it should bubble to the parent's actualDuration. If1126      // the fiber has not been cloned though, (meaning no work was done), then1127      // this value will reflect the amount of time spent working on a previous1128      // render. In that case it should not bubble. We determine whether it was1129      // cloned by comparing the child pointer.1130      var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;1131      var child = completedWork.child;1132      while (child !== null) {1133        newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));1134        if (shouldBubbleActualDurations) {1135          actualDuration += child.actualDuration;1136        }1137        treeBaseDuration += child.treeBaseDuration;1138        child = child.sibling;1139      }1140      var isTimedOutSuspense = completedWork.tag === SuspenseComponent && completedWork.memoizedState !== null;1141      if (isTimedOutSuspense) {1142        // Don't count time spent in a timed out Suspense subtree as part of the base duration.1143        var primaryChildFragment = completedWork.child;1144        if (primaryChildFragment !== null) {1145          treeBaseDuration -= primaryChildFragment.treeBaseDuration;1146        }1147      }1148      completedWork.actualDuration = actualDuration;1149      completedWork.treeBaseDuration = treeBaseDuration;1150    } else {1151      var _child = completedWork.child;1152      while (_child !== null) {1153        newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));1154        _child = _child.sibling;1155      }1156    }1157    completedWork.childLanes = newChildLanes;1158  }1159  function commitRoot(root) {1160    var renderPriorityLevel = getCurrentPriorityLevel();1161    runWithPriority$1(ImmediatePriority$1, commitRootImpl.bind(null, root, renderPriorityLevel));1162    return null;1163  }1164  function commitRootImpl(root, renderPriorityLevel) {1165    do {1166      // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which1167      // means `flushPassiveEffects` will sometimes result in additional1168      // passive effects. So we need to keep flushing in a loop until there are1169      // no more pending effects.1170      // TODO: Might be better if `flushPassiveEffects` did not automatically1171      // flush synchronous work at the end, to avoid factoring hazards like this.1172      flushPassiveEffects();1173    } while (rootWithPendingPassiveEffects !== null);1174    flushRenderPhaseStrictModeWarningsInDEV();1175    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {1176      {1177        throw Error( "Should not already be working." );1178      }1179    }1180    var finishedWork = root.finishedWork;1181    var lanes = root.finishedLanes;1182    {1183      markCommitStarted(lanes);1184    }1185    if (finishedWork === null) {1186      {1187        markCommitStopped();1188      }1189      return null;1190    }1191    root.finishedWork = null;1192    root.finishedLanes = NoLanes;1193    if (!(finishedWork !== root.current)) {1194      {1195        throw Error( "Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue." );1196      }1197    } // commitRoot never returns a continuation; it always finishes synchronously.1198    // So we can clear these now to allow a new callback to be scheduled.1199    root.callbackNode = null; // Update the first and last pending times on this root. The new first1200    // pending time is whatever is left on the root fiber.1201    var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);1202    markRootFinished(root, remainingLanes); // Clear already finished discrete updates in case that a later call of1203    // `flushDiscreteUpdates` starts a useless render pass which may cancels1204    // a scheduled timeout.1205    if (rootsWithPendingDiscreteUpdates !== null) {1206      if (!hasDiscreteLanes(remainingLanes) && rootsWithPendingDiscreteUpdates.has(root)) {1207        rootsWithPendingDiscreteUpdates.delete(root);1208      }1209    }1210    if (root === workInProgressRoot) {1211      // We can reset these now that they are finished.1212      workInProgressRoot = null;1213      workInProgress = null;1214      workInProgressRootRenderLanes = NoLanes;1215    } // Get the list of effects.1216    var firstEffect;1217    if (finishedWork.flags > PerformedWork) {1218      // A fiber's effect list consists only of its children, not itself. So if1219      // the root has an effect, we need to add it to the end of the list. The1220      // resulting list is the set that would belong to the root's parent, if it1221      // had one; that is, all the effects in the tree including the root.1222      if (finishedWork.lastEffect !== null) {1223        finishedWork.lastEffect.nextEffect = finishedWork;1224        firstEffect = finishedWork.firstEffect;1225      } else {1226        firstEffect = finishedWork;1227      }1228    } else {1229      // There is no effect on the root.1230      firstEffect = finishedWork.firstEffect;1231    }1232    if (firstEffect !== null) {1233      var prevExecutionContext = executionContext;1234      executionContext |= CommitContext;1235      var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles1236      ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass1237      // of the effect list for each phase: all mutation effects come before all1238      // layout effects, and so on.1239      // The first phase a "before mutation" phase. We use this phase to read the1240      // state of the host tree right before we mutate it. This is where1241      // getSnapshotBeforeUpdate is called.1242      focusedInstanceHandle = prepareForCommit(root.containerInfo);1243      shouldFireAfterActiveInstanceBlur = false;1244      nextEffect = firstEffect;1245      do {1246        {1247          invokeGuardedCallback(null, commitBeforeMutationEffects, null);1248          if (hasCaughtError()) {1249            if (!(nextEffect !== null)) {1250              {1251                throw Error( "Should be working on an effect." );1252              }1253            }1254            var error = clearCaughtError();1255            captureCommitPhaseError(nextEffect, error);1256            nextEffect = nextEffect.nextEffect;1257          }1258        }1259      } while (nextEffect !== null); // We no longer need to track the active instance fiber1260      focusedInstanceHandle = null;1261      {1262        // Mark the current commit time to be shared by all Profilers in this1263        // batch. This enables them to be grouped later.1264        recordCommitTime();1265      } // The next phase is the mutation phase, where we mutate the host tree.1266      nextEffect = firstEffect;1267      do {1268        {1269          invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);1270          if (hasCaughtError()) {1271            if (!(nextEffect !== null)) {1272              {1273                throw Error( "Should be working on an effect." );1274              }1275            }1276            var _error = clearCaughtError();1277            captureCommitPhaseError(nextEffect, _error);1278            nextEffect = nextEffect.nextEffect;1279          }1280        }1281      } while (nextEffect !== null);1282      resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after1283      // the mutation phase, so that the previous tree is still current during1284      // componentWillUnmount, but before the layout phase, so that the finished1285      // work is current during componentDidMount/Update.1286      root.current = finishedWork; // The next phase is the layout phase, where we call effects that read1287      // the host tree after it's been mutated. The idiomatic use case for this is1288      // layout, but class component lifecycles also fire here for legacy reasons.1289      nextEffect = firstEffect;1290      do {1291        {1292          invokeGuardedCallback(null, commitLayoutEffects, null, root, lanes);1293          if (hasCaughtError()) {1294            if (!(nextEffect !== null)) {1295              {1296                throw Error( "Should be working on an effect." );1297              }1298            }1299            var _error2 = clearCaughtError();1300            captureCommitPhaseError(nextEffect, _error2);1301            nextEffect = nextEffect.nextEffect;1302          }1303        }1304      } while (nextEffect !== null);1305      nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an1306      // opportunity to paint.1307      requestPaint();1308      {1309        popInteractions(prevInteractions);1310      }1311      executionContext = prevExecutionContext;1312    } else {1313      // No effects.1314      root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were1315      // no effects.1316      // TODO: Maybe there's a better way to report this.1317      {1318        recordCommitTime();1319      }1320    }1321    var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;1322    if (rootDoesHavePassiveEffects) {1323      // This commit has passive effects. Stash a reference to them. But don't1324      // schedule a callback until after flushing layout work.1325      rootDoesHavePassiveEffects = false;1326      rootWithPendingPassiveEffects = root;1327      pendingPassiveEffectsLanes = lanes;1328      pendingPassiveEffectsRenderPriority = renderPriorityLevel;1329    } else {1330      // We are done with the effect chain at this point so let's clear the1331      // nextEffect pointers to assist with GC. If we have passive effects, we'll1332      // clear this in flushPassiveEffects.1333      nextEffect = firstEffect;1334      while (nextEffect !== null) {1335        var nextNextEffect = nextEffect.nextEffect;1336        nextEffect.nextEffect = null;1337        if (nextEffect.flags & Deletion) {1338          detachFiberAfterEffects(nextEffect);1339        }1340        nextEffect = nextNextEffect;1341      }1342    } // Read this again, since an effect might have updated it1343    remainingLanes = root.pendingLanes; // Check if there's remaining work on this root1344    if (remainingLanes !== NoLanes) {1345      {1346        if (spawnedWorkDuringRender !== null) {1347          var expirationTimes = spawnedWorkDuringRender;1348          spawnedWorkDuringRender = null;1349          for (var i = 0; i < expirationTimes.length; i++) {1350            scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);1351          }1352        }1353        schedulePendingInteractions(root, remainingLanes);1354      }1355    } else {1356      // If there's no remaining work, we can clear the set of already failed1357      // error boundaries.1358      legacyErrorBoundariesThatAlreadyFailed = null;1359    }1360    {1361      if (!rootDidHavePassiveEffects) {1362        // If there are no passive effects, then we can complete the pending interactions.1363        // Otherwise, we'll wait until after the passive effects are flushed.1364        // Wait to do this until after remaining work has been scheduled,1365        // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.1366        finishPendingInteractions(root, lanes);1367      }1368    }1369    if (remainingLanes === SyncLane) {1370      // Count the number of times the root synchronously re-renders without1371      // finishing. If there are too many, it indicates an infinite update loop.1372      if (root === rootWithNestedUpdates) {1373        nestedUpdateCount++;1374      } else {1375        nestedUpdateCount = 0;1376        rootWithNestedUpdates = root;1377      }1378    } else {1379      nestedUpdateCount = 0;1380    }1381    onCommitRoot(finishedWork.stateNode, renderPriorityLevel);1382    {1383      onCommitRoot$1();1384    } // Always call this before exiting `commitRoot`, to ensure that any1385    // additional work on this root is scheduled.1386    ensureRootIsScheduled(root, now());1387    if (hasUncaughtError) {1388      hasUncaughtError = false;1389      var _error3 = firstUncaughtError;1390      firstUncaughtError = null;1391      throw _error3;1392    }1393    if ((executionContext & LegacyUnbatchedContext) !== NoContext) {1394      {1395        markCommitStopped();1396      } // This is a legacy edge case. We just committed the initial mount of1397      // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired1398      // synchronously, but layout updates should be deferred until the end1399      // of the batch.1400      return null;1401    } // If layout work was scheduled, flush it now.1402    flushSyncCallbackQueue();1403    {1404      markCommitStopped();1405    }1406    return null;1407  }1408  function commitBeforeMutationEffects() {1409    while (nextEffect !== null) {1410      var current = nextEffect.alternate;1411      if (!shouldFireAfterActiveInstanceBlur && focusedInstanceHandle !== null) {1412        if ((nextEffect.flags & Deletion) !== NoFlags) {1413          if (doesFiberContain(nextEffect, focusedInstanceHandle)) {1414            shouldFireAfterActiveInstanceBlur = true;1415          }1416        } else {1417          // TODO: Move this out of the hot path using a dedicated effect tag.1418          if (nextEffect.tag === SuspenseComponent && isSuspenseBoundaryBeingHidden(current, nextEffect) && doesFiberContain(nextEffect, focusedInstanceHandle)) {1419            shouldFireAfterActiveInstanceBlur = true;1420          }1421        }1422      }1423      var flags = nextEffect.flags;1424      if ((flags & Snapshot) !== NoFlags) {1425        setCurrentFiber(nextEffect);1426        commitBeforeMutationLifeCycles(current, nextEffect);1427        resetCurrentFiber();1428      }1429      if ((flags & Passive) !== NoFlags) {1430        // If there are passive effects, schedule a callback to flush at1431        // the earliest opportunity.1432        if (!rootDoesHavePassiveEffects) {1433          rootDoesHavePassiveEffects = true;1434          scheduleCallback(NormalPriority$1, function () {1435            flushPassiveEffects();1436            return null;1437          });1438        }1439      }1440      nextEffect = nextEffect.nextEffect;1441    }1442  }1443  function commitMutationEffects(root, renderPriorityLevel) {1444    // TODO: Should probably move the bulk of this function to commitWork.1445    while (nextEffect !== null) {1446      setCurrentFiber(nextEffect);1447      var flags = nextEffect.flags;1448      if (flags & ContentReset) {1449        commitResetTextContent(nextEffect);1450      }1451      if (flags & Ref) {1452        var current = nextEffect.alternate;1453        if (current !== null) {1454          commitDetachRef(current);1455        }1456      } // The following switch statement is only concerned about placement,1457      // updates, and deletions. To avoid needing to add a case for every possible1458      // bitmap value, we remove the secondary effects from the effect tag and1459      // switch on that value.1460      var primaryFlags = flags & (Placement | Update | Deletion | Hydrating);1461      switch (primaryFlags) {1462        case Placement:1463          {1464            commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is1465            // inserted, before any life-cycles like componentDidMount gets called.1466            // TODO: findDOMNode doesn't rely on this any more but isMounted does1467            // and isMounted is deprecated anyway so we should be able to kill this.1468            nextEffect.flags &= ~Placement;1469            break;1470          }1471        case PlacementAndUpdate:1472          {1473            // Placement1474            commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is1475            // inserted, before any life-cycles like componentDidMount gets called.1476            nextEffect.flags &= ~Placement; // Update1477            var _current = nextEffect.alternate;1478            commitWork(_current, nextEffect);1479            break;1480          }1481        case Hydrating:1482          {1483            nextEffect.flags &= ~Hydrating;1484            break;1485          }1486        case HydratingAndUpdate:1487          {1488            nextEffect.flags &= ~Hydrating; // Update1489            var _current2 = nextEffect.alternate;1490            commitWork(_current2, nextEffect);1491            break;1492          }1493        case Update:1494          {1495            var _current3 = nextEffect.alternate;1496            commitWork(_current3, nextEffect);1497            break;1498          }1499        case Deletion:1500          {1501            commitDeletion(root, nextEffect);1502            break;1503          }1504      }1505      resetCurrentFiber();1506      nextEffect = nextEffect.nextEffect;1507    }1508  }1509  function commitLayoutEffects(root, committedLanes) {1510    {1511      markLayoutEffectsStarted(committedLanes);1512    } // TODO: Should probably move the bulk of this function to commitWork.1513    while (nextEffect !== null) {1514      setCurrentFiber(nextEffect);1515      var flags = nextEffect.flags;1516      if (flags & (Update | Callback)) {1517        var current = nextEffect.alternate;1518        commitLifeCycles(root, current, nextEffect);1519      }1520      {1521        if (flags & Ref) {1522          commitAttachRef(nextEffect);1523        }1524      }1525      resetCurrentFiber();1526      nextEffect = nextEffect.nextEffect;1527    }1528    {1529      markLayoutEffectsStopped();1530    }1531  }1532  function flushPassiveEffects() {1533    // Returns whether passive effects were flushed.1534    if (pendingPassiveEffectsRenderPriority !== NoPriority$1) {1535      var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority$1 ? NormalPriority$1 : pendingPassiveEffectsRenderPriority;1536      pendingPassiveEffectsRenderPriority = NoPriority$1;1537      {1538        return runWithPriority$1(priorityLevel, flushPassiveEffectsImpl);1539      }1540    }1541    return false;1542  }1543  function enqueuePendingPassiveHookEffectMount(fiber, effect) {1544    pendingPassiveHookEffectsMount.push(effect, fiber);1545    if (!rootDoesHavePassiveEffects) {1546      rootDoesHavePassiveEffects = true;1547      scheduleCallback(NormalPriority$1, function () {1548        flushPassiveEffects();1549        return null;1550      });1551    }1552  }1553  function enqueuePendingPassiveHookEffectUnmount(fiber, effect) {1554    pendingPassiveHookEffectsUnmount.push(effect, fiber);1555    {1556      fiber.flags |= PassiveUnmountPendingDev;1557      var alternate = fiber.alternate;1558      if (alternate !== null) {1559        alternate.flags |= PassiveUnmountPendingDev;1560      }1561    }1562    if (!rootDoesHavePassiveEffects) {1563      rootDoesHavePassiveEffects = true;1564      scheduleCallback(NormalPriority$1, function () {1565        flushPassiveEffects();1566        return null;1567      });1568    }1569  }1570  function invokePassiveEffectCreate(effect) {1571    var create = effect.create;1572    effect.destroy = create();1573  }1574  function flushPassiveEffectsImpl() {1575    if (rootWithPendingPassiveEffects === null) {1576      return false;1577    }1578    var root = rootWithPendingPassiveEffects;1579    var lanes = pendingPassiveEffectsLanes;1580    rootWithPendingPassiveEffects = null;1581    pendingPassiveEffectsLanes = NoLanes;1582    if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {1583      {1584        throw Error( "Cannot flush passive effects while already rendering." );1585      }1586    }1587    {1588      markPassiveEffectsStarted(lanes);1589    }1590    {1591      isFlushingPassiveEffects = true;1592    }1593    var prevExecutionContext = executionContext;1594    executionContext |= CommitContext;1595    var prevInteractions = pushInteractions(root); // It's important that ALL pending passive effect destroy functions are called1596    // before ANY passive effect create functions are called.1597    // Otherwise effects in sibling components might interfere with each other.1598    // e.g. a destroy function in one component may unintentionally override a ref1599    // value set by a create function in another component.1600    // Layout effects have the same constraint.1601    // First pass: Destroy stale passive effects.1602    var unmountEffects = pendingPassiveHookEffectsUnmount;1603    pendingPassiveHookEffectsUnmount = [];1604    for (var i = 0; i < unmountEffects.length; i += 2) {1605      var _effect = unmountEffects[i];1606      var fiber = unmountEffects[i + 1];1607      var destroy = _effect.destroy;1608      _effect.destroy = undefined;1609      {1610        fiber.flags &= ~PassiveUnmountPendingDev;1611        var alternate = fiber.alternate;1612        if (alternate !== null) {1613          alternate.flags &= ~PassiveUnmountPendingDev;1614        }1615      }1616      if (typeof destroy === 'function') {1617        {1618          setCurrentFiber(fiber);1619          {1620            invokeGuardedCallback(null, destroy, null);1621          }1622          if (hasCaughtError()) {1623            if (!(fiber !== null)) {1624              {1625                throw Error( "Should be working on an effect." );1626              }1627            }1628            var error = clearCaughtError();1629            captureCommitPhaseError(fiber, error);1630          }1631          resetCurrentFiber();1632        }1633      }1634    } // Second pass: Create new passive effects.1635    var mountEffects = pendingPassiveHookEffectsMount;1636    pendingPassiveHookEffectsMount = [];1637    for (var _i = 0; _i < mountEffects.length; _i += 2) {1638      var _effect2 = mountEffects[_i];1639      var _fiber = mountEffects[_i + 1];1640      {1641        setCurrentFiber(_fiber);1642        {1643          invokeGuardedCallback(null, invokePassiveEffectCreate, null, _effect2);1644        }1645        if (hasCaughtError()) {1646          if (!(_fiber !== null)) {1647            {1648              throw Error( "Should be working on an effect." );1649            }1650          }1651          var _error4 = clearCaughtError();1652          captureCommitPhaseError(_fiber, _error4);1653        }1654        resetCurrentFiber();1655      }1656    } // Note: This currently assumes there are no passive effects on the root fiber1657    // because the root is not part of its own effect list.1658    // This could change in the future.1659    var effect = root.current.firstEffect;1660    while (effect !== null) {1661      var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC1662      effect.nextEffect = null;1663      if (effect.flags & Deletion) {1664        detachFiberAfterEffects(effect);1665      }1666      effect = nextNextEffect;1667    }1668    {1669      popInteractions(prevInteractions);1670      finishPendingInteractions(root, lanes);1671    }1672    {1673      isFlushingPassiveEffects = false;1674    }1675    {1676      markPassiveEffectsStopped();1677    }1678    executionContext = prevExecutionContext;1679    flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this1680    // exceeds the limit, we'll fire a warning.1681    nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1682    return true;1683  }1684  function isAlreadyFailedLegacyErrorBoundary(instance) {1685    return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);1686  }1687  function markLegacyErrorBoundaryAsFailed(instance) {1688    if (legacyErrorBoundariesThatAlreadyFailed === null) {1689      legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1690    } else {1691      legacyErrorBoundariesThatAlreadyFailed.add(instance);1692    }1693  }1694  function prepareToThrowUncaughtError(error) {1695    if (!hasUncaughtError) {1696      hasUncaughtError = true;1697      firstUncaughtError = error;1698    }1699  }1700  var onUncaughtError = prepareToThrowUncaughtError;1701  function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {1702    var errorInfo = createCapturedValue(error, sourceFiber);1703    var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);1704    enqueueUpdate(rootFiber, update);1705    var eventTime = requestEventTime();1706    var root = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane);1707    if (root !== null) {1708      markRootUpdated(root, SyncLane, eventTime);1709      ensureRootIsScheduled(root, eventTime);1710      schedulePendingInteractions(root, SyncLane);1711    }1712  }1713  function captureCommitPhaseError(sourceFiber, error) {1714    if (sourceFiber.tag === HostRoot) {1715      // Error was thrown at the root. There is no parent, so the root1716      // itself should capture it.1717      captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1718      return;1719    }1720    var fiber = sourceFiber.return;1721    while (fiber !== null) {1722      if (fiber.tag === HostRoot) {1723        captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1724        return;1725      } else if (fiber.tag === ClassComponent) {1726        var ctor = fiber.type;1727        var instance = fiber.stateNode;1728        if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {1729          var errorInfo = createCapturedValue(error, sourceFiber);1730          var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);1731          enqueueUpdate(fiber, update);1732          var eventTime = requestEventTime();1733          var root = markUpdateLaneFromFiberToRoot(fiber, SyncLane);1734          if (root !== null) {1735            markRootUpdated(root, SyncLane, eventTime);1736            ensureRootIsScheduled(root, eventTime);1737            schedulePendingInteractions(root, SyncLane);1738          } else {1739            // This component has already been unmounted.1740            // We can't schedule any follow up work for the root because the fiber is already unmounted,1741            // but we can still call the log-only boundary so the error isn't swallowed.1742            //1743            // TODO This is only a temporary bandaid for the old reconciler fork.1744            // We can delete this special case once the new fork is merged.1745            if (typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {1746              try {1747                instance.componentDidCatch(error, errorInfo);1748              } catch (errorToIgnore) {// TODO Ignore this error? Rethrow it?1749                // This is kind of an edge case.1750              }1751            }1752          }1753          return;1754        }1755      }1756      fiber = fiber.return;1757    }1758  }1759  function pingSuspendedRoot(root, wakeable, pingedLanes) {1760    var pingCache = root.pingCache;1761    if (pingCache !== null) {1762      // The wakeable resolved, so we no longer need to memoize, because it will1763      // never be thrown again.1764      pingCache.delete(wakeable);1765    }1766    var eventTime = requestEventTime();1767    markRootPinged(root, pingedLanes);1768    if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {1769      // Received a ping at the same priority level at which we're currently1770      // rendering. We might want to restart this render. This should mirror1771      // the logic of whether or not a root suspends once it completes.1772      // TODO: If we're rendering sync either due to Sync, Batched or expired,1773      // we should probably never restart.1774      // If we're suspended with delay, or if it's a retry, we'll always suspend1775      // so we can always restart.1776      if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {1777        // Restart from the root.1778        prepareFreshStack(root, NoLanes);1779      } else {1780        // Even though we can't restart right now, we might get an1781        // opportunity later. So we mark this render as having a ping.1782        workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);1783      }1784    }1785    ensureRootIsScheduled(root, eventTime);1786    schedulePendingInteractions(root, pingedLanes);1787  }1788  function retryTimedOutBoundary(boundaryFiber, retryLane) {1789    // The boundary fiber (a Suspense component or SuspenseList component)1790    // previously was rendered in its fallback state. One of the promises that1791    // suspended it has resolved, which means at least part of the tree was1792    // likely unblocked. Try rendering again, at a new expiration time.1793    if (retryLane === NoLane) {1794      retryLane = requestRetryLane(boundaryFiber);1795    } // TODO: Special case idle priority?1796    var eventTime = requestEventTime();1797    var root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);1798    if (root !== null) {1799      markRootUpdated(root, retryLane, eventTime);1800      ensureRootIsScheduled(root, eventTime);1801      schedulePendingInteractions(root, retryLane);1802    }1803  }1804  function retryDehydratedSuspenseBoundary(boundaryFiber) {1805    var suspenseState = boundaryFiber.memoizedState;1806    var retryLane = NoLane;1807    if (suspenseState !== null) {1808      retryLane = suspenseState.retryLane;...ReactFiberWorkLoop.new.js
Source:ReactFiberWorkLoop.new.js  
...386  // TODO: Move this type conversion to the event priority module.387  const eventLane: Lane = (getCurrentEventPriority(): any);388  return eventLane;389}390function requestRetryLane(fiber: Fiber) {391  // This is a fork of `requestUpdateLane` designed specifically for Suspense392  // "retries" â a special update that attempts to flip a Suspense boundary393  // from its placeholder state to its primary/resolved state.394  // Special cases395  const mode = fiber.mode;396  if ((mode & ConcurrentMode) === NoMode) {397    return (SyncLane: Lane);398  }399  return claimNextRetryLane();400}401export function scheduleUpdateOnFiber(402  fiber: Fiber,403  lane: Lane,404  eventTime: number,405): FiberRoot | null {406  checkForNestedUpdates();407  warnAboutRenderPhaseUpdatesInDEV(fiber);408  const root = markUpdateLaneFromFiberToRoot(fiber, lane);409  if (root === null) {410    return null;411  }412  if (enableUpdaterTracking) {413    if (isDevToolsPresent) {414      addFiberToLanesMap(root, fiber, lane);415    }416  }417  // Mark that the root has a pending update.418  markRootUpdated(root, lane, eventTime);419  if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {420    if (421      (executionContext & CommitContext) !== NoContext &&422      root === rootCommittingMutationOrLayoutEffects423    ) {424      if (fiber.mode & ProfileMode) {425        let current = fiber;426        while (current !== null) {427          if (current.tag === Profiler) {428            const {id, onNestedUpdateScheduled} = current.memoizedProps;429            if (typeof onNestedUpdateScheduled === 'function') {430              onNestedUpdateScheduled(id);431            }432          }433          current = current.return;434        }435      }436    }437  }438  // TODO: Consolidate with `isInterleavedUpdate` check439  if (root === workInProgressRoot) {440    // Received an update to a tree that's in the middle of rendering. Mark441    // that there was an interleaved update work on this root. Unless the442    // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render443    // phase update. In that case, we don't treat render phase updates as if444    // they were interleaved, for backwards compat reasons.445    if (446      deferRenderPhaseUpdateToNextBatch ||447      (executionContext & RenderContext) === NoContext448    ) {449      workInProgressRootUpdatedLanes = mergeLanes(450        workInProgressRootUpdatedLanes,451        lane,452      );453    }454    if (workInProgressRootExitStatus === RootSuspendedWithDelay) {455      // The root already suspended with a delay, which means this render456      // definitely won't finish. Since we have a new update, let's mark it as457      // suspended now, right before marking the incoming update. This has the458      // effect of interrupting the current render and switching to the update.459      // TODO: Make sure this doesn't override pings that happen while we've460      // already started rendering.461      markRootSuspended(root, workInProgressRootRenderLanes);462    }463  }464  ensureRootIsScheduled(root, eventTime);465  if (466    lane === SyncLane &&467    executionContext === NoContext &&468    (fiber.mode & ConcurrentMode) === NoMode &&469    // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.470    !(__DEV__ && ReactCurrentActQueue.isBatchingLegacy)471  ) {472    // Flush the synchronous work now, unless we're already working or inside473    // a batch. This is intentionally inside scheduleUpdateOnFiber instead of474    // scheduleCallbackForFiber to preserve the ability to schedule a callback475    // without immediately flushing it. We only do this for user-initiated476    // updates, to preserve historical behavior of legacy mode.477    resetRenderTimer();478    flushSyncCallbacksOnlyInLegacyMode();479  }480  return root;481}482// This is split into a separate function so we can mark a fiber with pending483// work without treating it as a typical update that originates from an event;484// e.g. retrying a Suspense boundary isn't an update, but it does schedule work485// on a fiber.486function markUpdateLaneFromFiberToRoot(487  sourceFiber: Fiber,488  lane: Lane,489): FiberRoot | null {490  // Update the source fiber's lanes491  sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);492  let alternate = sourceFiber.alternate;493  if (alternate !== null) {494    alternate.lanes = mergeLanes(alternate.lanes, lane);495  }496  if (__DEV__) {497    if (498      alternate === null &&499      (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags500    ) {501      warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);502    }503  }504  // Walk the parent path to the root and update the child lanes.505  let node = sourceFiber;506  let parent = sourceFiber.return;507  while (parent !== null) {508    parent.childLanes = mergeLanes(parent.childLanes, lane);509    alternate = parent.alternate;510    if (alternate !== null) {511      alternate.childLanes = mergeLanes(alternate.childLanes, lane);512    } else {513      if (__DEV__) {514        if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {515          warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);516        }517      }518    }519    node = parent;520    parent = parent.return;521  }522  if (node.tag === HostRoot) {523    const root: FiberRoot = node.stateNode;524    return root;525  } else {526    return null;527  }528}529export function isInterleavedUpdate(fiber: Fiber, lane: Lane) {530  return (531    // TODO: Optimize slightly by comparing to root that fiber belongs to.532    // Requires some refactoring. Not a big deal though since it's rare for533    // concurrent apps to have more than a single root.534    workInProgressRoot !== null &&535    (fiber.mode & ConcurrentMode) !== NoMode &&536    // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps),537    // then don't treat this as an interleaved update. This pattern is538    // accompanied by a warning but we haven't fully deprecated it yet. We can539    // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled.540    (deferRenderPhaseUpdateToNextBatch ||541      (executionContext & RenderContext) === NoContext)542  );543}544// Use this function to schedule a task for a root. There's only one task per545// root; if a task was already scheduled, we'll check to make sure the priority546// of the existing task is the same as the priority of the next level that the547// root has work on. This function is called on every update, and right before548// exiting a task.549function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {550  const existingCallbackNode = root.callbackNode;551  // Check if any lanes are being starved by other work. If so, mark them as552  // expired so we know to work on those next.553  markStarvedLanesAsExpired(root, currentTime);554  // Determine the next lanes to work on, and their priority.555  const nextLanes = getNextLanes(556    root,557    root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,558  );559  if (nextLanes === NoLanes) {560    // Special case: There's nothing to work on.561    if (existingCallbackNode !== null) {562      cancelCallback(existingCallbackNode);563    }564    root.callbackNode = null;565    root.callbackPriority = NoLane;566    return;567  }568  // We use the highest priority lane to represent the priority of the callback.569  const newCallbackPriority = getHighestPriorityLane(nextLanes);570  // Check if there's an existing task. We may be able to reuse it.571  const existingCallbackPriority = root.callbackPriority;572  if (573    existingCallbackPriority === newCallbackPriority &&574    // Special case related to `act`. If the currently scheduled task is a575    // Scheduler task, rather than an `act` task, cancel it and re-scheduled576    // on the `act` queue.577    !(578      __DEV__ &&579      ReactCurrentActQueue.current !== null &&580      existingCallbackNode !== fakeActCallbackNode581    )582  ) {583    if (__DEV__) {584      // If we're going to re-use an existing task, it needs to exist.585      // Assume that discrete update microtasks are non-cancellable and null.586      // TODO: Temporary until we confirm this warning is not fired.587      if (588        existingCallbackNode == null &&589        existingCallbackPriority !== SyncLane590      ) {591        console.error(592          'Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.',593        );594      }595    }596    // The priority hasn't changed. We can reuse the existing task. Exit.597    return;598  }599  if (existingCallbackNode != null) {600    // Cancel the existing callback. We'll schedule a new one below.601    cancelCallback(existingCallbackNode);602  }603  // Schedule a new callback.604  let newCallbackNode;605  if (newCallbackPriority === SyncLane) {606    // Special case: Sync React callbacks are scheduled on a special607    // internal queue608    if (root.tag === LegacyRoot) {609      if (__DEV__ && ReactCurrentActQueue.isBatchingLegacy !== null) {610        ReactCurrentActQueue.didScheduleLegacyUpdate = true;611      }612      scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));613    } else {614      scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));615    }616    if (supportsMicrotasks) {617      // Flush the queue in a microtask.618      if (__DEV__ && ReactCurrentActQueue.current !== null) {619        // Inside `act`, use our internal `act` queue so that these get flushed620        // at the end of the current scope even when using the sync version621        // of `act`.622        ReactCurrentActQueue.current.push(flushSyncCallbacks);623      } else {624        scheduleMicrotask(flushSyncCallbacks);625      }626    } else {627      // Flush the queue in an Immediate task.628      scheduleCallback(ImmediateSchedulerPriority, flushSyncCallbacks);629    }630    newCallbackNode = null;631  } else {632    let schedulerPriorityLevel;633    switch (lanesToEventPriority(nextLanes)) {634      case DiscreteEventPriority:635        schedulerPriorityLevel = ImmediateSchedulerPriority;636        break;637      case ContinuousEventPriority:638        schedulerPriorityLevel = UserBlockingSchedulerPriority;639        break;640      case DefaultEventPriority:641        schedulerPriorityLevel = NormalSchedulerPriority;642        break;643      case IdleEventPriority:644        schedulerPriorityLevel = IdleSchedulerPriority;645        break;646      default:647        schedulerPriorityLevel = NormalSchedulerPriority;648        break;649    }650    newCallbackNode = scheduleCallback(651      schedulerPriorityLevel,652      performConcurrentWorkOnRoot.bind(null, root),653    );654  }655  root.callbackPriority = newCallbackPriority;656  root.callbackNode = newCallbackNode;657}658// This is the entry point for every concurrent task, i.e. anything that659// goes through Scheduler.660function performConcurrentWorkOnRoot(root, didTimeout) {661  if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {662    resetNestedUpdateFlag();663  }664  // Since we know we're in a React event, we can clear the current665  // event time. The next update will compute a new event time.666  currentEventTime = NoTimestamp;667  currentEventTransitionLane = NoLanes;668  invariant(669    (executionContext & (RenderContext | CommitContext)) === NoContext,670    'Should not already be working.',671  );672  // Flush any pending passive effects before deciding which lanes to work on,673  // in case they schedule additional work.674  const originalCallbackNode = root.callbackNode;675  const didFlushPassiveEffects = flushPassiveEffects();676  if (didFlushPassiveEffects) {677    // Something in the passive effect phase may have canceled the current task.678    // Check if the task node for this root was changed.679    if (root.callbackNode !== originalCallbackNode) {680      // The current task was canceled. Exit. We don't need to call681      // `ensureRootIsScheduled` because the check above implies either that682      // there's a new task, or that there's no remaining work on this root.683      return null;684    } else {685      // Current task was not canceled. Continue.686    }687  }688  // Determine the next lanes to work on, using the fields stored689  // on the root.690  let lanes = getNextLanes(691    root,692    root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes,693  );694  if (lanes === NoLanes) {695    // Defensive coding. This is never expected to happen.696    return null;697  }698  // We disable time-slicing in some cases: if the work has been CPU-bound699  // for too long ("expired" work, to prevent starvation), or we're in700  // sync-updates-by-default mode.701  // TODO: We only check `didTimeout` defensively, to account for a Scheduler702  // bug we're still investigating. Once the bug in Scheduler is fixed,703  // we can remove this, since we track expiration ourselves.704  let exitStatus =705    shouldTimeSlice(root, lanes) &&706    (disableSchedulerTimeoutInWorkLoop || !didTimeout)707      ? renderRootConcurrent(root, lanes)708      : renderRootSync(root, lanes);709  if (exitStatus !== RootIncomplete) {710    if (exitStatus === RootErrored) {711      const prevExecutionContext = executionContext;712      executionContext |= RetryAfterError;713      // If an error occurred during hydration,714      // discard server response and fall back to client side render.715      if (root.hydrate) {716        root.hydrate = false;717        if (__DEV__) {718          errorHydratingContainer(root.containerInfo);719        }720        clearContainer(root.containerInfo);721      }722      // If something threw an error, try rendering one more time. We'll render723      // synchronously to block concurrent data mutations, and we'll includes724      // all pending updates are included. If it still fails after the second725      // attempt, we'll give up and commit the resulting tree.726      const errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);727      if (errorRetryLanes !== NoLanes) {728        lanes = errorRetryLanes;729        exitStatus = renderRootSync(root, errorRetryLanes);730      }731      executionContext = prevExecutionContext;732    }733    if (exitStatus === RootFatalErrored) {734      const fatalError = workInProgressRootFatalError;735      prepareFreshStack(root, NoLanes);736      markRootSuspended(root, lanes);737      ensureRootIsScheduled(root, now());738      throw fatalError;739    }740    // We now have a consistent tree. The next step is either to commit it,741    // or, if something suspended, wait to commit it after a timeout.742    const finishedWork: Fiber = (root.current.alternate: any);743    root.finishedWork = finishedWork;744    root.finishedLanes = lanes;745    finishConcurrentRender(root, exitStatus, lanes);746  }747  ensureRootIsScheduled(root, now());748  if (root.callbackNode === originalCallbackNode) {749    // The task node scheduled for this root is the same one that's750    // currently executed. Need to return a continuation.751    return performConcurrentWorkOnRoot.bind(null, root);752  }753  return null;754}755function finishConcurrentRender(root, exitStatus, lanes) {756  switch (exitStatus) {757    case RootIncomplete:758    case RootFatalErrored: {759      invariant(false, 'Root did not complete. This is a bug in React.');760    }761    // Flow knows about invariant, so it complains if I add a break762    // statement, but eslint doesn't know about invariant, so it complains763    // if I do. eslint-disable-next-line no-fallthrough764    case RootErrored: {765      // We should have already attempted to retry this tree. If we reached766      // this point, it errored again. Commit it.767      commitRoot(root);768      break;769    }770    case RootSuspended: {771      markRootSuspended(root, lanes);772      // We have an acceptable loading state. We need to figure out if we773      // should immediately commit it or wait a bit.774      if (775        includesOnlyRetries(lanes) &&776        // do not delay if we're inside an act() scope777        !shouldForceFlushFallbacksInDEV()778      ) {779        // This render only included retries, no updates. Throttle committing780        // retries so that we don't show too many loading states too quickly.781        const msUntilTimeout =782          globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now();783        // Don't bother with a very short suspense time.784        if (msUntilTimeout > 10) {785          const nextLanes = getNextLanes(root, NoLanes);786          if (nextLanes !== NoLanes) {787            // There's additional work on this root.788            break;789          }790          const suspendedLanes = root.suspendedLanes;791          if (!isSubsetOfLanes(suspendedLanes, lanes)) {792            // We should prefer to render the fallback of at the last793            // suspended level. Ping the last suspended level to try794            // rendering it again.795            // FIXME: What if the suspended lanes are Idle? Should not restart.796            const eventTime = requestEventTime();797            markRootPinged(root, suspendedLanes, eventTime);798            break;799          }800          // The render is suspended, it hasn't timed out, and there's no801          // lower priority work to do. Instead of committing the fallback802          // immediately, wait for more data to arrive.803          root.timeoutHandle = scheduleTimeout(804            commitRoot.bind(null, root),805            msUntilTimeout,806          );807          break;808        }809      }810      // The work expired. Commit immediately.811      commitRoot(root);812      break;813    }814    case RootSuspendedWithDelay: {815      markRootSuspended(root, lanes);816      if (includesOnlyTransitions(lanes)) {817        // This is a transition, so we should exit without committing a818        // placeholder and without scheduling a timeout. Delay indefinitely819        // until we receive more data.820        break;821      }822      if (!shouldForceFlushFallbacksInDEV()) {823        // This is not a transition, but we did trigger an avoided state.824        // Schedule a placeholder to display after a short delay, using the Just825        // Noticeable Difference.826        // TODO: Is the JND optimization worth the added complexity? If this is827        // the only reason we track the event time, then probably not.828        // Consider removing.829        const mostRecentEventTime = getMostRecentEventTime(root, lanes);830        const eventTimeMs = mostRecentEventTime;831        const timeElapsedMs = now() - eventTimeMs;832        const msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs;833        // Don't bother with a very short suspense time.834        if (msUntilTimeout > 10) {835          // Instead of committing the fallback immediately, wait for more data836          // to arrive.837          root.timeoutHandle = scheduleTimeout(838            commitRoot.bind(null, root),839            msUntilTimeout,840          );841          break;842        }843      }844      // Commit the placeholder.845      commitRoot(root);846      break;847    }848    case RootCompleted: {849      // The work completed. Ready to commit.850      commitRoot(root);851      break;852    }853    default: {854      invariant(false, 'Unknown root exit status.');855    }856  }857}858function markRootSuspended(root, suspendedLanes) {859  // When suspending, we should always exclude lanes that were pinged or (more860  // rarely, since we try to avoid it) updated during the render phase.861  // TODO: Lol maybe there's a better way to factor this besides this862  // obnoxiously named function :)863  suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);864  suspendedLanes = removeLanes(suspendedLanes, workInProgressRootUpdatedLanes);865  markRootSuspended_dontCallThisOneDirectly(root, suspendedLanes);866}867// This is the entry point for synchronous tasks that don't go868// through Scheduler869function performSyncWorkOnRoot(root) {870  if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {871    syncNestedUpdateFlag();872  }873  invariant(874    (executionContext & (RenderContext | CommitContext)) === NoContext,875    'Should not already be working.',876  );877  flushPassiveEffects();878  let lanes = getNextLanes(root, NoLanes);879  if (!includesSomeLane(lanes, SyncLane)) {880    // There's no remaining sync work left.881    ensureRootIsScheduled(root, now());882    return null;883  }884  let exitStatus = renderRootSync(root, lanes);885  if (root.tag !== LegacyRoot && exitStatus === RootErrored) {886    const prevExecutionContext = executionContext;887    executionContext |= RetryAfterError;888    // If an error occurred during hydration,889    // discard server response and fall back to client side render.890    if (root.hydrate) {891      root.hydrate = false;892      if (__DEV__) {893        errorHydratingContainer(root.containerInfo);894      }895      clearContainer(root.containerInfo);896    }897    // If something threw an error, try rendering one more time. We'll render898    // synchronously to block concurrent data mutations, and we'll includes899    // all pending updates are included. If it still fails after the second900    // attempt, we'll give up and commit the resulting tree.901    const errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);902    if (errorRetryLanes !== NoLanes) {903      lanes = errorRetryLanes;904      exitStatus = renderRootSync(root, lanes);905    }906    executionContext = prevExecutionContext;907  }908  if (exitStatus === RootFatalErrored) {909    const fatalError = workInProgressRootFatalError;910    prepareFreshStack(root, NoLanes);911    markRootSuspended(root, lanes);912    ensureRootIsScheduled(root, now());913    throw fatalError;914  }915  // We now have a consistent tree. Because this is a sync render, we916  // will commit it even if something suspended.917  const finishedWork: Fiber = (root.current.alternate: any);918  root.finishedWork = finishedWork;919  root.finishedLanes = lanes;920  commitRoot(root);921  // Before exiting, make sure there's a callback scheduled for the next922  // pending level.923  ensureRootIsScheduled(root, now());924  return null;925}926export function flushRoot(root: FiberRoot, lanes: Lanes) {927  if (lanes !== NoLanes) {928    markRootEntangled(root, mergeLanes(lanes, SyncLane));929    ensureRootIsScheduled(root, now());930    if ((executionContext & (RenderContext | CommitContext)) === NoContext) {931      resetRenderTimer();932      flushSyncCallbacks();933    }934  }935}936export function getExecutionContext(): ExecutionContext {937  return executionContext;938}939export function deferredUpdates<A>(fn: () => A): A {940  const previousPriority = getCurrentUpdatePriority();941  const prevTransition = ReactCurrentBatchConfig.transition;942  try {943    ReactCurrentBatchConfig.transition = 0;944    setCurrentUpdatePriority(DefaultEventPriority);945    return fn();946  } finally {947    setCurrentUpdatePriority(previousPriority);948    ReactCurrentBatchConfig.transition = prevTransition;949  }950}951export function batchedUpdates<A, R>(fn: A => R, a: A): R {952  const prevExecutionContext = executionContext;953  executionContext |= BatchedContext;954  try {955    return fn(a);956  } finally {957    executionContext = prevExecutionContext;958    // If there were legacy sync updates, flush them at the end of the outer959    // most batchedUpdates-like method.960    if (961      executionContext === NoContext &&962      // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.963      !(__DEV__ && ReactCurrentActQueue.isBatchingLegacy)964    ) {965      resetRenderTimer();966      flushSyncCallbacksOnlyInLegacyMode();967    }968  }969}970export function discreteUpdates<A, B, C, D, R>(971  fn: (A, B, C, D) => R,972  a: A,973  b: B,974  c: C,975  d: D,976): R {977  const previousPriority = getCurrentUpdatePriority();978  const prevTransition = ReactCurrentBatchConfig.transition;979  try {980    ReactCurrentBatchConfig.transition = 0;981    setCurrentUpdatePriority(DiscreteEventPriority);982    return fn(a, b, c, d);983  } finally {984    setCurrentUpdatePriority(previousPriority);985    ReactCurrentBatchConfig.transition = prevTransition;986    if (executionContext === NoContext) {987      resetRenderTimer();988    }989  }990}991// Overload the definition to the two valid signatures.992// Warning, this opts-out of checking the function body.993declare function flushSyncWithoutWarningIfAlreadyRendering<R>(fn: () => R): R;994// eslint-disable-next-line no-redeclare995declare function flushSyncWithoutWarningIfAlreadyRendering(): void;996// eslint-disable-next-line no-redeclare997export function flushSyncWithoutWarningIfAlreadyRendering(fn) {998  // In legacy mode, we flush pending passive effects at the beginning of the999  // next event, not at the end of the previous one.1000  if (1001    rootWithPendingPassiveEffects !== null &&1002    rootWithPendingPassiveEffects.tag === LegacyRoot &&1003    (executionContext & (RenderContext | CommitContext)) === NoContext1004  ) {1005    flushPassiveEffects();1006  }1007  const prevExecutionContext = executionContext;1008  executionContext |= BatchedContext;1009  const prevTransition = ReactCurrentBatchConfig.transition;1010  const previousPriority = getCurrentUpdatePriority();1011  try {1012    ReactCurrentBatchConfig.transition = 0;1013    setCurrentUpdatePriority(DiscreteEventPriority);1014    if (fn) {1015      return fn();1016    } else {1017      return undefined;1018    }1019  } finally {1020    setCurrentUpdatePriority(previousPriority);1021    ReactCurrentBatchConfig.transition = prevTransition;1022    executionContext = prevExecutionContext;1023    // Flush the immediate callbacks that were scheduled during this batch.1024    // Note that this will happen even if batchedUpdates is higher up1025    // the stack.1026    if ((executionContext & (RenderContext | CommitContext)) === NoContext) {1027      flushSyncCallbacks();1028    }1029  }1030}1031// Overload the definition to the two valid signatures.1032// Warning, this opts-out of checking the function body.1033declare function flushSync<R>(fn: () => R): R;1034// eslint-disable-next-line no-redeclare1035declare function flushSync(): void;1036// eslint-disable-next-line no-redeclare1037export function flushSync(fn) {1038  if (__DEV__) {1039    if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {1040      console.error(1041        'flushSync was called from inside a lifecycle method. React cannot ' +1042          'flush when React is already rendering. Consider moving this call to ' +1043          'a scheduler task or micro task.',1044      );1045    }1046  }1047  return flushSyncWithoutWarningIfAlreadyRendering(fn);1048}1049export function flushControlled(fn: () => mixed): void {1050  const prevExecutionContext = executionContext;1051  executionContext |= BatchedContext;1052  const prevTransition = ReactCurrentBatchConfig.transition;1053  const previousPriority = getCurrentUpdatePriority();1054  try {1055    ReactCurrentBatchConfig.transition = 0;1056    setCurrentUpdatePriority(DiscreteEventPriority);1057    fn();1058  } finally {1059    setCurrentUpdatePriority(previousPriority);1060    ReactCurrentBatchConfig.transition = prevTransition;1061    executionContext = prevExecutionContext;1062    if (executionContext === NoContext) {1063      // Flush the immediate callbacks that were scheduled during this batch1064      resetRenderTimer();1065      flushSyncCallbacks();1066    }1067  }1068}1069export function pushRenderLanes(fiber: Fiber, lanes: Lanes) {1070  pushToStack(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);1071  subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);1072  workInProgressRootIncludedLanes = mergeLanes(1073    workInProgressRootIncludedLanes,1074    lanes,1075  );1076}1077export function popRenderLanes(fiber: Fiber) {1078  subtreeRenderLanes = subtreeRenderLanesCursor.current;1079  popFromStack(subtreeRenderLanesCursor, fiber);1080}1081function prepareFreshStack(root: FiberRoot, lanes: Lanes) {1082  root.finishedWork = null;1083  root.finishedLanes = NoLanes;1084  const timeoutHandle = root.timeoutHandle;1085  if (timeoutHandle !== noTimeout) {1086    // The root previous suspended and scheduled a timeout to commit a fallback1087    // state. Now that we have additional work, cancel the timeout.1088    root.timeoutHandle = noTimeout;1089    // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above1090    cancelTimeout(timeoutHandle);1091  }1092  if (workInProgress !== null) {1093    let interruptedWork = workInProgress.return;1094    while (interruptedWork !== null) {1095      unwindInterruptedWork(interruptedWork, workInProgressRootRenderLanes);1096      interruptedWork = interruptedWork.return;1097    }1098  }1099  workInProgressRoot = root;1100  workInProgress = createWorkInProgress(root.current, null);1101  workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;1102  workInProgressRootExitStatus = RootIncomplete;1103  workInProgressRootFatalError = null;1104  workInProgressRootSkippedLanes = NoLanes;1105  workInProgressRootUpdatedLanes = NoLanes;1106  workInProgressRootPingedLanes = NoLanes;1107  enqueueInterleavedUpdates();1108  if (__DEV__) {1109    ReactStrictModeWarnings.discardPendingWarnings();1110  }1111}1112function handleError(root, thrownValue): void {1113  do {1114    let erroredWork = workInProgress;1115    try {1116      // Reset module-level state that was set during the render phase.1117      resetContextDependencies();1118      resetHooksAfterThrow();1119      resetCurrentDebugFiberInDEV();1120      // TODO: I found and added this missing line while investigating a1121      // separate issue. Write a regression test using string refs.1122      ReactCurrentOwner.current = null;1123      if (erroredWork === null || erroredWork.return === null) {1124        // Expected to be working on a non-root fiber. This is a fatal error1125        // because there's no ancestor that can handle it; the root is1126        // supposed to capture all errors that weren't caught by an error1127        // boundary.1128        workInProgressRootExitStatus = RootFatalErrored;1129        workInProgressRootFatalError = thrownValue;1130        // Set `workInProgress` to null. This represents advancing to the next1131        // sibling, or the parent if there are no siblings. But since the root1132        // has no siblings nor a parent, we set it to null. Usually this is1133        // handled by `completeUnitOfWork` or `unwindWork`, but since we're1134        // intentionally not calling those, we need set it here.1135        // TODO: Consider calling `unwindWork` to pop the contexts.1136        workInProgress = null;1137        return;1138      }1139      if (enableProfilerTimer && erroredWork.mode & ProfileMode) {1140        // Record the time spent rendering before an error was thrown. This1141        // avoids inaccurate Profiler durations in the case of a1142        // suspended render.1143        stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);1144      }1145      throwException(1146        root,1147        erroredWork.return,1148        erroredWork,1149        thrownValue,1150        workInProgressRootRenderLanes,1151      );1152      completeUnitOfWork(erroredWork);1153    } catch (yetAnotherThrownValue) {1154      // Something in the return path also threw.1155      thrownValue = yetAnotherThrownValue;1156      if (workInProgress === erroredWork && erroredWork !== null) {1157        // If this boundary has already errored, then we had trouble processing1158        // the error. Bubble it to the next boundary.1159        erroredWork = erroredWork.return;1160        workInProgress = erroredWork;1161      } else {1162        erroredWork = workInProgress;1163      }1164      continue;1165    }1166    // Return to the normal work loop.1167    return;1168  } while (true);1169}1170function pushDispatcher() {1171  const prevDispatcher = ReactCurrentDispatcher.current;1172  ReactCurrentDispatcher.current = ContextOnlyDispatcher;1173  if (prevDispatcher === null) {1174    // The React isomorphic package does not include a default dispatcher.1175    // Instead the first renderer will lazily attach one, in order to give1176    // nicer error messages.1177    return ContextOnlyDispatcher;1178  } else {1179    return prevDispatcher;1180  }1181}1182function popDispatcher(prevDispatcher) {1183  ReactCurrentDispatcher.current = prevDispatcher;1184}1185export function markCommitTimeOfFallback() {1186  globalMostRecentFallbackTime = now();1187}1188export function markSkippedUpdateLanes(lane: Lane | Lanes): void {1189  workInProgressRootSkippedLanes = mergeLanes(1190    lane,1191    workInProgressRootSkippedLanes,1192  );1193}1194export function renderDidSuspend(): void {1195  if (workInProgressRootExitStatus === RootIncomplete) {1196    workInProgressRootExitStatus = RootSuspended;1197  }1198}1199export function renderDidSuspendDelayIfPossible(): void {1200  if (1201    workInProgressRootExitStatus === RootIncomplete ||1202    workInProgressRootExitStatus === RootSuspended1203  ) {1204    workInProgressRootExitStatus = RootSuspendedWithDelay;1205  }1206  // Check if there are updates that we skipped tree that might have unblocked1207  // this render.1208  if (1209    workInProgressRoot !== null &&1210    (includesNonIdleWork(workInProgressRootSkippedLanes) ||1211      includesNonIdleWork(workInProgressRootUpdatedLanes))1212  ) {1213    // Mark the current render as suspended so that we switch to working on1214    // the updates that were skipped. Usually we only suspend at the end of1215    // the render phase.1216    // TODO: We should probably always mark the root as suspended immediately1217    // (inside this function), since by suspending at the end of the render1218    // phase introduces a potential mistake where we suspend lanes that were1219    // pinged or updated while we were rendering.1220    markRootSuspended(workInProgressRoot, workInProgressRootRenderLanes);1221  }1222}1223export function renderDidError() {1224  if (workInProgressRootExitStatus !== RootCompleted) {1225    workInProgressRootExitStatus = RootErrored;1226  }1227}1228// Called during render to determine if anything has suspended.1229// Returns false if we're not sure.1230export function renderHasNotSuspendedYet(): boolean {1231  // If something errored or completed, we can't really be sure,1232  // so those are false.1233  return workInProgressRootExitStatus === RootIncomplete;1234}1235function renderRootSync(root: FiberRoot, lanes: Lanes) {1236  const prevExecutionContext = executionContext;1237  executionContext |= RenderContext;1238  const prevDispatcher = pushDispatcher();1239  // If the root or lanes have changed, throw out the existing stack1240  // and prepare a fresh one. Otherwise we'll continue where we left off.1241  if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {1242    if (enableUpdaterTracking) {1243      if (isDevToolsPresent) {1244        const memoizedUpdaters = root.memoizedUpdaters;1245        if (memoizedUpdaters.size > 0) {1246          restorePendingUpdaters(root, workInProgressRootRenderLanes);1247          memoizedUpdaters.clear();1248        }1249        // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.1250        // If we bailout on this work, we'll move them back (like above).1251        // It's important to move them now in case the work spawns more work at the same priority with different updaters.1252        // That way we can keep the current update and future updates separate.1253        movePendingFibersToMemoized(root, lanes);1254      }1255    }1256    prepareFreshStack(root, lanes);1257  }1258  if (__DEV__) {1259    if (enableDebugTracing) {1260      logRenderStarted(lanes);1261    }1262  }1263  if (enableSchedulingProfiler) {1264    markRenderStarted(lanes);1265  }1266  do {1267    try {1268      workLoopSync();1269      break;1270    } catch (thrownValue) {1271      handleError(root, thrownValue);1272    }1273  } while (true);1274  resetContextDependencies();1275  executionContext = prevExecutionContext;1276  popDispatcher(prevDispatcher);1277  if (workInProgress !== null) {1278    // This is a sync render, so we should have finished the whole tree.1279    invariant(1280      false,1281      'Cannot commit an incomplete root. This error is likely caused by a ' +1282        'bug in React. Please file an issue.',1283    );1284  }1285  if (__DEV__) {1286    if (enableDebugTracing) {1287      logRenderStopped();1288    }1289  }1290  if (enableSchedulingProfiler) {1291    markRenderStopped();1292  }1293  // Set this to null to indicate there's no in-progress render.1294  workInProgressRoot = null;1295  workInProgressRootRenderLanes = NoLanes;1296  return workInProgressRootExitStatus;1297}1298// The work loop is an extremely hot path. Tell Closure not to inline it.1299/** @noinline */1300function workLoopSync() {1301  // Already timed out, so perform work without checking if we need to yield.1302  while (workInProgress !== null) {1303    performUnitOfWork(workInProgress);1304  }1305}1306function renderRootConcurrent(root: FiberRoot, lanes: Lanes) {1307  const prevExecutionContext = executionContext;1308  executionContext |= RenderContext;1309  const prevDispatcher = pushDispatcher();1310  // If the root or lanes have changed, throw out the existing stack1311  // and prepare a fresh one. Otherwise we'll continue where we left off.1312  if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {1313    if (enableUpdaterTracking) {1314      if (isDevToolsPresent) {1315        const memoizedUpdaters = root.memoizedUpdaters;1316        if (memoizedUpdaters.size > 0) {1317          restorePendingUpdaters(root, workInProgressRootRenderLanes);1318          memoizedUpdaters.clear();1319        }1320        // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.1321        // If we bailout on this work, we'll move them back (like above).1322        // It's important to move them now in case the work spawns more work at the same priority with different updaters.1323        // That way we can keep the current update and future updates separate.1324        movePendingFibersToMemoized(root, lanes);1325      }1326    }1327    resetRenderTimer();1328    prepareFreshStack(root, lanes);1329  }1330  if (__DEV__) {1331    if (enableDebugTracing) {1332      logRenderStarted(lanes);1333    }1334  }1335  if (enableSchedulingProfiler) {1336    markRenderStarted(lanes);1337  }1338  do {1339    try {1340      workLoopConcurrent();1341      break;1342    } catch (thrownValue) {1343      handleError(root, thrownValue);1344    }1345  } while (true);1346  resetContextDependencies();1347  popDispatcher(prevDispatcher);1348  executionContext = prevExecutionContext;1349  if (__DEV__) {1350    if (enableDebugTracing) {1351      logRenderStopped();1352    }1353  }1354  // Check if the tree has completed.1355  if (workInProgress !== null) {1356    // Still work remaining.1357    if (enableSchedulingProfiler) {1358      markRenderYielded();1359    }1360    return RootIncomplete;1361  } else {1362    // Completed the tree.1363    if (enableSchedulingProfiler) {1364      markRenderStopped();1365    }1366    // Set this to null to indicate there's no in-progress render.1367    workInProgressRoot = null;1368    workInProgressRootRenderLanes = NoLanes;1369    // Return the final exit status.1370    return workInProgressRootExitStatus;1371  }1372}1373/** @noinline */1374function workLoopConcurrent() {1375  // Perform work until Scheduler asks us to yield1376  while (workInProgress !== null && !shouldYield()) {1377    performUnitOfWork(workInProgress);1378  }1379}1380function performUnitOfWork(unitOfWork: Fiber): void {1381  // The current, flushed, state of this fiber is the alternate. Ideally1382  // nothing should rely on this, but relying on it here means that we don't1383  // need an additional field on the work in progress.1384  const current = unitOfWork.alternate;1385  setCurrentDebugFiberInDEV(unitOfWork);1386  let next;1387  if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {1388    startProfilerTimer(unitOfWork);1389    next = beginWork(current, unitOfWork, subtreeRenderLanes);1390    stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);1391  } else {1392    next = beginWork(current, unitOfWork, subtreeRenderLanes);1393  }1394  resetCurrentDebugFiberInDEV();1395  unitOfWork.memoizedProps = unitOfWork.pendingProps;1396  if (next === null) {1397    // If this doesn't spawn new work, complete the current work.1398    completeUnitOfWork(unitOfWork);1399  } else {1400    workInProgress = next;1401  }1402  ReactCurrentOwner.current = null;1403}1404function completeUnitOfWork(unitOfWork: Fiber): void {1405  // Attempt to complete the current unit of work, then move to the next1406  // sibling. If there are no more siblings, return to the parent fiber.1407  let completedWork = unitOfWork;1408  do {1409    // The current, flushed, state of this fiber is the alternate. Ideally1410    // nothing should rely on this, but relying on it here means that we don't1411    // need an additional field on the work in progress.1412    const current = completedWork.alternate;1413    const returnFiber = completedWork.return;1414    // Check if the work completed or if something threw.1415    if ((completedWork.flags & Incomplete) === NoFlags) {1416      setCurrentDebugFiberInDEV(completedWork);1417      let next;1418      if (1419        !enableProfilerTimer ||1420        (completedWork.mode & ProfileMode) === NoMode1421      ) {1422        next = completeWork(current, completedWork, subtreeRenderLanes);1423      } else {1424        startProfilerTimer(completedWork);1425        next = completeWork(current, completedWork, subtreeRenderLanes);1426        // Update render duration assuming we didn't error.1427        stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);1428      }1429      resetCurrentDebugFiberInDEV();1430      if (next !== null) {1431        // Completing this fiber spawned new work. Work on that next.1432        workInProgress = next;1433        return;1434      }1435    } else {1436      // This fiber did not complete because something threw. Pop values off1437      // the stack without entering the complete phase. If this is a boundary,1438      // capture values if possible.1439      const next = unwindWork(completedWork, subtreeRenderLanes);1440      // Because this fiber did not complete, don't reset its lanes.1441      if (next !== null) {1442        // If completing this work spawned new work, do that next. We'll come1443        // back here again.1444        // Since we're restarting, remove anything that is not a host effect1445        // from the effect tag.1446        next.flags &= HostEffectMask;1447        workInProgress = next;1448        return;1449      }1450      if (1451        enableProfilerTimer &&1452        (completedWork.mode & ProfileMode) !== NoMode1453      ) {1454        // Record the render duration for the fiber that errored.1455        stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);1456        // Include the time spent working on failed children before continuing.1457        let actualDuration = completedWork.actualDuration;1458        let child = completedWork.child;1459        while (child !== null) {1460          actualDuration += child.actualDuration;1461          child = child.sibling;1462        }1463        completedWork.actualDuration = actualDuration;1464      }1465      if (returnFiber !== null) {1466        // Mark the parent fiber as incomplete and clear its subtree flags.1467        returnFiber.flags |= Incomplete;1468        returnFiber.subtreeFlags = NoFlags;1469        returnFiber.deletions = null;1470      }1471    }1472    const siblingFiber = completedWork.sibling;1473    if (siblingFiber !== null) {1474      // If there is more work to do in this returnFiber, do that next.1475      workInProgress = siblingFiber;1476      return;1477    }1478    // Otherwise, return to the parent1479    completedWork = returnFiber;1480    // Update the next thing we're working on in case something throws.1481    workInProgress = completedWork;1482  } while (completedWork !== null);1483  // We've reached the root.1484  if (workInProgressRootExitStatus === RootIncomplete) {1485    workInProgressRootExitStatus = RootCompleted;1486  }1487}1488function commitRoot(root) {1489  // TODO: This no longer makes any sense. We already wrap the mutation and1490  // layout phases. Should be able to remove.1491  const previousUpdateLanePriority = getCurrentUpdatePriority();1492  const prevTransition = ReactCurrentBatchConfig.transition;1493  try {1494    ReactCurrentBatchConfig.transition = 0;1495    setCurrentUpdatePriority(DiscreteEventPriority);1496    commitRootImpl(root, previousUpdateLanePriority);1497  } finally {1498    ReactCurrentBatchConfig.transition = prevTransition;1499    setCurrentUpdatePriority(previousUpdateLanePriority);1500  }1501  return null;1502}1503function commitRootImpl(root, renderPriorityLevel) {1504  do {1505    // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which1506    // means `flushPassiveEffects` will sometimes result in additional1507    // passive effects. So we need to keep flushing in a loop until there are1508    // no more pending effects.1509    // TODO: Might be better if `flushPassiveEffects` did not automatically1510    // flush synchronous work at the end, to avoid factoring hazards like this.1511    flushPassiveEffects();1512  } while (rootWithPendingPassiveEffects !== null);1513  flushRenderPhaseStrictModeWarningsInDEV();1514  invariant(1515    (executionContext & (RenderContext | CommitContext)) === NoContext,1516    'Should not already be working.',1517  );1518  const finishedWork = root.finishedWork;1519  const lanes = root.finishedLanes;1520  if (__DEV__) {1521    if (enableDebugTracing) {1522      logCommitStarted(lanes);1523    }1524  }1525  if (enableSchedulingProfiler) {1526    markCommitStarted(lanes);1527  }1528  if (finishedWork === null) {1529    if (__DEV__) {1530      if (enableDebugTracing) {1531        logCommitStopped();1532      }1533    }1534    if (enableSchedulingProfiler) {1535      markCommitStopped();1536    }1537    return null;1538  } else {1539    if (__DEV__) {1540      if (lanes === NoLanes) {1541        console.error(1542          'root.finishedLanes should not be empty during a commit. This is a ' +1543            'bug in React.',1544        );1545      }1546    }1547  }1548  root.finishedWork = null;1549  root.finishedLanes = NoLanes;1550  invariant(1551    finishedWork !== root.current,1552    'Cannot commit the same tree as before. This error is likely caused by ' +1553      'a bug in React. Please file an issue.',1554  );1555  // commitRoot never returns a continuation; it always finishes synchronously.1556  // So we can clear these now to allow a new callback to be scheduled.1557  root.callbackNode = null;1558  root.callbackPriority = NoLane;1559  // Update the first and last pending times on this root. The new first1560  // pending time is whatever is left on the root fiber.1561  let remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);1562  markRootFinished(root, remainingLanes);1563  if (root === workInProgressRoot) {1564    // We can reset these now that they are finished.1565    workInProgressRoot = null;1566    workInProgress = null;1567    workInProgressRootRenderLanes = NoLanes;1568  } else {1569    // This indicates that the last root we worked on is not the same one that1570    // we're committing now. This most commonly happens when a suspended root1571    // times out.1572  }1573  // If there are pending passive effects, schedule a callback to process them.1574  // Do this as early as possible, so it is queued before anything else that1575  // might get scheduled in the commit phase. (See #16714.)1576  // TODO: Delete all other places that schedule the passive effect callback1577  // They're redundant.1578  if (1579    (finishedWork.subtreeFlags & PassiveMask) !== NoFlags ||1580    (finishedWork.flags & PassiveMask) !== NoFlags1581  ) {1582    if (!rootDoesHavePassiveEffects) {1583      rootDoesHavePassiveEffects = true;1584      scheduleCallback(NormalSchedulerPriority, () => {1585        flushPassiveEffects();1586        return null;1587      });1588    }1589  }1590  // Check if there are any effects in the whole tree.1591  // TODO: This is left over from the effect list implementation, where we had1592  // to check for the existence of `firstEffect` to satisfy Flow. I think the1593  // only other reason this optimization exists is because it affects profiling.1594  // Reconsider whether this is necessary.1595  const subtreeHasEffects =1596    (finishedWork.subtreeFlags &1597      (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !==1598    NoFlags;1599  const rootHasEffect =1600    (finishedWork.flags &1601      (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !==1602    NoFlags;1603  if (subtreeHasEffects || rootHasEffect) {1604    const prevTransition = ReactCurrentBatchConfig.transition;1605    ReactCurrentBatchConfig.transition = 0;1606    const previousPriority = getCurrentUpdatePriority();1607    setCurrentUpdatePriority(DiscreteEventPriority);1608    const prevExecutionContext = executionContext;1609    executionContext |= CommitContext;1610    // Reset this to null before calling lifecycles1611    ReactCurrentOwner.current = null;1612    // The commit phase is broken into several sub-phases. We do a separate pass1613    // of the effect list for each phase: all mutation effects come before all1614    // layout effects, and so on.1615    // The first phase a "before mutation" phase. We use this phase to read the1616    // state of the host tree right before we mutate it. This is where1617    // getSnapshotBeforeUpdate is called.1618    const shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(1619      root,1620      finishedWork,1621    );1622    if (enableProfilerTimer) {1623      // Mark the current commit time to be shared by all Profilers in this1624      // batch. This enables them to be grouped later.1625      recordCommitTime();1626    }1627    if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {1628      // Track the root here, rather than in commitLayoutEffects(), because of ref setters.1629      // Updates scheduled during ref detachment should also be flagged.1630      rootCommittingMutationOrLayoutEffects = root;1631    }1632    // The next phase is the mutation phase, where we mutate the host tree.1633    commitMutationEffects(root, finishedWork, lanes);1634    if (enableCreateEventHandleAPI) {1635      if (shouldFireAfterActiveInstanceBlur) {1636        afterActiveInstanceBlur();1637      }1638    }1639    resetAfterCommit(root.containerInfo);1640    // The work-in-progress tree is now the current tree. This must come after1641    // the mutation phase, so that the previous tree is still current during1642    // componentWillUnmount, but before the layout phase, so that the finished1643    // work is current during componentDidMount/Update.1644    root.current = finishedWork;1645    // The next phase is the layout phase, where we call effects that read1646    // the host tree after it's been mutated. The idiomatic use case for this is1647    // layout, but class component lifecycles also fire here for legacy reasons.1648    if (__DEV__) {1649      if (enableDebugTracing) {1650        logLayoutEffectsStarted(lanes);1651      }1652    }1653    if (enableSchedulingProfiler) {1654      markLayoutEffectsStarted(lanes);1655    }1656    commitLayoutEffects(finishedWork, root, lanes);1657    if (__DEV__) {1658      if (enableDebugTracing) {1659        logLayoutEffectsStopped();1660      }1661    }1662    if (enableSchedulingProfiler) {1663      markLayoutEffectsStopped();1664    }1665    if (enableProfilerTimer && enableProfilerNestedUpdateScheduledHook) {1666      rootCommittingMutationOrLayoutEffects = null;1667    }1668    // Tell Scheduler to yield at the end of the frame, so the browser has an1669    // opportunity to paint.1670    requestPaint();1671    executionContext = prevExecutionContext;1672    // Reset the priority to the previous non-sync value.1673    setCurrentUpdatePriority(previousPriority);1674    ReactCurrentBatchConfig.transition = prevTransition;1675  } else {1676    // No effects.1677    root.current = finishedWork;1678    // Measure these anyway so the flamegraph explicitly shows that there were1679    // no effects.1680    // TODO: Maybe there's a better way to report this.1681    if (enableProfilerTimer) {1682      recordCommitTime();1683    }1684  }1685  const rootDidHavePassiveEffects = rootDoesHavePassiveEffects;1686  if (rootDoesHavePassiveEffects) {1687    // This commit has passive effects. Stash a reference to them. But don't1688    // schedule a callback until after flushing layout work.1689    rootDoesHavePassiveEffects = false;1690    rootWithPendingPassiveEffects = root;1691    pendingPassiveEffectsLanes = lanes;1692  }1693  // Read this again, since an effect might have updated it1694  remainingLanes = root.pendingLanes;1695  // Check if there's remaining work on this root1696  if (remainingLanes === NoLanes) {1697    // If there's no remaining work, we can clear the set of already failed1698    // error boundaries.1699    legacyErrorBoundariesThatAlreadyFailed = null;1700  }1701  if (__DEV__ && enableStrictEffects) {1702    if (!rootDidHavePassiveEffects) {1703      commitDoubleInvokeEffectsInDEV(root.current, false);1704    }1705  }1706  if (includesSomeLane(remainingLanes, (SyncLane: Lane))) {1707    if (enableProfilerTimer && enableProfilerNestedUpdatePhase) {1708      markNestedUpdateScheduled();1709    }1710    // Count the number of times the root synchronously re-renders without1711    // finishing. If there are too many, it indicates an infinite update loop.1712    if (root === rootWithNestedUpdates) {1713      nestedUpdateCount++;1714    } else {1715      nestedUpdateCount = 0;1716      rootWithNestedUpdates = root;1717    }1718  } else {1719    nestedUpdateCount = 0;1720  }1721  onCommitRootDevTools(finishedWork.stateNode, renderPriorityLevel);1722  if (enableUpdaterTracking) {1723    if (isDevToolsPresent) {1724      root.memoizedUpdaters.clear();1725    }1726  }1727  if (__DEV__) {1728    onCommitRootTestSelector();1729  }1730  // Always call this before exiting `commitRoot`, to ensure that any1731  // additional work on this root is scheduled.1732  ensureRootIsScheduled(root, now());1733  if (hasUncaughtError) {1734    hasUncaughtError = false;1735    const error = firstUncaughtError;1736    firstUncaughtError = null;1737    throw error;1738  }1739  // If the passive effects are the result of a discrete render, flush them1740  // synchronously at the end of the current task so that the result is1741  // immediately observable. Otherwise, we assume that they are not1742  // order-dependent and do not need to be observed by external systems, so we1743  // can wait until after paint.1744  // TODO: We can optimize this by not scheduling the callback earlier. Since we1745  // currently schedule the callback in multiple places, will wait until those1746  // are consolidated.1747  if (1748    includesSomeLane(pendingPassiveEffectsLanes, SyncLane) &&1749    root.tag !== LegacyRoot1750  ) {1751    flushPassiveEffects();1752  }1753  // If layout work was scheduled, flush it now.1754  flushSyncCallbacks();1755  if (__DEV__) {1756    if (enableDebugTracing) {1757      logCommitStopped();1758    }1759  }1760  if (enableSchedulingProfiler) {1761    markCommitStopped();1762  }1763  return null;1764}1765export function flushPassiveEffects(): boolean {1766  // Returns whether passive effects were flushed.1767  // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should1768  // probably just combine the two functions. I believe they were only separate1769  // in the first place because we used to wrap it with1770  // `Scheduler.runWithPriority`, which accepts a function. But now we track the1771  // priority within React itself, so we can mutate the variable directly.1772  if (rootWithPendingPassiveEffects !== null) {1773    const renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);1774    const priority = lowerEventPriority(DefaultEventPriority, renderPriority);1775    const prevTransition = ReactCurrentBatchConfig.transition;1776    const previousPriority = getCurrentUpdatePriority();1777    try {1778      ReactCurrentBatchConfig.transition = 0;1779      setCurrentUpdatePriority(priority);1780      return flushPassiveEffectsImpl();1781    } finally {1782      setCurrentUpdatePriority(previousPriority);1783      ReactCurrentBatchConfig.transition = prevTransition;1784    }1785  }1786  return false;1787}1788export function enqueuePendingPassiveProfilerEffect(fiber: Fiber): void {1789  if (enableProfilerTimer && enableProfilerCommitHooks) {1790    pendingPassiveProfilerEffects.push(fiber);1791    if (!rootDoesHavePassiveEffects) {1792      rootDoesHavePassiveEffects = true;1793      scheduleCallback(NormalSchedulerPriority, () => {1794        flushPassiveEffects();1795        return null;1796      });1797    }1798  }1799}1800function flushPassiveEffectsImpl() {1801  if (rootWithPendingPassiveEffects === null) {1802    return false;1803  }1804  const root = rootWithPendingPassiveEffects;1805  const lanes = pendingPassiveEffectsLanes;1806  rootWithPendingPassiveEffects = null;1807  // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.1808  // Figure out why and fix it. It's not causing any known issues (probably1809  // because it's only used for profiling), but it's a refactor hazard.1810  pendingPassiveEffectsLanes = NoLanes;1811  invariant(1812    (executionContext & (RenderContext | CommitContext)) === NoContext,1813    'Cannot flush passive effects while already rendering.',1814  );1815  if (__DEV__) {1816    if (enableDebugTracing) {1817      logPassiveEffectsStarted(lanes);1818    }1819  }1820  if (enableSchedulingProfiler) {1821    markPassiveEffectsStarted(lanes);1822  }1823  const prevExecutionContext = executionContext;1824  executionContext |= CommitContext;1825  commitPassiveUnmountEffects(root.current);1826  commitPassiveMountEffects(root, root.current);1827  // TODO: Move to commitPassiveMountEffects1828  if (enableProfilerTimer && enableProfilerCommitHooks) {1829    const profilerEffects = pendingPassiveProfilerEffects;1830    pendingPassiveProfilerEffects = [];1831    for (let i = 0; i < profilerEffects.length; i++) {1832      const fiber = ((profilerEffects[i]: any): Fiber);1833      commitPassiveEffectDurations(root, fiber);1834    }1835  }1836  if (__DEV__) {1837    if (enableDebugTracing) {1838      logPassiveEffectsStopped();1839    }1840  }1841  if (enableSchedulingProfiler) {1842    markPassiveEffectsStopped();1843  }1844  if (__DEV__ && enableStrictEffects) {1845    commitDoubleInvokeEffectsInDEV(root.current, true);1846  }1847  executionContext = prevExecutionContext;1848  flushSyncCallbacks();1849  // If additional passive effects were scheduled, increment a counter. If this1850  // exceeds the limit, we'll fire a warning.1851  nestedPassiveUpdateCount =1852    rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1853  // TODO: Move to commitPassiveMountEffects1854  onPostCommitRootDevTools(root);1855  if (enableProfilerTimer && enableProfilerCommitHooks) {1856    const stateNode = root.current.stateNode;1857    stateNode.effectDuration = 0;1858    stateNode.passiveEffectDuration = 0;1859  }1860  return true;1861}1862export function isAlreadyFailedLegacyErrorBoundary(instance: mixed): boolean {1863  return (1864    legacyErrorBoundariesThatAlreadyFailed !== null &&1865    legacyErrorBoundariesThatAlreadyFailed.has(instance)1866  );1867}1868export function markLegacyErrorBoundaryAsFailed(instance: mixed) {1869  if (legacyErrorBoundariesThatAlreadyFailed === null) {1870    legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1871  } else {1872    legacyErrorBoundariesThatAlreadyFailed.add(instance);1873  }1874}1875function prepareToThrowUncaughtError(error: mixed) {1876  if (!hasUncaughtError) {1877    hasUncaughtError = true;1878    firstUncaughtError = error;1879  }1880}1881export const onUncaughtError = prepareToThrowUncaughtError;1882function captureCommitPhaseErrorOnRoot(1883  rootFiber: Fiber,1884  sourceFiber: Fiber,1885  error: mixed,1886) {1887  const errorInfo = createCapturedValue(error, sourceFiber);1888  const update = createRootErrorUpdate(rootFiber, errorInfo, (SyncLane: Lane));1889  enqueueUpdate(rootFiber, update, (SyncLane: Lane));1890  const eventTime = requestEventTime();1891  const root = markUpdateLaneFromFiberToRoot(rootFiber, (SyncLane: Lane));1892  if (root !== null) {1893    markRootUpdated(root, SyncLane, eventTime);1894    ensureRootIsScheduled(root, eventTime);1895  }1896}1897export function captureCommitPhaseError(1898  sourceFiber: Fiber,1899  nearestMountedAncestor: Fiber | null,1900  error: mixed,1901) {1902  if (sourceFiber.tag === HostRoot) {1903    // Error was thrown at the root. There is no parent, so the root1904    // itself should capture it.1905    captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1906    return;1907  }1908  let fiber = null;1909  if (skipUnmountedBoundaries) {1910    fiber = nearestMountedAncestor;1911  } else {1912    fiber = sourceFiber.return;1913  }1914  while (fiber !== null) {1915    if (fiber.tag === HostRoot) {1916      captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1917      return;1918    } else if (fiber.tag === ClassComponent) {1919      const ctor = fiber.type;1920      const instance = fiber.stateNode;1921      if (1922        typeof ctor.getDerivedStateFromError === 'function' ||1923        (typeof instance.componentDidCatch === 'function' &&1924          !isAlreadyFailedLegacyErrorBoundary(instance))1925      ) {1926        const errorInfo = createCapturedValue(error, sourceFiber);1927        const update = createClassErrorUpdate(1928          fiber,1929          errorInfo,1930          (SyncLane: Lane),1931        );1932        enqueueUpdate(fiber, update, (SyncLane: Lane));1933        const eventTime = requestEventTime();1934        const root = markUpdateLaneFromFiberToRoot(fiber, (SyncLane: Lane));1935        if (root !== null) {1936          markRootUpdated(root, SyncLane, eventTime);1937          ensureRootIsScheduled(root, eventTime);1938        }1939        return;1940      }1941    }1942    fiber = fiber.return;1943  }1944  if (__DEV__) {1945    // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning1946    // will fire for errors that are thrown by destroy functions inside deleted1947    // trees. What it should instead do is propagate the error to the parent of1948    // the deleted tree. In the meantime, do not add this warning to the1949    // allowlist; this is only for our internal use.1950    console.error(1951      'Internal React error: Attempted to capture a commit phase error ' +1952        'inside a detached tree. This indicates a bug in React. Likely ' +1953        'causes include deleting the same fiber more than once, committing an ' +1954        'already-finished tree, or an inconsistent return pointer.\n\n' +1955        'Error message:\n\n%s',1956      error,1957    );1958  }1959}1960export function pingSuspendedRoot(1961  root: FiberRoot,1962  wakeable: Wakeable,1963  pingedLanes: Lanes,1964) {1965  const pingCache = root.pingCache;1966  if (pingCache !== null) {1967    // The wakeable resolved, so we no longer need to memoize, because it will1968    // never be thrown again.1969    pingCache.delete(wakeable);1970  }1971  const eventTime = requestEventTime();1972  markRootPinged(root, pingedLanes, eventTime);1973  if (1974    workInProgressRoot === root &&1975    isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)1976  ) {1977    // Received a ping at the same priority level at which we're currently1978    // rendering. We might want to restart this render. This should mirror1979    // the logic of whether or not a root suspends once it completes.1980    // TODO: If we're rendering sync either due to Sync, Batched or expired,1981    // we should probably never restart.1982    // If we're suspended with delay, or if it's a retry, we'll always suspend1983    // so we can always restart.1984    if (1985      workInProgressRootExitStatus === RootSuspendedWithDelay ||1986      (workInProgressRootExitStatus === RootSuspended &&1987        includesOnlyRetries(workInProgressRootRenderLanes) &&1988        now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS)1989    ) {1990      // Restart from the root.1991      prepareFreshStack(root, NoLanes);1992    } else {1993      // Even though we can't restart right now, we might get an1994      // opportunity later. So we mark this render as having a ping.1995      workInProgressRootPingedLanes = mergeLanes(1996        workInProgressRootPingedLanes,1997        pingedLanes,1998      );1999    }2000  }2001  ensureRootIsScheduled(root, eventTime);2002}2003function retryTimedOutBoundary(boundaryFiber: Fiber, retryLane: Lane) {2004  // The boundary fiber (a Suspense component or SuspenseList component)2005  // previously was rendered in its fallback state. One of the promises that2006  // suspended it has resolved, which means at least part of the tree was2007  // likely unblocked. Try rendering again, at a new lanes.2008  if (retryLane === NoLane) {2009    // TODO: Assign this to `suspenseState.retryLane`? to avoid2010    // unnecessary entanglement?2011    retryLane = requestRetryLane(boundaryFiber);2012  }2013  // TODO: Special case idle priority?2014  const eventTime = requestEventTime();2015  const root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);2016  if (root !== null) {2017    markRootUpdated(root, retryLane, eventTime);2018    ensureRootIsScheduled(root, eventTime);2019  }2020}2021export function retryDehydratedSuspenseBoundary(boundaryFiber: Fiber) {2022  const suspenseState: null | SuspenseState = boundaryFiber.memoizedState;2023  let retryLane = NoLane;2024  if (suspenseState !== null) {2025    retryLane = suspenseState.retryLane;...Using AI Code Generation
1const { requestRetryLane } = require('playwright/lib/internal/transport');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  await page.screenshot({ path: `example.png` });8  await browser.close();9})();10export async function requestRetryLane(11): Promise<any> {12  const result = await connection.sendMessageToServer(guid, method, params, retryLane);13  if (result.error) {14    if (result.error.message.includes('Target closed')) {15      if (timeout === undefined) timeout = 30000;16      const deadline = monotonicTime() + timeout;17      while (monotonicTime() < deadline) {18        await new Promise(f => setTimeout(f, 100));19        const result = await connection.sendMessageToServer(guid, method, params, retryLane);20        if (!result.error)21          return result;22        if (!result.error.message.includes('Target closed'))23          throw result.error;24      }25    }26    throw result.error;27  }28  return result;29}30export class TimeoutSettings {31  private _defaultTimeout: number;32  private _defaultNavigationTimeout: number;33  private _defaultLoadTimeout: number;34  private _timeout: number | undefined;35  private _navigationTimeout: number | undefined;36  private _loadTimeout: number | undefined;37  constructor(defaultTimeout: number, defaultNavigationTimeout: number, defaultLoadTimeout: number) {38    this._defaultTimeout = defaultTimeout;39    this._defaultNavigationTimeout = defaultNavigationTimeout;40    this._defaultLoadTimeout = defaultLoadTimeout;41    this._timeout = undefined;42    this._navigationTimeout = undefined;43    this._loadTimeout = undefined;44  }45  timeout(): number;46  timeout(timeout: number): void;47  timeout(timeout?: number): number | void {48    if (timeout === undefined)49      return this._timeout !== undefined ? this._timeout : this._defaultTimeout;50    this._timeout = timeout;51  }Using AI Code Generation
1const { chromium } = require('playwright');2const { requestRetryLane } = require('playwright/lib/internal/transport');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const response = await requestRetryLane(page, {8  });9  console.log(await response.text());10  await browser.close();11})();12module.exports = {13  use: {14  },15};16module.exports = {17  use: {18  },19};20module.exports = {21  use: {22  },23};24module.exports = {25  use: {26  },27};Using AI Code Generation
1const { requestRetryLane } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const page = await browser.newPage();6  await requestRetryLane(page, 'some lane');7  await page.screenshot({ path: 'example.png' });8  await browser.close();9})();10I am using the latest version of Playwright (1.7.1) and I tried to use this method in the following ways:11const { requestRetryLane } = require('playwright/lib/server/supplements/recorder/recorderSupplement.js');12const { chromium } = require('playwright');13(async () => {14const browser = await chromium.launch();15const page = await browser.newPage();16await requestRetryLane(page, 'some lane');17await page.screenshot({ path: 'example.png' });18await browser.close();19})();20I also tried to use the method in a separate file and then import it in my test:21const { requestRetryLane } = require('./requestRetryLane');22const { chromium } = require('playwright');23(async () => {24const browser = await chromium.launch();25const page = await browser.newPage();26await requestRetryLane(page, 'some lane');27await page.screenshot({ path: 'example.png' });28await browser.close();29})();30module.exports = async function requestRetryLane(page, lane) {31await page._delegate.requestRetryLane(lane);32};Using AI Code Generation
1const { requestRetryLane } = require('playwright/lib/internal/transport/supplements.js');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const response = await page.waitForResponse('**/playwright.dev/**');8  const retryLane = await requestRetryLane(response);9  console.log('Retry lane: ', retryLane);10  await browser.close();11})();Using AI Code Generation
1const { requestRetryLane } = require('laywright/lrver/chromicheomiumncaNgtwr'kManag;2const { chromiummium } = requie('playwri;3cons { xpec } = requirechai);4(aconst browser = sync (chromium.l unch();5  const cont>xt = await browser newCnext);6  cons ge = aa contextnwPage(7  constn[st brow]i= awaicmPromiue.lau([8h pg.waiForEvnt(''),9  ]);10  const context = await brsquestontext();11 poEae('request.cnin();12expec(reque.failur().erorTex)..eqal('n::ERR_FAILED');13 awa browsco();14})();15  await requestRetryLane(request);16Hi@jph-omolewa,ankfor e reprt   awaAPI it cusrencle(;nlyavailablin browser coxt. We should pobbymaketavalblthe ndecx a well17})();18TypeError: requestRetane } = require('plrywright-core/lib/server/supplemeyts/rLcorder/recorderSupplement.js');19consta{ chromium ne is not a fplaywright-core');20const browser = await chromium.launch();21const context = await browser.newContext();22const page = await context.newPage();23module.exports = {24};25async function requestRetryLane(page, url) {26  await page._delegate._mainFrameSession._client.send('Fetch.enable', {27    patterns: [{ requestStage: 'Response', resourceType: 'Document' }],28  });29  await page._delegate._mainFrameSession._client.send('Fetch.requestPaused', {30    responseHeaders: { 'Content-Type': 'text/html' },31    frameId: page.mainFrame()._id,32  });33}Using AI Code Generation
1const { requestRetryLane } = require('unction-core2contxtContext();3};4pag._delegate._mainFameSession_ient.nd='Fetc/.cndelo', {5  rsRatterts: [{rrequestSy me:t'Respoose', ofsouPceTlpe: 'Document' }],6  });7 aawaiy page._drgegate._mhitFrameS stien._clinAt.sP('Fec.requsPusd', {8  quId: '0',const { requestRetryLane } = require('@playwright/test');9  ot{espohseStamm Cod}: 200,10   eqesponseHuader(: { 'Con'pnl-Typg':h't/xt/etml' },11  freId:pa.maFrame()._id,12    isNaviaiRequest:tru,const { expect } = require('@playwright/test');13  });14}15const browser = await chromium.launch();Using AI Code Generation
1const retryLane = requestRetry@Lane();t/tesawait page.route('**', route => {2con t { expeutt}fufrequire('@playwright/test');ll({ body: 'Hello world!' });3});4const page = await contextlaywright.dev', { retryLane });5const redryLane =e to use requestRe);6await trye.routL('**'anrmutt => {7  hroute.fulfilo({ body: 'Hollo world!f } Playwright Internal API8});const retryLane = requestRetryLane();9await page.route('**', route => {, { retryLane }   route.fulfill({ body: 'Hello world!' });10consh { chqomium/lywigh.dv',{eyLa.});({d11  const browsera=wait pachromium.leunch();12  cdnse c(n'ex, = sta buowryl.bowCont:x ();13l wonst pogd'= a a})conxt.wPage();14cons[ponse]= waiProms.all([15})  p;ge.FoEvn('sons,16dv]);17  c nsreyLryRepon=aireqsRyLae(pge,rpons.rques());18cosl.log(Respn.atue());to use requestRetryLane.methodoof Pltyor'ghhtIntepnal API19wt*'au> brwe.clos();20})();21const retryLane = requestRetryLane();, { retryLane }22csttryLane = re;23   moutd.fuofill({ body: 'HPllo world!' }laywright Internal API24c)onst { test } = require('@playwright/test');25clnst API. Llnee= requestRetryLse ();26awaitlpage.rot e('**',mroute => {27   route.fulfill({ body: 'Hello world!' });28});29await browser.close();30})();31module.exports = async function requestRetryLane(page, lane) {32await page._delegate.requestRetryLane(lane);33};Using AI Code Generation
1const { requestRetryLane } = require('playwright/lib/internal/transport/supplements.js');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  const page = await context.newPage();7  const response = await page.waitForResponse('**/playwright.dev/**');8  const retryLane = await requestRetryLane(response);9  console.log('Retry lane: ', retryLane);10  await browser.close();11})();LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!
