diff --git a/package.json b/package.json index 6ce8823941c293..d29ed06ee9ceab 100644 --- a/package.json +++ b/package.json @@ -197,18 +197,18 @@ "pretty-bytes": "5.3.0", "pretty-ms": "7.0.0", "random-seed": "0.3.0", - "react": "19.0.0-rc-6230622a1a-20240610", + "react": "19.0.0-rc-20b6f4c0e8-20240607", "react-17": "npm:react@17.0.2", - "react-builtin": "npm:react@19.0.0-rc-6230622a1a-20240610", - "react-dom": "19.0.0-rc-6230622a1a-20240610", + "react-builtin": "npm:react@19.0.0-rc-20b6f4c0e8-20240607", + "react-dom": "19.0.0-rc-20b6f4c0e8-20240607", "react-dom-17": "npm:react-dom@17.0.2", - "react-dom-builtin": "npm:react-dom@19.0.0-rc-6230622a1a-20240610", - "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-6230622a1a-20240610", - "react-experimental-builtin": "npm:react@0.0.0-experimental-6230622a1a-20240610", - "react-server-dom-turbopack": "19.0.0-rc-6230622a1a-20240610", - "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-6230622a1a-20240610", - "react-server-dom-webpack": "19.0.0-rc-6230622a1a-20240610", - "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-6230622a1a-20240610", + "react-dom-builtin": "npm:react-dom@19.0.0-rc-20b6f4c0e8-20240607", + "react-dom-experimental-builtin": "npm:react-dom@0.0.0-experimental-20b6f4c0e8-20240607", + "react-experimental-builtin": "npm:react@0.0.0-experimental-20b6f4c0e8-20240607", + "react-server-dom-turbopack": "19.0.0-rc-20b6f4c0e8-20240607", + "react-server-dom-turbopack-experimental": "npm:react-server-dom-turbopack@0.0.0-experimental-20b6f4c0e8-20240607", + "react-server-dom-webpack": "19.0.0-rc-20b6f4c0e8-20240607", + "react-server-dom-webpack-experimental": "npm:react-server-dom-webpack@0.0.0-experimental-20b6f4c0e8-20240607", "react-ssr-prepass": "1.0.8", "react-virtualized": "9.22.3", "relay-compiler": "13.0.2", @@ -218,8 +218,8 @@ "resolve-from": "5.0.0", "sass": "1.54.0", "satori": "0.10.9", - "scheduler-builtin": "npm:scheduler@0.25.0-rc-6230622a1a-20240610", - "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-6230622a1a-20240610", + "scheduler-builtin": "npm:scheduler@0.25.0-rc-20b6f4c0e8-20240607", + "scheduler-experimental-builtin": "npm:scheduler@0.0.0-experimental-20b6f4c0e8-20240607", "seedrandom": "3.0.5", "semver": "7.3.7", "shell-quote": "1.7.3", @@ -253,10 +253,10 @@ "@babel/traverse": "7.22.5", "@types/react": "npm:types-react@19.0.0-rc.0", "@types/react-dom": "npm:types-react-dom@19.0.0-rc.0", - "react": "19.0.0-rc-6230622a1a-20240610", - "react-dom": "19.0.0-rc-6230622a1a-20240610", - "react-is": "19.0.0-rc-6230622a1a-20240610", - "scheduler": "0.25.0-rc-6230622a1a-20240610" + "react": "19.0.0-rc-20b6f4c0e8-20240607", + "react-dom": "19.0.0-rc-20b6f4c0e8-20240607", + "react-is": "19.0.0-rc-20b6f4c0e8-20240607", + "scheduler": "0.25.0-rc-20b6f4c0e8-20240607" }, "engines": { "node": ">=18.17.0", diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js index b1262973216c8c..75c6b45cbe59e1 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.development.js @@ -11535,7 +11535,7 @@ var ownerHasKeyUseWarning; var ownerHasFunctionTypeWarning; var ownerHasSymbolTypeWarning; -var warnForMissingKey = function (child, returnFiber) {}; +var warnForMissingKey = function (returnFiber, workInProgress, child) {}; { didWarnAboutMaps = false; @@ -11550,7 +11550,7 @@ var warnForMissingKey = function (child, returnFiber) {}; ownerHasFunctionTypeWarning = {}; ownerHasSymbolTypeWarning = {}; - warnForMissingKey = function (child, returnFiber) { + warnForMissingKey = function (returnFiber, workInProgress, child) { if (child === null || typeof child !== 'object') { return; } @@ -11609,15 +11609,9 @@ var warnForMissingKey = function (child, returnFiber) {}; // Give the component that originally created this child. childOwnerAppendix = " It was passed a child from " + ownerName + "."; } - } // We create a fake Fiber for the child to log the stack trace from. - // TODO: Refactor the warnForMissingKey calls to happen after fiber creation - // so that we can get access to the fiber that will eventually be created. - // That way the log can show up associated with the right instance in DevTools. - + } - var fiber = createFiberFromElement(child, returnFiber.mode, 0); - fiber.return = returnFiber; - runWithFiberInDEV(fiber, function () { + runWithFiberInDEV(workInProgress, function () { error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); }); }; @@ -12214,7 +12208,7 @@ function createChildReconciler(shouldTrackSideEffects) { */ - function warnOnInvalidKey(child, knownKeys, returnFiber) { + function warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys) { { if (typeof child !== 'object' || child === null) { return knownKeys; @@ -12223,7 +12217,7 @@ function createChildReconciler(shouldTrackSideEffects) { switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: - warnForMissingKey(child, returnFiber); + warnForMissingKey(returnFiber, workInProgress, child); var key = child.key; if (typeof key !== 'string') { @@ -12241,8 +12235,9 @@ function createChildReconciler(shouldTrackSideEffects) { break; } - error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); - + runWithFiberInDEV(workInProgress, function () { + error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); + }); break; case REACT_LAZY_TYPE: @@ -12253,7 +12248,7 @@ function createChildReconciler(shouldTrackSideEffects) { resolvedChild = callLazyInitInDEV(child); } - warnOnInvalidKey(resolvedChild, knownKeys, returnFiber); + warnOnInvalidKey(returnFiber, workInProgress, resolvedChild, knownKeys); break; } } @@ -12278,16 +12273,7 @@ function createChildReconciler(shouldTrackSideEffects) { // (adding everything to a Map) in for every insert/move. // If you change this code, also update reconcileChildrenIterator() which // uses the same algorithm. - { - // First, validate keys. - var knownKeys = null; - - for (var i = 0; i < newChildren.length; i++) { - var child = newChildren[i]; - knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); - } - } - + var knownKeys = null; var resultingFirstChild = null; var previousNewFiber = null; var oldFiber = currentFirstChild; @@ -12317,6 +12303,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12364,6 +12354,10 @@ function createChildReconciler(shouldTrackSideEffects) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber, newChildren[newIdx], knownKeys); + } + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12391,6 +12385,10 @@ function createChildReconciler(shouldTrackSideEffects) { var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes, debugInfo); if (_newFiber2 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber2, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -12522,11 +12520,7 @@ function createChildReconciler(shouldTrackSideEffects) { var knownKeys = null; var step = newChildren.next(); - { - knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber); - } - - for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; oldFiber = null; @@ -12548,6 +12542,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12588,13 +12586,17 @@ function createChildReconciler(shouldTrackSideEffects) { if (oldFiber === null) { // If we don't have any more existing children we can choose a fast path // since the rest will all be insertions. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber3 = createChild(returnFiber, step.value, lanes, debugInfo); if (_newFiber3 === null) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber3, step.value, knownKeys); + } + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12618,10 +12620,14 @@ function createChildReconciler(shouldTrackSideEffects) { var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes, debugInfo); if (_newFiber4 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber4, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -36898,7 +36904,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; // Might add PROFILE later. diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js index 2543bedce93852..30b6d387893179 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-client.production.js @@ -3115,7 +3115,7 @@ function createChildReconciler(shouldTrackSideEffects) { nextOldFiber = null, step = newChildren.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3143,7 +3143,7 @@ function createChildReconciler(shouldTrackSideEffects) { resultingFirstChild ); if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next(), null) + for (; !step.done; newIdx++, step = newChildren.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), @@ -3157,7 +3157,7 @@ function createChildReconciler(shouldTrackSideEffects) { for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -14789,14 +14789,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1631 = React.version; if ( - "19.0.0-experimental-6230622a1a-20240610" !== + "19.0.0-experimental-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_1631 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1631, - "19.0.0-experimental-6230622a1a-20240610" + "19.0.0-experimental-20b6f4c0e8-20240607" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -14815,7 +14815,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1638 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-experimental-6230622a1a-20240610", + version: "19.0.0-experimental-20b6f4c0e8-20240607", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2016 = { @@ -14845,7 +14845,7 @@ var internals$jscomp$inline_2016 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-experimental-6230622a1a-20240610" + reconcilerVersion: "19.0.0-experimental-20b6f4c0e8-20240607" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2017 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -14951,4 +14951,4 @@ exports.hydrateRoot = function (container, initialChildren, options) { listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js index 574227c795ee7a..71edbf81815fc9 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.development.js @@ -11583,7 +11583,7 @@ var ownerHasKeyUseWarning; var ownerHasFunctionTypeWarning; var ownerHasSymbolTypeWarning; -var warnForMissingKey = function (child, returnFiber) {}; +var warnForMissingKey = function (returnFiber, workInProgress, child) {}; { didWarnAboutMaps = false; @@ -11598,7 +11598,7 @@ var warnForMissingKey = function (child, returnFiber) {}; ownerHasFunctionTypeWarning = {}; ownerHasSymbolTypeWarning = {}; - warnForMissingKey = function (child, returnFiber) { + warnForMissingKey = function (returnFiber, workInProgress, child) { if (child === null || typeof child !== 'object') { return; } @@ -11657,15 +11657,9 @@ var warnForMissingKey = function (child, returnFiber) {}; // Give the component that originally created this child. childOwnerAppendix = " It was passed a child from " + ownerName + "."; } - } // We create a fake Fiber for the child to log the stack trace from. - // TODO: Refactor the warnForMissingKey calls to happen after fiber creation - // so that we can get access to the fiber that will eventually be created. - // That way the log can show up associated with the right instance in DevTools. - + } - var fiber = createFiberFromElement(child, returnFiber.mode, 0); - fiber.return = returnFiber; - runWithFiberInDEV(fiber, function () { + runWithFiberInDEV(workInProgress, function () { error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); }); }; @@ -12262,7 +12256,7 @@ function createChildReconciler(shouldTrackSideEffects) { */ - function warnOnInvalidKey(child, knownKeys, returnFiber) { + function warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys) { { if (typeof child !== 'object' || child === null) { return knownKeys; @@ -12271,7 +12265,7 @@ function createChildReconciler(shouldTrackSideEffects) { switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: - warnForMissingKey(child, returnFiber); + warnForMissingKey(returnFiber, workInProgress, child); var key = child.key; if (typeof key !== 'string') { @@ -12289,8 +12283,9 @@ function createChildReconciler(shouldTrackSideEffects) { break; } - error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); - + runWithFiberInDEV(workInProgress, function () { + error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); + }); break; case REACT_LAZY_TYPE: @@ -12301,7 +12296,7 @@ function createChildReconciler(shouldTrackSideEffects) { resolvedChild = callLazyInitInDEV(child); } - warnOnInvalidKey(resolvedChild, knownKeys, returnFiber); + warnOnInvalidKey(returnFiber, workInProgress, resolvedChild, knownKeys); break; } } @@ -12326,16 +12321,7 @@ function createChildReconciler(shouldTrackSideEffects) { // (adding everything to a Map) in for every insert/move. // If you change this code, also update reconcileChildrenIterator() which // uses the same algorithm. - { - // First, validate keys. - var knownKeys = null; - - for (var i = 0; i < newChildren.length; i++) { - var child = newChildren[i]; - knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); - } - } - + var knownKeys = null; var resultingFirstChild = null; var previousNewFiber = null; var oldFiber = currentFirstChild; @@ -12365,6 +12351,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12412,6 +12402,10 @@ function createChildReconciler(shouldTrackSideEffects) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber, newChildren[newIdx], knownKeys); + } + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12439,6 +12433,10 @@ function createChildReconciler(shouldTrackSideEffects) { var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes, debugInfo); if (_newFiber2 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber2, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -12570,11 +12568,7 @@ function createChildReconciler(shouldTrackSideEffects) { var knownKeys = null; var step = newChildren.next(); - { - knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber); - } - - for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; oldFiber = null; @@ -12596,6 +12590,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12636,13 +12634,17 @@ function createChildReconciler(shouldTrackSideEffects) { if (oldFiber === null) { // If we don't have any more existing children we can choose a fast path // since the rest will all be insertions. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber3 = createChild(returnFiber, step.value, lanes, debugInfo); if (_newFiber3 === null) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber3, step.value, knownKeys); + } + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12666,10 +12668,14 @@ function createChildReconciler(shouldTrackSideEffects) { var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes, debugInfo); if (_newFiber4 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber4, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -36946,7 +36952,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation. implementation) { diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js index 869e063e755138..4c5f0bda802090 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-profiling.profiling.js @@ -3237,7 +3237,7 @@ function createChildReconciler(shouldTrackSideEffects) { nextOldFiber = null, step = newChildren.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3265,7 +3265,7 @@ function createChildReconciler(shouldTrackSideEffects) { resultingFirstChild ); if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next(), null) + for (; !step.done; newIdx++, step = newChildren.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), @@ -3279,7 +3279,7 @@ function createChildReconciler(shouldTrackSideEffects) { for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -15499,14 +15499,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1719 = React.version; if ( - "19.0.0-experimental-6230622a1a-20240610" !== + "19.0.0-experimental-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_1719 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1719, - "19.0.0-experimental-6230622a1a-20240610" + "19.0.0-experimental-20b6f4c0e8-20240607" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15525,7 +15525,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1726 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-experimental-6230622a1a-20240610", + version: "19.0.0-experimental-20b6f4c0e8-20240607", rendererPackageName: "react-dom" }; (function (internals) { @@ -15568,7 +15568,7 @@ var devToolsConfig$jscomp$inline_1726 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-experimental-6230622a1a-20240610" + reconcilerVersion: "19.0.0-experimental-20b6f4c0e8-20240607" }); function noop() {} function getCrossOriginStringAs(as, input) { @@ -15822,7 +15822,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js index 50f3351789139a..01d60d5f3a7f1b 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js index 23065ec2d9ee9b..2be70ae4164661 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.browser.production.js @@ -5863,4 +5863,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js index 1b311e7bace6d3..0b466de590080e 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js index 080b75226badb7..6450cc16029471 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server-legacy.node.production.js @@ -5959,4 +5959,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js index 47ac3fa761a15b..266b033e174702 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-experimental-6230622a1a-20240610'; +var reactDOMPackageVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -503,8 +503,20 @@ function murmurhash3_32_gc(key, seed) { return h1 >>> 0; } +var channel = new MessageChannel(); +var taskQueue = []; + +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + + if (task) { + task(); + } +}; + function scheduleWork(callback) { - callback(); + taskQueue.push(callback); + channel.port2.postMessage(null); } var VIEW_SIZE = 2048; var currentView = null; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js index 725e15419d634c..39d572e1a6f6f7 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.browser.production.js @@ -125,6 +125,16 @@ function murmurhash3_32_gc(key, seed) { 4294967295; return (h1 ^ (h1 >>> 16)) >>> 0; } +var channel = new MessageChannel(), + taskQueue = []; +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + task && task(); +}; +function scheduleWork(callback) { + taskQueue.push(callback); + channel.port2.postMessage(null); +} var currentView = null, writtenBytes = 0; function writeChunk(destination, chunk) { @@ -4035,7 +4045,9 @@ function pingTask(request, task) { request.pingedTasks.push(task); 1 === request.pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + scheduleWork(function () { + return performWork(request); + })); } function createSuspenseBoundary(request, fallbackAbortableTasks) { return { @@ -6246,22 +6258,25 @@ function flushCompletedQueues(request, destination) { } function startWork(request) { request.flushScheduled = null !== request.destination; - performWork(request); + scheduleWork(function () { + return performWork(request); + }); null === request.trackedPostpones && - safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + scheduleWork(function () { + safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - request.flushScheduled = !0; - var destination = request.destination; - destination - ? flushCompletedQueues(request, destination) - : (request.flushScheduled = !1); - } + null !== request.destination && + ((request.flushScheduled = !0), + scheduleWork(function () { + var destination = request.destination; + destination + ? flushCompletedQueues(request, destination) + : (request.flushScheduled = !1); + })); } function startFlowing(request, destination) { if (1 === request.status) @@ -6345,12 +6360,12 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion, - "19.0.0-experimental-6230622a1a-20240610" + "19.0.0-experimental-20b6f4c0e8-20240607" ) ); } @@ -6555,4 +6570,4 @@ exports.resume = function (children, postponedState, options) { startWork(request); }); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js index 84cc171c78b82a..361f946fef0b57 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.bun.production.js @@ -3569,7 +3569,9 @@ function pingTask(request, task) { request.pingedTasks.push(task); 1 === request.pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + setTimeout(function () { + return performWork(request); + }, 0)); } function createSuspenseBoundary(request, fallbackAbortableTasks) { return { @@ -5818,18 +5820,27 @@ function flushCompletedQueues(request, destination) { : flushBuffered(destination); } } +function startWork(request) { + request.flushScheduled = null !== request.destination; + setTimeout(function () { + return performWork(request); + }, 0); + null === request.trackedPostpones && + setTimeout(function () { + safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + }, 0); +} function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - request.flushScheduled = !0; - var destination = request.destination; - destination - ? flushCompletedQueues(request, destination) - : (request.flushScheduled = !1); - } + null !== request.destination && + ((request.flushScheduled = !0), + setTimeout(function () { + var destination = request.destination; + destination + ? flushCompletedQueues(request, destination) + : (request.flushScheduled = !1); + }, 0)); } function abort(request, reason) { try { @@ -5864,13 +5875,13 @@ function addToReplayParent(node, parentKeyPath, trackedPostpones) { } var isomorphicReactPackageVersion$jscomp$inline_800 = React.version; if ( - "19.0.0-experimental-6230622a1a-20240610" !== + "19.0.0-experimental-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_800 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_800 + - "\n - react-dom: 19.0.0-experimental-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-20b6f4c0e8-20240607\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -5955,10 +5966,7 @@ exports.renderToReadableStream = function (children, options) { signal.addEventListener("abort", listener); } } - request.flushScheduled = null !== request.destination; - performWork(request); - null === request.trackedPostpones && - safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + startWork(request); }); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js index 0cb90ebfd3c7b4..8f8886e02a45ad 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-experimental-6230622a1a-20240610'; +var reactDOMPackageVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js index 3b96678ec3d29c..c56d60e3f1e7b7 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.edge.production.js @@ -6468,11 +6468,11 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-20b6f4c0e8-20240607\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6676,4 +6676,4 @@ exports.resume = function (children, postponedState, options) { startWork(request); }); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js index 18c0609458ce48..89b64a86971daa 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.development.js @@ -21,7 +21,7 @@ var async_hooks = require('async_hooks'); var ReactDOM = require('react-dom'); var stream = require('stream'); -var reactDOMPackageVersion = '19.0.0-experimental-6230622a1a-20240610'; +var reactDOMPackageVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js index 4d1d54adaed253..17a6c08331c4f1 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-server.node.production.js @@ -6263,11 +6263,11 @@ function getPostponedState(request) { } function ensureCorrectIsomorphicReactVersion() { var isomorphicReactPackageVersion = React.version; - if ("19.0.0-experimental-6230622a1a-20240610" !== isomorphicReactPackageVersion) + if ("19.0.0-experimental-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion + - "\n - react-dom: 19.0.0-experimental-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-experimental-20b6f4c0e8-20240607\nLearn more: https://react.dev/warnings/version-mismatch") ); } ensureCorrectIsomorphicReactVersion(); @@ -6548,4 +6548,4 @@ exports.resumeToPipeableStream = function (children, postponedState, options) { } }; }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js index 0613fd5ed9ec5c..75a76766a21be6 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.development.js @@ -11676,7 +11676,7 @@ var ownerHasKeyUseWarning; var ownerHasFunctionTypeWarning; var ownerHasSymbolTypeWarning; -var warnForMissingKey = function (child, returnFiber) {}; +var warnForMissingKey = function (returnFiber, workInProgress, child) {}; { didWarnAboutMaps = false; @@ -11691,7 +11691,7 @@ var warnForMissingKey = function (child, returnFiber) {}; ownerHasFunctionTypeWarning = {}; ownerHasSymbolTypeWarning = {}; - warnForMissingKey = function (child, returnFiber) { + warnForMissingKey = function (returnFiber, workInProgress, child) { if (child === null || typeof child !== 'object') { return; } @@ -11750,15 +11750,9 @@ var warnForMissingKey = function (child, returnFiber) {}; // Give the component that originally created this child. childOwnerAppendix = " It was passed a child from " + ownerName + "."; } - } // We create a fake Fiber for the child to log the stack trace from. - // TODO: Refactor the warnForMissingKey calls to happen after fiber creation - // so that we can get access to the fiber that will eventually be created. - // That way the log can show up associated with the right instance in DevTools. - + } - var fiber = createFiberFromElement(child, returnFiber.mode, 0); - fiber.return = returnFiber; - runWithFiberInDEV(fiber, function () { + runWithFiberInDEV(workInProgress, function () { error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); }); }; @@ -12355,7 +12349,7 @@ function createChildReconciler(shouldTrackSideEffects) { */ - function warnOnInvalidKey(child, knownKeys, returnFiber) { + function warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys) { { if (typeof child !== 'object' || child === null) { return knownKeys; @@ -12364,7 +12358,7 @@ function createChildReconciler(shouldTrackSideEffects) { switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: - warnForMissingKey(child, returnFiber); + warnForMissingKey(returnFiber, workInProgress, child); var key = child.key; if (typeof key !== 'string') { @@ -12382,8 +12376,9 @@ function createChildReconciler(shouldTrackSideEffects) { break; } - error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); - + runWithFiberInDEV(workInProgress, function () { + error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); + }); break; case REACT_LAZY_TYPE: @@ -12394,7 +12389,7 @@ function createChildReconciler(shouldTrackSideEffects) { resolvedChild = callLazyInitInDEV(child); } - warnOnInvalidKey(resolvedChild, knownKeys, returnFiber); + warnOnInvalidKey(returnFiber, workInProgress, resolvedChild, knownKeys); break; } } @@ -12419,16 +12414,7 @@ function createChildReconciler(shouldTrackSideEffects) { // (adding everything to a Map) in for every insert/move. // If you change this code, also update reconcileChildrenIterator() which // uses the same algorithm. - { - // First, validate keys. - var knownKeys = null; - - for (var i = 0; i < newChildren.length; i++) { - var child = newChildren[i]; - knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); - } - } - + var knownKeys = null; var resultingFirstChild = null; var previousNewFiber = null; var oldFiber = currentFirstChild; @@ -12458,6 +12444,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12505,6 +12495,10 @@ function createChildReconciler(shouldTrackSideEffects) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber, newChildren[newIdx], knownKeys); + } + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12532,6 +12526,10 @@ function createChildReconciler(shouldTrackSideEffects) { var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes, debugInfo); if (_newFiber2 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber2, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -12663,11 +12661,7 @@ function createChildReconciler(shouldTrackSideEffects) { var knownKeys = null; var step = newChildren.next(); - { - knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber); - } - - for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; oldFiber = null; @@ -12689,6 +12683,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12729,13 +12727,17 @@ function createChildReconciler(shouldTrackSideEffects) { if (oldFiber === null) { // If we don't have any more existing children we can choose a fast path // since the rest will all be insertions. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber3 = createChild(returnFiber, step.value, lanes, debugInfo); if (_newFiber3 === null) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber3, step.value, knownKeys); + } + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12759,10 +12761,14 @@ function createChildReconciler(shouldTrackSideEffects) { var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes, debugInfo); if (_newFiber4 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber4, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -37599,7 +37605,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; // Might add PROFILE later. diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js index 9d61431c8aea1e..0cb30174793223 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom-unstable_testing.production.js @@ -3251,7 +3251,7 @@ function createChildReconciler(shouldTrackSideEffects) { nextOldFiber = null, step = newChildren.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3279,7 +3279,7 @@ function createChildReconciler(shouldTrackSideEffects) { resultingFirstChild ); if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next(), null) + for (; !step.done; newIdx++, step = newChildren.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), @@ -3293,7 +3293,7 @@ function createChildReconciler(shouldTrackSideEffects) { for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -15168,14 +15168,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1660 = React.version; if ( - "19.0.0-experimental-6230622a1a-20240610" !== + "19.0.0-experimental-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_1660 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1660, - "19.0.0-experimental-6230622a1a-20240610" + "19.0.0-experimental-20b6f4c0e8-20240607" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15194,7 +15194,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1667 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-experimental-6230622a1a-20240610", + version: "19.0.0-experimental-20b6f4c0e8-20240607", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2050 = { @@ -15224,7 +15224,7 @@ var internals$jscomp$inline_2050 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-experimental-6230622a1a-20240610" + reconcilerVersion: "19.0.0-experimental-20b6f4c0e8-20240607" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2051 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -15481,4 +15481,4 @@ exports.observeVisibleRects = function ( } }; }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js index 197c5b33a7c0c1..b51a50aca1bf29 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.development.js @@ -144,7 +144,7 @@ var Internals = { findDOMNode: null }; -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; /** * HTML nodeType values that represent the type of the node diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js index 9e324072ab49c9..023aacc6fb9349 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.production.js @@ -206,4 +206,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js index 1a32afc1da3c1e..bd9adb86e5ee65 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.development.js @@ -16,7 +16,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react-experimental"); -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var ReactSharedInternalsServer = // $FlowFixMe: It's defined in the one we resolve to. React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js index 456b1c2aa94629..fdcbcd604a1bbf 100644 --- a/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js +++ b/packages/next/src/compiled/react-dom-experimental/cjs/react-dom.react-server.production.js @@ -151,4 +151,4 @@ exports.preloadModule = function (href, options) { }); } else Internals.d.m(href); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom-experimental/package.json b/packages/next/src/compiled/react-dom-experimental/package.json index 0cc406b2d32b9d..97256abe270e89 100644 --- a/packages/next/src/compiled/react-dom-experimental/package.json +++ b/packages/next/src/compiled/react-dom-experimental/package.json @@ -72,10 +72,10 @@ "./package.json": "./package.json" }, "dependencies": { - "scheduler": "0.0.0-experimental-6230622a1a-20240610" + "scheduler": "0.0.0-experimental-20b6f4c0e8-20240607" }, "peerDependencies": { - "react": "0.0.0-experimental-6230622a1a-20240610" + "react": "0.0.0-experimental-20b6f4c0e8-20240607" }, "browser": { "./server.js": "./server.browser.js", diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js index 4cc92bdf21d53b..dde27a3aeaf1fb 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-client.development.js @@ -11289,7 +11289,7 @@ var ownerHasKeyUseWarning; var ownerHasFunctionTypeWarning; var ownerHasSymbolTypeWarning; -var warnForMissingKey = function (child, returnFiber) {}; +var warnForMissingKey = function (returnFiber, workInProgress, child) {}; { didWarnAboutMaps = false; @@ -11304,7 +11304,7 @@ var warnForMissingKey = function (child, returnFiber) {}; ownerHasFunctionTypeWarning = {}; ownerHasSymbolTypeWarning = {}; - warnForMissingKey = function (child, returnFiber) { + warnForMissingKey = function (returnFiber, workInProgress, child) { if (child === null || typeof child !== 'object') { return; } @@ -11363,15 +11363,9 @@ var warnForMissingKey = function (child, returnFiber) {}; // Give the component that originally created this child. childOwnerAppendix = " It was passed a child from " + ownerName + "."; } - } // We create a fake Fiber for the child to log the stack trace from. - // TODO: Refactor the warnForMissingKey calls to happen after fiber creation - // so that we can get access to the fiber that will eventually be created. - // That way the log can show up associated with the right instance in DevTools. - + } - var fiber = createFiberFromElement(child, returnFiber.mode, 0); - fiber.return = returnFiber; - runWithFiberInDEV(fiber, function () { + runWithFiberInDEV(workInProgress, function () { error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); }); }; @@ -11968,7 +11962,7 @@ function createChildReconciler(shouldTrackSideEffects) { */ - function warnOnInvalidKey(child, knownKeys, returnFiber) { + function warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys) { { if (typeof child !== 'object' || child === null) { return knownKeys; @@ -11977,7 +11971,7 @@ function createChildReconciler(shouldTrackSideEffects) { switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: - warnForMissingKey(child, returnFiber); + warnForMissingKey(returnFiber, workInProgress, child); var key = child.key; if (typeof key !== 'string') { @@ -11995,8 +11989,9 @@ function createChildReconciler(shouldTrackSideEffects) { break; } - error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); - + runWithFiberInDEV(workInProgress, function () { + error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); + }); break; case REACT_LAZY_TYPE: @@ -12007,7 +12002,7 @@ function createChildReconciler(shouldTrackSideEffects) { resolvedChild = callLazyInitInDEV(child); } - warnOnInvalidKey(resolvedChild, knownKeys, returnFiber); + warnOnInvalidKey(returnFiber, workInProgress, resolvedChild, knownKeys); break; } } @@ -12032,16 +12027,7 @@ function createChildReconciler(shouldTrackSideEffects) { // (adding everything to a Map) in for every insert/move. // If you change this code, also update reconcileChildrenIterator() which // uses the same algorithm. - { - // First, validate keys. - var knownKeys = null; - - for (var i = 0; i < newChildren.length; i++) { - var child = newChildren[i]; - knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); - } - } - + var knownKeys = null; var resultingFirstChild = null; var previousNewFiber = null; var oldFiber = currentFirstChild; @@ -12071,6 +12057,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12118,6 +12108,10 @@ function createChildReconciler(shouldTrackSideEffects) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber, newChildren[newIdx], knownKeys); + } + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12145,6 +12139,10 @@ function createChildReconciler(shouldTrackSideEffects) { var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes, debugInfo); if (_newFiber2 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber2, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -12239,11 +12237,7 @@ function createChildReconciler(shouldTrackSideEffects) { var knownKeys = null; var step = newChildren.next(); - { - knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber); - } - - for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; oldFiber = null; @@ -12265,6 +12259,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12305,13 +12303,17 @@ function createChildReconciler(shouldTrackSideEffects) { if (oldFiber === null) { // If we don't have any more existing children we can choose a fast path // since the rest will all be insertions. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber3 = createChild(returnFiber, step.value, lanes, debugInfo); if (_newFiber3 === null) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber3, step.value, knownKeys); + } + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12335,10 +12337,14 @@ function createChildReconciler(shouldTrackSideEffects) { var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes, debugInfo); if (_newFiber4 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber4, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -36434,7 +36440,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; // Might add PROFILE later. diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js index 52d5e3c749149c..6fccc372705d5a 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-client.production.js @@ -3082,7 +3082,7 @@ function createChildReconciler(shouldTrackSideEffects) { nextOldFiber = null, step = newChildren.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3110,7 +3110,7 @@ function createChildReconciler(shouldTrackSideEffects) { resultingFirstChild ); if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next(), null) + for (; !step.done; newIdx++, step = newChildren.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), @@ -3124,7 +3124,7 @@ function createChildReconciler(shouldTrackSideEffects) { for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -14633,14 +14633,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1651 = React.version; if ( - "19.0.0-rc-6230622a1a-20240610" !== + "19.0.0-rc-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_1651 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1651, - "19.0.0-rc-6230622a1a-20240610" + "19.0.0-rc-20b6f4c0e8-20240607" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -14659,7 +14659,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1658 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-6230622a1a-20240610", + version: "19.0.0-rc-20b6f4c0e8-20240607", rendererPackageName: "react-dom" }; var internals$jscomp$inline_2036 = { @@ -14689,7 +14689,7 @@ var internals$jscomp$inline_2036 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-6230622a1a-20240610" + reconcilerVersion: "19.0.0-rc-20b6f4c0e8-20240607" }; if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) { var hook$jscomp$inline_2037 = __REACT_DEVTOOLS_GLOBAL_HOOK__; @@ -14795,4 +14795,4 @@ exports.hydrateRoot = function (container, initialChildren, options) { listenToAllSupportedEvents(container); return new ReactDOMHydrationRoot(initialChildren); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js index d70e6d3421157d..3cb8af5c81c839 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.development.js @@ -11337,7 +11337,7 @@ var ownerHasKeyUseWarning; var ownerHasFunctionTypeWarning; var ownerHasSymbolTypeWarning; -var warnForMissingKey = function (child, returnFiber) {}; +var warnForMissingKey = function (returnFiber, workInProgress, child) {}; { didWarnAboutMaps = false; @@ -11352,7 +11352,7 @@ var warnForMissingKey = function (child, returnFiber) {}; ownerHasFunctionTypeWarning = {}; ownerHasSymbolTypeWarning = {}; - warnForMissingKey = function (child, returnFiber) { + warnForMissingKey = function (returnFiber, workInProgress, child) { if (child === null || typeof child !== 'object') { return; } @@ -11411,15 +11411,9 @@ var warnForMissingKey = function (child, returnFiber) {}; // Give the component that originally created this child. childOwnerAppendix = " It was passed a child from " + ownerName + "."; } - } // We create a fake Fiber for the child to log the stack trace from. - // TODO: Refactor the warnForMissingKey calls to happen after fiber creation - // so that we can get access to the fiber that will eventually be created. - // That way the log can show up associated with the right instance in DevTools. - + } - var fiber = createFiberFromElement(child, returnFiber.mode, 0); - fiber.return = returnFiber; - runWithFiberInDEV(fiber, function () { + runWithFiberInDEV(workInProgress, function () { error('Each child in a list should have a unique "key" prop.' + '%s%s See https://react.dev/link/warning-keys for more information.', currentComponentErrorInfo, childOwnerAppendix); }); }; @@ -12016,7 +12010,7 @@ function createChildReconciler(shouldTrackSideEffects) { */ - function warnOnInvalidKey(child, knownKeys, returnFiber) { + function warnOnInvalidKey(returnFiber, workInProgress, child, knownKeys) { { if (typeof child !== 'object' || child === null) { return knownKeys; @@ -12025,7 +12019,7 @@ function createChildReconciler(shouldTrackSideEffects) { switch (child.$$typeof) { case REACT_ELEMENT_TYPE: case REACT_PORTAL_TYPE: - warnForMissingKey(child, returnFiber); + warnForMissingKey(returnFiber, workInProgress, child); var key = child.key; if (typeof key !== 'string') { @@ -12043,8 +12037,9 @@ function createChildReconciler(shouldTrackSideEffects) { break; } - error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); - + runWithFiberInDEV(workInProgress, function () { + error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key); + }); break; case REACT_LAZY_TYPE: @@ -12055,7 +12050,7 @@ function createChildReconciler(shouldTrackSideEffects) { resolvedChild = callLazyInitInDEV(child); } - warnOnInvalidKey(resolvedChild, knownKeys, returnFiber); + warnOnInvalidKey(returnFiber, workInProgress, resolvedChild, knownKeys); break; } } @@ -12080,16 +12075,7 @@ function createChildReconciler(shouldTrackSideEffects) { // (adding everything to a Map) in for every insert/move. // If you change this code, also update reconcileChildrenIterator() which // uses the same algorithm. - { - // First, validate keys. - var knownKeys = null; - - for (var i = 0; i < newChildren.length; i++) { - var child = newChildren[i]; - knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber); - } - } - + var knownKeys = null; var resultingFirstChild = null; var previousNewFiber = null; var oldFiber = currentFirstChild; @@ -12119,6 +12105,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12166,6 +12156,10 @@ function createChildReconciler(shouldTrackSideEffects) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber, newChildren[newIdx], knownKeys); + } + lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12193,6 +12187,10 @@ function createChildReconciler(shouldTrackSideEffects) { var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes, debugInfo); if (_newFiber2 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber2, newChildren[newIdx], knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber2.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -12287,11 +12285,7 @@ function createChildReconciler(shouldTrackSideEffects) { var knownKeys = null; var step = newChildren.next(); - { - knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber); - } - - for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) { if (oldFiber.index > newIdx) { nextOldFiber = oldFiber; oldFiber = null; @@ -12313,6 +12307,10 @@ function createChildReconciler(shouldTrackSideEffects) { break; } + { + knownKeys = warnOnInvalidKey(returnFiber, newFiber, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (oldFiber && newFiber.alternate === null) { // We matched the slot, but we didn't reuse the existing fiber, so we @@ -12353,13 +12351,17 @@ function createChildReconciler(shouldTrackSideEffects) { if (oldFiber === null) { // If we don't have any more existing children we can choose a fast path // since the rest will all be insertions. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber3 = createChild(returnFiber, step.value, lanes, debugInfo); if (_newFiber3 === null) { continue; } + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber3, step.value, knownKeys); + } + lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx); if (previousNewFiber === null) { @@ -12383,10 +12385,14 @@ function createChildReconciler(shouldTrackSideEffects) { var existingChildren = mapRemainingChildren(oldFiber); // Keep scanning and use the map to restore deleted items as moves. - for (; !step.done; newIdx++, step = newChildren.next(), knownKeys = warnOnInvalidKey(step.value, knownKeys, returnFiber) ) { + for (; !step.done; newIdx++, step = newChildren.next()) { var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes, debugInfo); if (_newFiber4 !== null) { + { + knownKeys = warnOnInvalidKey(returnFiber, _newFiber4, step.value, knownKeys); + } + if (shouldTrackSideEffects) { if (_newFiber4.alternate !== null) { // The new fiber is a work in progress, but if there exists a @@ -36482,7 +36488,7 @@ identifierPrefix, onUncaughtError, onCaughtError, onRecoverableError, transition return root; } -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation. implementation) { diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js index 494d4a867b0edc..db99961f5d56c7 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-profiling.profiling.js @@ -3204,7 +3204,7 @@ function createChildReconciler(shouldTrackSideEffects) { nextOldFiber = null, step = newChildren.next(); null !== oldFiber && !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) { oldFiber.index > newIdx ? ((nextOldFiber = oldFiber), (oldFiber = null)) @@ -3232,7 +3232,7 @@ function createChildReconciler(shouldTrackSideEffects) { resultingFirstChild ); if (null === oldFiber) { - for (; !step.done; newIdx++, step = newChildren.next(), null) + for (; !step.done; newIdx++, step = newChildren.next()) (step = createChild(returnFiber, step.value, lanes)), null !== step && ((currentFirstChild = placeChild(step, currentFirstChild, newIdx)), @@ -3246,7 +3246,7 @@ function createChildReconciler(shouldTrackSideEffects) { for ( oldFiber = mapRemainingChildren(oldFiber); !step.done; - newIdx++, step = newChildren.next(), null + newIdx++, step = newChildren.next() ) (step = updateFromMap(oldFiber, returnFiber, newIdx, step.value, lanes)), null !== step && @@ -15343,14 +15343,14 @@ ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = function (target) { }; var isomorphicReactPackageVersion$jscomp$inline_1739 = React.version; if ( - "19.0.0-rc-6230622a1a-20240610" !== + "19.0.0-rc-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_1739 ) throw Error( formatProdErrorMessage( 527, isomorphicReactPackageVersion$jscomp$inline_1739, - "19.0.0-rc-6230622a1a-20240610" + "19.0.0-rc-20b6f4c0e8-20240607" ) ); ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { @@ -15369,7 +15369,7 @@ ReactDOMSharedInternals.findDOMNode = function (componentOrElement) { var devToolsConfig$jscomp$inline_1746 = { findFiberByHostInstance: getClosestInstanceFromNode, bundleType: 0, - version: "19.0.0-rc-6230622a1a-20240610", + version: "19.0.0-rc-20b6f4c0e8-20240607", rendererPackageName: "react-dom" }; (function (internals) { @@ -15412,7 +15412,7 @@ var devToolsConfig$jscomp$inline_1746 = { scheduleRoot: null, setRefreshHandler: null, getCurrentFiber: null, - reconcilerVersion: "19.0.0-rc-6230622a1a-20240610" + reconcilerVersion: "19.0.0-rc-20b6f4c0e8-20240607" }); function noop() {} function getCrossOriginStringAs(as, input) { @@ -15666,7 +15666,7 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; "undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ && "function" === typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop && diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js index fae26ddcab7bcb..c2b232dcb9af7f 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js index 3a49cf59b7cd56..2ec88992dca2e3 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.browser.production.js @@ -5469,4 +5469,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js index 946c5e44745565..16179809429d23 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js index 3211d1bf49077f..87c72ecb0ec259 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server-legacy.node.production.js @@ -5551,4 +5551,4 @@ exports.renderToString = function (children, options) { 'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToPipeableStream" which supports Suspense on the server' ); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js index dd5f57932f7956..04c07d0352a86e 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-rc-6230622a1a-20240610'; +var reactDOMPackageVersion = '19.0.0-rc-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; @@ -503,8 +503,20 @@ function murmurhash3_32_gc(key, seed) { return h1 >>> 0; } +var channel = new MessageChannel(); +var taskQueue = []; + +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + + if (task) { + task(); + } +}; + function scheduleWork(callback) { - callback(); + taskQueue.push(callback); + channel.port2.postMessage(null); } var VIEW_SIZE = 2048; var currentView = null; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js index 9e3e2f70509d0f..66ad18ac0bb43f 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.browser.production.js @@ -123,6 +123,16 @@ function murmurhash3_32_gc(key, seed) { 4294967295; return (h1 ^ (h1 >>> 16)) >>> 0; } +var channel = new MessageChannel(), + taskQueue = []; +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + task && task(); +}; +function scheduleWork(callback) { + taskQueue.push(callback); + channel.port2.postMessage(null); +} var currentView = null, writtenBytes = 0; function writeChunk(destination, chunk) { @@ -3743,7 +3753,9 @@ function pingTask(request, task) { request.pingedTasks.push(task); 1 === request.pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + scheduleWork(function () { + return performWork(request); + })); } function createSuspenseBoundary(request, fallbackAbortableTasks) { return { @@ -5685,18 +5697,27 @@ function flushCompletedQueues(request, destination) { : completeWriting(destination); } } +function startWork(request) { + request.flushScheduled = null !== request.destination; + scheduleWork(function () { + return performWork(request); + }); + null === request.trackedPostpones && + scheduleWork(function () { + safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + }); +} function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - request.flushScheduled = !0; - var destination = request.destination; - destination - ? flushCompletedQueues(request, destination) - : (request.flushScheduled = !1); - } + null !== request.destination && + ((request.flushScheduled = !0), + scheduleWork(function () { + var destination = request.destination; + destination + ? flushCompletedQueues(request, destination) + : (request.flushScheduled = !1); + })); } function abort(request, reason) { try { @@ -5715,16 +5736,16 @@ function abort(request, reason) { logRecoverableError(request, error$46, {}), fatalError(request, error$46); } } -var isomorphicReactPackageVersion$jscomp$inline_728 = React.version; +var isomorphicReactPackageVersion$jscomp$inline_720 = React.version; if ( - "19.0.0-rc-6230622a1a-20240610" !== - isomorphicReactPackageVersion$jscomp$inline_728 + "19.0.0-rc-20b6f4c0e8-20240607" !== + isomorphicReactPackageVersion$jscomp$inline_720 ) throw Error( formatProdErrorMessage( 527, - isomorphicReactPackageVersion$jscomp$inline_728, - "19.0.0-rc-6230622a1a-20240610" + isomorphicReactPackageVersion$jscomp$inline_720, + "19.0.0-rc-20b6f4c0e8-20240607" ) ); exports.renderToReadableStream = function (children, options) { @@ -5810,10 +5831,7 @@ exports.renderToReadableStream = function (children, options) { signal.addEventListener("abort", listener); } } - request.flushScheduled = null !== request.destination; - performWork(request); - null === request.trackedPostpones && - safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + startWork(request); }); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js index 132f8e49ea8a33..01ec362ec4f028 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.bun.production.js @@ -3426,7 +3426,9 @@ function pingTask(request, task) { request.pingedTasks.push(task); 1 === request.pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + setTimeout(function () { + return performWork(request); + }, 0)); } function createSuspenseBoundary(request, fallbackAbortableTasks) { return { @@ -5396,18 +5398,27 @@ function flushCompletedQueues(request, destination) { : flushBuffered(destination); } } +function startWork(request) { + request.flushScheduled = null !== request.destination; + setTimeout(function () { + return performWork(request); + }, 0); + null === request.trackedPostpones && + setTimeout(function () { + safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + }, 0); +} function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - request.flushScheduled = !0; - var destination = request.destination; - destination - ? flushCompletedQueues(request, destination) - : (request.flushScheduled = !1); - } + null !== request.destination && + ((request.flushScheduled = !0), + setTimeout(function () { + var destination = request.destination; + destination + ? flushCompletedQueues(request, destination) + : (request.flushScheduled = !1); + }, 0)); } function abort(request, reason) { try { @@ -5430,13 +5441,13 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_724 = React.version; if ( - "19.0.0-rc-6230622a1a-20240610" !== + "19.0.0-rc-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_724 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_724 + - "\n - react-dom: 19.0.0-rc-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-20b6f4c0e8-20240607\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -5521,10 +5532,7 @@ exports.renderToReadableStream = function (children, options) { signal.addEventListener("abort", listener); } } - request.flushScheduled = null !== request.destination; - performWork(request); - null === request.trackedPostpones && - safelyEmitEarlyPreloads(request, 0 === request.pendingRootTasks); + startWork(request); }); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js index 04c3f42c748d2e..8f4e3c60cd7d0b 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.development.js @@ -17,7 +17,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-rc-6230622a1a-20240610'; +var reactDOMPackageVersion = '19.0.0-rc-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js index b565ba3c56f43d..49f635657bd403 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.edge.production.js @@ -5832,13 +5832,13 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_728 = React.version; if ( - "19.0.0-rc-6230622a1a-20240610" !== + "19.0.0-rc-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_728 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_728 + - "\n - react-dom: 19.0.0-rc-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-20b6f4c0e8-20240607\nLearn more: https://react.dev/warnings/version-mismatch") ); exports.renderToReadableStream = function (children, options) { return new Promise(function (resolve, reject) { @@ -5926,4 +5926,4 @@ exports.renderToReadableStream = function (children, options) { startWork(request); }); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js index e81ff0454735bc..07d1e5834a4c9b 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.development.js @@ -20,7 +20,7 @@ var crypto = require('crypto'); var async_hooks = require('async_hooks'); var ReactDOM = require('react-dom'); -var reactDOMPackageVersion = '19.0.0-rc-6230622a1a-20240610'; +var reactDOMPackageVersion = '19.0.0-rc-20b6f4c0e8-20240607'; var ReactSharedInternals = React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js index 88b32e2e4cc19f..3f470c5ab1057d 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom-server.node.production.js @@ -5456,13 +5456,13 @@ function abort(request, reason) { } var isomorphicReactPackageVersion$jscomp$inline_751 = React.version; if ( - "19.0.0-rc-6230622a1a-20240610" !== + "19.0.0-rc-20b6f4c0e8-20240607" !== isomorphicReactPackageVersion$jscomp$inline_751 ) throw Error( 'Incompatible React versions: The "react" and "react-dom" packages must have the exact same version. Instead got:\n - react: ' + (isomorphicReactPackageVersion$jscomp$inline_751 + - "\n - react-dom: 19.0.0-rc-6230622a1a-20240610\nLearn more: https://react.dev/warnings/version-mismatch") + "\n - react-dom: 19.0.0-rc-20b6f4c0e8-20240607\nLearn more: https://react.dev/warnings/version-mismatch") ); function createDrainHandler(destination, request) { return function () { @@ -5789,4 +5789,4 @@ exports.renderToPipeableStream = function (children, options) { } }; }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom.development.js index 8db01a385167a4..c2d44e2282388d 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.development.js @@ -142,7 +142,7 @@ var Internals = { findDOMNode: null }; -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; /** * HTML nodeType values that represent the type of the node diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom.production.js index 09e9499d29d651..48123ab84df464 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.production.js @@ -206,4 +206,4 @@ exports.useFormState = function (action, initialState, permalink) { exports.useFormStatus = function () { return ReactSharedInternals.H.useHostTransitionStatus(); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js index ebba208d3dbab9..271d3076252ba5 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.development.js @@ -16,7 +16,7 @@ if (process.env.NODE_ENV !== "production") { var React = require("next/dist/compiled/react"); -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; var ReactSharedInternalsServer = // $FlowFixMe: It's defined in the one we resolve to. React.__SERVER_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE; diff --git a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js index 2550b1a3824784..2c5e8109104be9 100644 --- a/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js +++ b/packages/next/src/compiled/react-dom/cjs/react-dom.react-server.production.js @@ -151,4 +151,4 @@ exports.preloadModule = function (href, options) { }); } else Internals.d.m(href); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-dom/package.json b/packages/next/src/compiled/react-dom/package.json index 7cae0f6a1a0ac1..5c7351d9d1ced3 100644 --- a/packages/next/src/compiled/react-dom/package.json +++ b/packages/next/src/compiled/react-dom/package.json @@ -67,10 +67,10 @@ "./package.json": "./package.json" }, "dependencies": { - "scheduler": "0.25.0-rc-6230622a1a-20240610" + "scheduler": "0.25.0-rc-20b6f4c0e8-20240607" }, "peerDependencies": { - "react": "19.0.0-rc-6230622a1a-20240610" + "react": "19.0.0-rc-20b6f4c0e8-20240607" }, "browser": { "./server.js": "./server.browser.js", diff --git a/packages/next/src/compiled/react-experimental/cjs/react.development.js b/packages/next/src/compiled/react-experimental/cjs/react.development.js index 2d96aa48ef62b8..28a5bc8099ee59 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.development.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.development.js @@ -129,7 +129,7 @@ function printWarning(level, format, args, currentStack) { } } -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var REACT_ELEMENT_TYPE = Symbol.for('react.transitional.element') ; var REACT_PORTAL_TYPE = Symbol.for('react.portal'); diff --git a/packages/next/src/compiled/react-experimental/cjs/react.production.js b/packages/next/src/compiled/react-experimental/cjs/react.production.js index b052713a3bcb35..3fda938f9f1d6f 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.production.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.production.js @@ -559,4 +559,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js b/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js index 77efc5682d9e2c..3ac65b1635bfa7 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.react-server.development.js @@ -1683,7 +1683,7 @@ function postpone(reason) { throw postponeInstance; } -var ReactVersion = '19.0.0-experimental-6230622a1a-20240610'; +var ReactVersion = '19.0.0-experimental-20b6f4c0e8-20240607'; var getPrototypeOf = Object.getPrototypeOf; diff --git a/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js b/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js index 39f23503647825..ec7bba145d1cdc 100644 --- a/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js +++ b/packages/next/src/compiled/react-experimental/cjs/react.react-server.production.js @@ -564,4 +564,4 @@ exports.useId = function () { exports.useMemo = function (create, deps) { return ReactSharedInternals.H.useMemo(create, deps); }; -exports.version = "19.0.0-experimental-6230622a1a-20240610"; +exports.version = "19.0.0-experimental-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react-is/package.json b/packages/next/src/compiled/react-is/package.json index 4425e958fd1d04..5117e710e55c3a 100644 --- a/packages/next/src/compiled/react-is/package.json +++ b/packages/next/src/compiled/react-is/package.json @@ -1,6 +1,6 @@ { "name": "react-is", - "version": "19.0.0-rc-6230622a1a-20240610", + "version": "19.0.0-rc-20b6f4c0e8-20240607", "description": "Brand checking of React Elements.", "main": "index.js", "sideEffects": false, diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js index 156c0d3516f213..f8d3c768509bfd 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.browser.development.js @@ -2970,9 +2970,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3011,6 +3022,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3022,15 +3034,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.edge.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.edge.development.js index 06d3092106e45d..d7a66e3477be9a 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.edge.development.js @@ -3243,9 +3243,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3284,6 +3295,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3295,15 +3307,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.development.js index acf3bc6d563095..3dedc982739b26 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.development.js @@ -3241,9 +3241,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3282,6 +3293,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3293,15 +3305,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.unbundled.development.js index fdb1a30362bf5e..0b82d95a999b73 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-client.node.unbundled.development.js @@ -3196,9 +3196,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3237,6 +3248,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3248,15 +3260,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.development.js index 28b12ac53ab497..d0e4286bc6c7fc 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.development.js @@ -96,9 +96,32 @@ function printWarning(level, format, args, currentStack) { } } +var channel = new MessageChannel(); +var taskQueue = []; + +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + + if (task) { + task(); + } +}; + function scheduleWork(callback) { - callback(); + taskQueue.push(callback); + channel.port2.postMessage(null); +} + +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); } + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; var VIEW_SIZE = 2048; var currentView = null; var writtenBytes = 0; @@ -1728,6 +1751,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1766,8 +1791,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1868,6 +1894,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2261,6 +2297,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2633,6 +2676,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2657,7 +2707,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2955,21 +3005,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3003,6 +3064,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3015,10 +3087,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3122,6 +3196,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4111,6 +4192,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4167,10 +4249,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4182,6 +4274,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4243,6 +4346,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4339,6 +4447,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4359,10 +4468,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4398,19 +4511,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4432,7 +4547,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.production.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.production.js index c4b571061e446d..4a0e7a589361b8 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.browser.production.js @@ -11,6 +11,30 @@ "use strict"; var ReactDOM = require("react-dom"), React = require("react"), + channel = new MessageChannel(), + taskQueue = []; +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + task && task(); +}; +function scheduleWork(callback) { + taskQueue.push(callback); + channel.port2.postMessage(null); +} +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -671,6 +695,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -776,6 +801,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -985,6 +1018,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1082,6 +1116,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1098,7 +1133,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + scheduleMicrotask(function () { + return performWork(request); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1118,79 +1155,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1200,6 +1165,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); id = id.toString(16) + ":" + request + "\n"; @@ -1218,7 +1186,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1250,7 +1218,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1305,6 +1273,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1341,12 +1377,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1629,8 +1664,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1719,7 +1754,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1748,9 +1784,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1761,12 +1805,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1825,26 +1877,35 @@ function flushCompletedChunks(request, destination) { } 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.close(), (request.destination = null)); } +function startWork(request) { + request.flushScheduled = null !== request.destination; + scheduleWork(function () { + return performWork(request); + }); +} function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; - flushCompletedChunks(request, destination); - } + null !== request.destination && + ((request.flushScheduled = !0), + scheduleWork(function () { + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1856,37 +1917,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2328,8 +2399,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2337,10 +2408,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2705,13 +2776,12 @@ exports.renderToReadableStream = function (model, turbopackMap, options) { { type: "bytes", start: function () { - request.flushScheduled = null !== request.destination; - performWork(request); + startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js index 2ebac24a659a7a..ab24b3938fe045 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.development.js @@ -96,6 +96,16 @@ function printWarning(level, format, args, currentStack) { } } +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; function scheduleWork(callback) { setTimeout(callback, 0); } @@ -1763,6 +1773,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1801,8 +1813,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1908,6 +1921,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2304,6 +2327,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2676,6 +2706,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2700,7 +2737,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2998,21 +3035,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3046,6 +3094,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3058,10 +3117,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3165,6 +3226,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4160,6 +4228,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4216,10 +4285,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4231,6 +4310,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4292,6 +4382,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4388,6 +4483,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4412,10 +4508,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4451,19 +4551,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4485,7 +4587,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js index 34835be6eaec06..d9ab3f8f698595 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.edge.production.js @@ -10,7 +10,21 @@ "use strict"; var ReactDOM = require("react-dom"), - React = require("react"), + React = require("react"); +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -678,6 +692,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -791,6 +806,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -1000,6 +1023,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1097,6 +1121,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1113,9 +1138,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setTimeout(function () { + scheduleMicrotask(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1135,79 +1160,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1217,6 +1170,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); id = id.toString(16) + ":" + request + "\n"; @@ -1235,7 +1191,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1267,7 +1223,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1322,6 +1278,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1358,12 +1382,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1650,8 +1673,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1740,7 +1763,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1769,9 +1793,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1782,12 +1814,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1846,6 +1886,7 @@ function flushCompletedChunks(request, destination) { } 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.close(), (request.destination = null)); } @@ -1860,24 +1901,24 @@ function startWork(request) { }, 0); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setTimeout(function () { - return flushCompletedChunks(request, destination); - }, 0); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + }, 0)); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1889,37 +1930,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2361,8 +2412,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2370,10 +2421,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2741,9 +2792,9 @@ exports.renderToReadableStream = function (model, turbopackMap, options) { startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.development.js index 85d49dcc17329f..a62fd90f41875d 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.development.js @@ -102,6 +102,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1816,6 +1817,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1854,8 +1857,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1961,6 +1965,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2355,6 +2369,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2727,6 +2748,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2751,7 +2779,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -3049,21 +3077,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3097,6 +3136,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3109,10 +3159,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3216,6 +3268,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4207,6 +4266,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4263,10 +4323,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4278,6 +4348,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4339,6 +4420,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4437,6 +4523,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4457,10 +4544,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4496,19 +4587,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4530,7 +4623,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.production.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.production.js index e6d93f95bb65cc..47f13725808c82 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -708,6 +709,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -818,6 +820,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -1026,6 +1036,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1123,6 +1134,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1139,7 +1151,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1161,79 +1173,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1243,6 +1183,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); return id.toString(16) + ":" + request + "\n"; @@ -1260,7 +1203,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1291,7 +1234,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1346,6 +1289,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1382,12 +1393,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1668,8 +1678,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1680,6 +1690,10 @@ function emitErrorChunk(request, id, digest) { id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { if (TaintRegistryByteLengths.has(typedArray.byteLength)) { var tainted = TaintRegistryValues.get( @@ -1746,12 +1760,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1768,9 +1782,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1781,9 +1794,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1794,12 +1815,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1882,6 +1911,7 @@ function flushCompletedChunks(request, destination) { "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.end(), (request.destination = null)); } @@ -1892,22 +1922,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1918,10 +1946,12 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1933,37 +1963,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2405,8 +2445,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2414,10 +2454,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2775,12 +2815,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, turbopackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_203 = []; + var JSCompiler_object_inline_chunks_205 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_203.push(chunk); + JSCompiler_object_inline_chunks_205.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_203, { + var blob = new Blob(JSCompiler_object_inline_chunks_205, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.development.js index 79f18d994110e2..f6d04eb95faec0 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.development.js @@ -102,6 +102,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1816,6 +1817,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1854,8 +1857,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1961,6 +1965,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2355,6 +2369,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2727,6 +2748,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2751,7 +2779,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -3049,21 +3077,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3097,6 +3136,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3109,10 +3159,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3216,6 +3268,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4207,6 +4266,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4263,10 +4323,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4278,6 +4348,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4339,6 +4420,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4437,6 +4523,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4457,10 +4544,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4496,19 +4587,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4530,7 +4623,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.production.js b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.production.js index 8fc01b2098a3dc..58b997ff847a4e 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/cjs/react-server-dom-turbopack-server.node.unbundled.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -708,6 +709,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -818,6 +820,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -1026,6 +1036,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1123,6 +1134,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1139,7 +1151,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1161,79 +1173,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1243,6 +1183,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); return id.toString(16) + ":" + request + "\n"; @@ -1260,7 +1203,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1291,7 +1234,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1346,6 +1289,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1382,12 +1393,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1668,8 +1678,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1680,6 +1690,10 @@ function emitErrorChunk(request, id, digest) { id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { if (TaintRegistryByteLengths.has(typedArray.byteLength)) { var tainted = TaintRegistryValues.get( @@ -1746,12 +1760,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1768,9 +1782,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1781,9 +1794,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1794,12 +1815,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1882,6 +1911,7 @@ function flushCompletedChunks(request, destination) { "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.end(), (request.destination = null)); } @@ -1892,22 +1922,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1918,10 +1946,12 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1933,37 +1963,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2374,8 +2414,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2383,10 +2423,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2744,12 +2784,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, turbopackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_203 = []; + var JSCompiler_object_inline_chunks_205 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_203.push(chunk); + JSCompiler_object_inline_chunks_205.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_203, { + var blob = new Blob(JSCompiler_object_inline_chunks_205, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json b/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json index 753a9380a4924b..aa845203e30cd5 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json +++ b/packages/next/src/compiled/react-server-dom-turbopack-experimental/package.json @@ -47,7 +47,7 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "0.0.0-experimental-6230622a1a-20240610", - "react-dom": "0.0.0-experimental-6230622a1a-20240610" + "react": "0.0.0-experimental-20b6f4c0e8-20240607", + "react-dom": "0.0.0-experimental-20b6f4c0e8-20240607" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js index 6c1c09616b05a3..a54b5b704da7c9 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.browser.development.js @@ -2763,9 +2763,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js index 155930d18831d8..48d41fb22b4457 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.edge.development.js @@ -3036,9 +3036,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js index 898c55bd4871a4..ebbe54583a5313 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.development.js @@ -3034,9 +3034,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js index ae6127d1e8d162..67cf13d4077d66 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-client.node.unbundled.development.js @@ -2989,9 +2989,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js index 0a94876e7c39b8..1c9ec26064e081 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.development.js @@ -94,9 +94,32 @@ function printWarning(level, format, args, currentStack) { } } +var channel = new MessageChannel(); +var taskQueue = []; + +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + + if (task) { + task(); + } +}; + function scheduleWork(callback) { - callback(); + taskQueue.push(callback); + channel.port2.postMessage(null); +} + +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); } + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; var VIEW_SIZE = 2048; var currentView = null; var writtenBytes = 0; @@ -1558,6 +1581,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1567,8 +1592,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1661,6 +1687,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2034,6 +2070,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2375,6 +2418,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2399,7 +2449,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2697,21 +2747,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2727,6 +2788,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2739,10 +2811,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2846,6 +2920,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3754,6 +3835,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3810,14 +3892,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3879,6 +3982,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -3971,6 +4079,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -3991,10 +4100,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4030,15 +4143,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4055,7 +4170,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.js index 4183c4f8419900..240543fa0e8a67 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.browser.production.js @@ -11,6 +11,30 @@ "use strict"; var ReactDOM = require("react-dom"), React = require("react"), + channel = new MessageChannel(), + taskQueue = []; +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + task && task(); +}; +function scheduleWork(callback) { + taskQueue.push(callback); + channel.port2.postMessage(null); +} +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -670,7 +694,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -746,6 +771,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -932,6 +965,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1029,6 +1063,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1045,7 +1080,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + scheduleMicrotask(function () { + return performWork(request); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1077,50 +1114,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1273,12 +1321,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1539,8 +1586,8 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; @@ -1609,7 +1656,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1636,10 +1684,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1648,6 +1709,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1705,54 +1767,72 @@ function flushCompletedChunks(request, destination) { (writtenBytes = 0)); } 0 === request.pendingChunks && - (destination.close(), (request.destination = null)); + ((request.status = 3), destination.close(), (request.destination = null)); +} +function startWork(request) { + request.flushScheduled = null !== request.destination; + scheduleWork(function () { + return performWork(request); + }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; - flushCompletedChunks(request, destination); - } + null !== request.destination && + ((request.flushScheduled = !0), + scheduleWork(function () { + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2194,8 +2274,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2203,10 +2283,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2571,13 +2651,12 @@ exports.renderToReadableStream = function (model, turbopackMap, options) { { type: "bytes", start: function () { - request.flushScheduled = null !== request.destination; - performWork(request); + startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js index 4b11b1cf66facd..86f8193b208f95 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.development.js @@ -94,6 +94,16 @@ function printWarning(level, format, args, currentStack) { } } +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; function scheduleWork(callback) { setTimeout(callback, 0); } @@ -1571,6 +1581,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1580,8 +1592,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1679,6 +1692,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2055,6 +2078,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2396,6 +2426,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2420,7 +2457,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2718,21 +2755,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2748,6 +2796,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2760,10 +2819,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2867,6 +2928,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3781,6 +3849,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3837,14 +3906,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3906,6 +3996,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -3998,6 +4093,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4022,10 +4118,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4061,15 +4161,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4086,7 +4188,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js index 8eb8e50f4a02e2..ad80e015828bc3 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.edge.production.js @@ -10,7 +10,21 @@ "use strict"; var ReactDOM = require("react-dom"), - React = require("react"), + React = require("react"); +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -677,7 +691,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -761,6 +776,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -947,6 +970,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1044,6 +1068,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1060,9 +1085,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setTimeout(function () { + scheduleMicrotask(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1094,50 +1119,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1290,12 +1326,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1558,8 +1593,8 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; @@ -1628,7 +1663,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1655,10 +1691,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1667,6 +1716,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1724,7 +1774,7 @@ function flushCompletedChunks(request, destination) { (writtenBytes = 0)); } 0 === request.pendingChunks && - (destination.close(), (request.destination = null)); + ((request.status = 3), destination.close(), (request.destination = null)); } function startWork(request) { request.flushScheduled = null !== request.destination; @@ -1737,53 +1787,63 @@ function startWork(request) { }, 0); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setTimeout(function () { - return flushCompletedChunks(request, destination); - }, 0); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + }, 0)); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2225,8 +2285,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2234,10 +2294,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2605,9 +2665,9 @@ exports.renderToReadableStream = function (model, turbopackMap, options) { startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js index d9eecb883352da..1ee39e940ecddb 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.development.js @@ -100,6 +100,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1624,6 +1625,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1633,8 +1636,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1732,6 +1736,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2106,6 +2120,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2447,6 +2468,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2471,7 +2499,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2769,21 +2797,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2799,6 +2838,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2811,10 +2861,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2918,6 +2970,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3828,6 +3887,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3884,14 +3944,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3953,6 +4034,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4047,6 +4133,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4067,10 +4154,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4106,15 +4197,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4131,7 +4224,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.js index d50b25790f9b17..f890dfb443aff9 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -707,7 +708,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -788,6 +790,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -973,6 +983,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1070,6 +1081,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1086,7 +1098,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1120,50 +1132,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1314,12 +1337,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1579,14 +1601,18 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { request.pendingChunks++; typedArray = new Uint8Array( @@ -1638,12 +1664,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1660,9 +1686,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1671,10 +1696,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1683,6 +1721,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1764,7 +1803,7 @@ function flushCompletedChunks(request, destination) { } "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && - (destination.end(), (request.destination = null)); + ((request.status = 3), destination.end(), (request.destination = null)); } function startWork(request) { request.flushScheduled = null !== request.destination; @@ -1773,22 +1812,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1799,39 +1836,51 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2273,8 +2322,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2282,10 +2331,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2643,12 +2692,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, turbopackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_216 = []; + var JSCompiler_object_inline_chunks_201 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_216.push(chunk); + JSCompiler_object_inline_chunks_201.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_216, { + var blob = new Blob(JSCompiler_object_inline_chunks_201, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js index 0f79a67c489a3a..2a08b45d5665ac 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.development.js @@ -100,6 +100,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1624,6 +1625,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1633,8 +1636,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1732,6 +1736,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2106,6 +2120,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2447,6 +2468,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2471,7 +2499,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2769,21 +2797,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2799,6 +2838,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2811,10 +2861,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2918,6 +2970,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3828,6 +3887,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3884,14 +3944,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3953,6 +4034,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4047,6 +4133,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4067,10 +4154,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4106,15 +4197,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4131,7 +4224,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.js b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.js index 219314934a52af..b2a1cabf87ac7e 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.js +++ b/packages/next/src/compiled/react-server-dom-turbopack/cjs/react-server-dom-turbopack-server.node.unbundled.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -707,7 +708,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -788,6 +790,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -973,6 +983,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1070,6 +1081,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1086,7 +1098,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1120,50 +1132,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1314,12 +1337,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1579,14 +1601,18 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { request.pendingChunks++; typedArray = new Uint8Array( @@ -1638,12 +1664,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1660,9 +1686,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1671,10 +1696,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1683,6 +1721,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1764,7 +1803,7 @@ function flushCompletedChunks(request, destination) { } "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && - (destination.end(), (request.destination = null)); + ((request.status = 3), destination.end(), (request.destination = null)); } function startWork(request) { request.flushScheduled = null !== request.destination; @@ -1773,22 +1812,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1799,39 +1836,51 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2242,8 +2291,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2251,10 +2300,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2612,12 +2661,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, turbopackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_216 = []; + var JSCompiler_object_inline_chunks_201 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_216.push(chunk); + JSCompiler_object_inline_chunks_201.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_216, { + var blob = new Blob(JSCompiler_object_inline_chunks_201, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-turbopack/package.json b/packages/next/src/compiled/react-server-dom-turbopack/package.json index a3195b088c38fd..4d1e2b6cead8a7 100644 --- a/packages/next/src/compiled/react-server-dom-turbopack/package.json +++ b/packages/next/src/compiled/react-server-dom-turbopack/package.json @@ -47,7 +47,7 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "19.0.0-rc-6230622a1a-20240610", - "react-dom": "19.0.0-rc-6230622a1a-20240610" + "react": "19.0.0-rc-20b6f4c0e8-20240607", + "react-dom": "19.0.0-rc-20b6f4c0e8-20240607" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js index aea9b6e7a0e27b..edcd25de5ee0eb 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.browser.development.js @@ -2991,9 +2991,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3032,6 +3043,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3043,15 +3055,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.edge.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.edge.development.js index e47c9ee42f7f19..5478d33921acdd 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.edge.development.js @@ -3245,9 +3245,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3286,6 +3297,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3297,15 +3309,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.development.js index 403a895cc1b5cd..1573019566a0d7 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.development.js @@ -3243,9 +3243,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3284,6 +3295,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3295,15 +3307,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.unbundled.development.js index c934a07eb1afa0..fdf7ff93190dfd 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-client.node.unbundled.development.js @@ -3196,9 +3196,20 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + var callStack = buildFakeCallStack(response, stack, // $FlowFixMe[incompatible-use] + Error.bind(null, message || 'An error occurred in the Server Components render but no message was provided')); + var rootTask = response._debugRootTask; + + if (rootTask != null) { + error = rootTask.run(callStack); + } else { + error = callStack(); + } + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; @@ -3237,6 +3248,7 @@ function resolveHint(response, code, model) { var supportsCreateTask = !!console.createTask; var taskCache = supportsCreateTask ? new WeakMap() : null; var fakeFunctionCache = new Map() ; +var fakeFunctionIdx = 0; function createFakeFunction(name, filename, sourceMap, line, col) { // This creates a fake copy of a Server Module. It represents a module that has already @@ -3248,15 +3260,31 @@ function createFakeFunction(name, filename, sourceMap, line, col) { var code; if (line <= 1) { - code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment + '\n'; + code = '_=>' + ' '.repeat(col < 4 ? 0 : col - 4) + '_()\n' + comment; } else { - code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()\n'; + code = comment + '\n'.repeat(line - 2) + '_=>\n' + ' '.repeat(col < 1 ? 0 : col - 1) + '_()'; + } + + if (filename.startsWith('/')) { + // If the filename starts with `/` we assume that it is a file system file + // rather than relative to the current host. Since on the server fully qualified + // stack traces use the file path. + // TODO: What does this look like on Windows? + filename = 'file://' + filename; } if (sourceMap) { - code += '//# sourceMappingURL=' + sourceMap; + // We use the prefix rsc://React/ to separate these from other files listed in + // the Chrome DevTools. We need a "host name" and not just a protocol because + // otherwise the group name becomes the root folder. Ideally we don't want to + // show these at all but there's two reasons to assign a fake URL. + // 1) A printed stack trace string needs a unique URL to be able to source map it. + // 2) If source maps are disabled or fails, you should at least be able to tell + // which file it was. + code += '\n//# sourceURL=rsc://React/' + filename + '?' + fakeFunctionIdx++; + code += '\n//# sourceMappingURL=' + sourceMap; } else if (filename) { - code += '//# sourceURL=' + filename; + code += '\n//# sourceURL=' + filename; } var fn; diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.development.js index 2b4fa7bffe31fe..2213e50a749518 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.development.js @@ -96,9 +96,32 @@ function printWarning(level, format, args, currentStack) { } } +var channel = new MessageChannel(); +var taskQueue = []; + +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + + if (task) { + task(); + } +}; + function scheduleWork(callback) { - callback(); + taskQueue.push(callback); + channel.port2.postMessage(null); +} + +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); } + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; var VIEW_SIZE = 2048; var currentView = null; var writtenBytes = 0; @@ -1736,6 +1759,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1774,8 +1799,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1876,6 +1902,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2269,6 +2305,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2641,6 +2684,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2665,7 +2715,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2963,21 +3013,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3011,6 +3072,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3023,10 +3095,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3130,6 +3204,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4119,6 +4200,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4175,10 +4257,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4190,6 +4282,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4251,6 +4354,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4347,6 +4455,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4367,10 +4476,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4406,19 +4519,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4440,7 +4555,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.production.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.production.js index 571858d8fcd86f..21636a4c5ae420 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.browser.production.js @@ -11,6 +11,30 @@ "use strict"; var ReactDOM = require("react-dom"), React = require("react"), + channel = new MessageChannel(), + taskQueue = []; +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + task && task(); +}; +function scheduleWork(callback) { + taskQueue.push(callback); + channel.port2.postMessage(null); +} +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -671,6 +695,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -776,6 +801,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -985,6 +1018,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1082,6 +1116,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1098,7 +1133,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + scheduleMicrotask(function () { + return performWork(request); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1118,79 +1155,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1200,6 +1165,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); id = id.toString(16) + ":" + request + "\n"; @@ -1218,7 +1186,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1250,7 +1218,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1305,6 +1273,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1341,12 +1377,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1629,8 +1664,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1719,7 +1754,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1748,9 +1784,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1761,12 +1805,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1825,26 +1877,35 @@ function flushCompletedChunks(request, destination) { } 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.close(), (request.destination = null)); } +function startWork(request) { + request.flushScheduled = null !== request.destination; + scheduleWork(function () { + return performWork(request); + }); +} function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; - flushCompletedChunks(request, destination); - } + null !== request.destination && + ((request.flushScheduled = !0), + scheduleWork(function () { + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1856,37 +1917,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2338,8 +2409,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2347,10 +2418,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2715,13 +2786,12 @@ exports.renderToReadableStream = function (model, webpackMap, options) { { type: "bytes", start: function () { - request.flushScheduled = null !== request.destination; - performWork(request); + startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js index 06d9fbba45ac3f..5f90452354181b 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.development.js @@ -96,6 +96,16 @@ function printWarning(level, format, args, currentStack) { } } +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; function scheduleWork(callback) { setTimeout(callback, 0); } @@ -1771,6 +1781,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1809,8 +1821,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1916,6 +1929,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2312,6 +2335,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2684,6 +2714,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2708,7 +2745,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -3006,21 +3043,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3054,6 +3102,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3066,10 +3125,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3173,6 +3234,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4168,6 +4236,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4224,10 +4293,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4239,6 +4318,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4300,6 +4390,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4396,6 +4491,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4420,10 +4516,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4459,19 +4559,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4493,7 +4595,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js index 656fde5afd8528..d77de5b938d4fb 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.edge.production.js @@ -10,7 +10,21 @@ "use strict"; var ReactDOM = require("react-dom"), - React = require("react"), + React = require("react"); +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -678,6 +692,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -791,6 +806,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -1000,6 +1023,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1097,6 +1121,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1113,9 +1138,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setTimeout(function () { + scheduleMicrotask(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1135,79 +1160,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1217,6 +1170,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); id = id.toString(16) + ":" + request + "\n"; @@ -1235,7 +1191,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1267,7 +1223,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1322,6 +1278,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1358,12 +1382,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1650,8 +1673,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1740,7 +1763,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1769,9 +1793,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1782,12 +1814,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1846,6 +1886,7 @@ function flushCompletedChunks(request, destination) { } 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.close(), (request.destination = null)); } @@ -1860,24 +1901,24 @@ function startWork(request) { }, 0); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setTimeout(function () { - return flushCompletedChunks(request, destination); - }, 0); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + }, 0)); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1889,37 +1930,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2362,8 +2413,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2371,10 +2422,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2742,9 +2793,9 @@ exports.renderToReadableStream = function (model, webpackMap, options) { startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.development.js index 18ed8768aa7b0e..6ded86d6ba1926 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.development.js @@ -102,6 +102,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1824,6 +1825,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1862,8 +1865,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1969,6 +1973,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2363,6 +2377,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2735,6 +2756,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2759,7 +2787,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -3057,21 +3085,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3105,6 +3144,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3117,10 +3167,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3224,6 +3276,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4215,6 +4274,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4271,10 +4331,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4286,6 +4356,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4347,6 +4428,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4445,6 +4531,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4465,10 +4552,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4504,19 +4595,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4538,7 +4631,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.production.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.production.js index 45287f2fbf7c3d..63712e0a2c0e12 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -708,6 +709,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -818,6 +820,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -1026,6 +1036,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1123,6 +1134,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1139,7 +1151,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1161,79 +1173,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1243,6 +1183,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); return id.toString(16) + ":" + request + "\n"; @@ -1260,7 +1203,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1291,7 +1234,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1346,6 +1289,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1382,12 +1393,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1668,8 +1678,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1680,6 +1690,10 @@ function emitErrorChunk(request, id, digest) { id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { if (TaintRegistryByteLengths.has(typedArray.byteLength)) { var tainted = TaintRegistryValues.get( @@ -1746,12 +1760,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1768,9 +1782,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1781,9 +1794,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1794,12 +1815,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1882,6 +1911,7 @@ function flushCompletedChunks(request, destination) { "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.end(), (request.destination = null)); } @@ -1892,22 +1922,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1918,10 +1946,12 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1933,37 +1963,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2406,8 +2446,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2415,10 +2455,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2776,12 +2816,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, webpackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_203 = []; + var JSCompiler_object_inline_chunks_205 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_203.push(chunk); + JSCompiler_object_inline_chunks_205.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_203, { + var blob = new Blob(JSCompiler_object_inline_chunks_205, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.development.js index 309bd1ebe9f2cc..ac543b359f4c84 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.development.js @@ -102,6 +102,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1824,6 +1825,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; var TaintRegistryObjects = ReactSharedInternals.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternals.TaintRegistryValues, TaintRegistryByteLengths = ReactSharedInternals.TaintRegistryByteLengths, @@ -1862,8 +1865,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1969,6 +1973,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2363,6 +2377,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2735,6 +2756,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner, stack, validated); } @@ -2759,7 +2787,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -3057,21 +3085,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -3105,6 +3144,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(postponeId); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -3117,10 +3167,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -3224,6 +3276,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -4215,6 +4274,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -4271,10 +4331,20 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } else if (x.$$typeof === REACT_POSTPONE_TYPE) { request.abortableTasks.delete(task); @@ -4286,6 +4356,17 @@ function retryTask(request, task) { } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -4347,6 +4428,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4445,6 +4531,7 @@ function flushCompletedChunks(request, destination) { cleanupTaintQueue(request); } + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4465,10 +4552,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4504,19 +4595,21 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) { var postponeInstance = reason; logPostpone(request, postponeInstance.message); emitPostponeChunk(request, errorId, postponeInstance); } else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4538,7 +4631,7 @@ function abort(request, reason) { // We create an alternative reason for it instead. _error = new Error('The render was aborted due to being postponed.'); } else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.production.js b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.production.js index 5b65879a5afc62..c7027224896461 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/cjs/react-server-dom-webpack-server.node.unbundled.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -708,6 +709,7 @@ if (!ReactSharedInternalsServer) ); var ObjectPrototype = Object.prototype, stringify = JSON.stringify, + AbortSigil = {}, TaintRegistryObjects = ReactSharedInternalsServer.TaintRegistryObjects, TaintRegistryValues = ReactSharedInternalsServer.TaintRegistryValues, TaintRegistryByteLengths = @@ -818,6 +820,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -1026,6 +1036,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1123,6 +1134,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1139,7 +1151,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1161,79 +1173,7 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { return pingTask(request, task); }, toJSON: function (parentPropertyName, value) { - a: { - var prevKeyPath = task.keyPath, - prevImplicitSlot = task.implicitSlot; - try { - var JSCompiler_inline_result = renderModelDestructive( - request, - task, - this, - parentPropertyName, - value - ); - } catch (thrownValue) { - parentPropertyName = - thrownValue === SuspenseException - ? getSuspendedThenable() - : thrownValue; - value = task.model; - value = - "object" === typeof value && - null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE); - if ( - "object" === typeof parentPropertyName && - null !== parentPropertyName - ) { - if ("function" === typeof parentPropertyName.then) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - break a; - } - if (parentPropertyName.$$typeof === REACT_POSTPONE_TYPE) { - request.pendingChunks++; - JSCompiler_inline_result = request.nextChunkId++; - logPostpone(request, parentPropertyName.message); - emitPostponeChunk(request, JSCompiler_inline_result); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.toString(16) - : serializeByValueID(JSCompiler_inline_result); - break a; - } - } - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - if (value) - request.pendingChunks++, - (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), - emitErrorChunk(request, prevKeyPath, prevImplicitSlot), - (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; - } - } - return JSCompiler_inline_result; + return renderModel(request, task, this, parentPropertyName, value); }, thenableState: null }; @@ -1243,6 +1183,9 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { function serializeByValueID(id) { return "$" + id.toString(16); } +function serializeLazyID(id) { + return "$L" + id.toString(16); +} function encodeReferenceChunk(request, id, reference) { request = stringify(reference); return id.toString(16) + ":" + request + "\n"; @@ -1260,7 +1203,7 @@ function serializeClientReference( existingId = writtenClientReferences.get(clientReferenceKey); if (void 0 !== existingId) return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + existingId.toString(16) + ? serializeLazyID(existingId) : serializeByValueID(existingId); try { var config = request.bundlerConfig, @@ -1291,7 +1234,7 @@ function serializeClientReference( request.completedImportChunks.push(processedChunk); writtenClientReferences.set(clientReferenceKey, importId); return parent[0] === REACT_ELEMENT_TYPE && "1" === parentPropertyName - ? "$L" + importId.toString(16) + ? serializeLazyID(importId) : serializeByValueID(importId); } catch (x) { return ( @@ -1346,6 +1289,74 @@ function serializeBlob(request, blob) { return "$B" + newTask.id.toString(16); } var modelRoot = !1; +function renderModel(request, task, parent, key, value) { + var prevKeyPath = task.keyPath, + prevImplicitSlot = task.implicitSlot; + try { + return renderModelDestructive(request, task, parent, key, value); + } catch (thrownValue) { + parent = task.model; + parent = + "object" === typeof parent && + null !== parent && + (parent.$$typeof === REACT_ELEMENT_TYPE || + parent.$$typeof === REACT_LAZY_TYPE); + key = + thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; + if ("object" === typeof key && null !== key) { + if ("function" === typeof key.then) { + if (1 === request.status) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + request = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + value = request.ping; + key.then(value, value); + request.thenableState = getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + return parent + ? serializeLazyID(request.id) + : serializeByValueID(request.id); + } + if (key.$$typeof === REACT_POSTPONE_TYPE) + return ( + request.pendingChunks++, + (value = request.nextChunkId++), + logPostpone(request, key.message), + emitPostponeChunk(request, value), + (task.keyPath = prevKeyPath), + (task.implicitSlot = prevImplicitSlot), + parent ? serializeLazyID(value) : serializeByValueID(value) + ); + } + if (thrownValue === AbortSigil) + return ( + (task.status = 3), + (request = request.fatalError), + parent ? serializeLazyID(request) : serializeByValueID(request) + ); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + if (parent) + return ( + request.pendingChunks++, + (task = request.nextChunkId++), + (prevKeyPath = logRecoverableError(request, key)), + emitErrorChunk(request, task, prevKeyPath), + serializeLazyID(task) + ); + throw key; + } +} function renderModelDestructive( request, task, @@ -1382,12 +1393,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1668,8 +1678,8 @@ function logRecoverableError(request, error) { function fatalError(request, error) { cleanupTaintQueue(request); null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitPostponeChunk(request, id) { id = id.toString(16) + ":P\n"; @@ -1680,6 +1690,10 @@ function emitErrorChunk(request, id, digest) { id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { if (TaintRegistryByteLengths.has(typedArray.byteLength)) { var tainted = TaintRegistryValues.get( @@ -1746,12 +1760,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1768,9 +1782,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1781,9 +1794,17 @@ function retryTask(request, task) { : thrownValue; if ("object" === typeof x && null !== x) { if ("function" === typeof x.then) { + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + return; + } + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } if (x.$$typeof === REACT_POSTPONE_TYPE) { @@ -1794,12 +1815,20 @@ function retryTask(request, task) { return; } } - request.abortableTasks.delete(task); - task.status = 4; - var digest = logRecoverableError(request, x); - emitErrorChunk(request, task.id, digest); + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$23 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$23); + } else { + request.abortableTasks.delete(task); + task.status = 4; + var digest = logRecoverableError(request, x); + emitErrorChunk(request, task.id, digest); + } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1882,6 +1911,7 @@ function flushCompletedChunks(request, destination) { "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && (cleanupTaintQueue(request), + (request.status = 3), destination.end(), (request.destination = null)); } @@ -1892,22 +1922,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1918,10 +1946,12 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; if ( "object" === typeof reason && null !== reason && @@ -1933,37 +1963,47 @@ function abort(request, reason) { var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$26 = + var error$30 = "object" === typeof reason && null !== reason && reason.$$typeof === REACT_POSTPONE_TYPE ? Error("The render was aborted due to being postponed.") : void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$26); + return callback(error$30); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$27) { - logRecoverableError(request, error$27), fatalError(request, error$27); + } catch (error$31) { + logRecoverableError(request, error$31), fatalError(request, error$31); } } function resolveServerReference(bundlerConfig, id) { @@ -2374,8 +2414,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$30 = createPendingChunk(response); - chunk$30.then( + var chunk$34 = createPendingChunk(response); + chunk$34.then( function (v) { return controller.enqueue(v); }, @@ -2383,10 +2423,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$30; + previousBlockedChunk = chunk$34; chunk.then(function () { - previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); - resolveModelChunk(chunk$30, json, -1); + previousBlockedChunk === chunk$34 && (previousBlockedChunk = null); + resolveModelChunk(chunk$34, json, -1); }); } }, @@ -2744,12 +2784,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, webpackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_203 = []; + var JSCompiler_object_inline_chunks_205 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_203.push(chunk); + JSCompiler_object_inline_chunks_205.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_203, { + var blob = new Blob(JSCompiler_object_inline_chunks_205, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json b/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json index 2a519e5cd49eea..63a2c5b1cc0ab8 100644 --- a/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json +++ b/packages/next/src/compiled/react-server-dom-webpack-experimental/package.json @@ -46,8 +46,8 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "0.0.0-experimental-6230622a1a-20240610", - "react-dom": "0.0.0-experimental-6230622a1a-20240610", + "react": "0.0.0-experimental-20b6f4c0e8-20240607", + "react-dom": "0.0.0-experimental-20b6f4c0e8-20240607", "webpack": "^5.59.0" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js index c9bc9ea20580a1..6202ccc045bbcf 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.browser.development.js @@ -2784,9 +2784,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js index 6014f94919acab..98a600843f6089 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.edge.development.js @@ -3038,9 +3038,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js index 39aae25b37b21c..4bc7799fb81c62 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.development.js @@ -3036,9 +3036,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js index 898d858826800a..846dbc6cec3eeb 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-client.node.unbundled.development.js @@ -2989,9 +2989,16 @@ function stopStream(response, id, row) { function resolveErrorDev(response, id, digest, message, stack) { + var error; + + { + // Executing Error within a native stack isn't really limited to owner stacks + // but we gate it behind the same flag for now while iterating. + // eslint-disable-next-line react-internal/prod-error-codes + error = Error(message || 'An error occurred in the Server Components render but no message was provided'); + error.stack = stack; + } - var error = new Error(message || 'An error occurred in the Server Components render but no message was provided'); - error.stack = stack; error.digest = digest; var errorWithDigest = error; var chunks = response._chunks; diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js index bff4cc98957468..e276f64df10b6f 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.development.js @@ -94,9 +94,32 @@ function printWarning(level, format, args, currentStack) { } } +var channel = new MessageChannel(); +var taskQueue = []; + +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + + if (task) { + task(); + } +}; + function scheduleWork(callback) { - callback(); + taskQueue.push(callback); + channel.port2.postMessage(null); +} + +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); } + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; var VIEW_SIZE = 2048; var currentView = null; var writtenBytes = 0; @@ -1566,6 +1589,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1575,8 +1600,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1669,6 +1695,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2042,6 +2078,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2383,6 +2426,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2407,7 +2457,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2705,21 +2755,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2735,6 +2796,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2747,10 +2819,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2854,6 +2928,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3762,6 +3843,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3818,14 +3900,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3887,6 +3990,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -3979,6 +4087,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -3999,10 +4108,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4038,15 +4151,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4063,7 +4178,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.js index 99e8361ac82fbc..a754e327df5c0f 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.browser.production.js @@ -11,6 +11,30 @@ "use strict"; var ReactDOM = require("react-dom"), React = require("react"), + channel = new MessageChannel(), + taskQueue = []; +channel.port1.onmessage = function () { + var task = taskQueue.shift(); + task && task(); +}; +function scheduleWork(callback) { + taskQueue.push(callback); + channel.port2.postMessage(null); +} +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -670,7 +694,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -746,6 +771,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -932,6 +965,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1029,6 +1063,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1045,7 +1080,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - performWork(request)); + scheduleMicrotask(function () { + return performWork(request); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1077,50 +1114,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1273,12 +1321,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1539,8 +1586,8 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; @@ -1609,7 +1656,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1636,10 +1684,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1648,6 +1709,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1705,54 +1767,72 @@ function flushCompletedChunks(request, destination) { (writtenBytes = 0)); } 0 === request.pendingChunks && - (destination.close(), (request.destination = null)); + ((request.status = 3), destination.close(), (request.destination = null)); +} +function startWork(request) { + request.flushScheduled = null !== request.destination; + scheduleWork(function () { + return performWork(request); + }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; - flushCompletedChunks(request, destination); - } + null !== request.destination && + ((request.flushScheduled = !0), + scheduleWork(function () { + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2204,8 +2284,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2213,10 +2293,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2581,13 +2661,12 @@ exports.renderToReadableStream = function (model, webpackMap, options) { { type: "bytes", start: function () { - request.flushScheduled = null !== request.destination; - performWork(request); + startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js index 570d72b285694c..d9bd1672240c00 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.development.js @@ -94,6 +94,16 @@ function printWarning(level, format, args, currentStack) { } } +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} + +var LocalPromise = Promise; +var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : function (callback) { + LocalPromise.resolve(null).then(callback).catch(handleErrorInNextTick); +}; function scheduleWork(callback) { setTimeout(callback, 0); } @@ -1579,6 +1589,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1588,8 +1600,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1687,6 +1700,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2063,6 +2086,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2404,6 +2434,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2428,7 +2465,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2726,21 +2763,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2756,6 +2804,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2768,10 +2827,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2875,6 +2936,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3789,6 +3857,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3845,14 +3914,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3914,6 +4004,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4006,6 +4101,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4030,10 +4126,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4069,15 +4169,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4094,7 +4196,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js index 69d67b0581f68f..a16e1a773eabc9 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.edge.production.js @@ -10,7 +10,21 @@ "use strict"; var ReactDOM = require("react-dom"), - React = require("react"), + React = require("react"); +function handleErrorInNextTick(error) { + setTimeout(function () { + throw error; + }); +} +var LocalPromise = Promise, + scheduleMicrotask = + "function" === typeof queueMicrotask + ? queueMicrotask + : function (callback) { + LocalPromise.resolve(null) + .then(callback) + .catch(handleErrorInNextTick); + }, currentView = null, writtenBytes = 0; function writeChunkAndReturn(destination, chunk) { @@ -677,7 +691,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -761,6 +776,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -947,6 +970,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1044,6 +1068,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1060,9 +1085,9 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setTimeout(function () { + scheduleMicrotask(function () { return performWork(request); - }, 0)); + })); } function createTask(request, model, keyPath, implicitSlot, abortSet) { request.pendingChunks++; @@ -1094,50 +1119,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1290,12 +1326,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1558,8 +1593,8 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), closeWithError(request.destination, error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), closeWithError(request.destination, error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; @@ -1628,7 +1663,8 @@ function emitChunk(request, task, value) { } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1655,10 +1691,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1667,6 +1716,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1724,7 +1774,7 @@ function flushCompletedChunks(request, destination) { (writtenBytes = 0)); } 0 === request.pendingChunks && - (destination.close(), (request.destination = null)); + ((request.status = 3), destination.close(), (request.destination = null)); } function startWork(request) { request.flushScheduled = null !== request.destination; @@ -1737,53 +1787,63 @@ function startWork(request) { }, 0); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setTimeout(function () { - return flushCompletedChunks(request, destination); - }, 0); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + }, 0)); } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2226,8 +2286,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2235,10 +2295,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2606,9 +2666,9 @@ exports.renderToReadableStream = function (model, webpackMap, options) { startWork(request); }, pull: function (controller) { - if (1 === request.status) - (request.status = 2), closeWithError(controller, request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), closeWithError(controller, request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = controller; try { flushCompletedChunks(request, controller); diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js index 38c223f4f56c1e..0d7a339ea8e18e 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.development.js @@ -100,6 +100,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1632,6 +1633,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1641,8 +1644,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1740,6 +1744,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2114,6 +2128,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2455,6 +2476,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2479,7 +2507,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2777,21 +2805,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2807,6 +2846,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2819,10 +2869,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2926,6 +2978,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3836,6 +3895,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3892,14 +3952,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3961,6 +4042,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4055,6 +4141,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4075,10 +4162,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4114,15 +4205,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4139,7 +4232,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.js index ba407bb97f91ee..a8892300480787 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -707,7 +708,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -788,6 +790,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -973,6 +983,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1070,6 +1081,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1086,7 +1098,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1120,50 +1132,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1314,12 +1337,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1579,14 +1601,18 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { request.pendingChunks++; typedArray = new Uint8Array( @@ -1638,12 +1664,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1660,9 +1686,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1671,10 +1696,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1683,6 +1721,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1764,7 +1803,7 @@ function flushCompletedChunks(request, destination) { } "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && - (destination.end(), (request.destination = null)); + ((request.status = 3), destination.end(), (request.destination = null)); } function startWork(request) { request.flushScheduled = null !== request.destination; @@ -1773,22 +1812,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1799,39 +1836,51 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2274,8 +2323,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2283,10 +2332,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2644,12 +2693,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, webpackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_216 = []; + var JSCompiler_object_inline_chunks_201 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_216.push(chunk); + JSCompiler_object_inline_chunks_201.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_216, { + var blob = new Blob(JSCompiler_object_inline_chunks_201, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js index 5ee2f57659eedf..51c1640f3f7856 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.development.js @@ -100,6 +100,7 @@ function printWarning(level, format, args, currentStack) { function scheduleWork(callback) { setImmediate(callback); } +var scheduleMicrotask = queueMicrotask; function flushBuffered(destination) { // If we don't have any more data to send right now. // Flush whatever is in the buffer to the wire. @@ -1632,6 +1633,8 @@ var PENDING$1 = 0; var COMPLETED = 1; var ABORTED = 3; var ERRORED$1 = 4; +var RENDERING = 5; +var AbortSigil = {}; function defaultErrorHandler(error) { console['error'](error); // Don't transform to our wrapper @@ -1641,8 +1644,9 @@ function defaultPostponeHandler(reason) {// Noop } var OPEN = 0; -var CLOSING = 1; -var CLOSED = 2; +var ABORTING = 1; +var CLOSING = 2; +var CLOSED = 3; function createRequest(model, bundlerConfig, onError, identifierPrefix, onPostpone, environmentName, temporaryReferences) { if (ReactSharedInternals.A !== null && ReactSharedInternals.A !== DefaultAsyncDispatcher) { throw new Error('Currently React only supports one RSC renderer at a time.'); @@ -1740,6 +1744,16 @@ function serializeThenable(request, task, thenable) { default: { + if (request.status === ABORTING) { + // We can no longer accept any resolved values + newTask.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, newTask.id, model); + request.abortableTasks.delete(newTask); + return newTask.id; + } + if (typeof thenable.status === 'string') { // Only instrument the thenable if the status if not defined. If // it's defined, but an unknown value, assume it's been instrumented by @@ -2114,6 +2128,13 @@ validated) // DEV-only result = callComponentInDEV(Component, props, componentDebugInfo); } + if (request.status === ABORTING) { + // If we aborted during rendering we should interrupt the render but + // we don't need to provide an error because the renderer will encode + // the abort error as the reason. + throw AbortSigil; + } + if (typeof result === 'object' && result !== null && !isClientReference(result)) { if (typeof result.then === 'function') { // When the return value is in children position we can resolve it immediately, @@ -2455,6 +2476,13 @@ validated) // DEV only wrappedType = callLazyInitInDEV(type); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + return renderElement(request, task, wrappedType, key, ref, props, owner); } @@ -2479,7 +2507,7 @@ function pingTask(request, task) { if (pingedTasks.length === 1) { request.flushScheduled = request.destination !== null; - scheduleWork(function () { + scheduleMicrotask(function () { return performWork(request); }); } @@ -2777,21 +2805,32 @@ function renderModel(request, task, parent, key, value) { try { return renderModelDestructive(request, task, parent, key, value); } catch (thrownValue) { + // If the suspended/errored value was an element or lazy it can be reduced + // to a lazy reference, so that it doesn't error the parent. + var model = task.model; + var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); var x = thrownValue === SuspenseException ? // This is a special type of exception used for Suspense. For historical // reasons, the rest of the Suspense implementation expects the thrown // value to be a thenable, because before `use` existed that was the // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. - getSuspendedThenable() : thrownValue; // If the suspended/errored value was an element or lazy it can be reduced - // to a lazy reference, so that it doesn't error the parent. - - var model = task.model; - var wasReactNode = typeof model === 'object' && model !== null && (model.$$typeof === REACT_ELEMENT_TYPE || model.$$typeof === REACT_LAZY_TYPE); + getSuspendedThenable() : thrownValue; if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended, we'll need to create a new task and resolve it later. + if (request.status === ABORTING) { + task.status = ABORTED; + var errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(errorId); + } + + return serializeByValueID(errorId); + } // Something suspended, we'll need to create a new task and resolve it later. + + var newTask = createTask(request, task.model, task.keyPath, task.implicitSlot, request.abortableTasks); var ping = newTask.ping; x.then(ping, ping); @@ -2807,6 +2846,17 @@ function renderModel(request, task, parent, key, value) { return serializeByValueID(newTask.id); } + } + + if (thrownValue === AbortSigil) { + task.status = ABORTED; + var _errorId = request.fatalError; + + if (wasReactNode) { + return serializeLazyID(_errorId); + } + + return serializeByValueID(_errorId); } // Restore the context. We assume that this will be restored by the inner // functions in case nothing throws so we don't use "finally" here. @@ -2819,10 +2869,12 @@ function renderModel(request, task, parent, key, value) { // We'll replace this element with a lazy reference that throws on the client // once it gets rendered. request.pendingChunks++; - var errorId = request.nextChunkId++; + + var _errorId2 = request.nextChunkId++; + var digest = logRecoverableError(request, x); - emitErrorChunk(request, errorId, digest, x); - return serializeLazyID(errorId); + emitErrorChunk(request, _errorId2, digest, x); + return serializeLazyID(_errorId2); } // Something errored but it was not in a React Node. There's no need to serialize // it by value because it'll just error the whole parent row anyway so we can // just stop any siblings and error the whole parent row. @@ -2926,6 +2978,13 @@ function renderModelDestructive(request, task, parent, parentPropertyName, value resolvedModel = callLazyInitInDEV(lazy); } + if (request.status === ABORTING) { + // lazy initializers are user code and could abort during render + // we don't wan to return any value resolved from the lazy initializer + // if it aborts so we interrupt rendering here + throw AbortSigil; + } + { var _debugInfo = lazy._debugInfo; @@ -3836,6 +3895,7 @@ function retryTask(request, task) { } var prevDebugID = debugID; + task.status = RENDERING; try { // Track the root so we know that we have to emit this object even though it @@ -3892,14 +3952,35 @@ function retryTask(request, task) { if (typeof x === 'object' && x !== null) { // $FlowFixMe[method-unbinding] if (typeof x.then === 'function') { - // Something suspended again, let's pick it back up later. + if (request.status === ABORTING) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var errorId = request.fatalError; + var model = stringify(serializeByValueID(errorId)); + emitModelChunk(request, task.id, model); + return; + } // Something suspended again, let's pick it back up later. + + + task.status = PENDING$1; + task.thenableState = getThenableStateAfterSuspending(); var ping = task.ping; x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); return; } } + if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = ABORTED; + var _errorId3 = request.fatalError; + + var _model = stringify(serializeByValueID(_errorId3)); + + emitModelChunk(request, task.id, _model); + return; + } + request.abortableTasks.delete(task); task.status = ERRORED$1; var digest = logRecoverableError(request, x); @@ -3961,6 +4042,11 @@ function performWork(request) { } function abortTask(task, request, errorId) { + if (task.status === RENDERING) { + // This task will be aborted by the render + return; + } + task.status = ABORTED; // Instead of emitting an error per task.id, we emit a model that only // has a single value referencing the error. @@ -4055,6 +4141,7 @@ function flushCompletedChunks(request, destination) { if (request.pendingChunks === 0) { + request.status = CLOSED; close$1(destination); request.destination = null; } @@ -4075,10 +4162,14 @@ function enqueueFlush(request) { request.pingedTasks.length === 0 && // If there is no destination there is nothing we can flush to. A flush will // happen when we start flowing again request.destination !== null) { - var destination = request.destination; request.flushScheduled = true; scheduleWork(function () { - return flushCompletedChunks(request, destination); + request.flushScheduled = false; + var destination = request.destination; + + if (destination) { + flushCompletedChunks(request, destination); + } }); } } @@ -4114,15 +4205,17 @@ function stopFlowing(request) { function abort(request, reason) { try { + request.status = ABORTING; var abortableTasks = request.abortableTasks; // We have tasks to abort. We'll emit one error row and then emit a reference // to that row from every row that's still remaining. if (abortableTasks.size > 0) { request.pendingChunks++; var errorId = request.nextChunkId++; + request.fatalError = errorId; var postponeInstance; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + var error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; var digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); } @@ -4139,7 +4232,7 @@ function abort(request, reason) { var _error; if (enablePostpone && typeof reason === 'object' && reason !== null && reason.$$typeof === REACT_POSTPONE_TYPE) ; else { - _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : reason; + _error = reason === undefined ? new Error('The render was aborted by the server without a reason.') : typeof reason === 'object' && reason !== null && typeof reason.then === 'function' ? new Error('The render was aborted by the server with a promise.') : reason; } abortListeners.forEach(function (callback) { diff --git a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.js b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.js index 9c958f5708a3cd..3937e96796abd1 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.js +++ b/packages/next/src/compiled/react-server-dom-webpack/cjs/react-server-dom-webpack-server.node.unbundled.production.js @@ -14,6 +14,7 @@ require("crypto"); var async_hooks = require("async_hooks"), ReactDOM = require("react-dom"), React = require("react"), + scheduleMicrotask = queueMicrotask, currentView = null, writtenBytes = 0, destinationHasCapacity = !0; @@ -707,7 +708,8 @@ if (!ReactSharedInternalsServer) 'The "react" package in this environment is not configured correctly. The "react-server" condition must be enabled in any environment that runs React Server Components.' ); var ObjectPrototype = Object.prototype, - stringify = JSON.stringify; + stringify = JSON.stringify, + AbortSigil = {}; function defaultErrorHandler(error) { console.error(error); } @@ -788,6 +790,14 @@ function serializeThenable(request, task, thenable) { newTask.id ); default: + if (1 === request.status) + return ( + (newTask.status = 3), + (task = stringify(serializeByValueID(request.fatalError))), + emitModelChunk(request, newTask.id, task), + request.abortableTasks.delete(newTask), + newTask.id + ); "string" !== typeof thenable.status && ((thenable.status = "pending"), thenable.then( @@ -973,6 +983,7 @@ function renderFunctionComponent(request, task, key, Component, props) { thenableIndexCounter = 0; thenableState = prevThenableState; Component = Component(props, void 0); + if (1 === request.status) throw AbortSigil; if ( "object" === typeof Component && null !== Component && @@ -1070,6 +1081,7 @@ function renderElement(request, task, type, key, ref, props) { case REACT_LAZY_TYPE: var init = type._init; type = init(type._payload); + if (1 === request.status) throw AbortSigil; return renderElement(request, task, type, key, ref, props); case REACT_FORWARD_REF_TYPE: return renderFunctionComponent(request, task, key, type.render, props); @@ -1086,7 +1098,7 @@ function pingTask(request, task) { pingedTasks.push(task); 1 === pingedTasks.length && ((request.flushScheduled = null !== request.destination), - setImmediate(function () { + scheduleMicrotask(function () { return performWork(request); })); } @@ -1120,50 +1132,61 @@ function createTask(request, model, keyPath, implicitSlot, abortSet) { ); } catch (thrownValue) { if ( - ((parentPropertyName = + ((parentPropertyName = task.model), + (parentPropertyName = + "object" === typeof parentPropertyName && + null !== parentPropertyName && + (parentPropertyName.$$typeof === REACT_ELEMENT_TYPE || + parentPropertyName.$$typeof === REACT_LAZY_TYPE)), + (value = thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue), - (value = task.model), - (value = - "object" === typeof value && + "object" === typeof value && null !== value && - (value.$$typeof === REACT_ELEMENT_TYPE || - value.$$typeof === REACT_LAZY_TYPE)), - "object" === typeof parentPropertyName && - null !== parentPropertyName && - "function" === typeof parentPropertyName.then) - ) { - JSCompiler_inline_result = createTask( - request, - task.model, - task.keyPath, - task.implicitSlot, - request.abortableTasks - ); - var ping = JSCompiler_inline_result.ping; - parentPropertyName.then(ping, ping); - JSCompiler_inline_result.thenableState = - getThenableStateAfterSuspending(); - task.keyPath = prevKeyPath; - task.implicitSlot = prevImplicitSlot; - JSCompiler_inline_result = value - ? "$L" + JSCompiler_inline_result.id.toString(16) - : serializeByValueID(JSCompiler_inline_result.id); - } else if ( + "function" === typeof value.then) + ) + if (1 === request.status) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else { + JSCompiler_inline_result = createTask( + request, + task.model, + task.keyPath, + task.implicitSlot, + request.abortableTasks + ); + var ping = JSCompiler_inline_result.ping; + value.then(ping, ping); + JSCompiler_inline_result.thenableState = + getThenableStateAfterSuspending(); + task.keyPath = prevKeyPath; + task.implicitSlot = prevImplicitSlot; + JSCompiler_inline_result = parentPropertyName + ? "$L" + JSCompiler_inline_result.id.toString(16) + : serializeByValueID(JSCompiler_inline_result.id); + } + else if (thrownValue === AbortSigil) + (task.status = 3), + (prevKeyPath = request.fatalError), + (JSCompiler_inline_result = parentPropertyName + ? "$L" + prevKeyPath.toString(16) + : serializeByValueID(prevKeyPath)); + else if ( ((task.keyPath = prevKeyPath), (task.implicitSlot = prevImplicitSlot), - value) + parentPropertyName) ) request.pendingChunks++, (prevKeyPath = request.nextChunkId++), - (prevImplicitSlot = logRecoverableError( - request, - parentPropertyName - )), + (prevImplicitSlot = logRecoverableError(request, value)), emitErrorChunk(request, prevKeyPath, prevImplicitSlot), (JSCompiler_inline_result = "$L" + prevKeyPath.toString(16)); - else throw parentPropertyName; + else throw value; } return JSCompiler_inline_result; }, @@ -1314,12 +1337,11 @@ function renderModelDestructive( parentPropertyName ); case REACT_LAZY_TYPE: - return ( - (task.thenableState = null), - (parentPropertyName = value._init), - (value = parentPropertyName(value._payload)), - renderModelDestructive(request, task, emptyRoot, "", value) - ); + task.thenableState = null; + parentPropertyName = value._init; + value = parentPropertyName(value._payload); + if (1 === request.status) throw AbortSigil; + return renderModelDestructive(request, task, emptyRoot, "", value); case REACT_LEGACY_ELEMENT_TYPE: throw Error( 'A React Element from an older version of React was rendered. This is not supported. It can happen if:\n- Multiple copies of the "react" package is used.\n- A library pre-bundled an old copy of "react" or "react/jsx-runtime".\n- A compiler tries to "inline" JSX instead of using the runtime.' @@ -1579,14 +1601,18 @@ function logRecoverableError(request, error) { } function fatalError(request, error) { null !== request.destination - ? ((request.status = 2), request.destination.destroy(error)) - : ((request.status = 1), (request.fatalError = error)); + ? ((request.status = 3), request.destination.destroy(error)) + : ((request.status = 2), (request.fatalError = error)); } function emitErrorChunk(request, id, digest) { digest = { digest: digest }; id = id.toString(16) + ":E" + stringify(digest) + "\n"; request.completedErrorChunks.push(id); } +function emitModelChunk(request, id, json) { + id = id.toString(16) + ":" + json + "\n"; + request.completedRegularChunks.push(id); +} function emitTypedArrayChunk(request, id, tag, typedArray) { request.pendingChunks++; typedArray = new Uint8Array( @@ -1638,12 +1664,12 @@ function emitChunk(request, task, value) { : value instanceof DataView ? emitTypedArrayChunk(request, id, "V", value) : ((value = stringify(value, task.toJSON)), - (task = task.id.toString(16) + ":" + value + "\n"), - request.completedRegularChunks.push(task)); + emitModelChunk(request, task.id, value)); } var emptyRoot = {}; function retryTask(request, task) { - if (0 === task.status) + if (0 === task.status) { + task.status = 5; try { modelRoot = task.model; var resolvedModel = renderModelDestructive( @@ -1660,9 +1686,8 @@ function retryTask(request, task) { request.writtenObjects.set(resolvedModel, serializeByValueID(task.id)), emitChunk(request, task, resolvedModel); else { - var json = stringify(resolvedModel), - processedChunk = task.id.toString(16) + ":" + json + "\n"; - request.completedRegularChunks.push(processedChunk); + var json = stringify(resolvedModel); + emitModelChunk(request, task.id, json); } request.abortableTasks.delete(task); task.status = 1; @@ -1671,10 +1696,23 @@ function retryTask(request, task) { thrownValue === SuspenseException ? getSuspendedThenable() : thrownValue; - if ("object" === typeof x && null !== x && "function" === typeof x.then) { - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); + if ("object" === typeof x && null !== x && "function" === typeof x.then) + if (1 === request.status) { + request.abortableTasks.delete(task); + task.status = 3; + var model = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model); + } else { + task.status = 0; + task.thenableState = getThenableStateAfterSuspending(); + var ping = task.ping; + x.then(ping, ping); + } + else if (x === AbortSigil) { + request.abortableTasks.delete(task); + task.status = 3; + var model$19 = stringify(serializeByValueID(request.fatalError)); + emitModelChunk(request, task.id, model$19); } else { request.abortableTasks.delete(task); task.status = 4; @@ -1683,6 +1721,7 @@ function retryTask(request, task) { } } finally { } + } } function performWork(request) { var prevDispatcher = ReactSharedInternalsServer.H; @@ -1764,7 +1803,7 @@ function flushCompletedChunks(request, destination) { } "function" === typeof destination.flush && destination.flush(); 0 === request.pendingChunks && - (destination.end(), (request.destination = null)); + ((request.status = 3), destination.end(), (request.destination = null)); } function startWork(request) { request.flushScheduled = null !== request.destination; @@ -1773,22 +1812,20 @@ function startWork(request) { }); } function enqueueFlush(request) { - if ( - !1 === request.flushScheduled && + !1 === request.flushScheduled && 0 === request.pingedTasks.length && - null !== request.destination - ) { - var destination = request.destination; - request.flushScheduled = !0; + null !== request.destination && + ((request.flushScheduled = !0), setImmediate(function () { - return flushCompletedChunks(request, destination); - }); - } + request.flushScheduled = !1; + var destination = request.destination; + destination && flushCompletedChunks(request, destination); + })); } function startFlowing(request, destination) { - if (1 === request.status) - (request.status = 2), destination.destroy(request.fatalError); - else if (2 !== request.status && null === request.destination) { + if (2 === request.status) + (request.status = 3), destination.destroy(request.fatalError); + else if (3 !== request.status && null === request.destination) { request.destination = destination; try { flushCompletedChunks(request, destination); @@ -1799,39 +1836,51 @@ function startFlowing(request, destination) { } function abort(request, reason) { try { + request.status = 1; var abortableTasks = request.abortableTasks; if (0 < abortableTasks.size) { request.pendingChunks++; - var errorId = request.nextChunkId++, - error = + var errorId = request.nextChunkId++; + request.fatalError = errorId; + var error = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason, digest = logRecoverableError(request, error); emitErrorChunk(request, errorId, digest, error); abortableTasks.forEach(function (task) { - task.status = 3; - var ref = serializeByValueID(errorId); - task = encodeReferenceChunk(request, task.id, ref); - request.completedErrorChunks.push(task); + if (5 !== task.status) { + task.status = 3; + var ref = serializeByValueID(errorId); + task = encodeReferenceChunk(request, task.id, ref); + request.completedErrorChunks.push(task); + } }); abortableTasks.clear(); } var abortListeners = request.abortListeners; if (0 < abortListeners.size) { - var error$22 = + var error$26 = void 0 === reason ? Error("The render was aborted by the server without a reason.") + : "object" === typeof reason && + null !== reason && + "function" === typeof reason.then + ? Error("The render was aborted by the server with a promise.") : reason; abortListeners.forEach(function (callback) { - return callback(error$22); + return callback(error$26); }); abortListeners.clear(); } null !== request.destination && flushCompletedChunks(request, request.destination); - } catch (error$23) { - logRecoverableError(request, error$23), fatalError(request, error$23); + } catch (error$27) { + logRecoverableError(request, error$27), fatalError(request, error$27); } } function resolveServerReference(bundlerConfig, id) { @@ -2242,8 +2291,8 @@ function parseReadableStream(response, reference, type) { (previousBlockedChunk = chunk)); } else { chunk = previousBlockedChunk; - var chunk$26 = createPendingChunk(response); - chunk$26.then( + var chunk$30 = createPendingChunk(response); + chunk$30.then( function (v) { return controller.enqueue(v); }, @@ -2251,10 +2300,10 @@ function parseReadableStream(response, reference, type) { return controller.error(e); } ); - previousBlockedChunk = chunk$26; + previousBlockedChunk = chunk$30; chunk.then(function () { - previousBlockedChunk === chunk$26 && (previousBlockedChunk = null); - resolveModelChunk(chunk$26, json, -1); + previousBlockedChunk === chunk$30 && (previousBlockedChunk = null); + resolveModelChunk(chunk$30, json, -1); }); } }, @@ -2612,12 +2661,12 @@ exports.decodeReplyFromBusboy = function (busboyStream, webpackMap, options) { "React doesn't accept base64 encoded file uploads because we don't expect form data passed from a browser to ever encode data that way. If that's the wrong assumption, we can easily fix it." ); pendingFiles++; - var JSCompiler_object_inline_chunks_216 = []; + var JSCompiler_object_inline_chunks_201 = []; value.on("data", function (chunk) { - JSCompiler_object_inline_chunks_216.push(chunk); + JSCompiler_object_inline_chunks_201.push(chunk); }); value.on("end", function () { - var blob = new Blob(JSCompiler_object_inline_chunks_216, { + var blob = new Blob(JSCompiler_object_inline_chunks_201, { type: mimeType }); response._formData.append(name, blob, filename); diff --git a/packages/next/src/compiled/react-server-dom-webpack/package.json b/packages/next/src/compiled/react-server-dom-webpack/package.json index 71bd27598a5b41..def1d9eb8ec80f 100644 --- a/packages/next/src/compiled/react-server-dom-webpack/package.json +++ b/packages/next/src/compiled/react-server-dom-webpack/package.json @@ -46,8 +46,8 @@ "neo-async": "^2.6.1" }, "peerDependencies": { - "react": "19.0.0-rc-6230622a1a-20240610", - "react-dom": "19.0.0-rc-6230622a1a-20240610", + "react": "19.0.0-rc-20b6f4c0e8-20240607", + "react-dom": "19.0.0-rc-20b6f4c0e8-20240607", "webpack": "^5.59.0" } } \ No newline at end of file diff --git a/packages/next/src/compiled/react/cjs/react.development.js b/packages/next/src/compiled/react/cjs/react.development.js index 2b5e6c323f65f9..bd37b6acca397a 100644 --- a/packages/next/src/compiled/react/cjs/react.development.js +++ b/packages/next/src/compiled/react/cjs/react.development.js @@ -20,7 +20,7 @@ if ( ) { __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error()); } -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; // ----------------------------------------------------------------------------- diff --git a/packages/next/src/compiled/react/cjs/react.production.js b/packages/next/src/compiled/react/cjs/react.production.js index 94a3f59a625935..d8c44e06880ff0 100644 --- a/packages/next/src/compiled/react/cjs/react.production.js +++ b/packages/next/src/compiled/react/cjs/react.production.js @@ -536,4 +536,4 @@ exports.useSyncExternalStore = function ( exports.useTransition = function () { return ReactSharedInternals.H.useTransition(); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/react/cjs/react.react-server.development.js b/packages/next/src/compiled/react/cjs/react.react-server.development.js index 17c2f381a7cfa2..e7c009e7091f2d 100644 --- a/packages/next/src/compiled/react/cjs/react.react-server.development.js +++ b/packages/next/src/compiled/react/cjs/react.react-server.development.js @@ -2068,7 +2068,7 @@ function cache(fn) { }; } -var ReactVersion = '19.0.0-rc-6230622a1a-20240610'; +var ReactVersion = '19.0.0-rc-20b6f4c0e8-20240607'; var Children = { map: mapChildren, diff --git a/packages/next/src/compiled/react/cjs/react.react-server.production.js b/packages/next/src/compiled/react/cjs/react.react-server.production.js index 1e80bd7250e145..c4750622cab91d 100644 --- a/packages/next/src/compiled/react/cjs/react.react-server.production.js +++ b/packages/next/src/compiled/react/cjs/react.react-server.production.js @@ -424,4 +424,4 @@ exports.useId = function () { exports.useMemo = function (create, deps) { return ReactSharedInternals.H.useMemo(create, deps); }; -exports.version = "19.0.0-rc-6230622a1a-20240610"; +exports.version = "19.0.0-rc-20b6f4c0e8-20240607"; diff --git a/packages/next/src/compiled/unistore/unistore.js b/packages/next/src/compiled/unistore/unistore.js index 91850c3f0d7084..bb0d7150cbdc19 100644 --- a/packages/next/src/compiled/unistore/unistore.js +++ b/packages/next/src/compiled/unistore/unistore.js @@ -1 +1 @@ -(()=>{var t={448:t=>{function n(t,i){for(var _ in i)t[_]=i[_];return t}t.exports=function(t){var i=[];function u(t){for(var _=[],a=0;a{var t={899:t=>{function n(t,i){for(var _ in i)t[_]=i[_];return t}t.exports=function(t){var i=[];function u(t){for(var _=[],a=0;a=0.15.0' - version: 2.2.1(react@19.0.0-rc-6230622a1a-20240610) + version: 2.2.1(react@19.0.0-rc-20b6f4c0e8-20240607) source-map: specifier: ^0.7.0 version: 0.7.3 @@ -1584,8 +1584,8 @@ importers: packages/third-parties: dependencies: react: - specifier: 19.0.0-rc-6230622a1a-20240610 - version: 19.0.0-rc-6230622a1a-20240610 + specifier: 19.0.0-rc-20b6f4c0e8-20240607 + version: 19.0.0-rc-20b6f4c0e8-20240607 third-party-capital: specifier: 1.0.20 version: 1.0.20 @@ -3681,11 +3681,11 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: true - /@emotion/react@11.11.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + /@emotion/react@11.11.1(react@19.0.0-rc-20b6f4c0e8-20240607)(types-react@19.0.0-rc.0): resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==} peerDependencies: '@types/react': '*' - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 peerDependenciesMeta: '@types/react': optional: true @@ -3694,12 +3694,12 @@ packages: '@emotion/babel-plugin': 11.11.0 '@emotion/cache': 11.11.0 '@emotion/serialize': 1.1.2 - '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@19.0.0-rc-6230622a1a-20240610) + '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@19.0.0-rc-20b6f4c0e8-20240607) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 '@types/react': /types-react@19.0.0-rc.0 hoist-non-react-statics: 3.3.2 - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dev: true /@emotion/serialize@1.1.2: @@ -3720,12 +3720,12 @@ packages: resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==} dev: true - /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@19.0.0-rc-6230622a1a-20240610): + /@emotion/use-insertion-effect-with-fallbacks@1.0.1(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dev: true /@emotion/utils@1.2.1: @@ -5681,14 +5681,14 @@ packages: transitivePeerDependencies: - supports-color - /@mdx-js/react@2.2.1(react@19.0.0-rc-6230622a1a-20240610): + /@mdx-js/react@2.2.1(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-YdXcMcEnqZhzql98RNrqYo9cEhTTesBiCclEtoiQUbJwx87q9453GTapYU6kJ8ZZ2ek1Vp25SiAXEFy5O/eAPw==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: '@types/mdx': 2.0.3 '@types/react': /types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 /@mswjs/cookies@1.1.0: resolution: {integrity: sha512-0ZcCVQxifZmhwNBoQIrystCb+2sWBY2Zw8lpfJBPCHGCA/HWqehITeCRVIv4VMy8MPlaHo2w2pTHFV2pFfqKPw==} @@ -7032,13 +7032,13 @@ packages: redent: 3.0.0 dev: true - /@testing-library/react@15.0.7(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): + /@testing-library/react@15.0.7(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607)(types-react@19.0.0-rc.0): resolution: {integrity: sha512-cg0RvEdD1TIhhkm1IeYMQxrzy0MtUNfa3minv4MjbgcYzJAZ7yD0i0lwoPOTPr+INtiXFezt2o8xMSnyHhEn2Q==} engines: {node: '>=18'} peerDependencies: '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 peerDependenciesMeta: '@types/react': optional: true @@ -7047,8 +7047,8 @@ packages: '@testing-library/dom': 10.1.0 '@types/react': /types-react@19.0.0-rc.0 '@types/react-dom': /types-react-dom@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) dev: true /@tootallnate/once@1.1.2: @@ -14580,7 +14580,7 @@ packages: /hoist-non-react-statics@3.3.2: resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} dependencies: - react-is: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 dev: true /homedir-polyfill@1.0.3: @@ -18798,15 +18798,15 @@ packages: resolution: {integrity: sha1-yobR/ogoFpsBICCOPchCS524NCw=} dev: true - /next@14.3.0-canary.15(@babel/core@7.22.5)(@opentelemetry/api@1.4.1)(@playwright/test@1.19.2)(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(sass@1.54.0): + /next@14.3.0-canary.15(@babel/core@7.22.5)(@opentelemetry/api@1.4.1)(@playwright/test@1.19.2)(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607)(sass@1.54.0): resolution: {integrity: sha512-vQ376NxcS/zYLJKIZRRfyis9nK+Y23KUqD8Hg93kbrgVWhJW0fZIcKf14ATm8AZg2uxDt4/vj7gVOt1QrWtMIQ==} engines: {node: '>=18.17.0'} hasBin: true peerDependencies: '@opentelemetry/api': ^1.1.0 '@playwright/test': ^1.41.2 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 sass: ^1.3.0 peerDependenciesMeta: '@opentelemetry/api': @@ -18824,10 +18824,10 @@ packages: caniuse-lite: 1.0.30001579 graceful-fs: 4.2.11 postcss: 8.4.31 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) sass: 1.54.0 - styled-jsx: 5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-6230622a1a-20240610) + styled-jsx: 5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-20b6f4c0e8-20240607) optionalDependencies: '@next/swc-darwin-arm64': 14.3.0-canary.15 '@next/swc-darwin-x64': 14.3.0-canary.15 @@ -21460,7 +21460,7 @@ packages: '@jest/types': 24.9.0 ansi-regex: 4.1.0 ansi-styles: 3.2.1 - react-is: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 /pretty-format@27.5.1: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} @@ -21468,7 +21468,7 @@ packages: dependencies: ansi-regex: 5.0.1 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 /pretty-format@29.5.0: resolution: {integrity: sha512-V2mGkI31qdttvTFX7Mt4efOqHXqJWMu4/r66Xh3Z3BwZaPfPJgp6/gbwoujRpPUtfEF6AUUWx3Jim3GCw5g/Qw==} @@ -21476,7 +21476,7 @@ packages: dependencies: '@jest/schemas': 29.4.3 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 dev: true /pretty-format@29.7.0: @@ -21485,7 +21485,7 @@ packages: dependencies: '@jest/schemas': 29.6.3 ansi-styles: 5.2.0 - react-is: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 dev: true /pretty-ms@7.0.0: @@ -21587,7 +21587,7 @@ packages: dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react-is: 19.0.0-rc-6230622a1a-20240610 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 /proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} @@ -21867,36 +21867,36 @@ packages: strip-json-comments: 2.0.1 dev: true - /react-dom@0.0.0-experimental-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610): - resolution: {integrity: sha512-rkLgUvHRh4Spb22M7fVs0AKEqdwiw9TMyVQmZw6pj+FJpgn0Hgqb+evnWsT0B656bwplrp/mltS727Xkw4c0uw==} + /react-dom@0.0.0-experimental-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607): + resolution: {integrity: sha512-I16SgrNGq5f7qhEZiwS+11R1rG1IBg/e2w/5qbUGcw0r312QGbH9K7hOgPrn/ZpiK4A0oxTnRCDM6mI5fKFwbA==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: - react: 19.0.0-rc-6230622a1a-20240610 - scheduler: 0.25.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + scheduler: 0.25.0-rc-20b6f4c0e8-20240607 dev: true - /react-dom@17.0.2(react@19.0.0-rc-6230622a1a-20240610): + /react-dom@17.0.2(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: loose-envify: 1.4.0 object-assign: 4.1.1 - react: 19.0.0-rc-6230622a1a-20240610 - scheduler: 0.25.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + scheduler: 0.25.0-rc-20b6f4c0e8-20240607 dev: true - /react-dom@19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610): - resolution: {integrity: sha512-56G4Pum5E7FeGL1rwHX5IxidSJxQnXP4yORRo0pVeOJuu5DQJvNKpUwmJoftMP/ez0AiglYTY77L2Gs8iyt1Hg==} + /react-dom@19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607): + resolution: {integrity: sha512-XcCj/wjC8eCi2y+ba5ROsJbQMBIdZQYW5CMSiz/Dh5cduiyB4ERHYyfvC8SbreJuYildOHEBukmAVknDMVH+Gg==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: - react: 19.0.0-rc-6230622a1a-20240610 - scheduler: 0.25.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + scheduler: 0.25.0-rc-20b6f4c0e8-20240607 - /react-is@19.0.0-rc-6230622a1a-20240610: - resolution: {integrity: sha512-6BH4F/xpoTJ+BTcb2AmZAzWXInEPUNKgL4u4C1BssZmFkGsvUpZmllLgCEVa105omvex85ZWwKHCy22KftGwDw==} + /react-is@19.0.0-rc-20b6f4c0e8-20240607: + resolution: {integrity: sha512-3lSjb6Y5Fk+f49dU6CodhkijD9gWztoRYPwXO0LVIUxZfTyL+z3AEmQ0M5XqrNvFy6VCU/U9sPnkQRwP59NzLA==} /react-lifecycles-compat@3.0.4: resolution: {integrity: sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==} @@ -21918,157 +21918,91 @@ packages: engines: {node: '>=0.10.0'} dev: true - /react-remove-scroll-bar@2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-DtSYaao4mBmX+HDo5YWYdBWQwYIQQshUV/dVxFxK+KM26Wjwp1gZ6rv6OC3oujI6Bfu6Xyg3TwK533AQutsn/g==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': /types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) - tslib: 2.6.2 - dev: false - - /react-remove-scroll@2.5.10(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-m3zvBRANPBw3qxVVjEIPEQinkcwlFZ4qyomuWVpNJdv4c6MvHfXV0C3L9Jx5rr3HeBHKNRX+1jreB5QloDIJjA==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': /types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - react-remove-scroll-bar: 2.3.6(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) - react-style-singleton: 2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) - tslib: 2.6.2 - use-callback-ref: 1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) - use-sidecar: 1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) - dev: false - - /react-server-dom-turbopack@0.0.0-experimental-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): - resolution: {integrity: sha512-U/7v8k6XS+EPSn46S8/7igwIkNdlfLRjWOCYNxXRs1/nC/BQa/gYUti4bGrMJ7b/2h7WWIHQOdGZRxOvUKIBHg==} + /react-server-dom-turbopack@0.0.0-experimental-20b6f4c0e8-20240607(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607): + resolution: {integrity: sha512-YGXFceM1rsQp8wmuDosGYYbt8xa7EHxN3NcbbvwylKjXHtuLGV7zyooCiHG/+JINWe/O2eLH1TSBq8jUEujlkQ==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) dev: true - /react-server-dom-turbopack@19.0.0-rc-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): - resolution: {integrity: sha512-nhNFHBAB48CMxRZWRo1yrNAbqLrOnDtE6FiSCZuMCkkyiQYtVnWWVIS06O/unlZlY72A97XQyZX9K8RYb8K3iQ==} + /react-server-dom-turbopack@19.0.0-rc-20b6f4c0e8-20240607(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607): + resolution: {integrity: sha512-jFHrGTWw59F1VQsdPVGvQG8MizCi6u22mgTED4C/ZtO74DB8vNMX0KvtMfMikNCg77O/jGL+EkJdgMYD7US6Zg==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) dev: true - /react-server-dom-webpack@0.0.0-experimental-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(webpack@5.90.0): - resolution: {integrity: sha512-HunYxzgNQJ3QCB+wt/X1S0/jalfRWujzHZK5nn5lM72T14M+XEg0mspF55Rmm2+RDE++eFbVqiVLlwFOZ8ln3w==} + /react-server-dom-webpack@0.0.0-experimental-20b6f4c0e8-20240607(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607)(webpack@5.90.0): + resolution: {integrity: sha512-92P3E/drjADzesBI1ArmcsNot0LDQeEAb9Wc/4bVTuJnuUvxunF0JwwRb2yfZIOAd+wYEN/RcnYT7WPrLQj8DA==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 webpack: 5.90.0 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) webpack: 5.90.0(@swc/core@1.5.7) dev: true - /react-server-dom-webpack@19.0.0-rc-6230622a1a-20240610(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610)(webpack@5.90.0): - resolution: {integrity: sha512-nr+IsOVD07QdeCr4BLvR5TALfLaZLi9AIaoa6vXymBc051iDPWedJujYYrjRJy5+9jp9oCx3G8Tt/Bs//TckJw==} + /react-server-dom-webpack@19.0.0-rc-20b6f4c0e8-20240607(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607)(webpack@5.90.0): + resolution: {integrity: sha512-D/9Q/Z3ZypKAu9LkXlPWnu7CpNYfmdYSw8H+sVSQ70NiV+5eEhH4q/J/I/bPViI0muhDhhz3opUOT3O6xXGq9A==} engines: {node: '>=0.10.0'} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 webpack: 5.90.0 dependencies: acorn-loose: 8.3.0 neo-async: 2.6.1 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) webpack: 5.90.0(@swc/core@1.5.7) dev: true - /react-ssr-prepass@1.0.8(react-is@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + /react-ssr-prepass@1.0.8(react-is@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-O0gfRA1SaK+9ITKxqfnXsej2jF+OHGP/+GxD4unROQaM/0/UczGF9fuF+wTboxaQoKdIf4FvS3h/OigWh704VA==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - react-is: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: object-is: 1.0.2 - react: 19.0.0-rc-6230622a1a-20240610 - react-is: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-is: 19.0.0-rc-20b6f4c0e8-20240607 dev: true - /react-style-singleton@2.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': /types-react@19.0.0-rc.0 - get-nonce: 1.0.1 - invariant: 2.2.4 - react: 19.0.0-rc-6230622a1a-20240610 - tslib: 2.6.2 - dev: false - - /react-textarea-autosize@8.5.3(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-XT1024o2pqCuZSuBt9FwHlaDeNtVrtCXu0Rnz88t1jUGheCLa3PhjE1GH8Ctm2axEtvdCl5SUHYschyQ0L5QHQ==} - engines: {node: '>=10'} - peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - dependencies: - '@babel/runtime': 7.22.5 - react: 19.0.0-rc-6230622a1a-20240610 - use-composed-ref: 1.3.0(react@19.0.0-rc-6230622a1a-20240610) - use-latest: 1.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) - transitivePeerDependencies: - - '@types/react' - dev: false - - /react-virtualized@9.22.3(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + /react-virtualized@9.22.3(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-MKovKMxWTcwPSxE1kK1HcheQTWfuCxAuBoSTf2gwyMM21NdX/PXUhnoP8Uc5dRKd+nKm8v41R36OellhdCpkrw==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: '@babel/runtime': 7.22.5 clsx: 1.1.1 dom-helpers: 5.2.1 loose-envify: 1.4.0 prop-types: 15.8.1 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) react-lifecycles-compat: 3.0.4 dev: true - /react@0.0.0-experimental-6230622a1a-20240610: - resolution: {integrity: sha512-A6J2Uj5Jzgz8pLOj9qyyTEQ0v5SwyT6JASC56XxjAwbi9ckb3UwwG6lTjF+rltg4poT3fjPcPyRjd2Q4cWZy/Q==} + /react@0.0.0-experimental-20b6f4c0e8-20240607: + resolution: {integrity: sha512-p5ILF6Y2W1DeguDqbB1KD/VnQYByxMBsUpCRn/EZsJsUfnBV8EXhAReUnVnHml3lXkDlb+6GfNaohkDtNmBdKA==} engines: {node: '>=0.10.0'} dev: true @@ -22080,8 +22014,8 @@ packages: object-assign: 4.1.1 dev: true - /react@19.0.0-rc-6230622a1a-20240610: - resolution: {integrity: sha512-SMgWGY//7nO7F3HMuBfmC15Cr4vTe2tlpSCATfnz/wymSftDOKUqc+0smjRhcUeCFCc1zhOAWJ+N//U5CrmOzQ==} + /react@19.0.0-rc-20b6f4c0e8-20240607: + resolution: {integrity: sha512-1eTIYVwwwD43XOIXCGiOkHO1s6+DIKXfptplhZO0p0Fmr7qcVWz2wQj9icyb50H+vANWnT17EEOL/9xgFHbGEg==} engines: {node: '>=0.10.0'} /read-cache@1.0.0: @@ -23093,12 +23027,12 @@ packages: xmlchars: 2.2.0 dev: true - /scheduler@0.0.0-experimental-6230622a1a-20240610: - resolution: {integrity: sha512-jJZKVNvX9z+p8keIDncyZldGXNZVTBvHrBVWyJ6X9UYxZCtWgbRS0HGLXY9Doqz63wwg1SRIUX7cbgmwF30xKg==} + /scheduler@0.0.0-experimental-20b6f4c0e8-20240607: + resolution: {integrity: sha512-3hCxIYVwPeEqnecnN6r441mYEIaXXk3fGP01Z1hPMEc3KVbuy1gWNha5f/6woJCP4CxgGla/O5OWfiLj512lvA==} dev: true - /scheduler@0.25.0-rc-6230622a1a-20240610: - resolution: {integrity: sha512-GTIQdJXthps5mgkIFo7yAq03M0QQYTfN8z+GrnMC/SCKFSuyFP5tk2BMaaWUsVy4u4r+dTLdiXH8JEivVls0Bw==} + /scheduler@0.25.0-rc-20b6f4c0e8-20240607: + resolution: {integrity: sha512-C7CD1K4+ybod6icJjifT3yh7NPaPJm5TSPzIO+yJwvkxw5XghS+zr77LGQtdNrd7JzfK/K/39UvhIBu5WoXUig==} /schema-utils@2.7.1: resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==} @@ -24120,13 +24054,13 @@ packages: dependencies: inline-style-parser: 0.1.1 - /styled-components@6.0.0-rc.3(react-dom@19.0.0-rc-6230622a1a-20240610)(react@19.0.0-rc-6230622a1a-20240610): + /styled-components@6.0.0-rc.3(react-dom@19.0.0-rc-20b6f4c0e8-20240607)(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-5FbCTxynopck99GRwM5Ey0+VRp8pkQq69TwGOJJeYtR7gPvwGjNx8yBPLN7/dfxwwvn9ymOZYB19eQkv2k70wQ==} engines: {node: '>= 16'} peerDependencies: babel-plugin-styled-components: '>= 2' - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607 peerDependenciesMeta: babel-plugin-styled-components: optional: true @@ -24144,8 +24078,8 @@ packages: '@emotion/unitless': 0.8.1 css-to-react-native: 3.2.0 postcss: 8.4.31 - react: 19.0.0-rc-6230622a1a-20240610 - react-dom: 19.0.0-rc-6230622a1a-20240610(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + react-dom: 19.0.0-rc-20b6f4c0e8-20240607(react@19.0.0-rc-20b6f4c0e8-20240607) shallowequal: 1.1.0 stylis: 4.2.0 tslib: 2.5.3 @@ -24160,13 +24094,13 @@ packages: postcss-load-plugins: 2.3.0 dev: true - /styled-jsx@5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-6230622a1a-20240610): + /styled-jsx@5.1.1(@babel/core@7.22.5)(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} engines: {node: '>= 12.0.0'} peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 peerDependenciesMeta: '@babel/core': optional: true @@ -24175,16 +24109,16 @@ packages: dependencies: '@babel/core': 7.22.5 client-only: 0.0.1 - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dev: false - /styled-jsx@5.1.6(@babel/core@7.22.5)(react@19.0.0-rc-6230622a1a-20240610): + /styled-jsx@5.1.6(@babel/core@7.22.5)(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA==} engines: {node: '>= 12.0.0'} peerDependencies: '@babel/core': '*' babel-plugin-macros: '*' - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 peerDependenciesMeta: '@babel/core': optional: true @@ -24193,7 +24127,7 @@ packages: dependencies: '@babel/core': 7.22.5 client-only: 0.0.1 - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 /stylehacks@4.0.3: resolution: {integrity: sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==} @@ -24326,14 +24260,14 @@ packages: stable: 0.1.8 dev: true - /swr@2.2.4(react@19.0.0-rc-6230622a1a-20240610): + /swr@2.2.4(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-njiZ/4RiIhoOlAaLYDqwz5qH/KZXVilRLvomrx83HjzCWTfa+InyfAjv05PSFxnmLzZkNO9ZfvgoqzAaEI4sGQ==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: client-only: 0.0.1 - react: 19.0.0-rc-6230622a1a-20240610 - use-sync-external-store: 1.2.0(react@19.0.0-rc-6230622a1a-20240610) + react: 19.0.0-rc-20b6f4c0e8-20240607 + use-sync-external-store: 1.2.0(react@19.0.0-rc-20b6f4c0e8-20240607) dev: true /symbol-observable@1.0.1: @@ -25437,7 +25371,7 @@ packages: unist-util-is: 5.2.0 unist-util-visit-parents: 5.1.3 - /unistore@3.4.1(react@19.0.0-rc-6230622a1a-20240610): + /unistore@3.4.1(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-p2Ej8qqrqcD10Ah0ZUKUU/mhRB8pM4q6gzjxq9kZpgxa8dks7oHT8jDP4CqLhoRof3RXOZLKB9EBV1DTzHiJRw==} peerDependencies: preact: '*' @@ -25448,7 +25382,7 @@ packages: react: optional: true dependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dev: true /universal-github-app-jwt@1.1.1: @@ -25603,78 +25537,12 @@ packages: engines: {node: '>= 4'} dev: true - /use-callback-ref@1.3.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': /types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - tslib: 2.6.2 - dev: false - - /use-composed-ref@1.3.0(react@19.0.0-rc-6230622a1a-20240610): - resolution: {integrity: sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==} - peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 - dependencies: - react: 19.0.0-rc-6230622a1a-20240610 - dev: false - - /use-isomorphic-layout-effect@1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==} - peerDependencies: - '@types/react': '*' - react: 19.0.0-rc-6230622a1a-20240610 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': /types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - dev: false - - /use-latest@1.2.1(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==} - peerDependencies: - '@types/react': '*' - react: 19.0.0-rc-6230622a1a-20240610 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': /types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - use-isomorphic-layout-effect: 1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0) - dev: false - - /use-sidecar@1.1.2(react@19.0.0-rc-6230622a1a-20240610)(types-react@19.0.0-rc.0): - resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==} - engines: {node: '>=10'} - peerDependencies: - '@types/react': npm:types-react@19.0.0-rc.0 - react: 19.0.0-rc-6230622a1a-20240610 - peerDependenciesMeta: - '@types/react': - optional: true - dependencies: - '@types/react': /types-react@19.0.0-rc.0 - detect-node-es: 1.1.0 - react: 19.0.0-rc-6230622a1a-20240610 - tslib: 2.6.2 - dev: false - - /use-sync-external-store@1.2.0(react@19.0.0-rc-6230622a1a-20240610): + /use-sync-external-store@1.2.0(react@19.0.0-rc-20b6f4c0e8-20240607): resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} peerDependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dependencies: - react: 19.0.0-rc-6230622a1a-20240610 + react: 19.0.0-rc-20b6f4c0e8-20240607 dev: true /use@3.1.1: diff --git a/run-tests.js b/run-tests.js index 234c83171c1cdf..d8e29214cf7435 100644 --- a/run-tests.js +++ b/run-tests.js @@ -410,7 +410,8 @@ ${ENDGROUP}`) // a starter Next.js install to re-use to speed up tests // to avoid having to run yarn each time console.log(`${GROUP}Creating Next.js install for isolated tests`) - const reactVersion = process.env.NEXT_TEST_REACT_VERSION || '19.0.0-rc.0' + const reactVersion = + process.env.NEXT_TEST_REACT_VERSION || '19.0.0-rc-20b6f4c0e8-20240607' const { installDir, pkgPaths, tmpRepoDir } = await createNextInstall({ parentSpan: mockTrace(), dependencies: { diff --git a/test/.stats-app/package.json b/test/.stats-app/package.json index 45bdbd3a667f6d..3098287a024490 100644 --- a/test/.stats-app/package.json +++ b/test/.stats-app/package.json @@ -3,9 +3,9 @@ "private": true, "license": "MIT", "dependencies": { - "next": "19.0.0-rc-6230622a1a-20240610", - "react": "19.0.0-rc-6230622a1a-20240610", - "react-dom": "19.0.0-rc-6230622a1a-20240610" + "next": "19.0.0-rc-20b6f4c0e8-20240607", + "react": "19.0.0-rc-20b6f4c0e8-20240607", + "react-dom": "19.0.0-rc-20b6f4c0e8-20240607" }, "engines": { "node": ">=18.17.0"