mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
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.
70 lines
1.7 KiB
JavaScript
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 {ServerContextJSONValue} from 'shared/ReactTypes';
|
|
import type {BundlerConfig} from './ReactFlightServerWebpackBundlerConfig';
|
|
|
|
import {
|
|
createRequest,
|
|
startWork,
|
|
startFlowing,
|
|
abort,
|
|
} from 'react-server/src/ReactFlightServer';
|
|
|
|
type Options = {
|
|
identifierPrefix?: string,
|
|
signal?: AbortSignal,
|
|
context?: Array<[string, ServerContextJSONValue]>,
|
|
onError?: (error: mixed) => void,
|
|
};
|
|
|
|
function renderToReadableStream(
|
|
model: ReactModel,
|
|
webpackMap: BundlerConfig,
|
|
options?: Options,
|
|
): ReadableStream {
|
|
const request = createRequest(
|
|
model,
|
|
webpackMap,
|
|
options ? options.onError : undefined,
|
|
options ? options.context : undefined,
|
|
options ? options.identifierPrefix : undefined,
|
|
);
|
|
if (options && options.signal) {
|
|
const signal = options.signal;
|
|
if (signal.aborted) {
|
|
abort(request, (signal: any).reason);
|
|
} else {
|
|
const listener = () => {
|
|
abort(request, (signal: any).reason);
|
|
signal.removeEventListener('abort', listener);
|
|
};
|
|
signal.addEventListener('abort', listener);
|
|
}
|
|
}
|
|
const stream = new ReadableStream(
|
|
{
|
|
type: 'bytes',
|
|
start(controller) {
|
|
startWork(request);
|
|
},
|
|
pull(controller) {
|
|
startFlowing(request, controller);
|
|
},
|
|
cancel(reason) {},
|
|
},
|
|
// $FlowFixMe size() methods are not allowed on byte streams.
|
|
{highWaterMark: 0},
|
|
);
|
|
return stream;
|
|
}
|
|
|
|
export {renderToReadableStream};
|