mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
This effectively lets us consume Web Streams in a Node build. In fact the Node entry point is now just adding Node stream APIs. For the client, this is simple because the configs are not actually stream type specific. The server is a little trickier.
82 lines
2.3 KiB
JavaScript
82 lines
2.3 KiB
JavaScript
/**
|
|
* Copyright (c) Meta Platforms, Inc. and 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 {Thenable, ReactCustomFormAction} from 'shared/ReactTypes.js';
|
|
import type {Response} from 'react-client/src/ReactFlightClient';
|
|
import type {Readable} from 'stream';
|
|
|
|
import {
|
|
createResponse,
|
|
getRoot,
|
|
reportGlobalError,
|
|
processBinaryChunk,
|
|
close,
|
|
} from 'react-client/src/ReactFlightClient';
|
|
|
|
export * from './ReactFlightDOMClientEdge';
|
|
|
|
function findSourceMapURL(filename: string, environmentName: string) {
|
|
const devServer = parcelRequire.meta.devServer;
|
|
if (devServer != null) {
|
|
const qs = new URLSearchParams();
|
|
qs.set('filename', filename);
|
|
qs.set('env', environmentName);
|
|
return devServer + '/__parcel_source_map?' + qs.toString();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
function noServerCall() {
|
|
throw new Error(
|
|
'Server Functions cannot be called during initial render. ' +
|
|
'This would create a fetch waterfall. Try to use a Server Component ' +
|
|
'to pass data to Client Components instead.',
|
|
);
|
|
}
|
|
|
|
type EncodeFormActionCallback = <A>(
|
|
id: any,
|
|
args: Promise<A>,
|
|
) => ReactCustomFormAction;
|
|
|
|
export type Options = {
|
|
nonce?: string,
|
|
encodeFormAction?: EncodeFormActionCallback,
|
|
replayConsoleLogs?: boolean,
|
|
environmentName?: string,
|
|
};
|
|
|
|
export function createFromNodeStream<T>(
|
|
stream: Readable,
|
|
options?: Options,
|
|
): Thenable<T> {
|
|
const response: Response = createResponse(
|
|
null, // bundlerConfig
|
|
null, // serverReferenceConfig
|
|
null, // moduleLoading
|
|
noServerCall,
|
|
options ? options.encodeFormAction : undefined,
|
|
options && typeof options.nonce === 'string' ? options.nonce : undefined,
|
|
undefined, // TODO: If encodeReply is supported, this should support temporaryReferences
|
|
__DEV__ ? findSourceMapURL : undefined,
|
|
__DEV__ && options ? options.replayConsoleLogs === true : false, // defaults to false
|
|
__DEV__ && options && options.environmentName
|
|
? options.environmentName
|
|
: undefined,
|
|
);
|
|
stream.on('data', chunk => {
|
|
processBinaryChunk(response, chunk);
|
|
});
|
|
stream.on('error', error => {
|
|
reportGlobalError(response, error);
|
|
});
|
|
stream.on('end', () => close(response));
|
|
return getRoot(response);
|
|
}
|