Files
react/packages/react-server-dom-webpack/src/ReactFlightDOMServerNode.js
Sebastian Markbåge 56389e81ff Abort Flight (#24754)
Add aborting to the Flight Server. This encodes the reason as an "error"
row that gets thrown client side. These are still exposed in prod which
is a follow up we'll still have to do to encode them as digests instead.

The error is encoded once and then referenced by each row that needs to
be updated.
2022-06-19 11:05:41 -04:00

70 lines
1.7 KiB
JavaScript

/**
* 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 {ReactModel} from 'react-server/src/ReactFlightServer';
import type {BundlerConfig} 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, 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: ReactModel,
webpackMap: BundlerConfig,
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};