Don't modify keyPath until right before recursive renderNode call (#27366)

Currently, if a component suspends, the keyPath has already been
modified to include the identity of the component itself; the path is
set before the component body is called (akin to the begin phase in
Fiber). An accidental consequence is that when the promise resolves and
component is retried, the identity gets appended to the keyPath again,
leading to a duplicate node in the path.

To address this, we should only modify contexts after any code that may
suspend. For maximum safety, this should occur as late as possible:
right before the recursive renderNode call, before the children are
rendered.

I did not add a test yet because there's no feature that currently
observes it, but I do have tests in my other WIP PR for useFormState:
#27321

DiffTrain build for [d07921eeda](https://github.com/facebook/react/commit/d07921eeda62613bfcf52ecdb66322db26393567)
This commit is contained in:
acdlite
2023-09-13 01:32:34 +00:00
parent f527fd1878
commit ed7966e08f
8 changed files with 654 additions and 230 deletions
+1 -1
View File
@@ -1 +1 @@
7a3cb8f9cf43591afc74722ece9e3216ccc98128
d07921eeda62613bfcf52ecdb66322db26393567
@@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");
var ReactVersion = "18.3.0-www-classic-d167ae1b";
var ReactVersion = "18.3.0-www-classic-b080da7c";
// This refers to a WWW module.
var warningWWW = require("warning");
@@ -9930,7 +9930,7 @@ function fatalError(request, error) {
}
}
function renderSuspenseBoundary(request, task, props) {
function renderSuspenseBoundary(request, task, keyPath, props) {
pushBuiltInComponentStackInDEV(task, "Suspense");
var parentBoundary = task.blockedBoundary;
var parentSegment = task.blockedSegment; // Each time we enter a suspense boundary, we split out into a new segment for
@@ -9941,11 +9941,7 @@ function renderSuspenseBoundary(request, task, props) {
var fallback = props.fallback;
var content = props.children;
var fallbackAbortSet = new Set();
var newBoundary = createSuspenseBoundary(
request,
fallbackAbortSet,
task.keyPath
);
var newBoundary = createSuspenseBoundary(request, fallbackAbortSet, keyPath);
var insertionIndex = parentSegment.chunks.length; // The children of the boundary segment is actually the fallback.
var boundarySegment = createPendingSegment(
@@ -10043,8 +10039,8 @@ function renderSuspenseBoundary(request, task, props) {
fallback,
parentBoundary,
boundarySegment,
fallbackAbortSet,
task.keyPath,
fallbackAbortSet, // TODO: Should distinguish key path of fallback and primary tasks
keyPath,
task.formatContext,
task.legacyContext,
task.context,
@@ -10060,7 +10056,7 @@ function renderSuspenseBoundary(request, task, props) {
popComponentStackInDEV(task);
}
function renderHostElement(request, task, type, props) {
function renderHostElement(request, task, keyPath, type, props) {
pushBuiltInComponentStackInDEV(task, type);
var segment = task.blockedSegment;
var children = pushStartInstance(
@@ -10074,13 +10070,16 @@ function renderHostElement(request, task, type, props) {
);
segment.lastPushedText = false;
var prevContext = task.formatContext;
task.formatContext = getChildFormatContext(prevContext, type, props); // We use the non-destructive form because if something suspends, we still
var prevKeyPath = task.keyPath;
task.formatContext = getChildFormatContext(prevContext, type, props);
task.keyPath = keyPath; // We use the non-destructive form because if something suspends, we still
// need to pop back up and finish this subtree of HTML.
renderNode(request, task, children, -1); // We expect that errors will fatal the whole task and that we don't need
// the correct context. Therefore this is not in a finally.
task.formatContext = prevContext;
task.keyPath = prevKeyPath;
pushEndInstance(
segment.chunks,
type,
@@ -10110,7 +10109,14 @@ function renderWithHooks(
return finishHooks(Component, props, result, secondArg);
}
function finishClassComponent(request, task, instance, Component, props) {
function finishClassComponent(
request,
task,
keyPath,
instance,
Component,
props
) {
var nextChildren = instance.render();
{
@@ -10145,15 +10151,18 @@ function finishClassComponent(request, task, instance, Component, props) {
}
}
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, nextChildren, -1);
task.keyPath = prevKeyPath;
}
function renderClassComponent(request, task, Component, props) {
function renderClassComponent(request, task, keyPath, Component, props) {
pushClassComponentStackInDEV(task, Component);
var maskedContext = getMaskedContext(Component, task.legacyContext);
var instance = constructClassInstance(Component, props, maskedContext);
mountClassInstance(instance, Component, props, maskedContext);
finishClassComponent(request, task, instance, Component, props);
finishClassComponent(request, task, keyPath, instance, Component, props);
popComponentStackInDEV(task);
}
@@ -10171,6 +10180,7 @@ var hasWarnedAboutUsingContextAsConsumer = false; // This would typically be a f
function renderIndeterminateComponent(
request,
task,
keyPath,
prevThenableState,
Component,
props
@@ -10251,6 +10261,7 @@ function renderIndeterminateComponent(
finishFunctionComponent(
request,
task,
keyPath,
value,
hasId,
formStateCount,
@@ -10264,6 +10275,7 @@ function renderIndeterminateComponent(
function finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -10293,6 +10305,9 @@ function finishFunctionComponent(
}
}
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
if (hasId) {
// This component materialized an id. We treat this as its own level, with
// a single "child" slot.
@@ -10317,6 +10332,8 @@ function finishFunctionComponent(
// again, so we can use the destructive recursive form.
renderNodeDestructive(request, task, null, children, -1);
}
task.keyPath = prevKeyPath;
}
function validateFunctionComponentInDev(Component) {
@@ -10393,7 +10410,15 @@ function resolveDefaultProps(Component, baseProps) {
return baseProps;
}
function renderForwardRef(request, task, prevThenableState, type, props, ref) {
function renderForwardRef(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
pushFunctionComponentStackInDEV(task, type.render);
var children = renderWithHooks(
request,
@@ -10409,6 +10434,7 @@ function renderForwardRef(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -10417,12 +10443,21 @@ function renderForwardRef(request, task, prevThenableState, type, props, ref) {
popComponentStackInDEV(task);
}
function renderMemo(request, task, prevThenableState, type, props, ref) {
function renderMemo(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
var innerType = type.type;
var resolvedProps = resolveDefaultProps(innerType, props);
renderElement(
request,
task,
keyPath,
prevThenableState,
innerType,
resolvedProps,
@@ -10430,7 +10465,7 @@ function renderMemo(request, task, prevThenableState, type, props, ref) {
);
}
function renderContextConsumer(request, task, context, props) {
function renderContextConsumer(request, task, keyPath, context, props) {
// The logic below for Context differs depending on PROD or DEV mode. In
// DEV mode, we create a separate object for Context.Consumer that acts
// like a proxy to Context. This proxy object adds unnecessary code in PROD
@@ -10473,10 +10508,13 @@ function renderContextConsumer(request, task, context, props) {
var newValue = readContext$1(context);
var newChildren = render(newValue);
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, newChildren, -1);
task.keyPath = prevKeyPath;
}
function renderContextProvider(request, task, type, props) {
function renderContextProvider(request, task, keyPath, type, props) {
var context = type._context;
var value = props.value;
var children = props.children;
@@ -10486,9 +10524,12 @@ function renderContextProvider(request, task, type, props) {
prevSnapshot = task.context;
}
var prevKeyPath = task.keyPath;
task.context = pushProvider(context, value);
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, children, -1);
task.context = popProvider(context);
task.keyPath = prevKeyPath;
{
if (prevSnapshot !== task.context) {
@@ -10502,6 +10543,7 @@ function renderContextProvider(request, task, type, props) {
function renderLazyComponent(
request,
task,
keyPath,
prevThenableState,
lazyComponent,
props,
@@ -10515,6 +10557,7 @@ function renderLazyComponent(
renderElement(
request,
task,
keyPath,
prevThenableState,
Component,
resolvedProps,
@@ -10523,26 +10566,38 @@ function renderLazyComponent(
popComponentStackInDEV(task);
}
function renderOffscreen(request, task, props) {
function renderOffscreen(request, task, keyPath, props) {
var mode = props.mode;
if (mode === "hidden");
else {
// A visible Offscreen boundary is treated exactly like a fragment: a
// pure indirection.
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = prevKeyPath;
}
}
function renderElement(request, task, prevThenableState, type, props, ref) {
function renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
if (typeof type === "function") {
if (shouldConstruct(type)) {
renderClassComponent(request, task, type, props);
renderClassComponent(request, task, keyPath, type, props);
return;
} else {
renderIndeterminateComponent(
request,
task,
keyPath,
prevThenableState,
type,
props
@@ -10552,7 +10607,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
}
if (typeof type === "string") {
renderHostElement(request, task, type, props);
renderHostElement(request, task, keyPath, type, props);
return;
}
@@ -10571,33 +10626,42 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_STRICT_MODE_TYPE:
case REACT_PROFILER_TYPE:
case REACT_FRAGMENT_TYPE: {
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = prevKeyPath;
return;
}
case REACT_OFFSCREEN_TYPE: {
renderOffscreen(request, task, props);
renderOffscreen(request, task, keyPath, props);
return;
}
case REACT_SUSPENSE_LIST_TYPE: {
pushBuiltInComponentStackInDEV(task, "SuspenseList"); // TODO: SuspenseList should control the boundaries.
var _prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = _prevKeyPath;
popComponentStackInDEV(task);
return;
}
case REACT_SCOPE_TYPE: {
{
var _prevKeyPath2 = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = _prevKeyPath2;
return;
}
}
case REACT_SUSPENSE_TYPE: {
{
renderSuspenseBoundary(request, task, props);
renderSuspenseBoundary(request, task, keyPath, props);
}
return;
@@ -10607,27 +10671,42 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
if (typeof type === "object" && type !== null) {
switch (type.$$typeof) {
case REACT_FORWARD_REF_TYPE: {
renderForwardRef(request, task, prevThenableState, type, props, ref);
renderForwardRef(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
}
case REACT_MEMO_TYPE: {
renderMemo(request, task, prevThenableState, type, props, ref);
renderMemo(request, task, keyPath, prevThenableState, type, props, ref);
return;
}
case REACT_PROVIDER_TYPE: {
renderContextProvider(request, task, type, props);
renderContextProvider(request, task, keyPath, type, props);
return;
}
case REACT_CONTEXT_TYPE: {
renderContextConsumer(request, task, type, props);
renderContextConsumer(request, task, keyPath, type, props);
return;
}
case REACT_LAZY_TYPE: {
renderLazyComponent(request, task, prevThenableState, type, props);
renderLazyComponent(
request,
task,
keyPath,
prevThenableState,
type,
props
);
return;
}
}
@@ -10747,14 +10826,20 @@ function renderNodeDestructiveImpl(
var props = element.props;
var ref = element.ref;
var name = getComponentNameFromType(type);
var prevKeyPath = task.keyPath;
task.keyPath = [
var keyPath = [
task.keyPath,
name,
key == null ? (childIndex === -1 ? 0 : childIndex) : key
];
renderElement(request, task, prevThenableState, type, props, ref);
task.keyPath = prevKeyPath;
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
}
@@ -19,7 +19,7 @@ if (__DEV__) {
var React = require("react");
var ReactDOM = require("react-dom");
var ReactVersion = "18.3.0-www-modern-2efbee1a";
var ReactVersion = "18.3.0-www-modern-7c748307";
// This refers to a WWW module.
var warningWWW = require("warning");
@@ -9689,7 +9689,7 @@ function fatalError(request, error) {
}
}
function renderSuspenseBoundary(request, task, props) {
function renderSuspenseBoundary(request, task, keyPath, props) {
pushBuiltInComponentStackInDEV(task, "Suspense");
var parentBoundary = task.blockedBoundary;
var parentSegment = task.blockedSegment; // Each time we enter a suspense boundary, we split out into a new segment for
@@ -9700,11 +9700,7 @@ function renderSuspenseBoundary(request, task, props) {
var fallback = props.fallback;
var content = props.children;
var fallbackAbortSet = new Set();
var newBoundary = createSuspenseBoundary(
request,
fallbackAbortSet,
task.keyPath
);
var newBoundary = createSuspenseBoundary(request, fallbackAbortSet, keyPath);
var insertionIndex = parentSegment.chunks.length; // The children of the boundary segment is actually the fallback.
var boundarySegment = createPendingSegment(
@@ -9802,8 +9798,8 @@ function renderSuspenseBoundary(request, task, props) {
fallback,
parentBoundary,
boundarySegment,
fallbackAbortSet,
task.keyPath,
fallbackAbortSet, // TODO: Should distinguish key path of fallback and primary tasks
keyPath,
task.formatContext,
task.legacyContext,
task.context,
@@ -9819,7 +9815,7 @@ function renderSuspenseBoundary(request, task, props) {
popComponentStackInDEV(task);
}
function renderHostElement(request, task, type, props) {
function renderHostElement(request, task, keyPath, type, props) {
pushBuiltInComponentStackInDEV(task, type);
var segment = task.blockedSegment;
var children = pushStartInstance(
@@ -9833,13 +9829,16 @@ function renderHostElement(request, task, type, props) {
);
segment.lastPushedText = false;
var prevContext = task.formatContext;
task.formatContext = getChildFormatContext(prevContext, type, props); // We use the non-destructive form because if something suspends, we still
var prevKeyPath = task.keyPath;
task.formatContext = getChildFormatContext(prevContext, type, props);
task.keyPath = keyPath; // We use the non-destructive form because if something suspends, we still
// need to pop back up and finish this subtree of HTML.
renderNode(request, task, children, -1); // We expect that errors will fatal the whole task and that we don't need
// the correct context. Therefore this is not in a finally.
task.formatContext = prevContext;
task.keyPath = prevKeyPath;
pushEndInstance(
segment.chunks,
type,
@@ -9869,7 +9868,14 @@ function renderWithHooks(
return finishHooks(Component, props, result, secondArg);
}
function finishClassComponent(request, task, instance, Component, props) {
function finishClassComponent(
request,
task,
keyPath,
instance,
Component,
props
) {
var nextChildren = instance.render();
{
@@ -9886,15 +9892,18 @@ function finishClassComponent(request, task, instance, Component, props) {
}
}
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, nextChildren, -1);
task.keyPath = prevKeyPath;
}
function renderClassComponent(request, task, Component, props) {
function renderClassComponent(request, task, keyPath, Component, props) {
pushClassComponentStackInDEV(task, Component);
var maskedContext = undefined;
var instance = constructClassInstance(Component, props);
mountClassInstance(instance, Component, props, maskedContext);
finishClassComponent(request, task, instance, Component, props);
finishClassComponent(request, task, keyPath, instance, Component, props);
popComponentStackInDEV(task);
}
@@ -9912,6 +9921,7 @@ var hasWarnedAboutUsingContextAsConsumer = false; // This would typically be a f
function renderIndeterminateComponent(
request,
task,
keyPath,
prevThenableState,
Component,
props
@@ -9999,6 +10009,7 @@ function renderIndeterminateComponent(
finishFunctionComponent(
request,
task,
keyPath,
value,
hasId,
formStateCount,
@@ -10012,6 +10023,7 @@ function renderIndeterminateComponent(
function finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -10041,6 +10053,9 @@ function finishFunctionComponent(
}
}
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
if (hasId) {
// This component materialized an id. We treat this as its own level, with
// a single "child" slot.
@@ -10065,6 +10080,8 @@ function finishFunctionComponent(
// again, so we can use the destructive recursive form.
renderNodeDestructive(request, task, null, children, -1);
}
task.keyPath = prevKeyPath;
}
function validateFunctionComponentInDev(Component) {
@@ -10141,7 +10158,15 @@ function resolveDefaultProps(Component, baseProps) {
return baseProps;
}
function renderForwardRef(request, task, prevThenableState, type, props, ref) {
function renderForwardRef(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
pushFunctionComponentStackInDEV(task, type.render);
var children = renderWithHooks(
request,
@@ -10157,6 +10182,7 @@ function renderForwardRef(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -10165,12 +10191,21 @@ function renderForwardRef(request, task, prevThenableState, type, props, ref) {
popComponentStackInDEV(task);
}
function renderMemo(request, task, prevThenableState, type, props, ref) {
function renderMemo(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
var innerType = type.type;
var resolvedProps = resolveDefaultProps(innerType, props);
renderElement(
request,
task,
keyPath,
prevThenableState,
innerType,
resolvedProps,
@@ -10178,7 +10213,7 @@ function renderMemo(request, task, prevThenableState, type, props, ref) {
);
}
function renderContextConsumer(request, task, context, props) {
function renderContextConsumer(request, task, keyPath, context, props) {
// The logic below for Context differs depending on PROD or DEV mode. In
// DEV mode, we create a separate object for Context.Consumer that acts
// like a proxy to Context. This proxy object adds unnecessary code in PROD
@@ -10221,10 +10256,13 @@ function renderContextConsumer(request, task, context, props) {
var newValue = readContext$1(context);
var newChildren = render(newValue);
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, newChildren, -1);
task.keyPath = prevKeyPath;
}
function renderContextProvider(request, task, type, props) {
function renderContextProvider(request, task, keyPath, type, props) {
var context = type._context;
var value = props.value;
var children = props.children;
@@ -10234,9 +10272,12 @@ function renderContextProvider(request, task, type, props) {
prevSnapshot = task.context;
}
var prevKeyPath = task.keyPath;
task.context = pushProvider(context, value);
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, children, -1);
task.context = popProvider(context);
task.keyPath = prevKeyPath;
{
if (prevSnapshot !== task.context) {
@@ -10250,6 +10291,7 @@ function renderContextProvider(request, task, type, props) {
function renderLazyComponent(
request,
task,
keyPath,
prevThenableState,
lazyComponent,
props,
@@ -10263,6 +10305,7 @@ function renderLazyComponent(
renderElement(
request,
task,
keyPath,
prevThenableState,
Component,
resolvedProps,
@@ -10271,26 +10314,38 @@ function renderLazyComponent(
popComponentStackInDEV(task);
}
function renderOffscreen(request, task, props) {
function renderOffscreen(request, task, keyPath, props) {
var mode = props.mode;
if (mode === "hidden");
else {
// A visible Offscreen boundary is treated exactly like a fragment: a
// pure indirection.
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = prevKeyPath;
}
}
function renderElement(request, task, prevThenableState, type, props, ref) {
function renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
if (typeof type === "function") {
if (shouldConstruct(type)) {
renderClassComponent(request, task, type, props);
renderClassComponent(request, task, keyPath, type, props);
return;
} else {
renderIndeterminateComponent(
request,
task,
keyPath,
prevThenableState,
type,
props
@@ -10300,7 +10355,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
}
if (typeof type === "string") {
renderHostElement(request, task, type, props);
renderHostElement(request, task, keyPath, type, props);
return;
}
@@ -10319,33 +10374,42 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_STRICT_MODE_TYPE:
case REACT_PROFILER_TYPE:
case REACT_FRAGMENT_TYPE: {
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = prevKeyPath;
return;
}
case REACT_OFFSCREEN_TYPE: {
renderOffscreen(request, task, props);
renderOffscreen(request, task, keyPath, props);
return;
}
case REACT_SUSPENSE_LIST_TYPE: {
pushBuiltInComponentStackInDEV(task, "SuspenseList"); // TODO: SuspenseList should control the boundaries.
var _prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = _prevKeyPath;
popComponentStackInDEV(task);
return;
}
case REACT_SCOPE_TYPE: {
{
var _prevKeyPath2 = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = _prevKeyPath2;
return;
}
}
case REACT_SUSPENSE_TYPE: {
{
renderSuspenseBoundary(request, task, props);
renderSuspenseBoundary(request, task, keyPath, props);
}
return;
@@ -10355,27 +10419,42 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
if (typeof type === "object" && type !== null) {
switch (type.$$typeof) {
case REACT_FORWARD_REF_TYPE: {
renderForwardRef(request, task, prevThenableState, type, props, ref);
renderForwardRef(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
}
case REACT_MEMO_TYPE: {
renderMemo(request, task, prevThenableState, type, props, ref);
renderMemo(request, task, keyPath, prevThenableState, type, props, ref);
return;
}
case REACT_PROVIDER_TYPE: {
renderContextProvider(request, task, type, props);
renderContextProvider(request, task, keyPath, type, props);
return;
}
case REACT_CONTEXT_TYPE: {
renderContextConsumer(request, task, type, props);
renderContextConsumer(request, task, keyPath, type, props);
return;
}
case REACT_LAZY_TYPE: {
renderLazyComponent(request, task, prevThenableState, type, props);
renderLazyComponent(
request,
task,
keyPath,
prevThenableState,
type,
props
);
return;
}
}
@@ -10495,14 +10574,20 @@ function renderNodeDestructiveImpl(
var props = element.props;
var ref = element.ref;
var name = getComponentNameFromType(type);
var prevKeyPath = task.keyPath;
task.keyPath = [
var keyPath = [
task.keyPath,
name,
key == null ? (childIndex === -1 ? 0 : childIndex) : key
];
renderElement(request, task, prevThenableState, type, props, ref);
task.keyPath = prevKeyPath;
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
}
@@ -3009,6 +3009,7 @@ function fatalError(request, error) {
function finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -3026,14 +3027,17 @@ function finishFunctionComponent(
: segment.push("\x3c!--F--\x3e");
}
}
formStateCount = task.keyPath;
task.keyPath = keyPath;
hasId
? ((hasId = task.treeContext),
(task.treeContext = pushTreeContext(hasId, 1, 0)),
? ((keyPath = task.treeContext),
(task.treeContext = pushTreeContext(keyPath, 1, 0)),
renderNode(request, task, children, -1),
(task.treeContext = hasId))
(task.treeContext = keyPath))
: didEmitFormStateMarkers
? renderNode(request, task, children, -1)
: renderNodeDestructiveImpl(request, task, null, children, -1);
task.keyPath = formStateCount;
}
function resolveDefaultProps(Component, baseProps) {
if (Component && Component.defaultProps) {
@@ -3046,7 +3050,15 @@ function resolveDefaultProps(Component, baseProps) {
}
return baseProps;
}
function renderElement(request, task, prevThenableState, type, props, ref) {
function renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
if ("function" === typeof type)
if (type.prototype && type.prototype.isReactComponent) {
prevThenableState = getMaskedContext(type, task.legacyContext);
@@ -3136,15 +3148,15 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
}
} else ref.queue = null;
props = JSCompiler_inline_result.render();
ref = type.childContextTypes;
if (null !== ref && void 0 !== ref) {
prevThenableState = task.legacyContext;
prevThenableState = type.childContextTypes;
if (null !== prevThenableState && void 0 !== prevThenableState) {
keyPath = task.legacyContext;
if ("function" !== typeof JSCompiler_inline_result.getChildContext)
type = prevThenableState;
type = keyPath;
else {
JSCompiler_inline_result = JSCompiler_inline_result.getChildContext();
for (var contextKey in JSCompiler_inline_result)
if (!(contextKey in ref))
if (!(contextKey in prevThenableState))
throw Error(
formatProdErrorMessage(
108,
@@ -3152,12 +3164,16 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
contextKey
)
);
type = assign({}, prevThenableState, JSCompiler_inline_result);
type = assign({}, keyPath, JSCompiler_inline_result);
}
task.legacyContext = type;
renderNodeDestructiveImpl(request, task, null, props, -1);
task.legacyContext = prevThenableState;
} else renderNodeDestructiveImpl(request, task, null, props, -1);
task.legacyContext = keyPath;
} else
(type = task.keyPath),
(task.keyPath = keyPath),
renderNodeDestructiveImpl(request, task, null, props, -1),
(task.keyPath = type);
} else
(contextKey = getMaskedContext(type, task.legacyContext)),
(currentlyRenderingComponent = {}),
@@ -3176,6 +3192,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
props,
0 !== localIdCounter,
formStateCounter,
@@ -3194,13 +3211,16 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
);
contextKey.lastPushedText = !1;
JSCompiler_inline_result = task.formatContext;
ref = task.keyPath;
task.formatContext = getChildFormatContext(
JSCompiler_inline_result,
type,
props
);
task.keyPath = keyPath;
renderNode(request, task, prevThenableState, -1);
task.formatContext = JSCompiler_inline_result;
task.keyPath = ref;
a: {
task = contextKey.chunks;
request = request.resumableState;
@@ -3246,17 +3266,29 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_STRICT_MODE_TYPE:
case REACT_PROFILER_TYPE:
case REACT_FRAGMENT_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_OFFSCREEN_TYPE:
"hidden" !== props.mode &&
renderNodeDestructiveImpl(request, task, null, props.children, -1);
((type = task.keyPath),
(task.keyPath = keyPath),
renderNodeDestructiveImpl(request, task, null, props.children, -1),
(task.keyPath = type));
return;
case REACT_SUSPENSE_LIST_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_SCOPE_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_SUSPENSE_TYPE:
a: {
@@ -3265,7 +3297,6 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
prevThenableState = props.fallback;
props = props.children;
ref = new Set();
initialState = task.keyPath;
initialState = {
status: 0,
id: null,
@@ -3277,7 +3308,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
fallbackAbortableTasks: ref,
errorDigest: null,
resources: new Set(),
keyPath: initialState
keyPath: keyPath
};
contextType = createPendingSegment(
request,
@@ -3334,7 +3365,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
type,
contextType,
ref,
task.keyPath,
keyPath,
task.formatContext,
task.legacyContext,
task.context,
@@ -3359,6 +3390,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
props,
0 !== localIdCounter,
formStateCounter,
@@ -3368,44 +3400,72 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_MEMO_TYPE:
type = type.type;
props = resolveDefaultProps(type, props);
renderElement(request, task, prevThenableState, type, props, ref);
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
case REACT_PROVIDER_TYPE:
contextKey = props.children;
JSCompiler_inline_result = props.children;
contextKey = task.keyPath;
type = type._context;
props = props.value;
JSCompiler_inline_result = type._currentValue2;
prevThenableState = type._currentValue2;
type._currentValue2 = props;
prevThenableState = currentActiveSnapshot;
ref = currentActiveSnapshot;
currentActiveSnapshot = props = {
parent: prevThenableState,
depth: null === prevThenableState ? 0 : prevThenableState.depth + 1,
parent: ref,
depth: null === ref ? 0 : ref.depth + 1,
context: type,
parentValue: JSCompiler_inline_result,
parentValue: prevThenableState,
value: props
};
task.context = props;
renderNodeDestructiveImpl(request, task, null, contextKey, -1);
task.keyPath = keyPath;
renderNodeDestructiveImpl(
request,
task,
null,
JSCompiler_inline_result,
-1
);
request = currentActiveSnapshot;
if (null === request) throw Error(formatProdErrorMessage(403));
props = request.parentValue;
keyPath = request.parentValue;
request.context._currentValue2 =
props === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED
keyPath === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED
? request.context._defaultValue
: props;
: keyPath;
request = currentActiveSnapshot = request.parent;
task.context = request;
task.keyPath = contextKey;
return;
case REACT_CONTEXT_TYPE:
props = props.children;
props = props(type._currentValue2);
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props, -1);
task.keyPath = type;
return;
case REACT_LAZY_TYPE:
contextKey = type._init;
type = contextKey(type._payload);
props = resolveDefaultProps(type, props);
renderElement(request, task, prevThenableState, type, props, void 0);
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
void 0
);
return;
}
throw Error(
@@ -3429,15 +3489,20 @@ function renderNodeDestructiveImpl(
key = node.key,
props = node.props;
node = node.ref;
var name = getComponentNameFromType(type),
prevKeyPath = task.keyPath;
task.keyPath = [
task.keyPath,
name,
null == key ? (-1 === childIndex ? 0 : childIndex) : key
];
renderElement(request, task, prevThenableState, type, props, node);
task.keyPath = prevKeyPath;
var name = getComponentNameFromType(type);
renderElement(
request,
task,
[
task.keyPath,
name,
null == key ? (-1 === childIndex ? 0 : childIndex) : key
],
prevThenableState,
type,
props,
node
);
return;
case REACT_PORTAL_TYPE:
throw Error(formatProdErrorMessage(257));
@@ -4255,13 +4320,13 @@ function flushCompletedQueues(request, destination) {
completedBoundaries.splice(0, i);
var partialBoundaries = request.partialBoundaries;
for (i = 0; i < partialBoundaries.length; i++) {
var boundary$13 = partialBoundaries[i];
var boundary$15 = partialBoundaries[i];
a: {
clientRenderedBoundaries = request;
boundary = destination;
clientRenderedBoundaries.renderState.boundaryResources =
boundary$13.resources;
var completedSegments = boundary$13.completedSegments;
boundary$15.resources;
var completedSegments = boundary$15.completedSegments;
for (
resumableState$jscomp$1 = 0;
resumableState$jscomp$1 < completedSegments.length;
@@ -4271,7 +4336,7 @@ function flushCompletedQueues(request, destination) {
!flushPartiallyCompletedSegment(
clientRenderedBoundaries,
boundary,
boundary$13,
boundary$15,
completedSegments[resumableState$jscomp$1]
)
) {
@@ -4283,7 +4348,7 @@ function flushCompletedQueues(request, destination) {
completedSegments.splice(0, resumableState$jscomp$1);
JSCompiler_inline_result = writeResourcesForBoundary(
boundary,
boundary$13.resources,
boundary$15.resources,
clientRenderedBoundaries.renderState
);
}
@@ -4346,8 +4411,8 @@ function abort(request, reason) {
}
null !== request.destination &&
flushCompletedQueues(request, request.destination);
} catch (error$15) {
logRecoverableError(request, error$15), fatalError(request, error$15);
} catch (error$17) {
logRecoverableError(request, error$17), fatalError(request, error$17);
}
}
function onError() {}
@@ -4434,4 +4499,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-classic-d6f252d2";
exports.version = "18.3.0-www-classic-10a5a8c2";
@@ -3001,6 +3001,7 @@ function fatalError(request, error) {
function finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -3018,14 +3019,17 @@ function finishFunctionComponent(
: segment.push("\x3c!--F--\x3e");
}
}
formStateCount = task.keyPath;
task.keyPath = keyPath;
hasId
? ((hasId = task.treeContext),
(task.treeContext = pushTreeContext(hasId, 1, 0)),
? ((keyPath = task.treeContext),
(task.treeContext = pushTreeContext(keyPath, 1, 0)),
renderNode(request, task, children, -1),
(task.treeContext = hasId))
(task.treeContext = keyPath))
: didEmitFormStateMarkers
? renderNode(request, task, children, -1)
: renderNodeDestructiveImpl(request, task, null, children, -1);
task.keyPath = formStateCount;
}
function resolveDefaultProps(Component, baseProps) {
if (Component && Component.defaultProps) {
@@ -3038,7 +3042,15 @@ function resolveDefaultProps(Component, baseProps) {
}
return baseProps;
}
function renderElement(request, task, prevThenableState, type, props, ref) {
function renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
if ("function" === typeof type)
if (type.prototype && type.prototype.isReactComponent) {
var JSCompiler_inline_result = emptyContextObject;
@@ -3135,7 +3147,10 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
}
else prevThenableState.queue = null;
props = JSCompiler_inline_result.render();
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props, -1);
task.keyPath = type;
} else
(currentlyRenderingComponent = {}),
(currentlyRenderingTask = task),
@@ -3148,6 +3163,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
props,
0 !== localIdCounter,
formStateCounter,
@@ -3166,9 +3182,12 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
);
JSCompiler_inline_result.lastPushedText = !1;
prevThenableState = task.formatContext;
contextType = task.keyPath;
task.formatContext = getChildFormatContext(prevThenableState, type, props);
task.keyPath = keyPath;
renderNode(request, task, ref, -1);
task.formatContext = prevThenableState;
task.keyPath = contextType;
a: {
task = JSCompiler_inline_result.chunks;
request = request.resumableState;
@@ -3214,17 +3233,29 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_STRICT_MODE_TYPE:
case REACT_PROFILER_TYPE:
case REACT_FRAGMENT_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_OFFSCREEN_TYPE:
"hidden" !== props.mode &&
renderNodeDestructiveImpl(request, task, null, props.children, -1);
((type = task.keyPath),
(task.keyPath = keyPath),
renderNodeDestructiveImpl(request, task, null, props.children, -1),
(task.keyPath = type));
return;
case REACT_SUSPENSE_LIST_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_SCOPE_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_SUSPENSE_TYPE:
a: {
@@ -3233,7 +3264,6 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
ref = props.fallback;
props = props.children;
contextType = new Set();
partial = task.keyPath;
partial = {
status: 0,
id: null,
@@ -3245,7 +3275,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
fallbackAbortableTasks: contextType,
errorDigest: null,
resources: new Set(),
keyPath: partial
keyPath: keyPath
};
var boundarySegment = createPendingSegment(
request,
@@ -3302,7 +3332,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
type,
boundarySegment,
contextType,
task.keyPath,
keyPath,
task.formatContext,
task.legacyContext,
task.context,
@@ -3327,6 +3357,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
props,
0 !== localIdCounter,
formStateCounter,
@@ -3336,50 +3367,66 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_MEMO_TYPE:
type = type.type;
props = resolveDefaultProps(type, props);
renderElement(request, task, prevThenableState, type, props, ref);
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
case REACT_PROVIDER_TYPE:
JSCompiler_inline_result = props.children;
prevThenableState = props.children;
JSCompiler_inline_result = task.keyPath;
type = type._context;
props = props.value;
prevThenableState = type._currentValue2;
ref = type._currentValue2;
type._currentValue2 = props;
ref = currentActiveSnapshot;
contextType = currentActiveSnapshot;
currentActiveSnapshot = props = {
parent: ref,
depth: null === ref ? 0 : ref.depth + 1,
parent: contextType,
depth: null === contextType ? 0 : contextType.depth + 1,
context: type,
parentValue: prevThenableState,
parentValue: ref,
value: props
};
task.context = props;
renderNodeDestructiveImpl(
request,
task,
null,
JSCompiler_inline_result,
-1
);
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, prevThenableState, -1);
request = currentActiveSnapshot;
if (null === request) throw Error(formatProdErrorMessage(403));
props = request.parentValue;
keyPath = request.parentValue;
request.context._currentValue2 =
props === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED
keyPath === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED
? request.context._defaultValue
: props;
: keyPath;
request = currentActiveSnapshot = request.parent;
task.context = request;
task.keyPath = JSCompiler_inline_result;
return;
case REACT_CONTEXT_TYPE:
props = props.children;
props = props(type._currentValue2);
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props, -1);
task.keyPath = type;
return;
case REACT_LAZY_TYPE:
JSCompiler_inline_result = type._init;
type = JSCompiler_inline_result(type._payload);
props = resolveDefaultProps(type, props);
renderElement(request, task, prevThenableState, type, props, void 0);
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
void 0
);
return;
}
throw Error(
@@ -3403,15 +3450,20 @@ function renderNodeDestructiveImpl(
key = node.key,
props = node.props;
node = node.ref;
var name = getComponentNameFromType(type),
prevKeyPath = task.keyPath;
task.keyPath = [
task.keyPath,
name,
null == key ? (-1 === childIndex ? 0 : childIndex) : key
];
renderElement(request, task, prevThenableState, type, props, node);
task.keyPath = prevKeyPath;
var name = getComponentNameFromType(type);
renderElement(
request,
task,
[
task.keyPath,
name,
null == key ? (-1 === childIndex ? 0 : childIndex) : key
],
prevThenableState,
type,
props,
node
);
return;
case REACT_PORTAL_TYPE:
throw Error(formatProdErrorMessage(257));
@@ -4229,13 +4281,13 @@ function flushCompletedQueues(request, destination) {
completedBoundaries.splice(0, i);
var partialBoundaries = request.partialBoundaries;
for (i = 0; i < partialBoundaries.length; i++) {
var boundary$13 = partialBoundaries[i];
var boundary$15 = partialBoundaries[i];
a: {
clientRenderedBoundaries = request;
boundary = destination;
clientRenderedBoundaries.renderState.boundaryResources =
boundary$13.resources;
var completedSegments = boundary$13.completedSegments;
boundary$15.resources;
var completedSegments = boundary$15.completedSegments;
for (
resumableState$jscomp$1 = 0;
resumableState$jscomp$1 < completedSegments.length;
@@ -4245,7 +4297,7 @@ function flushCompletedQueues(request, destination) {
!flushPartiallyCompletedSegment(
clientRenderedBoundaries,
boundary,
boundary$13,
boundary$15,
completedSegments[resumableState$jscomp$1]
)
) {
@@ -4257,7 +4309,7 @@ function flushCompletedQueues(request, destination) {
completedSegments.splice(0, resumableState$jscomp$1);
JSCompiler_inline_result = writeResourcesForBoundary(
boundary,
boundary$13.resources,
boundary$15.resources,
clientRenderedBoundaries.renderState
);
}
@@ -4320,8 +4372,8 @@ function abort(request, reason) {
}
null !== request.destination &&
flushCompletedQueues(request, request.destination);
} catch (error$15) {
logRecoverableError(request, error$15), fatalError(request, error$15);
} catch (error$17) {
logRecoverableError(request, error$17), fatalError(request, error$17);
}
}
function onError() {}
@@ -4408,4 +4460,4 @@ exports.renderToString = function (children, options) {
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
);
};
exports.version = "18.3.0-www-modern-a9d281fb";
exports.version = "18.3.0-www-modern-c2a4cb0f";
@@ -9592,7 +9592,7 @@ function fatalError(request, error) {
}
}
function renderSuspenseBoundary(request, task, props) {
function renderSuspenseBoundary(request, task, keyPath, props) {
pushBuiltInComponentStackInDEV(task, "Suspense");
var parentBoundary = task.blockedBoundary;
var parentSegment = task.blockedSegment; // Each time we enter a suspense boundary, we split out into a new segment for
@@ -9603,11 +9603,7 @@ function renderSuspenseBoundary(request, task, props) {
var fallback = props.fallback;
var content = props.children;
var fallbackAbortSet = new Set();
var newBoundary = createSuspenseBoundary(
request,
fallbackAbortSet,
task.keyPath
);
var newBoundary = createSuspenseBoundary(request, fallbackAbortSet, keyPath);
var insertionIndex = parentSegment.chunks.length; // The children of the boundary segment is actually the fallback.
var boundarySegment = createPendingSegment(
@@ -9705,8 +9701,8 @@ function renderSuspenseBoundary(request, task, props) {
fallback,
parentBoundary,
boundarySegment,
fallbackAbortSet,
task.keyPath,
fallbackAbortSet, // TODO: Should distinguish key path of fallback and primary tasks
keyPath,
task.formatContext,
task.legacyContext,
task.context,
@@ -9722,7 +9718,7 @@ function renderSuspenseBoundary(request, task, props) {
popComponentStackInDEV(task);
}
function renderHostElement(request, task, type, props) {
function renderHostElement(request, task, keyPath, type, props) {
pushBuiltInComponentStackInDEV(task, type);
var segment = task.blockedSegment;
var children = pushStartInstance(
@@ -9736,13 +9732,16 @@ function renderHostElement(request, task, type, props) {
);
segment.lastPushedText = false;
var prevContext = task.formatContext;
task.formatContext = getChildFormatContext(prevContext, type, props); // We use the non-destructive form because if something suspends, we still
var prevKeyPath = task.keyPath;
task.formatContext = getChildFormatContext(prevContext, type, props);
task.keyPath = keyPath; // We use the non-destructive form because if something suspends, we still
// need to pop back up and finish this subtree of HTML.
renderNode(request, task, children, -1); // We expect that errors will fatal the whole task and that we don't need
// the correct context. Therefore this is not in a finally.
task.formatContext = prevContext;
task.keyPath = prevKeyPath;
pushEndInstance(
segment.chunks,
type,
@@ -9772,7 +9771,14 @@ function renderWithHooks(
return finishHooks(Component, props, result, secondArg);
}
function finishClassComponent(request, task, instance, Component, props) {
function finishClassComponent(
request,
task,
keyPath,
instance,
Component,
props
) {
var nextChildren = instance.render();
{
@@ -9789,15 +9795,18 @@ function finishClassComponent(request, task, instance, Component, props) {
}
}
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, nextChildren, -1);
task.keyPath = prevKeyPath;
}
function renderClassComponent(request, task, Component, props) {
function renderClassComponent(request, task, keyPath, Component, props) {
pushClassComponentStackInDEV(task, Component);
var maskedContext = undefined;
var instance = constructClassInstance(Component, props);
mountClassInstance(instance, Component, props, maskedContext);
finishClassComponent(request, task, instance, Component, props);
finishClassComponent(request, task, keyPath, instance, Component, props);
popComponentStackInDEV(task);
}
@@ -9815,6 +9824,7 @@ var hasWarnedAboutUsingContextAsConsumer = false; // This would typically be a f
function renderIndeterminateComponent(
request,
task,
keyPath,
prevThenableState,
Component,
props
@@ -9902,6 +9912,7 @@ function renderIndeterminateComponent(
finishFunctionComponent(
request,
task,
keyPath,
value,
hasId,
formStateCount,
@@ -9915,6 +9926,7 @@ function renderIndeterminateComponent(
function finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -9944,6 +9956,9 @@ function finishFunctionComponent(
}
}
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
if (hasId) {
// This component materialized an id. We treat this as its own level, with
// a single "child" slot.
@@ -9968,6 +9983,8 @@ function finishFunctionComponent(
// again, so we can use the destructive recursive form.
renderNodeDestructive(request, task, null, children, -1);
}
task.keyPath = prevKeyPath;
}
function validateFunctionComponentInDev(Component) {
@@ -10044,7 +10061,15 @@ function resolveDefaultProps(Component, baseProps) {
return baseProps;
}
function renderForwardRef(request, task, prevThenableState, type, props, ref) {
function renderForwardRef(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
pushFunctionComponentStackInDEV(task, type.render);
var children = renderWithHooks(
request,
@@ -10060,6 +10085,7 @@ function renderForwardRef(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -10068,12 +10094,21 @@ function renderForwardRef(request, task, prevThenableState, type, props, ref) {
popComponentStackInDEV(task);
}
function renderMemo(request, task, prevThenableState, type, props, ref) {
function renderMemo(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
var innerType = type.type;
var resolvedProps = resolveDefaultProps(innerType, props);
renderElement(
request,
task,
keyPath,
prevThenableState,
innerType,
resolvedProps,
@@ -10081,7 +10116,7 @@ function renderMemo(request, task, prevThenableState, type, props, ref) {
);
}
function renderContextConsumer(request, task, context, props) {
function renderContextConsumer(request, task, keyPath, context, props) {
// The logic below for Context differs depending on PROD or DEV mode. In
// DEV mode, we create a separate object for Context.Consumer that acts
// like a proxy to Context. This proxy object adds unnecessary code in PROD
@@ -10124,10 +10159,13 @@ function renderContextConsumer(request, task, context, props) {
var newValue = readContext$1(context);
var newChildren = render(newValue);
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, newChildren, -1);
task.keyPath = prevKeyPath;
}
function renderContextProvider(request, task, type, props) {
function renderContextProvider(request, task, keyPath, type, props) {
var context = type._context;
var value = props.value;
var children = props.children;
@@ -10137,9 +10175,12 @@ function renderContextProvider(request, task, type, props) {
prevSnapshot = task.context;
}
var prevKeyPath = task.keyPath;
task.context = pushProvider(context, value);
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, children, -1);
task.context = popProvider(context);
task.keyPath = prevKeyPath;
{
if (prevSnapshot !== task.context) {
@@ -10153,6 +10194,7 @@ function renderContextProvider(request, task, type, props) {
function renderLazyComponent(
request,
task,
keyPath,
prevThenableState,
lazyComponent,
props,
@@ -10166,6 +10208,7 @@ function renderLazyComponent(
renderElement(
request,
task,
keyPath,
prevThenableState,
Component,
resolvedProps,
@@ -10174,26 +10217,38 @@ function renderLazyComponent(
popComponentStackInDEV(task);
}
function renderOffscreen(request, task, props) {
function renderOffscreen(request, task, keyPath, props) {
var mode = props.mode;
if (mode === "hidden");
else {
// A visible Offscreen boundary is treated exactly like a fragment: a
// pure indirection.
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = prevKeyPath;
}
}
function renderElement(request, task, prevThenableState, type, props, ref) {
function renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
if (typeof type === "function") {
if (shouldConstruct(type)) {
renderClassComponent(request, task, type, props);
renderClassComponent(request, task, keyPath, type, props);
return;
} else {
renderIndeterminateComponent(
request,
task,
keyPath,
prevThenableState,
type,
props
@@ -10203,7 +10258,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
}
if (typeof type === "string") {
renderHostElement(request, task, type, props);
renderHostElement(request, task, keyPath, type, props);
return;
}
@@ -10222,33 +10277,42 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_STRICT_MODE_TYPE:
case REACT_PROFILER_TYPE:
case REACT_FRAGMENT_TYPE: {
var prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = prevKeyPath;
return;
}
case REACT_OFFSCREEN_TYPE: {
renderOffscreen(request, task, props);
renderOffscreen(request, task, keyPath, props);
return;
}
case REACT_SUSPENSE_LIST_TYPE: {
pushBuiltInComponentStackInDEV(task, "SuspenseList"); // TODO: SuspenseList should control the boundaries.
var _prevKeyPath = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = _prevKeyPath;
popComponentStackInDEV(task);
return;
}
case REACT_SCOPE_TYPE: {
{
var _prevKeyPath2 = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructive(request, task, null, props.children, -1);
task.keyPath = _prevKeyPath2;
return;
}
}
case REACT_SUSPENSE_TYPE: {
{
renderSuspenseBoundary(request, task, props);
renderSuspenseBoundary(request, task, keyPath, props);
}
return;
@@ -10258,27 +10322,42 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
if (typeof type === "object" && type !== null) {
switch (type.$$typeof) {
case REACT_FORWARD_REF_TYPE: {
renderForwardRef(request, task, prevThenableState, type, props, ref);
renderForwardRef(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
}
case REACT_MEMO_TYPE: {
renderMemo(request, task, prevThenableState, type, props, ref);
renderMemo(request, task, keyPath, prevThenableState, type, props, ref);
return;
}
case REACT_PROVIDER_TYPE: {
renderContextProvider(request, task, type, props);
renderContextProvider(request, task, keyPath, type, props);
return;
}
case REACT_CONTEXT_TYPE: {
renderContextConsumer(request, task, type, props);
renderContextConsumer(request, task, keyPath, type, props);
return;
}
case REACT_LAZY_TYPE: {
renderLazyComponent(request, task, prevThenableState, type, props);
renderLazyComponent(
request,
task,
keyPath,
prevThenableState,
type,
props
);
return;
}
}
@@ -10398,14 +10477,20 @@ function renderNodeDestructiveImpl(
var props = element.props;
var ref = element.ref;
var name = getComponentNameFromType(type);
var prevKeyPath = task.keyPath;
task.keyPath = [
var keyPath = [
task.keyPath,
name,
key == null ? (childIndex === -1 ? 0 : childIndex) : key
];
renderElement(request, task, prevThenableState, type, props, ref);
task.keyPath = prevKeyPath;
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
}
@@ -2798,6 +2798,7 @@ function fatalError(request, error) {
function finishFunctionComponent(
request,
task,
keyPath,
children,
hasId,
formStateCount,
@@ -2815,14 +2816,17 @@ function finishFunctionComponent(
: segment.push("\x3c!--F--\x3e");
}
}
formStateCount = task.keyPath;
task.keyPath = keyPath;
hasId
? ((hasId = task.treeContext),
(task.treeContext = pushTreeContext(hasId, 1, 0)),
? ((keyPath = task.treeContext),
(task.treeContext = pushTreeContext(keyPath, 1, 0)),
renderNode(request, task, children, -1),
(task.treeContext = hasId))
(task.treeContext = keyPath))
: didEmitFormStateMarkers
? renderNode(request, task, children, -1)
: renderNodeDestructiveImpl(request, task, null, children, -1);
task.keyPath = formStateCount;
}
function resolveDefaultProps(Component, baseProps) {
if (Component && Component.defaultProps) {
@@ -2835,7 +2839,15 @@ function resolveDefaultProps(Component, baseProps) {
}
return baseProps;
}
function renderElement(request, task, prevThenableState, type, props, ref) {
function renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
) {
if ("function" === typeof type)
if (type.prototype && type.prototype.isReactComponent) {
var JSCompiler_inline_result = emptyContextObject;
@@ -2932,7 +2944,10 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
}
else prevThenableState.queue = null;
props = JSCompiler_inline_result.render();
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props, -1);
task.keyPath = type;
} else
(currentlyRenderingComponent = {}),
(currentlyRenderingTask = task),
@@ -2945,6 +2960,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
props,
0 !== localIdCounter,
formStateCounter,
@@ -2963,9 +2979,12 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
);
JSCompiler_inline_result.lastPushedText = !1;
prevThenableState = task.formatContext;
contextType = task.keyPath;
task.formatContext = getChildFormatContext(prevThenableState, type, props);
task.keyPath = keyPath;
renderNode(request, task, ref, -1);
task.formatContext = prevThenableState;
task.keyPath = contextType;
a: {
task = JSCompiler_inline_result.chunks;
request = request.resumableState;
@@ -3011,17 +3030,29 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_STRICT_MODE_TYPE:
case REACT_PROFILER_TYPE:
case REACT_FRAGMENT_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_OFFSCREEN_TYPE:
"hidden" !== props.mode &&
renderNodeDestructiveImpl(request, task, null, props.children, -1);
((type = task.keyPath),
(task.keyPath = keyPath),
renderNodeDestructiveImpl(request, task, null, props.children, -1),
(task.keyPath = type));
return;
case REACT_SUSPENSE_LIST_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_SCOPE_TYPE:
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props.children, -1);
task.keyPath = type;
return;
case REACT_SUSPENSE_TYPE:
a: {
@@ -3030,7 +3061,6 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
ref = props.fallback;
props = props.children;
contextType = new Set();
partial = task.keyPath;
partial = {
status: 0,
id: null,
@@ -3042,7 +3072,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
fallbackAbortableTasks: contextType,
errorDigest: null,
resources: new Set(),
keyPath: partial
keyPath: keyPath
};
var boundarySegment = createPendingSegment(
request,
@@ -3098,7 +3128,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
type,
boundarySegment,
contextType,
task.keyPath,
keyPath,
task.formatContext,
task.legacyContext,
task.context,
@@ -3123,6 +3153,7 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
finishFunctionComponent(
request,
task,
keyPath,
props,
0 !== localIdCounter,
formStateCounter,
@@ -3132,53 +3163,69 @@ function renderElement(request, task, prevThenableState, type, props, ref) {
case REACT_MEMO_TYPE:
type = type.type;
props = resolveDefaultProps(type, props);
renderElement(request, task, prevThenableState, type, props, ref);
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
ref
);
return;
case REACT_PROVIDER_TYPE:
JSCompiler_inline_result = props.children;
prevThenableState = props.children;
JSCompiler_inline_result = task.keyPath;
type = type._context;
props = props.value;
prevThenableState = type._currentValue;
ref = type._currentValue;
type._currentValue = props;
ref = currentActiveSnapshot;
contextType = currentActiveSnapshot;
currentActiveSnapshot = props = {
parent: ref,
depth: null === ref ? 0 : ref.depth + 1,
parent: contextType,
depth: null === contextType ? 0 : contextType.depth + 1,
context: type,
parentValue: prevThenableState,
parentValue: ref,
value: props
};
task.context = props;
renderNodeDestructiveImpl(
request,
task,
null,
JSCompiler_inline_result,
-1
);
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, prevThenableState, -1);
request = currentActiveSnapshot;
if (null === request)
throw Error(
"Tried to pop a Context at the root of the app. This is a bug in React."
);
props = request.parentValue;
keyPath = request.parentValue;
request.context._currentValue =
props === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED
keyPath === REACT_SERVER_CONTEXT_DEFAULT_VALUE_NOT_LOADED
? request.context._defaultValue
: props;
: keyPath;
request = currentActiveSnapshot = request.parent;
task.context = request;
task.keyPath = JSCompiler_inline_result;
return;
case REACT_CONTEXT_TYPE:
props = props.children;
props = props(type._currentValue);
type = task.keyPath;
task.keyPath = keyPath;
renderNodeDestructiveImpl(request, task, null, props, -1);
task.keyPath = type;
return;
case REACT_LAZY_TYPE:
JSCompiler_inline_result = type._init;
type = JSCompiler_inline_result(type._payload);
props = resolveDefaultProps(type, props);
renderElement(request, task, prevThenableState, type, props, void 0);
renderElement(
request,
task,
keyPath,
prevThenableState,
type,
props,
void 0
);
return;
}
throw Error(
@@ -3203,15 +3250,20 @@ function renderNodeDestructiveImpl(
key = node.key,
props = node.props;
node = node.ref;
var name = getComponentNameFromType(type),
prevKeyPath = task.keyPath;
task.keyPath = [
task.keyPath,
name,
null == key ? (-1 === childIndex ? 0 : childIndex) : key
];
renderElement(request, task, prevThenableState, type, props, node);
task.keyPath = prevKeyPath;
var name = getComponentNameFromType(type);
renderElement(
request,
task,
[
task.keyPath,
name,
null == key ? (-1 === childIndex ? 0 : childIndex) : key
],
prevThenableState,
type,
props,
node
);
return;
case REACT_PORTAL_TYPE:
throw Error(
@@ -3929,13 +3981,13 @@ function flushCompletedQueues(request, destination) {
completedBoundaries.splice(0, i);
var partialBoundaries = request.partialBoundaries;
for (i = 0; i < partialBoundaries.length; i++) {
var boundary$13 = partialBoundaries[i];
var boundary$15 = partialBoundaries[i];
a: {
clientRenderedBoundaries = request;
boundary = destination;
clientRenderedBoundaries.renderState.boundaryResources =
boundary$13.resources;
var completedSegments = boundary$13.completedSegments;
boundary$15.resources;
var completedSegments = boundary$15.completedSegments;
for (
resumableState$jscomp$1 = 0;
resumableState$jscomp$1 < completedSegments.length;
@@ -3945,7 +3997,7 @@ function flushCompletedQueues(request, destination) {
!flushPartiallyCompletedSegment(
clientRenderedBoundaries,
boundary,
boundary$13,
boundary$15,
completedSegments[resumableState$jscomp$1]
)
) {
@@ -3957,7 +4009,7 @@ function flushCompletedQueues(request, destination) {
completedSegments.splice(0, resumableState$jscomp$1);
JSCompiler_inline_result = writeResourcesForBoundary(
boundary,
boundary$13.resources,
boundary$15.resources,
clientRenderedBoundaries.renderState
);
}
@@ -4017,8 +4069,8 @@ function abort(request, reason) {
}
null !== request.destination &&
flushCompletedQueues(request, request.destination);
} catch (error$15) {
logRecoverableError(request, error$15), fatalError(request, error$15);
} catch (error$17) {
logRecoverableError(request, error$17), fatalError(request, error$17);
}
}
exports.abortStream = function (stream) {
@@ -24356,7 +24356,7 @@ function createFiberRoot(
return root;
}
var ReactVersion = "18.3.0-www-modern-fa0eb004";
var ReactVersion = "18.3.0-www-modern-d9222bbe";
// Might add PROFILE later.