Skip to content
Merged
58 changes: 58 additions & 0 deletions packages/react-client/src/__tests__/ReactFlight-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2991,6 +2991,64 @@ describe('ReactFlight', () => {
);
});

// @gate !__DEV__ || enableComponentPerformanceTrack
it('preserves debug info for server-to-server through use()', async () => {
function ThirdPartyComponent() {
return 'hi';
}

function ServerComponent({transport}) {
// This is a Server Component that receives other Server Components from a third party.
const text = ReactServer.use(ReactNoopFlightClient.read(transport));
return <div>{text.toUpperCase()}</div>;
}

const thirdPartyTransport = ReactNoopFlightServer.render(
<ThirdPartyComponent />,
{
environmentName: 'third-party',
},
);

const transport = ReactNoopFlightServer.render(
<ServerComponent transport={thirdPartyTransport} />,
);

await act(async () => {
const promise = ReactNoopFlightClient.read(transport);
expect(getDebugInfo(promise)).toEqual(
__DEV__
? [
{time: 16},
{
name: 'ServerComponent',
env: 'Server',
key: null,
stack: ' in Object.<anonymous> (at **)',
props: {
transport: expect.arrayContaining([]),
},
},
{time: 16},
{
name: 'ThirdPartyComponent',
env: 'third-party',
key: null,
stack: ' in Object.<anonymous> (at **)',
props: {},
},
{time: 16},
{time: 17},
]
: undefined,
);
const result = await promise;
ReactNoop.render(result);
});

expect(ReactNoop).toMatchRenderedOutput(<div>HI</div>);
});

it('preserves error stacks passed through server-to-server with source maps', async () => {
async function ServerComponent({transport}) {
// This is a Server Component that receives other Server Components from a third party.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,9 @@ const deepProxyHandlers = {
// reference.
case 'defaultProps':
return undefined;
// React looks for debugInfo on thenables.
case '_debugInfo':
return undefined;
// Avoid this attempting to be serialized.
case 'toJSON':
return undefined;
Expand Down Expand Up @@ -210,6 +213,9 @@ function getReference(target: Function, name: string | symbol): $FlowFixMe {
// reference.
case 'defaultProps':
return undefined;
// React looks for debugInfo on thenables.
case '_debugInfo':
return undefined;
// Avoid this attempting to be serialized.
case 'toJSON':
return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,9 @@ const deepProxyHandlers = {
// reference.
case 'defaultProps':
return undefined;
// React looks for debugInfo on thenables.
case '_debugInfo':
return undefined;
// Avoid this attempting to be serialized.
case 'toJSON':
return undefined;
Expand Down Expand Up @@ -211,6 +214,9 @@ function getReference(target: Function, name: string | symbol): $FlowFixMe {
// reference.
case 'defaultProps':
return undefined;
// React looks for debugInfo on thenables.
case '_debugInfo':
return undefined;
// Avoid this attempting to be serialized.
case 'toJSON':
return undefined;
Expand Down
6 changes: 6 additions & 0 deletions packages/react-server/src/ReactFlightHooks.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ export function getThenableStateAfterSuspending(): ThenableState {
return state;
}

export function getTrackedThenablesAfterRendering(): null | Array<
Thenable<any>,
> {
return thenableState;
}

export const HooksDispatcher: Dispatcher = {
readContext: (unsupportedContext: any),

Expand Down
Loading
Loading