( request: Request, boundary: Root | SuspenseBoundary, row: null | SuspenseListRow, segment: null | Segment, )
| 5014 | } |
| 5015 | |
| 5016 | function finishedTask( |
| 5017 | request: Request, |
| 5018 | boundary: Root | SuspenseBoundary, |
| 5019 | row: null | SuspenseListRow, |
| 5020 | segment: null | Segment, |
| 5021 | ) { |
| 5022 | if (row !== null) { |
| 5023 | if (--row.pendingTasks === 0) { |
| 5024 | finishSuspenseListRow(request, row); |
| 5025 | } else if (row.together) { |
| 5026 | tryToResolveTogetherRow(request, row); |
| 5027 | } |
| 5028 | } |
| 5029 | request.allPendingTasks--; |
| 5030 | if (boundary === null) { |
| 5031 | if (segment !== null && segment.parentFlushed) { |
| 5032 | if (request.completedRootSegment !== null) { |
| 5033 | throw new Error( |
| 5034 | 'There can only be one root segment. This is a bug in React.', |
| 5035 | ); |
| 5036 | } |
| 5037 | |
| 5038 | request.completedRootSegment = segment; |
| 5039 | } |
| 5040 | request.pendingRootTasks--; |
| 5041 | if (request.pendingRootTasks === 0) { |
| 5042 | completeShell(request); |
| 5043 | } |
| 5044 | } else { |
| 5045 | boundary.pendingTasks--; |
| 5046 | if (boundary.status === CLIENT_RENDERED) { |
| 5047 | // This already errored. |
| 5048 | } else if (boundary.pendingTasks === 0) { |
| 5049 | if (boundary.status === PENDING) { |
| 5050 | boundary.status = COMPLETED; |
| 5051 | } |
| 5052 | // This must have been the last segment we were waiting on. This boundary is now complete. |
| 5053 | if (segment !== null && segment.parentFlushed) { |
| 5054 | // Our parent segment already flushed, so we need to schedule this segment to be emitted. |
| 5055 | // If it is a segment that was aborted, we'll write other content instead so we don't need |
| 5056 | // to emit it. |
| 5057 | if (segment.status === COMPLETED || segment.status === ABORTED) { |
| 5058 | queueCompletedSegment(boundary, segment); |
| 5059 | } |
| 5060 | } |
| 5061 | if (boundary.parentFlushed) { |
| 5062 | // The segment might be part of a segment that didn't flush yet, but if the boundary's |
| 5063 | // parent flushed, we need to schedule the boundary to be emitted. |
| 5064 | request.completedBoundaries.push(boundary); |
| 5065 | } |
| 5066 | |
| 5067 | // We can now cancel any pending task on the fallback since we won't need to show it anymore. |
| 5068 | // This needs to happen after we read the parentFlushed flags because aborting can finish |
| 5069 | // work which can trigger user code, which can start flushing, which can change those flags. |
| 5070 | // If the boundary was POSTPONED, we still need to finish the fallback first. |
| 5071 | // If the boundary is eligible to be outlined during flushing we can't cancel the fallback |
| 5072 | // since we might need it when it's being outlined. |
| 5073 | if (boundary.status === COMPLETED) { |
no test coverage detected