mirror of
https://github.com/zebrajr/react.git
synced 2026-01-15 12:15:22 +00:00
[Flight] Add debugChannel option to Edge and Node clients (#34236)
When a debug channel is used between the Flight server and a browser Flight client, we want to allow the same RSC stream to be used for server-side rendering. To support this, the Edge and Node Flight clients also need to accept a `debugChannel` option. Without it, debug information would be missing (e.g. for SSR error stacks), and in some cases this could result in `Connection closed` errors. This PR adds support for the `debugChannel` option in the Edge and Node clients for ESM, Parcel, Turbopack, and Webpack. Unlike the browser clients, these clients only support a one-way channel, since the Flight server’s return protocol is not designed for multiple clients. The implementation follows the approach used in the browser clients, but excludes the writable parts.
This commit is contained in:
@@ -56,8 +56,38 @@ export type Options = {
|
||||
findSourceMapURL?: FindSourceMapURLCallback,
|
||||
replayConsoleLogs?: boolean,
|
||||
environmentName?: string,
|
||||
// For the Node.js client we only support a single-direction debug channel.
|
||||
debugChannel?: Readable,
|
||||
};
|
||||
|
||||
function startReadingFromStream(
|
||||
response: Response,
|
||||
stream: Readable,
|
||||
isSecondaryStream: boolean,
|
||||
): void {
|
||||
const streamState = createStreamState();
|
||||
|
||||
stream.on('data', chunk => {
|
||||
if (typeof chunk === 'string') {
|
||||
processStringChunk(response, streamState, chunk);
|
||||
} else {
|
||||
processBinaryChunk(response, streamState, chunk);
|
||||
}
|
||||
});
|
||||
|
||||
stream.on('error', error => {
|
||||
reportGlobalError(response, error);
|
||||
});
|
||||
|
||||
stream.on('end', () => {
|
||||
// If we're the secondary stream, then we don't close the response until the
|
||||
// debug channel closes.
|
||||
if (!isSecondaryStream) {
|
||||
close(response);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function createFromNodeStream<T>(
|
||||
stream: Readable,
|
||||
moduleRootPath: string,
|
||||
@@ -80,18 +110,14 @@ function createFromNodeStream<T>(
|
||||
? options.environmentName
|
||||
: undefined,
|
||||
);
|
||||
const streamState = createStreamState();
|
||||
stream.on('data', chunk => {
|
||||
if (typeof chunk === 'string') {
|
||||
processStringChunk(response, streamState, chunk);
|
||||
} else {
|
||||
processBinaryChunk(response, streamState, chunk);
|
||||
}
|
||||
});
|
||||
stream.on('error', error => {
|
||||
reportGlobalError(response, error);
|
||||
});
|
||||
stream.on('end', () => close(response));
|
||||
|
||||
if (__DEV__ && options && options.debugChannel) {
|
||||
startReadingFromStream(response, options.debugChannel, false);
|
||||
startReadingFromStream(response, stream, true);
|
||||
} else {
|
||||
startReadingFromStream(response, stream, false);
|
||||
}
|
||||
|
||||
return getRoot(response);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user