[Fizz] Use RequestInstance constructor for resuming (#30947)
We added enough fields to need a constructor instead of inline object in V8. We didn't update the resumeRequest path though so it wasn't using the constructor and had a different hidden class.
Sebastian Markbåge committed
Sep 11, 2024 at 11:35 UTC
1bb056363c02fa9d188cc1122595d1587aa59d86
1 file changed
+54
-67
packages/react-server/src/ReactFizzServer.js
+54
-67
@@ -401,7 +401,6 @@ function noop(): void {}
401
402
function RequestInstance(
403
this: $FlowFixMe,
404
- children: ReactNodeList,
404
resumableState: ResumableState,
405
renderState: RenderState,
406
rootFormatContext: FormatContext,
@@ -447,38 +446,6 @@ function RequestInstance(
446
if (__DEV__) {
447
this.didWarnForKey = null;
448
}
450
- // This segment represents the root fallback.
451
- const rootSegment = createPendingSegment(
452
- this,
453
- 0,
454
- null,
455
- rootFormatContext,
456
- // Root segments are never embedded in Text on either edge
457
- false,
458
- false,
459
- );
460
- // There is no parent so conceptually, we're unblocked to flush this segment.
461
- rootSegment.parentFlushed = true;
462
- const rootTask = createRenderTask(
463
- this,
464
- null,
465
- children,
466
- -1,
467
- null,
468
- rootSegment,
469
- null,
470
- abortSet,
471
- null,
472
- rootFormatContext,
473
- rootContextSnapshot,
474
- emptyTreeContext,
475
- null,
476
- false,
477
- emptyContextObject,
478
- null,
479
- );
480
- pushComponentStack(rootTask);
481
- pingedTasks.push(rootTask);
449
}
450
451
export function createRequest(
@@ -496,8 +463,7 @@ export function createRequest(
463
formState: void | null | ReactFormState<any, any>,
464
): Request {
465
// $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors
499
- return new RequestInstance(
500
- children,
466
+ const request: Request = new RequestInstance(
467
resumableState,
468
renderState,
469
rootFormatContext,
@@ -510,6 +476,40 @@ export function createRequest(
476
onPostpone,
477
formState,
478
);
479
+
480
+ // This segment represents the root fallback.
481
+ const rootSegment = createPendingSegment(
482
+ request,
483
+ 0,
484
+ null,
485
+ rootFormatContext,
486
+ // Root segments are never embedded in Text on either edge
487
+ false,
488
+ false,
489
+ );
490
+ // There is no parent so conceptually, we're unblocked to flush this segment.
491
+ rootSegment.parentFlushed = true;
492
+ const rootTask = createRenderTask(
493
+ request,
494
+ null,
495
+ children,
496
+ -1,
497
+ null,
498
+ rootSegment,
499
+ null,
500
+ request.abortableTasks,
501
+ null,
502
+ rootFormatContext,
503
+ rootContextSnapshot,
504
+ emptyTreeContext,
505
+ null,
506
+ false,
507
+ emptyContextObject,
508
+ null,
509
+ );
510
+ pushComponentStack(rootTask);
511
+ request.pingedTasks.push(rootTask);
512
+ return request;
513
}
514
515
export function createPrerenderRequest(
@@ -559,35 +559,22 @@ export function resumeRequest(
559
onFatalError: void | ((error: mixed) => void),
560
onPostpone: void | ((reason: string, postponeInfo: PostponeInfo) => void),
561
): Request {
562
- const pingedTasks: Array<Task> = [];
563
- const abortSet: Set<Task> = new Set();
564
- const request: Request = {
565
- destination: null,
566
- flushScheduled: false,
567
- resumableState: postponedState.resumableState,
562
+ // $FlowFixMe[invalid-constructor]: the shapes are exact here but Flow doesn't like constructors
563
+ const request: Request = new RequestInstance(
564
+ postponedState.resumableState,
565
renderState,
569
- rootFormatContext: postponedState.rootFormatContext,
570
- progressiveChunkSize: postponedState.progressiveChunkSize,
571
- status: OPEN,
572
- fatalError: null,
573
- nextSegmentId: postponedState.nextSegmentId,
574
- allPendingTasks: 0,
575
- pendingRootTasks: 0,
576
- completedRootSegment: null,
577
- abortableTasks: abortSet,
578
- pingedTasks: pingedTasks,
579
- clientRenderedBoundaries: ([]: Array<SuspenseBoundary>),
580
- completedBoundaries: ([]: Array<SuspenseBoundary>),
581
- partialBoundaries: ([]: Array<SuspenseBoundary>),
582
- trackedPostpones: null,
583
- onError: onError === undefined ? defaultErrorHandler : onError,
584
- onPostpone: onPostpone === undefined ? noop : onPostpone,
585
- onAllReady: onAllReady === undefined ? noop : onAllReady,
586
- onShellReady: onShellReady === undefined ? noop : onShellReady,
587
- onShellError: onShellError === undefined ? noop : onShellError,
588
- onFatalError: onFatalError === undefined ? noop : onFatalError,
589
- formState: null,
590
- };
566
+ postponedState.rootFormatContext,
567
+ postponedState.progressiveChunkSize,
568
+ onError,
569
+ onAllReady,
570
+ onShellReady,
571
+ onShellError,
572
+ onFatalError,
573
+ onPostpone,
574
+ null,
575
+ );
576
+ request.nextSegmentId = postponedState.nextSegmentId;
577
+
578
if (typeof postponedState.replaySlots === 'number') {
579
const resumedId = postponedState.replaySlots;
580
// We have a resume slot at the very root. This is effectively just a full rerender.
@@ -611,7 +598,7 @@ export function resumeRequest(
598
null,
599
rootSegment,
600
null,
614
- abortSet,
601
+ request.abortableTasks,
602
null,
603
postponedState.rootFormatContext,
604
rootContextSnapshot,
@@ -622,7 +609,7 @@ export function resumeRequest(
609
null,
610
);
611
pushComponentStack(rootTask);
625
- pingedTasks.push(rootTask);
612
+ request.pingedTasks.push(rootTask);
613
return request;
614
}
615
@@ -639,7 +626,7 @@ export function resumeRequest(
626
-1,
627
null,
628
null,
642
- abortSet,
629
+ request.abortableTasks,
630
null,
631
postponedState.rootFormatContext,
632
rootContextSnapshot,
@@ -650,7 +637,7 @@ export function resumeRequest(
637
null,
638
);
639
pushComponentStack(rootTask);
653
- pingedTasks.push(rootTask);
640
+ request.pingedTasks.push(rootTask);
641
return request;
642
}
643