Ship partial-prerendering APIs to Canary (#34633)

This commit is contained in:
Sebastian "Sebbie" Silbermann 2025-10-01 18:22:30 +02:00 committed by GitHub
parent 548235db10
commit 1bd1f01f2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
56 changed files with 233 additions and 253 deletions

View File

@ -133,7 +133,7 @@ async function renderApp(res, returnValue, formState, noCache, debugChannel) {
}
async function prerenderApp(res, returnValue, formState, noCache) {
const {unstable_prerenderToNodeStream: prerenderToNodeStream} = await import(
const {prerenderToNodeStream} = await import(
'react-server-dom-webpack/static'
);
// const m = require('../src/App.js');

View File

@ -13,6 +13,4 @@ exports.version = l.version;
exports.renderToString = l.renderToString;
exports.renderToStaticMarkup = l.renderToStaticMarkup;
exports.renderToReadableStream = s.renderToReadableStream;
if (s.resume) {
exports.resume = s.resume;
}
exports.resume = s.resume;

View File

@ -12,8 +12,6 @@ if (process.env.NODE_ENV === 'production') {
exports.version = b.version;
exports.renderToReadableStream = b.renderToReadableStream;
if (b.resume) {
exports.resume = b.resume;
}
exports.resume = b.resume;
exports.renderToString = l.renderToString;
exports.renderToStaticMarkup = l.renderToStaticMarkup;

View File

@ -14,6 +14,4 @@ exports.version = b.version;
exports.renderToReadableStream = b.renderToReadableStream;
exports.renderToString = l.renderToString;
exports.renderToStaticMarkup = l.renderToStaticMarkup;
if (b.resume) {
exports.resume = b.resume;
}
exports.resume = b.resume;

View File

@ -14,9 +14,5 @@ exports.renderToString = l.renderToString;
exports.renderToStaticMarkup = l.renderToStaticMarkup;
exports.renderToPipeableStream = s.renderToPipeableStream;
exports.renderToReadableStream = s.renderToReadableStream;
if (s.resumeToPipeableStream) {
exports.resumeToPipeableStream = s.resumeToPipeableStream;
}
if (s.resume) {
exports.resume = s.resume;
}
exports.resumeToPipeableStream = s.resumeToPipeableStream;
exports.resume = s.resume;

View File

@ -416,7 +416,11 @@ describe('ReactDOMFizzStatic', () => {
return <div>aborted</div>;
}
const errors = [];
const pendingResult = ReactDOMFizzStatic.prerenderToNodeStream(<App />, {
onError: error => {
errors.push(error);
},
signal: controller.signal,
});
pendingResult.catch(() => {});
@ -430,6 +434,7 @@ describe('ReactDOMFizzStatic', () => {
result.prelude.pipe(writable);
});
expect(getVisibleChildren(container)).toEqual(undefined);
expect(errors).toEqual([]);
});
// @gate enablePostpone
@ -447,13 +452,18 @@ describe('ReactDOMFizzStatic', () => {
return <div>aborted</div>;
}
const errors = [];
const result = await ReactDOMFizzStatic.prerenderToNodeStream(<App />, {
onError: error => {
errors.push(error);
},
signal: controller.signal,
});
await act(async () => {
result.prelude.pipe(writable);
});
expect(getVisibleChildren(container)).toEqual(undefined);
expect(errors).toEqual([]);
});
// @gate enableHalt

View File

@ -40,9 +40,7 @@ describe('ReactDOMFizzStaticFloat', () => {
React = require('react');
ReactDOM = require('react-dom');
ReactDOMFizzServer = require('react-dom/server.browser');
if (__EXPERIMENTAL__) {
ReactDOMFizzStatic = require('react-dom/static.browser');
}
Suspense = React.Suspense;
container = document.createElement('div');
document.body.appendChild(container);

View File

@ -18,9 +18,7 @@ describe('ReactDOMFizzStaticNode', () => {
beforeEach(() => {
jest.resetModules();
React = require('react');
if (__EXPERIMENTAL__) {
ReactDOMFizzStatic = require('react-dom/static');
}
Suspense = React.Suspense;
});
@ -58,7 +56,7 @@ describe('ReactDOMFizzStaticNode', () => {
}
}
// @gate experimental
// @gate enableHalt || enablePostpone
it('should call prerenderToNodeStream', async () => {
const result = await ReactDOMFizzStatic.prerenderToNodeStream(
<div>hello world</div>,
@ -67,14 +65,14 @@ describe('ReactDOMFizzStaticNode', () => {
expect(prelude).toMatchInlineSnapshot(`"<div>hello world</div>"`);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should suppport web streams', async () => {
const result = await ReactDOMFizzStatic.prerender(<div>hello world</div>);
const prelude = await readContentWeb(result.prelude);
expect(prelude).toMatchInlineSnapshot(`"<div>hello world</div>"`);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should emit DOCTYPE at the root of the document', async () => {
const result = await ReactDOMFizzStatic.prerenderToNodeStream(
<html>
@ -93,7 +91,7 @@ describe('ReactDOMFizzStaticNode', () => {
}
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should emit bootstrap script src at the end', async () => {
const result = await ReactDOMFizzStatic.prerenderToNodeStream(
<div>hello world</div>,
@ -109,7 +107,7 @@ describe('ReactDOMFizzStaticNode', () => {
);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('emits all HTML as one unit', async () => {
let hasLoaded = false;
let resolve;
@ -139,7 +137,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(prelude).toMatchInlineSnapshot(`"<div><!--$-->Done<!--/$--></div>"`);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should reject the promise when an error is thrown at the root', async () => {
const reportedErrors = [];
let caughtError = null;
@ -161,7 +159,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(reportedErrors).toEqual([theError]);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should reject the promise when an error is thrown inside a fallback', async () => {
const reportedErrors = [];
let caughtError = null;
@ -185,7 +183,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(reportedErrors).toEqual([theError]);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should not error the stream when an error is thrown inside suspense boundary', async () => {
const reportedErrors = [];
const result = await ReactDOMFizzStatic.prerenderToNodeStream(
@ -206,7 +204,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(reportedErrors).toEqual([theError]);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should be able to complete by aborting even if the promise never resolves', async () => {
const errors = [];
const controller = new AbortController();
@ -236,7 +234,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(errors).toEqual(['This operation was aborted']);
});
// @gate experimental
// @gate enableHalt || enablePostpone
// @gate !enableHalt
it('should reject if aborting before the shell is complete and enableHalt is disabled', async () => {
const errors = [];
@ -302,7 +300,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(content).toBe('');
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('should be able to abort before something suspends', async () => {
const errors = [];
const controller = new AbortController();
@ -343,7 +341,7 @@ describe('ReactDOMFizzStaticNode', () => {
}
});
// @gate experimental
// @gate enableHalt || enablePostpone
// @gate !enableHalt
it('should reject if passing an already aborted signal and enableHalt is disabled', async () => {
const errors = [];
@ -414,7 +412,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(content).toBe('');
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('supports custom abort reasons with a string', async () => {
const promise = new Promise(r => {});
function Wait() {
@ -456,7 +454,7 @@ describe('ReactDOMFizzStaticNode', () => {
expect(errors).toEqual(['foobar', 'foobar']);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('supports custom abort reasons with an Error', async () => {
const promise = new Promise(r => {});
function Wait() {

View File

@ -7,5 +7,9 @@
* @flow
*/
export {renderToReadableStream, version} from './ReactDOMFizzServerBrowser.js';
export {prerender} from './ReactDOMFizzStaticBrowser.js';
export {
renderToReadableStream,
resume,
version,
} from './ReactDOMFizzServerBrowser.js';
export {prerender, resumeAndPrerender} from './ReactDOMFizzStaticBrowser.js';

View File

@ -7,5 +7,9 @@
* @flow
*/
export {renderToReadableStream, version} from './ReactDOMFizzServerEdge.js';
export {prerender} from './ReactDOMFizzStaticEdge.js';
export {
renderToReadableStream,
resume,
version,
} from './ReactDOMFizzServerEdge.js';
export {prerender, resumeAndPrerender} from './ReactDOMFizzStaticEdge.js';

View File

@ -10,6 +10,13 @@
export {
renderToPipeableStream,
renderToReadableStream,
resume,
resumeToPipeableStream,
version,
} from './ReactDOMFizzServerNode.js';
export {prerenderToNodeStream, prerender} from './ReactDOMFizzStaticNode.js';
export {
prerenderToNodeStream,
prerender,
resumeAndPrerender,
resumeAndPrerenderToNodeStream,
} from './ReactDOMFizzStaticNode.js';

View File

@ -1589,7 +1589,6 @@ describe('ReactHooks', () => {
useStateHelper,
];
if (__EXPERIMENTAL__) {
const useTransitionHelper = () => React.useTransition();
const useDeferredValueHelper = () =>
React.useDeferredValue(0, {timeoutMs: 1000});
@ -1599,7 +1598,6 @@ describe('ReactHooks', () => {
hooksInList.push(useTransitionHelper);
hooksInList.push(useDeferredValueHelper);
}
const formatHookNamesToMatchErrorMessage = (hookNameA, hookNameB) => {
return `use${hookNameA}${' '.repeat(24 - hookNameA.length)}${

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-esm-server.node.development.js');
}
if (s.unstable_prerenderToNodeStream) {
exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
}
exports.prerenderToNodeStream = s.prerenderToNodeStream;

View File

@ -9,7 +9,7 @@
export {
renderToPipeableStream,
prerenderToNodeStream as unstable_prerenderToNodeStream,
prerenderToNodeStream,
decodeReplyFromBusboy,
decodeReply,
decodeAction,

View File

@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerenderToNodeStream} from './src/server/react-flight-dom-server.node';
export {prerenderToNodeStream} from './src/server/react-flight-dom-server.node';

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-parcel-server.browser.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
exports.prerender = s.prerender;

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-parcel-server.edge.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
exports.prerender = s.prerender;

View File

@ -7,9 +7,5 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-parcel-server.node.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
if (s.unstable_prerenderToNodeStream) {
exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
}
exports.prerender = s.prerender;
exports.prerenderToNodeStream = s.prerenderToNodeStream;

View File

@ -9,7 +9,7 @@
export {
renderToReadableStream,
prerender as unstable_prerender,
prerender,
decodeReply,
decodeAction,
decodeFormState,

View File

@ -9,7 +9,7 @@
export {
renderToReadableStream,
prerender as unstable_prerender,
prerender,
decodeReply,
decodeReplyFromAsyncIterable,
decodeAction,

View File

@ -10,8 +10,8 @@
export {
renderToReadableStream,
renderToPipeableStream,
prerender as unstable_prerender,
prerenderToNodeStream as unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
decodeReply,
decodeReplyFromBusboy,
decodeReplyFromAsyncIterable,

View File

@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerender} from './src/server/react-flight-dom-server.browser';
export {prerender} from './src/server/react-flight-dom-server.browser';

View File

@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerender} from './src/server/react-flight-dom-server.edge';
export {prerender} from './src/server/react-flight-dom-server.edge';

View File

@ -8,6 +8,6 @@
*/
export {
unstable_prerender,
unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
} from './src/server/react-flight-dom-server.node';

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-turbopack-server.browser.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
exports.prerender = s.prerender;

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-turbopack-server.edge.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
exports.prerender = s.prerender;

View File

@ -7,9 +7,5 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-turbopack-server.node.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
if (s.unstable_prerenderToNodeStream) {
exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
}
exports.prerender = s.prerender;
exports.prerenderToNodeStream = s.prerenderToNodeStream;

View File

@ -9,7 +9,7 @@
export {
renderToReadableStream,
prerender as unstable_prerender,
prerender,
decodeReply,
decodeAction,
decodeFormState,

View File

@ -9,7 +9,7 @@
export {
renderToReadableStream,
prerender as unstable_prerender,
prerender,
decodeReply,
decodeReplyFromAsyncIterable,
decodeAction,

View File

@ -10,8 +10,8 @@
export {
renderToReadableStream,
renderToPipeableStream,
prerender as unstable_prerender,
prerenderToNodeStream as unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
decodeReply,
decodeReplyFromBusboy,
decodeReplyFromAsyncIterable,

View File

@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerender} from './src/server/react-flight-dom-server.browser';
export {prerender} from './src/server/react-flight-dom-server.browser';

View File

@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerender} from './src/server/react-flight-dom-server.edge';
export {prerender} from './src/server/react-flight-dom-server.edge';

View File

@ -8,6 +8,6 @@
*/
export {
unstable_prerender,
unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
} from './src/server/react-flight-dom-server.node';

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-webpack-server.browser.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
exports.prerender = s.prerender;

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-webpack-server.edge.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
exports.prerender = s.prerender;

View File

@ -7,9 +7,5 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-webpack-server.node.development.js');
}
if (s.unstable_prerender) {
exports.unstable_prerender = s.unstable_prerender;
}
if (s.unstable_prerenderToNodeStream) {
exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
}
exports.prerender = s.prerender;
exports.prerenderToNodeStream = s.prerenderToNodeStream;

View File

@ -7,6 +7,4 @@ if (process.env.NODE_ENV === 'production') {
s = require('./cjs/react-server-dom-webpack-server.node.unbundled.development.js');
}
if (s.unstable_prerenderToNodeStream) {
exports.unstable_prerenderToNodeStream = s.unstable_prerenderToNodeStream;
}
exports.prerenderToNodeStream = s.prerenderToNodeStream;

View File

@ -63,11 +63,9 @@ describe('ReactFlightDOM', () => {
jest.mock('react-server-dom-webpack/server', () =>
require('react-server-dom-webpack/server.node.unbundled'),
);
if (__EXPERIMENTAL__) {
jest.mock('react-server-dom-webpack/static', () =>
require('react-server-dom-webpack/static.node.unbundled'),
);
}
const WebpackMock = require('./utils/WebpackMock');
clientExports = WebpackMock.clientExports;
clientExportsESM = WebpackMock.clientExportsESM;
@ -75,9 +73,7 @@ describe('ReactFlightDOM', () => {
webpackMap = WebpackMock.webpackMap;
ReactServerDOMServer = require('react-server-dom-webpack/server');
if (__EXPERIMENTAL__) {
ReactServerDOMStaticServer = require('react-server-dom-webpack/static');
}
// This reset is to load modules for the SSR/Browser scope.
jest.unmock('react-server-dom-webpack/server');
@ -2874,7 +2870,7 @@ describe('ReactFlightDOM', () => {
);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('can prerender', async () => {
let resolveGreeting;
const greetingPromise = new Promise(resolve => {
@ -2897,8 +2893,7 @@ describe('ReactFlightDOM', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult:
ReactServerDOMStaticServer.unstable_prerenderToNodeStream(
pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream(
<App />,
webpackMap,
),
@ -2964,8 +2959,7 @@ describe('ReactFlightDOM', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult:
ReactServerDOMStaticServer.unstable_prerenderToNodeStream(
pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream(
<App />,
webpackMap,
{
@ -3022,7 +3016,7 @@ describe('ReactFlightDOM', () => {
});
// This could be a bug. Discovered while making enableAsyncDebugInfo dynamic for www.
// @gate experimental && (enableHalt || (enableAsyncDebugInfo && __DEV__))
// @gate enableHalt || enablePostpone || (enableAsyncDebugInfo && __DEV__)
it('will leave async iterables in an incomplete state when halting', async () => {
let resolve;
const wait = new Promise(r => (resolve = r));
@ -3040,8 +3034,7 @@ describe('ReactFlightDOM', () => {
const controller = new AbortController();
const {pendingResult} = await serverAct(() => {
return {
pendingResult:
ReactServerDOMStaticServer.unstable_prerenderToNodeStream(
pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream(
{
multiShotIterable,
},
@ -3124,8 +3117,7 @@ describe('ReactFlightDOM', () => {
const errors = [];
const {pendingResult} = await serverAct(() => {
return {
pendingResult:
ReactServerDOMStaticServer.unstable_prerenderToNodeStream(
pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream(
<App />,
{},
{

View File

@ -69,12 +69,10 @@ describe('ReactFlightDOMBrowser', () => {
webpackMap = WebpackMock.webpackMap;
webpackServerMap = WebpackMock.webpackServerMap;
ReactServerDOMServer = require('react-server-dom-webpack/server');
if (__EXPERIMENTAL__) {
jest.mock('react-server-dom-webpack/static', () =>
require('react-server-dom-webpack/static.browser'),
);
ReactServerDOMStaticServer = require('react-server-dom-webpack/static');
}
__unmockReact();
jest.resetModules();
@ -2497,7 +2495,7 @@ describe('ReactFlightDOMBrowser', () => {
expect(errors).toEqual([reason]);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('can prerender', async () => {
let resolveGreeting;
const greetingPromise = new Promise(resolve => {
@ -2520,7 +2518,7 @@ describe('ReactFlightDOMBrowser', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
<App />,
webpackMap,
),
@ -2573,7 +2571,7 @@ describe('ReactFlightDOMBrowser', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
<App />,
webpackMap,
{
@ -3011,9 +3009,9 @@ describe('ReactFlightDOMBrowser', () => {
[
"",
"/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js",
2937,
2935,
27,
2931,
2929,
34,
],
[
@ -3027,9 +3025,9 @@ describe('ReactFlightDOMBrowser', () => {
[
"Object.<anonymous>",
"/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMBrowser-test.js",
2931,
2929,
18,
2918,
2916,
89,
],
],

View File

@ -90,12 +90,10 @@ describe('ReactFlightDOMEdge', () => {
ReactServer = require('react');
ReactServerDOMServer = require('react-server-dom-webpack/server');
if (__EXPERIMENTAL__) {
jest.mock('react-server-dom-webpack/static', () =>
require('react-server-dom-webpack/static.edge'),
);
ReactServerDOMStaticServer = require('react-server-dom-webpack/static');
}
jest.resetModules();
__unmockReact();
@ -1372,7 +1370,7 @@ describe('ReactFlightDOMEdge', () => {
]);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('can prerender', async () => {
let resolveGreeting;
const greetingPromise = new Promise(resolve => {
@ -1395,7 +1393,7 @@ describe('ReactFlightDOMEdge', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
<App />,
webpackMap,
),
@ -1453,7 +1451,7 @@ describe('ReactFlightDOMEdge', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
<App />,
webpackMap,
{
@ -1514,7 +1512,7 @@ describe('ReactFlightDOMEdge', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
{promise: infinitePromise},
webpackMap,
{
@ -1554,12 +1552,12 @@ describe('ReactFlightDOMEdge', () => {
expect(error.message).toBe('Connection closed.');
});
// @gate experimental
it('should be able to handle a rejected promise in unstable_prerender', async () => {
// @gate enableHalt || enablePostpone
it('should be able to handle a rejected promise in prerender', async () => {
const expectedError = new Error('Bam!');
const errors = [];
const {prelude} = await ReactServerDOMStaticServer.unstable_prerender(
const {prelude} = await ReactServerDOMStaticServer.prerender(
Promise.reject(expectedError),
webpackMap,
{
@ -1593,12 +1591,12 @@ describe('ReactFlightDOMEdge', () => {
expect(error.message).toBe(expectedMessage);
});
// @gate experimental
it('should be able to handle an erroring async iterable in unstable_prerender', async () => {
// @gate enableHalt || enablePostpone
it('should be able to handle an erroring async iterable in prerender', async () => {
const expectedError = new Error('Bam!');
const errors = [];
const {prelude} = await ReactServerDOMStaticServer.unstable_prerender(
const {prelude} = await ReactServerDOMStaticServer.prerender(
{
async *[Symbol.asyncIterator]() {
await serverAct(() => {
@ -1640,12 +1638,12 @@ describe('ReactFlightDOMEdge', () => {
expect(error.message).toBe(expectedMessage);
});
// @gate experimental
it('should be able to handle an erroring readable stream in unstable_prerender', async () => {
// @gate enableHalt || enablePostpone
it('should be able to handle an erroring readable stream in prerender', async () => {
const expectedError = new Error('Bam!');
const errors = [];
const {prelude} = await ReactServerDOMStaticServer.unstable_prerender(
const {prelude} = await ReactServerDOMStaticServer.prerender(
new ReadableStream({
async start(controller) {
await serverAct(() => {
@ -1688,11 +1686,11 @@ describe('ReactFlightDOMEdge', () => {
expect(error.message).toBe(expectedMessage);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('can prerender an async iterable', async () => {
const errors = [];
const {prelude} = await ReactServerDOMStaticServer.unstable_prerender(
const {prelude} = await ReactServerDOMStaticServer.prerender(
{
async *[Symbol.asyncIterator]() {
yield 'hello';
@ -1732,11 +1730,11 @@ describe('ReactFlightDOMEdge', () => {
expect(text).toBe('hello world');
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('can prerender a readable stream', async () => {
const errors = [];
const {prelude} = await ReactServerDOMStaticServer.unstable_prerender(
const {prelude} = await ReactServerDOMStaticServer.prerender(
new ReadableStream({
start(controller) {
controller.enqueue('hello world');
@ -1766,7 +1764,7 @@ describe('ReactFlightDOMEdge', () => {
expect(result).toBe('hello world');
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('does not return a prerender prelude early when an error is emitted and there are still pending tasks', async () => {
let rejectPromise;
const rejectingPromise = new Promise(
@ -1775,7 +1773,7 @@ describe('ReactFlightDOMEdge', () => {
const expectedError = new Error('Boom!');
const errors = [];
const {prelude} = await ReactServerDOMStaticServer.unstable_prerender(
const {prelude} = await ReactServerDOMStaticServer.prerender(
[
rejectingPromise,
{
@ -1862,7 +1860,7 @@ describe('ReactFlightDOMEdge', () => {
const serverAbortController = new AbortController();
const errors = [];
const prerenderResult = ReactServerDOMStaticServer.unstable_prerender(
const prerenderResult = ReactServerDOMStaticServer.prerender(
ReactServer.createElement(App, null),
webpackMap,
{

View File

@ -49,12 +49,10 @@ describe('ReactFlightDOMNode', () => {
);
ReactServer = require('react');
ReactServerDOMServer = require('react-server-dom-webpack/server');
if (__EXPERIMENTAL__) {
jest.mock('react-server-dom-webpack/static', () =>
require('react-server-dom-webpack/static.node'),
);
ReactServerDOMStaticServer = require('react-server-dom-webpack/static');
}
const WebpackMock = require('./utils/WebpackMock');
clientExports = WebpackMock.clientExports;
@ -489,7 +487,7 @@ describe('ReactFlightDOMNode', () => {
expect(errors).toEqual([reason]);
});
// @gate experimental
// @gate enableHalt || enablePostpone
it('can prerender', async () => {
let resolveGreeting;
const greetingPromise = new Promise(resolve => {
@ -512,8 +510,7 @@ describe('ReactFlightDOMNode', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult:
ReactServerDOMStaticServer.unstable_prerenderToNodeStream(
pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream(
<App />,
webpackMap,
),
@ -571,8 +568,7 @@ describe('ReactFlightDOMNode', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult:
ReactServerDOMStaticServer.unstable_prerenderToNodeStream(
pendingResult: ReactServerDOMStaticServer.prerenderToNodeStream(
<App />,
webpackMap,
{
@ -618,7 +614,7 @@ describe('ReactFlightDOMNode', () => {
expect(result).toContain('loading...');
});
// @gate enableHalt && enableAsyncDebugInfo
// @gate enableHalt
it('includes source locations in component and owner stacks for halted components', async () => {
async function Component() {
await new Promise(() => {});
@ -646,7 +642,7 @@ describe('ReactFlightDOMNode', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
ReactServer.createElement(App, null),
webpackMap,
{
@ -722,7 +718,9 @@ describe('ReactFlightDOMNode', () => {
if (__DEV__) {
expect(normalizeCodeLocInfo(componentStack)).toBe(
'\n in Component (at **)\n' +
'\n' +
' in Component' +
(gate(flags => flags.enableAsyncDebugInfo) ? ' (at **)\n' : '\n') +
' in Suspense\n' +
' in body\n' +
' in html\n' +
@ -739,15 +737,19 @@ describe('ReactFlightDOMNode', () => {
}
if (__DEV__) {
if (gate(flags => flags.enableAsyncDebugInfo)) {
expect(normalizeCodeLocInfo(ownerStack)).toBe(
'\n in Component (at **)\n in App (at **)',
);
} else {
expect(normalizeCodeLocInfo(ownerStack)).toBe('\n in App (at **)');
}
} else {
expect(ownerStack).toBeNull();
}
});
// @gate enableHalt && enableAsyncDebugInfo
// @gate enableHalt
it('includes deeper location for aborted stacks', async () => {
async function getData() {
const signal = ReactServer.cacheSignal();
@ -792,7 +794,7 @@ describe('ReactFlightDOMNode', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
ReactServer.createElement(App, null),
webpackMap,
{
@ -869,7 +871,9 @@ describe('ReactFlightDOMNode', () => {
if (__DEV__) {
expect(normalizeCodeLocInfo(componentStack)).toBe(
'\n in Component (at **)\n' +
'\n' +
' in Component' +
(gate(flags => flags.enableAsyncDebugInfo) ? ' (at **)\n' : '\n') +
' in Suspense\n' +
' in body\n' +
' in html\n' +
@ -886,17 +890,24 @@ describe('ReactFlightDOMNode', () => {
}
if (__DEV__) {
if (gate(flags => flags.enableAsyncDebugInfo)) {
expect(normalizeCodeLocInfo(ownerStack)).toBe(
'' +
'\n in getData (at **)' +
'\n in Component (at **)' +
'\n in App (at **)',
);
} else {
expect(normalizeCodeLocInfo(ownerStack)).toBe(
'' + '\n in App (at **)',
);
}
} else {
expect(ownerStack).toBeNull();
}
});
// @gate experimental
// @gate enableHalt || enablePostpone
// @gate enableHalt
it('can handle an empty prelude when prerendering', async () => {
function App() {
@ -909,7 +920,7 @@ describe('ReactFlightDOMNode', () => {
const {pendingResult} = await serverAct(async () => {
// destructure trick to avoid the act scope from awaiting the returned value
return {
pendingResult: ReactServerDOMStaticServer.unstable_prerender(
pendingResult: ReactServerDOMStaticServer.prerender(
ReactServer.createElement(App, null),
webpackMap,
{

View File

@ -9,7 +9,7 @@
export {
renderToReadableStream,
prerender as unstable_prerender,
prerender,
decodeReply,
decodeAction,
decodeFormState,

View File

@ -9,7 +9,7 @@
export {
renderToReadableStream,
prerender as unstable_prerender,
prerender,
decodeReply,
decodeReplyFromAsyncIterable,
decodeAction,

View File

@ -10,8 +10,8 @@
export {
renderToReadableStream,
renderToPipeableStream,
prerender as unstable_prerender,
prerenderToNodeStream as unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
decodeReply,
decodeReplyFromBusboy,
decodeReplyFromAsyncIterable,

View File

@ -10,8 +10,8 @@
export {
renderToReadableStream,
renderToPipeableStream,
prerender as unstable_prerender,
prerenderToNodeStream as unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
decodeReply,
decodeReplyFromBusboy,
decodeReplyFromAsyncIterable,

View File

@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerender} from './src/server/react-flight-dom-server.browser';
export {prerender} from './src/server/react-flight-dom-server.browser';

View File

@ -7,4 +7,4 @@
* @flow
*/
export {unstable_prerender} from './src/server/react-flight-dom-server.edge';
export {prerender} from './src/server/react-flight-dom-server.edge';

View File

@ -8,6 +8,6 @@
*/
export {
unstable_prerender,
unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
} from './src/server/react-flight-dom-server.node';

View File

@ -8,6 +8,6 @@
*/
export {
unstable_prerender,
unstable_prerenderToNodeStream,
prerender,
prerenderToNodeStream,
} from './src/server/react-flight-dom-server.node.unbundled';

View File

@ -82,7 +82,7 @@ export const enableTaint = __EXPERIMENTAL__;
export const enablePostpone = __EXPERIMENTAL__;
export const enableHalt = __EXPERIMENTAL__;
export const enableHalt: boolean = true;
export const enableViewTransition = __EXPERIMENTAL__;

View File

@ -44,7 +44,7 @@ export const enableCPUSuspense: boolean = true;
export const enableCreateEventHandleAPI: boolean = false;
export const enableMoveBefore: boolean = true;
export const enableFizzExternalRuntime: boolean = true;
export const enableHalt: boolean = false;
export const enableHalt: boolean = true;
export const enableInfiniteRenderLoopDetection: boolean = false;
export const enableLegacyCache: boolean = false;
export const enableLegacyFBSupport: boolean = false;

View File

@ -30,7 +30,7 @@ export const enableCPUSuspense: boolean = false;
export const enableCreateEventHandleAPI: boolean = false;
export const enableMoveBefore: boolean = true;
export const enableFizzExternalRuntime: boolean = true;
export const enableHalt: boolean = false;
export const enableHalt: boolean = true;
export const enableHiddenSubtreeInsertionEffectCleanup: boolean = false;
export const enableInfiniteRenderLoopDetection: boolean = false;
export const enableLegacyCache: boolean = false;

View File

@ -21,7 +21,7 @@ export const enableLegacyCache: boolean = __EXPERIMENTAL__;
export const enableAsyncIterableChildren: boolean = false;
export const enableTaint: boolean = true;
export const enablePostpone: boolean = false;
export const enableHalt: boolean = false;
export const enableHalt: boolean = true;
export const disableCommentsAsDOMContainers: boolean = true;
export const disableInputAttributeSyncing: boolean = false;
export const enableScopeAPI: boolean = false;

View File

@ -25,7 +25,7 @@ export const enableCPUSuspense = true;
export const enableCreateEventHandleAPI = false;
export const enableMoveBefore = false;
export const enableFizzExternalRuntime = true;
export const enableHalt = false;
export const enableHalt = true;
export const enableInfiniteRenderLoopDetection = false;
export const enableHiddenSubtreeInsertionEffectCleanup = true;
export const enableLegacyCache = false;

View File

@ -21,7 +21,7 @@ export const enableLegacyCache: boolean = true;
export const enableAsyncIterableChildren: boolean = false;
export const enableTaint: boolean = true;
export const enablePostpone: boolean = false;
export const enableHalt: boolean = false;
export const enableHalt: boolean = true;
export const disableCommentsAsDOMContainers: boolean = true;
export const disableInputAttributeSyncing: boolean = false;
export const enableScopeAPI: boolean = true;

View File

@ -73,7 +73,7 @@ export const enableTaint: boolean = false;
export const enablePostpone: boolean = false;
export const enableHalt: boolean = false;
export const enableHalt: boolean = true;
// TODO: www currently relies on this feature. It's disabled in open source.
// Need to remove it.