mirror of
https://github.com/facebook/react.git
synced 2026-02-26 07:55:55 +00:00
This is just moving some stuff around and renaming things. This tuple is opaque to the Flight implementation and we should probably encode it separately as a single string instead of a model object. The term "Metadata" isn't the same as when used for ClientReferences so it's not really the right term anyway. I also made it optional since a bound function with no arguments bound is technically different than a raw instance of that function (it's a clone). I also renamed the type ReactModel to ReactClientValue. This is the generic serializable type for something that can pass through the serializable boundary from server to client. There will be another one for client to server. I also filled in missing classes and ensure the serializable sub-types are explicit. E.g. Array and Thenable.
74 lines
1.9 KiB
JavaScript
74 lines
1.9 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 {
|
|
Request,
|
|
ReactClientValue,
|
|
} from 'react-server/src/ReactFlightServer';
|
|
import type {Destination} from 'react-server/src/ReactServerStreamConfigNode';
|
|
import type {ClientManifest} from './ReactFlightServerWebpackBundlerConfig';
|
|
import type {Writable} from 'stream';
|
|
import type {ServerContextJSONValue} from 'shared/ReactTypes';
|
|
|
|
import {
|
|
createRequest,
|
|
startWork,
|
|
startFlowing,
|
|
abort,
|
|
} from 'react-server/src/ReactFlightServer';
|
|
|
|
function createDrainHandler(destination: Destination, request: Request) {
|
|
return () => startFlowing(request, destination);
|
|
}
|
|
|
|
type Options = {
|
|
onError?: (error: mixed) => void,
|
|
context?: Array<[string, ServerContextJSONValue]>,
|
|
identifierPrefix?: string,
|
|
};
|
|
|
|
type PipeableStream = {
|
|
abort(reason: mixed): void,
|
|
pipe<T: Writable>(destination: T): T,
|
|
};
|
|
|
|
function renderToPipeableStream(
|
|
model: ReactClientValue,
|
|
webpackMap: ClientManifest,
|
|
options?: Options,
|
|
): PipeableStream {
|
|
const request = createRequest(
|
|
model,
|
|
webpackMap,
|
|
options ? options.onError : undefined,
|
|
options ? options.context : undefined,
|
|
options ? options.identifierPrefix : undefined,
|
|
);
|
|
let hasStartedFlowing = false;
|
|
startWork(request);
|
|
return {
|
|
pipe<T: Writable>(destination: T): T {
|
|
if (hasStartedFlowing) {
|
|
throw new Error(
|
|
'React currently only supports piping to one writable stream.',
|
|
);
|
|
}
|
|
hasStartedFlowing = true;
|
|
startFlowing(request, destination);
|
|
destination.on('drain', createDrainHandler(destination, request));
|
|
return destination;
|
|
},
|
|
abort(reason: mixed) {
|
|
abort(request, reason);
|
|
},
|
|
};
|
|
}
|
|
|
|
export {renderToPipeableStream};
|