diff --git a/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js b/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js index 71631f9573086..44df0fb2deecc 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerBrowser.js @@ -16,7 +16,8 @@ import ReactVersion from 'shared/ReactVersion'; import { createRequest, - startRender, + resumeRequest, + startWork, startFlowing, abort, } from 'react-server/src/ReactFizzServer'; @@ -129,7 +130,7 @@ function renderToReadableStream( signal.addEventListener('abort', listener); } } - startRender(request); + startWork(request); }); } @@ -171,16 +172,14 @@ function resume( allReady.catch(() => {}); reject(error); } - const request = createRequest( + const request = resumeRequest( children, - postponedState.resumableState, + postponedState, createRenderState( postponedState.resumableState, options ? options.nonce : undefined, undefined, // importMap ), - postponedState.rootFormatContext, - postponedState.progressiveChunkSize, options ? options.onError : undefined, onAllReady, onShellReady, @@ -200,7 +199,7 @@ function resume( signal.addEventListener('abort', listener); } } - startRender(request); + startWork(request); }); } diff --git a/packages/react-dom/src/server/ReactDOMFizzServerBun.js b/packages/react-dom/src/server/ReactDOMFizzServerBun.js index 4464b95551271..997934e1a3d1a 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerBun.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerBun.js @@ -15,7 +15,7 @@ import ReactVersion from 'shared/ReactVersion'; import { createRequest, - startRender, + startWork, startFlowing, abort, } from 'react-server/src/ReactFizzServer'; @@ -121,7 +121,7 @@ function renderToReadableStream( signal.addEventListener('abort', listener); } } - startRender(request); + startWork(request); }); } diff --git a/packages/react-dom/src/server/ReactDOMFizzServerEdge.js b/packages/react-dom/src/server/ReactDOMFizzServerEdge.js index 71631f9573086..44df0fb2deecc 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerEdge.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerEdge.js @@ -16,7 +16,8 @@ import ReactVersion from 'shared/ReactVersion'; import { createRequest, - startRender, + resumeRequest, + startWork, startFlowing, abort, } from 'react-server/src/ReactFizzServer'; @@ -129,7 +130,7 @@ function renderToReadableStream( signal.addEventListener('abort', listener); } } - startRender(request); + startWork(request); }); } @@ -171,16 +172,14 @@ function resume( allReady.catch(() => {}); reject(error); } - const request = createRequest( + const request = resumeRequest( children, - postponedState.resumableState, + postponedState, createRenderState( postponedState.resumableState, options ? options.nonce : undefined, undefined, // importMap ), - postponedState.rootFormatContext, - postponedState.progressiveChunkSize, options ? options.onError : undefined, onAllReady, onShellReady, @@ -200,7 +199,7 @@ function resume( signal.addEventListener('abort', listener); } } - startRender(request); + startWork(request); }); } diff --git a/packages/react-dom/src/server/ReactDOMFizzServerNode.js b/packages/react-dom/src/server/ReactDOMFizzServerNode.js index c948d4f3996d8..c7de8e073e16e 100644 --- a/packages/react-dom/src/server/ReactDOMFizzServerNode.js +++ b/packages/react-dom/src/server/ReactDOMFizzServerNode.js @@ -18,7 +18,8 @@ import ReactVersion from 'shared/ReactVersion'; import { createRequest, - startRender, + resumeRequest, + startWork, startFlowing, abort, } from 'react-server/src/ReactFizzServer'; @@ -105,7 +106,7 @@ function renderToPipeableStream( ): PipeableStream { const request = createRequestImpl(children, options); let hasStartedFlowing = false; - startRender(request); + startWork(request); return { pipe(destination: T): T { if (hasStartedFlowing) { @@ -140,16 +141,14 @@ function resumeRequestImpl( postponedState: PostponedState, options: void | ResumeOptions, ) { - return createRequest( + return resumeRequest( children, - postponedState.resumableState, + postponedState, createRenderState( postponedState.resumableState, options ? options.nonce : undefined, undefined, // importMap ), - postponedState.rootFormatContext, - postponedState.progressiveChunkSize, options ? options.onError : undefined, options ? options.onAllReady : undefined, options ? options.onShellReady : undefined, @@ -166,7 +165,7 @@ function resumeToPipeableStream( ): PipeableStream { const request = resumeRequestImpl(children, postponedState, options); let hasStartedFlowing = false; - startRender(request); + startWork(request); return { pipe(destination: T): T { if (hasStartedFlowing) { diff --git a/packages/react-dom/src/server/ReactDOMFizzStaticBrowser.js b/packages/react-dom/src/server/ReactDOMFizzStaticBrowser.js index 64c5cf4ae28fd..fe61a1ba271a0 100644 --- a/packages/react-dom/src/server/ReactDOMFizzStaticBrowser.js +++ b/packages/react-dom/src/server/ReactDOMFizzStaticBrowser.js @@ -15,8 +15,8 @@ import type {ImportMap} from '../shared/ReactDOMTypes'; import ReactVersion from 'shared/ReactVersion'; import { - createRequest, - startPrerender, + createPrerenderRequest, + startWork, startFlowing, abort, getPostponedState, @@ -80,7 +80,7 @@ function prerender( options ? options.bootstrapModules : undefined, options ? options.unstable_externalRuntimeSrc : undefined, ); - const request = createRequest( + const request = createPrerenderRequest( children, resources, createRenderState( @@ -109,7 +109,7 @@ function prerender( signal.addEventListener('abort', listener); } } - startPrerender(request); + startWork(request); }); } diff --git a/packages/react-dom/src/server/ReactDOMFizzStaticEdge.js b/packages/react-dom/src/server/ReactDOMFizzStaticEdge.js index 64c5cf4ae28fd..fe61a1ba271a0 100644 --- a/packages/react-dom/src/server/ReactDOMFizzStaticEdge.js +++ b/packages/react-dom/src/server/ReactDOMFizzStaticEdge.js @@ -15,8 +15,8 @@ import type {ImportMap} from '../shared/ReactDOMTypes'; import ReactVersion from 'shared/ReactVersion'; import { - createRequest, - startPrerender, + createPrerenderRequest, + startWork, startFlowing, abort, getPostponedState, @@ -80,7 +80,7 @@ function prerender( options ? options.bootstrapModules : undefined, options ? options.unstable_externalRuntimeSrc : undefined, ); - const request = createRequest( + const request = createPrerenderRequest( children, resources, createRenderState( @@ -109,7 +109,7 @@ function prerender( signal.addEventListener('abort', listener); } } - startPrerender(request); + startWork(request); }); } diff --git a/packages/react-dom/src/server/ReactDOMFizzStaticNode.js b/packages/react-dom/src/server/ReactDOMFizzStaticNode.js index ee138ef5a3f6b..4c6260ca920f7 100644 --- a/packages/react-dom/src/server/ReactDOMFizzStaticNode.js +++ b/packages/react-dom/src/server/ReactDOMFizzStaticNode.js @@ -17,8 +17,8 @@ import {Writable, Readable} from 'stream'; import ReactVersion from 'shared/ReactVersion'; import { - createRequest, - startPrerender, + createPrerenderRequest, + startWork, startFlowing, abort, getPostponedState, @@ -94,7 +94,7 @@ function prerenderToNodeStream( options ? options.bootstrapModules : undefined, options ? options.unstable_externalRuntimeSrc : undefined, ); - const request = createRequest( + const request = createPrerenderRequest( children, resumableState, createRenderState( @@ -123,7 +123,7 @@ function prerenderToNodeStream( signal.addEventListener('abort', listener); } } - startPrerender(request); + startWork(request); }); } diff --git a/packages/react-dom/src/server/ReactDOMLegacyServerImpl.js b/packages/react-dom/src/server/ReactDOMLegacyServerImpl.js index 24a61cb40f68f..b08b51de19890 100644 --- a/packages/react-dom/src/server/ReactDOMLegacyServerImpl.js +++ b/packages/react-dom/src/server/ReactDOMLegacyServerImpl.js @@ -13,7 +13,7 @@ import type {ReactNodeList} from 'shared/ReactTypes'; import { createRequest, - startRender, + startWork, startFlowing, abort, } from 'react-server/src/ReactFizzServer'; @@ -81,7 +81,7 @@ function renderToStringImpl( undefined, undefined, ); - startRender(request); + startWork(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/packages/react-dom/src/server/ReactDOMLegacyServerNodeStream.js b/packages/react-dom/src/server/ReactDOMLegacyServerNodeStream.js index d01b063bc421f..a3e39def4ef4c 100644 --- a/packages/react-dom/src/server/ReactDOMLegacyServerNodeStream.js +++ b/packages/react-dom/src/server/ReactDOMLegacyServerNodeStream.js @@ -13,7 +13,7 @@ import type {Request} from 'react-server/src/ReactFizzServer'; import { createRequest, - startRender, + startWork, startFlowing, abort, } from 'react-server/src/ReactFizzServer'; @@ -92,7 +92,7 @@ function renderToNodeStreamImpl( undefined, ); destination.request = request; - startRender(request); + startWork(request); return destination; } diff --git a/packages/react-noop-renderer/src/ReactNoopFlightServer.js b/packages/react-noop-renderer/src/ReactNoopFlightServer.js index 560305d539f71..9faab3cdfa110 100644 --- a/packages/react-noop-renderer/src/ReactNoopFlightServer.js +++ b/packages/react-noop-renderer/src/ReactNoopFlightServer.js @@ -84,7 +84,7 @@ function render(model: ReactClientValue, options?: Options): Destination { options ? options.context : undefined, options ? options.identifierPrefix : undefined, ); - ReactNoopFlightServer.startRender(request); + ReactNoopFlightServer.startWork(request); ReactNoopFlightServer.startFlowing(request, destination); return destination; } diff --git a/packages/react-noop-renderer/src/ReactNoopServer.js b/packages/react-noop-renderer/src/ReactNoopServer.js index 44c9559d1ad56..34a2dac5592a2 100644 --- a/packages/react-noop-renderer/src/ReactNoopServer.js +++ b/packages/react-noop-renderer/src/ReactNoopServer.js @@ -304,7 +304,7 @@ function render(children: React$Element, options?: Options): Destination { options ? options.onAllReady : undefined, options ? options.onShellReady : undefined, ); - ReactNoopServer.startRender(request); + ReactNoopServer.startWork(request); ReactNoopServer.startFlowing(request, destination); return destination; } diff --git a/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js b/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js index 4d44fa01a3821..def3a58478e57 100644 --- a/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-esm/src/ReactFlightDOMServerNode.js @@ -20,7 +20,7 @@ import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; import { createRequest, - startRender, + startWork, startFlowing, abort, } from 'react-server/src/ReactFlightServer'; @@ -73,7 +73,7 @@ function renderToPipeableStream( options ? options.onPostpone : undefined, ); let hasStartedFlowing = false; - startRender(request); + startWork(request); return { pipe(destination: T): T { if (hasStartedFlowing) { diff --git a/packages/react-server-dom-fb/src/ReactDOMServerFB.js b/packages/react-server-dom-fb/src/ReactDOMServerFB.js index 91c99cead07c5..eec7404055e26 100644 --- a/packages/react-server-dom-fb/src/ReactDOMServerFB.js +++ b/packages/react-server-dom-fb/src/ReactDOMServerFB.js @@ -16,7 +16,7 @@ import type {BootstrapScriptDescriptor} from 'react-dom-bindings/src/server/Reac import { createRequest, - startRender, + startWork, performWork, startFlowing, abort, @@ -68,7 +68,7 @@ function renderToStream(children: ReactNodeList, options: Options): Stream { undefined, undefined, ); - startRender(request); + startWork(request); if (destination.fatal) { throw destination.error; } diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js b/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js index b445a4be15323..08214a4182ab2 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMServerBrowser.js @@ -14,7 +14,7 @@ import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import { createRequest, - startRender, + startWork, startFlowing, abort, } from 'react-server/src/ReactFlightServer'; @@ -70,7 +70,7 @@ function renderToReadableStream( { type: 'bytes', start: (controller): ?Promise => { - startRender(request); + startWork(request); }, pull: (controller): ?Promise => { startFlowing(request, controller); diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js b/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js index b445a4be15323..08214a4182ab2 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMServerEdge.js @@ -14,7 +14,7 @@ import type {ServerManifest} from 'react-client/src/ReactFlightClientConfig'; import { createRequest, - startRender, + startWork, startFlowing, abort, } from 'react-server/src/ReactFlightServer'; @@ -70,7 +70,7 @@ function renderToReadableStream( { type: 'bytes', start: (controller): ?Promise => { - startRender(request); + startWork(request); }, pull: (controller): ?Promise => { startFlowing(request, controller); diff --git a/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js b/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js index 17dd769cdecb8..1e39d000ffef4 100644 --- a/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js +++ b/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js @@ -20,7 +20,7 @@ import type {ServerContextJSONValue, Thenable} from 'shared/ReactTypes'; import { createRequest, - startRender, + startWork, startFlowing, abort, } from 'react-server/src/ReactFlightServer'; @@ -74,7 +74,7 @@ function renderToPipeableStream( options ? options.onPostpone : undefined, ); let hasStartedFlowing = false; - startRender(request); + startWork(request); return { pipe(destination: T): T { if (hasStartedFlowing) { diff --git a/packages/react-server/src/ReactFizzServer.js b/packages/react-server/src/ReactFizzServer.js index a188e9807373d..4d01fc3504d7d 100644 --- a/packages/react-server/src/ReactFizzServer.js +++ b/packages/react-server/src/ReactFizzServer.js @@ -396,6 +396,106 @@ export function createRequest( return request; } +export function createPrerenderRequest( + children: ReactNodeList, + resumableState: ResumableState, + renderState: RenderState, + rootFormatContext: FormatContext, + progressiveChunkSize: void | number, + onError: void | ((error: mixed) => ?string), + onAllReady: void | (() => void), + onShellReady: void | (() => void), + onShellError: void | ((error: mixed) => void), + onFatalError: void | ((error: mixed) => void), + onPostpone: void | ((reason: string) => void), +): Request { + const request = createRequest( + children, + resumableState, + renderState, + rootFormatContext, + progressiveChunkSize, + onError, + onAllReady, + onShellReady, + onShellError, + onFatalError, + onPostpone, + ); + // Start tracking postponed holes during this render. + request.trackedPostpones = {workingMap: new Map(), root: []}; + return request; +} + +export function resumeRequest( + children: ReactNodeList, + postponedState: PostponedState, + renderState: RenderState, + onError: void | ((error: mixed) => ?string), + onAllReady: void | (() => void), + onShellReady: void | (() => void), + onShellError: void | ((error: mixed) => void), + onFatalError: void | ((error: mixed) => void), + onPostpone: void | ((reason: string) => void), +): Request { + prepareHostDispatcher(); + const pingedTasks: Array = []; + const abortSet: Set = new Set(); + const request: Request = { + destination: null, + flushScheduled: false, + resumableState: postponedState.resumableState, + renderState, + rootFormatContext: postponedState.rootFormatContext, + progressiveChunkSize: postponedState.progressiveChunkSize, + status: OPEN, + fatalError: null, + nextSegmentId: 0, + allPendingTasks: 0, + pendingRootTasks: 0, + completedRootSegment: null, + abortableTasks: abortSet, + pingedTasks: pingedTasks, + clientRenderedBoundaries: ([]: Array), + completedBoundaries: ([]: Array), + partialBoundaries: ([]: Array), + trackedPostpones: null, + onError: onError === undefined ? defaultErrorHandler : onError, + onPostpone: onPostpone === undefined ? noop : onPostpone, + onAllReady: onAllReady === undefined ? noop : onAllReady, + onShellReady: onShellReady === undefined ? noop : onShellReady, + onShellError: onShellError === undefined ? noop : onShellError, + onFatalError: onFatalError === undefined ? noop : onFatalError, + }; + // This segment represents the root fallback. + const rootSegment = createPendingSegment( + request, + 0, + null, + postponedState.rootFormatContext, + // Root segments are never embedded in Text on either edge + false, + false, + ); + // There is no parent so conceptually, we're unblocked to flush this segment. + rootSegment.parentFlushed = true; + const rootTask = createTask( + request, + null, + children, + null, + rootSegment, + abortSet, + null, + postponedState.rootFormatContext, + emptyContextObject, + rootContextSnapshot, + emptyTreeContext, + ); + pingedTasks.push(rootTask); + return request; +} + let currentRequest: null | Request = null; export function resolveRequest(): null | Request { @@ -2751,7 +2851,7 @@ function flushCompletedQueues( } } -export function startRender(request: Request): void { +export function startWork(request: Request): void { request.flushScheduled = request.destination !== null; if (supportsRequestStorage) { scheduleWork(() => requestStorage.run(request, performWork, request)); @@ -2760,12 +2860,6 @@ export function startRender(request: Request): void { } } -export function startPrerender(request: Request): void { - // Start tracking postponed holes during this render. - request.trackedPostpones = {workingMap: new Map(), root: []}; - startRender(request); -} - function enqueueFlush(request: Request): void { if ( request.flushScheduled === false && diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index 515b6aa870613..cb62cd0cb1f40 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -1519,7 +1519,7 @@ function flushCompletedChunks( } } -export function startRender(request: Request): void { +export function startWork(request: Request): void { request.flushScheduled = request.destination !== null; if (supportsRequestStorage) { scheduleWork(() => requestStorage.run(request, performWork, request));