From fc578ff4b042dcf123e3bd419d300492764fed15 Mon Sep 17 00:00:00 2001 From: acdlite Date: Thu, 23 May 2024 21:25:04 +0000 Subject: [PATCH] Fix async batching in React.startTransition (#29226) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note: Despite the similar-sounding description, this fix is unrelated to the issue where updates that occur after an `await` in an async action must also be wrapped in their own `startTransition`, due to the absence of an AsyncContext mechanism in browsers today. --- Discovered a flaw in the current implementation of the isomorphic startTransition implementation (React.startTransition), related to async actions. It only creates an async scope if something calls setState within the synchronous part of the action (i.e. before the first `await`). I had thought this was fine because if there's no update during this part, then there's nothing that needs to be entangled. I didn't think this through, though — if there are multiple async updates interleaved throughout the rest of the action, we need the async scope to have already been created so that _those_ are batched together. An even easier way to observe this is to schedule an optimistic update after an `await` — the optimistic update should not be reverted until the async action is complete. To implement, during the reconciler's module initialization, we compose its startTransition implementation with any previous reconciler's startTransition that was already initialized. Then, the isomorphic startTransition is the composition of every reconciler's startTransition. ```js function startTransition(fn) { return startTransitionDOM(() => { return startTransitionART(() => { return startTransitionThreeFiber(() => { // and so on... return fn(); }); }); }); } ``` This is basically how flushSync is implemented, too. DiffTrain build for commit https://github.com/facebook/react/commit/ee5c19493086fdeb32057e16d1e3414370242307. --- .../cjs/ReactTestRenderer-dev.js | 83 +++++++++++-------- .../cjs/ReactTestRenderer-prod.js | 49 ++++++----- .../cjs/ReactTestRenderer-profiling.js | 49 ++++++----- .../vendor/react/react/cjs/React-dev.js | 24 +++--- .../vendor/react/react/cjs/React-prod.js | 21 +++-- .../vendor/react/react/cjs/React-profiling.js | 21 +++-- .../Libraries/Renderer/REVISION | 2 +- .../implementations/ReactFabric-dev.fb.js | 83 +++++++++++-------- .../implementations/ReactFabric-prod.fb.js | 49 ++++++----- .../ReactFabric-profiling.fb.js | 49 ++++++----- .../ReactNativeRenderer-dev.fb.js | 83 +++++++++++-------- .../ReactNativeRenderer-prod.fb.js | 49 ++++++----- .../ReactNativeRenderer-profiling.fb.js | 49 ++++++----- 13 files changed, 326 insertions(+), 285 deletions(-) diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js index c33735d638af1..e5b903283b18c 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<7d577e8126a68c701e64111a9f2bbd2a>> + * @generated SignedSource<<8b9b9798442c5728adfabb7cd8ca5f24>> */ 'use strict'; @@ -8576,9 +8576,7 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var prevState = actionQueue.state; // This is a fork of startTransition var prevTransition = ReactSharedInternals.T; - var currentTransition = { - _callbacks: new Set() - }; + var currentTransition = {}; ReactSharedInternals.T = currentTransition; { @@ -8591,11 +8589,15 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { try { var returnValue = action(prevState, payload); + var onStartTransitionFinish = ReactSharedInternals.S; + + if (onStartTransitionFinish !== null) { + onStartTransitionFinish(currentTransition, returnValue); + } if (returnValue !== null && typeof returnValue === 'object' && // $FlowFixMe[method-unbinding] typeof returnValue.then === 'function') { - var thenable = returnValue; - notifyTransitionCallbacks(currentTransition, thenable); // Attach a listener to read the return state of the action. As soon as + var thenable = returnValue; // Attach a listener to read the return state of the action. As soon as // this resolves, we can run the next action in the sequence. thenable.then(function (nextState) { @@ -9100,9 +9102,7 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op var previousPriority = getCurrentUpdatePriority(); setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority)); var prevTransition = ReactSharedInternals.T; - var currentTransition = { - _callbacks: new Set() - }; + var currentTransition = {}; { // We don't really need to use an optimistic update here, because we @@ -9121,7 +9121,12 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op try { if (enableAsyncActions) { - var returnValue = callback(); // Check if we're inside an async action scope. If so, we'll entangle + var returnValue = callback(); + var onStartTransitionFinish = ReactSharedInternals.S; + + if (onStartTransitionFinish !== null) { + onStartTransitionFinish(currentTransition, returnValue); + } // Check if we're inside an async action scope. If so, we'll entangle // this new action with the existing scope. // // If we're not already inside an async action scope, and this action is @@ -9130,9 +9135,9 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op // In the async case, the resulting render will suspend until the async // action scope has finished. + if (returnValue !== null && typeof returnValue === 'object' && typeof returnValue.then === 'function') { - var thenable = returnValue; - notifyTransitionCallbacks(currentTransition, thenable); // Create a thenable that resolves to `finishedState` once the async + var thenable = returnValue; // Create a thenable that resolves to `finishedState` once the async // action has completed. var thenableForFinishedState = chainThenableValue(thenable, finishedState); @@ -15141,30 +15146,42 @@ function popCacheProvider(workInProgress, cache) { popProvider(CacheContext, workInProgress); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - - if (transition !== null) { - // Whenever a transition update is scheduled, register a callback on the - // transition object so we can get the return value of the scope function. - transition._callbacks.add(handleAsyncAction); +// the shared internals object. This is used by the isomorphic implementation of +// startTransition to compose all the startTransitions together. +// +// function startTransition(fn) { +// return startTransitionDOM(() => { +// return startTransitionART(() => { +// return startTransitionThreeFiber(() => { +// // and so on... +// return fn(); +// }); +// }); +// }); +// } +// +// Currently we only compose together the code that runs at the end of each +// startTransition, because for now that's sufficient — the part that sets +// isTransition=true on the stack uses a separate shared internal field. But +// really we should delete the shared field and track isTransition per +// reconciler. Leaving this for a future PR. + +var prevOnStartTransitionFinish = ReactSharedInternals.S; + +ReactSharedInternals.S = function onStartTransitionFinishForReconciler(transition, returnValue) { + if (typeof returnValue === 'object' && returnValue !== null && typeof returnValue.then === 'function') { + // This is an async action + var thenable = returnValue; + entangleAsyncAction(transition, thenable); } - return transition; -} - -function handleAsyncAction(transition, thenable) { - { - // This is an async action. - entangleAsyncAction(transition, thenable); + if (prevOnStartTransitionFinish !== null) { + prevOnStartTransitionFinish(transition, returnValue); } -} +}; -function notifyTransitionCallbacks(transition, returnValue) { - var callbacks = transition._callbacks; - callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); +function requestCurrentTransition() { + return ReactSharedInternals.T; } // When retrying a Suspense/Offscreen boundary, we restore the cache that was // used during the previous render by placing it here, on the stack. @@ -23446,7 +23463,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-c940c483'; +var ReactVersion = '19.0.0-rc-5a18a922'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js index 702f140d75a79..602a7cef0fc40 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<8fc32585cc376c14df2f02921b08d02e>> + * @generated SignedSource<> */ "use strict"; @@ -2780,16 +2780,18 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var action = actionQueue.action, prevState = actionQueue.state, prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; setPendingState(!0); try { - var returnValue = action(prevState, payload); + var returnValue = action(prevState, payload), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then - ? (notifyTransitionCallbacks(currentTransition, returnValue), - returnValue.then( + ? (returnValue.then( function (nextState) { actionQueue.state = nextState; finishRunningActionStateAction( @@ -3049,17 +3051,19 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; var prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; dispatchOptimisticSetState(fiber, !1, queue, pendingState); try { - var returnValue = callback(); + var returnValue = callback(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); if ( null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then ) { - notifyTransitionCallbacks(currentTransition, returnValue); var thenableForFinishedState = chainThenableValue( returnValue, finishedState @@ -3160,7 +3164,6 @@ function dispatchSetState(fiber, queue, action) { } } function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - requestCurrentTransition(); action = { lane: 2, revertLane: requestTransitionLane(), @@ -5602,19 +5605,15 @@ function releaseCache(cache) { cache.controller.abort(); }); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - null !== transition && transition._callbacks.add(handleAsyncAction); - return transition; -} -function handleAsyncAction(transition, thenable) { - entangleAsyncAction(transition, thenable); -} -function notifyTransitionCallbacks(transition, returnValue) { - transition._callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); -} +var prevOnStartTransitionFinish = ReactSharedInternals.S; +ReactSharedInternals.S = function (transition, returnValue) { + "object" === typeof returnValue && + null !== returnValue && + "function" === typeof returnValue.then && + entangleAsyncAction(transition, returnValue); + null !== prevOnStartTransitionFinish && + prevOnStartTransitionFinish(transition, returnValue); +}; var resumedCache = createCursor(null); function peekCacheFromPool() { var cacheResumedFromPreviousRender = resumedCache.current; @@ -7573,7 +7572,7 @@ function requestUpdateLane(fiber) { if (0 === (fiber.mode & 1)) return 2; if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - if (null !== requestCurrentTransition()) + if (null !== ReactSharedInternals.T) return ( (fiber = currentEntangledLane), 0 !== fiber ? fiber : requestTransitionLane() @@ -9301,7 +9300,7 @@ var devToolsConfig$jscomp$inline_1042 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "19.0.0-rc-2bec340c", + version: "19.0.0-rc-9c2862e7", rendererPackageName: "react-test-renderer" }; var internals$jscomp$inline_1229 = { @@ -9332,7 +9331,7 @@ var internals$jscomp$inline_1229 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-2bec340c" + reconcilerVersion: "19.0.0-rc-9c2862e7" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1230 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js index 3146dab8668f9..f5a15b425598d 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react-test-renderer/cjs/ReactTestRenderer-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ "use strict"; @@ -2868,16 +2868,18 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var action = actionQueue.action, prevState = actionQueue.state, prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; setPendingState(!0); try { - var returnValue = action(prevState, payload); + var returnValue = action(prevState, payload), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then - ? (notifyTransitionCallbacks(currentTransition, returnValue), - returnValue.then( + ? (returnValue.then( function (nextState) { actionQueue.state = nextState; finishRunningActionStateAction( @@ -3139,17 +3141,19 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; var prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; dispatchOptimisticSetState(fiber, !1, queue, pendingState); try { - var returnValue = callback(); + var returnValue = callback(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); if ( null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then ) { - notifyTransitionCallbacks(currentTransition, returnValue); var thenableForFinishedState = chainThenableValue( returnValue, finishedState @@ -3252,7 +3256,6 @@ function dispatchSetState(fiber, queue, action) { markStateUpdateScheduled(fiber, lane); } function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - requestCurrentTransition(); action = { lane: 2, revertLane: requestTransitionLane(), @@ -5809,19 +5812,15 @@ function releaseCache(cache) { cache.controller.abort(); }); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - null !== transition && transition._callbacks.add(handleAsyncAction); - return transition; -} -function handleAsyncAction(transition, thenable) { - entangleAsyncAction(transition, thenable); -} -function notifyTransitionCallbacks(transition, returnValue) { - transition._callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); -} +var prevOnStartTransitionFinish = ReactSharedInternals.S; +ReactSharedInternals.S = function (transition, returnValue) { + "object" === typeof returnValue && + null !== returnValue && + "function" === typeof returnValue.then && + entangleAsyncAction(transition, returnValue); + null !== prevOnStartTransitionFinish && + prevOnStartTransitionFinish(transition, returnValue); +}; var resumedCache = createCursor(null); function peekCacheFromPool() { var cacheResumedFromPreviousRender = resumedCache.current; @@ -8056,7 +8055,7 @@ function requestUpdateLane(fiber) { if (0 === (fiber.mode & 1)) return 2; if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - if (null !== requestCurrentTransition()) + if (null !== ReactSharedInternals.T) return ( (fiber = currentEntangledLane), 0 !== fiber ? fiber : requestTransitionLane() @@ -9944,7 +9943,7 @@ var devToolsConfig$jscomp$inline_1105 = { throw Error("TestRenderer does not support findFiberByHostInstance()"); }, bundleType: 0, - version: "19.0.0-rc-e8e0cdf6", + version: "19.0.0-rc-6cf53e9c", rendererPackageName: "react-test-renderer" }; (function (internals) { @@ -9988,7 +9987,7 @@ var devToolsConfig$jscomp$inline_1105 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-e8e0cdf6" + reconcilerVersion: "19.0.0-rc-6cf53e9c" }); exports._Scheduler = Scheduler; exports.act = act; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js index d2cd3036d1205..428e43e96a659 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-dev.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<5b1dc62c6ba34c7e7218ad93ccffc6a0>> */ 'use strict'; @@ -24,7 +24,7 @@ if ( } var dynamicFlagsUntyped = require('ReactNativeInternalFeatureFlags'); -var ReactVersion = '19.0.0-rc-03d16137'; +var ReactVersion = '19.0.0-rc-f0094578'; // Re-export dynamic flags from the internal module. var dynamicFlags = dynamicFlagsUntyped; // We destructure each value before re-exporting to avoid a dynamic look-up on @@ -85,7 +85,8 @@ function getIteratorFn(maybeIterable) { var ReactSharedInternals = { H: null, A: null, - T: null + T: null, + S: null }; { @@ -2576,13 +2577,8 @@ reportError : function (error) { }; function startTransition(scope, options) { - var prevTransition = ReactSharedInternals.T; // Each renderer registers a callback to receive the return value of - // the scope function. This is used to implement async actions. - - var callbacks = new Set(); - var transition = { - _callbacks: callbacks - }; + var prevTransition = ReactSharedInternals.T; + var transition = {}; ReactSharedInternals.T = transition; var currentTransition = ReactSharedInternals.T; @@ -2593,11 +2589,13 @@ function startTransition(scope, options) { { try { var returnValue = scope(); + var onStartTransitionFinish = ReactSharedInternals.S; + + if (onStartTransitionFinish !== null) { + onStartTransitionFinish(transition, returnValue); + } if (typeof returnValue === 'object' && returnValue !== null && typeof returnValue.then === 'function') { - callbacks.forEach(function (callback) { - return callback(currentTransition, returnValue); - }); returnValue.then(noop, reportGlobalError); } } catch (error) { diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js index 70e26af075617..a2462c4a9ed44 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-prod.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<351b89bf44a598ef0b145129629686f1>> + * @generated SignedSource<> */ "use strict"; @@ -84,7 +84,7 @@ pureComponentPrototype.constructor = PureComponent; assign(pureComponentPrototype, Component.prototype); pureComponentPrototype.isPureReactComponent = !0; var isArrayImpl = Array.isArray, - ReactSharedInternals = { H: null, A: null, T: null }, + ReactSharedInternals = { H: null, A: null, T: null, S: null }, hasOwnProperty = Object.prototype.hasOwnProperty, enableFastJSXWithStringRefs = enableFastJSX && !0, enableFastJSXWithoutStringRefs = enableFastJSXWithStringRefs && !0; @@ -513,18 +513,17 @@ exports.memo = function (type, compare) { }; exports.startTransition = function (scope) { var prevTransition = ReactSharedInternals.T, - callbacks = new Set(); - ReactSharedInternals.T = { _callbacks: callbacks }; - var currentTransition = ReactSharedInternals.T; + transition = {}; + ReactSharedInternals.T = transition; try { - var returnValue = scope(); + var returnValue = scope(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(transition, returnValue); "object" === typeof returnValue && null !== returnValue && "function" === typeof returnValue.then && - (callbacks.forEach(function (callback) { - return callback(currentTransition, returnValue); - }), - returnValue.then(noop, reportGlobalError)); + returnValue.then(noop, reportGlobalError); } catch (error) { reportGlobalError(error); } finally { @@ -605,4 +604,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-f9855a0e"; +exports.version = "19.0.0-rc-84331da2"; diff --git a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js index e589a0cca8e46..dd34b7f2dcf68 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js +++ b/compiled-rn/facebook-fbsource/xplat/js/RKJSModules/vendor/react/react/cjs/React-profiling.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<9abe927796efac5ad36cba3bc74df7db>> */ "use strict"; @@ -88,7 +88,7 @@ pureComponentPrototype.constructor = PureComponent; assign(pureComponentPrototype, Component.prototype); pureComponentPrototype.isPureReactComponent = !0; var isArrayImpl = Array.isArray, - ReactSharedInternals = { H: null, A: null, T: null }, + ReactSharedInternals = { H: null, A: null, T: null, S: null }, hasOwnProperty = Object.prototype.hasOwnProperty, enableFastJSXWithStringRefs = enableFastJSX && !0, enableFastJSXWithoutStringRefs = enableFastJSXWithStringRefs && !0; @@ -517,18 +517,17 @@ exports.memo = function (type, compare) { }; exports.startTransition = function (scope) { var prevTransition = ReactSharedInternals.T, - callbacks = new Set(); - ReactSharedInternals.T = { _callbacks: callbacks }; - var currentTransition = ReactSharedInternals.T; + transition = {}; + ReactSharedInternals.T = transition; try { - var returnValue = scope(); + var returnValue = scope(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(transition, returnValue); "object" === typeof returnValue && null !== returnValue && "function" === typeof returnValue.then && - (callbacks.forEach(function (callback) { - return callback(currentTransition, returnValue); - }), - returnValue.then(noop, reportGlobalError)); + returnValue.then(noop, reportGlobalError); } catch (error) { reportGlobalError(error); } finally { @@ -609,7 +608,7 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-680d5437"; +exports.version = "19.0.0-rc-b23e981f"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION index ac73a4bcae47d..e451595645d89 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/REVISION @@ -1 +1 @@ -f55d172bcf921d761733533395b798c5b3665e04 +ee5c19493086fdeb32057e16d1e3414370242307 diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js index 94370107ca1ff..1ebbb9ab20ff6 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<757728100d8986540b7c4b4ec6d7f99d>> */ 'use strict'; @@ -11322,9 +11322,7 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var prevState = actionQueue.state; // This is a fork of startTransition var prevTransition = ReactSharedInternals.T; - var currentTransition = { - _callbacks: new Set() - }; + var currentTransition = {}; ReactSharedInternals.T = currentTransition; { @@ -11337,11 +11335,15 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { try { var returnValue = action(prevState, payload); + var onStartTransitionFinish = ReactSharedInternals.S; + + if (onStartTransitionFinish !== null) { + onStartTransitionFinish(currentTransition, returnValue); + } if (returnValue !== null && typeof returnValue === 'object' && // $FlowFixMe[method-unbinding] typeof returnValue.then === 'function') { - var thenable = returnValue; - notifyTransitionCallbacks(currentTransition, thenable); // Attach a listener to read the return state of the action. As soon as + var thenable = returnValue; // Attach a listener to read the return state of the action. As soon as // this resolves, we can run the next action in the sequence. thenable.then(function (nextState) { @@ -11859,9 +11861,7 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op var previousPriority = getCurrentUpdatePriority(); setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority)); var prevTransition = ReactSharedInternals.T; - var currentTransition = { - _callbacks: new Set() - }; + var currentTransition = {}; { // We don't really need to use an optimistic update here, because we @@ -11880,7 +11880,12 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op try { if (enableAsyncActions) { - var returnValue = callback(); // Check if we're inside an async action scope. If so, we'll entangle + var returnValue = callback(); + var onStartTransitionFinish = ReactSharedInternals.S; + + if (onStartTransitionFinish !== null) { + onStartTransitionFinish(currentTransition, returnValue); + } // Check if we're inside an async action scope. If so, we'll entangle // this new action with the existing scope. // // If we're not already inside an async action scope, and this action is @@ -11889,9 +11894,9 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op // In the async case, the resulting render will suspend until the async // action scope has finished. + if (returnValue !== null && typeof returnValue === 'object' && typeof returnValue.then === 'function') { - var thenable = returnValue; - notifyTransitionCallbacks(currentTransition, thenable); // Create a thenable that resolves to `finishedState` once the async + var thenable = returnValue; // Create a thenable that resolves to `finishedState` once the async // action has completed. var thenableForFinishedState = chainThenableValue(thenable, finishedState); @@ -17954,30 +17959,42 @@ function popCacheProvider(workInProgress, cache) { popProvider(CacheContext, workInProgress); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - - if (transition !== null) { - // Whenever a transition update is scheduled, register a callback on the - // transition object so we can get the return value of the scope function. - transition._callbacks.add(handleAsyncAction); +// the shared internals object. This is used by the isomorphic implementation of +// startTransition to compose all the startTransitions together. +// +// function startTransition(fn) { +// return startTransitionDOM(() => { +// return startTransitionART(() => { +// return startTransitionThreeFiber(() => { +// // and so on... +// return fn(); +// }); +// }); +// }); +// } +// +// Currently we only compose together the code that runs at the end of each +// startTransition, because for now that's sufficient — the part that sets +// isTransition=true on the stack uses a separate shared internal field. But +// really we should delete the shared field and track isTransition per +// reconciler. Leaving this for a future PR. + +var prevOnStartTransitionFinish = ReactSharedInternals.S; + +ReactSharedInternals.S = function onStartTransitionFinishForReconciler(transition, returnValue) { + if (typeof returnValue === 'object' && returnValue !== null && typeof returnValue.then === 'function') { + // This is an async action + var thenable = returnValue; + entangleAsyncAction(transition, thenable); } - return transition; -} - -function handleAsyncAction(transition, thenable) { - { - // This is an async action. - entangleAsyncAction(transition, thenable); + if (prevOnStartTransitionFinish !== null) { + prevOnStartTransitionFinish(transition, returnValue); } -} +}; -function notifyTransitionCallbacks(transition, returnValue) { - var callbacks = transition._callbacks; - callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); +function requestCurrentTransition() { + return ReactSharedInternals.T; } // When retrying a Suspense/Offscreen boundary, we restore the cache that was // used during the previous render by placing it here, on the stack. @@ -26185,7 +26202,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-c9a0036b'; +var ReactVersion = '19.0.0-rc-2dfc4dcf'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js index 8c7fb6b6d0336..13d6980370b67 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<<3df16b37cf2b6f509adae77d0539c068>> */ "use strict"; @@ -4160,16 +4160,18 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var action = actionQueue.action, prevState = actionQueue.state, prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; setPendingState(!0); try { - var returnValue = action(prevState, payload); + var returnValue = action(prevState, payload), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then - ? (notifyTransitionCallbacks(currentTransition, returnValue), - returnValue.then( + ? (returnValue.then( function (nextState) { actionQueue.state = nextState; finishRunningActionStateAction( @@ -4434,17 +4436,19 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; var prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; dispatchOptimisticSetState(fiber, !1, queue, pendingState); try { - var returnValue = callback(); + var returnValue = callback(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); if ( null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then ) { - notifyTransitionCallbacks(currentTransition, returnValue); var thenableForFinishedState = chainThenableValue( returnValue, finishedState @@ -4545,7 +4549,6 @@ function dispatchSetState(fiber, queue, action) { } } function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - requestCurrentTransition(); action = { lane: 2, revertLane: requestTransitionLane(), @@ -7009,19 +7012,15 @@ function releaseCache(cache) { cache.controller.abort(); }); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - null !== transition && transition._callbacks.add(handleAsyncAction); - return transition; -} -function handleAsyncAction(transition, thenable) { - entangleAsyncAction(transition, thenable); -} -function notifyTransitionCallbacks(transition, returnValue) { - transition._callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); -} +var prevOnStartTransitionFinish = ReactSharedInternals.S; +ReactSharedInternals.S = function (transition, returnValue) { + "object" === typeof returnValue && + null !== returnValue && + "function" === typeof returnValue.then && + entangleAsyncAction(transition, returnValue); + null !== prevOnStartTransitionFinish && + prevOnStartTransitionFinish(transition, returnValue); +}; var resumedCache = createCursor(null); function peekCacheFromPool() { var cacheResumedFromPreviousRender = resumedCache.current; @@ -8962,7 +8961,7 @@ function requestUpdateLane(fiber) { ? 2 : 0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes ? workInProgressRootRenderLanes & -workInProgressRootRenderLanes - : null !== requestCurrentTransition() + : null !== ReactSharedInternals.T ? ((fiber = currentEntangledLane), 0 !== fiber ? fiber : requestTransitionLane()) : resolveUpdatePriority(); @@ -10559,7 +10558,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1119 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-5eacd827", + version: "19.0.0-rc-f7d07ad2", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10602,7 +10601,7 @@ var internals$jscomp$inline_1349 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-5eacd827" + reconcilerVersion: "19.0.0-rc-f7d07ad2" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1350 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js index 2397b4e9c9cda..a273faf3260aa 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactFabric-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<7d5a8059edc8c032a1e129b62535d195>> + * @generated SignedSource<> */ "use strict"; @@ -4282,16 +4282,18 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var action = actionQueue.action, prevState = actionQueue.state, prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; setPendingState(!0); try { - var returnValue = action(prevState, payload); + var returnValue = action(prevState, payload), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then - ? (notifyTransitionCallbacks(currentTransition, returnValue), - returnValue.then( + ? (returnValue.then( function (nextState) { actionQueue.state = nextState; finishRunningActionStateAction( @@ -4556,17 +4558,19 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; var prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; dispatchOptimisticSetState(fiber, !1, queue, pendingState); try { - var returnValue = callback(); + var returnValue = callback(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); if ( null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then ) { - notifyTransitionCallbacks(currentTransition, returnValue); var thenableForFinishedState = chainThenableValue( returnValue, finishedState @@ -4669,7 +4673,6 @@ function dispatchSetState(fiber, queue, action) { markStateUpdateScheduled(fiber, lane); } function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - requestCurrentTransition(); action = { lane: 2, revertLane: requestTransitionLane(), @@ -7239,19 +7242,15 @@ function releaseCache(cache) { cache.controller.abort(); }); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - null !== transition && transition._callbacks.add(handleAsyncAction); - return transition; -} -function handleAsyncAction(transition, thenable) { - entangleAsyncAction(transition, thenable); -} -function notifyTransitionCallbacks(transition, returnValue) { - transition._callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); -} +var prevOnStartTransitionFinish = ReactSharedInternals.S; +ReactSharedInternals.S = function (transition, returnValue) { + "object" === typeof returnValue && + null !== returnValue && + "function" === typeof returnValue.then && + entangleAsyncAction(transition, returnValue); + null !== prevOnStartTransitionFinish && + prevOnStartTransitionFinish(transition, returnValue); +}; var resumedCache = createCursor(null); function peekCacheFromPool() { var cacheResumedFromPreviousRender = resumedCache.current; @@ -9490,7 +9489,7 @@ function requestUpdateLane(fiber) { ? 2 : 0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes ? workInProgressRootRenderLanes & -workInProgressRootRenderLanes - : null !== requestCurrentTransition() + : null !== ReactSharedInternals.T ? ((fiber = currentEntangledLane), 0 !== fiber ? fiber : requestTransitionLane()) : resolveUpdatePriority(); @@ -11264,7 +11263,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1199 = { findFiberByHostInstance: getInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-f1129266", + version: "19.0.0-rc-7258f280", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -11320,7 +11319,7 @@ var roots = new Map(), scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-f1129266" + reconcilerVersion: "19.0.0-rc-7258f280" }); exports.createPortal = function (children, containerTag) { return createPortal$1( diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js index 5571c454b263a..dbfe6359efe76 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-dev.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<> + * @generated SignedSource<> */ 'use strict'; @@ -11499,9 +11499,7 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var prevState = actionQueue.state; // This is a fork of startTransition var prevTransition = ReactSharedInternals.T; - var currentTransition = { - _callbacks: new Set() - }; + var currentTransition = {}; ReactSharedInternals.T = currentTransition; { @@ -11514,11 +11512,15 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { try { var returnValue = action(prevState, payload); + var onStartTransitionFinish = ReactSharedInternals.S; + + if (onStartTransitionFinish !== null) { + onStartTransitionFinish(currentTransition, returnValue); + } if (returnValue !== null && typeof returnValue === 'object' && // $FlowFixMe[method-unbinding] typeof returnValue.then === 'function') { - var thenable = returnValue; - notifyTransitionCallbacks(currentTransition, thenable); // Attach a listener to read the return state of the action. As soon as + var thenable = returnValue; // Attach a listener to read the return state of the action. As soon as // this resolves, we can run the next action in the sequence. thenable.then(function (nextState) { @@ -12036,9 +12038,7 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op var previousPriority = getCurrentUpdatePriority(); setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority)); var prevTransition = ReactSharedInternals.T; - var currentTransition = { - _callbacks: new Set() - }; + var currentTransition = {}; { // We don't really need to use an optimistic update here, because we @@ -12057,7 +12057,12 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op try { if (enableAsyncActions) { - var returnValue = callback(); // Check if we're inside an async action scope. If so, we'll entangle + var returnValue = callback(); + var onStartTransitionFinish = ReactSharedInternals.S; + + if (onStartTransitionFinish !== null) { + onStartTransitionFinish(currentTransition, returnValue); + } // Check if we're inside an async action scope. If so, we'll entangle // this new action with the existing scope. // // If we're not already inside an async action scope, and this action is @@ -12066,9 +12071,9 @@ function startTransition(fiber, queue, pendingState, finishedState, callback, op // In the async case, the resulting render will suspend until the async // action scope has finished. + if (returnValue !== null && typeof returnValue === 'object' && typeof returnValue.then === 'function') { - var thenable = returnValue; - notifyTransitionCallbacks(currentTransition, thenable); // Create a thenable that resolves to `finishedState` once the async + var thenable = returnValue; // Create a thenable that resolves to `finishedState` once the async // action has completed. var thenableForFinishedState = chainThenableValue(thenable, finishedState); @@ -18130,30 +18135,42 @@ function popCacheProvider(workInProgress, cache) { popProvider(CacheContext, workInProgress); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - - if (transition !== null) { - // Whenever a transition update is scheduled, register a callback on the - // transition object so we can get the return value of the scope function. - transition._callbacks.add(handleAsyncAction); +// the shared internals object. This is used by the isomorphic implementation of +// startTransition to compose all the startTransitions together. +// +// function startTransition(fn) { +// return startTransitionDOM(() => { +// return startTransitionART(() => { +// return startTransitionThreeFiber(() => { +// // and so on... +// return fn(); +// }); +// }); +// }); +// } +// +// Currently we only compose together the code that runs at the end of each +// startTransition, because for now that's sufficient — the part that sets +// isTransition=true on the stack uses a separate shared internal field. But +// really we should delete the shared field and track isTransition per +// reconciler. Leaving this for a future PR. + +var prevOnStartTransitionFinish = ReactSharedInternals.S; + +ReactSharedInternals.S = function onStartTransitionFinishForReconciler(transition, returnValue) { + if (typeof returnValue === 'object' && returnValue !== null && typeof returnValue.then === 'function') { + // This is an async action + var thenable = returnValue; + entangleAsyncAction(transition, thenable); } - return transition; -} - -function handleAsyncAction(transition, thenable) { - { - // This is an async action. - entangleAsyncAction(transition, thenable); + if (prevOnStartTransitionFinish !== null) { + prevOnStartTransitionFinish(transition, returnValue); } -} +}; -function notifyTransitionCallbacks(transition, returnValue) { - var callbacks = transition._callbacks; - callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); +function requestCurrentTransition() { + return ReactSharedInternals.T; } // When retrying a Suspense/Offscreen boundary, we restore the cache that was // used during the previous render by placing it here, on the stack. @@ -26535,7 +26552,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-1912d791'; +var ReactVersion = '19.0.0-rc-6976a022'; /* * The `'' + value` pattern (used in perf-sensitive code) throws for Symbol diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js index 626a330989f8c..0563091682cb3 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-prod.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<41508078d6db5680720082552b30dcb7>> + * @generated SignedSource<> */ "use strict"; @@ -4183,16 +4183,18 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var action = actionQueue.action, prevState = actionQueue.state, prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; setPendingState(!0); try { - var returnValue = action(prevState, payload); + var returnValue = action(prevState, payload), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then - ? (notifyTransitionCallbacks(currentTransition, returnValue), - returnValue.then( + ? (returnValue.then( function (nextState) { actionQueue.state = nextState; finishRunningActionStateAction( @@ -4457,17 +4459,19 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; var prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; dispatchOptimisticSetState(fiber, !1, queue, pendingState); try { - var returnValue = callback(); + var returnValue = callback(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); if ( null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then ) { - notifyTransitionCallbacks(currentTransition, returnValue); var thenableForFinishedState = chainThenableValue( returnValue, finishedState @@ -4568,7 +4572,6 @@ function dispatchSetState(fiber, queue, action) { } } function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - requestCurrentTransition(); action = { lane: 2, revertLane: requestTransitionLane(), @@ -7032,19 +7035,15 @@ function releaseCache(cache) { cache.controller.abort(); }); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - null !== transition && transition._callbacks.add(handleAsyncAction); - return transition; -} -function handleAsyncAction(transition, thenable) { - entangleAsyncAction(transition, thenable); -} -function notifyTransitionCallbacks(transition, returnValue) { - transition._callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); -} +var prevOnStartTransitionFinish = ReactSharedInternals.S; +ReactSharedInternals.S = function (transition, returnValue) { + "object" === typeof returnValue && + null !== returnValue && + "function" === typeof returnValue.then && + entangleAsyncAction(transition, returnValue); + null !== prevOnStartTransitionFinish && + prevOnStartTransitionFinish(transition, returnValue); +}; var resumedCache = createCursor(null); function peekCacheFromPool() { var cacheResumedFromPreviousRender = resumedCache.current; @@ -9141,7 +9140,7 @@ function requestUpdateLane(fiber) { if (0 === (fiber.mode & 1)) return 2; if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - if (null !== requestCurrentTransition()) + if (null !== ReactSharedInternals.T) return ( (fiber = currentEntangledLane), 0 !== fiber ? fiber : requestTransitionLane() @@ -10748,7 +10747,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1187 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-55846263", + version: "19.0.0-rc-9b393d26", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -10791,7 +10790,7 @@ var internals$jscomp$inline_1434 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-55846263" + reconcilerVersion: "19.0.0-rc-9b393d26" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_1435 = __REACT_DEVTOOLS_GLOBAL_HOOK__; diff --git a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js index e5a3e2950a756..9f93cdd0d55b2 100644 --- a/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js +++ b/compiled-rn/facebook-fbsource/xplat/js/react-native-github/Libraries/Renderer/implementations/ReactNativeRenderer-profiling.fb.js @@ -7,7 +7,7 @@ * @noflow * @nolint * @preventMunge - * @generated SignedSource<<7e640d0d6e354cc8d9a44fa800df401c>> + * @generated SignedSource<> */ "use strict"; @@ -4305,16 +4305,18 @@ function runActionStateAction(actionQueue, setPendingState, setState, payload) { var action = actionQueue.action, prevState = actionQueue.state, prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; setPendingState(!0); try { - var returnValue = action(prevState, payload); + var returnValue = action(prevState, payload), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then - ? (notifyTransitionCallbacks(currentTransition, returnValue), - returnValue.then( + ? (returnValue.then( function (nextState) { actionQueue.state = nextState; finishRunningActionStateAction( @@ -4579,17 +4581,19 @@ function startTransition(fiber, queue, pendingState, finishedState, callback) { currentUpdatePriority = 0 !== previousPriority && 8 > previousPriority ? previousPriority : 8; var prevTransition = ReactSharedInternals.T, - currentTransition = { _callbacks: new Set() }; + currentTransition = {}; ReactSharedInternals.T = currentTransition; dispatchOptimisticSetState(fiber, !1, queue, pendingState); try { - var returnValue = callback(); + var returnValue = callback(), + onStartTransitionFinish = ReactSharedInternals.S; + null !== onStartTransitionFinish && + onStartTransitionFinish(currentTransition, returnValue); if ( null !== returnValue && "object" === typeof returnValue && "function" === typeof returnValue.then ) { - notifyTransitionCallbacks(currentTransition, returnValue); var thenableForFinishedState = chainThenableValue( returnValue, finishedState @@ -4692,7 +4696,6 @@ function dispatchSetState(fiber, queue, action) { markStateUpdateScheduled(fiber, lane); } function dispatchOptimisticSetState(fiber, throwIfDuringRender, queue, action) { - requestCurrentTransition(); action = { lane: 2, revertLane: requestTransitionLane(), @@ -7262,19 +7265,15 @@ function releaseCache(cache) { cache.controller.abort(); }); } -function requestCurrentTransition() { - var transition = ReactSharedInternals.T; - null !== transition && transition._callbacks.add(handleAsyncAction); - return transition; -} -function handleAsyncAction(transition, thenable) { - entangleAsyncAction(transition, thenable); -} -function notifyTransitionCallbacks(transition, returnValue) { - transition._callbacks.forEach(function (callback) { - return callback(transition, returnValue); - }); -} +var prevOnStartTransitionFinish = ReactSharedInternals.S; +ReactSharedInternals.S = function (transition, returnValue) { + "object" === typeof returnValue && + null !== returnValue && + "function" === typeof returnValue.then && + entangleAsyncAction(transition, returnValue); + null !== prevOnStartTransitionFinish && + prevOnStartTransitionFinish(transition, returnValue); +}; var resumedCache = createCursor(null); function peekCacheFromPool() { var cacheResumedFromPreviousRender = resumedCache.current; @@ -9670,7 +9669,7 @@ function requestUpdateLane(fiber) { if (0 === (fiber.mode & 1)) return 2; if (0 !== (executionContext & 2) && 0 !== workInProgressRootRenderLanes) return workInProgressRootRenderLanes & -workInProgressRootRenderLanes; - if (null !== requestCurrentTransition()) + if (null !== ReactSharedInternals.T) return ( (fiber = currentEntangledLane), 0 !== fiber ? fiber : requestTransitionLane() @@ -11454,7 +11453,7 @@ var roots = new Map(), devToolsConfig$jscomp$inline_1267 = { findFiberByHostInstance: getInstanceFromTag, bundleType: 0, - version: "19.0.0-rc-ab6e6d8f", + version: "19.0.0-rc-49a80322", rendererPackageName: "react-native-renderer", rendererConfig: { getInspectorDataForInstance: getInspectorDataForInstance, @@ -11510,7 +11509,7 @@ var roots = new Map(), scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-ab6e6d8f" + reconcilerVersion: "19.0.0-rc-49a80322" }); exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { computeComponentStackForErrorReporting: function (reactTag) {