Best JavaScript code snippet using playwright-internal
ReactFiberScheduler.js
Source:ReactFiberScheduler.js  
...699        const currentTime = requestCurrentTime();700        if (currentTime < expirationTime) {701          // Restart at the current time.702          workPhase = prevWorkPhase;703          resetContextDependencies();704          ReactCurrentDispatcher.current = prevDispatcher;705          if (enableSchedulerTracing) {706            __interactionsRef.current = ((prevInteractions: any): Set<707              Interaction,708            >);709          }710          return renderRoot.bind(null, root, currentTime);711        }712      }713    } else {714      // Since we know we're in a React event, we can clear the current715      // event time. The next update will compute a new event time.716      currentEventTime = NoWork;717    }718    do {719      try {720        if (isSync) {721          workLoopSync();722        } else {723          workLoop();724        }725        break;726      } catch (thrownValue) {727        // Reset module-level state that was set during the render phase.728        resetContextDependencies();729        resetHooks();730        const sourceFiber = workInProgress;731        if (sourceFiber === null || sourceFiber.return === null) {732          // Expected to be working on a non-root fiber. This is a fatal error733          // because there's no ancestor that can handle it; the root is734          // supposed to capture all errors that weren't caught by an error735          // boundary.736          prepareFreshStack(root, expirationTime);737          workPhase = prevWorkPhase;738          throw thrownValue;739        }740        if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {741          // Record the time spent rendering before an error was thrown. This742          // avoids inaccurate Profiler durations in the case of a743          // suspended render.744          stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);745        }746        const returnFiber = sourceFiber.return;747        throwException(748          root,749          returnFiber,750          sourceFiber,751          thrownValue,752          renderExpirationTime,753        );754        workInProgress = completeUnitOfWork(sourceFiber);755      }756    } while (true);757    workPhase = prevWorkPhase;758    resetContextDependencies();759    ReactCurrentDispatcher.current = prevDispatcher;760    if (enableSchedulerTracing) {761      __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);762    }763    if (workInProgress !== null) {764      // There's still work left over. Return a continuation.765      stopInterruptedWorkLoopTimer();766      if (expirationTime !== Sync) {767        startRequestCallbackTimer();768      }769      return renderRoot.bind(null, root, expirationTime);770    }771  }772  // We now have a consistent tree. The next step is either to commit it, or, if773  // something suspended, wait to commit it after a timeout.774  stopFinishedWorkLoopTimer();775  const isLocked = resolveLocksOnRoot(root, expirationTime);776  if (isLocked) {777    // This root has a lock that prevents it from committing. Exit. If we begin778    // work on the root again, without any intervening updates, it will finish779    // without doing additional work.780    return null;781  }782  // Set this to null to indicate there's no in-progress render.783  workInProgressRoot = null;784  switch (workInProgressRootExitStatus) {785    case RootIncomplete: {786      invariant(false, 'Should have a work-in-progress.');787    }788    // Flow knows about invariant, so it compains if I add a break statement,789    // but eslint doesn't know about invariant, so it complains if I do.790    // eslint-disable-next-line no-fallthrough791    case RootErrored: {792      // An error was thrown. First check if there is lower priority work793      // scheduled on this root.794      const lastPendingTime = root.lastPendingTime;795      if (root.lastPendingTime < expirationTime) {796        // There's lower priority work. Before raising the error, try rendering797        // at the lower priority to see if it fixes it. Use a continuation to798        // maintain the existing priority and position in the queue.799        return renderRoot.bind(null, root, lastPendingTime);800      }801      if (!isSync) {802        // If we're rendering asynchronously, it's possible the error was803        // caused by tearing due to a mutation during an event. Try rendering804        // one more time without yiedling to events.805        prepareFreshStack(root, expirationTime);806        scheduleCallback(807          ImmediatePriority,808          renderRoot.bind(null, root, expirationTime),809        );810        return null;811      }812      // If we're already rendering synchronously, commit the root in its813      // errored state.814      return commitRoot.bind(null, root, expirationTime);815    }816    case RootSuspended: {817      if (!isSync) {818        const lastPendingTime = root.lastPendingTime;819        if (root.lastPendingTime < expirationTime) {820          // There's lower priority work. It might be unsuspended. Try rendering821          // at that level.822          return renderRoot.bind(null, root, lastPendingTime);823        }824        // If workInProgressRootMostRecentEventTime is Sync, that means we didn't825        // track any event times. That can happen if we retried but nothing switched826        // from fallback to content. There's no reason to delay doing no work.827        if (workInProgressRootMostRecentEventTime !== Sync) {828          let msUntilTimeout = computeMsUntilTimeout(829            workInProgressRootMostRecentEventTime,830            expirationTime,831          );832          // Don't bother with a very short suspense time.833          if (msUntilTimeout > 10) {834            // The render is suspended, it hasn't timed out, and there's no lower835            // priority work to do. Instead of committing the fallback836            // immediately, wait for more data to arrive.837            root.timeoutHandle = scheduleTimeout(838              commitRoot.bind(null, root, expirationTime),839              msUntilTimeout,840            );841            return null;842          }843        }844      }845      // The work expired. Commit immediately.846      return commitRoot.bind(null, root, expirationTime);847    }848    case RootCompleted: {849      // The work completed. Ready to commit.850      return commitRoot.bind(null, root, expirationTime);851    }852    default: {853      invariant(false, 'Unknown root exit status.');854    }855  }856}857export function markRenderEventTime(expirationTime: ExpirationTime): void {858  if (expirationTime < workInProgressRootMostRecentEventTime) {859    workInProgressRootMostRecentEventTime = expirationTime;860  }861}862export function renderDidSuspend(): void {863  if (workInProgressRootExitStatus === RootIncomplete) {864    workInProgressRootExitStatus = RootSuspended;865  }866}867export function renderDidError() {868  if (869    workInProgressRootExitStatus === RootIncomplete ||870    workInProgressRootExitStatus === RootSuspended871  ) {872    workInProgressRootExitStatus = RootErrored;873  }874}875function inferTimeFromExpirationTime(expirationTime: ExpirationTime): number {876  // We don't know exactly when the update was scheduled, but we can infer an877  // approximate start time from the expiration time.878  const earliestExpirationTimeMs = expirationTimeToMs(expirationTime);879  return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;880}881function workLoopSync() {882  // Already timed out, so perform work without checking if we need to yield.883  while (workInProgress !== null) {884    workInProgress = performUnitOfWork(workInProgress);885  }886}887function workLoop() {888  // Perform work until Scheduler asks us to yield889  while (workInProgress !== null && !shouldYield()) {890    workInProgress = performUnitOfWork(workInProgress);891  }892}893function performUnitOfWork(unitOfWork: Fiber): Fiber | null {894  // The current, flushed, state of this fiber is the alternate. Ideally895  // nothing should rely on this, but relying on it here means that we don't896  // need an additional field on the work in progress.897  const current = unitOfWork.alternate;898  startWorkTimer(unitOfWork);899  setCurrentDebugFiberInDEV(unitOfWork);900  let next;901  if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) {902    startProfilerTimer(unitOfWork);903    next = beginWork(current, unitOfWork, renderExpirationTime);904    stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);905  } else {906    next = beginWork(current, unitOfWork, renderExpirationTime);907  }908  resetCurrentDebugFiberInDEV();909  unitOfWork.memoizedProps = unitOfWork.pendingProps;910  if (next === null) {911    // If this doesn't spawn new work, complete the current work.912    next = completeUnitOfWork(unitOfWork);913  }914  ReactCurrentOwner.current = null;915  return next;916}917function completeUnitOfWork(unitOfWork: Fiber): Fiber | null {918  // Attempt to complete the current unit of work, then move to the next919  // sibling. If there are no more siblings, return to the parent fiber.920  workInProgress = unitOfWork;921  do {922    // The current, flushed, state of this fiber is the alternate. Ideally923    // nothing should rely on this, but relying on it here means that we don't924    // need an additional field on the work in progress.925    const current = workInProgress.alternate;926    const returnFiber = workInProgress.return;927    // Check if the work completed or if something threw.928    if ((workInProgress.effectTag & Incomplete) === NoEffect) {929      setCurrentDebugFiberInDEV(workInProgress);930      let next;931      if (932        !enableProfilerTimer ||933        (workInProgress.mode & ProfileMode) === NoContext934      ) {935        next = completeWork(current, workInProgress, renderExpirationTime);936      } else {937        startProfilerTimer(workInProgress);938        next = completeWork(current, workInProgress, renderExpirationTime);939        // Update render duration assuming we didn't error.940        stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);941      }942      stopWorkTimer(workInProgress);943      resetCurrentDebugFiberInDEV();944      resetChildExpirationTime(workInProgress);945      if (next !== null) {946        // Completing this fiber spawned new work. Work on that next.947        return next;948      }949      if (950        returnFiber !== null &&951        // Do not append effects to parents if a sibling failed to complete952        (returnFiber.effectTag & Incomplete) === NoEffect953      ) {954        // Append all the effects of the subtree and this fiber onto the effect955        // list of the parent. The completion order of the children affects the956        // side-effect order.957        if (returnFiber.firstEffect === null) {958          returnFiber.firstEffect = workInProgress.firstEffect;959        }960        if (workInProgress.lastEffect !== null) {961          if (returnFiber.lastEffect !== null) {962            returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;963          }964          returnFiber.lastEffect = workInProgress.lastEffect;965        }966        // If this fiber had side-effects, we append it AFTER the children's967        // side-effects. We can perform certain side-effects earlier if needed,968        // by doing multiple passes over the effect list. We don't want to969        // schedule our own side-effect on our own list because if end up970        // reusing children we'll schedule this effect onto itself since we're971        // at the end.972        const effectTag = workInProgress.effectTag;973        // Skip both NoWork and PerformedWork tags when creating the effect974        // list. PerformedWork effect is read by React DevTools but shouldn't be975        // committed.976        if (effectTag > PerformedWork) {977          if (returnFiber.lastEffect !== null) {978            returnFiber.lastEffect.nextEffect = workInProgress;979          } else {980            returnFiber.firstEffect = workInProgress;981          }982          returnFiber.lastEffect = workInProgress;983        }984      }985    } else {986      // This fiber did not complete because something threw. Pop values off987      // the stack without entering the complete phase. If this is a boundary,988      // capture values if possible.989      const next = unwindWork(workInProgress, renderExpirationTime);990      // Because this fiber did not complete, don't reset its expiration time.991      if (992        enableProfilerTimer &&993        (workInProgress.mode & ProfileMode) !== NoContext994      ) {995        // Record the render duration for the fiber that errored.996        stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);997        // Include the time spent working on failed children before continuing.998        let actualDuration = workInProgress.actualDuration;999        let child = workInProgress.child;1000        while (child !== null) {1001          actualDuration += child.actualDuration;1002          child = child.sibling;1003        }1004        workInProgress.actualDuration = actualDuration;1005      }1006      if (next !== null) {1007        // If completing this work spawned new work, do that next. We'll come1008        // back here again.1009        // Since we're restarting, remove anything that is not a host effect1010        // from the effect tag.1011        // TODO: The name stopFailedWorkTimer is misleading because Suspense1012        // also captures and restarts.1013        stopFailedWorkTimer(workInProgress);1014        next.effectTag &= HostEffectMask;1015        return next;1016      }1017      stopWorkTimer(workInProgress);1018      if (returnFiber !== null) {1019        // Mark the parent fiber as incomplete and clear its effect list.1020        returnFiber.firstEffect = returnFiber.lastEffect = null;1021        returnFiber.effectTag |= Incomplete;1022      }1023    }1024    const siblingFiber = workInProgress.sibling;1025    if (siblingFiber !== null) {1026      // If there is more work to do in this returnFiber, do that next.1027      return siblingFiber;1028    }1029    // Otherwise, return to the parent1030    workInProgress = returnFiber;1031  } while (workInProgress !== null);1032  // We've reached the root.1033  if (workInProgressRootExitStatus === RootIncomplete) {1034    workInProgressRootExitStatus = RootCompleted;1035  }1036  return null;1037}1038function resetChildExpirationTime(completedWork: Fiber) {1039  if (1040    renderExpirationTime !== Never &&1041    completedWork.childExpirationTime === Never1042  ) {1043    // The children of this component are hidden. Don't bubble their1044    // expiration times.1045    return;1046  }1047  let newChildExpirationTime = NoWork;1048  // Bubble up the earliest expiration time.1049  if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) {1050    // In profiling mode, resetChildExpirationTime is also used to reset1051    // profiler durations.1052    let actualDuration = completedWork.actualDuration;1053    let treeBaseDuration = completedWork.selfBaseDuration;1054    // When a fiber is cloned, its actualDuration is reset to 0. This value will1055    // only be updated if work is done on the fiber (i.e. it doesn't bailout).1056    // When work is done, it should bubble to the parent's actualDuration. If1057    // the fiber has not been cloned though, (meaning no work was done), then1058    // this value will reflect the amount of time spent working on a previous1059    // render. In that case it should not bubble. We determine whether it was1060    // cloned by comparing the child pointer.1061    const shouldBubbleActualDurations =1062      completedWork.alternate === null ||1063      completedWork.child !== completedWork.alternate.child;1064    let child = completedWork.child;1065    while (child !== null) {1066      const childUpdateExpirationTime = child.expirationTime;1067      const childChildExpirationTime = child.childExpirationTime;1068      if (childUpdateExpirationTime > newChildExpirationTime) {1069        newChildExpirationTime = childUpdateExpirationTime;1070      }1071      if (childChildExpirationTime > newChildExpirationTime) {1072        newChildExpirationTime = childChildExpirationTime;1073      }1074      if (shouldBubbleActualDurations) {1075        actualDuration += child.actualDuration;1076      }1077      treeBaseDuration += child.treeBaseDuration;1078      child = child.sibling;1079    }1080    completedWork.actualDuration = actualDuration;1081    completedWork.treeBaseDuration = treeBaseDuration;1082  } else {1083    let child = completedWork.child;1084    while (child !== null) {1085      const childUpdateExpirationTime = child.expirationTime;1086      const childChildExpirationTime = child.childExpirationTime;1087      if (childUpdateExpirationTime > newChildExpirationTime) {1088        newChildExpirationTime = childUpdateExpirationTime;1089      }1090      if (childChildExpirationTime > newChildExpirationTime) {1091        newChildExpirationTime = childChildExpirationTime;1092      }1093      child = child.sibling;1094    }1095  }1096  completedWork.childExpirationTime = newChildExpirationTime;1097}1098function commitRoot(root, expirationTime) {1099  runWithPriority(1100    ImmediatePriority,1101    commitRootImpl.bind(null, root, expirationTime),1102  );1103  // If there are passive effects, schedule a callback to flush them. This goes1104  // outside commitRootImpl so that it inherits the priority of the render.1105  if (rootWithPendingPassiveEffects !== null) {1106    const priorityLevel = getCurrentPriorityLevel();1107    scheduleCallback(priorityLevel, () => {1108      flushPassiveEffects();1109      return null;1110    });1111  }1112  return null;1113}1114function commitRootImpl(root, expirationTime) {1115  flushPassiveEffects();1116  flushRenderPhaseStrictModeWarningsInDEV();1117  invariant(1118    workPhase !== RenderPhase && workPhase !== CommitPhase,1119    'Should not already be working.',1120  );1121  const finishedWork = root.current.alternate;1122  invariant(finishedWork !== null, 'Should have a work-in-progress root.');1123  // commitRoot never returns a continuation; it always finishes synchronously.1124  // So we can clear these now to allow a new callback to be scheduled.1125  root.callbackNode = null;1126  root.callbackExpirationTime = NoWork;1127  startCommitTimer();1128  // Update the first and last pending times on this root. The new first1129  // pending time is whatever is left on the root fiber.1130  const updateExpirationTimeBeforeCommit = finishedWork.expirationTime;1131  const childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;1132  const firstPendingTimeBeforeCommit =1133    childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit1134      ? childExpirationTimeBeforeCommit1135      : updateExpirationTimeBeforeCommit;1136  root.firstPendingTime = firstPendingTimeBeforeCommit;1137  if (firstPendingTimeBeforeCommit < root.lastPendingTime) {1138    // This usually means we've finished all the work, but it can also happen1139    // when something gets downprioritized during render, like a hidden tree.1140    root.lastPendingTime = firstPendingTimeBeforeCommit;1141  }1142  if (root === workInProgressRoot) {1143    // We can reset these now that they are finished.1144    workInProgressRoot = null;1145    workInProgress = null;1146    renderExpirationTime = NoWork;1147  } else {1148    // This indicates that the last root we worked on is not the same one that1149    // we're committing now. This most commonly happens when a suspended root1150    // times out.1151  }1152  // Get the list of effects.1153  let firstEffect;1154  if (finishedWork.effectTag > PerformedWork) {1155    // A fiber's effect list consists only of its children, not itself. So if1156    // the root has an effect, we need to add it to the end of the list. The1157    // resulting list is the set that would belong to the root's parent, if it1158    // had one; that is, all the effects in the tree including the root.1159    if (finishedWork.lastEffect !== null) {1160      finishedWork.lastEffect.nextEffect = finishedWork;1161      firstEffect = finishedWork.firstEffect;1162    } else {1163      firstEffect = finishedWork;1164    }1165  } else {1166    // There is no effect on the root.1167    firstEffect = finishedWork.firstEffect;1168  }1169  if (firstEffect !== null) {1170    const prevWorkPhase = workPhase;1171    workPhase = CommitPhase;1172    let prevInteractions: Set<Interaction> | null = null;1173    if (enableSchedulerTracing) {1174      prevInteractions = __interactionsRef.current;1175      __interactionsRef.current = root.memoizedInteractions;1176    }1177    // Reset this to null before calling lifecycles1178    ReactCurrentOwner.current = null;1179    // The commit phase is broken into several sub-phases. We do a separate pass1180    // of the effect list for each phase: all mutation effects come before all1181    // layout effects, and so on.1182    // The first phase a "before mutation" phase. We use this phase to read the1183    // state of the host tree right before we mutate it. This is where1184    // getSnapshotBeforeUpdate is called.1185    startCommitSnapshotEffectsTimer();1186    prepareForCommit(root.containerInfo);1187    nextEffect = firstEffect;1188    do {1189      if (__DEV__) {1190        invokeGuardedCallback(null, commitBeforeMutationEffects, null);1191        if (hasCaughtError()) {1192          invariant(nextEffect !== null, 'Should be working on an effect.');1193          const error = clearCaughtError();1194          captureCommitPhaseError(nextEffect, error);1195          nextEffect = nextEffect.nextEffect;1196        }1197      } else {1198        try {1199          commitBeforeMutationEffects();1200        } catch (error) {1201          invariant(nextEffect !== null, 'Should be working on an effect.');1202          captureCommitPhaseError(nextEffect, error);1203          nextEffect = nextEffect.nextEffect;1204        }1205      }1206    } while (nextEffect !== null);1207    stopCommitSnapshotEffectsTimer();1208    if (enableProfilerTimer) {1209      // Mark the current commit time to be shared by all Profilers in this1210      // batch. This enables them to be grouped later.1211      recordCommitTime();1212    }1213    // The next phase is the mutation phase, where we mutate the host tree.1214    startCommitHostEffectsTimer();1215    nextEffect = firstEffect;1216    do {1217      if (__DEV__) {1218        invokeGuardedCallback(null, commitMutationEffects, null);1219        if (hasCaughtError()) {1220          invariant(nextEffect !== null, 'Should be working on an effect.');1221          const error = clearCaughtError();1222          captureCommitPhaseError(nextEffect, error);1223          nextEffect = nextEffect.nextEffect;1224        }1225      } else {1226        try {1227          commitMutationEffects();1228        } catch (error) {1229          invariant(nextEffect !== null, 'Should be working on an effect.');1230          captureCommitPhaseError(nextEffect, error);1231          nextEffect = nextEffect.nextEffect;1232        }1233      }1234    } while (nextEffect !== null);1235    stopCommitHostEffectsTimer();1236    resetAfterCommit(root.containerInfo);1237    // The work-in-progress tree is now the current tree. This must come after1238    // the mutation phase, so that the previous tree is still current during1239    // componentWillUnmount, but before the layout phase, so that the finished1240    // work is current during componentDidMount/Update.1241    root.current = finishedWork;1242    // The next phase is the layout phase, where we call effects that read1243    // the host tree after it's been mutated. The idiomatic use case for this is1244    // layout, but class component lifecycles also fire here for legacy reasons.1245    startCommitLifeCyclesTimer();1246    nextEffect = firstEffect;1247    do {1248      if (__DEV__) {1249        invokeGuardedCallback(1250          null,1251          commitLayoutEffects,1252          null,1253          root,1254          expirationTime,1255        );1256        if (hasCaughtError()) {1257          invariant(nextEffect !== null, 'Should be working on an effect.');1258          const error = clearCaughtError();1259          captureCommitPhaseError(nextEffect, error);1260          nextEffect = nextEffect.nextEffect;1261        }1262      } else {1263        try {1264          commitLayoutEffects(root, expirationTime);1265        } catch (error) {1266          invariant(nextEffect !== null, 'Should be working on an effect.');1267          captureCommitPhaseError(nextEffect, error);1268          nextEffect = nextEffect.nextEffect;1269        }1270      }1271    } while (nextEffect !== null);1272    stopCommitLifeCyclesTimer();1273    nextEffect = null;1274    if (enableSchedulerTracing) {1275      __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1276    }1277    workPhase = prevWorkPhase;1278  } else {1279    // No effects.1280    root.current = finishedWork;1281    // Measure these anyway so the flamegraph explicitly shows that there were1282    // no effects.1283    // TODO: Maybe there's a better way to report this.1284    startCommitSnapshotEffectsTimer();1285    stopCommitSnapshotEffectsTimer();1286    if (enableProfilerTimer) {1287      recordCommitTime();1288    }1289    startCommitHostEffectsTimer();1290    stopCommitHostEffectsTimer();1291    startCommitLifeCyclesTimer();1292    stopCommitLifeCyclesTimer();1293  }1294  stopCommitTimer();1295  if (rootDoesHavePassiveEffects) {1296    // This commit has passive effects. Stash a reference to them. But don't1297    // schedule a callback until after flushing layout work.1298    rootDoesHavePassiveEffects = false;1299    rootWithPendingPassiveEffects = root;1300    pendingPassiveEffectsExpirationTime = expirationTime;1301  } else {1302    if (enableSchedulerTracing) {1303      // If there are no passive effects, then we can complete the pending1304      // interactions. Otherwise, we'll wait until after the passive effects1305      // are flushed.1306      finishPendingInteractions(root, expirationTime);1307    }1308  }1309  // Check if there's remaining work on this root1310  const remainingExpirationTime = root.firstPendingTime;1311  if (remainingExpirationTime !== NoWork) {1312    const currentTime = requestCurrentTime();1313    const priorityLevel = inferPriorityFromExpirationTime(1314      currentTime,1315      remainingExpirationTime,1316    );1317    scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);1318  } else {1319    // If there's no remaining work, we can clear the set of already failed1320    // error boundaries.1321    legacyErrorBoundariesThatAlreadyFailed = null;1322  }1323  onCommitRoot(finishedWork.stateNode);1324  if (remainingExpirationTime === Sync) {1325    // Count the number of times the root synchronously re-renders without1326    // finishing. If there are too many, it indicates an infinite update loop.1327    if (root === rootWithNestedUpdates) {1328      nestedUpdateCount++;1329    } else {1330      nestedUpdateCount = 0;1331      rootWithNestedUpdates = root;1332    }1333  } else {1334    nestedUpdateCount = 0;1335  }1336  if (hasUncaughtError) {1337    hasUncaughtError = false;1338    const error = firstUncaughtError;1339    firstUncaughtError = null;1340    throw error;1341  }1342  if (workPhase === LegacyUnbatchedPhase) {1343    // This is a legacy edge case. We just committed the initial mount of1344    // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired1345    // synchronously, but layout updates should be deferred until the end1346    // of the batch.1347    return null;1348  }1349  // If layout work was scheduled, flush it now.1350  flushImmediateQueue();1351  return null;1352}1353function commitBeforeMutationEffects() {1354  while (nextEffect !== null) {1355    if ((nextEffect.effectTag & Snapshot) !== NoEffect) {1356      setCurrentDebugFiberInDEV(nextEffect);1357      recordEffect();1358      const current = nextEffect.alternate;1359      commitBeforeMutationEffectOnFiber(current, nextEffect);1360      resetCurrentDebugFiberInDEV();1361    }1362    nextEffect = nextEffect.nextEffect;1363  }1364}1365function commitMutationEffects() {1366  // TODO: Should probably move the bulk of this function to commitWork.1367  while (nextEffect !== null) {1368    setCurrentDebugFiberInDEV(nextEffect);1369    const effectTag = nextEffect.effectTag;1370    if (effectTag & ContentReset) {1371      commitResetTextContent(nextEffect);1372    }1373    if (effectTag & Ref) {1374      const current = nextEffect.alternate;1375      if (current !== null) {1376        commitDetachRef(current);1377      }1378    }1379    // The following switch statement is only concerned about placement,1380    // updates, and deletions. To avoid needing to add a case for every possible1381    // bitmap value, we remove the secondary effects from the effect tag and1382    // switch on that value.1383    let primaryEffectTag = effectTag & (Placement | Update | Deletion);1384    switch (primaryEffectTag) {1385      case Placement: {1386        commitPlacement(nextEffect);1387        // Clear the "placement" from effect tag so that we know that this is1388        // inserted, before any life-cycles like componentDidMount gets called.1389        // TODO: findDOMNode doesn't rely on this any more but isMounted does1390        // and isMounted is deprecated anyway so we should be able to kill this.1391        nextEffect.effectTag &= ~Placement;1392        break;1393      }1394      case PlacementAndUpdate: {1395        // Placement1396        commitPlacement(nextEffect);1397        // Clear the "placement" from effect tag so that we know that this is1398        // inserted, before any life-cycles like componentDidMount gets called.1399        nextEffect.effectTag &= ~Placement;1400        // Update1401        const current = nextEffect.alternate;1402        commitWork(current, nextEffect);1403        break;1404      }1405      case Update: {1406        const current = nextEffect.alternate;1407        commitWork(current, nextEffect);1408        break;1409      }1410      case Deletion: {1411        commitDeletion(nextEffect);1412        break;1413      }1414    }1415    // TODO: Only record a mutation effect if primaryEffectTag is non-zero.1416    recordEffect();1417    resetCurrentDebugFiberInDEV();1418    nextEffect = nextEffect.nextEffect;1419  }1420}1421function commitLayoutEffects(1422  root: FiberRoot,1423  committedExpirationTime: ExpirationTime,1424) {1425  // TODO: Should probably move the bulk of this function to commitWork.1426  while (nextEffect !== null) {1427    setCurrentDebugFiberInDEV(nextEffect);1428    const effectTag = nextEffect.effectTag;1429    if (effectTag & (Update | Callback)) {1430      recordEffect();1431      const current = nextEffect.alternate;1432      commitLayoutEffectOnFiber(1433        root,1434        current,1435        nextEffect,1436        committedExpirationTime,1437      );1438    }1439    if (effectTag & Ref) {1440      recordEffect();1441      commitAttachRef(nextEffect);1442    }1443    if (effectTag & Passive) {1444      rootDoesHavePassiveEffects = true;1445    }1446    resetCurrentDebugFiberInDEV();1447    nextEffect = nextEffect.nextEffect;1448  }1449}1450export function flushPassiveEffects() {1451  if (rootWithPendingPassiveEffects === null) {1452    return false;1453  }1454  const root = rootWithPendingPassiveEffects;1455  const expirationTime = pendingPassiveEffectsExpirationTime;1456  rootWithPendingPassiveEffects = null;1457  pendingPassiveEffectsExpirationTime = NoWork;1458  let prevInteractions: Set<Interaction> | null = null;1459  if (enableSchedulerTracing) {1460    prevInteractions = __interactionsRef.current;1461    __interactionsRef.current = root.memoizedInteractions;1462  }1463  invariant(1464    workPhase !== RenderPhase && workPhase !== CommitPhase,1465    'Cannot flush passive effects while already rendering.',1466  );1467  const prevWorkPhase = workPhase;1468  workPhase = CommitPhase;1469  // Note: This currently assumes there are no passive effects on the root1470  // fiber, because the root is not part of its own effect list. This could1471  // change in the future.1472  let effect = root.current.firstEffect;1473  while (effect !== null) {1474    if (__DEV__) {1475      setCurrentDebugFiberInDEV(effect);1476      invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);1477      if (hasCaughtError()) {1478        invariant(effect !== null, 'Should be working on an effect.');1479        const error = clearCaughtError();1480        captureCommitPhaseError(effect, error);1481      }1482      resetCurrentDebugFiberInDEV();1483    } else {1484      try {1485        commitPassiveHookEffects(effect);1486      } catch (error) {1487        invariant(effect !== null, 'Should be working on an effect.');1488        captureCommitPhaseError(effect, error);1489      }1490    }1491    effect = effect.nextEffect;1492  }1493  if (enableSchedulerTracing) {1494    __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1495    finishPendingInteractions(root, expirationTime);1496  }1497  workPhase = prevWorkPhase;1498  flushImmediateQueue();1499  // If additional passive effects were scheduled, increment a counter. If this1500  // exceeds the limit, we'll fire a warning.1501  nestedPassiveUpdateCount =1502    rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1503  return true;1504}1505export function isAlreadyFailedLegacyErrorBoundary(instance: mixed): boolean {1506  return (1507    legacyErrorBoundariesThatAlreadyFailed !== null &&1508    legacyErrorBoundariesThatAlreadyFailed.has(instance)1509  );1510}1511export function markLegacyErrorBoundaryAsFailed(instance: mixed) {1512  if (legacyErrorBoundariesThatAlreadyFailed === null) {1513    legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1514  } else {1515    legacyErrorBoundariesThatAlreadyFailed.add(instance);1516  }1517}1518function prepareToThrowUncaughtError(error: mixed) {1519  if (!hasUncaughtError) {1520    hasUncaughtError = true;1521    firstUncaughtError = error;1522  }1523}1524export const onUncaughtError = prepareToThrowUncaughtError;1525function captureCommitPhaseErrorOnRoot(1526  rootFiber: Fiber,1527  sourceFiber: Fiber,1528  error: mixed,1529) {1530  const errorInfo = createCapturedValue(error, sourceFiber);1531  const update = createRootErrorUpdate(rootFiber, errorInfo, Sync);1532  enqueueUpdate(rootFiber, update);1533  const root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);1534  if (root !== null) {1535    scheduleCallbackForRoot(root, ImmediatePriority, Sync);1536  }1537}1538export function captureCommitPhaseError(sourceFiber: Fiber, error: mixed) {1539  if (sourceFiber.tag === HostRoot) {1540    // Error was thrown at the root. There is no parent, so the root1541    // itself should capture it.1542    captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1543    return;1544  }1545  let fiber = sourceFiber.return;1546  while (fiber !== null) {1547    if (fiber.tag === HostRoot) {1548      captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1549      return;1550    } else if (fiber.tag === ClassComponent) {1551      const ctor = fiber.type;1552      const instance = fiber.stateNode;1553      if (1554        typeof ctor.getDerivedStateFromError === 'function' ||1555        (typeof instance.componentDidCatch === 'function' &&1556          !isAlreadyFailedLegacyErrorBoundary(instance))1557      ) {1558        const errorInfo = createCapturedValue(error, sourceFiber);1559        const update = createClassErrorUpdate(1560          fiber,1561          errorInfo,1562          // TODO: This is always sync1563          Sync,1564        );1565        enqueueUpdate(fiber, update);1566        const root = markUpdateTimeFromFiberToRoot(fiber, Sync);1567        if (root !== null) {1568          scheduleCallbackForRoot(root, ImmediatePriority, Sync);1569        }1570        return;1571      }1572    }1573    fiber = fiber.return;1574  }1575}1576export function pingSuspendedRoot(1577  root: FiberRoot,1578  thenable: Thenable,1579  suspendedTime: ExpirationTime,1580) {1581  const pingCache = root.pingCache;1582  if (pingCache !== null) {1583    // The thenable resolved, so we no longer need to memoize, because it will1584    // never be thrown again.1585    pingCache.delete(thenable);1586  }1587  if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {1588    // Received a ping at the same priority level at which we're currently1589    // rendering. Restart from the root. Don't need to schedule a ping because1590    // we're already working on this tree.1591    prepareFreshStack(root, renderExpirationTime);1592    return;1593  }1594  const lastPendingTime = root.lastPendingTime;1595  if (lastPendingTime < suspendedTime) {1596    // The root is no longer suspended at this time.1597    return;1598  }1599  const pingTime = root.pingTime;1600  if (pingTime !== NoWork && pingTime < suspendedTime) {1601    // There's already a lower priority ping scheduled.1602    return;1603  }1604  // Mark the time at which this ping was scheduled.1605  root.pingTime = suspendedTime;1606  const currentTime = requestCurrentTime();1607  const priorityLevel = inferPriorityFromExpirationTime(1608    currentTime,1609    suspendedTime,1610  );1611  scheduleCallbackForRoot(root, priorityLevel, suspendedTime);1612}1613export function retryTimedOutBoundary(boundaryFiber: Fiber) {1614  // The boundary fiber (a Suspense component) previously timed out and was1615  // rendered in its fallback state. One of the promises that suspended it has1616  // resolved, which means at least part of the tree was likely unblocked. Try1617  // rendering again, at a new expiration time.1618  const currentTime = requestCurrentTime();1619  const retryTime = computeExpirationForFiber(currentTime, boundaryFiber);1620  // TODO: Special case idle priority?1621  const priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);1622  const root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);1623  if (root !== null) {1624    scheduleCallbackForRoot(root, priorityLevel, retryTime);1625  }1626}1627export function resolveRetryThenable(boundaryFiber: Fiber, thenable: Thenable) {1628  let retryCache: WeakSet<Thenable> | Set<Thenable> | null;1629  if (enableSuspenseServerRenderer) {1630    switch (boundaryFiber.tag) {1631      case SuspenseComponent:1632        retryCache = boundaryFiber.stateNode;1633        break;1634      case DehydratedSuspenseComponent:1635        retryCache = boundaryFiber.memoizedState;1636        break;1637      default:1638        invariant(1639          false,1640          'Pinged unknown suspense boundary type. ' +1641            'This is probably a bug in React.',1642        );1643    }1644  } else {1645    retryCache = boundaryFiber.stateNode;1646  }1647  if (retryCache !== null) {1648    // The thenable resolved, so we no longer need to memoize, because it will1649    // never be thrown again.1650    retryCache.delete(thenable);1651  }1652  retryTimedOutBoundary(boundaryFiber);1653}1654// Computes the next Just Noticeable Difference (JND) boundary.1655// The theory is that a person can't tell the difference between small differences in time.1656// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable1657// difference in the experience. However, waiting for longer might mean that we can avoid1658// showing an intermediate loading state. The longer we have already waited, the harder it1659// is to tell small differences in time. Therefore, the longer we've already waited,1660// the longer we can wait additionally. At some point we have to give up though.1661// We pick a train model where the next boundary commits at a consistent schedule.1662// These particular numbers are vague estimates. We expect to adjust them based on research.1663function jnd(timeElapsed: number) {1664  return timeElapsed < 1201665    ? 1201666    : timeElapsed < 4801667      ? 4801668      : timeElapsed < 10801669        ? 10801670        : timeElapsed < 19201671          ? 19201672          : timeElapsed < 30001673            ? 30001674            : timeElapsed < 43201675              ? 43201676              : ceil(timeElapsed / 1960) * 1960;1677}1678function computeMsUntilTimeout(1679  mostRecentEventTime: ExpirationTime,1680  committedExpirationTime: ExpirationTime,1681) {1682  if (disableYielding) {1683    // Timeout immediately when yielding is disabled.1684    return 0;1685  }1686  const eventTimeMs: number = inferTimeFromExpirationTime(mostRecentEventTime);1687  const currentTimeMs: number = now();1688  const timeElapsed = currentTimeMs - eventTimeMs;1689  let msUntilTimeout = jnd(timeElapsed) - timeElapsed;1690  // Compute the time until this render pass would expire.1691  const timeUntilExpirationMs =1692    expirationTimeToMs(committedExpirationTime) - currentTimeMs;1693  // Clamp the timeout to the expiration time.1694  // TODO: Once the event time is exact instead of inferred from expiration time1695  // we don't need this.1696  if (timeUntilExpirationMs < msUntilTimeout) {1697    msUntilTimeout = timeUntilExpirationMs;1698  }1699  // This is the value that is passed to `setTimeout`.1700  return msUntilTimeout;1701}1702function checkForNestedUpdates() {1703  if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {1704    nestedUpdateCount = 0;1705    rootWithNestedUpdates = null;1706    invariant(1707      false,1708      'Maximum update depth exceeded. This can happen when a component ' +1709        'repeatedly calls setState inside componentWillUpdate or ' +1710        'componentDidUpdate. React limits the number of nested updates to ' +1711        'prevent infinite loops.',1712    );1713  }1714  if (__DEV__) {1715    if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {1716      nestedPassiveUpdateCount = 0;1717      warning(1718        false,1719        'Maximum update depth exceeded. This can happen when a component ' +1720          "calls setState inside useEffect, but useEffect either doesn't " +1721          'have a dependency array, or one of the dependencies changes on ' +1722          'every render.',1723      );1724    }1725  }1726}1727function flushRenderPhaseStrictModeWarningsInDEV() {1728  if (__DEV__) {1729    ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();1730    ReactStrictModeWarnings.flushLegacyContextWarning();1731    if (warnAboutDeprecatedLifecycles) {1732      ReactStrictModeWarnings.flushPendingDeprecationWarnings();1733    }1734  }1735}1736function stopFinishedWorkLoopTimer() {1737  const didCompleteRoot = true;1738  stopWorkLoopTimer(interruptedBy, didCompleteRoot);1739  interruptedBy = null;1740}1741function stopInterruptedWorkLoopTimer() {1742  // TODO: Track which fiber caused the interruption.1743  const didCompleteRoot = false;1744  stopWorkLoopTimer(interruptedBy, didCompleteRoot);1745  interruptedBy = null;1746}1747function checkForInterruption(1748  fiberThatReceivedUpdate: Fiber,1749  updateExpirationTime: ExpirationTime,1750) {1751  if (1752    enableUserTimingAPI &&1753    workInProgressRoot !== null &&1754    updateExpirationTime > renderExpirationTime1755  ) {1756    interruptedBy = fiberThatReceivedUpdate;1757  }1758}1759let didWarnStateUpdateForUnmountedComponent: Set<string> | null = null;1760function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {1761  if (__DEV__) {1762    const tag = fiber.tag;1763    if (1764      tag !== HostRoot &&1765      tag !== ClassComponent &&1766      tag !== FunctionComponent &&1767      tag !== ForwardRef &&1768      tag !== MemoComponent &&1769      tag !== SimpleMemoComponent1770    ) {1771      // Only warn for user-defined components, not internal ones like Suspense.1772      return;1773    }1774    // We show the whole stack but dedupe on the top component's name because1775    // the problematic code almost always lies inside that component.1776    const componentName = getComponentName(fiber.type) || 'ReactComponent';1777    if (didWarnStateUpdateForUnmountedComponent !== null) {1778      if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {1779        return;1780      }1781      didWarnStateUpdateForUnmountedComponent.add(componentName);1782    } else {1783      didWarnStateUpdateForUnmountedComponent = new Set([componentName]);1784    }1785    warningWithoutStack(1786      false,1787      "Can't perform a React state update on an unmounted component. This " +1788        'is a no-op, but it indicates a memory leak in your application. To ' +1789        'fix, cancel all subscriptions and asynchronous tasks in %s.%s',1790      tag === ClassComponent1791        ? 'the componentWillUnmount method'1792        : 'a useEffect cleanup function',1793      getStackByFiberInDevAndProd(fiber),1794    );1795  }1796}1797let beginWork;1798if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {1799  let dummyFiber = null;1800  beginWork = (current, unitOfWork, expirationTime) => {1801    // If a component throws an error, we replay it again in a synchronously1802    // dispatched event, so that the debugger will treat it as an uncaught1803    // error See ReactErrorUtils for more information.1804    // Before entering the begin phase, copy the work-in-progress onto a dummy1805    // fiber. If beginWork throws, we'll use this to reset the state.1806    const originalWorkInProgressCopy = assignFiberPropertiesInDEV(1807      dummyFiber,1808      unitOfWork,1809    );1810    try {1811      return originalBeginWork(current, unitOfWork, expirationTime);1812    } catch (originalError) {1813      if (1814        originalError !== null &&1815        typeof originalError === 'object' &&1816        typeof originalError.then === 'function'1817      ) {1818        // Don't replay promises. Treat everything else like an error.1819        throw originalError;1820      }1821      // Keep this code in sync with renderRoot; any changes here must have1822      // corresponding changes there.1823      resetContextDependencies();1824      resetHooks();1825      // Unwind the failed stack frame1826      unwindInterruptedWork(unitOfWork);1827      // Restore the original properties of the fiber.1828      assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);1829      if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {1830        // Reset the profiler timer.1831        startProfilerTimer(unitOfWork);1832      }1833      // Run beginWork again.1834      invokeGuardedCallback(1835        null,1836        originalBeginWork,1837        null,...ReactFiberScheduler.new.js
Source:ReactFiberScheduler.new.js  
...689        const currentTime = requestCurrentTime();690        if (currentTime < expirationTime) {691          // Restart at the current time.692          workPhase = prevWorkPhase;693          resetContextDependencies();694          ReactCurrentDispatcher.current = prevDispatcher;695          if (enableSchedulerTracing) {696            __interactionsRef.current = ((prevInteractions: any): Set<697              Interaction,698            >);699          }700          return renderRoot.bind(null, root, currentTime);701        }702      }703    } else {704      // Since we know we're in a React event, we can clear the current705      // event time. The next update will compute a new event time.706      currentEventTime = NoWork;707    }708    do {709      try {710        if (isSync) {711          workLoopSync();712        } else {713          workLoop();714        }715        break;716      } catch (thrownValue) {717        // Reset module-level state that was set during the render phase.718        resetContextDependencies();719        resetHooks();720        const sourceFiber = workInProgress;721        if (sourceFiber === null || sourceFiber.return === null) {722          // Expected to be working on a non-root fiber. This is a fatal error723          // because there's no ancestor that can handle it; the root is724          // supposed to capture all errors that weren't caught by an error725          // boundary.726          prepareFreshStack(root, expirationTime);727          workPhase = prevWorkPhase;728          throw thrownValue;729        }730        if (enableProfilerTimer && sourceFiber.mode & ProfileMode) {731          // Record the time spent rendering before an error was thrown. This732          // avoids inaccurate Profiler durations in the case of a733          // suspended render.734          stopProfilerTimerIfRunningAndRecordDelta(sourceFiber, true);735        }736        const returnFiber = sourceFiber.return;737        throwException(738          root,739          returnFiber,740          sourceFiber,741          thrownValue,742          renderExpirationTime,743        );744        workInProgress = completeUnitOfWork(sourceFiber);745      }746    } while (true);747    workPhase = prevWorkPhase;748    resetContextDependencies();749    ReactCurrentDispatcher.current = prevDispatcher;750    if (enableSchedulerTracing) {751      __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);752    }753    if (workInProgress !== null) {754      // There's still work left over. Return a continuation.755      stopInterruptedWorkLoopTimer();756      if (expirationTime !== Sync) {757        startRequestCallbackTimer();758      }759      return renderRoot.bind(null, root, expirationTime);760    }761  }762  // We now have a consistent tree. The next step is either to commit it, or, if763  // something suspended, wait to commit it after a timeout.764  stopFinishedWorkLoopTimer();765  const isLocked = resolveLocksOnRoot(root, expirationTime);766  if (isLocked) {767    // This root has a lock that prevents it from committing. Exit. If we begin768    // work on the root again, without any intervening updates, it will finish769    // without doing additional work.770    return null;771  }772  // Set this to null to indicate there's no in-progress render.773  workInProgressRoot = null;774  switch (workInProgressRootExitStatus) {775    case RootIncomplete: {776      invariant(false, 'Should have a work-in-progress.');777    }778    // Flow knows about invariant, so it compains if I add a break statement,779    // but eslint doesn't know about invariant, so it complains if I do.780    // eslint-disable-next-line no-fallthrough781    case RootErrored: {782      // An error was thrown. First check if there is lower priority work783      // scheduled on this root.784      const lastPendingTime = root.lastPendingTime;785      if (root.lastPendingTime < expirationTime) {786        // There's lower priority work. Before raising the error, try rendering787        // at the lower priority to see if it fixes it. Use a continuation to788        // maintain the existing priority and position in the queue.789        return renderRoot.bind(null, root, lastPendingTime);790      }791      if (!isSync) {792        // If we're rendering asynchronously, it's possible the error was793        // caused by tearing due to a mutation during an event. Try rendering794        // one more time without yiedling to events.795        prepareFreshStack(root, expirationTime);796        scheduleCallback(797          ImmediatePriority,798          renderRoot.bind(null, root, expirationTime),799        );800        return null;801      }802      // If we're already rendering synchronously, commit the root in its803      // errored state.804      return commitRoot.bind(null, root, expirationTime);805    }806    case RootSuspended: {807      const lastPendingTime = root.lastPendingTime;808      if (root.lastPendingTime < expirationTime) {809        // There's lower priority work. It might be unsuspended. Try rendering810        // at that level.811        return renderRoot.bind(null, root, lastPendingTime);812      }813      if (!isSync) {814        const msUntilTimeout = computeMsUntilTimeout(815          root,816          workInProgressRootAbsoluteTimeoutMs,817        );818        if (msUntilTimeout > 0) {819          // The render is suspended, it hasn't timed out, and there's no lower820          // priority work to do. Instead of committing the fallback821          // immediately, wait for more data to arrive.822          root.timeoutHandle = scheduleTimeout(823            commitRoot.bind(null, root, expirationTime),824            msUntilTimeout,825          );826          return null;827        }828      }829      // The work expired. Commit immediately.830      return commitRoot.bind(null, root, expirationTime);831    }832    case RootCompleted: {833      // The work completed. Ready to commit.834      return commitRoot.bind(null, root, expirationTime);835    }836    default: {837      invariant(false, 'Unknown root exit status.');838    }839  }840}841export function renderDidSuspend(842  root: FiberRoot,843  absoluteTimeoutMs: number,844  // TODO: Don't need this argument anymore845  suspendedTime: ExpirationTime,846) {847  if (848    absoluteTimeoutMs >= 0 &&849    workInProgressRootAbsoluteTimeoutMs < absoluteTimeoutMs850  ) {851    workInProgressRootAbsoluteTimeoutMs = absoluteTimeoutMs;852    if (workInProgressRootExitStatus === RootIncomplete) {853      workInProgressRootExitStatus = RootSuspended;854    }855  }856}857export function renderDidError() {858  if (859    workInProgressRootExitStatus === RootIncomplete ||860    workInProgressRootExitStatus === RootSuspended861  ) {862    workInProgressRootExitStatus = RootErrored;863  }864}865function workLoopSync() {866  // Already timed out, so perform work without checking if we need to yield.867  while (workInProgress !== null) {868    workInProgress = performUnitOfWork(workInProgress);869  }870}871function workLoop() {872  // Perform work until Scheduler asks us to yield873  while (workInProgress !== null && !shouldYield()) {874    workInProgress = performUnitOfWork(workInProgress);875  }876}877function performUnitOfWork(unitOfWork: Fiber): Fiber | null {878  // The current, flushed, state of this fiber is the alternate. Ideally879  // nothing should rely on this, but relying on it here means that we don't880  // need an additional field on the work in progress.881  const current = unitOfWork.alternate;882  startWorkTimer(unitOfWork);883  setCurrentDebugFiberInDEV(unitOfWork);884  let next;885  if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoContext) {886    startProfilerTimer(unitOfWork);887    next = beginWork(current, unitOfWork, renderExpirationTime);888    stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);889  } else {890    next = beginWork(current, unitOfWork, renderExpirationTime);891  }892  resetCurrentDebugFiberInDEV();893  unitOfWork.memoizedProps = unitOfWork.pendingProps;894  if (next === null) {895    // If this doesn't spawn new work, complete the current work.896    next = completeUnitOfWork(unitOfWork);897  }898  ReactCurrentOwner.current = null;899  return next;900}901function completeUnitOfWork(unitOfWork: Fiber): Fiber | null {902  // Attempt to complete the current unit of work, then move to the next903  // sibling. If there are no more siblings, return to the parent fiber.904  workInProgress = unitOfWork;905  do {906    // The current, flushed, state of this fiber is the alternate. Ideally907    // nothing should rely on this, but relying on it here means that we don't908    // need an additional field on the work in progress.909    const current = workInProgress.alternate;910    const returnFiber = workInProgress.return;911    // Check if the work completed or if something threw.912    if ((workInProgress.effectTag & Incomplete) === NoEffect) {913      setCurrentDebugFiberInDEV(workInProgress);914      let next;915      if (916        !enableProfilerTimer ||917        (workInProgress.mode & ProfileMode) === NoContext918      ) {919        next = completeWork(current, workInProgress, renderExpirationTime);920      } else {921        startProfilerTimer(workInProgress);922        next = completeWork(current, workInProgress, renderExpirationTime);923        // Update render duration assuming we didn't error.924        stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);925      }926      stopWorkTimer(workInProgress);927      resetCurrentDebugFiberInDEV();928      resetChildExpirationTime(workInProgress);929      if (next !== null) {930        // Completing this fiber spawned new work. Work on that next.931        return next;932      }933      if (934        returnFiber !== null &&935        // Do not append effects to parents if a sibling failed to complete936        (returnFiber.effectTag & Incomplete) === NoEffect937      ) {938        // Append all the effects of the subtree and this fiber onto the effect939        // list of the parent. The completion order of the children affects the940        // side-effect order.941        if (returnFiber.firstEffect === null) {942          returnFiber.firstEffect = workInProgress.firstEffect;943        }944        if (workInProgress.lastEffect !== null) {945          if (returnFiber.lastEffect !== null) {946            returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;947          }948          returnFiber.lastEffect = workInProgress.lastEffect;949        }950        // If this fiber had side-effects, we append it AFTER the children's951        // side-effects. We can perform certain side-effects earlier if needed,952        // by doing multiple passes over the effect list. We don't want to953        // schedule our own side-effect on our own list because if end up954        // reusing children we'll schedule this effect onto itself since we're955        // at the end.956        const effectTag = workInProgress.effectTag;957        // Skip both NoWork and PerformedWork tags when creating the effect958        // list. PerformedWork effect is read by React DevTools but shouldn't be959        // committed.960        if (effectTag > PerformedWork) {961          if (returnFiber.lastEffect !== null) {962            returnFiber.lastEffect.nextEffect = workInProgress;963          } else {964            returnFiber.firstEffect = workInProgress;965          }966          returnFiber.lastEffect = workInProgress;967        }968      }969    } else {970      // This fiber did not complete because something threw. Pop values off971      // the stack without entering the complete phase. If this is a boundary,972      // capture values if possible.973      const next = unwindWork(workInProgress, renderExpirationTime);974      // Because this fiber did not complete, don't reset its expiration time.975      if (976        enableProfilerTimer &&977        (workInProgress.mode & ProfileMode) !== NoContext978      ) {979        // Record the render duration for the fiber that errored.980        stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);981        // Include the time spent working on failed children before continuing.982        let actualDuration = workInProgress.actualDuration;983        let child = workInProgress.child;984        while (child !== null) {985          actualDuration += child.actualDuration;986          child = child.sibling;987        }988        workInProgress.actualDuration = actualDuration;989      }990      if (next !== null) {991        // If completing this work spawned new work, do that next. We'll come992        // back here again.993        // Since we're restarting, remove anything that is not a host effect994        // from the effect tag.995        // TODO: The name stopFailedWorkTimer is misleading because Suspense996        // also captures and restarts.997        stopFailedWorkTimer(workInProgress);998        next.effectTag &= HostEffectMask;999        return next;1000      }1001      stopWorkTimer(workInProgress);1002      if (returnFiber !== null) {1003        // Mark the parent fiber as incomplete and clear its effect list.1004        returnFiber.firstEffect = returnFiber.lastEffect = null;1005        returnFiber.effectTag |= Incomplete;1006      }1007    }1008    const siblingFiber = workInProgress.sibling;1009    if (siblingFiber !== null) {1010      // If there is more work to do in this returnFiber, do that next.1011      return siblingFiber;1012    }1013    // Otherwise, return to the parent1014    workInProgress = returnFiber;1015  } while (workInProgress !== null);1016  // We've reached the root.1017  if (workInProgressRootExitStatus === RootIncomplete) {1018    workInProgressRootExitStatus = RootCompleted;1019  }1020  return null;1021}1022function resetChildExpirationTime(completedWork: Fiber) {1023  if (1024    renderExpirationTime !== Never &&1025    completedWork.childExpirationTime === Never1026  ) {1027    // The children of this component are hidden. Don't bubble their1028    // expiration times.1029    return;1030  }1031  let newChildExpirationTime = NoWork;1032  // Bubble up the earliest expiration time.1033  if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoContext) {1034    // In profiling mode, resetChildExpirationTime is also used to reset1035    // profiler durations.1036    let actualDuration = completedWork.actualDuration;1037    let treeBaseDuration = completedWork.selfBaseDuration;1038    // When a fiber is cloned, its actualDuration is reset to 0. This value will1039    // only be updated if work is done on the fiber (i.e. it doesn't bailout).1040    // When work is done, it should bubble to the parent's actualDuration. If1041    // the fiber has not been cloned though, (meaning no work was done), then1042    // this value will reflect the amount of time spent working on a previous1043    // render. In that case it should not bubble. We determine whether it was1044    // cloned by comparing the child pointer.1045    const shouldBubbleActualDurations =1046      completedWork.alternate === null ||1047      completedWork.child !== completedWork.alternate.child;1048    let child = completedWork.child;1049    while (child !== null) {1050      const childUpdateExpirationTime = child.expirationTime;1051      const childChildExpirationTime = child.childExpirationTime;1052      if (childUpdateExpirationTime > newChildExpirationTime) {1053        newChildExpirationTime = childUpdateExpirationTime;1054      }1055      if (childChildExpirationTime > newChildExpirationTime) {1056        newChildExpirationTime = childChildExpirationTime;1057      }1058      if (shouldBubbleActualDurations) {1059        actualDuration += child.actualDuration;1060      }1061      treeBaseDuration += child.treeBaseDuration;1062      child = child.sibling;1063    }1064    completedWork.actualDuration = actualDuration;1065    completedWork.treeBaseDuration = treeBaseDuration;1066  } else {1067    let child = completedWork.child;1068    while (child !== null) {1069      const childUpdateExpirationTime = child.expirationTime;1070      const childChildExpirationTime = child.childExpirationTime;1071      if (childUpdateExpirationTime > newChildExpirationTime) {1072        newChildExpirationTime = childUpdateExpirationTime;1073      }1074      if (childChildExpirationTime > newChildExpirationTime) {1075        newChildExpirationTime = childChildExpirationTime;1076      }1077      child = child.sibling;1078    }1079  }1080  completedWork.childExpirationTime = newChildExpirationTime;1081}1082function commitRoot(root, expirationTime) {1083  runWithPriority(1084    ImmediatePriority,1085    commitRootImpl.bind(null, root, expirationTime),1086  );1087  // If there are passive effects, schedule a callback to flush them. This goes1088  // outside commitRootImpl so that it inherits the priority of the render.1089  if (rootWithPendingPassiveEffects !== null) {1090    const priorityLevel = getCurrentPriorityLevel();1091    scheduleCallback(priorityLevel, () => {1092      flushPassiveEffects();1093      return null;1094    });1095  }1096  return null;1097}1098function commitRootImpl(root, expirationTime) {1099  flushPassiveEffects();1100  flushRenderPhaseStrictModeWarningsInDEV();1101  invariant(1102    workPhase !== RenderPhase && workPhase !== CommitPhase,1103    'Should not already be working.',1104  );1105  const finishedWork = root.current.alternate;1106  invariant(finishedWork !== null, 'Should have a work-in-progress root.');1107  // commitRoot never returns a continuation; it always finishes synchronously.1108  // So we can clear these now to allow a new callback to be scheduled.1109  root.callbackNode = null;1110  root.callbackExpirationTime = NoWork;1111  startCommitTimer();1112  // Update the first and last pending times on this root. The new first1113  // pending time is whatever is left on the root fiber.1114  const updateExpirationTimeBeforeCommit = finishedWork.expirationTime;1115  const childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;1116  const firstPendingTimeBeforeCommit =1117    childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit1118      ? childExpirationTimeBeforeCommit1119      : updateExpirationTimeBeforeCommit;1120  root.firstPendingTime = firstPendingTimeBeforeCommit;1121  if (firstPendingTimeBeforeCommit < root.lastPendingTime) {1122    // This usually means we've finished all the work, but it can also happen1123    // when something gets downprioritized during render, like a hidden tree.1124    root.lastPendingTime = firstPendingTimeBeforeCommit;1125  }1126  if (root === workInProgressRoot) {1127    // We can reset these now that they are finished.1128    workInProgressRoot = null;1129    workInProgress = null;1130    renderExpirationTime = NoWork;1131  } else {1132    // This indicates that the last root we worked on is not the same one that1133    // we're committing now. This most commonly happens when a suspended root1134    // times out.1135  }1136  // Get the list of effects.1137  let firstEffect;1138  if (finishedWork.effectTag > PerformedWork) {1139    // A fiber's effect list consists only of its children, not itself. So if1140    // the root has an effect, we need to add it to the end of the list. The1141    // resulting list is the set that would belong to the root's parent, if it1142    // had one; that is, all the effects in the tree including the root.1143    if (finishedWork.lastEffect !== null) {1144      finishedWork.lastEffect.nextEffect = finishedWork;1145      firstEffect = finishedWork.firstEffect;1146    } else {1147      firstEffect = finishedWork;1148    }1149  } else {1150    // There is no effect on the root.1151    firstEffect = finishedWork.firstEffect;1152  }1153  if (firstEffect !== null) {1154    const prevWorkPhase = workPhase;1155    workPhase = CommitPhase;1156    let prevInteractions: Set<Interaction> | null = null;1157    if (enableSchedulerTracing) {1158      prevInteractions = __interactionsRef.current;1159      __interactionsRef.current = root.memoizedInteractions;1160    }1161    // Reset this to null before calling lifecycles1162    ReactCurrentOwner.current = null;1163    // The commit phase is broken into several sub-phases. We do a separate pass1164    // of the effect list for each phase: all mutation effects come before all1165    // layout effects, and so on.1166    // The first phase a "before mutation" phase. We use this phase to read the1167    // state of the host tree right before we mutate it. This is where1168    // getSnapshotBeforeUpdate is called.1169    startCommitSnapshotEffectsTimer();1170    prepareForCommit(root.containerInfo);1171    nextEffect = firstEffect;1172    do {1173      if (__DEV__) {1174        invokeGuardedCallback(null, commitBeforeMutationEffects, null);1175        if (hasCaughtError()) {1176          invariant(nextEffect !== null, 'Should be working on an effect.');1177          const error = clearCaughtError();1178          captureCommitPhaseError(nextEffect, error);1179          nextEffect = nextEffect.nextEffect;1180        }1181      } else {1182        try {1183          commitBeforeMutationEffects();1184        } catch (error) {1185          invariant(nextEffect !== null, 'Should be working on an effect.');1186          captureCommitPhaseError(nextEffect, error);1187          nextEffect = nextEffect.nextEffect;1188        }1189      }1190    } while (nextEffect !== null);1191    stopCommitSnapshotEffectsTimer();1192    if (enableProfilerTimer) {1193      // Mark the current commit time to be shared by all Profilers in this1194      // batch. This enables them to be grouped later.1195      recordCommitTime();1196    }1197    // The next phase is the mutation phase, where we mutate the host tree.1198    startCommitHostEffectsTimer();1199    nextEffect = firstEffect;1200    do {1201      if (__DEV__) {1202        invokeGuardedCallback(null, commitMutationEffects, null);1203        if (hasCaughtError()) {1204          invariant(nextEffect !== null, 'Should be working on an effect.');1205          const error = clearCaughtError();1206          captureCommitPhaseError(nextEffect, error);1207          nextEffect = nextEffect.nextEffect;1208        }1209      } else {1210        try {1211          commitMutationEffects();1212        } catch (error) {1213          invariant(nextEffect !== null, 'Should be working on an effect.');1214          captureCommitPhaseError(nextEffect, error);1215          nextEffect = nextEffect.nextEffect;1216        }1217      }1218    } while (nextEffect !== null);1219    stopCommitHostEffectsTimer();1220    resetAfterCommit(root.containerInfo);1221    // The work-in-progress tree is now the current tree. This must come after1222    // the mutation phase, so that the previous tree is still current during1223    // componentWillUnmount, but before the layout phase, so that the finished1224    // work is current during componentDidMount/Update.1225    root.current = finishedWork;1226    // The next phase is the layout phase, where we call effects that read1227    // the host tree after it's been mutated. The idiomatic use case for this is1228    // layout, but class component lifecycles also fire here for legacy reasons.1229    startCommitLifeCyclesTimer();1230    nextEffect = firstEffect;1231    do {1232      if (__DEV__) {1233        invokeGuardedCallback(1234          null,1235          commitLayoutEffects,1236          null,1237          root,1238          expirationTime,1239        );1240        if (hasCaughtError()) {1241          invariant(nextEffect !== null, 'Should be working on an effect.');1242          const error = clearCaughtError();1243          captureCommitPhaseError(nextEffect, error);1244          nextEffect = nextEffect.nextEffect;1245        }1246      } else {1247        try {1248          commitLayoutEffects(root, expirationTime);1249        } catch (error) {1250          invariant(nextEffect !== null, 'Should be working on an effect.');1251          captureCommitPhaseError(nextEffect, error);1252          nextEffect = nextEffect.nextEffect;1253        }1254      }1255    } while (nextEffect !== null);1256    stopCommitLifeCyclesTimer();1257    nextEffect = null;1258    if (enableSchedulerTracing) {1259      __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1260    }1261    workPhase = prevWorkPhase;1262  } else {1263    // No effects.1264    root.current = finishedWork;1265    // Measure these anyway so the flamegraph explicitly shows that there were1266    // no effects.1267    // TODO: Maybe there's a better way to report this.1268    startCommitSnapshotEffectsTimer();1269    stopCommitSnapshotEffectsTimer();1270    if (enableProfilerTimer) {1271      recordCommitTime();1272    }1273    startCommitHostEffectsTimer();1274    stopCommitHostEffectsTimer();1275    startCommitLifeCyclesTimer();1276    stopCommitLifeCyclesTimer();1277  }1278  stopCommitTimer();1279  if (rootDoesHavePassiveEffects) {1280    // This commit has passive effects. Stash a reference to them. But don't1281    // schedule a callback until after flushing layout work.1282    rootDoesHavePassiveEffects = false;1283    rootWithPendingPassiveEffects = root;1284    pendingPassiveEffectsExpirationTime = expirationTime;1285  } else {1286    if (enableSchedulerTracing) {1287      // If there are no passive effects, then we can complete the pending1288      // interactions. Otherwise, we'll wait until after the passive effects1289      // are flushed.1290      finishPendingInteractions(root, expirationTime);1291    }1292  }1293  // Check if there's remaining work on this root1294  const remainingExpirationTime = root.firstPendingTime;1295  if (remainingExpirationTime !== NoWork) {1296    const currentTime = requestCurrentTime();1297    const priorityLevel = inferPriorityFromExpirationTime(1298      currentTime,1299      remainingExpirationTime,1300    );1301    scheduleCallbackForRoot(root, priorityLevel, remainingExpirationTime);1302  } else {1303    // If there's no remaining work, we can clear the set of already failed1304    // error boundaries.1305    legacyErrorBoundariesThatAlreadyFailed = null;1306  }1307  onCommitRoot(finishedWork.stateNode);1308  if (remainingExpirationTime === Sync) {1309    // Count the number of times the root synchronously re-renders without1310    // finishing. If there are too many, it indicates an infinite update loop.1311    if (root === rootWithNestedUpdates) {1312      nestedUpdateCount++;1313    } else {1314      nestedUpdateCount = 0;1315      rootWithNestedUpdates = root;1316    }1317  } else {1318    nestedUpdateCount = 0;1319  }1320  if (hasUncaughtError) {1321    hasUncaughtError = false;1322    const error = firstUncaughtError;1323    firstUncaughtError = null;1324    throw error;1325  }1326  if (workPhase === LegacyUnbatchedPhase) {1327    // This is a legacy edge case. We just committed the initial mount of1328    // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired1329    // synchronously, but layout updates should be deferred until the end1330    // of the batch.1331    return null;1332  }1333  // If layout work was scheduled, flush it now.1334  flushImmediateQueue();1335  return null;1336}1337function commitBeforeMutationEffects() {1338  while (nextEffect !== null) {1339    if ((nextEffect.effectTag & Snapshot) !== NoEffect) {1340      setCurrentDebugFiberInDEV(nextEffect);1341      recordEffect();1342      const current = nextEffect.alternate;1343      commitBeforeMutationEffectOnFiber(current, nextEffect);1344      resetCurrentDebugFiberInDEV();1345    }1346    nextEffect = nextEffect.nextEffect;1347  }1348}1349function commitMutationEffects() {1350  // TODO: Should probably move the bulk of this function to commitWork.1351  while (nextEffect !== null) {1352    setCurrentDebugFiberInDEV(nextEffect);1353    const effectTag = nextEffect.effectTag;1354    if (effectTag & ContentReset) {1355      commitResetTextContent(nextEffect);1356    }1357    if (effectTag & Ref) {1358      const current = nextEffect.alternate;1359      if (current !== null) {1360        commitDetachRef(current);1361      }1362    }1363    // The following switch statement is only concerned about placement,1364    // updates, and deletions. To avoid needing to add a case for every possible1365    // bitmap value, we remove the secondary effects from the effect tag and1366    // switch on that value.1367    let primaryEffectTag = effectTag & (Placement | Update | Deletion);1368    switch (primaryEffectTag) {1369      case Placement: {1370        commitPlacement(nextEffect);1371        // Clear the "placement" from effect tag so that we know that this is1372        // inserted, before any life-cycles like componentDidMount gets called.1373        // TODO: findDOMNode doesn't rely on this any more but isMounted does1374        // and isMounted is deprecated anyway so we should be able to kill this.1375        nextEffect.effectTag &= ~Placement;1376        break;1377      }1378      case PlacementAndUpdate: {1379        // Placement1380        commitPlacement(nextEffect);1381        // Clear the "placement" from effect tag so that we know that this is1382        // inserted, before any life-cycles like componentDidMount gets called.1383        nextEffect.effectTag &= ~Placement;1384        // Update1385        const current = nextEffect.alternate;1386        commitWork(current, nextEffect);1387        break;1388      }1389      case Update: {1390        const current = nextEffect.alternate;1391        commitWork(current, nextEffect);1392        break;1393      }1394      case Deletion: {1395        commitDeletion(nextEffect);1396        break;1397      }1398    }1399    // TODO: Only record a mutation effect if primaryEffectTag is non-zero.1400    recordEffect();1401    resetCurrentDebugFiberInDEV();1402    nextEffect = nextEffect.nextEffect;1403  }1404}1405function commitLayoutEffects(1406  root: FiberRoot,1407  committedExpirationTime: ExpirationTime,1408) {1409  // TODO: Should probably move the bulk of this function to commitWork.1410  while (nextEffect !== null) {1411    setCurrentDebugFiberInDEV(nextEffect);1412    const effectTag = nextEffect.effectTag;1413    if (effectTag & (Update | Callback)) {1414      recordEffect();1415      const current = nextEffect.alternate;1416      commitLayoutEffectOnFiber(1417        root,1418        current,1419        nextEffect,1420        committedExpirationTime,1421      );1422    }1423    if (effectTag & Ref) {1424      recordEffect();1425      commitAttachRef(nextEffect);1426    }1427    if (effectTag & Passive) {1428      rootDoesHavePassiveEffects = true;1429    }1430    resetCurrentDebugFiberInDEV();1431    nextEffect = nextEffect.nextEffect;1432  }1433}1434export function flushPassiveEffects() {1435  if (rootWithPendingPassiveEffects === null) {1436    return false;1437  }1438  const root = rootWithPendingPassiveEffects;1439  const expirationTime = pendingPassiveEffectsExpirationTime;1440  rootWithPendingPassiveEffects = null;1441  pendingPassiveEffectsExpirationTime = NoWork;1442  let prevInteractions: Set<Interaction> | null = null;1443  if (enableSchedulerTracing) {1444    prevInteractions = __interactionsRef.current;1445    __interactionsRef.current = root.memoizedInteractions;1446  }1447  invariant(1448    workPhase !== RenderPhase && workPhase !== CommitPhase,1449    'Cannot flush passive effects while already rendering.',1450  );1451  const prevWorkPhase = workPhase;1452  workPhase = CommitPhase;1453  // Note: This currently assumes there are no passive effects on the root1454  // fiber, because the root is not part of its own effect list. This could1455  // change in the future.1456  let effect = root.current.firstEffect;1457  while (effect !== null) {1458    if (__DEV__) {1459      setCurrentDebugFiberInDEV(effect);1460      invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);1461      if (hasCaughtError()) {1462        invariant(effect !== null, 'Should be working on an effect.');1463        const error = clearCaughtError();1464        captureCommitPhaseError(effect, error);1465      }1466      resetCurrentDebugFiberInDEV();1467    } else {1468      try {1469        commitPassiveHookEffects(effect);1470      } catch (error) {1471        invariant(effect !== null, 'Should be working on an effect.');1472        captureCommitPhaseError(effect, error);1473      }1474    }1475    effect = effect.nextEffect;1476  }1477  if (enableSchedulerTracing) {1478    __interactionsRef.current = ((prevInteractions: any): Set<Interaction>);1479    finishPendingInteractions(root, expirationTime);1480  }1481  workPhase = prevWorkPhase;1482  flushImmediateQueue();1483  // If additional passive effects were scheduled, increment a counter. If this1484  // exceeds the limit, we'll fire a warning.1485  nestedPassiveUpdateCount =1486    rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;1487  return true;1488}1489export function isAlreadyFailedLegacyErrorBoundary(instance: mixed): boolean {1490  return (1491    legacyErrorBoundariesThatAlreadyFailed !== null &&1492    legacyErrorBoundariesThatAlreadyFailed.has(instance)1493  );1494}1495export function markLegacyErrorBoundaryAsFailed(instance: mixed) {1496  if (legacyErrorBoundariesThatAlreadyFailed === null) {1497    legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);1498  } else {1499    legacyErrorBoundariesThatAlreadyFailed.add(instance);1500  }1501}1502function prepareToThrowUncaughtError(error: mixed) {1503  if (!hasUncaughtError) {1504    hasUncaughtError = true;1505    firstUncaughtError = error;1506  }1507}1508export const onUncaughtError = prepareToThrowUncaughtError;1509function captureCommitPhaseErrorOnRoot(1510  rootFiber: Fiber,1511  sourceFiber: Fiber,1512  error: mixed,1513) {1514  const errorInfo = createCapturedValue(error, sourceFiber);1515  const update = createRootErrorUpdate(rootFiber, errorInfo, Sync);1516  enqueueUpdate(rootFiber, update);1517  const root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);1518  if (root !== null) {1519    scheduleCallbackForRoot(root, ImmediatePriority, Sync);1520  }1521}1522export function captureCommitPhaseError(sourceFiber: Fiber, error: mixed) {1523  if (sourceFiber.tag === HostRoot) {1524    // Error was thrown at the root. There is no parent, so the root1525    // itself should capture it.1526    captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);1527    return;1528  }1529  let fiber = sourceFiber.return;1530  while (fiber !== null) {1531    if (fiber.tag === HostRoot) {1532      captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);1533      return;1534    } else if (fiber.tag === ClassComponent) {1535      const ctor = fiber.type;1536      const instance = fiber.stateNode;1537      if (1538        typeof ctor.getDerivedStateFromError === 'function' ||1539        (typeof instance.componentDidCatch === 'function' &&1540          !isAlreadyFailedLegacyErrorBoundary(instance))1541      ) {1542        const errorInfo = createCapturedValue(error, sourceFiber);1543        const update = createClassErrorUpdate(1544          fiber,1545          errorInfo,1546          // TODO: This is always sync1547          Sync,1548        );1549        enqueueUpdate(fiber, update);1550        const root = markUpdateTimeFromFiberToRoot(fiber, Sync);1551        if (root !== null) {1552          scheduleCallbackForRoot(root, ImmediatePriority, Sync);1553        }1554        return;1555      }1556    }1557    fiber = fiber.return;1558  }1559}1560export function pingSuspendedRoot(1561  root: FiberRoot,1562  thenable: Thenable,1563  suspendedTime: ExpirationTime,1564) {1565  const pingCache = root.pingCache;1566  if (pingCache !== null) {1567    // The thenable resolved, so we no longer need to memoize, because it will1568    // never be thrown again.1569    pingCache.delete(thenable);1570  }1571  if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {1572    // Received a ping at the same priority level at which we're currently1573    // rendering. Restart from the root. Don't need to schedule a ping because1574    // we're already working on this tree.1575    prepareFreshStack(root, renderExpirationTime);1576    return;1577  }1578  const lastPendingTime = root.lastPendingTime;1579  if (lastPendingTime < suspendedTime) {1580    // The root is no longer suspended at this time.1581    return;1582  }1583  const pingTime = root.pingTime;1584  if (pingTime !== NoWork && pingTime < suspendedTime) {1585    // There's already a lower priority ping scheduled.1586    return;1587  }1588  // Mark the time at which this ping was scheduled.1589  root.pingTime = suspendedTime;1590  const currentTime = requestCurrentTime();1591  const priorityLevel = inferPriorityFromExpirationTime(1592    currentTime,1593    suspendedTime,1594  );1595  scheduleCallbackForRoot(root, priorityLevel, suspendedTime);1596}1597export function retryTimedOutBoundary(boundaryFiber: Fiber) {1598  // The boundary fiber (a Suspense component) previously timed out and was1599  // rendered in its fallback state. One of the promises that suspended it has1600  // resolved, which means at least part of the tree was likely unblocked. Try1601  // rendering again, at a new expiration time.1602  const currentTime = requestCurrentTime();1603  const retryTime = computeExpirationForFiber(currentTime, boundaryFiber);1604  // TODO: Special case idle priority?1605  const priorityLevel = inferPriorityFromExpirationTime(currentTime, retryTime);1606  const root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);1607  if (root !== null) {1608    scheduleCallbackForRoot(root, priorityLevel, retryTime);1609  }1610}1611export function resolveRetryThenable(boundaryFiber: Fiber, thenable: Thenable) {1612  let retryCache: WeakSet<Thenable> | Set<Thenable> | null;1613  if (enableSuspenseServerRenderer) {1614    switch (boundaryFiber.tag) {1615      case SuspenseComponent:1616        retryCache = boundaryFiber.stateNode;1617        break;1618      case DehydratedSuspenseComponent:1619        retryCache = boundaryFiber.memoizedState;1620        break;1621      default:1622        invariant(1623          false,1624          'Pinged unknown suspense boundary type. ' +1625            'This is probably a bug in React.',1626        );1627    }1628  } else {1629    retryCache = boundaryFiber.stateNode;1630  }1631  if (retryCache !== null) {1632    // The thenable resolved, so we no longer need to memoize, because it will1633    // never be thrown again.1634    retryCache.delete(thenable);1635  }1636  retryTimedOutBoundary(boundaryFiber);1637}1638export function inferStartTimeFromExpirationTime(1639  root: FiberRoot,1640  expirationTime: ExpirationTime,1641) {1642  // We don't know exactly when the update was scheduled, but we can infer an1643  // approximate start time from the expiration time.1644  const earliestExpirationTimeMs = expirationTimeToMs(root.firstPendingTime);1645  // TODO: Track this on the root instead. It's more accurate, doesn't rely on1646  // assumptions about priority, and isn't coupled to Scheduler details.1647  return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;1648}1649function computeMsUntilTimeout(root, absoluteTimeoutMs) {1650  if (disableYielding) {1651    // Timeout immediately when yielding is disabled.1652    return 0;1653  }1654  // Find the earliest uncommitted expiration time in the tree, including1655  // work that is suspended. The timeout threshold cannot be longer than1656  // the overall expiration.1657  const earliestExpirationTimeMs = expirationTimeToMs(root.firstPendingTime);1658  if (earliestExpirationTimeMs < absoluteTimeoutMs) {1659    absoluteTimeoutMs = earliestExpirationTimeMs;1660  }1661  // Subtract the current time from the absolute timeout to get the number1662  // of milliseconds until the timeout. In other words, convert an absolute1663  // timestamp to a relative time. This is the value that is passed1664  // to `setTimeout`.1665  let msUntilTimeout = absoluteTimeoutMs - now();1666  return msUntilTimeout < 0 ? 0 : msUntilTimeout;1667}1668function checkForNestedUpdates() {1669  if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {1670    nestedUpdateCount = 0;1671    rootWithNestedUpdates = null;1672    invariant(1673      false,1674      'Maximum update depth exceeded. This can happen when a component ' +1675        'repeatedly calls setState inside componentWillUpdate or ' +1676        'componentDidUpdate. React limits the number of nested updates to ' +1677        'prevent infinite loops.',1678    );1679  }1680  if (__DEV__) {1681    if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {1682      nestedPassiveUpdateCount = 0;1683      warning(1684        false,1685        'Maximum update depth exceeded. This can happen when a component ' +1686          "calls setState inside useEffect, but useEffect either doesn't " +1687          'have a dependency array, or one of the dependencies changes on ' +1688          'every render.',1689      );1690    }1691  }1692}1693function flushRenderPhaseStrictModeWarningsInDEV() {1694  if (__DEV__) {1695    ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();1696    ReactStrictModeWarnings.flushLegacyContextWarning();1697    if (warnAboutDeprecatedLifecycles) {1698      ReactStrictModeWarnings.flushPendingDeprecationWarnings();1699    }1700  }1701}1702function stopFinishedWorkLoopTimer() {1703  const didCompleteRoot = true;1704  stopWorkLoopTimer(interruptedBy, didCompleteRoot);1705  interruptedBy = null;1706}1707function stopInterruptedWorkLoopTimer() {1708  // TODO: Track which fiber caused the interruption.1709  const didCompleteRoot = false;1710  stopWorkLoopTimer(interruptedBy, didCompleteRoot);1711  interruptedBy = null;1712}1713function checkForInterruption(1714  fiberThatReceivedUpdate: Fiber,1715  updateExpirationTime: ExpirationTime,1716) {1717  if (1718    enableUserTimingAPI &&1719    workInProgressRoot !== null &&1720    updateExpirationTime > renderExpirationTime1721  ) {1722    interruptedBy = fiberThatReceivedUpdate;1723  }1724}1725let didWarnStateUpdateForUnmountedComponent: Set<string> | null = null;1726function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {1727  if (__DEV__) {1728    const tag = fiber.tag;1729    if (1730      tag !== HostRoot &&1731      tag !== ClassComponent &&1732      tag !== FunctionComponent &&1733      tag !== ForwardRef &&1734      tag !== MemoComponent &&1735      tag !== SimpleMemoComponent1736    ) {1737      // Only warn for user-defined components, not internal ones like Suspense.1738      return;1739    }1740    // We show the whole stack but dedupe on the top component's name because1741    // the problematic code almost always lies inside that component.1742    const componentName = getComponentName(fiber.type) || 'ReactComponent';1743    if (didWarnStateUpdateForUnmountedComponent !== null) {1744      if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {1745        return;1746      }1747      didWarnStateUpdateForUnmountedComponent.add(componentName);1748    } else {1749      didWarnStateUpdateForUnmountedComponent = new Set([componentName]);1750    }1751    warningWithoutStack(1752      false,1753      "Can't perform a React state update on an unmounted component. This " +1754        'is a no-op, but it indicates a memory leak in your application. To ' +1755        'fix, cancel all subscriptions and asynchronous tasks in %s.%s',1756      tag === ClassComponent1757        ? 'the componentWillUnmount method'1758        : 'a useEffect cleanup function',1759      getStackByFiberInDevAndProd(fiber),1760    );1761  }1762}1763let beginWork;1764if (__DEV__ && replayFailedUnitOfWorkWithInvokeGuardedCallback) {1765  let dummyFiber = null;1766  beginWork = (current, unitOfWork, expirationTime) => {1767    // If a component throws an error, we replay it again in a synchronously1768    // dispatched event, so that the debugger will treat it as an uncaught1769    // error See ReactErrorUtils for more information.1770    // Before entering the begin phase, copy the work-in-progress onto a dummy1771    // fiber. If beginWork throws, we'll use this to reset the state.1772    const originalWorkInProgressCopy = assignFiberPropertiesInDEV(1773      dummyFiber,1774      unitOfWork,1775    );1776    try {1777      return originalBeginWork(current, unitOfWork, expirationTime);1778    } catch (originalError) {1779      if (1780        originalError !== null &&1781        typeof originalError === 'object' &&1782        typeof originalError.then === 'function'1783      ) {1784        // Don't replay promises. Treat everything else like an error.1785        throw originalError;1786      }1787      // Keep this code in sync with renderRoot; any changes here must have1788      // corresponding changes there.1789      resetContextDependencies();1790      resetHooks();1791      // Unwind the failed stack frame1792      unwindInterruptedWork(unitOfWork);1793      // Restore the original properties of the fiber.1794      assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);1795      if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {1796        // Reset the profiler timer.1797        startProfilerTimer(unitOfWork);1798      }1799      // Run beginWork again.1800      invokeGuardedCallback(1801        null,1802        originalBeginWork,1803        null,...ReactFiberWorkLoop.js
Source:ReactFiberWorkLoop.js  
...619    } catch (thrownValue) {620      // handleError(root, thrownValue);621    }622  } while (true);623  resetContextDependencies();624  executionContext = prevExecutionContext;625  popDispatcher(prevDispatcher);626  if (workInProgress !== null) {627    invariant(628      false,629      'Cannot commit an incomplete root. This error is likely caused by a ' +630        'bug in React. Please file an issue.'631    );632  }633  workInProgressRoot = null;634  workInProgressRootRenderLanes = NoLanes;635  return workInProgressRootExitStatus;636};637const ensureRootIsScheduled = (root, currentTime) => {...ReactFiberNewContext.new.js
Source:ReactFiberNewContext.new.js  
...40let currentlyRenderingFiber: Fiber | null = null;41let lastContextDependency: ContextDependency<mixed> | null = null;42let lastContextWithAllBitsObserved: ReactContext<any> | null = null;43let isDisallowedContextReadInDEV: boolean = false;44export function resetContextDependencies(): void {45  // This is called right before React yields execution, to ensure `readContext`46  // cannot be called outside the render phase.47  currentlyRenderingFiber = null;48  lastContextDependency = null;49  lastContextWithAllBitsObserved = null;50  if (__DEV__) {51    isDisallowedContextReadInDEV = false;52  }53}54export function enterDisallowedContextReadInDEV(): void {55  if (__DEV__) {56    isDisallowedContextReadInDEV = true;57  }58}...ReactFiberNewContext.old.js
Source:ReactFiberNewContext.old.js  
...7  var currentlyRenderingFiber = null;8  var lastContextDependency = null;9  var lastContextWithAllBitsObserved = null;10  var isDisallowedContextReadInDEV = false;11  function resetContextDependencies() {12    // This is called right before React yields execution, to ensure `readContext`13    // cannot be called outside the render phase.14    currentlyRenderingFiber = null;15    lastContextDependency = null;16    lastContextWithAllBitsObserved = null;17    {18      isDisallowedContextReadInDEV = false;19    }20  }21  function enterDisallowedContextReadInDEV() {22    {23      isDisallowedContextReadInDEV = true;24    }25  }...ReactFiberNewContext.js
Source:ReactFiberNewContext.js  
1import { includesSomeLane, NoLanes } from './ReactFiberLane';2import { markWorkInProgressReceivedUpdate } from './ReactFiberBeginWork';3const invariant = require('invariant');4const MAX_SIGNED_31_BIT_INT = 1073741823;5let currentlyRenderingFiber = null;6let lastContextDependency = null;7let lastContextWithAllBitsObserved = null;8const resetContextDependencies = () => {9  currentlyRenderingFiber = null;10  lastContextDependency = null;11  lastContextWithAllBitsObserved = null;12};13const prepareToReadContext = (workInProgress, renderLanes) => {14  currentlyRenderingFiber = workInProgress;15  lastContextDependency = null;16  lastContextWithAllBitsObserved = null;17  const dependencies = workInProgress.dependencies;18  if (dependencies !== null) {19    const firstContext = dependencies.firstContext;20    if (firstContext !== null) {21      if (includesSomeLane(dependencies.lanes, renderLanes)) {22        markWorkInProgressReceivedUpdate();23      }24      dependencies.firstContext = null;25    }26  }27};28const readContext = (context, observedBits) => {29  if (lastContextWithAllBitsObserved === context) {30    // Nothing to do. We already observe everything in this context.31  } else if (observedBits === false || observedBits === 0) {32    // Do not observe any updates.33  } else {34    let resolvedObservedBits;35    if (36      typeof observedBits !== 'number' ||37      observedBits === MAX_SIGNED_31_BIT_INT38    ) {39      lastContextWithAllBitsObserved = context;40      resolvedObservedBits = MAX_SIGNED_31_BIT_INT;41    } else {42      resolvedObservedBits = observedBits;43    }44    const contextItem = {45      context: context,46      observedBits: resolvedObservedBits,47      next: null,48    };49    if (lastContextDependency === null) {50      invariant(51        currentlyRenderingFiber !== null,52        'Context can only be read while React is rendering. ' +53          'In classes, you can read it in the render method or getDerivedStateFromProps. ' +54          'In function components, you can read it directly in the function body, but not ' +55          'inside Hooks like useReducer() or useMemo().'56      );57      lastContextDependency = contextItem;58      currentlyRenderingFiber.dependencies = {59        lanes: NoLanes,60        firstContext: contextItem,61        responders: null,62      };63    } else {64      lastContextDependency = lastContextDependency.next = contextItem;65    }66  }67  return context._currentValue;68};...Using AI Code Generation
1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  await resetContextDependencies(context);7  await context.close();8  await browser.close();9})();10const { chromium } = require('playwright');11(async () => {12  const browser = await chromium.launch();13  const context = await browser.newContext();14  await context.close();15  await browser.close();16})();17    at Object.throwProtocolError (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:285:15)18    at CDPSession.dispatch (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:181:23)19    at CDPSession._onMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:132:16)20    at WebSocketTransport._ws.addEventListener (/Users/kritikaparmar/Desktop/playwright-test/node_modules/playwright/lib/server/cjs/transport.js:42:24)21    at WebSocket.onMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/event-target.js:132:16)22    at WebSocket.emit (events.js:315:20)23    at Receiver.receiverOnMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/websocket.js:800:20)24    at Receiver.emit (events.js:315:20)25    at Receiver.dataMessage (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/receiver.js:437:14)26    at Receiver.getData (/Users/kritikaparmar/Desktop/playwright-test/node_modules/ws/lib/receiver.js:367:17)Using AI Code Generation
1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch();5  const context = await browser.newContext();6  await resetContextDependencies(context);7  await context.close();8  await browser.close();9})();10const { chromium } = require('playwright');11const { resetContextDependencies } = require('playwright/lib/server/browserContext');12describe('My test', () => {13  let browser;14  let context;15  beforeEach(async () => {16    browser = await chromium.launch();17    context = await browser.newContext();18  });19  afterEach(async () => {20    await resetContextDependencies(context);21    await context.close();22    await browser.close();23  });24  it('should work', async () => {25    const page = await context.newPage();26    await page.screenshot({ path: 'playwright.png' });27  });28});Using AI Code Generation
1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3(async () => {4  const browser = await chromium.launch({ headless: false });5  const context = await browser.newContext();6  await resetContextDependencies(context);7  await browser.close();8})();9const { resetContextDependencies } = require('playwright/lib/server/browserContext');10const { chromium } = require('playwright');11(async () => {12  const browser = await chromium.launch({ headless: false });13  const context = await browser.newContext();14  await resetContextDependencies(context);15  await browser.close();16})();17const { resetContextDependencies } = require('playwright/lib/server/browserContext');18const { chromium } = require('playwright');19(async () => {20  const browser = await chromium.launch({ headless: false });21  const context = await browser.newContext();22  await resetContextDependencies(context);23  await browser.close();24})();25const { resetContextDependencies } = require('playwright/lib/server/browserContext');26const { chromium } = require('playwright');27(async () => {28  const browser = await chromium.launch({ headless: false });29  const context = await browser.newContext();30  await resetContextDependencies(context);31  await browser.close();32})();33const { resetContextDependencies } = require('playwright/lib/server/browserContext');34const { chromium } = require('playwright');35(async () => {36  const browser = await chromium.launch({ headless: false });37  const context = await browser.newContext();38  await resetContextDependencies(context);39  await browser.close();40})();41const { resetContextDependencies } = require('playwright/lib/server/browserContext');42const { chromium } = require('playwright');43(async () => {44  const browser = await chromium.launch({ headless: false });45  const context = await browser.newContext();46  await resetContextDependencies(context);47  await browser.close();48})();Using AI Code Generation
1const { resetContextDependencies } = require('playwright-core/lib/server/browserContext');2resetContextDependencies();3const { resetBrowserDependencies } = require('playwright-core/lib/server/browser');4resetBrowserDependencies();5const { resetBrowserTypeDependencies } = require('playwright-core/lib/server/browserType');6resetBrowserTypeDependencies();7const { resetServerDependencies } = require('playwright-core/lib/server/server');8resetServerDependencies();9const { resetTestState } = require('playwright-core/lib/test/test');10resetTestState();11const { resetTestTypeDependencies } = require('playwright-core/lib/test/testType');12resetTestTypeDependencies();13const { resetTraceModel } = require('playwright-core/lib/trace/traceModel');14resetTraceModel();15const { resetTracePlayer } = require('playwright-core/lib/trace/tracePlayer');16resetTracePlayer();17const { resetTraceRecorder } = require('playwright-core/lib/trace/traceRecorder');18resetTraceRecorder();19const { resetTransport } = require('playwright-core/lib/transport/transport');20resetTransport();21const { resetWebSocketTransport } = require('playwright-core/lib/transport/webSocketTransport');22resetWebSocketTransport();23const { resetBrowserServer } = require('playwright-core/lib/server/browserServer');24resetBrowserServer();25const { resetBrowserContext } = require('playwright-core/lib/server/browserContext');26resetBrowserContext();27const { resetBrowserType } = require('playwright-core/lib/server/browserType');28resetBrowserType();Using AI Code Generation
1const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");2resetContextDependencies();3const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");4resetContextDependencies();5const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");6resetContextDependencies();7const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");8resetContextDependencies();9const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");10resetContextDependencies();11const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");12resetContextDependencies();13const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");14resetContextDependencies();15const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");16resetContextDependencies();17const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");18resetContextDependencies();19const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");20resetContextDependencies();21const { resetContextDependencies } = require("playwright/lib/server/firefox/ffBrowser");22resetContextDependencies();23const { resetContextDependencies } = require("playwright/lib/server/webkit/wkBrowser");24resetContextDependencies();25const { resetContextDependencies } = require("playwright/lib/server/chromium/crBrowser");26resetContextDependencies();27const { resetContextDependencies } = require("playwright/lib/server/firefox/Using AI Code Generation
1const playwright = require('playwright');2(async () => {3  const browser = await playwright.chromium.launch();4  await browser._defaultContext.resetContextDependencies();5  await browser.close();6})();7const playwright = require('playwright');8(async () => {9  const browser = await playwright.chromium.launch();10  await browser._defaultContext.resetContextDependencies();11  await browser.close();12})();13const playwright = require('playwright');14(async () => {15  const browser = await playwright.chromium.launch();16  await browser._defaultContext.resetContextDependencies();17  await browser.close();18})();19const playwright = require('playwright');20(async () => {21  const browser = await playwright.chromium.launch();22  await browser._defaultContext.resetContextDependencies();23  await browser.close();24})();25const playwright = require('playwright');26(async () => {27  const browser = await playwright.chromium.launch();28  await browser._defaultContext.resetContextDependencies();29  await browser.close();30})();31const playwright = require('playwright');32(async () => {33  const browser = await playwright.chromium.launch();34  await browser._defaultContext.resetContextDependencies();35  await browser.close();36})();37const playwright = require('playwright');38(async () => {39  const browser = await playwright.chromium.launch();40  await browser._defaultContext.resetContextDependencies();41  await browser.close();42})();43const playwright = require('playwright');44(async () => {45  const browser = await playwright.chromium.launch();46  await browser._defaultContext.resetContextDependencies();47  await browser.close();48})();49const playwright = require('playwright');50(async () => {51  const browser = await playwright.chromium.launch();52  await browser._defaultContext.resetContextDependencies();53  await browser.close();54})();55const playwright = require('Using AI Code Generation
1const { resetContextDependencies } = require('playwright/lib/server/browserContext');2const { chromium } = require('playwright');3const context = await chromium.launchPersistentContext('./data');4await resetContextDependencies(context);5await context.close();6await context.clearCookies();7await context.clearPermissions();8await context.clearStorageData();9await context.tracing.start({ screenshots: true, snapshots: true });10await context.tracing.stop({ path: 'trace.zip' });11await context.tracing.startChunk();12await context.tracing.stopChunk({ path: 'trace.zip' });13await context.addCookies([{14}]);15const cookies = await context.cookies();16console.log(cookies);17await context.grantPermissions(['geolocation']);18const permissions = await context.permissions();19console.log(permissions);20await context.setGeolocation({ latitude: 59.95, longitude: 30.31667 });21await context.setExtraHTTPHeaders({ foo: 'bar' });22await context.setOffline(true);23await context.setHTTPCredentials({ username: 'user', password: 'pass' });24await context.addInitScript({ path: 'inject.js' });25await context.addInitScript({ content: 'window.injected = 123;' });26await context.exposeBinding('compute', (source, ...args) => {27  return args.reduce((a, b) => a * b, 1);28});29await context.exposeFunction('compute', (...args) => {30  return args.reduce((a, b) => a * b, 1);31});32await context.route('**/*', route => route.continue());33await context.unroute('**/*');34await context.waitForEvent('page');35const page = await context.newPage();36await context.close();37await context.clearCookies();38await context.clearPermissions();39await context.clearStorageData();40await context.tracing.start({ screenshots: true, snapshots: true });41await context.tracing.stop({ path: 'trace.zip' });42await context.tracing.startChunk();43await context.tracing.stopChunk({ path: 'trace.zip' });44await context.addCookies([{Using AI Code Generation
1const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");2resetContextDependencies();3const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");4resetContextDependencies();5const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");6resetContextDependencies();7const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");8resetContextDependencies();9const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");10resetContextDependencies();11const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");12resetContextDependencies();13const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");14resetContextDependencies();15const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");16resetContextDependencies();17const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");18resetContextDependencies();19const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");20resetContextDependencies();21const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");22resetContextDependencies();23const { resetContextDependencies } = require("@playwright/test/lib/server/trace/recorder/dependencies");24resetContextDependencies();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!!
