Skip to content

Commit 1a971d7

Browse files
committed
[Fiber] Support AsyncIterable children in SuspenseList (#33299)
We support AsyncIterable (more so when it's a cached form like in coming from Flight) as children. This fixes some warnings and bugs when passed to SuspenseList. Ideally SuspenseList with `tail="hidden"` should support unblocking before the full result has resolved but that's an optimization on top. We also might want to change semantics for this for `revealOrder="backwards"` so it becomes possible to stream items in reverse order. DiffTrain build for [4c6967b](4c6967b)
1 parent 2ca88df commit 1a971d7

35 files changed

+1047
-866
lines changed

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c6c2a52ad8fb1894b03a3bb618eb57e5deca5aa0
1+
4c6967be290fc31182c61cfdac19915fdb16aa60
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
c6c2a52ad8fb1894b03a3bb618eb57e5deca5aa0
1+
4c6967be290fc31182c61cfdac19915fdb16aa60

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,7 @@ __DEV__ &&
15371537
exports.useTransition = function () {
15381538
return resolveDispatcher().useTransition();
15391539
};
1540-
exports.version = "19.2.0-www-classic-c6c2a52a-20250519";
1540+
exports.version = "19.2.0-www-classic-4c6967be-20250520";
15411541
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
15421542
"function" ===
15431543
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,7 @@ __DEV__ &&
15371537
exports.useTransition = function () {
15381538
return resolveDispatcher().useTransition();
15391539
};
1540-
exports.version = "19.2.0-www-modern-c6c2a52a-20250519";
1540+
exports.version = "19.2.0-www-modern-4c6967be-20250520";
15411541
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
15421542
"function" ===
15431543
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,4 +635,4 @@ exports.useSyncExternalStore = function (
635635
exports.useTransition = function () {
636636
return ReactSharedInternals.H.useTransition();
637637
};
638-
exports.version = "19.2.0-www-classic-c6c2a52a-20250519";
638+
exports.version = "19.2.0-www-classic-4c6967be-20250520";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -635,4 +635,4 @@ exports.useSyncExternalStore = function (
635635
exports.useTransition = function () {
636636
return ReactSharedInternals.H.useTransition();
637637
};
638-
exports.version = "19.2.0-www-modern-c6c2a52a-20250519";
638+
exports.version = "19.2.0-www-modern-4c6967be-20250520";

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ exports.useSyncExternalStore = function (
639639
exports.useTransition = function () {
640640
return ReactSharedInternals.H.useTransition();
641641
};
642-
exports.version = "19.2.0-www-classic-c6c2a52a-20250519";
642+
exports.version = "19.2.0-www-classic-4c6967be-20250520";
643643
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
644644
"function" ===
645645
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -639,7 +639,7 @@ exports.useSyncExternalStore = function (
639639
exports.useTransition = function () {
640640
return ReactSharedInternals.H.useTransition();
641641
};
642-
exports.version = "19.2.0-www-modern-c6c2a52a-20250519";
642+
exports.version = "19.2.0-www-modern-4c6967be-20250520";
643643
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
644644
"function" ===
645645
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

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

Lines changed: 71 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -4251,6 +4251,20 @@ __DEV__ &&
42514251
}
42524252
};
42534253
}
4254+
function validateSuspenseListNestedChild(childSlot, index) {
4255+
var isAnArray = isArrayImpl(childSlot);
4256+
childSlot = !isAnArray && "function" === typeof getIteratorFn(childSlot);
4257+
return isAnArray || childSlot
4258+
? ((isAnArray = isAnArray ? "array" : "iterable"),
4259+
console.error(
4260+
"A nested %s was passed to row #%s in <SuspenseList />. Wrap it in an additional SuspenseList to configure its revealOrder: <SuspenseList revealOrder=...> ... <SuspenseList revealOrder=...>{%s}</SuspenseList> ... </SuspenseList>",
4261+
isAnArray,
4262+
index,
4263+
isAnArray
4264+
),
4265+
!1)
4266+
: !0;
4267+
}
42544268
function finishQueueingConcurrentUpdates() {
42554269
for (
42564270
var endIndex = concurrentQueuesIndex,
@@ -8323,20 +8337,6 @@ __DEV__ &&
83238337
propagationRoot
83248338
);
83258339
}
8326-
function validateSuspenseListNestedChild(childSlot, index) {
8327-
var isAnArray = isArrayImpl(childSlot);
8328-
childSlot = !isAnArray && "function" === typeof getIteratorFn(childSlot);
8329-
return isAnArray || childSlot
8330-
? ((isAnArray = isAnArray ? "array" : "iterable"),
8331-
console.error(
8332-
"A nested %s was passed to row #%s in <SuspenseList />. Wrap it in an additional SuspenseList to configure its revealOrder: <SuspenseList revealOrder=...> ... <SuspenseList revealOrder=...>{%s}</SuspenseList> ... </SuspenseList>",
8333-
isAnArray,
8334-
index,
8335-
isAnArray
8336-
),
8337-
!1)
8338-
: !0;
8339-
}
83408340
function initSuspenseListRenderState(
83418341
workInProgress,
83428342
isBackwards,
@@ -8366,6 +8366,15 @@ __DEV__ &&
83668366
revealOrder = nextProps.revealOrder,
83678367
tailMode = nextProps.tail;
83688368
nextProps = nextProps.children;
8369+
var suspenseContext = suspenseStackCursor.current,
8370+
shouldForceFallback = 0 !== (suspenseContext & ForceSuspenseFallback);
8371+
shouldForceFallback
8372+
? ((suspenseContext =
8373+
(suspenseContext & SubtreeSuspenseContextMask) |
8374+
ForceSuspenseFallback),
8375+
(workInProgress.flags |= 128))
8376+
: (suspenseContext &= SubtreeSuspenseContextMask);
8377+
push(suspenseStackCursor, suspenseContext, workInProgress);
83698378
if (
83708379
void 0 !== revealOrder &&
83718380
"forwards" !== revealOrder &&
@@ -8428,12 +8437,29 @@ __DEV__ &&
84288437
!1 !== nextProps
84298438
)
84308439
if (isArrayImpl(nextProps))
8431-
for (var i = 0; i < nextProps.length; i++) {
8432-
if (!validateSuspenseListNestedChild(nextProps[i], i)) break a;
8440+
for (
8441+
suspenseContext = 0;
8442+
suspenseContext < nextProps.length;
8443+
suspenseContext++
8444+
) {
8445+
if (
8446+
!validateSuspenseListNestedChild(
8447+
nextProps[suspenseContext],
8448+
suspenseContext
8449+
)
8450+
)
8451+
break a;
84338452
}
8434-
else if (((i = getIteratorFn(nextProps)), "function" === typeof i)) {
8435-
if ((i = i.call(nextProps)))
8436-
for (var step = i.next(), _i = 0; !step.done; step = i.next()) {
8453+
else if (
8454+
((suspenseContext = getIteratorFn(nextProps)),
8455+
"function" === typeof suspenseContext)
8456+
) {
8457+
if ((suspenseContext = suspenseContext.call(nextProps)))
8458+
for (
8459+
var step = suspenseContext.next(), _i = 0;
8460+
!step.done;
8461+
step = suspenseContext.next()
8462+
) {
84378463
if (!validateSuspenseListNestedChild(step.value, _i)) break a;
84388464
_i++;
84398465
}
@@ -8443,40 +8469,31 @@ __DEV__ &&
84438469
revealOrder
84448470
);
84458471
reconcileChildren(current, workInProgress, nextProps, renderLanes);
8446-
nextProps = suspenseStackCursor.current;
8447-
if (0 !== (nextProps & ForceSuspenseFallback))
8448-
(nextProps =
8449-
(nextProps & SubtreeSuspenseContextMask) | ForceSuspenseFallback),
8450-
(workInProgress.flags |= 128);
8451-
else {
8452-
if (null !== current && 0 !== (current.flags & 128))
8453-
a: for (current = workInProgress.child; null !== current; ) {
8454-
if (13 === current.tag)
8455-
null !== current.memoizedState &&
8456-
scheduleSuspenseWorkOnFiber(
8457-
current,
8458-
renderLanes,
8459-
workInProgress
8460-
);
8461-
else if (19 === current.tag)
8472+
if (
8473+
!shouldForceFallback &&
8474+
null !== current &&
8475+
0 !== (current.flags & 128)
8476+
)
8477+
a: for (current = workInProgress.child; null !== current; ) {
8478+
if (13 === current.tag)
8479+
null !== current.memoizedState &&
84628480
scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);
8463-
else if (null !== current.child) {
8464-
current.child.return = current;
8465-
current = current.child;
8466-
continue;
8467-
}
8468-
if (current === workInProgress) break a;
8469-
for (; null === current.sibling; ) {
8470-
if (null === current.return || current.return === workInProgress)
8471-
break a;
8472-
current = current.return;
8473-
}
8474-
current.sibling.return = current.return;
8475-
current = current.sibling;
8481+
else if (19 === current.tag)
8482+
scheduleSuspenseWorkOnFiber(current, renderLanes, workInProgress);
8483+
else if (null !== current.child) {
8484+
current.child.return = current;
8485+
current = current.child;
8486+
continue;
84768487
}
8477-
nextProps &= SubtreeSuspenseContextMask;
8478-
}
8479-
push(suspenseStackCursor, nextProps, workInProgress);
8488+
if (current === workInProgress) break a;
8489+
for (; null === current.sibling; ) {
8490+
if (null === current.return || current.return === workInProgress)
8491+
break a;
8492+
current = current.return;
8493+
}
8494+
current.sibling.return = current.return;
8495+
current = current.sibling;
8496+
}
84808497
switch (revealOrder) {
84818498
case "forwards":
84828499
renderLanes = workInProgress.child;
@@ -19063,10 +19080,10 @@ __DEV__ &&
1906319080
(function () {
1906419081
var internals = {
1906519082
bundleType: 1,
19066-
version: "19.2.0-www-classic-c6c2a52a-20250519",
19083+
version: "19.2.0-www-classic-4c6967be-20250520",
1906719084
rendererPackageName: "react-art",
1906819085
currentDispatcherRef: ReactSharedInternals,
19069-
reconcilerVersion: "19.2.0-www-classic-c6c2a52a-20250519"
19086+
reconcilerVersion: "19.2.0-www-classic-4c6967be-20250520"
1907019087
};
1907119088
internals.overrideHookState = overrideHookState;
1907219089
internals.overrideHookStateDeletePath = overrideHookStateDeletePath;
@@ -19100,7 +19117,7 @@ __DEV__ &&
1910019117
exports.Shape = Shape;
1910119118
exports.Surface = Surface;
1910219119
exports.Text = Text;
19103-
exports.version = "19.2.0-www-classic-c6c2a52a-20250519";
19120+
exports.version = "19.2.0-www-classic-4c6967be-20250520";
1910419121
"undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ &&
1910519122
"function" ===
1910619123
typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop &&

0 commit comments

Comments
 (0)