23
} from 'shared/ReactTypes';
24
import type {LazyComponent as LazyComponentType} from 'react/src/ReactLazy';
25
import type {
26
- SuspenseBoundaryID,
26
RenderState,
27
ResumableState,
28
FormatContext,
63
pushStartCompletedSuspenseBoundary,
64
pushEndCompletedSuspenseBoundary,
65
pushSegmentFinale,
67
- UNINITIALIZED_SUSPENSE_BOUNDARY_ID,
68
- assignSuspenseBoundaryID,
66
getChildFormatContext,
67
writeResourcesForBoundary,
68
writePreamble,
173
string | null /* name */,
174
string | number /* key */,
175
Array<ResumableNode> /* children */,
179
- SuspenseBoundaryID /* id */,
176
number /* rootSegmentID */,
177
];
178
189
3, // RESUME_SUSPENSE_BOUNDARY
190
string | null /* name */,
191
string | number /* key */,
196
- SuspenseBoundaryID /* id */,
192
number /* rootSegmentID */,
193
];
194
224
225
type SuspenseBoundary = {
226
status: 0 | 1 | 4 | 5,
232
- id: SuspenseBoundaryID,
227
rootSegmentID: number,
228
errorDigest: ?string, // the error hash if it errors
229
errorMessage?: string, // the error string if it errors
569
): SuspenseBoundary {
570
return {
571
status: PENDING,
578
- id: UNINITIALIZED_SUSPENSE_BOUNDARY_ID,
572
rootSegmentID: -1,
573
parentFlushed: false,
574
pendingTasks: 0,
997
);
998
resumedBoundary.parentFlushed = true;
999
// We restore the same id of this boundary as was used during prerender.
1007
- resumedBoundary.id = replayNode[4];
1008
- resumedBoundary.rootSegmentID = replayNode[5];
1000
+ resumedBoundary.rootSegmentID = replayNode[4];
1001
1002
// We can reuse the current context and task to render the content immediately without
1003
// context switching. We just need to temporarily switch which boundary and replay node
1094
task.keyPath,
1095
);
1096
resumedBoundary.parentFlushed = true;
1097
+ const id = replayNode[3];
1098
// We restore the same id of this boundary as was used during prerender.
1106
- resumedBoundary.id = replayNode[3];
1107
- resumedBoundary.rootSegmentID = replayNode[4];
1099
+ resumedBoundary.rootSegmentID = id;
1100
1101
const resumedSegment = createPendingSegment(
1102
request,
1107
false,
1108
);
1109
resumedSegment.parentFlushed = true;
1118
- resumedSegment.id = replayNode[4];
1110
+ resumedSegment.id = id;
1111
1112
// We can reuse the current context and task to render the content immediately without
1113
// context switching. We just need to temporarily switch which boundary and replay node
2639
boundary.status = POSTPONED;
2640
// We need to eagerly assign it an ID because we'll need to refer to
2641
// it before flushing and we know that we can't inline it.
2650
- boundary.id = assignSuspenseBoundaryID(
2651
- request.renderState,
2652
- request.resumableState,
2653
- );
2642
boundary.rootSegmentID = request.nextSegmentId++;
2643
2644
const boundaryKeyPath = boundary.keyPath;
2657
RESUME_SUSPENSE_BOUNDARY,
2658
boundaryKeyPath[1],
2659
boundaryKeyPath[2],
2672
- boundary.id,
2660
boundary.rootSegmentID,
2661
];
2662
addToReplayParent(boundaryNode, boundaryKeyPath[0], trackedPostpones);
2668
boundaryKeyPath[1],
2669
boundaryKeyPath[2],
2670
children,
2684
- boundary.id,
2671
boundary.rootSegmentID,
2672
];
2673
trackedPostpones.workingMap.set(boundaryKeyPath, boundaryNode);
3084
3085
function abortRemainingSuspenseBoundary(
3086
request: Request,
3101
- id: SuspenseBoundaryID,
3087
rootSegmentID: number,
3088
error: mixed,
3089
errorDigest: ?string,
3095
);
3096
resumedBoundary.parentFlushed = true;
3097
// We restore the same id of this boundary as was used during prerender.
3113
- resumedBoundary.id = id;
3098
resumedBoundary.rootSegmentID = rootSegmentID;
3099
3100
resumedBoundary.status = CLIENT_RENDERED;
3143
}
3144
case REPLAY_SUSPENSE_BOUNDARY: {
3145
const boundaryNode: ReplaySuspenseBoundary = node;
3162
- const id = boundaryNode[4];
3163
- const rootSegmentID = boundaryNode[5];
3146
+ const rootSegmentID = boundaryNode[4];
3147
abortRemainingSuspenseBoundary(
3148
request,
3166
- id,
3149
rootSegmentID,
3150
error,
3151
errorDigest,
3154
}
3155
case RESUME_SUSPENSE_BOUNDARY: {
3156
const boundaryNode: ResumeSuspenseBoundary = node;
3175
- const id = boundaryNode[3];
3176
- const rootSegmentID = boundaryNode[4];
3157
+ const rootSegmentID = boundaryNode[3];
3158
abortRemainingSuspenseBoundary(
3159
request,
3179
- id,
3160
rootSegmentID,
3161
error,
3162
errorDigest,
3733
if (boundary.status === PENDING) {
3734
// For pending boundaries we lazily assign an ID to the boundary
3735
// and root segment.
3756
- boundary.id = assignSuspenseBoundaryID(
3757
- request.renderState,
3758
- request.resumableState,
3759
- );
3736
boundary.rootSegmentID = request.nextSegmentId++;
3737
}
3738
3743
3744
// This boundary is still loading. Emit a pending suspense boundary wrapper.
3745
3770
- /// This is the first time we should have referenced this ID.
3771
- const id = boundary.id;
3772
-
3746
+ const id = boundary.rootSegmentID;
3747
writeStartPendingSuspenseBoundary(destination, request.renderState, id);
3748
3749
// Flush the fallback.
3765
writeStartPendingSuspenseBoundary(
3766
destination,
3767
request.renderState,
3794
- boundary.id,
3768
+ boundary.rootSegmentID,
3769
);
3770
3771
// Flush the fallback.
3803
destination,
3804
request.resumableState,
3805
request.renderState,
3832
- boundary.id,
3806
+ boundary.rootSegmentID,
3807
boundary.errorDigest,
3808
boundary.errorMessage,
3809
boundary.errorComponentStack,
3856
destination,
3857
request.resumableState,
3858
request.renderState,
3885
- boundary.id,
3859
boundary.rootSegmentID,
3860
boundary.resources,
3861
);