diff --git a/compiled/facebook-www/REVISION b/compiled/facebook-www/REVISION index 48844cd7d4..8dbf95b4de 100644 --- a/compiled/facebook-www/REVISION +++ b/compiled/facebook-www/REVISION @@ -1 +1 @@ -2fba484cd095ea79b940364cea5107fa4ca9f0c8 +b70a0d70224ceb4e277bd8ac535a2caafa5c075a diff --git a/compiled/facebook-www/ReactDOMServer-dev.classic.js b/compiled/facebook-www/ReactDOMServer-dev.classic.js index 81ffe7823b..f17b145ea6 100644 --- a/compiled/facebook-www/ReactDOMServer-dev.classic.js +++ b/compiled/facebook-www/ReactDOMServer-dev.classic.js @@ -19,7 +19,7 @@ if (__DEV__) { var React = require("react"); var ReactDOM = require("react-dom"); -var ReactVersion = "18.3.0-www-classic-b66d17d9"; +var ReactVersion = "18.3.0-www-classic-b794beee"; // This refers to a WWW module. var warningWWW = require("warning"); @@ -9789,14 +9789,14 @@ function getStackByComponentStackNode(componentStack) { var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; var ReactCurrentCache = ReactSharedInternals.ReactCurrentCache; var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; // Linked list representing the identity of a component given the component/tag name and key. -// The name might be minified but we assume that it's going to be the same generated name. Typically -// because it's just the same compiled output in practice. +var CLIENT_RENDERED = 4; // if it errors or infinitely suspends var PENDING = 0; var COMPLETED = 1; var FLUSHED = 2; var ABORTED = 3; var ERRORED = 4; +var POSTPONED = 5; var OPEN = 0; var CLOSING = 1; var CLOSED = 2; // This is a default heuristic for how to split up the HTML content into progressive @@ -9846,6 +9846,7 @@ function createRequest( flushScheduled: false, resumableState: resumableState, renderState: renderState, + rootFormatContext: rootFormatContext, progressiveChunkSize: progressiveChunkSize === undefined ? DEFAULT_PROGRESSIVE_CHUNK_SIZE @@ -9861,6 +9862,7 @@ function createRequest( clientRenderedBoundaries: [], completedBoundaries: [], partialBoundaries: [], + trackedPostpones: null, onError: onError === undefined ? defaultErrorHandler : onError, onPostpone: onPostpone === undefined ? noop : onPostpone, onAllReady: onAllReady === undefined ? noop : onAllReady, @@ -9913,18 +9915,19 @@ function pingTask(request, task) { } } -function createSuspenseBoundary(request, fallbackAbortableTasks) { +function createSuspenseBoundary(request, fallbackAbortableTasks, keyPath) { return { + status: PENDING, id: UNINITIALIZED_SUSPENSE_BOUNDARY_ID, rootSegmentID: -1, parentFlushed: false, pendingTasks: 0, - forceClientRender: false, completedSegments: [], byteSize: 0, fallbackAbortableTasks: fallbackAbortableTasks, errorDigest: null, - resources: createBoundaryResources() + resources: createBoundaryResources(), + keyPath: keyPath }; } @@ -10117,7 +10120,11 @@ function renderSuspenseBoundary(request, task, props) { var fallback = props.fallback; var content = props.children; var fallbackAbortSet = new Set(); - var newBoundary = createSuspenseBoundary(request, fallbackAbortSet); + var newBoundary = createSuspenseBoundary( + request, + fallbackAbortSet, + task.keyPath + ); var insertionIndex = parentSegment.chunks.length; // The children of the boundary segment is actually the fallback. var boundarySegment = createPendingSegment( @@ -10172,16 +10179,17 @@ function renderSuspenseBoundary(request, task, props) { contentRootSegment.status = COMPLETED; queueCompletedSegment(newBoundary, contentRootSegment); - if (newBoundary.pendingTasks === 0) { - // This must have been the last segment we were waiting on. This boundary is now complete. + if (newBoundary.pendingTasks === 0 && newBoundary.status === PENDING) { + newBoundary.status = COMPLETED; // This must have been the last segment we were waiting on. This boundary is now complete. // Therefore we won't need the fallback. We early return so that we don't have to create // the fallback. + popComponentStackInDEV(task); return; } } catch (error) { contentRootSegment.status = ERRORED; - newBoundary.forceClientRender = true; + newBoundary.status = CLIENT_RENDERED; var errorDigest; { @@ -11134,43 +11142,45 @@ function renderNode(request, task, node, childIndex) { // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. getSuspendedThenable() - : thrownValue; // $FlowFixMe[method-unbinding] + : thrownValue; - if (typeof x === "object" && x !== null && typeof x.then === "function") { - var wakeable = x; - var thenableState = getThenableStateAfterSuspending(); - spawnNewSuspendedTask(request, task, thenableState, wakeable); // 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. + if (typeof x === "object" && x !== null) { + // $FlowFixMe[method-unbinding] + if (typeof x.then === "function") { + var wakeable = x; + var thenableState = getThenableStateAfterSuspending(); + spawnNewSuspendedTask(request, task, thenableState, wakeable); // 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. - task.blockedSegment.formatContext = previousFormatContext; - task.legacyContext = previousLegacyContext; - task.context = previousContext; - task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. + task.blockedSegment.formatContext = previousFormatContext; + task.legacyContext = previousLegacyContext; + task.context = previousContext; + task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. - switchContext(previousContext); + switchContext(previousContext); - { - task.componentStack = previousComponentStack; + { + task.componentStack = previousComponentStack; + } + + return; } + } // 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. - return; - } else { - // 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. - task.blockedSegment.formatContext = previousFormatContext; - task.legacyContext = previousLegacyContext; - task.context = previousContext; - task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. + task.blockedSegment.formatContext = previousFormatContext; + task.legacyContext = previousLegacyContext; + task.context = previousContext; + task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. - switchContext(previousContext); + switchContext(previousContext); - { - task.componentStack = previousComponentStack; - } // We assume that we don't need the correct context. - // Let's terminate the rest of the tree and don't render any siblings. + { + task.componentStack = previousComponentStack; + } // We assume that we don't need the correct context. + // Let's terminate the rest of the tree and don't render any siblings. - throw x; - } + throw x; } } @@ -11187,8 +11197,8 @@ function erroredTask(request, boundary, segment, error) { } else { boundary.pendingTasks--; - if (!boundary.forceClientRender) { - boundary.forceClientRender = true; + if (boundary.status !== CLIENT_RENDERED) { + boundary.status = CLIENT_RENDERED; boundary.errorDigest = errorDigest; { @@ -11243,8 +11253,8 @@ function abortTask(task, request, error) { } else { boundary.pendingTasks--; - if (!boundary.forceClientRender) { - boundary.forceClientRender = true; + if (boundary.status !== CLIENT_RENDERED) { + boundary.status = CLIENT_RENDERED; boundary.errorDigest = request.onError(error); { @@ -11331,9 +11341,12 @@ function finishedTask(request, boundary, segment) { } else { boundary.pendingTasks--; - if (boundary.forceClientRender); + if (boundary.status === CLIENT_RENDERED); else if (boundary.pendingTasks === 0) { - // This must have been the last segment we were waiting on. This boundary is now complete. + if (boundary.status === PENDING) { + boundary.status = COMPLETED; + } // This must have been the last segment we were waiting on. This boundary is now complete. + if (segment.parentFlushed) { // Our parent segment already flushed, so we need to schedule this segment to be emitted. // If it is a segment that was aborted, we'll write other content instead so we don't need @@ -11444,18 +11457,23 @@ function retryTask(request, task) { // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. getSuspendedThenable() - : thrownValue; // $FlowFixMe[method-unbinding] + : thrownValue; - if (typeof x === "object" && x !== null && typeof x.then === "function") { - // Something suspended again, let's pick it back up later. - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); - } else { - task.abortSet.delete(task); - segment.status = ERRORED; - erroredTask(request, task.blockedBoundary, segment, x); + if (typeof x === "object" && x !== null) { + // $FlowFixMe[method-unbinding] + if (typeof x.then === "function") { + // Something suspended again, let's pick it back up later. + var ping = task.ping; + x.then(ping, ping); + task.thenableState = getThenableStateAfterSuspending(); + return; + } } + + task.abortSet.delete(task); + segment.status = ERRORED; + erroredTask(request, task.blockedBoundary, segment, x); + return; } finally { { setCurrentlyRenderingBoundaryResourcesTarget(request.renderState, null); @@ -11545,7 +11563,11 @@ function flushSubtree(request, destination, segment) { case PENDING: { // We're emitting a placeholder for this segment to be filled in later. // Therefore we'll need to assign it an ID - to refer to it by. - var segmentID = (segment.id = request.nextSegmentId++); // When this segment finally completes it won't be embedded in text since it will flush separately + segment.id = request.nextSegmentId++; // Fallthrough + } + + case POSTPONED: { + var segmentID = segment.id; // When this segment finally completes it won't be embedded in text since it will flush separately segment.lastPushedText = false; segment.textEmbedded = false; @@ -11599,7 +11621,7 @@ function flushSegment(request, destination, segment) { boundary.parentFlushed = true; // This segment is a Suspense boundary. We need to decide whether to // emit the content or the fallback now. - if (boundary.forceClientRender) { + if (boundary.status === CLIENT_RENDERED) { // Emit a client rendered suspense boundary wrapper. // We never queue the inner boundary so we'll never emit its content or partial segments. writeStartClientRenderedSuspenseBoundary( @@ -11615,9 +11637,15 @@ function flushSegment(request, destination, segment) { destination, request.renderState ); - } else if (boundary.pendingTasks > 0) { - // This boundary is still loading. Emit a pending suspense boundary wrapper. + } else if (boundary.status !== COMPLETED) { + if (boundary.status === PENDING) { + boundary.id = assignSuspenseBoundaryID( + request.renderState, + request.resumableState + ); + } // This boundary is still loading. Emit a pending suspense boundary wrapper. // Assign an ID to refer to the future content by. + boundary.rootSegmentID = request.nextSegmentId++; if (boundary.completedSegments.length > 0) { @@ -11625,10 +11653,7 @@ function flushSegment(request, destination, segment) { request.partialBoundaries.push(boundary); } /// This is the first time we should have referenced this ID. - var id = (boundary.id = assignSuspenseBoundaryID( - request.renderState, - request.resumableState - )); + var id = boundary.id; writeStartPendingSuspenseBoundary(destination, request.renderState, id); // Flush the fallback. flushSubtree(request, destination, segment); @@ -11924,7 +11949,11 @@ function flushCompletedQueues(request, destination) { request.flushScheduled = false; { - writePostamble(destination, request.resumableState); + // We write the trailing tags but only if don't have any data to resume. + // If we need to resume we'll write the postamble in the resume instead. + { + writePostamble(destination, request.resumableState); + } } { @@ -11940,7 +11969,7 @@ function flushCompletedQueues(request, destination) { } } -function startWork(request) { +function startRender(request) { request.flushScheduled = request.destination !== null; { @@ -12019,7 +12048,7 @@ function flushResources(request) { } function getResumableState(request) { return request.resumableState; -} // Returns the state of a postponed request or null if nothing was postponed. +} function onError() { // Non-fatal errors are ignored. @@ -12076,7 +12105,7 @@ function renderToStringImpl( undefined, undefined ); - startWork(request); // If anything suspended and is still pending, we'll abort it before writing. + startRender(request); // If anything suspended and is still pending, we'll abort it before writing. // That way we write only client-rendered boundaries from the start. abort(request, abortReason); diff --git a/compiled/facebook-www/ReactDOMServer-dev.modern.js b/compiled/facebook-www/ReactDOMServer-dev.modern.js index 5f94f24061..f0fc3bffae 100644 --- a/compiled/facebook-www/ReactDOMServer-dev.modern.js +++ b/compiled/facebook-www/ReactDOMServer-dev.modern.js @@ -19,7 +19,7 @@ if (__DEV__) { var React = require("react"); var ReactDOM = require("react-dom"); -var ReactVersion = "18.3.0-www-modern-a9c5f511"; +var ReactVersion = "18.3.0-www-modern-8d028b97"; // This refers to a WWW module. var warningWWW = require("warning"); @@ -9548,14 +9548,14 @@ function getStackByComponentStackNode(componentStack) { var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; var ReactCurrentCache = ReactSharedInternals.ReactCurrentCache; var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; // Linked list representing the identity of a component given the component/tag name and key. -// The name might be minified but we assume that it's going to be the same generated name. Typically -// because it's just the same compiled output in practice. +var CLIENT_RENDERED = 4; // if it errors or infinitely suspends var PENDING = 0; var COMPLETED = 1; var FLUSHED = 2; var ABORTED = 3; var ERRORED = 4; +var POSTPONED = 5; var OPEN = 0; var CLOSING = 1; var CLOSED = 2; // This is a default heuristic for how to split up the HTML content into progressive @@ -9605,6 +9605,7 @@ function createRequest( flushScheduled: false, resumableState: resumableState, renderState: renderState, + rootFormatContext: rootFormatContext, progressiveChunkSize: progressiveChunkSize === undefined ? DEFAULT_PROGRESSIVE_CHUNK_SIZE @@ -9620,6 +9621,7 @@ function createRequest( clientRenderedBoundaries: [], completedBoundaries: [], partialBoundaries: [], + trackedPostpones: null, onError: onError === undefined ? defaultErrorHandler : onError, onPostpone: onPostpone === undefined ? noop : onPostpone, onAllReady: onAllReady === undefined ? noop : onAllReady, @@ -9672,18 +9674,19 @@ function pingTask(request, task) { } } -function createSuspenseBoundary(request, fallbackAbortableTasks) { +function createSuspenseBoundary(request, fallbackAbortableTasks, keyPath) { return { + status: PENDING, id: UNINITIALIZED_SUSPENSE_BOUNDARY_ID, rootSegmentID: -1, parentFlushed: false, pendingTasks: 0, - forceClientRender: false, completedSegments: [], byteSize: 0, fallbackAbortableTasks: fallbackAbortableTasks, errorDigest: null, - resources: createBoundaryResources() + resources: createBoundaryResources(), + keyPath: keyPath }; } @@ -9876,7 +9879,11 @@ function renderSuspenseBoundary(request, task, props) { var fallback = props.fallback; var content = props.children; var fallbackAbortSet = new Set(); - var newBoundary = createSuspenseBoundary(request, fallbackAbortSet); + var newBoundary = createSuspenseBoundary( + request, + fallbackAbortSet, + task.keyPath + ); var insertionIndex = parentSegment.chunks.length; // The children of the boundary segment is actually the fallback. var boundarySegment = createPendingSegment( @@ -9931,16 +9938,17 @@ function renderSuspenseBoundary(request, task, props) { contentRootSegment.status = COMPLETED; queueCompletedSegment(newBoundary, contentRootSegment); - if (newBoundary.pendingTasks === 0) { - // This must have been the last segment we were waiting on. This boundary is now complete. + if (newBoundary.pendingTasks === 0 && newBoundary.status === PENDING) { + newBoundary.status = COMPLETED; // This must have been the last segment we were waiting on. This boundary is now complete. // Therefore we won't need the fallback. We early return so that we don't have to create // the fallback. + popComponentStackInDEV(task); return; } } catch (error) { contentRootSegment.status = ERRORED; - newBoundary.forceClientRender = true; + newBoundary.status = CLIENT_RENDERED; var errorDigest; { @@ -10882,43 +10890,45 @@ function renderNode(request, task, node, childIndex) { // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. getSuspendedThenable() - : thrownValue; // $FlowFixMe[method-unbinding] + : thrownValue; - if (typeof x === "object" && x !== null && typeof x.then === "function") { - var wakeable = x; - var thenableState = getThenableStateAfterSuspending(); - spawnNewSuspendedTask(request, task, thenableState, wakeable); // 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. + if (typeof x === "object" && x !== null) { + // $FlowFixMe[method-unbinding] + if (typeof x.then === "function") { + var wakeable = x; + var thenableState = getThenableStateAfterSuspending(); + spawnNewSuspendedTask(request, task, thenableState, wakeable); // 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. - task.blockedSegment.formatContext = previousFormatContext; - task.legacyContext = previousLegacyContext; - task.context = previousContext; - task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. + task.blockedSegment.formatContext = previousFormatContext; + task.legacyContext = previousLegacyContext; + task.context = previousContext; + task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. - switchContext(previousContext); + switchContext(previousContext); - { - task.componentStack = previousComponentStack; + { + task.componentStack = previousComponentStack; + } + + return; } + } // 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. - return; - } else { - // 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. - task.blockedSegment.formatContext = previousFormatContext; - task.legacyContext = previousLegacyContext; - task.context = previousContext; - task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. + task.blockedSegment.formatContext = previousFormatContext; + task.legacyContext = previousLegacyContext; + task.context = previousContext; + task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. - switchContext(previousContext); + switchContext(previousContext); - { - task.componentStack = previousComponentStack; - } // We assume that we don't need the correct context. - // Let's terminate the rest of the tree and don't render any siblings. + { + task.componentStack = previousComponentStack; + } // We assume that we don't need the correct context. + // Let's terminate the rest of the tree and don't render any siblings. - throw x; - } + throw x; } } @@ -10935,8 +10945,8 @@ function erroredTask(request, boundary, segment, error) { } else { boundary.pendingTasks--; - if (!boundary.forceClientRender) { - boundary.forceClientRender = true; + if (boundary.status !== CLIENT_RENDERED) { + boundary.status = CLIENT_RENDERED; boundary.errorDigest = errorDigest; { @@ -10991,8 +11001,8 @@ function abortTask(task, request, error) { } else { boundary.pendingTasks--; - if (!boundary.forceClientRender) { - boundary.forceClientRender = true; + if (boundary.status !== CLIENT_RENDERED) { + boundary.status = CLIENT_RENDERED; boundary.errorDigest = request.onError(error); { @@ -11079,9 +11089,12 @@ function finishedTask(request, boundary, segment) { } else { boundary.pendingTasks--; - if (boundary.forceClientRender); + if (boundary.status === CLIENT_RENDERED); else if (boundary.pendingTasks === 0) { - // This must have been the last segment we were waiting on. This boundary is now complete. + if (boundary.status === PENDING) { + boundary.status = COMPLETED; + } // This must have been the last segment we were waiting on. This boundary is now complete. + if (segment.parentFlushed) { // Our parent segment already flushed, so we need to schedule this segment to be emitted. // If it is a segment that was aborted, we'll write other content instead so we don't need @@ -11192,18 +11205,23 @@ function retryTask(request, task) { // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. getSuspendedThenable() - : thrownValue; // $FlowFixMe[method-unbinding] + : thrownValue; - if (typeof x === "object" && x !== null && typeof x.then === "function") { - // Something suspended again, let's pick it back up later. - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); - } else { - task.abortSet.delete(task); - segment.status = ERRORED; - erroredTask(request, task.blockedBoundary, segment, x); + if (typeof x === "object" && x !== null) { + // $FlowFixMe[method-unbinding] + if (typeof x.then === "function") { + // Something suspended again, let's pick it back up later. + var ping = task.ping; + x.then(ping, ping); + task.thenableState = getThenableStateAfterSuspending(); + return; + } } + + task.abortSet.delete(task); + segment.status = ERRORED; + erroredTask(request, task.blockedBoundary, segment, x); + return; } finally { { setCurrentlyRenderingBoundaryResourcesTarget(request.renderState, null); @@ -11293,7 +11311,11 @@ function flushSubtree(request, destination, segment) { case PENDING: { // We're emitting a placeholder for this segment to be filled in later. // Therefore we'll need to assign it an ID - to refer to it by. - var segmentID = (segment.id = request.nextSegmentId++); // When this segment finally completes it won't be embedded in text since it will flush separately + segment.id = request.nextSegmentId++; // Fallthrough + } + + case POSTPONED: { + var segmentID = segment.id; // When this segment finally completes it won't be embedded in text since it will flush separately segment.lastPushedText = false; segment.textEmbedded = false; @@ -11347,7 +11369,7 @@ function flushSegment(request, destination, segment) { boundary.parentFlushed = true; // This segment is a Suspense boundary. We need to decide whether to // emit the content or the fallback now. - if (boundary.forceClientRender) { + if (boundary.status === CLIENT_RENDERED) { // Emit a client rendered suspense boundary wrapper. // We never queue the inner boundary so we'll never emit its content or partial segments. writeStartClientRenderedSuspenseBoundary( @@ -11363,9 +11385,15 @@ function flushSegment(request, destination, segment) { destination, request.renderState ); - } else if (boundary.pendingTasks > 0) { - // This boundary is still loading. Emit a pending suspense boundary wrapper. + } else if (boundary.status !== COMPLETED) { + if (boundary.status === PENDING) { + boundary.id = assignSuspenseBoundaryID( + request.renderState, + request.resumableState + ); + } // This boundary is still loading. Emit a pending suspense boundary wrapper. // Assign an ID to refer to the future content by. + boundary.rootSegmentID = request.nextSegmentId++; if (boundary.completedSegments.length > 0) { @@ -11373,10 +11401,7 @@ function flushSegment(request, destination, segment) { request.partialBoundaries.push(boundary); } /// This is the first time we should have referenced this ID. - var id = (boundary.id = assignSuspenseBoundaryID( - request.renderState, - request.resumableState - )); + var id = boundary.id; writeStartPendingSuspenseBoundary(destination, request.renderState, id); // Flush the fallback. flushSubtree(request, destination, segment); @@ -11672,7 +11697,11 @@ function flushCompletedQueues(request, destination) { request.flushScheduled = false; { - writePostamble(destination, request.resumableState); + // We write the trailing tags but only if don't have any data to resume. + // If we need to resume we'll write the postamble in the resume instead. + { + writePostamble(destination, request.resumableState); + } } { @@ -11688,7 +11717,7 @@ function flushCompletedQueues(request, destination) { } } -function startWork(request) { +function startRender(request) { request.flushScheduled = request.destination !== null; { @@ -11767,7 +11796,7 @@ function flushResources(request) { } function getResumableState(request) { return request.resumableState; -} // Returns the state of a postponed request or null if nothing was postponed. +} function onError() { // Non-fatal errors are ignored. @@ -11824,7 +11853,7 @@ function renderToStringImpl( undefined, undefined ); - startWork(request); // If anything suspended and is still pending, we'll abort it before writing. + startRender(request); // If anything suspended and is still pending, we'll abort it before writing. // That way we write only client-rendered boundaries from the start. abort(request, abortReason); diff --git a/compiled/facebook-www/ReactDOMServer-prod.classic.js b/compiled/facebook-www/ReactDOMServer-prod.classic.js index ca2931ac41..9491b329ed 100644 --- a/compiled/facebook-www/ReactDOMServer-prod.classic.js +++ b/compiled/facebook-www/ReactDOMServer-prod.classic.js @@ -2925,6 +2925,7 @@ function createRequest( flushScheduled: !1, resumableState: resumableState, renderState: renderState, + rootFormatContext: rootFormatContext, progressiveChunkSize: void 0 === progressiveChunkSize ? 12800 : progressiveChunkSize, status: 0, @@ -2938,6 +2939,7 @@ function createRequest( clientRenderedBoundaries: [], completedBoundaries: [], partialBoundaries: [], + trackedPostpones: null, onError: void 0 === onError ? defaultErrorHandler : onError, onPostpone: void 0 === onPostpone ? noop : onPostpone, onAllReady: void 0 === onAllReady ? noop : onAllReady, @@ -3271,17 +3273,19 @@ function renderElement(request, task, prevThenableState, type, props, ref) { prevThenableState = props.fallback; props = props.children; ref = new Set(); + initialState = task.keyPath; initialState = { + status: 0, id: null, rootSegmentID: -1, parentFlushed: !1, pendingTasks: 0, - forceClientRender: !1, completedSegments: [], byteSize: 0, fallbackAbortableTasks: ref, errorDigest: null, - resources: new Set() + resources: new Set(), + keyPath: initialState }; contextType = createPendingSegment( request, @@ -3314,12 +3318,14 @@ function renderElement(request, task, prevThenableState, type, props, ref) { oldReplace.chunks.push("\x3c!-- --\x3e")), (oldReplace.status = 1), queueCompletedSegment(initialState, oldReplace), - 0 === initialState.pendingTasks) - ) + 0 === initialState.pendingTasks && 0 === initialState.status) + ) { + initialState.status = 1; break a; + } } catch (error) { (oldReplace.status = 4), - (initialState.forceClientRender = !0), + (initialState.status = 4), (JSCompiler_inline_result = logRecoverableError(request, error)), (initialState.errorDigest = JSCompiler_inline_result); } finally { @@ -3600,8 +3606,8 @@ function abortTask(task, request, error) { 2 !== request.status && (logRecoverableError(request, error), fatalError(request, error))) : (boundary.pendingTasks--, - boundary.forceClientRender || - ((boundary.forceClientRender = !0), + 4 !== boundary.status && + ((boundary.status = 4), (boundary.errorDigest = request.onError(error)), boundary.parentFlushed && request.clientRenderedBoundaries.push(boundary)), @@ -3638,9 +3644,10 @@ function finishedTask(request, boundary, segment) { boundary()); } else boundary.pendingTasks--, - boundary.forceClientRender || + 4 !== boundary.status && (0 === boundary.pendingTasks - ? (segment.parentFlushed && + ? (0 === boundary.status && (boundary.status = 1), + segment.parentFlushed && 1 === segment.status && queueCompletedSegment(boundary, segment), boundary.parentFlushed && @@ -3729,8 +3736,8 @@ function performWork(request$jscomp$1) { null === boundary ? fatalError(request$jscomp$0, error$jscomp$0) : (boundary.pendingTasks--, - boundary.forceClientRender || - ((boundary.forceClientRender = !0), + 4 !== boundary.status && + ((boundary.status = 4), (boundary.errorDigest = errorDigest), boundary.parentFlushed && request$jscomp$0.clientRenderedBoundaries.push( @@ -3766,7 +3773,9 @@ function flushSubtree(request, destination, segment) { segment.parentFlushed = !0; switch (segment.status) { case 0: - var segmentID = (segment.id = request.nextSegmentId++); + segment.id = request.nextSegmentId++; + case 5: + var segmentID = segment.id; segment.lastPushedText = !1; segment.textEmbedded = !1; request = request.renderState; @@ -3799,7 +3808,7 @@ function flushSegment(request, destination, segment) { var boundary = segment.boundary; if (null === boundary) return flushSubtree(request, destination, segment); boundary.parentFlushed = !0; - if (boundary.forceClientRender) + if (4 === boundary.status) return ( request.renderState.generateStaticMarkup || ((boundary = boundary.errorDigest), @@ -3817,19 +3826,21 @@ function flushSegment(request, destination, segment) { : destination.push("\x3c!--/$--\x3e")), request ); - if (0 < boundary.pendingTasks) { + if (1 !== boundary.status) { + if (0 === boundary.status) { + var JSCompiler_inline_result = request.renderState; + var generatedID = request.resumableState.nextSuspenseID++; + JSCompiler_inline_result = + JSCompiler_inline_result.boundaryPrefix + generatedID.toString(16); + boundary.id = JSCompiler_inline_result; + } boundary.rootSegmentID = request.nextSegmentId++; 0 < boundary.completedSegments.length && request.partialBoundaries.push(boundary); - var JSCompiler_inline_result = request.renderState; - var generatedID = request.resumableState.nextSuspenseID++; - JSCompiler_inline_result = - JSCompiler_inline_result.boundaryPrefix + generatedID.toString(16); - boundary = boundary.id = JSCompiler_inline_result; writeStartPendingSuspenseBoundary( destination, request.renderState, - boundary + boundary.id ); flushSubtree(request, destination, segment); return destination.push("\x3c!--/$--\x3e"); @@ -4415,4 +4426,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 = "18.3.0-www-classic-d7739767"; +exports.version = "18.3.0-www-classic-fde0e1c7"; diff --git a/compiled/facebook-www/ReactDOMServer-prod.modern.js b/compiled/facebook-www/ReactDOMServer-prod.modern.js index c65d4a698c..d9b80a3ccc 100644 --- a/compiled/facebook-www/ReactDOMServer-prod.modern.js +++ b/compiled/facebook-www/ReactDOMServer-prod.modern.js @@ -2917,6 +2917,7 @@ function createRequest( flushScheduled: !1, resumableState: resumableState, renderState: renderState, + rootFormatContext: rootFormatContext, progressiveChunkSize: void 0 === progressiveChunkSize ? 12800 : progressiveChunkSize, status: 0, @@ -2930,6 +2931,7 @@ function createRequest( clientRenderedBoundaries: [], completedBoundaries: [], partialBoundaries: [], + trackedPostpones: null, onError: void 0 === onError ? defaultErrorHandler : onError, onPostpone: void 0 === onPostpone ? noop : onPostpone, onAllReady: void 0 === onAllReady ? noop : onAllReady, @@ -3248,17 +3250,19 @@ function renderElement(request, task, prevThenableState, type, props, ref) { ref = props.fallback; props = props.children; contextType = new Set(); + partial = task.keyPath; partial = { + status: 0, id: null, rootSegmentID: -1, parentFlushed: !1, pendingTasks: 0, - forceClientRender: !1, completedSegments: [], byteSize: 0, fallbackAbortableTasks: contextType, errorDigest: null, - resources: new Set() + resources: new Set(), + keyPath: partial }; var boundarySegment = createPendingSegment( request, @@ -3291,12 +3295,14 @@ function renderElement(request, task, prevThenableState, type, props, ref) { contentRootSegment.chunks.push("\x3c!-- --\x3e")), (contentRootSegment.status = 1), queueCompletedSegment(partial, contentRootSegment), - 0 === partial.pendingTasks) - ) + 0 === partial.pendingTasks && 0 === partial.status) + ) { + partial.status = 1; break a; + } } catch (error) { (contentRootSegment.status = 4), - (partial.forceClientRender = !0), + (partial.status = 4), (JSCompiler_inline_result = logRecoverableError(request, error)), (partial.errorDigest = JSCompiler_inline_result); } finally { @@ -3583,8 +3589,8 @@ function abortTask(task, request, error) { 2 !== request.status && (logRecoverableError(request, error), fatalError(request, error))) : (boundary.pendingTasks--, - boundary.forceClientRender || - ((boundary.forceClientRender = !0), + 4 !== boundary.status && + ((boundary.status = 4), (boundary.errorDigest = request.onError(error)), boundary.parentFlushed && request.clientRenderedBoundaries.push(boundary)), @@ -3621,9 +3627,10 @@ function finishedTask(request, boundary, segment) { boundary()); } else boundary.pendingTasks--, - boundary.forceClientRender || + 4 !== boundary.status && (0 === boundary.pendingTasks - ? (segment.parentFlushed && + ? (0 === boundary.status && (boundary.status = 1), + segment.parentFlushed && 1 === segment.status && queueCompletedSegment(boundary, segment), boundary.parentFlushed && @@ -3712,8 +3719,8 @@ function performWork(request$jscomp$1) { null === boundary ? fatalError(request$jscomp$0, error$jscomp$0) : (boundary.pendingTasks--, - boundary.forceClientRender || - ((boundary.forceClientRender = !0), + 4 !== boundary.status && + ((boundary.status = 4), (boundary.errorDigest = errorDigest), boundary.parentFlushed && request$jscomp$0.clientRenderedBoundaries.push( @@ -3749,7 +3756,9 @@ function flushSubtree(request, destination, segment) { segment.parentFlushed = !0; switch (segment.status) { case 0: - var segmentID = (segment.id = request.nextSegmentId++); + segment.id = request.nextSegmentId++; + case 5: + var segmentID = segment.id; segment.lastPushedText = !1; segment.textEmbedded = !1; request = request.renderState; @@ -3782,7 +3791,7 @@ function flushSegment(request, destination, segment) { var boundary = segment.boundary; if (null === boundary) return flushSubtree(request, destination, segment); boundary.parentFlushed = !0; - if (boundary.forceClientRender) + if (4 === boundary.status) return ( request.renderState.generateStaticMarkup || ((boundary = boundary.errorDigest), @@ -3800,19 +3809,21 @@ function flushSegment(request, destination, segment) { : destination.push("\x3c!--/$--\x3e")), request ); - if (0 < boundary.pendingTasks) { + if (1 !== boundary.status) { + if (0 === boundary.status) { + var JSCompiler_inline_result = request.renderState; + var generatedID = request.resumableState.nextSuspenseID++; + JSCompiler_inline_result = + JSCompiler_inline_result.boundaryPrefix + generatedID.toString(16); + boundary.id = JSCompiler_inline_result; + } boundary.rootSegmentID = request.nextSegmentId++; 0 < boundary.completedSegments.length && request.partialBoundaries.push(boundary); - var JSCompiler_inline_result = request.renderState; - var generatedID = request.resumableState.nextSuspenseID++; - JSCompiler_inline_result = - JSCompiler_inline_result.boundaryPrefix + generatedID.toString(16); - boundary = boundary.id = JSCompiler_inline_result; writeStartPendingSuspenseBoundary( destination, request.renderState, - boundary + boundary.id ); flushSubtree(request, destination, segment); return destination.push("\x3c!--/$--\x3e"); @@ -4398,4 +4409,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 = "18.3.0-www-modern-eac21e34"; +exports.version = "18.3.0-www-modern-ec9c6ec0"; diff --git a/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js b/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js index afcf10b072..93445c7b39 100644 --- a/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js +++ b/compiled/facebook-www/ReactDOMServerStreaming-dev.modern.js @@ -9454,14 +9454,14 @@ function getStackByComponentStackNode(componentStack) { var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher; var ReactCurrentCache = ReactSharedInternals.ReactCurrentCache; var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame; // Linked list representing the identity of a component given the component/tag name and key. -// The name might be minified but we assume that it's going to be the same generated name. Typically -// because it's just the same compiled output in practice. +var CLIENT_RENDERED = 4; // if it errors or infinitely suspends var PENDING = 0; var COMPLETED = 1; var FLUSHED = 2; var ABORTED = 3; var ERRORED = 4; +var POSTPONED = 5; var OPEN = 0; var CLOSING = 1; var CLOSED = 2; // This is a default heuristic for how to split up the HTML content into progressive @@ -9511,6 +9511,7 @@ function createRequest( flushScheduled: false, resumableState: resumableState, renderState: renderState, + rootFormatContext: rootFormatContext, progressiveChunkSize: progressiveChunkSize === undefined ? DEFAULT_PROGRESSIVE_CHUNK_SIZE @@ -9526,6 +9527,7 @@ function createRequest( clientRenderedBoundaries: [], completedBoundaries: [], partialBoundaries: [], + trackedPostpones: null, onError: onError === undefined ? defaultErrorHandler : onError, onPostpone: onPostpone === undefined ? noop : onPostpone, onAllReady: onAllReady === undefined ? noop : onAllReady, @@ -9575,18 +9577,19 @@ function pingTask(request, task) { } } -function createSuspenseBoundary(request, fallbackAbortableTasks) { +function createSuspenseBoundary(request, fallbackAbortableTasks, keyPath) { return { + status: PENDING, id: UNINITIALIZED_SUSPENSE_BOUNDARY_ID, rootSegmentID: -1, parentFlushed: false, pendingTasks: 0, - forceClientRender: false, completedSegments: [], byteSize: 0, fallbackAbortableTasks: fallbackAbortableTasks, errorDigest: null, - resources: createBoundaryResources() + resources: createBoundaryResources(), + keyPath: keyPath }; } @@ -9779,7 +9782,11 @@ function renderSuspenseBoundary(request, task, props) { var fallback = props.fallback; var content = props.children; var fallbackAbortSet = new Set(); - var newBoundary = createSuspenseBoundary(request, fallbackAbortSet); + var newBoundary = createSuspenseBoundary( + request, + fallbackAbortSet, + task.keyPath + ); var insertionIndex = parentSegment.chunks.length; // The children of the boundary segment is actually the fallback. var boundarySegment = createPendingSegment( @@ -9834,16 +9841,17 @@ function renderSuspenseBoundary(request, task, props) { contentRootSegment.status = COMPLETED; queueCompletedSegment(newBoundary, contentRootSegment); - if (newBoundary.pendingTasks === 0) { - // This must have been the last segment we were waiting on. This boundary is now complete. + if (newBoundary.pendingTasks === 0 && newBoundary.status === PENDING) { + newBoundary.status = COMPLETED; // This must have been the last segment we were waiting on. This boundary is now complete. // Therefore we won't need the fallback. We early return so that we don't have to create // the fallback. + popComponentStackInDEV(task); return; } } catch (error) { contentRootSegment.status = ERRORED; - newBoundary.forceClientRender = true; + newBoundary.status = CLIENT_RENDERED; var errorDigest; { @@ -10785,43 +10793,45 @@ function renderNode(request, task, node, childIndex) { // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. getSuspendedThenable() - : thrownValue; // $FlowFixMe[method-unbinding] + : thrownValue; - if (typeof x === "object" && x !== null && typeof x.then === "function") { - var wakeable = x; - var thenableState = getThenableStateAfterSuspending(); - spawnNewSuspendedTask(request, task, thenableState, wakeable); // 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. + if (typeof x === "object" && x !== null) { + // $FlowFixMe[method-unbinding] + if (typeof x.then === "function") { + var wakeable = x; + var thenableState = getThenableStateAfterSuspending(); + spawnNewSuspendedTask(request, task, thenableState, wakeable); // 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. - task.blockedSegment.formatContext = previousFormatContext; - task.legacyContext = previousLegacyContext; - task.context = previousContext; - task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. + task.blockedSegment.formatContext = previousFormatContext; + task.legacyContext = previousLegacyContext; + task.context = previousContext; + task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. - switchContext(previousContext); + switchContext(previousContext); - { - task.componentStack = previousComponentStack; + { + task.componentStack = previousComponentStack; + } + + return; } + } // 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. - return; - } else { - // 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. - task.blockedSegment.formatContext = previousFormatContext; - task.legacyContext = previousLegacyContext; - task.context = previousContext; - task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. + task.blockedSegment.formatContext = previousFormatContext; + task.legacyContext = previousLegacyContext; + task.context = previousContext; + task.keyPath = previousKeyPath; // Restore all active ReactContexts to what they were before. - switchContext(previousContext); + switchContext(previousContext); - { - task.componentStack = previousComponentStack; - } // We assume that we don't need the correct context. - // Let's terminate the rest of the tree and don't render any siblings. + { + task.componentStack = previousComponentStack; + } // We assume that we don't need the correct context. + // Let's terminate the rest of the tree and don't render any siblings. - throw x; - } + throw x; } } @@ -10838,8 +10848,8 @@ function erroredTask(request, boundary, segment, error) { } else { boundary.pendingTasks--; - if (!boundary.forceClientRender) { - boundary.forceClientRender = true; + if (boundary.status !== CLIENT_RENDERED) { + boundary.status = CLIENT_RENDERED; boundary.errorDigest = errorDigest; { @@ -10894,8 +10904,8 @@ function abortTask(task, request, error) { } else { boundary.pendingTasks--; - if (!boundary.forceClientRender) { - boundary.forceClientRender = true; + if (boundary.status !== CLIENT_RENDERED) { + boundary.status = CLIENT_RENDERED; boundary.errorDigest = request.onError(error); { @@ -10982,9 +10992,12 @@ function finishedTask(request, boundary, segment) { } else { boundary.pendingTasks--; - if (boundary.forceClientRender); + if (boundary.status === CLIENT_RENDERED); else if (boundary.pendingTasks === 0) { - // This must have been the last segment we were waiting on. This boundary is now complete. + if (boundary.status === PENDING) { + boundary.status = COMPLETED; + } // This must have been the last segment we were waiting on. This boundary is now complete. + if (segment.parentFlushed) { // Our parent segment already flushed, so we need to schedule this segment to be emitted. // If it is a segment that was aborted, we'll write other content instead so we don't need @@ -11095,18 +11108,23 @@ function retryTask(request, task) { // (unstable) API for suspending. This implementation detail can change // later, once we deprecate the old API in favor of `use`. getSuspendedThenable() - : thrownValue; // $FlowFixMe[method-unbinding] + : thrownValue; - if (typeof x === "object" && x !== null && typeof x.then === "function") { - // Something suspended again, let's pick it back up later. - var ping = task.ping; - x.then(ping, ping); - task.thenableState = getThenableStateAfterSuspending(); - } else { - task.abortSet.delete(task); - segment.status = ERRORED; - erroredTask(request, task.blockedBoundary, segment, x); + if (typeof x === "object" && x !== null) { + // $FlowFixMe[method-unbinding] + if (typeof x.then === "function") { + // Something suspended again, let's pick it back up later. + var ping = task.ping; + x.then(ping, ping); + task.thenableState = getThenableStateAfterSuspending(); + return; + } } + + task.abortSet.delete(task); + segment.status = ERRORED; + erroredTask(request, task.blockedBoundary, segment, x); + return; } finally { { setCurrentlyRenderingBoundaryResourcesTarget(request.renderState, null); @@ -11196,7 +11214,11 @@ function flushSubtree(request, destination, segment) { case PENDING: { // We're emitting a placeholder for this segment to be filled in later. // Therefore we'll need to assign it an ID - to refer to it by. - var segmentID = (segment.id = request.nextSegmentId++); // When this segment finally completes it won't be embedded in text since it will flush separately + segment.id = request.nextSegmentId++; // Fallthrough + } + + case POSTPONED: { + var segmentID = segment.id; // When this segment finally completes it won't be embedded in text since it will flush separately segment.lastPushedText = false; segment.textEmbedded = false; @@ -11250,7 +11272,7 @@ function flushSegment(request, destination, segment) { boundary.parentFlushed = true; // This segment is a Suspense boundary. We need to decide whether to // emit the content or the fallback now. - if (boundary.forceClientRender) { + if (boundary.status === CLIENT_RENDERED) { // Emit a client rendered suspense boundary wrapper. // We never queue the inner boundary so we'll never emit its content or partial segments. writeStartClientRenderedSuspenseBoundary( @@ -11263,9 +11285,15 @@ function flushSegment(request, destination, segment) { flushSubtree(request, destination, segment); return writeEndClientRenderedSuspenseBoundary(destination); - } else if (boundary.pendingTasks > 0) { - // This boundary is still loading. Emit a pending suspense boundary wrapper. + } else if (boundary.status !== COMPLETED) { + if (boundary.status === PENDING) { + boundary.id = assignSuspenseBoundaryID( + request.renderState, + request.resumableState + ); + } // This boundary is still loading. Emit a pending suspense boundary wrapper. // Assign an ID to refer to the future content by. + boundary.rootSegmentID = request.nextSegmentId++; if (boundary.completedSegments.length > 0) { @@ -11273,10 +11301,7 @@ function flushSegment(request, destination, segment) { request.partialBoundaries.push(boundary); } /// This is the first time we should have referenced this ID. - var id = (boundary.id = assignSuspenseBoundaryID( - request.renderState, - request.resumableState - )); + var id = boundary.id; writeStartPendingSuspenseBoundary(destination, request.renderState, id); // Flush the fallback. flushSubtree(request, destination, segment); @@ -11572,7 +11597,11 @@ function flushCompletedQueues(request, destination) { request.flushScheduled = false; { - writePostamble(destination, request.resumableState); + // We write the trailing tags but only if don't have any data to resume. + // If we need to resume we'll write the postamble in the resume instead. + { + writePostamble(destination, request.resumableState); + } } { @@ -11588,7 +11617,7 @@ function flushCompletedQueues(request, destination) { } } -function startWork(request) { +function startRender(request) { request.flushScheduled = request.destination !== null; } @@ -11657,7 +11686,7 @@ function flushResources(request) { } function getResumableState(request) { return request.resumableState; -} // Returns the state of a postponed request or null if nothing was postponed. +} function renderToStream(children, options) { var destination = { @@ -11684,7 +11713,7 @@ function renderToStream(children, options) { undefined, undefined ); - startWork(request); + startRender(request); if (destination.fatal) { throw destination.error; diff --git a/compiled/facebook-www/ReactDOMServerStreaming-prod.modern.js b/compiled/facebook-www/ReactDOMServerStreaming-prod.modern.js index d93d9aa02f..b91d5c66e1 100644 --- a/compiled/facebook-www/ReactDOMServerStreaming-prod.modern.js +++ b/compiled/facebook-www/ReactDOMServerStreaming-prod.modern.js @@ -3048,17 +3048,19 @@ function renderElement(request, task, prevThenableState, type, props, ref) { ref = props.fallback; props = props.children; contextType = new Set(); + partial = task.keyPath; partial = { + status: 0, id: null, rootSegmentID: -1, parentFlushed: !1, pendingTasks: 0, - forceClientRender: !1, completedSegments: [], byteSize: 0, fallbackAbortableTasks: contextType, errorDigest: null, - resources: new Set() + resources: new Set(), + keyPath: partial }; var boundarySegment = createPendingSegment( request, @@ -3090,12 +3092,14 @@ function renderElement(request, task, prevThenableState, type, props, ref) { contentRootSegment.chunks.push("\x3c!-- --\x3e"), (contentRootSegment.status = 1), queueCompletedSegment(partial, contentRootSegment), - 0 === partial.pendingTasks) - ) + 0 === partial.pendingTasks && 0 === partial.status) + ) { + partial.status = 1; break a; + } } catch (error) { (contentRootSegment.status = 4), - (partial.forceClientRender = !0), + (partial.status = 4), (JSCompiler_inline_result = logRecoverableError(request, error)), (partial.errorDigest = JSCompiler_inline_result); } finally { @@ -3387,8 +3391,8 @@ function abortTask(task, request, error) { 2 !== request.status && (logRecoverableError(request, error), fatalError(request, error))) : (boundary.pendingTasks--, - boundary.forceClientRender || - ((boundary.forceClientRender = !0), + 4 !== boundary.status && + ((boundary.status = 4), (boundary.errorDigest = request.onError(error)), boundary.parentFlushed && request.clientRenderedBoundaries.push(boundary)), @@ -3427,9 +3431,10 @@ function finishedTask(request, boundary, segment) { boundary()); } else boundary.pendingTasks--, - boundary.forceClientRender || + 4 !== boundary.status && (0 === boundary.pendingTasks - ? (segment.parentFlushed && + ? (0 === boundary.status && (boundary.status = 1), + segment.parentFlushed && 1 === segment.status && queueCompletedSegment(boundary, segment), boundary.parentFlushed && @@ -3449,7 +3454,9 @@ function flushSubtree(request, destination, segment) { segment.parentFlushed = !0; switch (segment.status) { case 0: - var segmentID = (segment.id = request.nextSegmentId++); + segment.id = request.nextSegmentId++; + case 5: + var segmentID = segment.id; segment.lastPushedText = !1; segment.textEmbedded = !1; request = request.renderState; @@ -3484,7 +3491,7 @@ function flushSegment(request, destination, segment) { var boundary = segment.boundary; if (null === boundary) return flushSubtree(request, destination, segment); boundary.parentFlushed = !0; - if (boundary.forceClientRender) + if (4 === boundary.status) (boundary = boundary.errorDigest), writeChunkAndReturn(destination, "\x3c!--$!--\x3e"), writeChunk(destination, ""), flushSubtree(request, destination, segment); - else if (0 < boundary.pendingTasks) { + else if (1 !== boundary.status) { + if (0 === boundary.status) { + var JSCompiler_inline_result = request.renderState; + var generatedID = request.resumableState.nextSuspenseID++; + JSCompiler_inline_result = + JSCompiler_inline_result.boundaryPrefix + generatedID.toString(16); + boundary.id = JSCompiler_inline_result; + } boundary.rootSegmentID = request.nextSegmentId++; 0 < boundary.completedSegments.length && request.partialBoundaries.push(boundary); - var JSCompiler_inline_result = request.renderState; - var generatedID = request.resumableState.nextSuspenseID++; - JSCompiler_inline_result = - JSCompiler_inline_result.boundaryPrefix + generatedID.toString(16); - boundary = boundary.id = JSCompiler_inline_result; writeStartPendingSuspenseBoundary( destination, request.renderState, - boundary + boundary.id ); flushSubtree(request, destination, segment); } else if (boundary.byteSize > request.progressiveChunkSize) @@ -4100,8 +4109,8 @@ exports.renderNextChunk = function (stream) { null === boundary ? fatalError(request, error$jscomp$0) : (boundary.pendingTasks--, - boundary.forceClientRender || - ((boundary.forceClientRender = !0), + 4 !== boundary.status && + ((boundary.status = 4), (boundary.errorDigest = errorDigest), boundary.parentFlushed && request.clientRenderedBoundaries.push(boundary))); @@ -4342,6 +4351,7 @@ exports.renderToStream = function (children, options) { flushScheduled: !1, resumableState: bootstrapScriptContent, renderState: bootstrapScripts, + rootFormatContext: bootstrapModules, progressiveChunkSize: void 0 === externalRuntimeConfig ? 12800 : externalRuntimeConfig, status: 0, @@ -4355,6 +4365,7 @@ exports.renderToStream = function (children, options) { clientRenderedBoundaries: [], completedBoundaries: [], partialBoundaries: [], + trackedPostpones: null, onError: void 0 === idPrefix ? defaultErrorHandler : idPrefix, onPostpone: noop, onAllReady: noop,