[Flight] Fully support serializing Map/Set in console logs (#30295)

Currently we serialize Map/Set through our regular flow and not the
console serialization. The console one is more forgiving than the
regular one.
This commit is contained in:
Sebastian Markbåge
2024-07-09 14:22:50 -04:00
committed by GitHub
parent ba95cf4b8f
commit 8aafbcf115
2 changed files with 32 additions and 3 deletions
+8 -1
View File
@@ -2628,7 +2628,7 @@ describe('ReactFlight', () => {
return 'hello';
}
function ServerComponent() {
console.log('hi', {prop: 123, fn: foo});
console.log('hi', {prop: 123, fn: foo, map: new Map([['foo', foo]])});
throw new Error('err');
}
@@ -2670,6 +2670,13 @@ describe('ReactFlight', () => {
expect(typeof loggedFn).toBe('function');
expect(loggedFn).not.toBe(foo);
expect(loggedFn.toString()).toBe(foo.toString());
const loggedMap = mockConsoleLog.mock.calls[0][1].map;
expect(loggedMap instanceof Map).toBe(true);
const loggedFn2 = loggedMap.get('foo');
expect(typeof loggedFn2).toBe('function');
expect(loggedFn2).not.toBe(foo);
expect(loggedFn2.toString()).toBe(foo.toString());
});
it('uses the server component debug info as the element owner in DEV', async () => {
+24 -2
View File
@@ -2021,6 +2021,28 @@ function serializeSet(request: Request, set: Set<ReactClientValue>): string {
return '$W' + id.toString(16);
}
function serializeConsoleMap(
request: Request,
counter: {objectCount: number},
map: Map<ReactClientValue, ReactClientValue>,
): string {
// Like serializeMap but for renderConsoleValue.
const entries = Array.from(map);
const id = outlineConsoleValue(request, counter, entries);
return '$Q' + id.toString(16);
}
function serializeConsoleSet(
request: Request,
counter: {objectCount: number},
set: Set<ReactClientValue>,
): string {
// Like serializeMap but for renderConsoleValue.
const entries = Array.from(set);
const id = outlineConsoleValue(request, counter, entries);
return '$W' + id.toString(16);
}
function serializeIterator(
request: Request,
iterator: Iterator<ReactClientValue>,
@@ -3220,10 +3242,10 @@ function renderConsoleValue(
}
if (value instanceof Map) {
return serializeMap(request, value);
return serializeConsoleMap(request, counter, value);
}
if (value instanceof Set) {
return serializeSet(request, value);
return serializeConsoleSet(request, counter, value);
}
// TODO: FormData is not available in old Node. Remove the typeof later.
if (typeof FormData === 'function' && value instanceof FormData) {