Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Next.js runtime support to ReactFizzServer #22350

Closed
wants to merge 13 commits into from
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export * from 'react-client/src/ReactFlightClientHostConfigBrowser';
export * from 'react-client/src/ReactFlightClientHostConfigStream';
export * from 'react-server-dom-webpack/src/ReactFlightClientWebpackBundlerConfig';
80 changes: 80 additions & 0 deletions packages/react-dom/src/server/ReactDOMFizzServerNext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

import type {ReactNodeList} from 'shared/ReactTypes';
import type {Destination} from 'react-server/src/ReactServerStreamConfigNext';

import ReactVersion from 'shared/ReactVersion';

import {
createRequest,
startWork,
startFlowing,
stopFlowing,
abort,
} from 'react-server/src/ReactFizzServer';

import {
createResponseState,
createRootFormatContext,
} from './ReactDOMServerFormatConfig';

type Options = {|
identifierPrefix?: string,
namespaceURI?: string,
progressiveChunkSize?: number,
onReadyToStream?: () => void,
onCompleteAll?: () => void,
onError?: (error: mixed) => void,
|};

type Controls = {|
abort(): void,
update(): void,
|};

function createRequestImpl(
children: ReactNodeList,
destination: Destination,
options: void | Options,
) {
return createRequest(
children,
destination,
createResponseState(options ? options.identifierPrefix : undefined),
createRootFormatContext(options ? options.namespaceURI : undefined),
options ? options.progressiveChunkSize : undefined,
options ? options.onError : undefined,
options ? options.onCompleteAll : undefined,
options ? options.onReadyToStream : undefined,
);
}

function renderToNextStream(
children: ReactNodeList,
destination: Destination,
options?: Options,
): Controls {
const request = createRequestImpl(children, destination, options);
startWork(request);
return {
abort() {
abort(request);
},
update() {
if (destination.ready) {
startFlowing(request);
} else {
stopFlowing(request);
}
},
};
}

export {renderToNextStream, ReactVersion as version};
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export * from 'react-dom/src/client/ReactDOMHostConfig';
7 changes: 7 additions & 0 deletions packages/react-server/src/ReactFizzServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -1915,6 +1915,13 @@ export function startFlowing(request: Request): void {
}
}

export function stopFlowing(request: Request): void {
if (request.status === CLOSED) {
return;
}
request.status = BUFFERING;
}

// This is called to early terminate a request. It puts all pending boundaries in client rendered state.
export function abort(request: Request): void {
try {
Expand Down
65 changes: 65 additions & 0 deletions packages/react-server/src/ReactServerStreamConfigNext.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

declare function __next_scheduleReactServerStreamWork__(
callback: () => void,
): void;

export type Destination = {|
write: (chunk: Uint8Array) => void,
buffer: (shouldBuffer: boolean) => void,
flush: () => void,
close: (error: mixed) => void,
ready: boolean,
|};

export type PrecomputedChunk = Uint8Array;
export type Chunk = Uint8Array;

export function scheduleWork(callback: () => void) {
__next_scheduleReactServerStreamWork__(callback);
}

export function flushBuffered(destination: Destination) {
destination.flush();
}

export function beginWriting(destination: Destination) {
destination.buffer(true);
}

export function writeChunk(
destination: Destination,
chunk: PrecomputedChunk | Chunk,
): boolean {
destination.write(chunk);
return destination.ready;
}

export function completeWriting(destination: Destination) {
destination.buffer(false);
}

export function close(destination: Destination) {
destination.close();
}

const textEncoder = new TextEncoder();

export function stringToChunk(content: string): Chunk {
return textEncoder.encode(content);
}

export function stringToPrecomputedChunk(content: string): PrecomputedChunk {
return textEncoder.encode(content);
}

export function closeWithError(destination: Destination, error: mixed): void {
destination.close(error);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export * from '../ReactFlightServerConfigStream';
export * from 'react-server-dom-webpack/src/ReactFlightServerWebpackBundlerConfig';
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export * from 'react-dom/src/server/ReactDOMServerFormatConfig';
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

export * from '../ReactServerStreamConfigNext';
8 changes: 8 additions & 0 deletions scripts/rollup/bundles.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,14 @@ const bundles = [
global: 'ReactDOMServer',
externals: ['react'],
},
{
bundleTypes: [NODE_DEV, NODE_PROD],
moduleType: RENDERER,
entry: 'react-dom/src/server/ReactDOMFizzServerNext',
name: 'react-dom-server-next',
global: 'ReactDOMServer',
externals: ['react'],
},
{
bundleTypes: __EXPERIMENTAL__ ? [FB_WWW_DEV, FB_WWW_PROD] : [],
moduleType: RENDERER,
Expand Down
14 changes: 14 additions & 0 deletions scripts/shared/inlinedHostConfigs.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,20 @@ module.exports = [
isFlowTyped: true,
isServerSupported: true,
},
{
shortName: 'dom-next',
entryPoints: [
'react-dom/src/server/ReactDOMFizzServerNext', // react-dom/server
],
paths: [
'react-dom',
'react-server-dom-webpack',
'react-dom/src/server/ReactDOMFizzServerNext.js', // react-dom/server.browser
'react-client/src/ReactFlightClientStream.js', // We can only type check this in streaming configurations.
],
isFlowTyped: true,
isServerSupported: true,
},
{
shortName: 'art',
entryPoints: ['react-art'],
Expand Down