Decouple update priority tracking from Scheduler package (#19121)
* Initial currentLanePriority implementation * Minor updates from review * Fix typos and enable flag * Fix feature flags and lint * Fix simple event tests by switching to withSuspenseConfig * Don't lower the priority of setPending in startTransition below InputContinuous * Move currentUpdateLanePriority in commit root into the first effect block * Refactor requestUpdateLane to log for priority mismatches Also verifies that the update lane priority matches the scheduler lane priority before using it * Fix four tests by adding ReactDOM.unstable_runWithPriority * Fix partial hydration when using update lane priority * Fix partial hydration when using update lane priority * Rename feature flag and only log for now * Move unstable_runWithPriority to ReactFiberReconciler * Add unstable_runWithPriority to ReactNoopPersistent too * Bug fixes and performance improvements * Initial currentLanePriority implementation * Minor updates from review * Fix typos and enable flag * Remove higherLanePriority from ReactDOMEventReplaying.js * Change warning implementation and startTransition update lane priority * Inject reconciler functions to avoid importing src/ * Fix feature flags and lint * Fix simple event tests by switching to withSuspenseConfig * Don't lower the priority of setPending in startTransition below InputContinuous * Move currentUpdateLanePriority in commit root into the first effect block * Refactor requestUpdateLane to log for priority mismatches Also verifies that the update lane priority matches the scheduler lane priority before using it * Fix four tests by adding ReactDOM.unstable_runWithPriority * Fix partial hydration when using update lane priority * Fix partial hydration when using update lane priority * Rename feature flag and only log for now * Move unstable_runWithPriority to ReactFiberReconciler * Bug fixes and performance improvements * Remove higherLanePriority from ReactDOMEventReplaying.js * Change warning implementation and startTransition update lane priority * Inject reconciler functions to avoid importing src/ * Fixes from bad rebase
This commit is contained in:
parent
c3e42a962b
commit
91a2e8173f
|
@ -34,6 +34,7 @@ export {
|
||||||
createBlockingRoot as unstable_createBlockingRoot,
|
createBlockingRoot as unstable_createBlockingRoot,
|
||||||
unstable_flushControlled,
|
unstable_flushControlled,
|
||||||
unstable_scheduleHydration,
|
unstable_scheduleHydration,
|
||||||
|
unstable_runWithPriority,
|
||||||
unstable_renderSubtreeIntoContainer,
|
unstable_renderSubtreeIntoContainer,
|
||||||
unstable_createPortal,
|
unstable_createPortal,
|
||||||
unstable_createEventHandle,
|
unstable_createEventHandle,
|
||||||
|
|
|
@ -23,6 +23,8 @@ export {
|
||||||
createBlockingRoot as unstable_createBlockingRoot,
|
createBlockingRoot as unstable_createBlockingRoot,
|
||||||
unstable_flushControlled,
|
unstable_flushControlled,
|
||||||
unstable_scheduleHydration,
|
unstable_scheduleHydration,
|
||||||
|
// DO NOT USE: Temporarily exposing this to migrate off of Scheduler.runWithPriority.
|
||||||
|
unstable_runWithPriority,
|
||||||
// Disabled behind disableUnstableRenderSubtreeIntoContainer
|
// Disabled behind disableUnstableRenderSubtreeIntoContainer
|
||||||
unstable_renderSubtreeIntoContainer,
|
unstable_renderSubtreeIntoContainer,
|
||||||
// Disabled behind disableUnstableCreatePortal
|
// Disabled behind disableUnstableCreatePortal
|
||||||
|
|
|
@ -25,6 +25,7 @@ export {
|
||||||
createBlockingRoot as unstable_createBlockingRoot,
|
createBlockingRoot as unstable_createBlockingRoot,
|
||||||
unstable_flushControlled,
|
unstable_flushControlled,
|
||||||
unstable_scheduleHydration,
|
unstable_scheduleHydration,
|
||||||
|
unstable_runWithPriority,
|
||||||
unstable_renderSubtreeIntoContainer,
|
unstable_renderSubtreeIntoContainer,
|
||||||
unstable_createPortal,
|
unstable_createPortal,
|
||||||
unstable_createEventHandle,
|
unstable_createEventHandle,
|
||||||
|
|
|
@ -19,6 +19,7 @@ export {
|
||||||
createBlockingRoot as unstable_createBlockingRoot,
|
createBlockingRoot as unstable_createBlockingRoot,
|
||||||
unstable_flushControlled,
|
unstable_flushControlled,
|
||||||
unstable_scheduleHydration,
|
unstable_scheduleHydration,
|
||||||
|
unstable_runWithPriority,
|
||||||
unstable_createEventHandle,
|
unstable_createEventHandle,
|
||||||
unstable_isNewReconciler,
|
unstable_isNewReconciler,
|
||||||
} from './src/client/ReactDOM';
|
} from './src/client/ReactDOM';
|
||||||
|
|
|
@ -35,6 +35,8 @@ import {
|
||||||
attemptUserBlockingHydration,
|
attemptUserBlockingHydration,
|
||||||
attemptContinuousHydration,
|
attemptContinuousHydration,
|
||||||
attemptHydrationAtCurrentPriority,
|
attemptHydrationAtCurrentPriority,
|
||||||
|
runWithPriority,
|
||||||
|
getCurrentUpdatePriority,
|
||||||
} from 'react-reconciler/src/ReactFiberReconciler';
|
} from 'react-reconciler/src/ReactFiberReconciler';
|
||||||
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
|
import {createPortal as createPortalImpl} from 'react-reconciler/src/ReactPortal';
|
||||||
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
import {canUseDOM} from 'shared/ExecutionEnvironment';
|
||||||
|
@ -58,6 +60,8 @@ import {
|
||||||
setAttemptContinuousHydration,
|
setAttemptContinuousHydration,
|
||||||
setAttemptHydrationAtCurrentPriority,
|
setAttemptHydrationAtCurrentPriority,
|
||||||
queueExplicitHydrationTarget,
|
queueExplicitHydrationTarget,
|
||||||
|
setGetCurrentUpdatePriority,
|
||||||
|
setAttemptHydrationAtPriority,
|
||||||
} from '../events/ReactDOMEventReplaying';
|
} from '../events/ReactDOMEventReplaying';
|
||||||
import {setBatchingImplementation} from '../events/ReactDOMUpdateBatching';
|
import {setBatchingImplementation} from '../events/ReactDOMUpdateBatching';
|
||||||
import {
|
import {
|
||||||
|
@ -70,6 +74,8 @@ setAttemptSynchronousHydration(attemptSynchronousHydration);
|
||||||
setAttemptUserBlockingHydration(attemptUserBlockingHydration);
|
setAttemptUserBlockingHydration(attemptUserBlockingHydration);
|
||||||
setAttemptContinuousHydration(attemptContinuousHydration);
|
setAttemptContinuousHydration(attemptContinuousHydration);
|
||||||
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
|
setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority);
|
||||||
|
setGetCurrentUpdatePriority(getCurrentUpdatePriority);
|
||||||
|
setAttemptHydrationAtPriority(runWithPriority);
|
||||||
|
|
||||||
let didWarnAboutUnstableCreatePortal = false;
|
let didWarnAboutUnstableCreatePortal = false;
|
||||||
let didWarnAboutUnstableRenderSubtreeIntoContainer = false;
|
let didWarnAboutUnstableRenderSubtreeIntoContainer = false;
|
||||||
|
@ -205,6 +211,9 @@ export {
|
||||||
unstable_createPortal,
|
unstable_createPortal,
|
||||||
// enableCreateEventHandleAPI
|
// enableCreateEventHandleAPI
|
||||||
createEventHandle as unstable_createEventHandle,
|
createEventHandle as unstable_createEventHandle,
|
||||||
|
// TODO: Remove this once callers migrate to alternatives.
|
||||||
|
// This should only be used by React internals.
|
||||||
|
runWithPriority as unstable_runWithPriority,
|
||||||
};
|
};
|
||||||
|
|
||||||
const foundDevTools = injectIntoDevTools({
|
const foundDevTools = injectIntoDevTools({
|
||||||
|
|
|
@ -12,7 +12,10 @@ import type {Container, SuspenseInstance} from '../client/ReactDOMHostConfig';
|
||||||
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
import type {DOMTopLevelEventType} from '../events/TopLevelEventTypes';
|
||||||
import type {ElementListenerMap} from '../client/ReactDOMComponentTree';
|
import type {ElementListenerMap} from '../client/ReactDOMComponentTree';
|
||||||
import type {EventSystemFlags} from './EventSystemFlags';
|
import type {EventSystemFlags} from './EventSystemFlags';
|
||||||
import type {FiberRoot} from 'react-reconciler/src/ReactInternalTypes';
|
import type {
|
||||||
|
FiberRoot,
|
||||||
|
ReactPriorityLevel,
|
||||||
|
} from 'react-reconciler/src/ReactInternalTypes';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
enableDeprecatedFlareAPI,
|
enableDeprecatedFlareAPI,
|
||||||
|
@ -64,6 +67,23 @@ export function setAttemptHydrationAtCurrentPriority(
|
||||||
attemptHydrationAtCurrentPriority = fn;
|
attemptHydrationAtCurrentPriority = fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let getCurrentUpdatePriority: () => ReactPriorityLevel;
|
||||||
|
|
||||||
|
export function setGetCurrentUpdatePriority(fn: () => ReactPriorityLevel) {
|
||||||
|
getCurrentUpdatePriority = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
let attemptHydrationAtPriority: <T>(
|
||||||
|
priority: ReactPriorityLevel,
|
||||||
|
fn: () => T,
|
||||||
|
) => T;
|
||||||
|
|
||||||
|
export function setAttemptHydrationAtPriority(
|
||||||
|
fn: <T>(priority: ReactPriorityLevel, fn: () => T) => T,
|
||||||
|
) {
|
||||||
|
attemptHydrationAtPriority = fn;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Upgrade this definition once we're on a newer version of Flow that
|
// TODO: Upgrade this definition once we're on a newer version of Flow that
|
||||||
// has this definition built-in.
|
// has this definition built-in.
|
||||||
type PointerEvent = Event & {
|
type PointerEvent = Event & {
|
||||||
|
@ -147,6 +167,7 @@ type QueuedHydrationTarget = {|
|
||||||
blockedOn: null | Container | SuspenseInstance,
|
blockedOn: null | Container | SuspenseInstance,
|
||||||
target: Node,
|
target: Node,
|
||||||
priority: number,
|
priority: number,
|
||||||
|
lanePriority: ReactPriorityLevel,
|
||||||
|};
|
|};
|
||||||
const queuedExplicitHydrationTargets: Array<QueuedHydrationTarget> = [];
|
const queuedExplicitHydrationTargets: Array<QueuedHydrationTarget> = [];
|
||||||
|
|
||||||
|
@ -508,9 +529,12 @@ function attemptExplicitHydrationTarget(
|
||||||
// We're blocked on hydrating this boundary.
|
// We're blocked on hydrating this boundary.
|
||||||
// Increase its priority.
|
// Increase its priority.
|
||||||
queuedTarget.blockedOn = instance;
|
queuedTarget.blockedOn = instance;
|
||||||
runWithPriority(queuedTarget.priority, () => {
|
attemptHydrationAtPriority(queuedTarget.lanePriority, () => {
|
||||||
attemptHydrationAtCurrentPriority(nearestMounted);
|
runWithPriority(queuedTarget.priority, () => {
|
||||||
|
attemptHydrationAtCurrentPriority(nearestMounted);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else if (tag === HostRoot) {
|
} else if (tag === HostRoot) {
|
||||||
|
@ -529,15 +553,17 @@ function attemptExplicitHydrationTarget(
|
||||||
|
|
||||||
export function queueExplicitHydrationTarget(target: Node): void {
|
export function queueExplicitHydrationTarget(target: Node): void {
|
||||||
if (enableSelectiveHydration) {
|
if (enableSelectiveHydration) {
|
||||||
const priority = getCurrentPriorityLevel();
|
const schedulerPriority = getCurrentPriorityLevel();
|
||||||
|
const updateLanePriority = getCurrentUpdatePriority();
|
||||||
const queuedTarget: QueuedHydrationTarget = {
|
const queuedTarget: QueuedHydrationTarget = {
|
||||||
blockedOn: null,
|
blockedOn: null,
|
||||||
target: target,
|
target: target,
|
||||||
priority: priority,
|
priority: schedulerPriority,
|
||||||
|
lanePriority: updateLanePriority,
|
||||||
};
|
};
|
||||||
let i = 0;
|
let i = 0;
|
||||||
for (; i < queuedExplicitHydrationTargets.length; i++) {
|
for (; i < queuedExplicitHydrationTargets.length; i++) {
|
||||||
if (priority <= queuedExplicitHydrationTargets[i].priority) {
|
if (schedulerPriority <= queuedExplicitHydrationTargets[i].priority) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,6 +231,8 @@ describe('SimpleEventPlugin', function() {
|
||||||
describe('interactive events, in concurrent mode', () => {
|
describe('interactive events, in concurrent mode', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
jest.resetModules();
|
jest.resetModules();
|
||||||
|
|
||||||
|
React = require('react');
|
||||||
ReactDOM = require('react-dom');
|
ReactDOM = require('react-dom');
|
||||||
Scheduler = require('scheduler');
|
Scheduler = require('scheduler');
|
||||||
});
|
});
|
||||||
|
@ -377,11 +379,14 @@ describe('SimpleEventPlugin', function() {
|
||||||
<button
|
<button
|
||||||
ref={el => (button = el)}
|
ref={el => (button = el)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
Scheduler.unstable_next(() => {
|
React.unstable_withSuspenseConfig(
|
||||||
this.setState(state => ({
|
() => {
|
||||||
lowPriCount: state.lowPriCount + 1,
|
this.setState(state => ({
|
||||||
}));
|
lowPriCount: state.lowPriCount + 1,
|
||||||
});
|
}));
|
||||||
|
},
|
||||||
|
{timeoutMs: 5000},
|
||||||
|
);
|
||||||
}}>
|
}}>
|
||||||
{text}
|
{text}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
@ -47,6 +47,9 @@ export const {
|
||||||
act,
|
act,
|
||||||
dumpTree,
|
dumpTree,
|
||||||
getRoot,
|
getRoot,
|
||||||
|
// TODO: Remove this once callers migrate to alternatives.
|
||||||
|
// This should only be used by React internals.
|
||||||
|
unstable_runWithPriority,
|
||||||
} = createReactNoop(
|
} = createReactNoop(
|
||||||
ReactFiberReconciler, // reconciler
|
ReactFiberReconciler, // reconciler
|
||||||
true, // useMutation
|
true, // useMutation
|
||||||
|
|
|
@ -47,6 +47,9 @@ export const {
|
||||||
act,
|
act,
|
||||||
dumpTree,
|
dumpTree,
|
||||||
getRoot,
|
getRoot,
|
||||||
|
// TODO: Remove this once callers migrate to alternatives.
|
||||||
|
// This should only be used by React internals.
|
||||||
|
unstable_runWithPriority,
|
||||||
} = createReactNoop(
|
} = createReactNoop(
|
||||||
ReactFiberReconciler, // reconciler
|
ReactFiberReconciler, // reconciler
|
||||||
false, // useMutation
|
false, // useMutation
|
||||||
|
|
|
@ -954,6 +954,8 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
|
||||||
return Scheduler.unstable_flushExpired();
|
return Scheduler.unstable_flushExpired();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
unstable_runWithPriority: NoopRenderer.runWithPriority,
|
||||||
|
|
||||||
batchedUpdates: NoopRenderer.batchedUpdates,
|
batchedUpdates: NoopRenderer.batchedUpdates,
|
||||||
|
|
||||||
deferredUpdates: NoopRenderer.deferredUpdates,
|
deferredUpdates: NoopRenderer.deferredUpdates,
|
||||||
|
|
|
@ -30,11 +30,16 @@ import {NoMode, BlockingMode} from './ReactTypeOfMode';
|
||||||
import {
|
import {
|
||||||
NoLane,
|
NoLane,
|
||||||
NoLanes,
|
NoLanes,
|
||||||
|
InputContinuousLanePriority,
|
||||||
isSubsetOfLanes,
|
isSubsetOfLanes,
|
||||||
mergeLanes,
|
mergeLanes,
|
||||||
removeLanes,
|
removeLanes,
|
||||||
markRootEntangled,
|
markRootEntangled,
|
||||||
markRootMutableRead,
|
markRootMutableRead,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
higherLanePriority,
|
||||||
|
DefaultLanePriority,
|
||||||
} from './ReactFiberLane';
|
} from './ReactFiberLane';
|
||||||
import {readContext} from './ReactFiberNewContext.new';
|
import {readContext} from './ReactFiberNewContext.new';
|
||||||
import {createDeprecatedResponderListener} from './ReactFiberDeprecatedEvents.new';
|
import {createDeprecatedResponderListener} from './ReactFiberDeprecatedEvents.new';
|
||||||
|
@ -1498,12 +1503,20 @@ function rerenderDeferredValue<T>(
|
||||||
|
|
||||||
function startTransition(setPending, config, callback) {
|
function startTransition(setPending, config, callback) {
|
||||||
const priorityLevel = getCurrentPriorityLevel();
|
const priorityLevel = getCurrentPriorityLevel();
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
setCurrentUpdateLanePriority(
|
||||||
|
higherLanePriority(previousLanePriority, InputContinuousLanePriority),
|
||||||
|
);
|
||||||
runWithPriority(
|
runWithPriority(
|
||||||
priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel,
|
priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel,
|
||||||
() => {
|
() => {
|
||||||
setPending(true);
|
setPending(true);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If there's no SuspenseConfig set, we'll use the DefaultLanePriority for this transition.
|
||||||
|
setCurrentUpdateLanePriority(DefaultLanePriority);
|
||||||
|
|
||||||
runWithPriority(
|
runWithPriority(
|
||||||
priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
|
priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
|
||||||
() => {
|
() => {
|
||||||
|
@ -1513,6 +1526,7 @@ function startTransition(setPending, config, callback) {
|
||||||
setPending(false);
|
setPending(false);
|
||||||
callback();
|
callback();
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
ReactCurrentBatchConfig.suspense = previousConfig;
|
ReactCurrentBatchConfig.suspense = previousConfig;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -33,11 +33,16 @@ import {NoMode, BlockingMode, DebugTracingMode} from './ReactTypeOfMode';
|
||||||
import {
|
import {
|
||||||
NoLane,
|
NoLane,
|
||||||
NoLanes,
|
NoLanes,
|
||||||
|
InputContinuousLanePriority,
|
||||||
isSubsetOfLanes,
|
isSubsetOfLanes,
|
||||||
mergeLanes,
|
mergeLanes,
|
||||||
removeLanes,
|
removeLanes,
|
||||||
markRootEntangled,
|
markRootEntangled,
|
||||||
markRootMutableRead,
|
markRootMutableRead,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
higherLanePriority,
|
||||||
|
DefaultLanePriority,
|
||||||
} from './ReactFiberLane';
|
} from './ReactFiberLane';
|
||||||
import {readContext} from './ReactFiberNewContext.old';
|
import {readContext} from './ReactFiberNewContext.old';
|
||||||
import {createDeprecatedResponderListener} from './ReactFiberDeprecatedEvents.old';
|
import {createDeprecatedResponderListener} from './ReactFiberDeprecatedEvents.old';
|
||||||
|
@ -1502,12 +1507,20 @@ function rerenderDeferredValue<T>(
|
||||||
|
|
||||||
function startTransition(setPending, config, callback) {
|
function startTransition(setPending, config, callback) {
|
||||||
const priorityLevel = getCurrentPriorityLevel();
|
const priorityLevel = getCurrentPriorityLevel();
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
setCurrentUpdateLanePriority(
|
||||||
|
higherLanePriority(previousLanePriority, InputContinuousLanePriority),
|
||||||
|
);
|
||||||
runWithPriority(
|
runWithPriority(
|
||||||
priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel,
|
priorityLevel < UserBlockingPriority ? UserBlockingPriority : priorityLevel,
|
||||||
() => {
|
() => {
|
||||||
setPending(true);
|
setPending(true);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// If there's no SuspenseConfig set, we'll use the DefaultLanePriority for this transition.
|
||||||
|
setCurrentUpdateLanePriority(DefaultLanePriority);
|
||||||
|
|
||||||
runWithPriority(
|
runWithPriority(
|
||||||
priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
|
priorityLevel > NormalPriority ? NormalPriority : priorityLevel,
|
||||||
() => {
|
() => {
|
||||||
|
@ -1517,6 +1530,7 @@ function startTransition(setPending, config, callback) {
|
||||||
setPending(false);
|
setPending(false);
|
||||||
callback();
|
callback();
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
ReactCurrentBatchConfig.suspense = previousConfig;
|
ReactCurrentBatchConfig.suspense = previousConfig;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -49,10 +49,10 @@ const InputDiscreteHydrationLanePriority: LanePriority = 14;
|
||||||
export const InputDiscreteLanePriority: LanePriority = 13;
|
export const InputDiscreteLanePriority: LanePriority = 13;
|
||||||
|
|
||||||
const InputContinuousHydrationLanePriority: LanePriority = 12;
|
const InputContinuousHydrationLanePriority: LanePriority = 12;
|
||||||
const InputContinuousLanePriority: LanePriority = 11;
|
export const InputContinuousLanePriority: LanePriority = 11;
|
||||||
|
|
||||||
const DefaultHydrationLanePriority: LanePriority = 10;
|
const DefaultHydrationLanePriority: LanePriority = 10;
|
||||||
const DefaultLanePriority: LanePriority = 9;
|
export const DefaultLanePriority: LanePriority = 9;
|
||||||
|
|
||||||
const TransitionShortHydrationLanePriority: LanePriority = 8;
|
const TransitionShortHydrationLanePriority: LanePriority = 8;
|
||||||
export const TransitionShortLanePriority: LanePriority = 7;
|
export const TransitionShortLanePriority: LanePriority = 7;
|
||||||
|
@ -120,6 +120,16 @@ export const OffscreenLane: Lane = /* */ 0b1000000000000000000
|
||||||
|
|
||||||
export const NoTimestamp = -1;
|
export const NoTimestamp = -1;
|
||||||
|
|
||||||
|
let currentUpdateLanePriority: LanePriority = NoLanePriority;
|
||||||
|
|
||||||
|
export function getCurrentUpdateLanePriority(): LanePriority {
|
||||||
|
return currentUpdateLanePriority;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setCurrentUpdateLanePriority(newLanePriority: LanePriority) {
|
||||||
|
currentUpdateLanePriority = newLanePriority;
|
||||||
|
}
|
||||||
|
|
||||||
// "Registers" used to "return" multiple values
|
// "Registers" used to "return" multiple values
|
||||||
// Used by getHighestPriorityLanes and getNextLanes:
|
// Used by getHighestPriorityLanes and getNextLanes:
|
||||||
let return_highestLanePriority: LanePriority = DefaultLanePriority;
|
let return_highestLanePriority: LanePriority = DefaultLanePriority;
|
||||||
|
@ -651,6 +661,13 @@ export function higherPriorityLane(a: Lane, b: Lane) {
|
||||||
return a !== NoLane && a < b ? a : b;
|
return a !== NoLane && a < b ? a : b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function higherLanePriority(
|
||||||
|
a: LanePriority,
|
||||||
|
b: LanePriority,
|
||||||
|
): LanePriority {
|
||||||
|
return a !== NoLanePriority && a > b ? a : b;
|
||||||
|
}
|
||||||
|
|
||||||
export function createLaneMap<T>(initial: T): LaneMap<T> {
|
export function createLaneMap<T>(initial: T): LaneMap<T> {
|
||||||
return new Array(TotalLanes).fill(initial);
|
return new Array(TotalLanes).fill(initial);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,8 @@ import {
|
||||||
focusWithin as focusWithin_old,
|
focusWithin as focusWithin_old,
|
||||||
observeVisibleRects as observeVisibleRects_old,
|
observeVisibleRects as observeVisibleRects_old,
|
||||||
registerMutableSourceForHydration as registerMutableSourceForHydration_old,
|
registerMutableSourceForHydration as registerMutableSourceForHydration_old,
|
||||||
|
runWithPriority as runWithPriority_old,
|
||||||
|
getCurrentUpdatePriority as getCurrentUpdatePriority_old,
|
||||||
} from './ReactFiberReconciler.old';
|
} from './ReactFiberReconciler.old';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -88,6 +90,8 @@ import {
|
||||||
focusWithin as focusWithin_new,
|
focusWithin as focusWithin_new,
|
||||||
observeVisibleRects as observeVisibleRects_new,
|
observeVisibleRects as observeVisibleRects_new,
|
||||||
registerMutableSourceForHydration as registerMutableSourceForHydration_new,
|
registerMutableSourceForHydration as registerMutableSourceForHydration_new,
|
||||||
|
runWithPriority as runWithPriority_new,
|
||||||
|
getCurrentUpdatePriority as getCurrentUpdatePriority_new,
|
||||||
} from './ReactFiberReconciler.new';
|
} from './ReactFiberReconciler.new';
|
||||||
|
|
||||||
export const createContainer = enableNewReconciler
|
export const createContainer = enableNewReconciler
|
||||||
|
@ -139,6 +143,9 @@ export const attemptContinuousHydration = enableNewReconciler
|
||||||
export const attemptHydrationAtCurrentPriority = enableNewReconciler
|
export const attemptHydrationAtCurrentPriority = enableNewReconciler
|
||||||
? attemptHydrationAtCurrentPriority_new
|
? attemptHydrationAtCurrentPriority_new
|
||||||
: attemptHydrationAtCurrentPriority_old;
|
: attemptHydrationAtCurrentPriority_old;
|
||||||
|
export const getCurrentUpdatePriority = enableNewReconciler
|
||||||
|
? getCurrentUpdatePriority_new
|
||||||
|
: getCurrentUpdatePriority_old;
|
||||||
export const findHostInstance = enableNewReconciler
|
export const findHostInstance = enableNewReconciler
|
||||||
? findHostInstance_new
|
? findHostInstance_new
|
||||||
: findHostInstance_old;
|
: findHostInstance_old;
|
||||||
|
@ -194,3 +201,6 @@ export const observeVisibleRects = enableNewReconciler
|
||||||
export const registerMutableSourceForHydration = enableNewReconciler
|
export const registerMutableSourceForHydration = enableNewReconciler
|
||||||
? registerMutableSourceForHydration_new
|
? registerMutableSourceForHydration_new
|
||||||
: registerMutableSourceForHydration_old;
|
: registerMutableSourceForHydration_old;
|
||||||
|
export const runWithPriority = enableNewReconciler
|
||||||
|
? runWithPriority_new
|
||||||
|
: runWithPriority_old;
|
||||||
|
|
|
@ -7,7 +7,11 @@
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {Fiber, SuspenseHydrationCallbacks} from './ReactInternalTypes';
|
import type {
|
||||||
|
Fiber,
|
||||||
|
ReactPriorityLevel,
|
||||||
|
SuspenseHydrationCallbacks,
|
||||||
|
} from './ReactInternalTypes';
|
||||||
import type {FiberRoot} from './ReactInternalTypes';
|
import type {FiberRoot} from './ReactInternalTypes';
|
||||||
import type {RootTag} from './ReactRootTags';
|
import type {RootTag} from './ReactRootTags';
|
||||||
import type {
|
import type {
|
||||||
|
@ -79,6 +83,10 @@ import {
|
||||||
NoTimestamp,
|
NoTimestamp,
|
||||||
getHighestPriorityPendingLanes,
|
getHighestPriorityPendingLanes,
|
||||||
higherPriorityLane,
|
higherPriorityLane,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
schedulerPriorityToLanePriority,
|
||||||
|
lanePriorityToSchedulerPriority,
|
||||||
} from './ReactFiberLane';
|
} from './ReactFiberLane';
|
||||||
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
|
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
|
||||||
import {
|
import {
|
||||||
|
@ -424,6 +432,20 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
|
||||||
markRetryLaneIfNotHydrated(fiber, lane);
|
markRetryLaneIfNotHydrated(fiber, lane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function runWithPriority<T>(priority: ReactPriorityLevel, fn: () => T) {
|
||||||
|
const previousPriority = getCurrentUpdateLanePriority();
|
||||||
|
try {
|
||||||
|
setCurrentUpdateLanePriority(schedulerPriorityToLanePriority(priority));
|
||||||
|
return fn();
|
||||||
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousPriority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCurrentUpdatePriority(): ReactPriorityLevel {
|
||||||
|
return lanePriorityToSchedulerPriority(getCurrentUpdateLanePriority());
|
||||||
|
}
|
||||||
|
|
||||||
export {findHostInstance};
|
export {findHostInstance};
|
||||||
|
|
||||||
export {findHostInstanceWithWarning};
|
export {findHostInstanceWithWarning};
|
||||||
|
|
|
@ -7,7 +7,11 @@
|
||||||
* @flow
|
* @flow
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {Fiber, SuspenseHydrationCallbacks} from './ReactInternalTypes';
|
import type {
|
||||||
|
Fiber,
|
||||||
|
ReactPriorityLevel,
|
||||||
|
SuspenseHydrationCallbacks,
|
||||||
|
} from './ReactInternalTypes';
|
||||||
import type {FiberRoot} from './ReactInternalTypes';
|
import type {FiberRoot} from './ReactInternalTypes';
|
||||||
import type {RootTag} from './ReactRootTags';
|
import type {RootTag} from './ReactRootTags';
|
||||||
import type {
|
import type {
|
||||||
|
@ -79,6 +83,10 @@ import {
|
||||||
NoTimestamp,
|
NoTimestamp,
|
||||||
getHighestPriorityPendingLanes,
|
getHighestPriorityPendingLanes,
|
||||||
higherPriorityLane,
|
higherPriorityLane,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
schedulerPriorityToLanePriority,
|
||||||
|
lanePriorityToSchedulerPriority,
|
||||||
} from './ReactFiberLane';
|
} from './ReactFiberLane';
|
||||||
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
|
import {requestCurrentSuspenseConfig} from './ReactFiberSuspenseConfig';
|
||||||
import {
|
import {
|
||||||
|
@ -424,6 +432,20 @@ export function attemptHydrationAtCurrentPriority(fiber: Fiber): void {
|
||||||
markRetryLaneIfNotHydrated(fiber, lane);
|
markRetryLaneIfNotHydrated(fiber, lane);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function runWithPriority<T>(priority: ReactPriorityLevel, fn: () => T) {
|
||||||
|
const previousPriority = getCurrentUpdateLanePriority();
|
||||||
|
try {
|
||||||
|
setCurrentUpdateLanePriority(schedulerPriorityToLanePriority(priority));
|
||||||
|
return fn();
|
||||||
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousPriority);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getCurrentUpdatePriority(): ReactPriorityLevel {
|
||||||
|
return lanePriorityToSchedulerPriority(getCurrentUpdateLanePriority());
|
||||||
|
}
|
||||||
|
|
||||||
export {findHostInstance};
|
export {findHostInstance};
|
||||||
|
|
||||||
export {findHostInstanceWithWarning};
|
export {findHostInstanceWithWarning};
|
||||||
|
|
|
@ -26,6 +26,7 @@ import {
|
||||||
enableSchedulerTracing,
|
enableSchedulerTracing,
|
||||||
warnAboutUnmockedScheduler,
|
warnAboutUnmockedScheduler,
|
||||||
deferRenderPhaseUpdateToNextBatch,
|
deferRenderPhaseUpdateToNextBatch,
|
||||||
|
decoupleUpdatePriorityFromScheduler,
|
||||||
} from 'shared/ReactFeatureFlags';
|
} from 'shared/ReactFeatureFlags';
|
||||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||||
import invariant from 'shared/invariant';
|
import invariant from 'shared/invariant';
|
||||||
|
@ -113,6 +114,7 @@ import {
|
||||||
InputDiscreteLanePriority,
|
InputDiscreteLanePriority,
|
||||||
TransitionShortLanePriority,
|
TransitionShortLanePriority,
|
||||||
TransitionLongLanePriority,
|
TransitionLongLanePriority,
|
||||||
|
DefaultLanePriority,
|
||||||
NoLanes,
|
NoLanes,
|
||||||
NoLane,
|
NoLane,
|
||||||
SyncLane,
|
SyncLane,
|
||||||
|
@ -130,6 +132,8 @@ import {
|
||||||
hasUpdatePriority,
|
hasUpdatePriority,
|
||||||
getNextLanes,
|
getNextLanes,
|
||||||
returnNextLanesPriority,
|
returnNextLanesPriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
markStarvedLanesAsExpired,
|
markStarvedLanesAsExpired,
|
||||||
getLanesToRetrySynchronouslyOnError,
|
getLanesToRetrySynchronouslyOnError,
|
||||||
markRootUpdated,
|
markRootUpdated,
|
||||||
|
@ -394,7 +398,6 @@ export function requestUpdateLane(
|
||||||
currentEventWipLanes = workInProgressRootIncludedLanes;
|
currentEventWipLanes = workInProgressRootIncludedLanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lane;
|
|
||||||
if (suspenseConfig !== null) {
|
if (suspenseConfig !== null) {
|
||||||
// Use the size of the timeout as a heuristic to prioritize shorter
|
// Use the size of the timeout as a heuristic to prioritize shorter
|
||||||
// transitions over longer ones.
|
// transitions over longer ones.
|
||||||
|
@ -412,26 +415,56 @@ export function requestUpdateLane(
|
||||||
: NoLanes;
|
: NoLanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
lane = findTransitionLane(
|
return findTransitionLane(
|
||||||
transitionLanePriority,
|
transitionLanePriority,
|
||||||
currentEventWipLanes,
|
currentEventWipLanes,
|
||||||
currentEventPendingLanes,
|
currentEventPendingLanes,
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
// TODO: If we're not inside `runWithPriority`, this returns the priority
|
|
||||||
// of the currently running task. That's probably not what we want.
|
|
||||||
const schedulerPriority = getCurrentPriorityLevel();
|
|
||||||
|
|
||||||
if (
|
// TODO: Remove this dependency on the Scheduler priority.
|
||||||
// TODO: Temporary. We're removing the concept of discrete updates.
|
// To do that, we're replacing it with an update lane priority.
|
||||||
(executionContext & DiscreteEventContext) !== NoContext &&
|
const schedulerPriority = getCurrentPriorityLevel();
|
||||||
schedulerPriority === UserBlockingSchedulerPriority
|
|
||||||
) {
|
// The old behavior was using the priority level of the Scheduler.
|
||||||
lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);
|
// This couples React to the Scheduler internals, so we're replacing it
|
||||||
} else {
|
// with the currentUpdateLanePriority above. As an example of how this
|
||||||
const lanePriority = schedulerPriorityToLanePriority(schedulerPriority);
|
// could be problematic, if we're not inside `Scheduler.runWithPriority`,
|
||||||
lane = findUpdateLane(lanePriority, currentEventWipLanes);
|
// then we'll get the priority of the current running Scheduler task,
|
||||||
|
// which is probably not what we want.
|
||||||
|
let lane;
|
||||||
|
if (
|
||||||
|
// TODO: Temporary. We're removing the concept of discrete updates.
|
||||||
|
(executionContext & DiscreteEventContext) !== NoContext &&
|
||||||
|
schedulerPriority === UserBlockingSchedulerPriority
|
||||||
|
) {
|
||||||
|
lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);
|
||||||
|
} else {
|
||||||
|
const schedulerLanePriority = schedulerPriorityToLanePriority(
|
||||||
|
schedulerPriority,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (decoupleUpdatePriorityFromScheduler) {
|
||||||
|
// In the new strategy, we will track the current update lane priority
|
||||||
|
// inside React and use that priority to select a lane for this update.
|
||||||
|
// For now, we're just logging when they're different so we can assess.
|
||||||
|
const currentUpdateLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
|
||||||
|
if (
|
||||||
|
schedulerLanePriority !== currentUpdateLanePriority &&
|
||||||
|
currentUpdateLanePriority !== NoLanePriority
|
||||||
|
) {
|
||||||
|
if (__DEV__) {
|
||||||
|
console.error(
|
||||||
|
'Expected current scheduler lane priority %s to match current update lane priority %s',
|
||||||
|
schedulerLanePriority,
|
||||||
|
currentUpdateLanePriority,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lane;
|
return lane;
|
||||||
|
@ -1068,7 +1101,13 @@ export function flushDiscreteUpdates() {
|
||||||
|
|
||||||
export function deferredUpdates<A>(fn: () => A): A {
|
export function deferredUpdates<A>(fn: () => A): A {
|
||||||
// TODO: Remove in favor of Scheduler.next
|
// TODO: Remove in favor of Scheduler.next
|
||||||
return runWithPriority(NormalSchedulerPriority, fn);
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
try {
|
||||||
|
setCurrentUpdateLanePriority(DefaultLanePriority);
|
||||||
|
return runWithPriority(NormalSchedulerPriority, fn);
|
||||||
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function flushPendingDiscreteUpdates() {
|
function flushPendingDiscreteUpdates() {
|
||||||
|
@ -1123,13 +1162,16 @@ export function discreteUpdates<A, B, C, D, R>(
|
||||||
): R {
|
): R {
|
||||||
const prevExecutionContext = executionContext;
|
const prevExecutionContext = executionContext;
|
||||||
executionContext |= DiscreteEventContext;
|
executionContext |= DiscreteEventContext;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
|
setCurrentUpdateLanePriority(InputDiscreteLanePriority);
|
||||||
// Should this
|
// Should this
|
||||||
return runWithPriority(
|
return runWithPriority(
|
||||||
UserBlockingSchedulerPriority,
|
UserBlockingSchedulerPriority,
|
||||||
fn.bind(null, a, b, c, d),
|
fn.bind(null, a, b, c, d),
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
if (executionContext === NoContext) {
|
if (executionContext === NoContext) {
|
||||||
// Flush the immediate callbacks that were scheduled during this batch
|
// Flush the immediate callbacks that were scheduled during this batch
|
||||||
|
@ -1166,13 +1208,16 @@ export function flushSync<A, R>(fn: A => R, a: A): R {
|
||||||
return fn(a);
|
return fn(a);
|
||||||
}
|
}
|
||||||
executionContext |= BatchedContext;
|
executionContext |= BatchedContext;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
if (fn) {
|
if (fn) {
|
||||||
return runWithPriority(ImmediateSchedulerPriority, fn.bind(null, a));
|
return runWithPriority(ImmediateSchedulerPriority, fn.bind(null, a));
|
||||||
} else {
|
} else {
|
||||||
return (undefined: $FlowFixMe);
|
return (undefined: $FlowFixMe);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
// Flush the immediate callbacks that were scheduled during this batch.
|
// Flush the immediate callbacks that were scheduled during this batch.
|
||||||
// Note that this will happen even if batchedUpdates is higher up
|
// Note that this will happen even if batchedUpdates is higher up
|
||||||
|
@ -1184,9 +1229,12 @@ export function flushSync<A, R>(fn: A => R, a: A): R {
|
||||||
export function flushControlled(fn: () => mixed): void {
|
export function flushControlled(fn: () => mixed): void {
|
||||||
const prevExecutionContext = executionContext;
|
const prevExecutionContext = executionContext;
|
||||||
executionContext |= BatchedContext;
|
executionContext |= BatchedContext;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
runWithPriority(ImmediateSchedulerPriority, fn);
|
runWithPriority(ImmediateSchedulerPriority, fn);
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
if (executionContext === NoContext) {
|
if (executionContext === NoContext) {
|
||||||
// Flush the immediate callbacks that were scheduled during this batch
|
// Flush the immediate callbacks that were scheduled during this batch
|
||||||
|
@ -1867,6 +1915,9 @@ function commitRootImpl(root, renderPriorityLevel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstEffect !== null) {
|
if (firstEffect !== null) {
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
|
|
||||||
const prevExecutionContext = executionContext;
|
const prevExecutionContext = executionContext;
|
||||||
executionContext |= CommitContext;
|
executionContext |= CommitContext;
|
||||||
const prevInteractions = pushInteractions(root);
|
const prevInteractions = pushInteractions(root);
|
||||||
|
@ -1987,6 +2038,9 @@ function commitRootImpl(root, renderPriorityLevel) {
|
||||||
popInteractions(((prevInteractions: any): Set<Interaction>));
|
popInteractions(((prevInteractions: any): Set<Interaction>));
|
||||||
}
|
}
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
|
|
||||||
|
// Reset the priority to the previous non-sync value.
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
} else {
|
} else {
|
||||||
// No effects.
|
// No effects.
|
||||||
root.current = finishedWork;
|
root.current = finishedWork;
|
||||||
|
@ -2249,7 +2303,15 @@ export function flushPassiveEffects() {
|
||||||
? NormalSchedulerPriority
|
? NormalSchedulerPriority
|
||||||
: pendingPassiveEffectsRenderPriority;
|
: pendingPassiveEffectsRenderPriority;
|
||||||
pendingPassiveEffectsRenderPriority = NoSchedulerPriority;
|
pendingPassiveEffectsRenderPriority = NoSchedulerPriority;
|
||||||
return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
try {
|
||||||
|
setCurrentUpdateLanePriority(
|
||||||
|
schedulerPriorityToLanePriority(priorityLevel),
|
||||||
|
);
|
||||||
|
return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
|
||||||
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ import {
|
||||||
enableSchedulerTracing,
|
enableSchedulerTracing,
|
||||||
warnAboutUnmockedScheduler,
|
warnAboutUnmockedScheduler,
|
||||||
deferRenderPhaseUpdateToNextBatch,
|
deferRenderPhaseUpdateToNextBatch,
|
||||||
|
decoupleUpdatePriorityFromScheduler,
|
||||||
enableDebugTracing,
|
enableDebugTracing,
|
||||||
} from 'shared/ReactFeatureFlags';
|
} from 'shared/ReactFeatureFlags';
|
||||||
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
import ReactSharedInternals from 'shared/ReactSharedInternals';
|
||||||
|
@ -124,6 +125,7 @@ import {
|
||||||
InputDiscreteLanePriority,
|
InputDiscreteLanePriority,
|
||||||
TransitionShortLanePriority,
|
TransitionShortLanePriority,
|
||||||
TransitionLongLanePriority,
|
TransitionLongLanePriority,
|
||||||
|
DefaultLanePriority,
|
||||||
NoLanes,
|
NoLanes,
|
||||||
NoLane,
|
NoLane,
|
||||||
SyncLane,
|
SyncLane,
|
||||||
|
@ -141,6 +143,8 @@ import {
|
||||||
hasUpdatePriority,
|
hasUpdatePriority,
|
||||||
getNextLanes,
|
getNextLanes,
|
||||||
returnNextLanesPriority,
|
returnNextLanesPriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
markStarvedLanesAsExpired,
|
markStarvedLanesAsExpired,
|
||||||
getLanesToRetrySynchronouslyOnError,
|
getLanesToRetrySynchronouslyOnError,
|
||||||
markRootUpdated,
|
markRootUpdated,
|
||||||
|
@ -405,7 +409,6 @@ export function requestUpdateLane(
|
||||||
currentEventWipLanes = workInProgressRootIncludedLanes;
|
currentEventWipLanes = workInProgressRootIncludedLanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
let lane;
|
|
||||||
if (suspenseConfig !== null) {
|
if (suspenseConfig !== null) {
|
||||||
// Use the size of the timeout as a heuristic to prioritize shorter
|
// Use the size of the timeout as a heuristic to prioritize shorter
|
||||||
// transitions over longer ones.
|
// transitions over longer ones.
|
||||||
|
@ -423,26 +426,56 @@ export function requestUpdateLane(
|
||||||
: NoLanes;
|
: NoLanes;
|
||||||
}
|
}
|
||||||
|
|
||||||
lane = findTransitionLane(
|
return findTransitionLane(
|
||||||
transitionLanePriority,
|
transitionLanePriority,
|
||||||
currentEventWipLanes,
|
currentEventWipLanes,
|
||||||
currentEventPendingLanes,
|
currentEventPendingLanes,
|
||||||
);
|
);
|
||||||
} else {
|
}
|
||||||
// TODO: If we're not inside `runWithPriority`, this returns the priority
|
|
||||||
// of the currently running task. That's probably not what we want.
|
|
||||||
const schedulerPriority = getCurrentPriorityLevel();
|
|
||||||
|
|
||||||
if (
|
// TODO: Remove this dependency on the Scheduler priority.
|
||||||
// TODO: Temporary. We're removing the concept of discrete updates.
|
// To do that, we're replacing it with an update lane priority.
|
||||||
(executionContext & DiscreteEventContext) !== NoContext &&
|
const schedulerPriority = getCurrentPriorityLevel();
|
||||||
schedulerPriority === UserBlockingSchedulerPriority
|
|
||||||
) {
|
// The old behavior was using the priority level of the Scheduler.
|
||||||
lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);
|
// This couples React to the Scheduler internals, so we're replacing it
|
||||||
} else {
|
// with the currentUpdateLanePriority above. As an example of how this
|
||||||
const lanePriority = schedulerPriorityToLanePriority(schedulerPriority);
|
// could be problematic, if we're not inside `Scheduler.runWithPriority`,
|
||||||
lane = findUpdateLane(lanePriority, currentEventWipLanes);
|
// then we'll get the priority of the current running Scheduler task,
|
||||||
|
// which is probably not what we want.
|
||||||
|
let lane;
|
||||||
|
if (
|
||||||
|
// TODO: Temporary. We're removing the concept of discrete updates.
|
||||||
|
(executionContext & DiscreteEventContext) !== NoContext &&
|
||||||
|
schedulerPriority === UserBlockingSchedulerPriority
|
||||||
|
) {
|
||||||
|
lane = findUpdateLane(InputDiscreteLanePriority, currentEventWipLanes);
|
||||||
|
} else {
|
||||||
|
const schedulerLanePriority = schedulerPriorityToLanePriority(
|
||||||
|
schedulerPriority,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (decoupleUpdatePriorityFromScheduler) {
|
||||||
|
// In the new strategy, we will track the current update lane priority
|
||||||
|
// inside React and use that priority to select a lane for this update.
|
||||||
|
// For now, we're just logging when they're different so we can assess.
|
||||||
|
const currentUpdateLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
|
||||||
|
if (
|
||||||
|
schedulerLanePriority !== currentUpdateLanePriority &&
|
||||||
|
currentUpdateLanePriority !== NoLanePriority
|
||||||
|
) {
|
||||||
|
if (__DEV__) {
|
||||||
|
console.error(
|
||||||
|
'Expected current scheduler lane priority %s to match current update lane priority %s',
|
||||||
|
schedulerLanePriority,
|
||||||
|
currentUpdateLanePriority,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lane = findUpdateLane(schedulerLanePriority, currentEventWipLanes);
|
||||||
}
|
}
|
||||||
|
|
||||||
return lane;
|
return lane;
|
||||||
|
@ -1079,7 +1112,13 @@ export function flushDiscreteUpdates() {
|
||||||
|
|
||||||
export function deferredUpdates<A>(fn: () => A): A {
|
export function deferredUpdates<A>(fn: () => A): A {
|
||||||
// TODO: Remove in favor of Scheduler.next
|
// TODO: Remove in favor of Scheduler.next
|
||||||
return runWithPriority(NormalSchedulerPriority, fn);
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
try {
|
||||||
|
setCurrentUpdateLanePriority(DefaultLanePriority);
|
||||||
|
return runWithPriority(NormalSchedulerPriority, fn);
|
||||||
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function flushPendingDiscreteUpdates() {
|
function flushPendingDiscreteUpdates() {
|
||||||
|
@ -1134,13 +1173,16 @@ export function discreteUpdates<A, B, C, D, R>(
|
||||||
): R {
|
): R {
|
||||||
const prevExecutionContext = executionContext;
|
const prevExecutionContext = executionContext;
|
||||||
executionContext |= DiscreteEventContext;
|
executionContext |= DiscreteEventContext;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
|
setCurrentUpdateLanePriority(InputDiscreteLanePriority);
|
||||||
// Should this
|
// Should this
|
||||||
return runWithPriority(
|
return runWithPriority(
|
||||||
UserBlockingSchedulerPriority,
|
UserBlockingSchedulerPriority,
|
||||||
fn.bind(null, a, b, c, d),
|
fn.bind(null, a, b, c, d),
|
||||||
);
|
);
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
if (executionContext === NoContext) {
|
if (executionContext === NoContext) {
|
||||||
// Flush the immediate callbacks that were scheduled during this batch
|
// Flush the immediate callbacks that were scheduled during this batch
|
||||||
|
@ -1177,13 +1219,16 @@ export function flushSync<A, R>(fn: A => R, a: A): R {
|
||||||
return fn(a);
|
return fn(a);
|
||||||
}
|
}
|
||||||
executionContext |= BatchedContext;
|
executionContext |= BatchedContext;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
if (fn) {
|
if (fn) {
|
||||||
return runWithPriority(ImmediateSchedulerPriority, fn.bind(null, a));
|
return runWithPriority(ImmediateSchedulerPriority, fn.bind(null, a));
|
||||||
} else {
|
} else {
|
||||||
return (undefined: $FlowFixMe);
|
return (undefined: $FlowFixMe);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
// Flush the immediate callbacks that were scheduled during this batch.
|
// Flush the immediate callbacks that were scheduled during this batch.
|
||||||
// Note that this will happen even if batchedUpdates is higher up
|
// Note that this will happen even if batchedUpdates is higher up
|
||||||
|
@ -1195,9 +1240,12 @@ export function flushSync<A, R>(fn: A => R, a: A): R {
|
||||||
export function flushControlled(fn: () => mixed): void {
|
export function flushControlled(fn: () => mixed): void {
|
||||||
const prevExecutionContext = executionContext;
|
const prevExecutionContext = executionContext;
|
||||||
executionContext |= BatchedContext;
|
executionContext |= BatchedContext;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
runWithPriority(ImmediateSchedulerPriority, fn);
|
runWithPriority(ImmediateSchedulerPriority, fn);
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
if (executionContext === NoContext) {
|
if (executionContext === NoContext) {
|
||||||
// Flush the immediate callbacks that were scheduled during this batch
|
// Flush the immediate callbacks that were scheduled during this batch
|
||||||
|
@ -1915,6 +1963,9 @@ function commitRootImpl(root, renderPriorityLevel) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (firstEffect !== null) {
|
if (firstEffect !== null) {
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
|
|
||||||
const prevExecutionContext = executionContext;
|
const prevExecutionContext = executionContext;
|
||||||
executionContext |= CommitContext;
|
executionContext |= CommitContext;
|
||||||
const prevInteractions = pushInteractions(root);
|
const prevInteractions = pushInteractions(root);
|
||||||
|
@ -2035,6 +2086,9 @@ function commitRootImpl(root, renderPriorityLevel) {
|
||||||
popInteractions(((prevInteractions: any): Set<Interaction>));
|
popInteractions(((prevInteractions: any): Set<Interaction>));
|
||||||
}
|
}
|
||||||
executionContext = prevExecutionContext;
|
executionContext = prevExecutionContext;
|
||||||
|
|
||||||
|
// Reset the priority to the previous non-sync value.
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
} else {
|
} else {
|
||||||
// No effects.
|
// No effects.
|
||||||
root.current = finishedWork;
|
root.current = finishedWork;
|
||||||
|
@ -2321,7 +2375,15 @@ export function flushPassiveEffects() {
|
||||||
? NormalSchedulerPriority
|
? NormalSchedulerPriority
|
||||||
: pendingPassiveEffectsRenderPriority;
|
: pendingPassiveEffectsRenderPriority;
|
||||||
pendingPassiveEffectsRenderPriority = NoSchedulerPriority;
|
pendingPassiveEffectsRenderPriority = NoSchedulerPriority;
|
||||||
return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
|
try {
|
||||||
|
setCurrentUpdateLanePriority(
|
||||||
|
schedulerPriorityToLanePriority(priorityLevel),
|
||||||
|
);
|
||||||
|
return runWithPriority(priorityLevel, flushPassiveEffectsImpl);
|
||||||
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,11 @@ import * as Scheduler from 'scheduler';
|
||||||
import {__interactionsRef} from 'scheduler/tracing';
|
import {__interactionsRef} from 'scheduler/tracing';
|
||||||
import {enableSchedulerTracing} from 'shared/ReactFeatureFlags';
|
import {enableSchedulerTracing} from 'shared/ReactFeatureFlags';
|
||||||
import invariant from 'shared/invariant';
|
import invariant from 'shared/invariant';
|
||||||
|
import {
|
||||||
|
SyncLanePriority,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
} from './ReactFiberLane';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
unstable_runWithPriority: Scheduler_runWithPriority,
|
unstable_runWithPriority: Scheduler_runWithPriority,
|
||||||
|
@ -171,9 +176,11 @@ function flushSyncCallbackQueueImpl() {
|
||||||
// Prevent re-entrancy.
|
// Prevent re-entrancy.
|
||||||
isFlushingSyncQueue = true;
|
isFlushingSyncQueue = true;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
const isSync = true;
|
const isSync = true;
|
||||||
const queue = syncQueue;
|
const queue = syncQueue;
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
runWithPriority(ImmediatePriority, () => {
|
runWithPriority(ImmediatePriority, () => {
|
||||||
for (; i < queue.length; i++) {
|
for (; i < queue.length; i++) {
|
||||||
let callback = queue[i];
|
let callback = queue[i];
|
||||||
|
@ -195,6 +202,7 @@ function flushSyncCallbackQueueImpl() {
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
isFlushingSyncQueue = false;
|
isFlushingSyncQueue = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,11 @@ import * as Scheduler from 'scheduler';
|
||||||
import {__interactionsRef} from 'scheduler/tracing';
|
import {__interactionsRef} from 'scheduler/tracing';
|
||||||
import {enableSchedulerTracing} from 'shared/ReactFeatureFlags';
|
import {enableSchedulerTracing} from 'shared/ReactFeatureFlags';
|
||||||
import invariant from 'shared/invariant';
|
import invariant from 'shared/invariant';
|
||||||
|
import {
|
||||||
|
SyncLanePriority,
|
||||||
|
getCurrentUpdateLanePriority,
|
||||||
|
setCurrentUpdateLanePriority,
|
||||||
|
} from './ReactFiberLane';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
unstable_runWithPriority: Scheduler_runWithPriority,
|
unstable_runWithPriority: Scheduler_runWithPriority,
|
||||||
|
@ -171,9 +176,11 @@ function flushSyncCallbackQueueImpl() {
|
||||||
// Prevent re-entrancy.
|
// Prevent re-entrancy.
|
||||||
isFlushingSyncQueue = true;
|
isFlushingSyncQueue = true;
|
||||||
let i = 0;
|
let i = 0;
|
||||||
|
const previousLanePriority = getCurrentUpdateLanePriority();
|
||||||
try {
|
try {
|
||||||
const isSync = true;
|
const isSync = true;
|
||||||
const queue = syncQueue;
|
const queue = syncQueue;
|
||||||
|
setCurrentUpdateLanePriority(SyncLanePriority);
|
||||||
runWithPriority(ImmediatePriority, () => {
|
runWithPriority(ImmediatePriority, () => {
|
||||||
for (; i < queue.length; i++) {
|
for (; i < queue.length; i++) {
|
||||||
let callback = queue[i];
|
let callback = queue[i];
|
||||||
|
@ -195,6 +202,7 @@ function flushSyncCallbackQueueImpl() {
|
||||||
);
|
);
|
||||||
throw error;
|
throw error;
|
||||||
} finally {
|
} finally {
|
||||||
|
setCurrentUpdateLanePriority(previousLanePriority);
|
||||||
isFlushingSyncQueue = false;
|
isFlushingSyncQueue = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -516,11 +516,16 @@ describe('ReactIncrementalUpdates', () => {
|
||||||
Scheduler.unstable_yieldValue('Committed: ' + log);
|
Scheduler.unstable_yieldValue('Committed: ' + log);
|
||||||
if (log === 'B') {
|
if (log === 'B') {
|
||||||
// Right after B commits, schedule additional updates.
|
// Right after B commits, schedule additional updates.
|
||||||
Scheduler.unstable_runWithPriority(
|
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||||
|
ReactNoop.unstable_runWithPriority(
|
||||||
Scheduler.unstable_UserBlockingPriority,
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
() => {
|
() =>
|
||||||
pushToLog('C');
|
Scheduler.unstable_runWithPriority(
|
||||||
},
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
|
() => {
|
||||||
|
pushToLog('C');
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
setLog(prevLog => prevLog + 'D');
|
setLog(prevLog => prevLog + 'D');
|
||||||
}
|
}
|
||||||
|
@ -538,11 +543,17 @@ describe('ReactIncrementalUpdates', () => {
|
||||||
|
|
||||||
await ReactNoop.act(async () => {
|
await ReactNoop.act(async () => {
|
||||||
pushToLog('A');
|
pushToLog('A');
|
||||||
Scheduler.unstable_runWithPriority(
|
|
||||||
|
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||||
|
ReactNoop.unstable_runWithPriority(
|
||||||
Scheduler.unstable_UserBlockingPriority,
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
() => {
|
() =>
|
||||||
pushToLog('B');
|
Scheduler.unstable_runWithPriority(
|
||||||
},
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
|
() => {
|
||||||
|
pushToLog('B');
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
expect(Scheduler).toHaveYielded([
|
expect(Scheduler).toHaveYielded([
|
||||||
|
@ -574,11 +585,16 @@ describe('ReactIncrementalUpdates', () => {
|
||||||
Scheduler.unstable_yieldValue('Committed: ' + this.state.log);
|
Scheduler.unstable_yieldValue('Committed: ' + this.state.log);
|
||||||
if (this.state.log === 'B') {
|
if (this.state.log === 'B') {
|
||||||
// Right after B commits, schedule additional updates.
|
// Right after B commits, schedule additional updates.
|
||||||
Scheduler.unstable_runWithPriority(
|
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||||
|
ReactNoop.unstable_runWithPriority(
|
||||||
Scheduler.unstable_UserBlockingPriority,
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
() => {
|
() =>
|
||||||
this.pushToLog('C');
|
Scheduler.unstable_runWithPriority(
|
||||||
},
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
|
() => {
|
||||||
|
this.pushToLog('C');
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
this.pushToLog('D');
|
this.pushToLog('D');
|
||||||
}
|
}
|
||||||
|
@ -598,11 +614,16 @@ describe('ReactIncrementalUpdates', () => {
|
||||||
|
|
||||||
await ReactNoop.act(async () => {
|
await ReactNoop.act(async () => {
|
||||||
pushToLog('A');
|
pushToLog('A');
|
||||||
Scheduler.unstable_runWithPriority(
|
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||||
|
ReactNoop.unstable_runWithPriority(
|
||||||
Scheduler.unstable_UserBlockingPriority,
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
() => {
|
() =>
|
||||||
pushToLog('B');
|
Scheduler.unstable_runWithPriority(
|
||||||
},
|
Scheduler.unstable_UserBlockingPriority,
|
||||||
|
() => {
|
||||||
|
pushToLog('B');
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
expect(Scheduler).toHaveYielded([
|
expect(Scheduler).toHaveYielded([
|
||||||
|
|
|
@ -232,9 +232,14 @@ describe('ReactDOMTracing', () => {
|
||||||
Scheduler.unstable_yieldValue('Child:update');
|
Scheduler.unstable_yieldValue('Child:update');
|
||||||
} else {
|
} else {
|
||||||
Scheduler.unstable_yieldValue('Child:mount');
|
Scheduler.unstable_yieldValue('Child:mount');
|
||||||
Scheduler.unstable_runWithPriority(
|
// TODO: Double wrapping is temporary while we remove Scheduler runWithPriority.
|
||||||
|
ReactDOM.unstable_runWithPriority(
|
||||||
Scheduler.unstable_IdlePriority,
|
Scheduler.unstable_IdlePriority,
|
||||||
() => setDidMount(true),
|
() =>
|
||||||
|
Scheduler.unstable_runWithPriority(
|
||||||
|
Scheduler.unstable_IdlePriority,
|
||||||
|
() => setDidMount(true),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}, [didMount]);
|
}, [didMount]);
|
||||||
|
|
|
@ -120,3 +120,6 @@ export const enableLegacyFBSupport = false;
|
||||||
// interleaved event. Remove this flag once we have migrated to the
|
// interleaved event. Remove this flag once we have migrated to the
|
||||||
// new behavior.
|
// new behavior.
|
||||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||||
|
|
||||||
|
// Replacement for runWithPriority in React internals.
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = false;
|
||||||
|
|
|
@ -46,6 +46,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
|
||||||
|
|
||||||
export const enableNewReconciler = false;
|
export const enableNewReconciler = false;
|
||||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = false;
|
||||||
|
|
||||||
// Flow magic to verify the exports of this file match the original version.
|
// Flow magic to verify the exports of this file match the original version.
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|
|
@ -45,6 +45,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
|
||||||
|
|
||||||
export const enableNewReconciler = false;
|
export const enableNewReconciler = false;
|
||||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = false;
|
||||||
|
|
||||||
// Flow magic to verify the exports of this file match the original version.
|
// Flow magic to verify the exports of this file match the original version.
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|
|
@ -45,6 +45,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
|
||||||
|
|
||||||
export const enableNewReconciler = false;
|
export const enableNewReconciler = false;
|
||||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = false;
|
||||||
|
|
||||||
// Flow magic to verify the exports of this file match the original version.
|
// Flow magic to verify the exports of this file match the original version.
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|
|
@ -45,6 +45,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
|
||||||
|
|
||||||
export const enableNewReconciler = false;
|
export const enableNewReconciler = false;
|
||||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = false;
|
||||||
|
|
||||||
// Flow magic to verify the exports of this file match the original version.
|
// Flow magic to verify the exports of this file match the original version.
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|
|
@ -45,6 +45,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
|
||||||
|
|
||||||
export const enableNewReconciler = false;
|
export const enableNewReconciler = false;
|
||||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = false;
|
||||||
|
|
||||||
// Flow magic to verify the exports of this file match the original version.
|
// Flow magic to verify the exports of this file match the original version.
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|
|
@ -45,6 +45,7 @@ export const enableFilterEmptyStringAttributesDOM = false;
|
||||||
|
|
||||||
export const enableNewReconciler = false;
|
export const enableNewReconciler = false;
|
||||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = false;
|
||||||
|
|
||||||
// Flow magic to verify the exports of this file match the original version.
|
// Flow magic to verify the exports of this file match the original version.
|
||||||
// eslint-disable-next-line no-unused-vars
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
|
|
@ -18,6 +18,7 @@ export const disableInputAttributeSyncing = __VARIANT__;
|
||||||
export const enableFilterEmptyStringAttributesDOM = __VARIANT__;
|
export const enableFilterEmptyStringAttributesDOM = __VARIANT__;
|
||||||
export const enableLegacyFBSupport = __VARIANT__;
|
export const enableLegacyFBSupport = __VARIANT__;
|
||||||
export const enableDebugTracing = !__VARIANT__;
|
export const enableDebugTracing = !__VARIANT__;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = __VARIANT__;
|
||||||
|
|
||||||
// This only has an effect in the new reconciler. But also, the new reconciler
|
// This only has an effect in the new reconciler. But also, the new reconciler
|
||||||
// is only enabled when __VARIANT__ is true. So this is set to the opposite of
|
// is only enabled when __VARIANT__ is true. So this is set to the opposite of
|
||||||
|
|
|
@ -75,6 +75,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||||
// don't have to add another test dimension. The build system will compile this
|
// don't have to add another test dimension. The build system will compile this
|
||||||
// to the correct value.
|
// to the correct value.
|
||||||
export const enableNewReconciler = __VARIANT__;
|
export const enableNewReconciler = __VARIANT__;
|
||||||
|
export const decoupleUpdatePriorityFromScheduler = __VARIANT__;
|
||||||
|
|
||||||
// TODO: This does not currently exist in the new reconciler fork.
|
// TODO: This does not currently exist in the new reconciler fork.
|
||||||
export const enableDebugTracing = !__VARIANT__;
|
export const enableDebugTracing = !__VARIANT__;
|
||||||
|
|
Loading…
Reference in New Issue