next
Version:
The React Framework
1,593 lines (1,388 loc) • 1.33 MB
JavaScript
/**
* @license React
* react-dom-unstable_testing.development.js
*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
'use strict';
if (process.env.NODE_ENV !== "production") {
(function() {
'use strict';
var React = require("next/dist/compiled/react-experimental");
var Scheduler = require("next/dist/compiled/scheduler-experimental");
var Internals = {
usingClientEntryPoint: false,
Events: null,
Dispatcher: {
current: null
}
};
var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
var suppressWarning = false;
function setSuppressWarning(newSuppressWarning) {
{
suppressWarning = newSuppressWarning;
}
} // In DEV, calls to console.warn and console.error get replaced
// by calls to these methods by a Babel plugin.
//
// In PROD (or in packages without access to React internals),
// they are left as they are instead.
function warn(format) {
{
if (!suppressWarning) {
for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
printWarning('warn', format, args);
}
}
}
function error(format) {
{
if (!suppressWarning) {
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
printWarning('error', format, args);
}
}
}
function printWarning(level, format, args) {
// When changing this logic, you might want to also
// update consoleWithStackDev.www.js as well.
{
var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
var stack = ReactDebugCurrentFrame.getStackAddendum();
if (stack !== '') {
format += '%s';
args = args.concat([stack]);
} // eslint-disable-next-line react-internal/safe-string-coercion
var argsWithFormat = args.map(function (item) {
return String(item);
}); // Careful: RN currently depends on this prefix
argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
// breaks IE9: https://github.com/facebook/react/issues/13610
// eslint-disable-next-line react-internal/no-production-logging
Function.prototype.apply.call(console[level], console, argsWithFormat);
}
}
var assign = Object.assign;
// -----------------------------------------------------------------------------
// Killswitch
//
// Flags that exist solely to turn off a change in case it causes a regression
// when it rolls out to prod. We should remove these as soon as possible.
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Land or remove (moderate effort)
//
// Flags that can be probably deleted or landed, but might require extra effort
// like migrating internal callers or performance testing.
// -----------------------------------------------------------------------------
// TODO: Finish rolling out in www
var enableClientRenderFallbackOnTextMismatch = true; // Not sure if www still uses this. We don't have a replacement but whatever we
// Slated for removal in the future (significant effort)
//
// These are experiments that didn't work out, and never shipped, but we can't
// delete from the codebase until we migrate internal callers.
// -----------------------------------------------------------------------------
// Add a callback property to suspense to notify which promises are currently
// in the update queue. This allows reporting and tracing of what is causing
// the user to see a loading state.
//
// Also allows hydration callbacks to fire when a dehydrated boundary gets
// hydrated or deleted.
//
// This will eventually be replaced by the Transition Tracing proposal.
var enableSuspenseCallback = false; // Experimental Scope support.
var enableFormActions = true;
var enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics.
var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
var enableHostSingletons = true;
var diffInCommitPhase = true;
var enableAsyncActions = true;
var alwaysThrottleRetries = true; // -----------------------------------------------------------------------------
// Chopping Block
//
// Planned feature deprecations and breaking changes. Sorted roughly in order of
// when we plan to enable them.
// -----------------------------------------------------------------------------
// This flag enables Strict Effects by default. We're not turning this on until
// after 18 because it requires migration work. Recommendation is to use
// <StrictMode /> to gradually upgrade components.
// If TRUE, trees rendered with createRoot will be StrictEffectsMode.
// If FALSE, these trees will be StrictLegacyMode.
var createRootStrictEffectsByDefault = false;
// React DOM Chopping Block
//
// Similar to main Chopping Block but only flags related to React DOM. These are
// grouped because we will likely batch all of them into a single major release.
// -----------------------------------------------------------------------------
// Disable support for comment nodes as React DOM containers. Already disabled
// in open source, but www codebase still relies on it. Need to remove.
var disableCommentsAsDOMContainers = true; // Disable javascript: URL strings in href for XSS protection.
var disableIEWorkarounds = true; // Filter certain DOM attributes (e.g. src, href) if their values are empty
// Debugging and DevTools
// -----------------------------------------------------------------------------
// Adds user timing marks for e.g. state updates, suspense, and work loop stuff,
// for an experimental timeline tool.
var enableSchedulingProfiler = true; // Helps identify side effects in render-phase lifecycle hooks and setState
var enableProfilerTimer = true; // Record durations for commit and passive effects phases.
var enableProfilerCommitHooks = true; // Phase param passed to onRender callback differentiates between an "update" and a "cascading-update".
var enableProfilerNestedUpdatePhase = true; // Adds verbose console logging for e.g. state updates, suspense, and work loop
var ReactCurrentDispatcher$3 = ReactSharedInternals.ReactCurrentDispatcher; // Since the "not pending" value is always the same, we can reuse the
// same object across all transitions.
var sharedNotPendingObject = {
pending: false,
data: null,
method: null,
action: null
};
var NotPending = Object.freeze(sharedNotPendingObject) ;
function resolveDispatcher() {
// Copied from react/src/ReactHooks.js. It's the same thing but in a
// different package.
var dispatcher = ReactCurrentDispatcher$3.current;
{
if (dispatcher === null) {
error('Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for' + ' one of the following reasons:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.');
}
} // Will result in a null access error if accessed outside render phase. We
// intentionally don't throw our own error because this is in a hot path.
// Also helps ensure this is inlined.
return dispatcher;
}
function useFormStatus() {
{
var dispatcher = resolveDispatcher(); // $FlowFixMe[not-a-function] We know this exists because of the feature check above.
return dispatcher.useHostTransitionStatus();
}
}
var valueStack = [];
var fiberStack;
{
fiberStack = [];
}
var index = -1;
function createCursor(defaultValue) {
return {
current: defaultValue
};
}
function pop(cursor, fiber) {
if (index < 0) {
{
error('Unexpected pop.');
}
return;
}
{
if (fiber !== fiberStack[index]) {
error('Unexpected Fiber popped.');
}
}
cursor.current = valueStack[index];
valueStack[index] = null;
{
fiberStack[index] = null;
}
index--;
}
function push(cursor, value, fiber) {
index++;
valueStack[index] = cursor.current;
{
fiberStack[index] = fiber;
}
cursor.current = value;
}
// ATTENTION
// When adding new symbols to this file,
// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
// The Symbol used to tag the ReactElement-like types.
var REACT_ELEMENT_TYPE = Symbol.for('react.element');
var REACT_PORTAL_TYPE = Symbol.for('react.portal');
var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
var REACT_CONTEXT_TYPE = Symbol.for('react.context');
var REACT_SERVER_CONTEXT_TYPE = Symbol.for('react.server_context');
var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
var REACT_MEMO_TYPE = Symbol.for('react.memo');
var REACT_LAZY_TYPE = Symbol.for('react.lazy');
var REACT_SCOPE_TYPE = Symbol.for('react.scope');
var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
var REACT_CACHE_TYPE = Symbol.for('react.cache');
var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
var REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED = Symbol.for('react.default_value');
var REACT_MEMO_CACHE_SENTINEL = Symbol.for('react.memo_cache_sentinel');
var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
var FAUX_ITERATOR_SYMBOL = '@@iterator';
function getIteratorFn(maybeIterable) {
if (maybeIterable === null || typeof maybeIterable !== 'object') {
return null;
}
var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
if (typeof maybeIterator === 'function') {
return maybeIterator;
}
return null;
}
var contextStackCursor$1 = createCursor(null);
var contextFiberStackCursor = createCursor(null);
var rootInstanceStackCursor = createCursor(null); // Represents the nearest host transition provider (in React DOM, a <form />)
// NOTE: Since forms cannot be nested, and this feature is only implemented by
// React DOM, we don't technically need this to be a stack. It could be a single
// module variable instead.
var hostTransitionProviderCursor = createCursor(null); // TODO: This should initialize to NotPendingTransition, a constant
// imported from the fiber config. However, because of a cycle in the module
// graph, that value isn't defined during this module's initialization. I can't
// think of a way to work around this without moving that value out of the
// fiber config. For now, the "no provider" case is handled when reading,
// inside useHostTransitionStatus.
var HostTransitionContext = {
$$typeof: REACT_CONTEXT_TYPE,
_currentValue: null,
_currentValue2: null,
_threadCount: 0,
Provider: null,
Consumer: null,
_defaultValue: null,
_globalName: null
};
function requiredContext(c) {
{
if (c === null) {
error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.');
}
}
return c;
}
function getCurrentRootHostContainer() {
return rootInstanceStackCursor.current;
}
function getRootHostContainer() {
var rootInstance = requiredContext(rootInstanceStackCursor.current);
return rootInstance;
}
function pushHostContainer(fiber, nextRootInstance) {
// Push current root instance onto the stack;
// This allows us to reset root when portals are popped.
push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
// This enables us to pop only Fibers that provide unique contexts.
push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
// However, we can't just call getRootHostContext() and push it because
// we'd have a different number of entries on the stack depending on
// whether getRootHostContext() throws somewhere in renderer code or not.
// So we push an empty value first. This lets us safely unwind on errors.
push(contextStackCursor$1, null, fiber);
var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
pop(contextStackCursor$1, fiber);
push(contextStackCursor$1, nextRootContext, fiber);
}
function popHostContainer(fiber) {
pop(contextStackCursor$1, fiber);
pop(contextFiberStackCursor, fiber);
pop(rootInstanceStackCursor, fiber);
}
function getHostContext() {
var context = requiredContext(contextStackCursor$1.current);
return context;
}
function pushHostContext(fiber) {
{
var stateHook = fiber.memoizedState;
if (stateHook !== null) {
// Only provide context if this fiber has been upgraded by a host
// transition. We use the same optimization for regular host context below.
push(hostTransitionProviderCursor, fiber, fiber);
}
}
var context = requiredContext(contextStackCursor$1.current);
var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
if (context !== nextContext) {
// Track the context and the Fiber that provided it.
// This enables us to pop only Fibers that provide unique contexts.
push(contextFiberStackCursor, fiber, fiber);
push(contextStackCursor$1, nextContext, fiber);
}
}
function popHostContext(fiber) {
if (contextFiberStackCursor.current === fiber) {
// Do not pop unless this Fiber provided the current context.
// pushHostContext() only pushes Fibers that provide unique contexts.
pop(contextStackCursor$1, fiber);
pop(contextFiberStackCursor, fiber);
}
{
if (hostTransitionProviderCursor.current === fiber) {
// Do not pop unless this Fiber provided the current context. This is mostly
// a performance optimization, but conveniently it also prevents a potential
// data race where a host provider is upgraded (i.e. memoizedState becomes
// non-null) during a concurrent event. This is a bit of a flaw in the way
// we upgrade host components, but because we're accounting for it here, it
// should be fine.
pop(hostTransitionProviderCursor, fiber); // When popping the transition provider, we reset the context value back
// to `null`. We can do this because you're not allowd to nest forms. If
// we allowed for multiple nested host transition providers, then we'd
// need to reset this to the parent provider's status.
{
HostTransitionContext._currentValue = null;
}
}
}
}
var NoFlags$1 =
/* */
0;
var PerformedWork =
/* */
1;
var Placement =
/* */
2;
var DidCapture =
/* */
128;
var Hydrating =
/* */
4096; // You can change the rest (and add more).
var Update =
/* */
4;
/* Skipped value: 0b0000000000000000000000001000; */
var ChildDeletion =
/* */
16;
var ContentReset =
/* */
32;
var Callback =
/* */
64;
/* Used by DidCapture: 0b0000000000000000000010000000; */
var ForceClientRender =
/* */
256;
var Ref =
/* */
512;
var Snapshot =
/* */
1024;
var Passive$1 =
/* */
2048;
/* Used by Hydrating: 0b0000000000000001000000000000; */
var Visibility =
/* */
8192;
var StoreConsistency =
/* */
16384; // It's OK to reuse these bits because these flags are mutually exclusive for
// different fiber types. We should really be doing this for as many flags as
// possible, because we're about to run out of bits.
var ScheduleRetry = StoreConsistency;
var ShouldSuspendCommit = Visibility;
var LifecycleEffectMask = Passive$1 | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
var HostEffectMask =
/* */
32767; // These are not really side effects, but we still reuse this field.
var Incomplete =
/* */
32768;
var ShouldCapture =
/* */
65536;
var ForceUpdateForLegacySuspense =
/* */
131072;
var Forked =
/* */
1048576; // Static tags describe aspects of a fiber that are not specific to a render,
// e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
// This enables us to defer more work in the unmount case,
// since we can defer traversing the tree during layout to look for Passive effects,
// and instead rely on the static flag as a signal that there may be cleanup work.
var RefStatic =
/* */
2097152;
var LayoutStatic =
/* */
4194304;
var PassiveStatic =
/* */
8388608;
var MaySuspendCommit =
/* */
16777216; // Flag used to identify newly inserted fibers. It isn't reset after commit unlike `Placement`.
var PlacementDEV =
/* */
33554432;
var MountLayoutDev =
/* */
67108864;
var MountPassiveDev =
/* */
134217728; // Groups of flags that are used in the commit phase to skip over trees that
// don't contain effects, by checking subtreeFlags.
var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
// flag logic (see #20043)
Update | Snapshot | (0);
var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility;
var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask
var PassiveMask = Passive$1 | Visibility | ChildDeletion; // Union of tags that don't get reset on clones.
// This allows certain concepts to persist without recalculating them,
// e.g. whether a subtree contains passive effects or portals.
var StaticMask = LayoutStatic | PassiveStatic | RefStatic | MaySuspendCommit;
// This module only exists as an ESM wrapper around the external CommonJS
var scheduleCallback$3 = Scheduler.unstable_scheduleCallback;
var cancelCallback$1 = Scheduler.unstable_cancelCallback;
var shouldYield = Scheduler.unstable_shouldYield;
var requestPaint = Scheduler.unstable_requestPaint;
var now$1 = Scheduler.unstable_now;
var getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel;
var ImmediatePriority = Scheduler.unstable_ImmediatePriority;
var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
var NormalPriority$1 = Scheduler.unstable_NormalPriority;
var LowPriority = Scheduler.unstable_LowPriority;
var IdlePriority = Scheduler.unstable_IdlePriority; // this doesn't actually exist on the scheduler, but it *does*
// on scheduler/unstable_mock, which we'll need for internal testing
var log$1 = Scheduler.log;
var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue;
// Helpers to patch console.logs to avoid logging during side-effect free
// replaying on render function. This currently only patches the object
// lazily which won't cover if the log function was extracted eagerly.
// We could also eagerly patch the method.
var disabledDepth = 0;
var prevLog;
var prevInfo;
var prevWarn;
var prevError;
var prevGroup;
var prevGroupCollapsed;
var prevGroupEnd;
function disabledLog() {}
disabledLog.__reactDisabledLog = true;
function disableLogs() {
{
if (disabledDepth === 0) {
/* eslint-disable react-internal/no-production-logging */
prevLog = console.log;
prevInfo = console.info;
prevWarn = console.warn;
prevError = console.error;
prevGroup = console.group;
prevGroupCollapsed = console.groupCollapsed;
prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
var props = {
configurable: true,
enumerable: true,
value: disabledLog,
writable: true
}; // $FlowFixMe[cannot-write] Flow thinks console is immutable.
Object.defineProperties(console, {
info: props,
log: props,
warn: props,
error: props,
group: props,
groupCollapsed: props,
groupEnd: props
});
/* eslint-enable react-internal/no-production-logging */
}
disabledDepth++;
}
}
function reenableLogs() {
{
disabledDepth--;
if (disabledDepth === 0) {
/* eslint-disable react-internal/no-production-logging */
var props = {
configurable: true,
enumerable: true,
writable: true
}; // $FlowFixMe[cannot-write] Flow thinks console is immutable.
Object.defineProperties(console, {
log: assign({}, props, {
value: prevLog
}),
info: assign({}, props, {
value: prevInfo
}),
warn: assign({}, props, {
value: prevWarn
}),
error: assign({}, props, {
value: prevError
}),
group: assign({}, props, {
value: prevGroup
}),
groupCollapsed: assign({}, props, {
value: prevGroupCollapsed
}),
groupEnd: assign({}, props, {
value: prevGroupEnd
})
});
/* eslint-enable react-internal/no-production-logging */
}
if (disabledDepth < 0) {
error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
}
}
}
var rendererID = null;
var injectedHook = null;
var injectedProfilingHooks = null;
var hasLoggedError = false;
var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
function injectInternals(internals) {
if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
// No DevTools
return false;
}
var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
if (hook.isDisabled) {
// This isn't a real property on the hook, but it can be set to opt out
// of DevTools integration and associated warnings and logs.
// https://github.com/facebook/react/issues/3877
return true;
}
if (!hook.supportsFiber) {
{
error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://reactjs.org/link/react-devtools');
} // DevTools exists, even though it doesn't support Fiber.
return true;
}
try {
if (enableSchedulingProfiler) {
// Conditionally inject these hooks only if Timeline profiler is supported by this build.
// This gives DevTools a way to feature detect that isn't tied to version number
// (since profiling and timeline are controlled by different feature flags).
internals = assign({}, internals, {
getLaneLabelMap: getLaneLabelMap,
injectProfilingHooks: injectProfilingHooks
});
}
rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
injectedHook = hook;
} catch (err) {
// Catch all errors because it is unsafe to throw during initialization.
{
error('React instrumentation encountered an error: %s.', err);
}
}
if (hook.checkDCE) {
// This is the real DevTools.
return true;
} else {
// This is likely a hook installed by Fast Refresh runtime.
return false;
}
}
function onScheduleRoot(root, children) {
{
if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
try {
injectedHook.onScheduleFiberRoot(rendererID, root, children);
} catch (err) {
if (!hasLoggedError) {
hasLoggedError = true;
error('React instrumentation encountered an error: %s', err);
}
}
}
}
}
function onCommitRoot$1(root, eventPriority) {
if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
try {
var didError = (root.current.flags & DidCapture) === DidCapture;
if (enableProfilerTimer) {
var schedulerPriority;
switch (eventPriority) {
case DiscreteEventPriority:
schedulerPriority = ImmediatePriority;
break;
case ContinuousEventPriority:
schedulerPriority = UserBlockingPriority;
break;
case DefaultEventPriority:
schedulerPriority = NormalPriority$1;
break;
case IdleEventPriority:
schedulerPriority = IdlePriority;
break;
default:
schedulerPriority = NormalPriority$1;
break;
}
injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError);
}
} catch (err) {
{
if (!hasLoggedError) {
hasLoggedError = true;
error('React instrumentation encountered an error: %s', err);
}
}
}
}
}
function onPostCommitRoot(root) {
if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') {
try {
injectedHook.onPostCommitFiberRoot(rendererID, root);
} catch (err) {
{
if (!hasLoggedError) {
hasLoggedError = true;
error('React instrumentation encountered an error: %s', err);
}
}
}
}
}
function onCommitUnmount(fiber) {
if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
try {
injectedHook.onCommitFiberUnmount(rendererID, fiber);
} catch (err) {
{
if (!hasLoggedError) {
hasLoggedError = true;
error('React instrumentation encountered an error: %s', err);
}
}
}
}
}
function setIsStrictModeForDevtools(newIsStrictMode) {
{
if (typeof log$1 === 'function') {
// We're in a test because Scheduler.log only exists
// in SchedulerMock. To reduce the noise in strict mode tests,
// suppress warnings and disable scheduler yielding during the double render
unstable_setDisableYieldValue(newIsStrictMode);
setSuppressWarning(newIsStrictMode);
}
if (injectedHook && typeof injectedHook.setStrictMode === 'function') {
try {
injectedHook.setStrictMode(rendererID, newIsStrictMode);
} catch (err) {
{
if (!hasLoggedError) {
hasLoggedError = true;
error('React instrumentation encountered an error: %s', err);
}
}
}
}
}
} // Profiler API hooks
function injectProfilingHooks(profilingHooks) {
injectedProfilingHooks = profilingHooks;
}
function getLaneLabelMap() {
{
var map = new Map();
var lane = 1;
for (var index = 0; index < TotalLanes; index++) {
var label = getLabelForLane(lane);
map.set(lane, label);
lane *= 2;
}
return map;
}
}
function markCommitStarted(lanes) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === 'function') {
injectedProfilingHooks.markCommitStarted(lanes);
}
}
}
function markCommitStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === 'function') {
injectedProfilingHooks.markCommitStopped();
}
}
}
function markComponentRenderStarted(fiber) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === 'function') {
injectedProfilingHooks.markComponentRenderStarted(fiber);
}
}
}
function markComponentRenderStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === 'function') {
injectedProfilingHooks.markComponentRenderStopped();
}
}
}
function markComponentPassiveEffectMountStarted(fiber) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === 'function') {
injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber);
}
}
}
function markComponentPassiveEffectMountStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === 'function') {
injectedProfilingHooks.markComponentPassiveEffectMountStopped();
}
}
}
function markComponentPassiveEffectUnmountStarted(fiber) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === 'function') {
injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber);
}
}
}
function markComponentPassiveEffectUnmountStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === 'function') {
injectedProfilingHooks.markComponentPassiveEffectUnmountStopped();
}
}
}
function markComponentLayoutEffectMountStarted(fiber) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === 'function') {
injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber);
}
}
}
function markComponentLayoutEffectMountStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === 'function') {
injectedProfilingHooks.markComponentLayoutEffectMountStopped();
}
}
}
function markComponentLayoutEffectUnmountStarted(fiber) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === 'function') {
injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber);
}
}
}
function markComponentLayoutEffectUnmountStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === 'function') {
injectedProfilingHooks.markComponentLayoutEffectUnmountStopped();
}
}
}
function markComponentErrored(fiber, thrownValue, lanes) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === 'function') {
injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes);
}
}
}
function markComponentSuspended(fiber, wakeable, lanes) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === 'function') {
injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes);
}
}
}
function markLayoutEffectsStarted(lanes) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === 'function') {
injectedProfilingHooks.markLayoutEffectsStarted(lanes);
}
}
}
function markLayoutEffectsStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === 'function') {
injectedProfilingHooks.markLayoutEffectsStopped();
}
}
}
function markPassiveEffectsStarted(lanes) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === 'function') {
injectedProfilingHooks.markPassiveEffectsStarted(lanes);
}
}
}
function markPassiveEffectsStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === 'function') {
injectedProfilingHooks.markPassiveEffectsStopped();
}
}
}
function markRenderStarted(lanes) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === 'function') {
injectedProfilingHooks.markRenderStarted(lanes);
}
}
}
function markRenderYielded() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === 'function') {
injectedProfilingHooks.markRenderYielded();
}
}
}
function markRenderStopped() {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === 'function') {
injectedProfilingHooks.markRenderStopped();
}
}
}
function markRenderScheduled(lane) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === 'function') {
injectedProfilingHooks.markRenderScheduled(lane);
}
}
}
function markForceUpdateScheduled(fiber, lane) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === 'function') {
injectedProfilingHooks.markForceUpdateScheduled(fiber, lane);
}
}
}
function markStateUpdateScheduled(fiber, lane) {
{
if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === 'function') {
injectedProfilingHooks.markStateUpdateScheduled(fiber, lane);
}
}
}
var NoMode =
/* */
0; // TODO: Remove ConcurrentMode by reading from the root tag instead
var ConcurrentMode =
/* */
1;
var ProfileMode =
/* */
2;
var StrictLegacyMode =
/* */
8;
var StrictEffectsMode =
/* */
16;
var NoStrictPassiveEffectsMode =
/* */
64;
// TODO: This is pretty well supported by browsers. Maybe we can drop it.
var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros.
// Based on:
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
var log = Math.log;
var LN2 = Math.LN2;
function clz32Fallback(x) {
var asUint = x >>> 0;
if (asUint === 0) {
return 32;
}
return 31 - (log(asUint) / LN2 | 0) | 0;
}
// If those values are changed that package should be rebuilt and redeployed.
var TotalLanes = 31;
var NoLanes =
/* */
0;
var NoLane =
/* */
0;
var SyncHydrationLane =
/* */
1;
var SyncLane =
/* */
2;
var InputContinuousHydrationLane =
/* */
4;
var InputContinuousLane =
/* */
8;
var DefaultHydrationLane =
/* */
16;
var DefaultLane =
/* */
32;
var SyncUpdateLanes =
/* */
42;
var TransitionHydrationLane =
/* */
64;
var TransitionLanes =
/* */
8388480;
var TransitionLane1 =
/* */
128;
var TransitionLane2 =
/* */
256;
var TransitionLane3 =
/* */
512;
var TransitionLane4 =
/* */
1024;
var TransitionLane5 =
/* */
2048;
var TransitionLane6 =
/* */
4096;
var TransitionLane7 =
/* */
8192;
var TransitionLane8 =
/* */
16384;
var TransitionLane9 =
/* */
32768;
var TransitionLane10 =
/* */
65536;
var TransitionLane11 =
/* */
131072;
var TransitionLane12 =
/* */
262144;
var TransitionLane13 =
/* */
524288;
var TransitionLane14 =
/* */
1048576;
var TransitionLane15 =
/* */
2097152;
var TransitionLane16 =
/* */
4194304;
var RetryLanes =
/* */
125829120;
var RetryLane1 =
/* */
8388608;
var RetryLane2 =
/* */
16777216;
var RetryLane3 =
/* */
33554432;
var RetryLane4 =
/* */
67108864;
var SomeRetryLane = RetryLane1;
var SelectiveHydrationLane =
/* */
134217728;
var NonIdleLanes =
/* */
268435455;
var IdleHydrationLane =
/* */
268435456;
var IdleLane =
/* */
536870912;
var OffscreenLane =
/* */
1073741824; // This function is used for the experimental timeline (react-devtools-timeline)
// It should be kept in sync with the Lanes values above.
function getLabelForLane(lane) {
{
if (lane & SyncHydrationLane) {
return 'SyncHydrationLane';
}
if (lane & SyncLane) {
return 'Sync';
}
if (lane & InputContinuousHydrationLane) {
return 'InputContinuousHydration';
}
if (lane & InputContinuousLane) {
return 'InputContinuous';
}
if (lane & DefaultHydrationLane) {
return 'DefaultHydration';
}
if (lane & DefaultLane) {
return 'Default';
}
if (lane & TransitionHydrationLane) {
return 'TransitionHydration';
}
if (lane & TransitionLanes) {
return 'Transition';
}
if (lane & RetryLanes) {
return 'Retry';
}
if (lane & SelectiveHydrationLane) {
return 'SelectiveHydration';
}
if (lane & IdleHydrationLane) {
return 'IdleHydration';
}
if (lane & IdleLane) {
return 'Idle';
}
if (lane & OffscreenLane) {
return 'Offscreen';
}
}
}
var NoTimestamp = -1;
var nextTransitionLane = TransitionLane1;
var nextRetryLane = RetryLane1;
function getHighestPriorityLanes(lanes) {
{
var pendingSyncLanes = lanes & SyncUpdateLanes;
if (pendingSyncLanes !== 0) {
return pendingSyncLanes;
}
}
switch (getHighestPriorityLane(lanes)) {
case SyncHydrationLane:
return SyncHydrationLane;
case SyncLane:
return SyncLane;
case InputContinuousHydrationLane:
return InputContinuousHydrationLane;
case InputContinuousLane:
return InputContinuousLane;
case DefaultHydrationLane:
return DefaultHydrationLane;
case DefaultLane:
return DefaultLane;
case TransitionHydrationLane:
return TransitionHydrationLane;
case TransitionLane1:
case TransitionLane2:
case TransitionLane3:
case TransitionLane4:
case TransitionLane5:
case TransitionLane6:
case TransitionLane7:
case TransitionLane8:
case TransitionLane9:
case TransitionLane10:
case TransitionLane11:
case TransitionLane12:
case TransitionLane13:
case TransitionLane14:
case TransitionLane15:
case TransitionLane16:
return lanes & TransitionLanes;
case RetryLane1:
case RetryLane2:
case RetryLane3:
case RetryLane4:
return lanes & RetryLanes;
case SelectiveHydrationLane:
return SelectiveHydrationLane;
case IdleHydrationLane:
return IdleHydrationLane;
case IdleLane:
return IdleLane;
case OffscreenLane:
return OffscreenLane;
default:
{
error('Should have found matching lanes. This is a bug in React.');
} // This shouldn't be reachable, but as a fallback, return the entire bitmask.
return lanes;
}
}
function getNextLanes(root, wipLanes) {
// Early bailout if there's no pending work left.
var pendingLanes = root.pendingLanes;
if (pendingLanes === NoLanes) {
return NoLanes;
}
var nextLanes = NoLanes;
var suspendedLanes = root.suspendedLanes;
var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished,
// even if the work is suspended.
var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
if (nonIdlePendingLanes !== NoLanes) {
var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
if (nonIdleUnblockedLanes !== NoLanes) {
nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
} else {
var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
if (nonIdlePingedLanes !== NoLanes) {
nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
}
}
} else {
// The only remaining work is Idle.
var unblockedLanes = pendingLanes & ~suspendedLanes;
if (unblockedLanes !== NoLanes) {
nextLanes = getHighestPriorityLanes(unblockedLanes);
} else {
if (pingedLanes !== NoLanes) {
nextLanes = getHighestPriorityLanes(pingedLanes);
}
}
}
if (nextLanes === NoLanes) {
// This should only be reachable if we're suspended
// TODO: Consider warning in this path if a fallback timer is not scheduled.
return NoLanes;
} // If we're already in the middle of a render, switching lanes will interrupt
// it and we'll lose our progress. We should only do this if the new lanes are
// higher priority.
if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
// bother waiting until the root is complete.
(wipLanes & suspendedLanes) === NoLanes) {
var nextLane = getHighestPriorityLane(nextLanes);
var wipLane = getHighestPriorityLane(wipLanes);
if ( // Tests whether the next lane is equal or lower priority than the wip
// one. This works because the bits decrease in priority as you go left.
nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The
// only difference between default updates and transition updates is that
// default updates do not support refresh transitions.
nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
// Keep working on the existing in-progress tree. Do not interrupt.
return wipLanes;
}
}
if ((nextLanes & InputContinuousLane) !== NoLanes) {
// When updates are sync by default, we entangle continuous priority updates
// and default updates, so they render in the same batch. The only reason
// they use separate lanes is because continuous updates should interrupt
// transitions, but default updates should not.
nextLanes |= pendingLanes & DefaultLane;
} // Check for entangled lanes and add them to the batch.
//
// A lane is said to be entangled with another when it's not allowed to render
// in a batch that does not also include the other lane. Typically we do this
// when multiple updates have the same source, and we only want to respond to
// the most recent event from that source.
//
// Note that we apply entanglements *after* checking for partial work above.
// This means that if a lane is entangled during an interleaved event while
// it's already rendering, we won't interrupt it. This is intentional, since
// entanglement is usually "best effort": we'll try our best to render the
// lanes in the same batch, but it's not worth throwing out partially
// completed work in order to do it.
// TODO: Reconsider this. The counter-argument is that the partial work
// represents an intermediate state, which we don't want to show to the user.
// And by spending extra time finishing it, we're increasing the amount of
// time it takes to show the final state, which is what they are actually
// waiting for.
//
// For those exceptions where entanglement is semantically important,
// we should ensure that there is no partial work at the
// time we apply the entanglement.
var entangledLanes = root.entangledLanes;
if (entangledLanes !== NoLanes) {
var entanglements = root.entanglements;
var lanes = nextLanes & entangledLanes;
while (lanes > 0) {
var index = pickArbitraryLaneIndex(lanes);
var lane = 1 << index;
nextLanes |= entanglements[index];
lanes &= ~lane;
}
}
return nextLanes;
}
function computeExpirationTime(lane, currentTime) {
switch (lane) {
case SyncHydrationLane:
case SyncLane:
case InputContinuousHydrationLane:
case InputContinuousLane:
// User interactions should expire slightly more quickly.
//
// NOTE: This is set to the corresponding constant as in Scheduler.js.
// When we made it larger, a product metric in www regressed, suggesting
// there's a user interaction that's being starved by a series of
// synchronous updates. If that theory is correct, the proper solution is
// to fix the starvation. However, this scenario supports the idea that
// expiration times are an important safeguard when starvation
// does happen.
return currentTime + 250;
case DefaultHydrationLane:
case DefaultLane:
case TransitionHydrationLane:
case TransitionLane1:
case TransitionLane2:
case TransitionLane3:
case TransitionLane4:
case TransitionLane5:
case TransitionLane6:
case TransitionLane7:
case TransitionLane8:
case TransitionLane9:
case TransitionLane10:
case TransitionLane11:
case TransitionLane12:
case TransitionLane13:
case TransitionLane14:
case TransitionLane15:
case TransitionLane16:
return currentTime + 5000;
case RetryLane1:
case RetryLane2:
case RetryLane3:
case RetryLane4:
// TODO: Retries should be allowed to expire if they are CPU bound for
// too long, but when I made this change it caused a spike in browser
// crashes. There must be some other underlying bug; not super urgent but
// ideally should figure out why and fix it. Unfortunately we don't have
// a repro for the crashes, only detected via production metrics.
return NoTimestamp;
case SelectiveHydrationLane:
case IdleHydrationLane:
case IdleLane:
case OffscreenLane:
// Anything idle priority or lower should never expire.
return NoTimestamp;
default:
{
error('Should have found matching lanes. This is a bug in React.');
}
return NoTimestamp;
}
}
function markStarvedLanesAsExpired(root, currentTime) {
// TODO: This gets called every time we yield. We can optimize by storing
// the earliest expiration time on the root. Then use that to quickly bail out
// of this function.
var pendingLanes = root.pendingLanes;
var suspendedLanes = root.suspendedLanes;
var pingedLanes = root.pingedLanes;
var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
// expiration time. If so, we'll assume the update is being starved and mark
// it as expired to force it to finish.
//
// We exclude retry lanes because those must always be time sliced, in order
// to unwrap uncached promises.
// TODO: Write a test for this
var lanes = pendingLanes & ~RetryLanes;
while (lanes > 0) {
var index = pickArbitraryLaneIndex(lanes);
var lane = 1 << index;
var expirationTime = expirationTimes[index];
if (expirationTime === NoTimestamp) {
// Found a pending lane with no expiration time. If it's not suspended, or
// if it's pinged, assume it's CPU-bound. Compute a new expiration time
// using the current time.
if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
// Assumes timestamps are monotonically increasing.
expirationTimes[index] = computeExpirationTime(lane, currentTime);
}
} else if (expirationTime <= currentTime) {
// This lane expired
root.expiredLanes |= lane;
}
lanes &= ~lane;
}
} // This returns the highest priority pending lanes regardless of whether they
// are suspended.
function getHighestPriorityPendingLanes(root) {
return getHighestPriorityLanes(root.pendingLanes);
}
function getLanesToRetrySynchronouslyOnError(root, originallyAttemptedLanes) {
if (root.errorRecoveryDisabledLanes & originallyAttemptedLanes) {
// The error recovery mechanism is disabled until these lanes are cleared.
return NoLanes;
}
var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
if (everythingButOffscreen !== NoLanes) {
return everythingButOffscreen;
}
if (everythingButOffscreen & OffscreenLane) {
return OffscreenLane;
}
return NoLanes;
}
function includesSyncLane(lanes) {
return (lanes & (SyncLane | SyncHydrationLane)) !== NoLanes;
}
function includesNonIdleWork(lanes) {
return (lanes & NonIdleLanes) !== NoLanes;
}
function includesOnlyRetries(lanes) {
return (lanes & RetryLanes) === lanes;
}
function includesOnlyNonUrgentLanes(lanes) {
// TODO: Should hydration lanes be included here? This function is only
// used in `updateDeferredValueImpl`.
var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane;
return (lanes & UrgentLanes) === NoLanes;
}
function includesOnlyTransitions(lanes) {
return (lanes & TransitionLanes) === lanes;
}
function includesBlockingLane(root, lanes) {
var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
return (lanes & SyncDefaultLanes) !== NoLanes;
}
function includesExpiredLane(root, lanes) {
// This is a separate check from includesBlockingLane because a lane can
// expire after a render has already started.
return (lanes & root.expiredLanes) !== NoLanes;
}
function isTransitionLane(lane) {
return (lane & TransitionLanes) !== NoLanes;
}
function claimNextTransitionLane() {
// Cycle through the lanes, assigning each new transition to the next lane.
// In most cases, this means every transition gets its own lane, until we
// run out of lanes and cycle back to the beginning.
var lane = nextTransitionLane;
nextTransitionLane <<= 1;
if ((nextTransitionLane & TransitionLanes) === NoLanes) {
nextTransitionLane = TransitionLane1;
}
return lane;
}
function claimNextRetryLane() {
var lane = nextRetryLane;
nextRetryLane <<= 1;
if ((nextRetryLane & RetryLanes) === NoLanes) {
nextRetryLane = RetryLane1;
}
return lane;
}
function getHighestPriorityLane(lanes) {
return lanes & -lanes;
}
function pickA