Skip to content

Commit

Permalink
[DOM] move flushSync out of the reconciler (#28500)
Browse files Browse the repository at this point in the history
This PR moves `flushSync` out of the reconciler. there is still an
internal implementation that is used when these semantics are needed for
React methods such as `unmount` on roots.

This new isomorphic `flushSync` is only used in builds that no longer
support legacy mode.

Additionally all the internal uses of flushSync in the reconciler have
been replaced with more direct methods. There is a new
`updateContainerSync` method which updates a container but forces it to
the Sync lane and flushes passive effects if necessary. This combined
with flushSyncWork can be used to replace flushSync for all instances of
internal usage.

We still maintain the original flushSync implementation as
`flushSyncFromReconciler` because it will be used as the flushSync
implementation for FB builds. This is because it has special legacy mode
handling that the new isomorphic implementation does not need to
consider. It will be removed from production OSS builds by closure
though

DiffTrain build for commit 4c12339.
  • Loading branch information
gnoff committed Apr 8, 2024
1 parent bb12450 commit d629d07
Show file tree
Hide file tree
Showing 10 changed files with 370 additions and 336 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<7d40122affc60fd6dee01dfb5006f923>>
* @generated SignedSource<<80d7175505ee7b5092250e0e58c47878>>
*/

"use strict";
Expand Down Expand Up @@ -121,6 +121,9 @@ if (__DEV__) {

var assign = Object.assign;

var LegacyRoot = 0;
var ConcurrentRoot = 1;

/**
* `ReactInstanceMap` maintains a mapping from a public facing stateful
* instance (key) and the internal representation (value). This allows public
Expand Down Expand Up @@ -2867,9 +2870,6 @@ if (__DEV__) {
}
}

var LegacyRoot = 0;
var ConcurrentRoot = 1;

// We use the existence of the state object as an indicator that the component
// is hidden.
var OffscreenVisible =
Expand Down Expand Up @@ -22409,11 +22409,11 @@ if (__DEV__) {
}

var PossiblyWeakMap = typeof WeakMap === "function" ? WeakMap : Map;
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher,
ReactCurrentCache = ReactSharedInternals.ReactCurrentCache,
ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner,
ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig,
ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
var ReactCurrentCache = ReactSharedInternals.ReactCurrentCache;
var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
var NoContext =
/* */
0;
Expand Down Expand Up @@ -22560,13 +22560,11 @@ if (__DEV__) {

if (transition !== null) {
{
var batchConfigTransition = ReactCurrentBatchConfig.transition;

if (!batchConfigTransition._updatedFibers) {
batchConfigTransition._updatedFibers = new Set();
if (!transition._updatedFibers) {
transition._updatedFibers = new Set();
}

batchConfigTransition._updatedFibers.add(fiber);
transition._updatedFibers.add(fiber);
}

var actionScopeLane = peekEntangledActionLane();
Expand Down Expand Up @@ -23265,7 +23263,7 @@ if (__DEV__) {
// eslint-disable-next-line no-redeclare
// eslint-disable-next-line no-redeclare

function flushSync(fn) {
function flushSyncFromReconciler(fn) {
// In legacy mode, we flush pending passive effects at the beginning of the
// next event, not at the end of the previous one.
if (
Expand Down Expand Up @@ -23305,6 +23303,16 @@ if (__DEV__) {
flushSyncWorkOnAllRoots();
}
}
} // If called outside of a render or commit will flush all sync work on all roots
// Returns whether the the call was during a render or not

function flushSyncWork() {
if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
flushSyncWorkOnAllRoots();
return false;
}

return true;
}
// hidden subtree. The stack logic is managed there because that's the only
// place that ever modifies it. Which module it lives in doesn't matter for
Expand Down Expand Up @@ -25633,13 +25641,12 @@ if (__DEV__) {
var staleFamilies = update.staleFamilies,
updatedFamilies = update.updatedFamilies;
flushPassiveEffects();
flushSync(function () {
scheduleFibersWithFamiliesRecursively(
root.current,
updatedFamilies,
staleFamilies
);
});
scheduleFibersWithFamiliesRecursively(
root.current,
updatedFamilies,
staleFamilies
);
flushSyncWork();
}
};
var scheduleRoot = function (root, element) {
Expand All @@ -25651,10 +25658,8 @@ if (__DEV__) {
return;
}

flushPassiveEffects();
flushSync(function () {
updateContainer(element, root, null, null);
});
updateContainerSync(element, root, null, null);
flushSyncWork();
}
};

Expand Down Expand Up @@ -26615,7 +26620,7 @@ if (__DEV__) {
return root;
}

var ReactVersion = "19.0.0-canary-33793d9f";
var ReactVersion = "19.0.0-canary-5acb30be";

/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
Expand Down Expand Up @@ -26750,13 +26755,52 @@ if (__DEV__) {
);
}
function updateContainer(element, container, parentComponent, callback) {
var current = container.current;
var lane = requestUpdateLane(current);
updateContainerImpl(
current,
lane,
element,
container,
parentComponent,
callback
);
return lane;
}
function updateContainerSync(
element,
container,
parentComponent,
callback
) {
if (container.tag === LegacyRoot) {
flushPassiveEffects();
}

var current = container.current;
updateContainerImpl(
current,
SyncLane,
element,
container,
parentComponent,
callback
);
return SyncLane;
}

function updateContainerImpl(
rootFiber,
lane,
element,
container,
parentComponent,
callback
) {
{
onScheduleRoot(container, element);
}

var current$1 = container.current;
var lane = requestUpdateLane(current$1);

{
markRenderScheduled(lane);
}
Expand Down Expand Up @@ -26805,14 +26849,12 @@ if (__DEV__) {
update.callback = callback;
}

var root = enqueueUpdate(current$1, update, lane);
var root = enqueueUpdate(rootFiber, update, lane);

if (root !== null) {
scheduleUpdateOnFiber(root, current$1, lane);
entangleTransitions(root, current$1, lane);
scheduleUpdateOnFiber(root, rootFiber, lane);
entangleTransitions(root, rootFiber, lane);
}

return lane;
}
function getPublicRootInstance(container) {
var containerFiber = container.current;
Expand Down Expand Up @@ -27713,7 +27755,7 @@ if (__DEV__) {

return getPublicRootInstance(root);
},
unstable_flushSync: flushSync
unstable_flushSync: flushSyncFromReconciler
};
Object.defineProperty(entry, "root", {
configurable: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<c59ed5cae3404a53f31f2928d4976364>>
* @generated SignedSource<<493cdb9fbf258eb499287015c0434886>>
*/

"use strict";
Expand Down Expand Up @@ -7733,7 +7733,7 @@ function performSyncWorkOnRoot(root, lanes) {
ensureRootIsScheduled(root);
return null;
}
function flushSync(fn) {
function flushSyncFromReconciler(fn) {
null !== rootWithPendingPassiveEffects &&
0 === rootWithPendingPassiveEffects.tag &&
0 === (executionContext & 6) &&
Expand Down Expand Up @@ -9148,19 +9148,19 @@ function wrapFiber(fiber) {
fiberToWrapper.set(fiber, wrapper));
return wrapper;
}
var devToolsConfig$jscomp$inline_996 = {
var devToolsConfig$jscomp$inline_1000 = {
findFiberByHostInstance: function () {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-canary-a6279bb7",
version: "19.0.0-canary-0c75b31c",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1216 = {
bundleType: devToolsConfig$jscomp$inline_996.bundleType,
version: devToolsConfig$jscomp$inline_996.version,
rendererPackageName: devToolsConfig$jscomp$inline_996.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_996.rendererConfig,
var internals$jscomp$inline_1222 = {
bundleType: devToolsConfig$jscomp$inline_1000.bundleType,
version: devToolsConfig$jscomp$inline_1000.version,
rendererPackageName: devToolsConfig$jscomp$inline_1000.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1000.rendererConfig,
overrideHookState: null,
overrideHookStateDeletePath: null,
overrideHookStateRenamePath: null,
Expand All @@ -9177,26 +9177,26 @@ var internals$jscomp$inline_1216 = {
return null === fiber ? null : fiber.stateNode;
},
findFiberByHostInstance:
devToolsConfig$jscomp$inline_996.findFiberByHostInstance ||
devToolsConfig$jscomp$inline_1000.findFiberByHostInstance ||
emptyFindFiberByHostInstance,
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-canary-a6279bb7"
reconcilerVersion: "19.0.0-canary-0c75b31c"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1217 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
var hook$jscomp$inline_1223 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
if (
!hook$jscomp$inline_1217.isDisabled &&
hook$jscomp$inline_1217.supportsFiber
!hook$jscomp$inline_1223.isDisabled &&
hook$jscomp$inline_1223.supportsFiber
)
try {
(rendererID = hook$jscomp$inline_1217.inject(
internals$jscomp$inline_1216
(rendererID = hook$jscomp$inline_1223.inject(
internals$jscomp$inline_1222
)),
(injectedHook = hook$jscomp$inline_1217);
(injectedHook = hook$jscomp$inline_1223);
} catch (err) {}
}
exports._Scheduler = Scheduler;
Expand Down Expand Up @@ -9296,7 +9296,7 @@ exports.create = function (element, options) {
}
return JSCompiler_inline_result;
},
unstable_flushSync: flushSync
unstable_flushSync: flushSyncFromReconciler
};
Object.defineProperty(element, "root", {
configurable: !0,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<d579b23be98702834f1877ba69ecd091>>
* @generated SignedSource<<4431ac600b9b830957ac137277654c1b>>
*/

"use strict";
Expand Down Expand Up @@ -8207,7 +8207,7 @@ function performSyncWorkOnRoot(root, lanes) {
ensureRootIsScheduled(root);
return null;
}
function flushSync(fn) {
function flushSyncFromReconciler(fn) {
null !== rootWithPendingPassiveEffects &&
0 === rootWithPendingPassiveEffects.tag &&
0 === (executionContext & 6) &&
Expand Down Expand Up @@ -9764,12 +9764,12 @@ function wrapFiber(fiber) {
fiberToWrapper.set(fiber, wrapper));
return wrapper;
}
var devToolsConfig$jscomp$inline_1080 = {
var devToolsConfig$jscomp$inline_1082 = {
findFiberByHostInstance: function () {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-canary-e4931763",
version: "19.0.0-canary-091aeabc",
rendererPackageName: "react-test-renderer"
};
(function (internals) {
Expand All @@ -9786,10 +9786,10 @@ var devToolsConfig$jscomp$inline_1080 = {
} catch (err) {}
return hook.checkDCE ? !0 : !1;
})({
bundleType: devToolsConfig$jscomp$inline_1080.bundleType,
version: devToolsConfig$jscomp$inline_1080.version,
rendererPackageName: devToolsConfig$jscomp$inline_1080.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1080.rendererConfig,
bundleType: devToolsConfig$jscomp$inline_1082.bundleType,
version: devToolsConfig$jscomp$inline_1082.version,
rendererPackageName: devToolsConfig$jscomp$inline_1082.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1082.rendererConfig,
overrideHookState: null,
overrideHookStateDeletePath: null,
overrideHookStateRenamePath: null,
Expand All @@ -9806,14 +9806,14 @@ var devToolsConfig$jscomp$inline_1080 = {
return null === fiber ? null : fiber.stateNode;
},
findFiberByHostInstance:
devToolsConfig$jscomp$inline_1080.findFiberByHostInstance ||
devToolsConfig$jscomp$inline_1082.findFiberByHostInstance ||
emptyFindFiberByHostInstance,
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-canary-e4931763"
reconcilerVersion: "19.0.0-canary-091aeabc"
});
exports._Scheduler = Scheduler;
exports.act = act;
Expand Down Expand Up @@ -9912,7 +9912,7 @@ exports.create = function (element, options) {
}
return JSCompiler_inline_result;
},
unstable_flushSync: flushSync
unstable_flushSync: flushSyncFromReconciler
};
Object.defineProperty(element, "root", {
configurable: !0,
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
8e1462e8c471fbec98aac2b3e1326498d0ff7139
4c12339ce3fa398050d1026c616ea43d43dcaf4a
Loading

0 comments on commit d629d07

Please sign in to comment.