Skip to content

Commit ed07719

Browse files
authored
[Flight] Dedupe objects serialized as Debug Models in a separate set (#33583)
Stacked on #33539. Stores dedupes of `renderConsoleValue` in a separate set. This allows us to dedupe objects safely since we can't write objects using this algorithm if they might also be referenced by the "real" serialization. Also renamed it to `renderDebugModel` since it's not just for console anymore.
1 parent 643257c commit ed07719

File tree

3 files changed

+151
-113
lines changed

3 files changed

+151
-113
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,11 @@ ReactPromise.prototype.then = function <T>(
266266
initializeModuleChunk(chunk);
267267
break;
268268
}
269-
if (__DEV__ && enableAsyncDebugInfo) {
269+
if (
270+
__DEV__ &&
271+
enableAsyncDebugInfo &&
272+
(typeof resolve !== 'function' || !(resolve: any).isReactInternalListener)
273+
) {
270274
// Because only native Promises get picked up when we're awaiting we need to wrap
271275
// this in a native Promise in DEV. This means that these callbacks are no longer sync
272276
// but the lazy initialization is still sync and the .value can be inspected after,
@@ -1052,6 +1056,10 @@ function waitForReference<T>(
10521056
}
10531057
}
10541058
}
1059+
// Use to avoid the microtask resolution in DEV.
1060+
if (__DEV__ && enableAsyncDebugInfo) {
1061+
(fulfill: any).isReactInternalListener = true;
1062+
}
10551063

10561064
function reject(error: mixed): void {
10571065
if (handler.errored) {

packages/react-client/src/__tests__/ReactFlight-test.js

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3328,19 +3328,10 @@ describe('ReactFlight', () => {
33283328
await ReactNoopFlightClient.read(transport);
33293329

33303330
expect(mockConsoleLog).toHaveBeenCalledTimes(1);
3331-
// TODO: Support cyclic objects in console encoding.
3332-
// expect(mockConsoleLog.mock.calls[0][0]).toBe('hi');
3333-
// const cyclic2 = mockConsoleLog.mock.calls[0][1].cyclic;
3334-
// expect(cyclic2).not.toBe(cyclic); // Was serialized and therefore cloned
3335-
// expect(cyclic2.cycle).toBe(cyclic2);
3336-
expect(mockConsoleLog.mock.calls[0][0]).toBe(
3337-
'Unknown Value: React could not send it from the server.',
3338-
);
3339-
expect(mockConsoleLog.mock.calls[0][1].message).toBe(
3340-
'Converting circular structure to JSON\n' +
3341-
" --> starting at object with constructor 'Object'\n" +
3342-
" --- property 'cycle' closes the circle",
3343-
);
3331+
expect(mockConsoleLog.mock.calls[0][0]).toBe('hi');
3332+
const cyclic2 = mockConsoleLog.mock.calls[0][1].cyclic;
3333+
expect(cyclic2).not.toBe(cyclic); // Was serialized and therefore cloned
3334+
expect(cyclic2.cycle).toBe(cyclic2);
33443335
});
33453336

33463337
// @gate !__DEV__ || enableComponentPerformanceTrack

0 commit comments

Comments
 (0)