Skip to content

Commit

Permalink
Track Owner for Server Components in DEV (#28753)
Browse files Browse the repository at this point in the history
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 commit f33a6b6.
  • Loading branch information
sebmarkbage committed Apr 5, 2024
1 parent aecaccf commit 6eddd13
Show file tree
Hide file tree
Showing 13 changed files with 361 additions and 437 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<98fc293dc2ddd5bd7ffa9ec7eb7ac707>>
* @generated SignedSource<<fa29b2fc6de1e6452849c40ebd890ad7>>
*/

"use strict";
Expand Down Expand Up @@ -349,6 +349,17 @@ if (__DEV__) {
return type.displayName || "Context";
}

function getComponentNameFromOwner(owner) {
if (typeof owner.tag === "number") {
return getComponentNameFromFiber(owner);
}

if (typeof owner.name === "string") {
return owner.name;
}

return null;
}
function getComponentNameFromFiber(fiber) {
var tag = fiber.tag,
type = fiber.type;
Expand Down Expand Up @@ -2881,21 +2892,14 @@ if (__DEV__) {

var objectIs = typeof Object.is === "function" ? Object.is : is; // $FlowFixMe[method-unbinding]

function describeBuiltInComponentFrame(name, ownerFn) {
function describeBuiltInComponentFrame(name) {
{
var ownerName = null;

if (ownerFn) {
ownerName = ownerFn.displayName || ownerFn.name || null;
}

return describeComponentFrame(name, ownerName);
return describeComponentFrame(name);
}
}
function describeDebugInfoFrame(name, env) {
return describeBuiltInComponentFrame(
name + (env ? " (" + env + ")" : ""),
null
name + (env ? " (" + env + ")" : "")
);
}

Expand All @@ -2904,65 +2908,51 @@ if (__DEV__) {
new PossiblyWeakMap$1();
}

function describeComponentFrame(name, ownerName) {
var sourceInfo = "";

if (ownerName) {
sourceInfo = " (created by " + ownerName + ")";
}

return "\n in " + (name || "Unknown") + sourceInfo;
function describeComponentFrame(name) {
return "\n in " + (name || "Unknown");
}

function describeClassComponentFrame(ctor, ownerFn) {
function describeClassComponentFrame(ctor) {
{
return describeFunctionComponentFrame(ctor, ownerFn);
return describeFunctionComponentFrame(ctor);
}
}
function describeFunctionComponentFrame(fn, ownerFn) {
function describeFunctionComponentFrame(fn) {
{
if (!fn) {
return "";
}

var name = fn.displayName || fn.name || null;
var ownerName = null;

if (ownerFn) {
ownerName = ownerFn.displayName || ownerFn.name || null;
}

return describeComponentFrame(name, ownerName);
return describeComponentFrame(name);
}
}

function describeFiber(fiber) {
var owner = fiber._debugOwner ? fiber._debugOwner.type : null;

switch (fiber.tag) {
case HostHoistable:
case HostSingleton:
case HostComponent:
return describeBuiltInComponentFrame(fiber.type, owner);
return describeBuiltInComponentFrame(fiber.type);

case LazyComponent:
return describeBuiltInComponentFrame("Lazy", owner);
return describeBuiltInComponentFrame("Lazy");

case SuspenseComponent:
return describeBuiltInComponentFrame("Suspense", owner);
return describeBuiltInComponentFrame("Suspense");

case SuspenseListComponent:
return describeBuiltInComponentFrame("SuspenseList", owner);
return describeBuiltInComponentFrame("SuspenseList");

case FunctionComponent:
case SimpleMemoComponent:
return describeFunctionComponentFrame(fiber.type, owner);
return describeFunctionComponentFrame(fiber.type);

case ForwardRef:
return describeFunctionComponentFrame(fiber.type.render, owner);
return describeFunctionComponentFrame(fiber.type.render);

case ClassComponent:
return describeClassComponentFrame(fiber.type, owner);
return describeClassComponentFrame(fiber.type);

default:
return "";
Expand Down Expand Up @@ -5253,8 +5243,8 @@ if (__DEV__) {

var owner = current._debugOwner;

if (owner !== null && typeof owner !== "undefined") {
return getComponentNameFromFiber(owner);
if (owner != null) {
return getComponentNameFromOwner(owner);
}
}

Expand Down Expand Up @@ -26367,7 +26357,7 @@ if (__DEV__) {
"named imports.";
}

var ownerName = owner ? getComponentNameFromFiber(owner) : null;
var ownerName = owner ? getComponentNameFromOwner(owner) : null;

if (ownerName) {
info += "\n\nCheck the render method of `" + ownerName + "`.";
Expand Down Expand Up @@ -26630,7 +26620,7 @@ if (__DEV__) {
return root;
}

var ReactVersion = "19.0.0-canary-fbd6543d";
var ReactVersion = "19.0.0-canary-2f991a8a";

/*
* The `'' + value` pattern (used in perf-sensitive code) throws for Symbol
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<06b7bf08ce800f028055b90ac4c262ac>>
* @generated SignedSource<<c280d92632a452d04a57733b09d6735d>>
*/

"use strict";
Expand Down Expand Up @@ -654,28 +654,24 @@ function is(x, y) {
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
}
var objectIs = "function" === typeof Object.is ? Object.is : is;
function describeComponentFrame(name, ownerName) {
var sourceInfo = "";
ownerName && (sourceInfo = " (created by " + ownerName + ")");
return "\n in " + (name || "Unknown") + sourceInfo;
function describeBuiltInComponentFrame(name) {
return "\n in " + (name || "Unknown");
}
function describeFunctionComponentFrame(fn) {
return fn
? describeComponentFrame(fn.displayName || fn.name || null, null)
: "";
return fn ? "\n in " + (fn.displayName || fn.name || "Unknown") : "";
}
function describeFiber(fiber) {
switch (fiber.tag) {
case 26:
case 27:
case 5:
return describeComponentFrame(fiber.type, null);
return describeBuiltInComponentFrame(fiber.type);
case 16:
return describeComponentFrame("Lazy", null);
return describeBuiltInComponentFrame("Lazy");
case 13:
return describeComponentFrame("Suspense", null);
return describeBuiltInComponentFrame("Suspense");
case 19:
return describeComponentFrame("SuspenseList", null);
return describeBuiltInComponentFrame("SuspenseList");
case 0:
case 15:
return describeFunctionComponentFrame(fiber.type);
Expand Down Expand Up @@ -9153,19 +9149,19 @@ function wrapFiber(fiber) {
fiberToWrapper.set(fiber, wrapper));
return wrapper;
}
var devToolsConfig$jscomp$inline_995 = {
var devToolsConfig$jscomp$inline_994 = {
findFiberByHostInstance: function () {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-canary-6296ea1f",
version: "19.0.0-canary-f92daaf1",
rendererPackageName: "react-test-renderer"
};
var internals$jscomp$inline_1215 = {
bundleType: devToolsConfig$jscomp$inline_995.bundleType,
version: devToolsConfig$jscomp$inline_995.version,
rendererPackageName: devToolsConfig$jscomp$inline_995.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_995.rendererConfig,
var internals$jscomp$inline_1214 = {
bundleType: devToolsConfig$jscomp$inline_994.bundleType,
version: devToolsConfig$jscomp$inline_994.version,
rendererPackageName: devToolsConfig$jscomp$inline_994.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_994.rendererConfig,
overrideHookState: null,
overrideHookStateDeletePath: null,
overrideHookStateRenamePath: null,
Expand All @@ -9182,26 +9178,26 @@ var internals$jscomp$inline_1215 = {
return null === fiber ? null : fiber.stateNode;
},
findFiberByHostInstance:
devToolsConfig$jscomp$inline_995.findFiberByHostInstance ||
devToolsConfig$jscomp$inline_994.findFiberByHostInstance ||
emptyFindFiberByHostInstance,
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-canary-6296ea1f"
reconcilerVersion: "19.0.0-canary-f92daaf1"
};
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
var hook$jscomp$inline_1216 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
var hook$jscomp$inline_1215 = __REACT_DEVTOOLS_GLOBAL_HOOK__;
if (
!hook$jscomp$inline_1216.isDisabled &&
hook$jscomp$inline_1216.supportsFiber
!hook$jscomp$inline_1215.isDisabled &&
hook$jscomp$inline_1215.supportsFiber
)
try {
(rendererID = hook$jscomp$inline_1216.inject(
internals$jscomp$inline_1215
(rendererID = hook$jscomp$inline_1215.inject(
internals$jscomp$inline_1214
)),
(injectedHook = hook$jscomp$inline_1216);
(injectedHook = hook$jscomp$inline_1215);
} catch (err) {}
}
exports._Scheduler = Scheduler;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
* @noflow
* @nolint
* @preventMunge
* @generated SignedSource<<4f09bf783fcfd1bedefb736ffc52c17b>>
* @generated SignedSource<<74899a6d3fe92773c2f385a9916407bb>>
*/

"use strict";
Expand Down Expand Up @@ -742,28 +742,24 @@ function is(x, y) {
return (x === y && (0 !== x || 1 / x === 1 / y)) || (x !== x && y !== y);
}
var objectIs = "function" === typeof Object.is ? Object.is : is;
function describeComponentFrame(name, ownerName) {
var sourceInfo = "";
ownerName && (sourceInfo = " (created by " + ownerName + ")");
return "\n in " + (name || "Unknown") + sourceInfo;
function describeBuiltInComponentFrame(name) {
return "\n in " + (name || "Unknown");
}
function describeFunctionComponentFrame(fn) {
return fn
? describeComponentFrame(fn.displayName || fn.name || null, null)
: "";
return fn ? "\n in " + (fn.displayName || fn.name || "Unknown") : "";
}
function describeFiber(fiber) {
switch (fiber.tag) {
case 26:
case 27:
case 5:
return describeComponentFrame(fiber.type, null);
return describeBuiltInComponentFrame(fiber.type);
case 16:
return describeComponentFrame("Lazy", null);
return describeBuiltInComponentFrame("Lazy");
case 13:
return describeComponentFrame("Suspense", null);
return describeBuiltInComponentFrame("Suspense");
case 19:
return describeComponentFrame("SuspenseList", null);
return describeBuiltInComponentFrame("SuspenseList");
case 0:
case 15:
return describeFunctionComponentFrame(fiber.type);
Expand Down Expand Up @@ -9769,12 +9765,12 @@ function wrapFiber(fiber) {
fiberToWrapper.set(fiber, wrapper));
return wrapper;
}
var devToolsConfig$jscomp$inline_1079 = {
var devToolsConfig$jscomp$inline_1078 = {
findFiberByHostInstance: function () {
throw Error("TestRenderer does not support findFiberByHostInstance()");
},
bundleType: 0,
version: "19.0.0-canary-99936a6e",
version: "19.0.0-canary-aa699661",
rendererPackageName: "react-test-renderer"
};
(function (internals) {
Expand All @@ -9791,10 +9787,10 @@ var devToolsConfig$jscomp$inline_1079 = {
} catch (err) {}
return hook.checkDCE ? !0 : !1;
})({
bundleType: devToolsConfig$jscomp$inline_1079.bundleType,
version: devToolsConfig$jscomp$inline_1079.version,
rendererPackageName: devToolsConfig$jscomp$inline_1079.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1079.rendererConfig,
bundleType: devToolsConfig$jscomp$inline_1078.bundleType,
version: devToolsConfig$jscomp$inline_1078.version,
rendererPackageName: devToolsConfig$jscomp$inline_1078.rendererPackageName,
rendererConfig: devToolsConfig$jscomp$inline_1078.rendererConfig,
overrideHookState: null,
overrideHookStateDeletePath: null,
overrideHookStateRenamePath: null,
Expand All @@ -9811,14 +9807,14 @@ var devToolsConfig$jscomp$inline_1079 = {
return null === fiber ? null : fiber.stateNode;
},
findFiberByHostInstance:
devToolsConfig$jscomp$inline_1079.findFiberByHostInstance ||
devToolsConfig$jscomp$inline_1078.findFiberByHostInstance ||
emptyFindFiberByHostInstance,
findHostInstancesForRefresh: null,
scheduleRefresh: null,
scheduleRoot: null,
setRefreshHandler: null,
getCurrentFiber: null,
reconcilerVersion: "19.0.0-canary-99936a6e"
reconcilerVersion: "19.0.0-canary-aa699661"
});
exports._Scheduler = Scheduler;
exports.act = act;
Expand Down
Loading

0 comments on commit 6eddd13

Please sign in to comment.