Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fiber] Stash usables on _debugUsables for DevTools #28295

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 8 additions & 5 deletions packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,13 @@
* @flow
*/

import type {Thenable} from 'shared/ReactTypes';
import type {
Thenable,
ReactDebugInfo,
ReactComponentInfo,
ReactAsyncInfo,
ReactConsoleInfo,
} from 'shared/ReactTypes';
import type {LazyComponent} from 'react/src/ReactLazy';

import type {
Expand Down Expand Up @@ -76,9 +82,6 @@ const RESOLVED_MODULE = 'resolved_module';
const INITIALIZED = 'fulfilled';
const ERRORED = 'rejected';

// Dev-only
type ReactDebugInfo = Array<{+name?: string}>;

type PendingChunk<T> = {
status: 'pending',
value: null | Array<(T) => mixed>,
Expand Down Expand Up @@ -1014,7 +1017,7 @@ function resolveHint<Code: HintCode>(
function resolveDebugInfo(
response: Response,
id: number,
debugInfo: {name: string},
debugInfo: ReactComponentInfo | ReactAsyncInfo | ReactConsoleInfo,
): void {
if (!__DEV__) {
// These errors should never make it into a build so we don't need to encode them in codes.json
Expand Down
68 changes: 66 additions & 2 deletions packages/react-client/src/__tests__/ReactFlight-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ describe('ReactFlight', () => {
const rootModel = await ReactNoopFlightClient.read(transport);
const greeting = rootModel.greeting;
expect(greeting._debugInfo).toEqual(
__DEV__ ? [{name: 'Greeting'}] : undefined,
__DEV__ ? [{name: 'Greeting', env: 'server'}] : undefined,
);
ReactNoop.render(greeting);
});
Expand All @@ -214,7 +214,7 @@ describe('ReactFlight', () => {
await act(async () => {
const promise = ReactNoopFlightClient.read(transport);
expect(promise._debugInfo).toEqual(
__DEV__ ? [{name: 'Greeting'}] : undefined,
__DEV__ ? [{name: 'Greeting', env: 'server'}] : undefined,
);
ReactNoop.render(await promise);
});
Expand Down Expand Up @@ -1806,4 +1806,68 @@ describe('ReactFlight', () => {

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

it('preserves debug info for server-to-server pass through', async () => {
function ThirdPartyLazyComponent() {
return <span>!</span>;
}

const lazy = React.lazy(async () => ({
default: <ThirdPartyLazyComponent />,
}));

function ThirdPartyComponent() {
return <span>stranger</span>;
}

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

const promiseComponent = Promise.resolve(<ThirdPartyComponent />);

const thirdPartyTransport = ReactNoopFlightServer.render(
[promiseComponent, lazy],
{
environmentName: 'third-party',
},
);

// Wait for the lazy component to initialize
await 0;

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

await act(async () => {
const promise = ReactNoopFlightClient.read(transport);
expect(promise._debugInfo).toEqual(
__DEV__ ? [{name: 'ServerComponent', env: 'server'}] : undefined,
);
const result = await promise;
const thirdPartyChildren = await result.props.children[1];
// We expect the debug info to be transferred from the inner stream to the outer.
expect(thirdPartyChildren[0]._debugInfo).toEqual(
__DEV__
? [{name: 'ThirdPartyComponent', env: 'third-party'}]
: undefined,
);
expect(thirdPartyChildren[1]._debugInfo).toEqual(
__DEV__
? [{name: 'ThirdPartyLazyComponent', env: 'third-party'}]
: undefined,
);
ReactNoop.render(result);
});

expect(ReactNoop).toMatchRenderedOutput(
<div>
Hello, <span>stranger</span>
<span>!</span>
</div>,
);
});
});
6 changes: 5 additions & 1 deletion packages/react-noop-renderer/src/ReactNoopFlightServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,10 @@ const ReactNoopFlightServer = ReactFlightServer({
});

type Options = {
onError?: (error: mixed) => void,
environmentName?: string,
identifierPrefix?: string,
onError?: (error: mixed) => void,
onPostpone?: (reason: string) => void,
};

function render(model: ReactClientValue, options?: Options): Destination {
Expand All @@ -80,6 +82,8 @@ function render(model: ReactClientValue, options?: Options): Destination {
bundlerConfig,
options ? options.onError : undefined,
options ? options.identifierPrefix : undefined,
options ? options.onPostpone : undefined,
options ? options.environmentName : undefined,
);
ReactNoopFlightServer.startWork(request);
ReactNoopFlightServer.startFlowing(request, destination);
Expand Down
Loading