From 4add586723212094a76d77b64cb8a4c1c41a703c Mon Sep 17 00:00:00 2001 From: subhamkumarr Date: Mon, 9 Feb 2026 03:20:27 +0530 Subject: [PATCH 1/2] fix: initialize transition start time with performance.now() --- .../src/ReactFiberWorkLoop.js | 186 +++++++++--------- packages/react/src/ReactStartTransition.js | 9 +- 2 files changed, 98 insertions(+), 97 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js index d055b271ad77..b4c91c324dd1 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js @@ -7,25 +7,25 @@ * @flow */ -import {REACT_STRICT_MODE_TYPE} from 'shared/ReactSymbols'; +import { REACT_STRICT_MODE_TYPE } from 'shared/ReactSymbols'; import type { Wakeable, Thenable, GestureOptionsRequired, } from 'shared/ReactTypes'; -import type {Fiber, FiberRoot} from './ReactInternalTypes'; -import type {Lanes, Lane} from './ReactFiberLane'; -import type {ActivityState} from './ReactFiberActivityComponent'; -import type {SuspenseState} from './ReactFiberSuspenseComponent'; -import type {FunctionComponentUpdateQueue} from './ReactFiberHooks'; -import type {Transition} from 'react/src/ReactStartTransition'; +import type { Fiber, FiberRoot } from './ReactInternalTypes'; +import type { Lanes, Lane } from './ReactFiberLane'; +import type { ActivityState } from './ReactFiberActivityComponent'; +import type { SuspenseState } from './ReactFiberSuspenseComponent'; +import type { FunctionComponentUpdateQueue } from './ReactFiberHooks'; +import type { Transition } from 'react/src/ReactStartTransition'; import type { PendingTransitionCallbacks, PendingBoundaries, TransitionAbort, } from './ReactFiberTracingMarkerComponent'; -import type {OffscreenInstance} from './ReactFiberOffscreenComponent'; +import type { OffscreenInstance } from './ReactFiberOffscreenComponent'; import type { Resource, ViewTransitionInstance, @@ -33,12 +33,12 @@ import type { GestureTimeline, SuspendedState, } from './ReactFiberConfig'; -import type {RootState} from './ReactFiberRoot'; +import type { RootState } from './ReactFiberRoot'; import { getViewTransitionName, type ViewTransitionState, } from './ReactFiberViewTransitionComponent'; -import type {TransitionTypes} from 'react/src/ReactTransitionType'; +import type { TransitionTypes } from 'react/src/ReactTransitionType'; import { enableCreateEventHandleAPI, @@ -60,7 +60,7 @@ import { enableDefaultTransitionIndicator, enableParallelTransitions, } from 'shared/ReactFeatureFlags'; -import {resetOwnerStackLimit} from 'shared/ReactOwnerStackReset'; +import { resetOwnerStackLimit } from 'shared/ReactOwnerStackReset'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import is from 'shared/objectIs'; @@ -126,8 +126,8 @@ import { flushHydrationEvents, } from './ReactFiberConfig'; -import {createWorkInProgress, resetWorkInProgress} from './ReactFiber'; -import {isRootDehydrated} from './ReactFiberShellHydration'; +import { createWorkInProgress, resetWorkInProgress } from './ReactFiber'; +import { isRootDehydrated } from './ReactFiberShellHydration'; import { getIsHydrating, popHydrationStateOnInterruptedWork, @@ -154,8 +154,8 @@ import { HostHoistable, HostSingleton, } from './ReactWorkTags'; -import {ConcurrentRoot, LegacyRoot} from './ReactRootTags'; -import type {Flags} from './ReactFiberFlags'; +import { ConcurrentRoot, LegacyRoot } from './ReactRootTags'; +import type { Flags } from './ReactFiberFlags'; import { NoFlags, Incomplete, @@ -226,14 +226,14 @@ import { lanesToEventPriority, eventPriorityToLane, } from './ReactEventPriorities'; -import {requestCurrentTransition} from './ReactFiberTransition'; +import { requestCurrentTransition } from './ReactFiberTransition'; import { SelectiveHydrationException, beginWork, replayFunctionComponent, } from './ReactFiberBeginWork'; -import {completeWork} from './ReactFiberCompleteWork'; -import {unwindWork, unwindInterruptedWork} from './ReactFiberUnwindWork'; +import { completeWork } from './ReactFiberCompleteWork'; +import { unwindWork, unwindInterruptedWork } from './ReactFiberUnwindWork'; import { throwException, createRootErrorUpdate, @@ -258,21 +258,21 @@ import { invokePassiveEffectUnmountInDEV, accumulateSuspenseyCommit, } from './ReactFiberCommitWork'; -import {resetShouldStartViewTransition} from './ReactFiberCommitViewTransitions'; -import {shouldStartViewTransition} from './ReactFiberCommitViewTransitions'; +import { resetShouldStartViewTransition } from './ReactFiberCommitViewTransitions'; +import { shouldStartViewTransition } from './ReactFiberCommitViewTransitions'; import { insertDestinationClones, applyDepartureTransitions, startGestureAnimations, } from './ReactFiberApplyGesture'; -import {enqueueUpdate} from './ReactFiberClassUpdateQueue'; -import {resetContextDependencies} from './ReactFiberNewContext'; +import { enqueueUpdate } from './ReactFiberClassUpdateQueue'; +import { resetContextDependencies } from './ReactFiberNewContext'; import { resetHooksAfterThrow, resetHooksOnUnwind, ContextOnlyDispatcher, } from './ReactFiberHooks'; -import {DefaultAsyncDispatcher} from './ReactFiberAsyncDispatcher'; +import { DefaultAsyncDispatcher } from './ReactFiberAsyncDispatcher'; import { createCapturedValueAtFiber, type CapturedValue, @@ -378,13 +378,13 @@ import { onPostCommitRoot as onPostCommitRootDevTools, setIsStrictModeForDevtools, } from './ReactFiberDevToolsHook'; -import {onCommitRoot as onCommitRootTestSelector} from './ReactTestSelectors'; -import {releaseCache} from './ReactFiberCacheComponent'; +import { onCommitRoot as onCommitRootTestSelector } from './ReactTestSelectors'; +import { releaseCache } from './ReactFiberCacheComponent'; import { isLegacyActEnvironment, isConcurrentActEnvironment, } from './ReactFiberAct'; -import {processTransitionCallbacks} from './ReactFiberTracingMarkerComponent'; +import { processTransitionCallbacks } from './ReactFiberTracingMarkerComponent'; import { SuspenseException, SuspenseActionException, @@ -392,25 +392,25 @@ import { getSuspendedThenable, isThenableResolved, } from './ReactFiberThenable'; -import {schedulePostPaintCallback} from './ReactPostPaintCallback'; +import { schedulePostPaintCallback } from './ReactPostPaintCallback'; import { getSuspenseHandler, getShellBoundary, } from './ReactFiberSuspenseContext'; -import {resetChildReconcilerOnUnwind} from './ReactChildFiber'; +import { resetChildReconcilerOnUnwind } from './ReactChildFiber'; import { ensureRootIsScheduled, flushSyncWorkOnAllRoots, flushSyncWorkOnLegacyRootsOnly, requestTransitionLane, } from './ReactFiberRootScheduler'; -import {getMaskedContext, getUnmaskedContext} from './ReactFiberLegacyContext'; -import {logUncaughtError} from './ReactFiberErrorLogger'; +import { getMaskedContext, getUnmaskedContext } from './ReactFiberLegacyContext'; +import { logUncaughtError } from './ReactFiberErrorLogger'; import { scheduleGestureCommit, stopCommittedGesture, } from './ReactFiberGestureScheduler'; -import {claimQueuedTransitionTypes} from './ReactFiberTransitionTypes'; +import { claimQueuedTransitionTypes } from './ReactFiberTransitionTypes'; const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; @@ -559,7 +559,7 @@ export function addTransitionStartCallbackToPendingTransition( if (currentPendingTransitionCallbacks.transitionStart === null) { currentPendingTransitionCallbacks.transitionStart = - ([]: Array); + ([]: Array < Transition >); } currentPendingTransitionCallbacks.transitionStart.push(transition); @@ -693,7 +693,7 @@ export function addTransitionCompleteCallbackToPendingTransition( if (currentPendingTransitionCallbacks.transitionComplete === null) { currentPendingTransitionCallbacks.transitionComplete = - ([]: Array); + ([]: Array < Transition >); } currentPendingTransitionCallbacks.transitionComplete.push(transition); @@ -828,9 +828,9 @@ export function requestUpdateLane(fiber: Fiber): Lane { if (transition.gesture) { throw new Error( 'Cannot setState on regular state inside a startGestureTransition. ' + - 'Gestures can only update the useOptimistic() hook. There should be no ' + - 'side-effects associated with starting a Gesture until its Action is ' + - 'invoked. Move side-effects to the Action instead.', + 'Gestures can only update the useOptimistic() hook. There should be no ' + + 'side-effects associated with starting a Gesture until its Action is ' + + 'invoked. Move side-effects to the Action instead.', ); } } @@ -1036,10 +1036,6 @@ export function scheduleUpdateOnFiber( if (enableTransitionTracing) { const transition = ReactSharedInternals.T; if (transition !== null && transition.name != null) { - if (transition.startTime === -1) { - transition.startTime = now(); - } - addTransitionToLanesMap(root, transition, lane); } } @@ -1576,7 +1572,7 @@ function completeRootWhenReady( const maySuspendCommit = subtreeFlags & ShouldSuspendCommit || (subtreeFlags & BothVisibilityAndMaySuspendCommit) === - BothVisibilityAndMaySuspendCommit; + BothVisibilityAndMaySuspendCommit; let suspendedState: null | SuspendedState = null; if (isViewTransitionEligible || maySuspendCommit || isGestureTransition) { // Before committing, ask the renderer whether the host tree is ready. @@ -2333,11 +2329,11 @@ function handleThrow(root: FiberRoot, thrownValue: any): void { workInProgressSuspendedReason = isWakeable ? // A wakeable object was thrown by a legacy Suspense implementation. - // This has slightly different behavior than suspending with `use`. - SuspendedOnDeprecatedThrowPromise + // This has slightly different behavior than suspending with `use`. + SuspendedOnDeprecatedThrowPromise : // This is a regular error. If something earlier in the component already - // suspended, we must clear the thenable state to unblock the work loop. - SuspendedOnError; + // suspended, we must clear the thenable state to unblock the work loop. + SuspendedOnError; } workInProgressThrownValue = thrownValue; @@ -2929,7 +2925,7 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes): RootExitStatus { if (__DEV__) { console.error( 'Unexpected type of fiber triggered a suspensey commit. ' + - 'This is a bug in React.', + 'This is a bug in React.', ); } break; @@ -3540,7 +3536,7 @@ function completeRoot( finishedWork !== null && finishedWork.alternate !== null && (finishedWork.alternate.memoizedState: RootState).isDehydrated && - (finishedWork.flags & ForceClientRender) !== NoFlags; + (finishedWork.flags & ForceClientRender) !== NoFlags; logRecoveredRenderPhase( completedRenderStartTime, completedRenderEndTime, @@ -3579,7 +3575,7 @@ function completeRoot( if (lanes === NoLanes) { console.error( 'finishedLanes should not be empty during a commit. This is a ' + - 'bug in React.', + 'bug in React.', ); } } @@ -3588,7 +3584,7 @@ function completeRoot( if (finishedWork === root.current) { throw new Error( 'Cannot commit the same tree as before. This error is likely caused by ' + - 'a bug in React. Please file an issue.', + 'a bug in React. Please file an issue.', ); } @@ -3882,7 +3878,7 @@ function commitRoot( enableProfilerTimer ? suspendedViewTransition : (null: any), enableProfilerTimer ? // This callback fires after "pendingEffects" so we need to snapshot the arguments. - finishedViewTransition.bind(null, lanes) + finishedViewTransition.bind(null, lanes) : (null: any), ); } else { @@ -4441,7 +4437,7 @@ function applyGestureOnRoot( reportViewTransitionError, enableProfilerTimer ? // This callback fires after "pendingEffects" so we need to snapshot the arguments. - finishedViewTransition.bind(null, pendingEffectsLanes) + finishedViewTransition.bind(null, pendingEffectsLanes) : (null: any), ); } @@ -4582,8 +4578,8 @@ function makeErrorInfo(componentStack: ?string) { get() { console.error( 'You are accessing "digest" from the errorInfo object passed to onRecoverableError.' + - ' This property is no longer provided as part of errorInfo but can be accessed as a property' + - ' of the Error instance itself.', + ' This property is no longer provided as part of errorInfo but can be accessed as a property' + + ' of the Error instance itself.', ); }, }); @@ -4624,9 +4620,9 @@ export function flushPendingEffects(): boolean { didWarnAboutInterruptedViewTransitions = true; console.warn( 'A flushSync update cancelled a View Transition because it was called ' + - 'while the View Transition was still preparing. To preserve the synchronous ' + - 'semantics, React had to skip the View Transition. If you can, try to avoid ' + - "flushSync() in a scenario that's likely to interfere.", + 'while the View Transition was still preparing. To preserve the synchronous ' + + 'semantics, React had to skip the View Transition. If you can, try to avoid ' + + "flushSync() in a scenario that's likely to interfere.", ); } } @@ -4912,10 +4908,10 @@ export function captureCommitPhaseError( if (__DEV__) { console.error( 'Internal React error: Attempted to capture a commit phase error ' + - 'inside a detached tree. This indicates a bug in React. Potential ' + - 'causes include deleting the same fiber more than once, committing an ' + - 'already-finished tree, or an inconsistent return pointer.\n\n' + - 'Error message:\n\n%s', + 'inside a detached tree. This indicates a bug in React. Potential ' + + 'causes include deleting the same fiber more than once, committing an ' + + 'already-finished tree, or an inconsistent return pointer.\n\n' + + 'Error message:\n\n%s', error, ); } @@ -4942,7 +4938,7 @@ export function attachPingListener( let threadIDs; if (pingCache === null) { pingCache = root.pingCache = new PossiblyWeakMap(); - threadIDs = new Set(); + threadIDs = new Set < mixed > (); pingCache.set(wakeable, threadIDs); } else { threadIDs = pingCache.get(wakeable); @@ -5132,7 +5128,7 @@ export function resolveRetryWakeable(boundaryFiber: Fiber, wakeable: Wakeable) { default: throw new Error( 'Pinged unknown suspense boundary type. ' + - 'This is probably a bug in React.', + 'This is probably a bug in React.', ); } @@ -5167,9 +5163,9 @@ export function throwIfInfiniteUpdateLoopDetected() { throw new Error( 'Maximum update depth exceeded. This can happen when a component ' + - 'repeatedly calls setState inside componentWillUpdate or ' + - 'componentDidUpdate. React limits the number of nested updates to ' + - 'prevent infinite loops.', + 'repeatedly calls setState inside componentWillUpdate or ' + + 'componentDidUpdate. React limits the number of nested updates to ' + + 'prevent infinite loops.', ); } @@ -5180,9 +5176,9 @@ export function throwIfInfiniteUpdateLoopDetected() { console.error( 'Maximum update depth exceeded. This can happen when a component ' + - "calls setState inside useEffect, but useEffect either doesn't " + - 'have a dependency array, or one of the dependencies changes on ' + - 'every render.', + "calls setState inside useEffect, but useEffect either doesn't " + + 'have a dependency array, or one of the dependencies changes on ' + + 'every render.', ); } } @@ -5393,9 +5389,9 @@ export function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber: Fiber) { runWithFiberInDEV(fiber, () => { console.error( "Can't perform a React state update on a component that hasn't mounted yet. " + - 'This indicates that you have a side-effect in your render function that ' + - 'asynchronously tries to update the component. Move this work to ' + - 'useEffect instead.', + 'This indicates that you have a side-effect in your render function that ' + + 'asynchronously tries to update the component. Move this work to ' + + 'useEffect instead.', ); }); } @@ -5404,7 +5400,7 @@ export function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber: Fiber) { let didWarnAboutUpdateInRender = false; let didWarnAboutUpdateInRenderForAnotherComponent; if (__DEV__) { - didWarnAboutUpdateInRenderForAnotherComponent = new Set(); + didWarnAboutUpdateInRenderForAnotherComponent = new Set < string > (); } function warnAboutRenderPhaseUpdatesInDEV(fiber: Fiber) { @@ -5425,8 +5421,8 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber: Fiber) { getComponentNameFromFiber(fiber) || 'Unknown'; console.error( 'Cannot update a component (`%s`) while rendering a ' + - 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + - 'follow the stack trace as described in https://react.dev/link/setstate-in-render', + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + + 'follow the stack trace as described in https://react.dev/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName, @@ -5438,8 +5434,8 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber: Fiber) { if (!didWarnAboutUpdateInRender) { console.error( 'Cannot update during an existing state transition (such as ' + - 'within `render`). Render methods should be a pure ' + - 'function of props and state.', + 'within `render`). Render methods should be a pure ' + + 'function of props and state.', ); didWarnAboutUpdateInRender = true; } @@ -5522,15 +5518,15 @@ function warnIfUpdatesNotWrappedWithActDEV(fiber: Fiber): void { runWithFiberInDEV(fiber, () => { console.error( 'An update to %s inside a test was not wrapped in act(...).\n\n' + - 'When testing, code that causes React state updates should be ' + - 'wrapped into act(...):\n\n' + - 'act(() => {\n' + - ' /* fire events that update state */\n' + - '});\n' + - '/* assert on the output */\n\n' + - "This ensures that you're testing the behavior the user would see " + - 'in the browser.' + - ' Learn more at https://react.dev/link/wrap-tests-with-act', + 'When testing, code that causes React state updates should be ' + + 'wrapped into act(...):\n\n' + + 'act(() => {\n' + + ' /* fire events that update state */\n' + + '});\n' + + '/* assert on the output */\n\n' + + "This ensures that you're testing the behavior the user would see " + + 'in the browser.' + + ' Learn more at https://react.dev/link/wrap-tests-with-act', getComponentNameFromFiber(fiber), ); }); @@ -5547,16 +5543,16 @@ function warnIfSuspenseResolutionNotWrappedWithActDEV(root: FiberRoot): void { ) { console.error( 'A suspended resource finished loading inside a test, but the event ' + - 'was not wrapped in act(...).\n\n' + - 'When testing, code that resolves suspended data should be wrapped ' + - 'into act(...):\n\n' + - 'act(() => {\n' + - ' /* finish loading suspended data */\n' + - '});\n' + - '/* assert on the output */\n\n' + - "This ensures that you're testing the behavior the user would see " + - 'in the browser.' + - ' Learn more at https://react.dev/link/wrap-tests-with-act', + 'was not wrapped in act(...).\n\n' + + 'When testing, code that resolves suspended data should be wrapped ' + + 'into act(...):\n\n' + + 'act(() => {\n' + + ' /* finish loading suspended data */\n' + + '});\n' + + '/* assert on the output */\n\n' + + "This ensures that you're testing the behavior the user would see " + + 'in the browser.' + + ' Learn more at https://react.dev/link/wrap-tests-with-act', ); } } diff --git a/packages/react/src/ReactStartTransition.js b/packages/react/src/ReactStartTransition.js index 3e353a3b6153..82ee99b2de8b 100644 --- a/packages/react/src/ReactStartTransition.js +++ b/packages/react/src/ReactStartTransition.js @@ -42,6 +42,11 @@ function releaseAsyncTransition() { } } +const now = + typeof performance === 'object' && typeof performance.now === 'function' + ? () => performance.now() + : () => Date.now(); + export function startTransition( scope: () => void, options?: StartTransitionOptions, @@ -65,7 +70,7 @@ export function startTransition( if (enableTransitionTracing) { currentTransition.name = options !== undefined && options.name !== undefined ? options.name : null; - currentTransition.startTime = -1; // TODO: This should read the timestamp. + currentTransition.startTime = now(); } if (__DEV__) { currentTransition._updatedFibers = new Set(); @@ -146,7 +151,7 @@ export function startGestureTransition( if (enableTransitionTracing) { currentTransition.name = options !== undefined && options.name !== undefined ? options.name : null; - currentTransition.startTime = -1; // TODO: This should read the timestamp. + currentTransition.startTime = now(); } if (__DEV__) { currentTransition._updatedFibers = new Set(); From 13712bc953d35d3cfdfbbfb63a51ce978d8f4392 Mon Sep 17 00:00:00 2001 From: subhamkumarr Date: Mon, 9 Feb 2026 03:48:32 +0530 Subject: [PATCH 2/2] style: fix whitespace and formatting to minimize diff --- .../src/ReactFiberWorkLoop.js | 182 +++++++++--------- packages/react/src/ReactStartTransition.js | 1 + 2 files changed, 92 insertions(+), 91 deletions(-) diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.js b/packages/react-reconciler/src/ReactFiberWorkLoop.js index b4c91c324dd1..555a75dacf72 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.js +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.js @@ -7,25 +7,25 @@ * @flow */ -import { REACT_STRICT_MODE_TYPE } from 'shared/ReactSymbols'; +import {REACT_STRICT_MODE_TYPE} from 'shared/ReactSymbols'; import type { Wakeable, Thenable, GestureOptionsRequired, } from 'shared/ReactTypes'; -import type { Fiber, FiberRoot } from './ReactInternalTypes'; -import type { Lanes, Lane } from './ReactFiberLane'; -import type { ActivityState } from './ReactFiberActivityComponent'; -import type { SuspenseState } from './ReactFiberSuspenseComponent'; -import type { FunctionComponentUpdateQueue } from './ReactFiberHooks'; -import type { Transition } from 'react/src/ReactStartTransition'; +import type {Fiber, FiberRoot} from './ReactInternalTypes'; +import type {Lanes, Lane} from './ReactFiberLane'; +import type {ActivityState} from './ReactFiberActivityComponent'; +import type {SuspenseState} from './ReactFiberSuspenseComponent'; +import type {FunctionComponentUpdateQueue} from './ReactFiberHooks'; +import type {Transition} from 'react/src/ReactStartTransition'; import type { PendingTransitionCallbacks, PendingBoundaries, TransitionAbort, } from './ReactFiberTracingMarkerComponent'; -import type { OffscreenInstance } from './ReactFiberOffscreenComponent'; +import type {OffscreenInstance} from './ReactFiberOffscreenComponent'; import type { Resource, ViewTransitionInstance, @@ -33,12 +33,12 @@ import type { GestureTimeline, SuspendedState, } from './ReactFiberConfig'; -import type { RootState } from './ReactFiberRoot'; +import type {RootState} from './ReactFiberRoot'; import { getViewTransitionName, type ViewTransitionState, } from './ReactFiberViewTransitionComponent'; -import type { TransitionTypes } from 'react/src/ReactTransitionType'; +import type {TransitionTypes} from 'react/src/ReactTransitionType'; import { enableCreateEventHandleAPI, @@ -60,7 +60,7 @@ import { enableDefaultTransitionIndicator, enableParallelTransitions, } from 'shared/ReactFeatureFlags'; -import { resetOwnerStackLimit } from 'shared/ReactOwnerStackReset'; +import {resetOwnerStackLimit} from 'shared/ReactOwnerStackReset'; import ReactSharedInternals from 'shared/ReactSharedInternals'; import is from 'shared/objectIs'; @@ -126,8 +126,8 @@ import { flushHydrationEvents, } from './ReactFiberConfig'; -import { createWorkInProgress, resetWorkInProgress } from './ReactFiber'; -import { isRootDehydrated } from './ReactFiberShellHydration'; +import {createWorkInProgress, resetWorkInProgress} from './ReactFiber'; +import {isRootDehydrated} from './ReactFiberShellHydration'; import { getIsHydrating, popHydrationStateOnInterruptedWork, @@ -154,8 +154,8 @@ import { HostHoistable, HostSingleton, } from './ReactWorkTags'; -import { ConcurrentRoot, LegacyRoot } from './ReactRootTags'; -import type { Flags } from './ReactFiberFlags'; +import {ConcurrentRoot, LegacyRoot} from './ReactRootTags'; +import type {Flags} from './ReactFiberFlags'; import { NoFlags, Incomplete, @@ -226,14 +226,14 @@ import { lanesToEventPriority, eventPriorityToLane, } from './ReactEventPriorities'; -import { requestCurrentTransition } from './ReactFiberTransition'; +import {requestCurrentTransition} from './ReactFiberTransition'; import { SelectiveHydrationException, beginWork, replayFunctionComponent, } from './ReactFiberBeginWork'; -import { completeWork } from './ReactFiberCompleteWork'; -import { unwindWork, unwindInterruptedWork } from './ReactFiberUnwindWork'; +import {completeWork} from './ReactFiberCompleteWork'; +import {unwindWork, unwindInterruptedWork} from './ReactFiberUnwindWork'; import { throwException, createRootErrorUpdate, @@ -258,21 +258,21 @@ import { invokePassiveEffectUnmountInDEV, accumulateSuspenseyCommit, } from './ReactFiberCommitWork'; -import { resetShouldStartViewTransition } from './ReactFiberCommitViewTransitions'; -import { shouldStartViewTransition } from './ReactFiberCommitViewTransitions'; +import {resetShouldStartViewTransition} from './ReactFiberCommitViewTransitions'; +import {shouldStartViewTransition} from './ReactFiberCommitViewTransitions'; import { insertDestinationClones, applyDepartureTransitions, startGestureAnimations, } from './ReactFiberApplyGesture'; -import { enqueueUpdate } from './ReactFiberClassUpdateQueue'; -import { resetContextDependencies } from './ReactFiberNewContext'; +import {enqueueUpdate} from './ReactFiberClassUpdateQueue'; +import {resetContextDependencies} from './ReactFiberNewContext'; import { resetHooksAfterThrow, resetHooksOnUnwind, ContextOnlyDispatcher, } from './ReactFiberHooks'; -import { DefaultAsyncDispatcher } from './ReactFiberAsyncDispatcher'; +import {DefaultAsyncDispatcher} from './ReactFiberAsyncDispatcher'; import { createCapturedValueAtFiber, type CapturedValue, @@ -378,13 +378,13 @@ import { onPostCommitRoot as onPostCommitRootDevTools, setIsStrictModeForDevtools, } from './ReactFiberDevToolsHook'; -import { onCommitRoot as onCommitRootTestSelector } from './ReactTestSelectors'; -import { releaseCache } from './ReactFiberCacheComponent'; +import {onCommitRoot as onCommitRootTestSelector} from './ReactTestSelectors'; +import {releaseCache} from './ReactFiberCacheComponent'; import { isLegacyActEnvironment, isConcurrentActEnvironment, } from './ReactFiberAct'; -import { processTransitionCallbacks } from './ReactFiberTracingMarkerComponent'; +import {processTransitionCallbacks} from './ReactFiberTracingMarkerComponent'; import { SuspenseException, SuspenseActionException, @@ -392,25 +392,25 @@ import { getSuspendedThenable, isThenableResolved, } from './ReactFiberThenable'; -import { schedulePostPaintCallback } from './ReactPostPaintCallback'; +import {schedulePostPaintCallback} from './ReactPostPaintCallback'; import { getSuspenseHandler, getShellBoundary, } from './ReactFiberSuspenseContext'; -import { resetChildReconcilerOnUnwind } from './ReactChildFiber'; +import {resetChildReconcilerOnUnwind} from './ReactChildFiber'; import { ensureRootIsScheduled, flushSyncWorkOnAllRoots, flushSyncWorkOnLegacyRootsOnly, requestTransitionLane, } from './ReactFiberRootScheduler'; -import { getMaskedContext, getUnmaskedContext } from './ReactFiberLegacyContext'; -import { logUncaughtError } from './ReactFiberErrorLogger'; +import {getMaskedContext, getUnmaskedContext} from './ReactFiberLegacyContext'; +import {logUncaughtError} from './ReactFiberErrorLogger'; import { scheduleGestureCommit, stopCommittedGesture, } from './ReactFiberGestureScheduler'; -import { claimQueuedTransitionTypes } from './ReactFiberTransitionTypes'; +import {claimQueuedTransitionTypes} from './ReactFiberTransitionTypes'; const PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map; @@ -559,7 +559,7 @@ export function addTransitionStartCallbackToPendingTransition( if (currentPendingTransitionCallbacks.transitionStart === null) { currentPendingTransitionCallbacks.transitionStart = - ([]: Array < Transition >); + ([]: Array); } currentPendingTransitionCallbacks.transitionStart.push(transition); @@ -693,7 +693,7 @@ export function addTransitionCompleteCallbackToPendingTransition( if (currentPendingTransitionCallbacks.transitionComplete === null) { currentPendingTransitionCallbacks.transitionComplete = - ([]: Array < Transition >); + ([]: Array); } currentPendingTransitionCallbacks.transitionComplete.push(transition); @@ -828,9 +828,9 @@ export function requestUpdateLane(fiber: Fiber): Lane { if (transition.gesture) { throw new Error( 'Cannot setState on regular state inside a startGestureTransition. ' + - 'Gestures can only update the useOptimistic() hook. There should be no ' + - 'side-effects associated with starting a Gesture until its Action is ' + - 'invoked. Move side-effects to the Action instead.', + 'Gestures can only update the useOptimistic() hook. There should be no ' + + 'side-effects associated with starting a Gesture until its Action is ' + + 'invoked. Move side-effects to the Action instead.', ); } } @@ -1572,7 +1572,7 @@ function completeRootWhenReady( const maySuspendCommit = subtreeFlags & ShouldSuspendCommit || (subtreeFlags & BothVisibilityAndMaySuspendCommit) === - BothVisibilityAndMaySuspendCommit; + BothVisibilityAndMaySuspendCommit; let suspendedState: null | SuspendedState = null; if (isViewTransitionEligible || maySuspendCommit || isGestureTransition) { // Before committing, ask the renderer whether the host tree is ready. @@ -2329,11 +2329,11 @@ function handleThrow(root: FiberRoot, thrownValue: any): void { workInProgressSuspendedReason = isWakeable ? // A wakeable object was thrown by a legacy Suspense implementation. - // This has slightly different behavior than suspending with `use`. - SuspendedOnDeprecatedThrowPromise + // This has slightly different behavior than suspending with `use`. + SuspendedOnDeprecatedThrowPromise : // This is a regular error. If something earlier in the component already - // suspended, we must clear the thenable state to unblock the work loop. - SuspendedOnError; + // suspended, we must clear the thenable state to unblock the work loop. + SuspendedOnError; } workInProgressThrownValue = thrownValue; @@ -2925,7 +2925,7 @@ function renderRootConcurrent(root: FiberRoot, lanes: Lanes): RootExitStatus { if (__DEV__) { console.error( 'Unexpected type of fiber triggered a suspensey commit. ' + - 'This is a bug in React.', + 'This is a bug in React.', ); } break; @@ -3536,7 +3536,7 @@ function completeRoot( finishedWork !== null && finishedWork.alternate !== null && (finishedWork.alternate.memoizedState: RootState).isDehydrated && - (finishedWork.flags & ForceClientRender) !== NoFlags; + (finishedWork.flags & ForceClientRender) !== NoFlags; logRecoveredRenderPhase( completedRenderStartTime, completedRenderEndTime, @@ -3575,7 +3575,7 @@ function completeRoot( if (lanes === NoLanes) { console.error( 'finishedLanes should not be empty during a commit. This is a ' + - 'bug in React.', + 'bug in React.', ); } } @@ -3584,7 +3584,7 @@ function completeRoot( if (finishedWork === root.current) { throw new Error( 'Cannot commit the same tree as before. This error is likely caused by ' + - 'a bug in React. Please file an issue.', + 'a bug in React. Please file an issue.', ); } @@ -3878,7 +3878,7 @@ function commitRoot( enableProfilerTimer ? suspendedViewTransition : (null: any), enableProfilerTimer ? // This callback fires after "pendingEffects" so we need to snapshot the arguments. - finishedViewTransition.bind(null, lanes) + finishedViewTransition.bind(null, lanes) : (null: any), ); } else { @@ -4437,7 +4437,7 @@ function applyGestureOnRoot( reportViewTransitionError, enableProfilerTimer ? // This callback fires after "pendingEffects" so we need to snapshot the arguments. - finishedViewTransition.bind(null, pendingEffectsLanes) + finishedViewTransition.bind(null, pendingEffectsLanes) : (null: any), ); } @@ -4578,8 +4578,8 @@ function makeErrorInfo(componentStack: ?string) { get() { console.error( 'You are accessing "digest" from the errorInfo object passed to onRecoverableError.' + - ' This property is no longer provided as part of errorInfo but can be accessed as a property' + - ' of the Error instance itself.', + ' This property is no longer provided as part of errorInfo but can be accessed as a property' + + ' of the Error instance itself.', ); }, }); @@ -4620,9 +4620,9 @@ export function flushPendingEffects(): boolean { didWarnAboutInterruptedViewTransitions = true; console.warn( 'A flushSync update cancelled a View Transition because it was called ' + - 'while the View Transition was still preparing. To preserve the synchronous ' + - 'semantics, React had to skip the View Transition. If you can, try to avoid ' + - "flushSync() in a scenario that's likely to interfere.", + 'while the View Transition was still preparing. To preserve the synchronous ' + + 'semantics, React had to skip the View Transition. If you can, try to avoid ' + + "flushSync() in a scenario that's likely to interfere.", ); } } @@ -4908,10 +4908,10 @@ export function captureCommitPhaseError( if (__DEV__) { console.error( 'Internal React error: Attempted to capture a commit phase error ' + - 'inside a detached tree. This indicates a bug in React. Potential ' + - 'causes include deleting the same fiber more than once, committing an ' + - 'already-finished tree, or an inconsistent return pointer.\n\n' + - 'Error message:\n\n%s', + 'inside a detached tree. This indicates a bug in React. Potential ' + + 'causes include deleting the same fiber more than once, committing an ' + + 'already-finished tree, or an inconsistent return pointer.\n\n' + + 'Error message:\n\n%s', error, ); } @@ -4938,7 +4938,7 @@ export function attachPingListener( let threadIDs; if (pingCache === null) { pingCache = root.pingCache = new PossiblyWeakMap(); - threadIDs = new Set < mixed > (); + threadIDs = new Set(); pingCache.set(wakeable, threadIDs); } else { threadIDs = pingCache.get(wakeable); @@ -5128,7 +5128,7 @@ export function resolveRetryWakeable(boundaryFiber: Fiber, wakeable: Wakeable) { default: throw new Error( 'Pinged unknown suspense boundary type. ' + - 'This is probably a bug in React.', + 'This is probably a bug in React.', ); } @@ -5163,9 +5163,9 @@ export function throwIfInfiniteUpdateLoopDetected() { throw new Error( 'Maximum update depth exceeded. This can happen when a component ' + - 'repeatedly calls setState inside componentWillUpdate or ' + - 'componentDidUpdate. React limits the number of nested updates to ' + - 'prevent infinite loops.', + 'repeatedly calls setState inside componentWillUpdate or ' + + 'componentDidUpdate. React limits the number of nested updates to ' + + 'prevent infinite loops.', ); } @@ -5176,9 +5176,9 @@ export function throwIfInfiniteUpdateLoopDetected() { console.error( 'Maximum update depth exceeded. This can happen when a component ' + - "calls setState inside useEffect, but useEffect either doesn't " + - 'have a dependency array, or one of the dependencies changes on ' + - 'every render.', + "calls setState inside useEffect, but useEffect either doesn't " + + 'have a dependency array, or one of the dependencies changes on ' + + 'every render.', ); } } @@ -5389,9 +5389,9 @@ export function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber: Fiber) { runWithFiberInDEV(fiber, () => { console.error( "Can't perform a React state update on a component that hasn't mounted yet. " + - 'This indicates that you have a side-effect in your render function that ' + - 'asynchronously tries to update the component. Move this work to ' + - 'useEffect instead.', + 'This indicates that you have a side-effect in your render function that ' + + 'asynchronously tries to update the component. Move this work to ' + + 'useEffect instead.', ); }); } @@ -5400,7 +5400,7 @@ export function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber: Fiber) { let didWarnAboutUpdateInRender = false; let didWarnAboutUpdateInRenderForAnotherComponent; if (__DEV__) { - didWarnAboutUpdateInRenderForAnotherComponent = new Set < string > (); + didWarnAboutUpdateInRenderForAnotherComponent = new Set(); } function warnAboutRenderPhaseUpdatesInDEV(fiber: Fiber) { @@ -5421,8 +5421,8 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber: Fiber) { getComponentNameFromFiber(fiber) || 'Unknown'; console.error( 'Cannot update a component (`%s`) while rendering a ' + - 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + - 'follow the stack trace as described in https://react.dev/link/setstate-in-render', + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + + 'follow the stack trace as described in https://react.dev/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName, @@ -5434,8 +5434,8 @@ function warnAboutRenderPhaseUpdatesInDEV(fiber: Fiber) { if (!didWarnAboutUpdateInRender) { console.error( 'Cannot update during an existing state transition (such as ' + - 'within `render`). Render methods should be a pure ' + - 'function of props and state.', + 'within `render`). Render methods should be a pure ' + + 'function of props and state.', ); didWarnAboutUpdateInRender = true; } @@ -5518,15 +5518,15 @@ function warnIfUpdatesNotWrappedWithActDEV(fiber: Fiber): void { runWithFiberInDEV(fiber, () => { console.error( 'An update to %s inside a test was not wrapped in act(...).\n\n' + - 'When testing, code that causes React state updates should be ' + - 'wrapped into act(...):\n\n' + - 'act(() => {\n' + - ' /* fire events that update state */\n' + - '});\n' + - '/* assert on the output */\n\n' + - "This ensures that you're testing the behavior the user would see " + - 'in the browser.' + - ' Learn more at https://react.dev/link/wrap-tests-with-act', + 'When testing, code that causes React state updates should be ' + + 'wrapped into act(...):\n\n' + + 'act(() => {\n' + + ' /* fire events that update state */\n' + + '});\n' + + '/* assert on the output */\n\n' + + "This ensures that you're testing the behavior the user would see " + + 'in the browser.' + + ' Learn more at https://react.dev/link/wrap-tests-with-act', getComponentNameFromFiber(fiber), ); }); @@ -5543,16 +5543,16 @@ function warnIfSuspenseResolutionNotWrappedWithActDEV(root: FiberRoot): void { ) { console.error( 'A suspended resource finished loading inside a test, but the event ' + - 'was not wrapped in act(...).\n\n' + - 'When testing, code that resolves suspended data should be wrapped ' + - 'into act(...):\n\n' + - 'act(() => {\n' + - ' /* finish loading suspended data */\n' + - '});\n' + - '/* assert on the output */\n\n' + - "This ensures that you're testing the behavior the user would see " + - 'in the browser.' + - ' Learn more at https://react.dev/link/wrap-tests-with-act', + 'was not wrapped in act(...).\n\n' + + 'When testing, code that resolves suspended data should be wrapped ' + + 'into act(...):\n\n' + + 'act(() => {\n' + + ' /* finish loading suspended data */\n' + + '});\n' + + '/* assert on the output */\n\n' + + "This ensures that you're testing the behavior the user would see " + + 'in the browser.' + + ' Learn more at https://react.dev/link/wrap-tests-with-act', ); } } diff --git a/packages/react/src/ReactStartTransition.js b/packages/react/src/ReactStartTransition.js index 82ee99b2de8b..987dc51a6294 100644 --- a/packages/react/src/ReactStartTransition.js +++ b/packages/react/src/ReactStartTransition.js @@ -42,6 +42,7 @@ function releaseAsyncTransition() { } } + const now = typeof performance === 'object' && typeof performance.now === 'function' ? () => performance.now()