Skip to content

Commit bb28bb0

Browse files
committed
Move performance track property serialization to shared
1 parent 31d9165 commit bb28bb0

File tree

4 files changed

+139
-126
lines changed

4 files changed

+139
-126
lines changed

packages/react-client/src/ReactFlightClient.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ import {getOwnerStackByComponentInfoInDev} from 'shared/ReactComponentInfoStack'
100100

101101
import {injectInternals} from './ReactFlightClientDevToolsHook';
102102

103-
import {OMITTED_PROP_ERROR} from './ReactFlightPropertyAccess';
103+
import {OMITTED_PROP_ERROR} from 'shared/ReactFlightPropertyAccess';
104104

105105
import ReactVersion from 'shared/ReactVersion';
106106

packages/react-client/src/ReactFlightPerformanceTrack.js

Lines changed: 4 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ import type {
1717

1818
import {enableProfilerTimer} from 'shared/ReactFeatureFlags';
1919

20-
import {OMITTED_PROP_ERROR} from './ReactFlightPropertyAccess';
21-
22-
import hasOwnProperty from 'shared/hasOwnProperty';
23-
import isArray from 'shared/isArray';
20+
import {
21+
addValueToProperties,
22+
addObjectToProperties,
23+
} from 'shared/ReactPerformanceTrackProperties';
2424

2525
const supportsUserTiming =
2626
enableProfilerTimer &&
@@ -33,127 +33,6 @@ const supportsUserTiming =
3333
const IO_TRACK = 'Server Requests ⚛';
3434
const COMPONENTS_TRACK = 'Server Components ⚛';
3535

36-
const EMPTY_ARRAY = 0;
37-
const COMPLEX_ARRAY = 1;
38-
const PRIMITIVE_ARRAY = 2; // Primitive values only
39-
const ENTRIES_ARRAY = 3; // Tuple arrays of string and value (like Headers, Map, etc)
40-
function getArrayKind(array: Object): 0 | 1 | 2 | 3 {
41-
let kind = EMPTY_ARRAY;
42-
for (let i = 0; i < array.length; i++) {
43-
const value = array[i];
44-
if (typeof value === 'object' && value !== null) {
45-
if (
46-
isArray(value) &&
47-
value.length === 2 &&
48-
typeof value[0] === 'string'
49-
) {
50-
// Key value tuple
51-
if (kind !== EMPTY_ARRAY && kind !== ENTRIES_ARRAY) {
52-
return COMPLEX_ARRAY;
53-
}
54-
kind = ENTRIES_ARRAY;
55-
} else {
56-
return COMPLEX_ARRAY;
57-
}
58-
} else if (typeof value === 'function') {
59-
return COMPLEX_ARRAY;
60-
} else if (typeof value === 'string' && value.length > 50) {
61-
return COMPLEX_ARRAY;
62-
} else if (kind !== EMPTY_ARRAY && kind !== PRIMITIVE_ARRAY) {
63-
return COMPLEX_ARRAY;
64-
} else {
65-
kind = PRIMITIVE_ARRAY;
66-
}
67-
}
68-
return kind;
69-
}
70-
71-
function addObjectToProperties(
72-
object: Object,
73-
properties: Array<[string, string]>,
74-
indent: number,
75-
): void {
76-
for (const key in object) {
77-
if (hasOwnProperty.call(object, key) && key[0] !== '_') {
78-
const value = object[key];
79-
addValueToProperties(key, value, properties, indent);
80-
}
81-
}
82-
}
83-
84-
function addValueToProperties(
85-
propertyName: string,
86-
value: mixed,
87-
properties: Array<[string, string]>,
88-
indent: number,
89-
): void {
90-
let desc;
91-
switch (typeof value) {
92-
case 'object':
93-
if (value === null) {
94-
desc = 'null';
95-
break;
96-
} else {
97-
// $FlowFixMe[method-unbinding]
98-
const objectToString = Object.prototype.toString.call(value);
99-
let objectName = objectToString.slice(8, objectToString.length - 1);
100-
if (objectName === 'Array') {
101-
const array: Array<any> = (value: any);
102-
const kind = getArrayKind(array);
103-
if (kind === PRIMITIVE_ARRAY || kind === EMPTY_ARRAY) {
104-
desc = JSON.stringify(array);
105-
break;
106-
} else if (kind === ENTRIES_ARRAY) {
107-
properties.push(['\xa0\xa0'.repeat(indent) + propertyName, '']);
108-
for (let i = 0; i < array.length; i++) {
109-
const entry = array[i];
110-
addValueToProperties(entry[0], entry[1], properties, indent + 1);
111-
}
112-
return;
113-
}
114-
}
115-
if (objectName === 'Object') {
116-
const proto: any = Object.getPrototypeOf(value);
117-
if (proto && typeof proto.constructor === 'function') {
118-
objectName = proto.constructor.name;
119-
}
120-
}
121-
properties.push([
122-
'\xa0\xa0'.repeat(indent) + propertyName,
123-
objectName === 'Object' ? '' : objectName,
124-
]);
125-
if (indent < 3) {
126-
addObjectToProperties(value, properties, indent + 1);
127-
}
128-
return;
129-
}
130-
case 'function':
131-
if (value.name === '') {
132-
desc = '() => {}';
133-
} else {
134-
desc = value.name + '() {}';
135-
}
136-
break;
137-
case 'string':
138-
if (value === OMITTED_PROP_ERROR) {
139-
desc = '...';
140-
} else {
141-
desc = JSON.stringify(value);
142-
}
143-
break;
144-
case 'undefined':
145-
desc = 'undefined';
146-
break;
147-
case 'boolean':
148-
desc = value ? 'true' : 'false';
149-
break;
150-
default:
151-
// eslint-disable-next-line react-internal/safe-string-coercion
152-
desc = String(value);
153-
}
154-
properties.push(['\xa0\xa0'.repeat(indent) + propertyName, desc]);
155-
}
156-
15736
export function markAllTracksInOrder() {
15837
if (supportsUserTiming) {
15938
// Ensure we create the Server Component track groups earlier than the Client Scheduler
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow
8+
*/
9+
10+
import {OMITTED_PROP_ERROR} from 'shared/ReactFlightPropertyAccess';
11+
12+
import hasOwnProperty from 'shared/hasOwnProperty';
13+
import isArray from 'shared/isArray';
14+
15+
const EMPTY_ARRAY = 0;
16+
const COMPLEX_ARRAY = 1;
17+
const PRIMITIVE_ARRAY = 2; // Primitive values only
18+
const ENTRIES_ARRAY = 3; // Tuple arrays of string and value (like Headers, Map, etc)
19+
function getArrayKind(array: Object): 0 | 1 | 2 | 3 {
20+
let kind = EMPTY_ARRAY;
21+
for (let i = 0; i < array.length; i++) {
22+
const value = array[i];
23+
if (typeof value === 'object' && value !== null) {
24+
if (
25+
isArray(value) &&
26+
value.length === 2 &&
27+
typeof value[0] === 'string'
28+
) {
29+
// Key value tuple
30+
if (kind !== EMPTY_ARRAY && kind !== ENTRIES_ARRAY) {
31+
return COMPLEX_ARRAY;
32+
}
33+
kind = ENTRIES_ARRAY;
34+
} else {
35+
return COMPLEX_ARRAY;
36+
}
37+
} else if (typeof value === 'function') {
38+
return COMPLEX_ARRAY;
39+
} else if (typeof value === 'string' && value.length > 50) {
40+
return COMPLEX_ARRAY;
41+
} else if (kind !== EMPTY_ARRAY && kind !== PRIMITIVE_ARRAY) {
42+
return COMPLEX_ARRAY;
43+
} else {
44+
kind = PRIMITIVE_ARRAY;
45+
}
46+
}
47+
return kind;
48+
}
49+
50+
export function addObjectToProperties(
51+
object: Object,
52+
properties: Array<[string, string]>,
53+
indent: number,
54+
): void {
55+
for (const key in object) {
56+
if (hasOwnProperty.call(object, key) && key[0] !== '_') {
57+
const value = object[key];
58+
addValueToProperties(key, value, properties, indent);
59+
}
60+
}
61+
}
62+
63+
export function addValueToProperties(
64+
propertyName: string,
65+
value: mixed,
66+
properties: Array<[string, string]>,
67+
indent: number,
68+
): void {
69+
let desc;
70+
switch (typeof value) {
71+
case 'object':
72+
if (value === null) {
73+
desc = 'null';
74+
break;
75+
} else {
76+
// $FlowFixMe[method-unbinding]
77+
const objectToString = Object.prototype.toString.call(value);
78+
let objectName = objectToString.slice(8, objectToString.length - 1);
79+
if (objectName === 'Array') {
80+
const array: Array<any> = (value: any);
81+
const kind = getArrayKind(array);
82+
if (kind === PRIMITIVE_ARRAY || kind === EMPTY_ARRAY) {
83+
desc = JSON.stringify(array);
84+
break;
85+
} else if (kind === ENTRIES_ARRAY) {
86+
properties.push(['\xa0\xa0'.repeat(indent) + propertyName, '']);
87+
for (let i = 0; i < array.length; i++) {
88+
const entry = array[i];
89+
addValueToProperties(entry[0], entry[1], properties, indent + 1);
90+
}
91+
return;
92+
}
93+
}
94+
if (objectName === 'Object') {
95+
const proto: any = Object.getPrototypeOf(value);
96+
if (proto && typeof proto.constructor === 'function') {
97+
objectName = proto.constructor.name;
98+
}
99+
}
100+
properties.push([
101+
'\xa0\xa0'.repeat(indent) + propertyName,
102+
objectName === 'Object' ? '' : objectName,
103+
]);
104+
if (indent < 3) {
105+
addObjectToProperties(value, properties, indent + 1);
106+
}
107+
return;
108+
}
109+
case 'function':
110+
if (value.name === '') {
111+
desc = '() => {}';
112+
} else {
113+
desc = value.name + '() {}';
114+
}
115+
break;
116+
case 'string':
117+
if (value === OMITTED_PROP_ERROR) {
118+
desc = '...';
119+
} else {
120+
desc = JSON.stringify(value);
121+
}
122+
break;
123+
case 'undefined':
124+
desc = 'undefined';
125+
break;
126+
case 'boolean':
127+
desc = value ? 'true' : 'false';
128+
break;
129+
default:
130+
// eslint-disable-next-line react-internal/safe-string-coercion
131+
desc = String(value);
132+
}
133+
properties.push(['\xa0\xa0'.repeat(indent) + propertyName, desc]);
134+
}

0 commit comments

Comments
 (0)