[Flight] Use Web Streams APIs for 3rd-party component in Flight fixture (#33481)

This commit is contained in:
Hendrik Liebau 2025-06-08 06:33:25 +02:00 committed by GitHub
parent e4b88ae4c6
commit c0b5a0cad3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,6 +1,6 @@
import * as React from 'react'; import * as React from 'react';
import {renderToPipeableStream} from 'react-server-dom-webpack/server'; import {renderToReadableStream} from 'react-server-dom-webpack/server';
import {createFromNodeStream} from 'react-server-dom-webpack/client'; import {createFromReadableStream} from 'react-server-dom-webpack/client';
import {PassThrough, Readable} from 'stream'; import {PassThrough, Readable} from 'stream';
import Container from './Container.js'; import Container from './Container.js';
@ -46,43 +46,33 @@ async function ThirdPartyComponent() {
return delay('hello from a 3rd party', 30); return delay('hello from a 3rd party', 30);
} }
// Using Web streams for tee'ing convenience here. let cachedThirdPartyStream;
let cachedThirdPartyReadableWeb;
// We create the Component outside of AsyncLocalStorage so that it has no owner. // We create the Component outside of AsyncLocalStorage so that it has no owner.
// That way it gets the owner from the call to createFromNodeStream. // That way it gets the owner from the call to createFromNodeStream.
const thirdPartyComponent = <ThirdPartyComponent />; const thirdPartyComponent = <ThirdPartyComponent />;
function fetchThirdParty(noCache) { function fetchThirdParty(noCache) {
if (cachedThirdPartyReadableWeb && !noCache) { // We're using the Web Streams APIs for tee'ing convenience.
const [readableWeb1, readableWeb2] = cachedThirdPartyReadableWeb.tee(); const stream =
cachedThirdPartyReadableWeb = readableWeb1; cachedThirdPartyStream && !noCache
? cachedThirdPartyStream
return createFromNodeStream(Readable.fromWeb(readableWeb2), { : renderToReadableStream(
moduleMap: {},
moduleLoading: {},
});
}
const stream = renderToPipeableStream(
thirdPartyComponent, thirdPartyComponent,
{}, {},
{environmentName: 'third-party'} {environmentName: 'third-party'}
); );
const readable = new PassThrough(); const [stream1, stream2] = stream.tee();
// React currently only supports piping to one stream, so we convert, tee, and cachedThirdPartyStream = stream1;
// convert back again.
// TODO: Switch to web streams without converting when #33442 has landed.
const [readableWeb1, readableWeb2] = Readable.toWeb(readable).tee();
cachedThirdPartyReadableWeb = readableWeb1;
const result = createFromNodeStream(Readable.fromWeb(readableWeb2), {
moduleMap: {},
moduleLoading: {},
});
stream.pipe(readable);
return result; return createFromReadableStream(stream2, {
serverConsumerManifest: {
moduleMap: {},
serverModuleMap: null,
moduleLoading: null,
},
});
} }
async function ServerComponent({noCache}) { async function ServerComponent({noCache}) {