Skip to content

Commit 2b619ee

Browse files
committed
Track Owner for Server Components in DEV (#28753)
This implements the concept of a DEV-only "owner" for Server Components. The owner concept isn't really super useful. We barely use it anymore, but we do have it as a concept in DevTools in a couple of cases so this adds it for parity. However, this is mainly interesting because it could be used to wire up future owner-based stacks. I do this by outlining the DebugInfo for a Server Component (ReactComponentInfo). Then I just rely on Flight deduping to refer to that. I refer to the same thing by referential equality so that we can associate a Server Component parent in DebugInfo with an owner. If you suspend and replay a Server Component, we have to restore the same owner. To do that, I did a little ugly hack and stashed it on the thenable state object. Felt unnecessarily complicated to add a stateful wrapper for this one dev-only case. The owner could really be anything since it could be coming from a different implementation. Because this is the first time we have an owner other than Fiber, I have to fix up a bunch of places that assumes Fiber. I mainly did the `typeof owner.tag === 'number'` to assume it's a Fiber for now. This also doesn't actually add it to DevTools / RN Inspector yet. I just ignore them there for now. Because Server Components can be async the owner isn't tracked after an await. We need per-component AsyncLocalStorage for that. This can be done in a follow up. DiffTrain build for [e0455fe](e0455fe)
1 parent 60928e3 commit 2b619ee

30 files changed

+640
-475
lines changed

compiled/facebook-www/JSXDEVRuntime-dev.classic.js

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ if (__DEV__) {
471471

472472
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
473473
var prefix;
474-
function describeBuiltInComponentFrame(name, ownerFn) {
474+
function describeBuiltInComponentFrame(name) {
475475
{
476476
if (prefix === undefined) {
477477
// Extract the VM specific prefix used by each line.
@@ -740,7 +740,7 @@ if (__DEV__) {
740740

741741
return syntheticFrame;
742742
}
743-
function describeFunctionComponentFrame(fn, ownerFn) {
743+
function describeFunctionComponentFrame(fn) {
744744
{
745745
return describeNativeComponentFrame(fn, false);
746746
}
@@ -751,7 +751,7 @@ if (__DEV__) {
751751
return !!(prototype && prototype.isReactComponent);
752752
}
753753

754-
function describeUnknownElementTypeFrameInDEV(type, ownerFn) {
754+
function describeUnknownElementTypeFrameInDEV(type) {
755755
if (type == null) {
756756
return "";
757757
}
@@ -781,7 +781,7 @@ if (__DEV__) {
781781

782782
case REACT_MEMO_TYPE:
783783
// Memo may contain any component type so we recursively resolve it.
784-
return describeUnknownElementTypeFrameInDEV(type.type, ownerFn);
784+
return describeUnknownElementTypeFrameInDEV(type.type);
785785

786786
case REACT_LAZY_TYPE: {
787787
var lazyComponent = type;
@@ -790,10 +790,7 @@ if (__DEV__) {
790790

791791
try {
792792
// Lazy may contain any component type so we recursively resolve it.
793-
return describeUnknownElementTypeFrameInDEV(
794-
init(payload),
795-
ownerFn
796-
);
793+
return describeUnknownElementTypeFrameInDEV(init(payload));
797794
} catch (x) {}
798795
}
799796
}
@@ -1397,14 +1394,18 @@ if (__DEV__) {
13971394

13981395
if (
13991396
element &&
1400-
element._owner &&
1397+
element._owner != null &&
14011398
element._owner !== ReactCurrentOwner.current
14021399
) {
1403-
// Give the component that originally created this child.
1404-
childOwner =
1405-
" It was passed a child from " +
1406-
getComponentNameFromType(element._owner.type) +
1407-
".";
1400+
var ownerName = null;
1401+
1402+
if (typeof element._owner.tag === "number") {
1403+
ownerName = getComponentNameFromType(element._owner.type);
1404+
} else if (typeof element._owner.name === "string") {
1405+
ownerName = element._owner.name;
1406+
} // Give the component that originally created this child.
1407+
1408+
childOwner = " It was passed a child from " + ownerName + ".";
14081409
}
14091410

14101411
setCurrentlyValidatingElement(element);
@@ -1423,11 +1424,7 @@ if (__DEV__) {
14231424
function setCurrentlyValidatingElement(element) {
14241425
{
14251426
if (element) {
1426-
var owner = element._owner;
1427-
var stack = describeUnknownElementTypeFrameInDEV(
1428-
element.type,
1429-
owner ? owner.type : null
1430-
);
1427+
var stack = describeUnknownElementTypeFrameInDEV(element.type);
14311428
ReactDebugCurrentFrame.setExtraStackFrame(stack);
14321429
} else {
14331430
ReactDebugCurrentFrame.setExtraStackFrame(null);

compiled/facebook-www/JSXDEVRuntime-dev.modern.js

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,7 @@ if (__DEV__) {
471471

472472
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
473473
var prefix;
474-
function describeBuiltInComponentFrame(name, ownerFn) {
474+
function describeBuiltInComponentFrame(name) {
475475
{
476476
if (prefix === undefined) {
477477
// Extract the VM specific prefix used by each line.
@@ -740,7 +740,7 @@ if (__DEV__) {
740740

741741
return syntheticFrame;
742742
}
743-
function describeFunctionComponentFrame(fn, ownerFn) {
743+
function describeFunctionComponentFrame(fn) {
744744
{
745745
return describeNativeComponentFrame(fn, false);
746746
}
@@ -751,7 +751,7 @@ if (__DEV__) {
751751
return !!(prototype && prototype.isReactComponent);
752752
}
753753

754-
function describeUnknownElementTypeFrameInDEV(type, ownerFn) {
754+
function describeUnknownElementTypeFrameInDEV(type) {
755755
if (type == null) {
756756
return "";
757757
}
@@ -781,7 +781,7 @@ if (__DEV__) {
781781

782782
case REACT_MEMO_TYPE:
783783
// Memo may contain any component type so we recursively resolve it.
784-
return describeUnknownElementTypeFrameInDEV(type.type, ownerFn);
784+
return describeUnknownElementTypeFrameInDEV(type.type);
785785

786786
case REACT_LAZY_TYPE: {
787787
var lazyComponent = type;
@@ -790,10 +790,7 @@ if (__DEV__) {
790790

791791
try {
792792
// Lazy may contain any component type so we recursively resolve it.
793-
return describeUnknownElementTypeFrameInDEV(
794-
init(payload),
795-
ownerFn
796-
);
793+
return describeUnknownElementTypeFrameInDEV(init(payload));
797794
} catch (x) {}
798795
}
799796
}
@@ -1397,14 +1394,18 @@ if (__DEV__) {
13971394

13981395
if (
13991396
element &&
1400-
element._owner &&
1397+
element._owner != null &&
14011398
element._owner !== ReactCurrentOwner.current
14021399
) {
1403-
// Give the component that originally created this child.
1404-
childOwner =
1405-
" It was passed a child from " +
1406-
getComponentNameFromType(element._owner.type) +
1407-
".";
1400+
var ownerName = null;
1401+
1402+
if (typeof element._owner.tag === "number") {
1403+
ownerName = getComponentNameFromType(element._owner.type);
1404+
} else if (typeof element._owner.name === "string") {
1405+
ownerName = element._owner.name;
1406+
} // Give the component that originally created this child.
1407+
1408+
childOwner = " It was passed a child from " + ownerName + ".";
14081409
}
14091410

14101411
setCurrentlyValidatingElement(element);
@@ -1423,11 +1424,7 @@ if (__DEV__) {
14231424
function setCurrentlyValidatingElement(element) {
14241425
{
14251426
if (element) {
1426-
var owner = element._owner;
1427-
var stack = describeUnknownElementTypeFrameInDEV(
1428-
element.type,
1429-
owner ? owner.type : null
1430-
);
1427+
var stack = describeUnknownElementTypeFrameInDEV(element.type);
14311428
ReactDebugCurrentFrame.setExtraStackFrame(stack);
14321429
} else {
14331430
ReactDebugCurrentFrame.setExtraStackFrame(null);

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
48b4ecc9012638ed51b275aad24b2086b8215e32
1+
e0455fe62a648f541d2e029017465ae4b5f000a8

compiled/facebook-www/React-dev.classic.js

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if (__DEV__) {
2424
) {
2525
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
2626
}
27-
var ReactVersion = "19.0.0-www-classic-b9e0eea7";
27+
var ReactVersion = "19.0.0-www-classic-8aa01ae9";
2828

2929
// ATTENTION
3030
// When adding new symbols to this file,
@@ -843,7 +843,7 @@ if (__DEV__) {
843843

844844
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
845845
var prefix;
846-
function describeBuiltInComponentFrame(name, ownerFn) {
846+
function describeBuiltInComponentFrame(name) {
847847
{
848848
if (prefix === undefined) {
849849
// Extract the VM specific prefix used by each line.
@@ -1112,7 +1112,7 @@ if (__DEV__) {
11121112

11131113
return syntheticFrame;
11141114
}
1115-
function describeFunctionComponentFrame(fn, ownerFn) {
1115+
function describeFunctionComponentFrame(fn) {
11161116
{
11171117
return describeNativeComponentFrame(fn, false);
11181118
}
@@ -1123,7 +1123,7 @@ if (__DEV__) {
11231123
return !!(prototype && prototype.isReactComponent);
11241124
}
11251125

1126-
function describeUnknownElementTypeFrameInDEV(type, ownerFn) {
1126+
function describeUnknownElementTypeFrameInDEV(type) {
11271127
if (type == null) {
11281128
return "";
11291129
}
@@ -1153,7 +1153,7 @@ if (__DEV__) {
11531153

11541154
case REACT_MEMO_TYPE:
11551155
// Memo may contain any component type so we recursively resolve it.
1156-
return describeUnknownElementTypeFrameInDEV(type.type, ownerFn);
1156+
return describeUnknownElementTypeFrameInDEV(type.type);
11571157

11581158
case REACT_LAZY_TYPE: {
11591159
var lazyComponent = type;
@@ -1162,10 +1162,7 @@ if (__DEV__) {
11621162

11631163
try {
11641164
// Lazy may contain any component type so we recursively resolve it.
1165-
return describeUnknownElementTypeFrameInDEV(
1166-
init(payload),
1167-
ownerFn
1168-
);
1165+
return describeUnknownElementTypeFrameInDEV(init(payload));
11691166
} catch (x) {}
11701167
}
11711168
}
@@ -2097,14 +2094,18 @@ if (__DEV__) {
20972094

20982095
if (
20992096
element &&
2100-
element._owner &&
2097+
element._owner != null &&
21012098
element._owner !== ReactCurrentOwner.current
21022099
) {
2103-
// Give the component that originally created this child.
2104-
childOwner =
2105-
" It was passed a child from " +
2106-
getComponentNameFromType(element._owner.type) +
2107-
".";
2100+
var ownerName = null;
2101+
2102+
if (typeof element._owner.tag === "number") {
2103+
ownerName = getComponentNameFromType(element._owner.type);
2104+
} else if (typeof element._owner.name === "string") {
2105+
ownerName = element._owner.name;
2106+
} // Give the component that originally created this child.
2107+
2108+
childOwner = " It was passed a child from " + ownerName + ".";
21082109
}
21092110

21102111
setCurrentlyValidatingElement(element);
@@ -2123,11 +2124,7 @@ if (__DEV__) {
21232124
function setCurrentlyValidatingElement(element) {
21242125
{
21252126
if (element) {
2126-
var owner = element._owner;
2127-
var stack = describeUnknownElementTypeFrameInDEV(
2128-
element.type,
2129-
owner ? owner.type : null
2130-
);
2127+
var stack = describeUnknownElementTypeFrameInDEV(element.type);
21312128
ReactDebugCurrentFrame.setExtraStackFrame(stack);
21322129
} else {
21332130
ReactDebugCurrentFrame.setExtraStackFrame(null);

compiled/facebook-www/React-dev.modern.js

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ if (__DEV__) {
2424
) {
2525
__REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
2626
}
27-
var ReactVersion = "19.0.0-www-modern-3a8173ed";
27+
var ReactVersion = "19.0.0-www-modern-ab03ab4b";
2828

2929
// ATTENTION
3030
// When adding new symbols to this file,
@@ -843,7 +843,7 @@ if (__DEV__) {
843843

844844
var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
845845
var prefix;
846-
function describeBuiltInComponentFrame(name, ownerFn) {
846+
function describeBuiltInComponentFrame(name) {
847847
{
848848
if (prefix === undefined) {
849849
// Extract the VM specific prefix used by each line.
@@ -1112,7 +1112,7 @@ if (__DEV__) {
11121112

11131113
return syntheticFrame;
11141114
}
1115-
function describeFunctionComponentFrame(fn, ownerFn) {
1115+
function describeFunctionComponentFrame(fn) {
11161116
{
11171117
return describeNativeComponentFrame(fn, false);
11181118
}
@@ -1123,7 +1123,7 @@ if (__DEV__) {
11231123
return !!(prototype && prototype.isReactComponent);
11241124
}
11251125

1126-
function describeUnknownElementTypeFrameInDEV(type, ownerFn) {
1126+
function describeUnknownElementTypeFrameInDEV(type) {
11271127
if (type == null) {
11281128
return "";
11291129
}
@@ -1153,7 +1153,7 @@ if (__DEV__) {
11531153

11541154
case REACT_MEMO_TYPE:
11551155
// Memo may contain any component type so we recursively resolve it.
1156-
return describeUnknownElementTypeFrameInDEV(type.type, ownerFn);
1156+
return describeUnknownElementTypeFrameInDEV(type.type);
11571157

11581158
case REACT_LAZY_TYPE: {
11591159
var lazyComponent = type;
@@ -1162,10 +1162,7 @@ if (__DEV__) {
11621162

11631163
try {
11641164
// Lazy may contain any component type so we recursively resolve it.
1165-
return describeUnknownElementTypeFrameInDEV(
1166-
init(payload),
1167-
ownerFn
1168-
);
1165+
return describeUnknownElementTypeFrameInDEV(init(payload));
11691166
} catch (x) {}
11701167
}
11711168
}
@@ -2097,14 +2094,18 @@ if (__DEV__) {
20972094

20982095
if (
20992096
element &&
2100-
element._owner &&
2097+
element._owner != null &&
21012098
element._owner !== ReactCurrentOwner.current
21022099
) {
2103-
// Give the component that originally created this child.
2104-
childOwner =
2105-
" It was passed a child from " +
2106-
getComponentNameFromType(element._owner.type) +
2107-
".";
2100+
var ownerName = null;
2101+
2102+
if (typeof element._owner.tag === "number") {
2103+
ownerName = getComponentNameFromType(element._owner.type);
2104+
} else if (typeof element._owner.name === "string") {
2105+
ownerName = element._owner.name;
2106+
} // Give the component that originally created this child.
2107+
2108+
childOwner = " It was passed a child from " + ownerName + ".";
21082109
}
21092110

21102111
setCurrentlyValidatingElement(element);
@@ -2123,11 +2124,7 @@ if (__DEV__) {
21232124
function setCurrentlyValidatingElement(element) {
21242125
{
21252126
if (element) {
2126-
var owner = element._owner;
2127-
var stack = describeUnknownElementTypeFrameInDEV(
2128-
element.type,
2129-
owner ? owner.type : null
2130-
);
2127+
var stack = describeUnknownElementTypeFrameInDEV(element.type);
21312128
ReactDebugCurrentFrame.setExtraStackFrame(stack);
21322129
} else {
21332130
ReactDebugCurrentFrame.setExtraStackFrame(null);

0 commit comments

Comments
 (0)