@@ -5721,6 +5721,7 @@ export function attach(
57215721
57225722 function getSuspendedByOfSuspenseNode(
57235723 suspenseNode: SuspenseNode,
5724+ filterByChildInstance: null | DevToolsInstance, // only include suspended by instances in this subtree
57245725 ): Array<SerializedAsyncInfo> {
57255726 // Collect all ReactAsyncInfo that was suspending this SuspenseNode but
57265727 // isn't also in any parent set.
@@ -5756,8 +5757,30 @@ export function attach(
57565757 if (set.size === 0) {
57575758 return;
57585759 }
5759- const firstInstance: DevToolsInstance = (set.values().next().value: any);
5760- if (firstInstance.suspendedBy !== null) {
5760+ let firstInstance: null | DevToolsInstance = null;
5761+ if (filterByChildInstance === null) {
5762+ firstInstance = (set.values().next().value: any);
5763+ } else {
5764+ // eslint-disable-next-line no-for-of-loops/no-for-of-loops
5765+ for (const childInstance of set.values()) {
5766+ if (firstInstance === null) {
5767+ firstInstance = childInstance;
5768+ }
5769+ if (
5770+ childInstance !== filterByChildInstance &&
5771+ !isChildOf(
5772+ filterByChildInstance,
5773+ childInstance,
5774+ suspenseNode.instance,
5775+ )
5776+ ) {
5777+ // Something suspended on this outside the filtered instance. That means that
5778+ // it is not unique to just this filtered instance so we skip including it.
5779+ return;
5780+ }
5781+ }
5782+ }
5783+ if (firstInstance !== null && firstInstance.suspendedBy !== null) {
57615784 const asyncInfo = getAwaitInSuspendedByFromIO(
57625785 firstInstance.suspendedBy,
57635786 ioInfo,
@@ -5870,6 +5893,23 @@ export function attach(
58705893 return result;
58715894 }
58725895
5896+ function getSuspendedByOfInstanceSubtree(
5897+ devtoolsInstance: DevToolsInstance,
5898+ ): Array<SerializedAsyncInfo> {
5899+ // Get everything suspending below this instance down to the next Suspense node.
5900+ // First find the parent Suspense boundary which will have accumulated everything
5901+ let suspenseParentInstance = devtoolsInstance;
5902+ while (suspenseParentInstance.suspenseNode === null) {
5903+ if (suspenseParentInstance.parent === null) {
5904+ // We don't expect to hit this. We should always find the root.
5905+ return [];
5906+ }
5907+ suspenseParentInstance = suspenseParentInstance.parent;
5908+ }
5909+ const suspenseNode: SuspenseNode = suspenseParentInstance.suspenseNode;
5910+ return getSuspendedByOfSuspenseNode(suspenseNode, devtoolsInstance);
5911+ }
5912+
58735913 const FALLBACK_THROTTLE_MS: number = 300;
58745914
58755915 function getSuspendedByRange(
@@ -6383,13 +6423,17 @@ export function attach(
63836423 fiberInstance.suspenseNode !== null
63846424 ? // If this is a Suspense boundary, then we include everything in the subtree that might suspend
63856425 // this boundary down to the next Suspense boundary.
6386- getSuspendedByOfSuspenseNode(fiberInstance.suspenseNode)
6387- : // This set is an edge case where if you pass a promise to a Client Component into a children
6388- // position without a Server Component as the direct parent. E.g. <div>{promise}</div>
6389- // In this case, this becomes associated with the Client/Host Component where as normally
6390- // you'd expect these to be associated with the Server Component that awaited the data.
6391- // TODO: Prepend other suspense sources like css, images and use().
6392- getSuspendedByOfInstance(fiberInstance, hooks);
6426+ getSuspendedByOfSuspenseNode(fiberInstance.suspenseNode, null)
6427+ : tag === ActivityComponent
6428+ ? // For Activity components we show everything that suspends the subtree down to the next boundary
6429+ // so that you can see what suspends a Transition at that level.
6430+ getSuspendedByOfInstanceSubtree(fiberInstance)
6431+ : // This set is an edge case where if you pass a promise to a Client Component into a children
6432+ // position without a Server Component as the direct parent. E.g. <div>{promise}</div>
6433+ // In this case, this becomes associated with the Client/Host Component where as normally
6434+ // you'd expect these to be associated with the Server Component that awaited the data.
6435+ // TODO: Prepend other suspense sources like css, images and use().
6436+ getSuspendedByOfInstance(fiberInstance, hooks);
63936437 const suspendedByRange = getSuspendedByRange(
63946438 getNearestSuspenseNode(fiberInstance),
63956439 );
0 commit comments