diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts index 7f8640122b942..e0b0536f28cc6 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts @@ -325,6 +325,15 @@ function runWithEnvironment( outlineJSX(hir); } + if (env.config.enableNameAnonymousFunctions) { + nameAnonymousFunctions(hir); + log({ + kind: 'hir', + name: 'NameAnonymousFunctions', + value: hir, + }); + } + if (env.config.enableFunctionOutlining) { outlineFunctions(hir, fbtOperands); log({kind: 'hir', name: 'OutlineFunctions', value: hir}); @@ -415,15 +424,6 @@ function runWithEnvironment( }); } - if (env.config.enableNameAnonymousFunctions) { - nameAnonymousFunctions(hir); - log({ - kind: 'hir', - name: 'NameAnonymougFunctions', - value: hir, - }); - } - const reactiveFunction = buildReactiveFunction(hir); log({ kind: 'reactive', diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts index 4d0461fe105b0..702eaf0f692a2 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/BuildHIR.ts @@ -47,6 +47,7 @@ import { makePropertyLiteral, makeType, promoteTemporary, + validateIdentifierName, } from './HIR'; import HIRBuilder, {Bindings, createTemporaryPlace} from './HIRBuilder'; import {BuiltInArrayId} from './ObjectShape'; @@ -213,6 +214,16 @@ export function lower( ); } + let validatedId: HIRFunction['id'] = null; + if (id != null) { + const idResult = validateIdentifierName(id); + if (idResult.isErr()) { + builder.errors.merge(idResult.unwrapErr()); + } else { + validatedId = idResult.unwrap().value; + } + } + if (builder.errors.hasAnyErrors()) { return Err(builder.errors); } @@ -234,7 +245,8 @@ export function lower( ); return Ok({ - id, + id: validatedId, + nameHint: null, params, fnType: bindings == null ? env.fnType : 'Other', returnTypeAnnotation: null, // TODO: extract the actual return type node if present @@ -3563,19 +3575,14 @@ function lowerFunctionToValue( ): InstructionValue { const exprNode = expr.node; const exprLoc = exprNode.loc ?? GeneratedSource; - let name: string | null = null; - if (expr.isFunctionExpression()) { - name = expr.get('id')?.node?.name ?? null; - } else if (expr.isFunctionDeclaration()) { - name = expr.get('id')?.node?.name ?? null; - } const loweredFunc = lowerFunction(builder, expr); if (!loweredFunc) { return {kind: 'UnsupportedNode', node: exprNode, loc: exprLoc}; } return { kind: 'FunctionExpression', - name, + name: loweredFunc.func.id, + nameHint: null, type: expr.node.type, loc: exprLoc, loweredFunc, diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts index fa502f821d0b7..4d2d4ed80d69c 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts @@ -7,7 +7,11 @@ import {BindingKind} from '@babel/traverse'; import * as t from '@babel/types'; -import {CompilerError} from '../CompilerError'; +import { + CompilerDiagnostic, + CompilerError, + ErrorCategory, +} from '../CompilerError'; import {assertExhaustive} from '../Utils/utils'; import {Environment, ReactFunctionType} from './Environment'; import type {HookKind} from './ObjectShape'; @@ -54,7 +58,8 @@ export type SourceLocation = t.SourceLocation | typeof GeneratedSource; */ export type ReactiveFunction = { loc: SourceLocation; - id: string | null; + id: ValidIdentifierName | null; + nameHint: string | null; params: Array; generator: boolean; async: boolean; @@ -276,7 +281,8 @@ export type ReactiveTryTerminal = { // A function lowered to HIR form, ie where its body is lowered to an HIR control-flow graph export type HIRFunction = { loc: SourceLocation; - id: string | null; + id: ValidIdentifierName | null; + nameHint: string | null; fnType: ReactFunctionType; env: Environment; params: Array; @@ -1124,7 +1130,8 @@ export type JsxAttribute = export type FunctionExpression = { kind: 'FunctionExpression'; - name: string | null; + name: ValidIdentifierName | null; + nameHint: string | null; loweredFunc: LoweredFunction; type: | 'ArrowFunctionExpression' @@ -1301,11 +1308,41 @@ export function forkTemporaryIdentifier( export function validateIdentifierName( name: string, -): Result { - if (isReservedWord(name) || !t.isValidIdentifier(name)) { - return Err(null); +): Result { + if (isReservedWord(name)) { + const error = new CompilerError(); + error.pushDiagnostic( + CompilerDiagnostic.create({ + category: ErrorCategory.Syntax, + reason: 'Expected a non-reserved identifier name', + description: `\`${name}\` is a reserved word in JavaScript and cannot be used as an identifier name`, + suggestions: null, + }).withDetails({ + kind: 'error', + loc: GeneratedSource, + message: 'reserved word', + }), + ); + return Err(error); + } else if (!t.isValidIdentifier(name)) { + const error = new CompilerError(); + error.pushDiagnostic( + CompilerDiagnostic.create({ + category: ErrorCategory.Syntax, + reason: `Expected a valid identifier name`, + description: `\`${name}\` is not a valid JavaScript identifier`, + suggestions: null, + }).withDetails({ + kind: 'error', + loc: GeneratedSource, + message: 'reserved word', + }), + ); } - return Ok(makeIdentifierName(name).value); + return Ok({ + kind: 'named', + value: name as ValidIdentifierName, + }); } /** @@ -1314,31 +1351,7 @@ export function validateIdentifierName( * original source code. */ export function makeIdentifierName(name: string): ValidatedIdentifier { - if (isReservedWord(name)) { - CompilerError.throwInvalidJS({ - reason: 'Expected a non-reserved identifier name', - loc: GeneratedSource, - description: `\`${name}\` is a reserved word in JavaScript and cannot be used as an identifier name`, - suggestions: null, - }); - } else { - CompilerError.invariant(t.isValidIdentifier(name), { - reason: `Expected a valid identifier name`, - description: `\`${name}\` is not a valid JavaScript identifier`, - details: [ - { - kind: 'error', - loc: GeneratedSource, - message: null, - }, - ], - suggestions: null, - }); - } - return { - kind: 'named', - value: name as ValidIdentifierName, - }; + return validateIdentifierName(name).unwrap(); } /** diff --git a/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts b/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts index 197e486e8af3b..71fb4c43b33e8 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/HIR/PrintHIR.ts @@ -56,6 +56,9 @@ export function printFunction(fn: HIRFunction): string { } else { definition += '<>'; } + if (fn.nameHint != null) { + definition += ` ${fn.nameHint}`; + } if (fn.params.length !== 0) { definition += '(' + diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts index 8b82e685b0bd3..911f71329b440 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingEffects.ts @@ -748,10 +748,14 @@ function applyEffect( case 'Alias': case 'Capture': { CompilerError.invariant( - effect.kind === 'Capture' || initialized.has(effect.into.identifier.id), + effect.kind === 'Capture' || + effect.kind === 'MaybeAlias' || + initialized.has(effect.into.identifier.id), { - reason: `Expected destination value to already be initialized within this instruction for Alias effect`, - description: `Destination ${printPlace(effect.into)} is not initialized in this instruction`, + reason: `Expected destination to already be initialized within this instruction`, + description: + `Destination ${printPlace(effect.into)} is not initialized in this ` + + `instruction for effect ${printAliasingEffect(effect)}`, details: [ { kind: 'error', @@ -767,49 +771,67 @@ function applyEffect( * copy-on-write semantics, then we can prune the effect */ const intoKind = state.kind(effect.into).kind; - let isMutableDesination: boolean; + let destinationType: 'context' | 'mutable' | null = null; switch (intoKind) { - case ValueKind.Context: - case ValueKind.Mutable: - case ValueKind.MaybeFrozen: { - isMutableDesination = true; + case ValueKind.Context: { + destinationType = 'context'; break; } - default: { - isMutableDesination = false; + case ValueKind.Mutable: + case ValueKind.MaybeFrozen: { + destinationType = 'mutable'; break; } } const fromKind = state.kind(effect.from).kind; - let isMutableReferenceType: boolean; + let sourceType: 'context' | 'mutable' | 'frozen' | null = null; switch (fromKind) { + case ValueKind.Context: { + sourceType = 'context'; + break; + } case ValueKind.Global: case ValueKind.Primitive: { - isMutableReferenceType = false; break; } case ValueKind.Frozen: { - isMutableReferenceType = false; - applyEffect( - context, - state, - { - kind: 'ImmutableCapture', - from: effect.from, - into: effect.into, - }, - initialized, - effects, - ); + sourceType = 'frozen'; break; } default: { - isMutableReferenceType = true; + sourceType = 'mutable'; break; } } - if (isMutableDesination && isMutableReferenceType) { + + if (sourceType === 'frozen') { + applyEffect( + context, + state, + { + kind: 'ImmutableCapture', + from: effect.from, + into: effect.into, + }, + initialized, + effects, + ); + } else if ( + (sourceType === 'mutable' && destinationType === 'mutable') || + effect.kind === 'MaybeAlias' + ) { effects.push(effect); + } else if ( + (sourceType === 'context' && destinationType != null) || + (sourceType === 'mutable' && destinationType === 'context') + ) { + applyEffect( + context, + state, + {kind: 'MaybeAlias', from: effect.from, into: effect.into}, + initialized, + effects, + ); } break; } diff --git a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingRanges.ts b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingRanges.ts index 32f84e1e28b2a..43148dc4c67fa 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingRanges.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Inference/InferMutationAliasingRanges.ts @@ -779,7 +779,13 @@ class AliasingState { if (edge.index >= index) { break; } - queue.push({place: edge.node, transitive, direction: 'forwards', kind}); + queue.push({ + place: edge.node, + transitive, + direction: 'forwards', + // Traversing a maybeAlias edge always downgrades to conditional mutation + kind: edge.kind === 'maybeAlias' ? MutationKind.Conditional : kind, + }); } for (const [alias, when] of node.createdFrom) { if (when >= index) { @@ -807,7 +813,12 @@ class AliasingState { if (when >= index) { continue; } - queue.push({place: alias, transitive, direction: 'backwards', kind}); + queue.push({ + place: alias, + transitive, + direction: 'backwards', + kind, + }); } /** * MaybeAlias indicates potential data flow from unknown function calls, diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts index 62845934c16f4..50f00427205bb 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts @@ -249,6 +249,7 @@ function emitSelectorFn(env: Environment, keys: Array): Instruction { const fn: HIRFunction = { loc: GeneratedSource, id: null, + nameHint: null, fnType: 'Other', env, params: [obj], @@ -275,6 +276,7 @@ function emitSelectorFn(env: Environment, keys: Array): Instruction { value: { kind: 'FunctionExpression', name: null, + nameHint: null, loweredFunc: { func: fn, }, diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineFunctions.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineFunctions.ts index 0e6d1fd59201f..6ab0a811ff5d9 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineFunctions.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineFunctions.ts @@ -31,7 +31,9 @@ export function outlineFunctions( ) { const loweredFunc = value.loweredFunc.func; - const id = fn.env.generateGloballyUniqueIdentifierName(loweredFunc.id); + const id = fn.env.generateGloballyUniqueIdentifierName( + loweredFunc.id ?? loweredFunc.nameHint, + ); loweredFunc.id = id.value; fn.env.outlineFunction(loweredFunc, null); diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts index 6232456e620c3..5c98997953d0e 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/OutlineJsx.ts @@ -364,6 +364,7 @@ function emitOutlinedFn( const fn: HIRFunction = { loc: GeneratedSource, id: null, + nameHint: null, fnType: 'Other', env, params: [propsObj], diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/BuildReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/BuildReactiveFunction.ts index b400bb349876a..2e8584050eb7a 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/BuildReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/BuildReactiveFunction.ts @@ -44,6 +44,7 @@ export function buildReactiveFunction(fn: HIRFunction): ReactiveFunction { return { loc: fn.loc, id: fn.id, + nameHint: fn.nameHint, params: fn.params, generator: fn.generator, async: fn.async, diff --git a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts index 28d8afd84b4fe..c497253a22fb5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/CodegenReactiveFunction.ts @@ -43,7 +43,6 @@ import { ValidIdentifierName, getHookKind, makeIdentifierName, - validateIdentifierName, } from '../HIR/HIR'; import {printIdentifier, printInstruction, printPlace} from '../HIR/PrintHIR'; import {eachPatternOperand} from '../HIR/visitors'; @@ -62,6 +61,7 @@ export const EARLY_RETURN_SENTINEL = 'react.early_return_sentinel'; export type CodegenFunction = { type: 'CodegenFunction'; id: t.Identifier | null; + nameHint: string | null; params: t.FunctionDeclaration['params']; body: t.BlockStatement; generator: boolean; @@ -384,6 +384,7 @@ function codegenReactiveFunction( type: 'CodegenFunction', loc: fn.loc, id: fn.id !== null ? t.identifier(fn.id) : null, + nameHint: fn.nameHint, params, body, generator: fn.generator, @@ -2328,10 +2329,6 @@ function codegenInstructionValue( reactiveFunction, ).unwrap(); - const validatedName = - instrValue.name != null - ? validateIdentifierName(instrValue.name) - : Err(null); if (instrValue.type === 'ArrowFunctionExpression') { let body: t.BlockStatement | t.Expression = fn.body; if (body.body.length === 1 && loweredFunc.directives.length == 0) { @@ -2343,9 +2340,7 @@ function codegenInstructionValue( value = t.arrowFunctionExpression(fn.params, body, fn.async); } else { value = t.functionExpression( - validatedName - .map(name => t.identifier(name)) - .unwrapOr(null), + instrValue.name != null ? t.identifier(instrValue.name) : null, fn.params, fn.body, fn.generator, @@ -2354,10 +2349,10 @@ function codegenInstructionValue( } if ( cx.env.config.enableNameAnonymousFunctions && - validatedName.isErr() && - instrValue.name != null + instrValue.name == null && + instrValue.nameHint != null ) { - const name = instrValue.name; + const name = instrValue.nameHint; value = t.memberExpression( t.objectExpression([t.objectProperty(t.stringLiteral(name), value)]), t.stringLiteral(name), diff --git a/compiler/packages/babel-plugin-react-compiler/src/Transform/NameAnonymousFunctions.ts b/compiler/packages/babel-plugin-react-compiler/src/Transform/NameAnonymousFunctions.ts index 5fed3af0f733f..cf6d443b907ad 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Transform/NameAnonymousFunctions.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Transform/NameAnonymousFunctions.ts @@ -26,7 +26,8 @@ export function nameAnonymousFunctions(fn: HIRFunction): void { * nesting depth. */ const name = `${prefix}${node.generatedName}]`; - node.fn.name = name; + node.fn.nameHint = name; + node.fn.loweredFunc.func.nameHint = name; } /** * Whether or not we generated a name for the function at this node, diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/name-anonymous-functions-outline.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/name-anonymous-functions-outline.expect.md new file mode 100644 index 0000000000000..a1267c6f8295b --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/name-anonymous-functions-outline.expect.md @@ -0,0 +1,52 @@ + +## Input + +```javascript +// @enableNameAnonymousFunctions +import {Stringify} from 'shared-runtime'; + +function Component(props) { + const onClick = () => { + console.log('hello!'); + }; + return
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableNameAnonymousFunctions +import { Stringify } from "shared-runtime"; + +function Component(props) { + const $ = _c(1); + const onClick = _ComponentOnClick; + let t0; + if ($[0] === Symbol.for("react.memo_cache_sentinel")) { + t0 =
; + $[0] = t0; + } else { + t0 = $[0]; + } + return t0; +} +function _ComponentOnClick() { + console.log("hello!"); +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{ value: 42 }], +}; + +``` + +### Eval output +(kind: ok)
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/name-anonymous-functions-outline.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/name-anonymous-functions-outline.js new file mode 100644 index 0000000000000..0906cb928a8c3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/name-anonymous-functions-outline.js @@ -0,0 +1,14 @@ +// @enableNameAnonymousFunctions +import {Stringify} from 'shared-runtime'; + +function Component(props) { + const onClick = () => { + console.log('hello!'); + }; + return
; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{value: 42}], +}; diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dispatch-spread-event-marks-event-frozen.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dispatch-spread-event-marks-event-frozen.expect.md new file mode 100644 index 0000000000000..699140137ac26 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dispatch-spread-event-marks-event-frozen.expect.md @@ -0,0 +1,82 @@ + +## Input + +```javascript +// @compilationMode:"infer" +function Component() { + const dispatch = useDispatch(); + // const [state, setState] = useState(0); + + return ( +
+ { + dispatch(...event.target); + event.target.value = ''; + }} + /> +
+ ); +} + +function useDispatch() { + 'use no memo'; + // skip compilation to make it easier to debug the above function + return (...values) => { + console.log(...values); + }; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @compilationMode:"infer" +function Component() { + const $ = _c(2); + const dispatch = useDispatch(); + let t0; + if ($[0] !== dispatch) { + t0 = ( +
+ { + dispatch(...event.target); + event.target.value = ""; + }} + /> +
+ ); + $[0] = dispatch; + $[1] = t0; + } else { + t0 = $[1]; + } + return t0; +} + +function useDispatch() { + "use no memo"; + // skip compilation to make it easier to debug the above function + return (...values) => { + console.log(...values); + }; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; + +``` + +### Eval output +(kind: ok)
\ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dispatch-spread-event-marks-event-frozen.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dispatch-spread-event-marks-event-frozen.js new file mode 100644 index 0000000000000..386729e407897 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/repro-dispatch-spread-event-marks-event-frozen.js @@ -0,0 +1,30 @@ +// @compilationMode:"infer" +function Component() { + const dispatch = useDispatch(); + // const [state, setState] = useState(0); + + return ( +
+ { + dispatch(...event.target); + event.target.value = ''; + }} + /> +
+ ); +} + +function useDispatch() { + 'use no memo'; + // skip compilation to make it easier to debug the above function + return (...values) => { + console.log(...values); + }; +} + +export const FIXTURE_ENTRYPOINT = { + fn: Component, + params: [{}], +}; diff --git a/fixtures/flight/src/App.js b/fixtures/flight/src/App.js index e6366f4bd0ea4..df2c8922b8424 100644 --- a/fixtures/flight/src/App.js +++ b/fixtures/flight/src/App.js @@ -21,6 +21,8 @@ import {Note} from './cjs/Note.js'; import {GenerateImage} from './GenerateImage.js'; +import LargeContent from './LargeContent.js'; + import {like, greet, increment} from './actions.js'; import {getServerState} from './ServerState.js'; @@ -233,6 +235,11 @@ export default async function App({prerender, noCache}) { {dedupedChild} {Promise.resolve([dedupedChild])} + {prerender ? null : ( // TODO: prerender is broken for large content for some reason. + + + + )} diff --git a/fixtures/flight/src/LargeContent.js b/fixtures/flight/src/LargeContent.js new file mode 100644 index 0000000000000..cacdda3df725e --- /dev/null +++ b/fixtures/flight/src/LargeContent.js @@ -0,0 +1,1115 @@ +import * as React from 'react'; + +export default async function LargeContent() { + return ( +
+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras auctor + dapibus nunc, at feugiat sem tempor id. Pellentesque euismod a libero in + dignissim. Curabitur consequat urna blandit eros pellentesque sagittis. + Quisque sed odio elit. Vivamus semper, ipsum eget congue ornare, neque + nibh suscipit mauris, in luctus ligula urna nec ligula. Interdum et + malesuada fames ac ante ipsum primis in faucibus. Vivamus in ligula sit + amet ligula gravida accumsan. Suspendisse potenti. Suspendisse vulputate + auctor ligula nec scelerisque. Praesent tempus diam nec porta malesuada. + Cras pellentesque euismod sapien, ut luctus risus egestas id. Nam sed + neque vehicula, tempor lacus non, maximus felis. Curabitur lobortis + efficitur massa, sed volutpat elit vulputate eget. Nullam posuere risus + vel purus bibendum placerat at nec libero. +

+

+ Pellentesque eget laoreet nulla, in dictum ex. Maecenas odio nulla, + laoreet sed dapibus eget, fermentum ut ipsum. Nam nec gravida massa, non + scelerisque augue. Donec vulputate nibh at sem convallis, quis imperdiet + arcu vestibulum. Duis eget nibh sapien. Praesent nulla arcu, mattis et + velit sit amet, viverra facilisis leo. Integer gravida nisi urna, in + fermentum purus sagittis a. Integer a convallis dui. Nunc gravida erat + nec nunc porttitor, eu pharetra nibh varius. Vestibulum ante ipsum + primis in faucibus orci luctus et ultrices posuere cubilia curae; Cras + quis lobortis sapien, et accumsan mi. Sed in interdum libero. Vivamus + congue, est mollis elementum porta, lectus nulla maximus urna, sed + cursus ex est sit amet lorem. Morbi et porta urna, sit amet varius + magna. Maecenas tincidunt lorem nec dolor venenatis elementum. +

+

+ Vivamus dapibus mi urna. Aliquam rutrum accumsan nisi, vitae convallis + risus rhoncus a. Phasellus ultrices rutrum leo. Phasellus eget diam et + turpis porttitor tincidunt eget et massa. Aliquam quis pellentesque + orci, eu auctor urna. Maecenas hendrerit nisi vestibulum ligula blandit, + id vestibulum erat facilisis. Phasellus ac pulvinar nibh. Fusce + suscipit, lectus vel viverra blandit, risus erat congue urna, in cursus + tortor lorem nec eros. Mauris dapibus, justo ac gravida mattis, nunc + massa euismod elit, vel eleifend ipsum nisi vitae massa. Cras id + volutpat magna, in semper quam. +

+

+ Ut id vehicula turpis. Nullam ac iaculis sem, pulvinar elementum odio. + Aliquam venenatis feugiat risus ut lacinia. Pellentesque habitant morbi + tristique senectus et netus et malesuada fames ac turpis egestas. Cras + quis blandit tellus. Ut vitae imperdiet dolor. Duis rutrum a tortor in + porta. Nulla sed euismod leo. Etiam urna nisi, eleifend tristique velit + sit amet, bibendum eleifend turpis. Pellentesque tellus purus, faucibus + quis pellentesque ac, finibus sed mi. Aenean eget lobortis neque. +

+

+ Sed fermentum pulvinar dolor, a euismod felis pulvinar sed. Aliquam et + vestibulum eros. Pellentesque mattis efficitur erat. Quisque scelerisque + sem venenatis eros bibendum porta. Fusce a elit et ante rutrum gravida. + Sed ex orci, venenatis non elementum id, faucibus et diam. Nullam + posuere viverra tempus. Duis faucibus metus urna, sit amet bibendum + lorem fermentum ut. Quisque laoreet ultrices purus. +

+

+ Praesent placerat laoreet augue, eu mollis mi vulputate in. Sed commodo + est at sapien laoreet pulvinar. Interdum et malesuada fames ac ante + ipsum primis in faucibus. Sed libero velit, porttitor vitae lectus sit + amet, accumsan rhoncus mi. Donec tincidunt purus odio. Aliquam ac + molestie nisi, sed hendrerit sem. Nulla facilisi. Sed tempor odio eu + nisl facilisis, vel porttitor augue auctor. Fusce in ex euismod, + dignissim diam quis, lacinia purus. Interdum et malesuada fames ac ante + ipsum primis in faucibus. Integer non nibh odio. Ut ut ligula felis. + Curabitur tempor lacus a risus condimentum, eu accumsan turpis sagittis. + Nulla facilisi. Quisque at congue nunc, at suscipit neque. +

+

+ Integer feugiat ligula quis nunc ultrices, eget sodales metus elementum. + Proin ex justo, mollis a pulvinar ullamcorper, fermentum sit amet + tellus. Fusce id euismod nisi. Cras mattis placerat purus nec venenatis. + Aenean sed dui faucibus, egestas ipsum at, tempus purus. Proin facilisis + tellus quis odio ultrices, a tincidunt elit congue. Nam tempus sapien + vel quam sodales tempus. Ut blandit pellentesque lorem vel imperdiet. + Cras nisi turpis, volutpat a mauris nec, faucibus ultrices tortor. + Praesent a ornare augue. Ut eget neque sed felis imperdiet vestibulum et + ut metus. Maecenas vel dolor ante. Vivamus posuere risus interdum lacus + pulvinar, eget tincidunt velit tempus. Sed viverra erat tellus, nec + iaculis dolor tincidunt et. Sed rhoncus mauris nibh, non lacinia lorem + vehicula nec. +

+

+ Maecenas ultrices malesuada urna quis maximus. Proin vel dictum ipsum. + Duis lacinia turpis vel molestie pharetra. Nullam iaculis porta rhoncus. + Maecenas ullamcorper massa non velit sagittis suscipit. Quisque lobortis + blandit diam, vehicula cursus quam faucibus in. Duis eget mauris vitae + augue convallis interdum. Ut ac iaculis ex, quis maximus justo. Ut sed + fermentum tellus. Pellentesque facilisis turpis nisi, id molestie tortor + aliquam dignissim. Aenean luctus quam at arcu viverra venenatis. Proin + quis pellentesque nisi. Donec iaculis nunc id ornare pharetra. Donec id + ligula mollis, hendrerit ipsum in, vulputate justo. Praesent in + condimentum sem. Pellentesque malesuada velit ullamcorper dui pharetra + placerat. +

+

+ In lacus nibh, finibus sed nulla ut, dictum feugiat magna. Aliquam + semper turpis non placerat scelerisque. Maecenas lobortis, est vitae + aliquam maximus, metus tortor porta dolor, vitae ullamcorper elit enim + vel tellus. Vestibulum volutpat posuere luctus. Nullam eros leo, aliquam + et ullamcorper sed, viverra in erat. Nam mauris metus, imperdiet non + convallis et, viverra et tortor. Nulla quis pretium tellus. In + scelerisque finibus mi convallis euismod. Pellentesque ante tellus, + vestibulum non egestas in, volutpat eu arcu. Donec malesuada risus nisi, + eget consequat massa rhoncus ut. Maecenas eget magna a metus consectetur + interdum. Sed lorem est, eleifend sed mattis in, feugiat ac magna. + Pellentesque iaculis nunc sed metus laoreet, ac feugiat est maximus. + Aenean velit magna, dapibus ut scelerisque ac, sollicitudin sed justo. + Phasellus venenatis metus sit amet dapibus imperdiet. +

+

+ Nullam nec volutpat purus. Duis elementum ex risus, id consectetur + lectus commodo molestie. Duis tristique nisl non convallis tristique. + Nam eget lectus tempor, porta orci ut, fermentum nibh. Morbi egestas + semper tempor. Nunc est lacus, aliquet id pellentesque vel, tincidunt id + eros. Suspendisse vitae nibh vitae ligula faucibus tristique eu eu + lorem. Donec nec turpis consequat, laoreet sapien ut, condimentum orci. + Mauris imperdiet feugiat consectetur. Nam vel ultrices arcu. Donec quis + pharetra augue, in egestas quam. Ut vitae ligula bibendum, suscipit + risus non, malesuada tellus. Praesent quis dui nec odio rutrum tempor + vitae nec augue. +

+

+ Nam tristique erat vitae congue venenatis. Suspendisse sed mattis nisi. + Aliquam erat volutpat. Quisque vitae odio eu sapien hendrerit pretium. + Etiam sollicitudin orci purus, a bibendum erat tincidunt at. Nunc + ultricies ac arcu eget consectetur. Cras augue libero, hendrerit et + placerat in, imperdiet sed lectus. Pellentesque varius enim laoreet est + finibus, vitae vulputate leo venenatis. Nam tincidunt metus eget neque + tristique pretium. +

+

+ Ut ultrices dapibus ornare. Aliquam et est eu nisl mattis fermentum. + Aliquam luctus est sed lobortis aliquam. Donec vel pretium purus. Donec + augue augue, euismod viverra orci a, lacinia maximus risus. Nam sagittis + nibh eget urna feugiat, et venenatis erat facilisis. Donec fermentum non + nisi ut pretium. Aenean sodales fermentum lacus, vitae fermentum elit + efficitur hendrerit. Proin dictum pretium lacus, vestibulum efficitur + orci hendrerit ac. Maecenas non elementum diam, vel venenatis eros. + Donec finibus luctus arcu, porttitor condimentum tortor tincidunt vel. +

+

+ Interdum et malesuada fames ac ante ipsum primis in faucibus. Phasellus + viverra massa diam, in dignissim nunc dapibus eu. Phasellus tincidunt + fermentum libero vitae eleifend. Nullam vel pellentesque libero, et + sagittis turpis. Quisque euismod quis diam quis ornare. Cras id quam + elementum, suscipit augue id, sodales eros. Vivamus egestas, quam vitae + sagittis pellentesque, justo purus aliquam purus, vel bibendum turpis + nisi quis lectus. Ut ac libero vitae mauris placerat luctus et eget + velit. Nullam semper eros elementum, efficitur lacus eget, consequat + magna. Ut eu tincidunt urna, vel congue sapien. Vestibulum ante ipsum + primis in faucibus orci luctus et ultrices posuere cubilia curae; Donec + odio velit, rutrum sit amet porta et, imperdiet a augue. +

+

+ Nunc nec odio nec ipsum convallis mattis. Nulla ut aliquet quam. Morbi + enim tortor, dignissim sit amet volutpat non, consequat in neque. + Maecenas vitae enim blandit, dictum lorem eget, placerat turpis. + Suspendisse potenti. Integer dapibus efficitur nunc non dignissim. Proin + rhoncus laoreet imperdiet. Aenean nec iaculis est. Praesent placerat + nibh ac augue blandit pulvinar. Suspendisse vitae ipsum eget sapien + aliquet fermentum in a urna. +

+

+ Quisque porta odio eu blandit vehicula. Maecenas sapien libero, sodales + quis quam ut, pharetra finibus libero. Etiam vel neque ipsum. Aliquam + quis dui mi. Vestibulum vitae massa nulla. Ut est nibh, elementum vitae + nisi fermentum, viverra consectetur risus. Phasellus cursus egestas + felis quis interdum. Nam non ipsum et mauris dignissim vehicula nec nec + est. Duis quis venenatis mi. Pellentesque blandit ullamcorper felis, + commodo ultricies ligula faucibus vel. Maecenas scelerisque neque a erat + consequat vehicula. Ut finibus tempus facilisis. In sodales lacus at + magna tincidunt, in maximus neque convallis. In at lorem eu purus + volutpat aliquam at vitae enim. Sed sit amet mauris vitae tortor finibus + scelerisque ut et eros. +

+

+ Integer in fermentum massa, a maximus purus. Donec rhoncus, lectus sit + amet consequat vestibulum, neque ante cursus urna, eleifend varius felis + ante sed enim. In dui mi, euismod ac mollis id, porttitor vel leo. + Pellentesque habitant morbi tristique senectus et netus et malesuada + fames ac turpis egestas. Nunc nisl sapien, convallis bibendum vehicula + non, convallis ut sem. Nullam non molestie massa. Phasellus eu volutpat + mi. Pellentesque porta ex sed turpis commodo, sit amet aliquet ex + sagittis. Vestibulum molestie ante a magna eleifend imperdiet. In + hendrerit nibh sed eleifend facilisis. Mauris malesuada cursus tortor + non fringilla. Sed a nibh sed sem accumsan finibus. Vivamus egestas + mauris porta, ultricies felis at, sodales arcu. Ut eu lacinia eros. + Aliquam consequat laoreet ante, in interdum eros lacinia ac. Nunc luctus + nisl eget nulla vehicula, a fermentum diam porta. +

+

+ Proin vel tellus placerat, lacinia arcu pretium, gravida ligula. + Vestibulum pharetra diam non ultrices finibus. Quisque facilisis + imperdiet lorem, ullamcorper molestie odio laoreet in. Praesent tellus + quam, laoreet et orci quis, consequat ullamcorper magna. Nam lobortis id + ligula ut sodales. Quisque venenatis, lacus non accumsan fermentum, + magna mauris dignissim mi, vel finibus nulla leo id nibh. Integer + condimentum nulla et diam scelerisque mollis. Interdum et malesuada + fames ac ante ipsum primis in faucibus. +

+

+ Fusce gravida ultrices hendrerit. Mauris aliquet, risus in feugiat + dictum, sem ligula mattis odio, consequat consectetur mi tellus non + nulla. Duis quis rhoncus ex, at vehicula urna. Quisque vitae dolor + tincidunt, egestas mauris id, tristique mauris. Mauris hendrerit iaculis + urna. Mauris molestie dictum massa, non porttitor arcu commodo id. + Praesent enim erat, malesuada dictum orci id, gravida consequat metus. + Duis vel magna ultricies, ultrices mi eu, euismod lectus. Quisque non + mauris ut urna efficitur vestibulum eu eget sem. Integer bibendum + bibendum arcu, at placerat felis luctus faucibus. +

+

+ Quisque porttitor euismod justo, in mattis tortor gravida et. Aliquam + dapibus enim ut purus blandit consectetur. Quisque erat est, pretium + eget mattis in, finibus at urna. Nulla pulvinar euismod magna eu + sollicitudin. Sed varius sapien quis dolor vehicula rhoncus. Etiam eget + arcu vel mi placerat scelerisque. Proin sed viverra est. Nullam sit amet + porta urna. In hac habitasse platea dictumst. Etiam eget ullamcorper + ipsum. Aenean nisi magna, efficitur sed maximus nec, finibus ut massa. +

+

+ Nullam vitae condimentum odio. In tempus velit vel lacus molestie + vestibulum at congue lacus. Vestibulum sed ante elit. Aliquam suscipit + est sed metus mollis, ut gravida dolor scelerisque. Mauris placerat + risus turpis, nec varius neque malesuada non. Fusce ultrices facilisis + tempus. Praesent consectetur aliquam nulla. Quisque a luctus leo. Nam + odio elit, consectetur quis turpis ut, vestibulum laoreet leo. Sed vitae + purus quis metus dignissim viverra. Proin lobortis tempor tincidunt. + Phasellus posuere tristique nisl, et laoreet mauris sodales quis. Donec + finibus leo arcu, a ultrices mi viverra at. Aenean lacinia ex quis + pretium vehicula. In hac habitasse platea dictumst. +

+

+ Morbi gravida sit amet leo aliquam mattis. Aliquam vestibulum, est ac + rutrum sollicitudin, dui dolor mollis turpis, finibus euismod purus est + id purus. Proin eleifend leo consequat augue suscipit accumsan. Sed nec + dolor id sem tincidunt tempor. Morbi neque nisl, malesuada nec placerat + eget, finibus viverra quam. In id leo gravida, lobortis libero quis, + bibendum diam. Aliquam et fermentum augue, et pretium lacus. +

+

+ Phasellus quis massa in mi suscipit auctor eget in ante. Phasellus a + efficitur lectus. Nam porta eros a est aliquet, interdum luctus tortor + accumsan. Nam ac mollis est. Duis vitae sagittis magna. Pellentesque + molestie vehicula tortor. Curabitur in semper sapien. Phasellus vitae + bibendum ligula, in bibendum leo. Phasellus pellentesque mi sed ante + tristique, et condimentum enim fringilla. Nulla facilisi. +

+

+ Phasellus porta risus eu lobortis dapibus. Nulla ut leo sem. Vivamus nec + nisi erat. Proin vel dolor auctor, tristique purus at, congue nisi. In + sit amet fermentum tortor. Nullam volutpat, massa sit amet tempor + sollicitudin, orci risus aliquet elit, et consequat ante nisl vel odio. + Sed auctor mollis justo, vel gravida lacus aliquam vel. Sed elit tellus, + blandit nec dictum a, tempus quis libero. +

+

+ Mauris molestie in elit ac faucibus. Praesent a velit diam. Praesent ut + dapibus arcu, ut molestie quam. Cras eget pretium sem. Sed quis lacus + hendrerit, auctor nisi eget, venenatis dui. Cras id nisl aliquam, + elementum lacus ac, sodales purus. Cras venenatis quam eu leo mattis, + feugiat venenatis turpis rutrum. Vestibulum non leo lectus. Aenean at + leo pellentesque ex efficitur sollicitudin. Sed nec nunc eu elit + hendrerit ultrices. Nullam porta tincidunt vestibulum. Aliquam convallis + nisl eu ipsum posuere, vitae aliquam diam tempor. +

+

+ Cras vitae auctor risus. Morbi aliquam aliquet massa, et varius sem + interdum eu. Praesent purus ligula, rhoncus sed consequat id, rutrum ut + elit. Aenean in est eu velit fermentum consequat. Sed vulputate placerat + augue, vel cursus purus placerat ut. Maecenas mauris velit, tristique + fringilla fermentum eu, hendrerit in dui. Fusce vestibulum ligula non + sem tempus, pellentesque vulputate nibh iaculis. Curabitur eleifend vel + ante non malesuada. Mauris a dolor nec leo sagittis convallis nec non + velit. Maecenas accumsan est at ligula malesuada, eu pulvinar ligula + consequat. Suspendisse potenti. Nullam nec urna id metus efficitur + posuere et in dui. Maecenas varius, eros vitae sollicitudin pulvinar, + sem nisi rhoncus arcu, id feugiat nunc tellus id velit. Vestibulum sit + amet dictum lectus. Praesent eget massa pulvinar, mollis leo at, tempor + erat. +

+

+ Duis ut mi ac ex fringilla molestie. Sed ultricies rutrum purus. Nam + varius placerat varius. Pellentesque libero ligula, gravida at egestas + sed, tempor vel nisi. Suspendisse convallis tortor et mi convallis, + vitae tempus felis dignissim. Nulla facilisi. Sed at augue eget purus + rutrum volutpat. Mauris auctor arcu a arcu placerat pulvinar. Maecenas + in tortor ipsum. Integer quam nulla, congue et velit sodales, ornare + semper mauris. Etiam luctus nisl vitae risus condimentum, vitae sagittis + metus vehicula. Etiam non nulla mi. Vivamus ornare accumsan est, sit + amet condimentum est pretium a. +

+

+ Donec faucibus erat quis libero lobortis dictum. Proin lacus arcu, + laoreet id semper a, dictum eget lacus. Sed consectetur metus turpis, + non sodales massa fringilla sit amet. Donec ultrices rutrum risus, vitae + facilisis est porta non. Integer congue scelerisque enim sed + condimentum. Cras rutrum ex ullamcorper ultrices malesuada. Suspendisse + potenti. Donec pretium eros ipsum, id pharetra tortor posuere non. Proin + accumsan tempus ipsum, eget lobortis tellus. Proin blandit mi ut orci + consectetur, sed elementum nibh tempor. Ut eu tincidunt nunc, sit amet + aliquam turpis. Nulla facilisis felis lectus, a ultricies dolor + efficitur eget. In a pellentesque libero. +

+

+ Aenean cursus orci sed est tincidunt finibus. Duis efficitur nec turpis + ut placerat. Aenean aliquet tortor lorem, eget elementum orci dapibus + eu. Etiam imperdiet congue sollicitudin. Nunc congue, ante quis molestie + porta, lorem nunc gravida felis, id lacinia lorem risus nec metus. Donec + orci magna, tempus id urna sed, feugiat malesuada felis. Aliquam nec + eleifend arcu. Vivamus ac lectus tempor, tempus leo in, lacinia est. Nam + ut viverra lectus. Sed sit amet rhoncus neque. Sed mollis in urna id + volutpat. +

+

+ Fusce vestibulum in odio nec tempor. Praesent nulla lorem, commodo vel + ligula et, accumsan bibendum mauris. Mauris ornare nulla sapien, sit + amet dapibus lacus dignissim in. Donec dapibus dui ac nisl feugiat, et + gravida risus facilisis. Sed gravida, odio non consectetur efficitur, + urna metus venenatis nisl, sit amet vulputate ante mauris in lectus. + Phasellus tincidunt, risus nec interdum dictum, mi tellus malesuada + justo, vel tempus leo enim quis orci. Sed in commodo ligula. Mauris non + interdum elit, id dapibus quam. +

+

+ Proin a velit sit amet nunc congue feugiat sit amet ut lorem. Mauris vel + iaculis nisi. Praesent purus massa, accumsan ac euismod hendrerit, + auctor et arcu. Curabitur tempus ornare velit interdum tempor. Morbi a + turpis vel mauris luctus tincidunt ut id quam. Aliquam tincidunt nec + erat a volutpat. Donec ultricies accumsan tortor, ut pulvinar mauris + consectetur in. Duis condimentum blandit ipsum, sit amet dapibus risus + dignissim et. Vestibulum sodales imperdiet facilisis. Donec gravida + tellus a posuere faucibus. Nunc vitae placerat lorem. +

+

+ Mauris dictum nunc sed turpis commodo, eget elementum nibh lobortis. + Vivamus ut condimentum sem. Etiam dui diam, facilisis vel egestas et, + fringilla eget odio. Pellentesque quis sapien mattis, dignissim nisi + quis, volutpat massa. Vivamus eget pulvinar risus. Aliquam tristique + elit vel viverra facilisis. Vestibulum ac malesuada ex. Lorem ipsum + dolor sit amet, consectetur adipiscing elit. Phasellus condimentum est + nec iaculis dignissim. Aenean congue, odio quis vestibulum malesuada, + justo enim tristique sapien, tempor lobortis erat tortor vitae felis. + Aliquam erat volutpat. Nullam vel mattis mauris, ut dictum lacus. Fusce + tincidunt accumsan magna quis tincidunt. Aenean nec diam convallis, + facilisis ex ut, varius nunc. +

+

+ Nullam facilisis congue semper. Aenean placerat ipsum ut felis semper, + ut sagittis eros congue. Duis non volutpat sapien, eu ullamcorper lorem. + Donec consectetur mauris vitae neque pharetra, eu sollicitudin ex + scelerisque. Donec at urna feugiat leo mollis viverra. Integer imperdiet + tincidunt quam, in congue turpis finibus vel. Phasellus porta maximus + ullamcorper. Etiam ultrices nec diam non tempus. Sed vitae lacus et leo + finibus elementum. Suspendisse potenti. Fusce tincidunt mattis sapien + nec maximus. +

+

+ Aenean ultricies purus sit amet dapibus vehicula. Fusce quis libero + orci. Vestibulum interdum rutrum augue eget ornare. Nullam euismod + tellus a erat ornare, sed feugiat est sodales. Donec iaculis orci nisl. + Nulla ligula nisi, euismod in varius et, consectetur eget lorem. Vivamus + eu magna vel turpis interdum varius non non magna. Pellentesque sit amet + velit eget justo eleifend pharetra. +

+

+ Fusce scelerisque sapien magna, eget mollis orci tincidunt a. Quisque at + dolor iaculis, euismod quam et, facilisis risus. Morbi eget tincidunt + turpis, nec sodales sem. Morbi ut sem eget dui pretium molestie eget ac + neque. Proin scelerisque tellus sed congue tincidunt. Suspendisse + sagittis condimentum elit, at lobortis mauris varius ut. Proin bibendum + ultricies maximus. Suspendisse tempor orci ultrices diam tristique + maximus. +

+

+ Cras et odio id ex eleifend varius ac at metus. Class aptent taciti + sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. + Proin congue quam efficitur sapien vestibulum pretium. Nulla fringilla, + augue ac consectetur maximus, nibh ligula elementum risus, eget + tincidunt dui sapien eu libero. Phasellus quis nulla quis nunc pretium + faucibus. Quisque vel lacinia massa, ac rhoncus nulla. Nullam a erat non + quam ultricies maximus. Donec non dui ac nisl aliquet eleifend. Praesent + elementum nunc eu ultrices viverra. Maecenas congue, tortor ut fringilla + sollicitudin, purus ligula aliquet neque, vel egestas ex lorem sit amet + nisl. Fusce dignissim leo quis ante placerat, eu interdum dolor + tristique. In porttitor vestibulum ante, sit amet imperdiet nulla + facilisis a. Duis posuere auctor orci, ut tristique nulla. Morbi congue + ante dignissim lacus varius, ac volutpat felis fermentum. Morbi ipsum + mi, tincidunt vitae nunc vel, molestie porta ante. +

+

+ Sed sollicitudin mauris a iaculis porta. Nunc sit amet congue lorem, vel + porta est. Nulla a nibh suscipit, cursus mi nec, rhoncus enim. Cras + hendrerit faucibus dui, sit amet viverra sem ultricies sit amet. + Pellentesque non luctus orci, ornare porttitor dolor. Cras id tincidunt + justo. Integer vestibulum, libero ac convallis malesuada, quam quam + feugiat sapien, ac eleifend sapien ante eget leo. Aenean eu nisl nisl. + Pellentesque et congue nunc. Integer odio ante, laoreet eu lectus in, + auctor blandit diam. Maecenas ultrices gravida magna, in mattis leo + aliquam ut. +

+

+ Pellentesque nec felis at felis auctor congue. Integer ut finibus lacus. + Nullam viverra porttitor elit, non rutrum metus auctor sit amet. Lorem + ipsum dolor sit amet, consectetur adipiscing elit. Integer vitae tellus + a nunc sodales placerat. Class aptent taciti sociosqu ad litora torquent + per conubia nostra, per inceptos himenaeos. Maecenas egestas rhoncus + quam, quis eleifend massa condimentum vel. In id nunc a tortor + pellentesque congue sed ac arcu. Cras vestibulum quis leo sed pulvinar. + Nulla nec commodo urna. Aliquam maximus vel ex sed efficitur. Praesent + tincidunt, metus sed facilisis mattis, felis ex mollis leo, sit amet + tincidunt ante tellus sit amet mi. +

+

+ Class aptent taciti sociosqu ad litora torquent per conubia nostra, per + inceptos himenaeos. Aliquam erat volutpat. Duis porta efficitur rhoncus. + Phasellus viverra nunc tellus, in mollis augue tempor non. Nullam at + metus urna. Fusce vitae ligula eu lectus vulputate porta. Nullam + convallis, nulla in placerat ultrices, lorem nunc lobortis diam, ac + sodales quam orci a mi. Ut sodales placerat lectus id aliquet. Morbi + vestibulum, eros et sodales molestie, felis justo aliquet dui, vitae + dignissim tortor sapien vel quam. Nunc in pretium metus. Aliquam erat + justo, vestibulum quis arcu sed, luctus sagittis lacus. Nam consectetur + efficitur volutpat. +

+

+ Etiam odio lorem, tincidunt a convallis eu, vestibulum eu massa. Integer + faucibus sed purus sed malesuada. Sed sollicitudin, nisi at fermentum + accumsan, eros odio luctus nisl, vel placerat ante turpis at metus. + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque + faucibus dui odio, imperdiet aliquam ex ullamcorper ac. Aenean leo ex, + tincidunt sit amet venenatis eget, congue in elit. Vestibulum tempus + iaculis nunc vitae volutpat. Nullam eu maximus risus. Cras ut volutpat + nulla, et pulvinar orci. Nunc et vestibulum mauris. Donec sit amet nunc + hendrerit, malesuada neque non, malesuada neque. Aenean id sagittis + massa. Morbi non lectus ipsum. Donec facilisis fermentum augue non + laoreet. Nunc pulvinar tincidunt lacus laoreet condimentum. Aliquam + rutrum ultricies diam ac maximus. +

+

+ Sed sagittis nisi ut metus imperdiet, sed tempus sem ornare. Duis + vehicula interdum mauris, eu facilisis sapien egestas et. Donec eget + libero neque. Curabitur volutpat dolor sit amet neque ultrices, vitae + viverra ipsum congue. Cras et quam ullamcorper, tempor nisi vel, + convallis lectus. Donec sagittis, felis vitae finibus auctor, neque odio + mollis sapien, quis euismod lacus mi et augue. Vestibulum tincidunt + lorem vel auctor dictum. Nam ultrices nisi at blandit dignissim. +

+

+ Proin cursus, erat a hendrerit dictum, urna nisl laoreet orci, vel + posuere libero arcu vitae purus. Etiam ac nulla sit amet ligula feugiat + aliquam eu et ex. In hac habitasse platea dictumst. Nullam id + condimentum justo, quis vulputate enim. Donec consequat fringilla ipsum + sit amet vulputate. Suspendisse potenti. Etiam iaculis lorem non + facilisis aliquam. Ut at lobortis leo. Aenean fermentum augue vel leo + vehicula condimentum et vitae ex. +

+

+ Etiam auctor arcu placerat, semper turpis non, aliquet lorem. Proin + auctor pharetra augue vitae tempus. Duis semper magna metus. Nam quis + nunc non augue mattis porta nec sed est. Sed at porta tortor. Fusce eget + consequat turpis, et dignissim enim. Ut non mollis erat, nec volutpat + ipsum. Vivamus eget felis ipsum. Nullam aliquet bibendum semper. Proin + id sapien eget libero ultricies iaculis. Praesent dictum mauris et justo + porttitor luctus. Mauris imperdiet est eget feugiat egestas. Aenean + cursus facilisis ipsum, sed convallis eros vulputate ut. Vivamus laoreet + urna vel justo molestie tincidunt. Sed tristique justo quis nunc + tincidunt, viverra aliquet lorem sodales. Nam aliquam venenatis turpis, + quis accumsan lorem gravida nec. +

+

+ Interdum et malesuada fames ac ante ipsum primis in faucibus. Curabitur + eget sapien in ipsum suscipit aliquam. Phasellus dui nulla, egestas quis + orci in, pulvinar hendrerit tellus. Sed faucibus, urna non dignissim + sollicitudin, turpis arcu imperdiet velit, ut tristique lacus lorem + bibendum elit. Donec ullamcorper justo nisl, nec rhoncus purus venenatis + quis. Praesent vestibulum venenatis erat, sit amet iaculis risus + ullamcorper at. Aenean ligula odio, pulvinar vitae metus placerat, porta + finibus enim. Etiam suscipit, odio vel accumsan varius, lorem leo + consectetur magna, id bibendum est dolor varius nibh. Nullam erat ante, + placerat ac ante sed, suscipit gravida nunc. Vivamus euismod fermentum + dolor, eu fermentum est dictum in. +

+

+ Interdum et malesuada fames ac ante ipsum primis in faucibus. Nullam + placerat volutpat iaculis. Morbi ligula felis, congue non hendrerit + vitae, ultricies eu felis. Fusce elementum, lorem id ultricies semper, + purus libero vulputate turpis, vitae pellentesque enim nisi vel urna. + Nunc mi odio, dapibus id velit eu, commodo varius sapien. Donec et nulla + volutpat, semper ipsum ac, molestie enim. Vivamus non quam mattis, + viverra massa nec, maximus lectus. Aliquam eleifend dolor quis fringilla + tincidunt. Donec tincidunt suscipit urna efficitur hendrerit. Cras + lectus metus, vulputate vitae dolor eu, condimentum lobortis nisi. Sed + sodales elementum orci. Suspendisse hendrerit tortor nulla. +

+

+ Proin bibendum vel justo non fringilla. Praesent auctor at tortor et + eleifend. Sed finibus tempor interdum. Sed dui diam, feugiat dictum + faucibus sit amet, dictum ut lacus. Suspendisse consectetur varius + fringilla. In sit amet leo nunc. Maecenas mollis mauris ut arcu rutrum + finibus. Pellentesque magna elit, efficitur at nisl ac, porta + scelerisque nisl. In vitae metus a libero euismod vestibulum. Donec + faucibus augue at dolor volutpat gravida. Vivamus feugiat sagittis leo + id hendrerit. Quisque placerat, augue at eleifend tempor, nibh lorem + sodales orci, quis maximus eros diam in dui. Pellentesque habitant morbi + tristique senectus et netus et malesuada fames ac turpis egestas. Nunc + luctus mauris scelerisque, ullamcorper erat a, volutpat diam. Mauris id + lacinia turpis. Proin in ligula bibendum, molestie leo ut, accumsan + elit. +

+

+ Integer tempus, elit ac tincidunt iaculis, nibh quam rutrum augue, at + maximus quam ligula non odio. Integer commodo ullamcorper tempor. Mauris + vestibulum, nisi eu maximus bibendum, sem est eleifend magna, porttitor + dignissim nulla lorem id ante. Aliquam erat volutpat. Donec vitae + ullamcorper quam, lobortis porttitor eros. Quisque vitae tempor eros. + Sed faucibus a arcu suscipit suscipit. Etiam eros justo, aliquet at + velit id, tempor rutrum elit. Quisque et purus sit amet felis lacinia + condimentum. Suspendisse potenti. Nunc ex mi, commodo blandit tempus in, + tempor vel lacus. Cras urna enim, tempor eget lacus sit amet, accumsan + maximus ligula. Donec quis lorem quam. Etiam at est ut justo rutrum + bibendum. Vivamus lectus felis, mollis a enim a, tincidunt vehicula + purus. +

+

+ Phasellus vehicula congue sapien, in volutpat felis posuere id. Aliquam + non urna eu purus placerat sollicitudin id a elit. Morbi pharetra est + non augue porttitor, sed volutpat ipsum fermentum. Fusce sed velit + risus. Sed id dolor ac dolor rhoncus lobortis eu ut leo. In dapibus est + lobortis, dictum nulla in, suscipit risus. Aliquam tincidunt, dolor sit + amet laoreet egestas, eros mi pulvinar nisi, sed varius elit arcu et + massa. Orci varius natoque penatibus et magnis dis parturient montes, + nascetur ridiculus mus. Mauris finibus neque nec gravida aliquet. Etiam + nec neque sem. Donec eget eros ex. Nam porta eget libero vitae + porttitor. In hac habitasse platea dictumst. +

+

+ Integer a dictum urna. Etiam nulla leo, molestie eu hendrerit non, + finibus at tellus. Sed hendrerit non mauris in imperdiet. Donec eleifend + elementum felis eget posuere. Proin in massa rutrum dui tempor bibendum. + Vivamus eget nisi porta tellus tempor volutpat nec non purus. Aenean eu + nisi dolor. Morbi in sodales lectus, at lacinia lacus. +

+

+ Morbi ligula lacus, auctor eu aliquet et, ultricies sagittis odio. + Phasellus in diam a metus congue dapibus ut ac mi. In hac habitasse + platea dictumst. Pellentesque et commodo magna, ut molestie nibh. Donec + ac justo ut nisl pharetra ultrices non vitae diam. Cras convallis erat + nulla, ac consequat justo condimentum vitae. Etiam vitae magna vitae + risus molestie luctus vitae at ipsum. Duis in nisl interdum risus + facilisis pretium. Donec tempus elementum faucibus. Etiam eu molestie + elit, ac egestas sem. Sed consequat diam vel venenatis pharetra. + Vestibulum efficitur eget sapien in ultricies. +

+

+ Nunc mauris magna, scelerisque vel aliquam ultrices, tincidunt vel nisl. + Duis luctus quis nisl quis vehicula. Nullam non tristique felis. + Curabitur semper ipsum non lacus dictum ullamcorper. Proin sed sodales + elit. Suspendisse volutpat vehicula elit, nec mattis tortor sagittis ut. + Praesent eu sem enim. Fusce sit amet odio in velit sagittis fringilla. + Nulla facilisi. Pellentesque non massa sit amet ligula vehicula + vestibulum ac et lorem. Ut elementum orci orci, ut facilisis massa + cursus in. +

+

+ Praesent ultrices urna eu ultrices ultricies. Phasellus sapien purus, + accumsan quis dui a, tempor ornare augue. Pellentesque tempor dolor et + placerat dapibus. Pellentesque fermentum dictum tellus vitae elementum. + Morbi in erat pharetra, posuere odio et, semper nisl. Integer quis + consectetur massa. Sed ac mi elit. Fusce aliquam enim nulla, in + consequat urna dignissim sit amet. Duis porttitor placerat elit vel + ornare. Praesent malesuada dictum mollis. Suspendisse vitae sem quis + felis posuere finibus. Donec a porta metus. Class aptent taciti sociosqu + ad litora torquent per conubia nostra, per inceptos himenaeos. Vivamus + mattis tempor sapien, non scelerisque turpis auctor venenatis. Aenean + sed metus vitae orci facilisis luctus. Pellentesque vestibulum varius + gravida. +

+

+ Nulla id elit sit amet ligula aliquam tristique. Vestibulum eleifend + suscipit velit a rutrum. Suspendisse ultrices iaculis libero ut + ullamcorper. Vivamus interdum dignissim mi, vitae tempus lectus + tristique non. Fusce consectetur feugiat fermentum. Donec sagittis non + est vel porttitor. Pellentesque iaculis massa vitae quam lobortis + vehicula accumsan in elit. Aliquam erat volutpat. Nam sit amet metus + odio. Nulla condimentum justo eget purus interdum faucibus. Quisque + facilisis nisl blandit, gravida nisl in, ornare neque. +

+

+ Orci varius natoque penatibus et magnis dis parturient montes, nascetur + ridiculus mus. Donec sed nunc vel lacus ornare dictum. Donec lacinia + iaculis sollicitudin. Nunc tempor eleifend ligula in dignissim. + Suspendisse id accumsan tellus. Praesent vulputate elit est, sed + sagittis neque suscipit ut. Etiam in tincidunt ipsum. +

+

+ Praesent tincidunt lectus eu nisl eleifend varius. Sed rutrum imperdiet + lorem, a volutpat augue posuere elementum. Praesent luctus aliquam + ligula id mollis. Curabitur lorem nisl, vulputate sit amet velit + dapibus, dictum aliquet nisl. Donec vitae ornare magna, ut facilisis + ipsum. Vestibulum volutpat ligula et ipsum hendrerit vehicula. Donec + scelerisque accumsan turpis sit amet porta. +

+

+ Curabitur aliquet varius felis, sit amet condimentum urna commodo vitae. + Pellentesque eget nisl tincidunt, dictum quam ut, feugiat est. In + vulputate metus at nunc faucibus aliquam. Aenean vulputate, nunc at + pharetra iaculis, dui lacus porta diam, id consectetur magna magna ac + massa. Class aptent taciti sociosqu ad litora torquent per conubia + nostra, per inceptos himenaeos. Ut dapibus sollicitudin neque, tempor + luctus dui lacinia ac. Fusce quis ex id ligula varius feugiat eget et + enim. Pellentesque bibendum elit massa, vel tempor neque gravida quis. + Nulla facilisi. Etiam ut mauris sit amet ipsum imperdiet venenatis. Ut + porta vestibulum dolor eu suscipit. Vivamus mollis interdum ipsum sed + posuere. +

+

+ Aliquam tristique mi eget lacinia maximus. Ut auctor leo sit amet risus + sodales, quis tempor justo accumsan. Sed eu tincidunt risus. Suspendisse + orci metus, rutrum sit amet risus non, lobortis facilisis augue. Nunc + dolor turpis, posuere ut condimentum nec, euismod sed eros. Donec mattis + dignissim mi in pulvinar. Curabitur ut metus magna. Nulla facilisi. +

+

+ Proin vel porttitor ipsum. Fusce in lectus in ipsum bibendum mollis. + Donec pellentesque iaculis tincidunt. Etiam sit amet mi porttitor, + condimentum nibh non, dictum purus. Nulla dapibus suscipit maximus. Cras + eu dignissim libero. Pellentesque habitant morbi tristique senectus et + netus et malesuada fames ac turpis egestas. Praesent tempor placerat + tincidunt. Vestibulum nec sapien blandit, mollis neque rhoncus, + sollicitudin sapien. Donec et consequat enim. +

+

+ Pellentesque fringilla egestas sapien eget egestas. Curabitur malesuada + elit quis nulla pretium, aliquam semper orci pharetra. In pellentesque, + metus quis tempus aliquet, ligula lorem scelerisque ligula, ut maximus + risus orci hendrerit lectus. Fusce in quam non turpis ultricies pulvinar + sed id nunc. Nullam blandit varius risus eget ultricies. Cras ut dolor + et elit eleifend ornare. In hac habitasse platea dictumst. Lorem ipsum + dolor sit amet, consectetur adipiscing elit. Suspendisse sollicitudin + vitae nibh eget pellentesque. Nam luctus congue massa, sed semper mauris + tincidunt non. Nulla facilisi. Suspendisse quis rutrum leo. Donec + aliquam sem nibh, quis egestas augue egestas vitae. Duis consequat + sapien eget sem venenatis ornare. Curabitur tincidunt lobortis orci, nec + viverra justo pulvinar tincidunt. Maecenas iaculis bibendum est, nec + dapibus massa tempor quis. +

+

+ Aliquam in nulla eget erat euismod posuere. Proin consectetur, lorem eu + fringilla posuere, ante quam imperdiet ligula, quis suscipit neque risus + ac est. Fusce congue nibh viverra nibh aliquet, sit amet ullamcorper + lectus lacinia. Fusce quis auctor diam. Orci varius natoque penatibus et + magnis dis parturient montes, nascetur ridiculus mus. Etiam tristique + elit ac arcu interdum ullamcorper. Pellentesque lobortis sollicitudin + metus sit amet faucibus. Sed vehicula elementum justo vel egestas. + Suspendisse varius laoreet lacinia. Nullam eget venenatis lacus. Aliquam + in orci consequat, rhoncus ligula in, faucibus lorem. Maecenas feugiat + luctus tristique. Nunc turpis felis, pellentesque sed molestie ac, + cursus eu arcu. In vitae metus hendrerit, interdum tortor eget, + scelerisque sem. Proin quis tortor libero. Sed euismod cursus tortor, + nec pellentesque magna. +

+

+ In a ex accumsan, semper nisl vitae, porttitor turpis. Morbi sed blandit + tortor, vitae venenatis ex. Mauris eu fermentum nunc, vitae rutrum + neque. Donec eu diam vulputate, venenatis sem dictum, placerat magna. + Cras ante enim, imperdiet eu lacinia ut, tempor eget lectus. Praesent + molestie turpis massa, sed commodo mauris dignissim at. Etiam ultrices + ex a purus mollis varius. Ut ac erat diam. Maecenas laoreet massa purus. +

+

+ Suspendisse luctus leo egestas est vulputate consectetur. Sed porttitor + nisi id orci lobortis consectetur. Praesent id neque ac eros tincidunt + mollis ac eget mi. Aliquam fringilla lorem ligula, quis maximus tortor + mattis vitae. Pellentesque faucibus neque vel commodo blandit. Integer a + dictum mi, id auctor metus. Vestibulum efficitur ornare felis eu + lobortis. Quisque ac viverra eros. Ut mattis accumsan justo. +

+

+ Curabitur convallis tellus neque, a ornare dui pulvinar ut. Nulla + sagittis sit amet tellus quis dignissim. Aliquam convallis commodo + tellus vitae ultricies. Pellentesque habitant morbi tristique senectus + et netus et malesuada fames ac turpis egestas. Proin nunc augue, maximus + at eros in, iaculis lobortis turpis. Aliquam ut sapien sit amet ante + condimentum sollicitudin. Quisque rhoncus sollicitudin imperdiet. + Integer luctus laoreet maximus. Donec pulvinar porta metus, sit amet + tristique erat tempor at. In convallis mi quis justo pretium varius sit + amet nec diam. Suspendisse potenti. Morbi pulvinar tristique elit id + semper. Donec pulvinar cursus volutpat. +

+

+ Nulla consequat felis felis, sed vehicula turpis rhoncus a. Suspendisse + potenti. Sed tortor ante, aliquet in eros in, tempor finibus diam. + Aliquam neque lorem, commodo pretium vestibulum id, tincidunt vel ipsum. + Nunc feugiat augue a magna tempor, vitae suscipit est elementum. Proin + imperdiet dui ante, ut auctor nulla consequat sed. Aenean bibendum massa + a lectus egestas, nec posuere nisi tempor. Praesent et rhoncus magna. + Maecenas nec diam vitae risus malesuada sodales nec id risus. Mauris + pulvinar mi at nulla feugiat, nec faucibus ex efficitur. Aenean a risus + vel diam commodo congue nec et purus. Curabitur lobortis hendrerit nibh + sed feugiat. Praesent sollicitudin porttitor mauris, consequat consequat + odio vulputate eget. Quisque convallis velit quam, ut ornare sem + faucibus et. In posuere ullamcorper hendrerit. Nam vel sapien risus. +

+

+ Mauris venenatis nunc sit amet diam faucibus accumsan. Maecenas sed + augue nec dolor eleifend placerat vulputate eu metus. Aliquam eu purus + quis orci dapibus aliquam id ut elit. Quisque ornare, dui blandit + ullamcorper posuere, magna urna dictum est, sit amet faucibus magna mi + eu neque. Cras sodales aliquet sem, ac vulputate eros facilisis + interdum. Duis ut gravida neque. Sed facilisis lectus et lorem finibus + imperdiet. Vestibulum quis libero et nunc tristique suscipit. Ut at + purus tortor. +

+

+ Sed dolor est, mattis eget molestie in, convallis a odio. Nulla quis + consectetur metus. Nulla et lacus blandit, rutrum eros sit amet, + condimentum lectus. Suspendisse feugiat felis dignissim eros accumsan + feugiat. Etiam lobortis orci massa, vel rutrum urna feugiat vel. Donec + mollis nisl eget ex laoreet aliquet. Donec neque arcu, finibus et nisl + sed, ultricies facilisis nibh. Sed condimentum tortor est, ut dignissim + nulla bibendum et. Donec sagittis posuere est dictum tempor. +

+

+ Vestibulum pretium justo metus, eget lobortis augue consectetur at. + Quisque sodales magna quis consectetur eleifend. Duis eu dapibus erat. + Donec eros nibh, facilisis eu neque at, egestas commodo purus. + Pellentesque id urna erat. Aenean lacinia diam eu leo convallis, et + volutpat justo dignissim. Etiam id dolor elementum, porta dui at, porta + arcu. Proin elementum ac ex sit amet viverra. Aenean nec sagittis magna. +

+

+ Aliquam suscipit est sed ipsum finibus laoreet. Proin porta lacus in + neque sollicitudin, non posuere lacus luctus. Cras ultricies imperdiet + tempor. Nulla sit amet magna facilisis, semper nunc a, placerat nunc. + Cras commodo, sapien vitae bibendum ornare, odio mi iaculis leo, eu + volutpat risus libero id turpis. Morbi sollicitudin, augue nec dictum + dignissim, nulla tortor tincidunt eros, nec finibus metus leo ac nisi. + Mauris rhoncus, urna sed lacinia posuere, ante magna suscipit arcu, + vitae vestibulum lacus odio vel ligula. Integer aliquam euismod + ullamcorper. Vestibulum ante ipsum primis in faucibus orci luctus et + ultrices posuere cubilia curae; Integer non lectus massa. In ac odio + condimentum urna aliquet aliquam sed nec ligula. Sed ut dolor varius + felis eleifend tincidunt quis sed sapien. +

+

+ Vestibulum ornare tellus orci, a pretium libero congue et. Praesent in + egestas diam, quis fermentum nisl. Vivamus eu scelerisque metus, et + sagittis justo. Aenean pulvinar justo felis, at cursus ante gravida ut. + Mauris tristique mi placerat rutrum elementum. Vestibulum porta sagittis + ligula, ut tristique urna egestas eget. Aliquam et sagittis turpis. + Vestibulum accumsan nunc in nibh iaculis, eget pretium justo elementum. + Donec varius ex sed quam pellentesque, eu auctor dolor pulvinar. +

+

+ Nulla et purus lacus. Sed fringilla finibus sodales. Etiam venenatis dui + vitae felis condimentum, vitae venenatis orci vulputate. Phasellus + rhoncus arcu id vehicula pretium. Sed sit amet dolor arcu. Fusce nec + commodo risus. Orci varius natoque penatibus et magnis dis parturient + montes, nascetur ridiculus mus. +

+

+ Nam sit amet dapibus est. Mauris imperdiet ex ac elit mattis tempus. Nam + placerat felis eu mauris commodo euismod. In hac habitasse platea + dictumst. Quisque auctor nec arcu quis varius. Integer iaculis est sed + egestas elementum. Aenean gravida auctor erat sed efficitur. Donec + sapien urna, condimentum at libero eu, viverra porta metus. Proin + sodales erat lorem, eget hendrerit massa dictum vitae. Quisque sit amet + fringilla ex. Vivamus lobortis tempor nulla, id feugiat neque aliquet + et. Cras et placerat turpis, sed hendrerit justo. Ut in placerat risus. + Praesent id nibh eu velit consequat efficitur eget nec magna. +

+

+ Praesent nec consequat nisi. Integer ac nulla eget nunc condimentum + lobortis ac non lacus. In eu porta magna. Etiam dapibus ultrices turpis, + vel placerat tellus lacinia non. Pellentesque aliquam libero in massa + sodales, nec tincidunt ligula pretium. Nulla blandit neque turpis, nec + accumsan nibh pulvinar blandit. Cras facilisis gravida placerat. + Curabitur pellentesque velit quis lorem imperdiet vulputate viverra in + metus. Proin et tellus dictum dui lacinia varius ac ut metus. Nullam + dignissim eros erat, id dignissim ante sagittis sit amet. Sed lobortis, + quam volutpat rutrum consequat, velit nunc lobortis eros, at ultricies + ex nibh sit amet ligula. Phasellus tempor mi at dolor consequat, eget + sodales mauris consequat. Orci varius natoque penatibus et magnis dis + parturient montes, nascetur ridiculus mus. Aliquam convallis ex vel + lectus bibendum, in gravida lectus dictum. Orci varius natoque penatibus + et magnis dis parturient montes, nascetur ridiculus mus. Curabitur + volutpat lectus quis magna interdum ornare. +

+

+ Pellentesque rutrum maximus purus vitae commodo. Vivamus imperdiet vitae + mi sit amet cursus. Nullam bibendum consequat felis at tincidunt. + Quisque pellentesque diam leo, eget vestibulum risus gravida quis. + Phasellus ipsum sapien, scelerisque eget nisi eu, sodales fringilla est. + Nam purus lacus, euismod eget sem et, accumsan auctor lectus. Sed + porttitor ex non nunc commodo, et posuere erat hendrerit. Praesent eu + dolor id dolor ullamcorper cursus at eu risus. Nam tincidunt, ipsum in + tempus tristique, neque quam tempus mauris, quis fringilla quam purus + vitae elit. Maecenas finibus efficitur consequat. Curabitur et suscipit + nibh. Cras eleifend ultricies molestie. +

+

+ Fusce eu hendrerit nisl. Etiam at arcu in nisl aliquam ultricies sit + amet ut orci. Class aptent taciti sociosqu ad litora torquent per + conubia nostra, per inceptos himenaeos. Quisque volutpat ex quis ante + lobortis dignissim. Fusce pulvinar sodales aliquam. Mauris felis augue, + vulputate non nunc vitae, mollis volutpat odio. Suspendisse lobortis + ligula nec dolor hendrerit aliquet. +

+

+ Suspendisse gravida, diam vitae rutrum varius, mauris erat lacinia mi, + non fringilla nisi lorem eget lectus. Suspendisse iaculis condimentum + eros, quis sodales turpis maximus ut. Sed congue posuere mi at congue. + Phasellus eget lacus vitae urna molestie aliquet sed sed felis. Donec + fermentum urna at dolor condimentum consectetur. Aenean sed pretium + tortor. Suspendisse sed lectus risus. Sed sapien erat, tincidunt + scelerisque urna vitae, congue condimentum est. Mauris eget urna id + purus vestibulum lacinia ut non augue. Nunc id elementum nisi, interdum + sollicitudin neque. Pellentesque massa risus, varius nec leo nec, mollis + cursus nisl. Mauris aliquet hendrerit risus. Vestibulum congue interdum + massa, ac ultrices nibh mollis id. Phasellus justo lorem, malesuada sit + amet accumsan vel, mollis ut urna. +

+

+ Curabitur nec tortor sodales, maximus diam in, efficitur quam. Ut rutrum + mi id libero tristique luctus. Phasellus et neque sollicitudin purus + interdum dapibus eget at ex. Duis non mi at massa molestie tempor a sed + tortor. In placerat metus nec condimentum fermentum. Maecenas varius + velit in velit tempus dignissim fermentum id justo. Pellentesque + dignissim tempus porttitor. Fusce scelerisque bibendum sagittis. Donec + tristique tellus ut placerat auctor. Nunc porta tempus risus, at maximus + quam lobortis id. +

+

+ Vivamus volutpat tortor sed justo lobortis porttitor. Etiam a aliquam + lorem. Nullam rutrum accumsan augue, eget sagittis tellus posuere nec. + Aliquam dignissim urna at tellus blandit fermentum. Nunc fermentum justo + ut odio pharetra fringilla. Nunc aliquet eleifend magna nec mattis. + Pellentesque ac tristique dui. Suspendisse nec nunc et lorem tincidunt + congue egestas nec tortor. Suspendisse tincidunt eros felis, nec + ultricies turpis varius ut. Morbi leo sapien, eleifend vitae aliquet at, + suscipit ut arcu. Nulla pretium placerat nunc, quis tempus lorem semper + sit amet. Vestibulum tempus, libero ut ultricies egestas, nisi ex mollis + diam, vel porta nisl augue vitae nulla. Nullam ante ipsum, convallis + finibus sem id, hendrerit ultrices velit. Praesent tincidunt, urna ac + viverra facilisis, nisi massa eleifend sapien, ac congue leo ex vitae + lorem. Cras at pulvinar elit, non vestibulum urna. +

+

+ Quisque consectetur posuere erat, eget finibus turpis semper in. Ut + commodo leo turpis, a elementum tortor lacinia id. Nunc tempor ligula eu + nunc semper porta. Maecenas luctus turpis in justo faucibus iaculis. + Integer rutrum, nunc ac tincidunt pellentesque, velit ipsum gravida + urna, a pretium nunc eros eget dui. Phasellus maximus consectetur elit, + in fermentum odio interdum id. In feugiat tincidunt semper. Phasellus + porta ultricies orci a gravida. Etiam lobortis velit sapien, vitae + consectetur felis laoreet at. Morbi ac metus velit. Aliquam mollis neque + at purus tempus lobortis. +

+

+ Ut ornare justo nec euismod iaculis. Orci varius natoque penatibus et + magnis dis parturient montes, nascetur ridiculus mus. In sit amet + tristique sem. Donec ut tincidunt eros, nec sagittis risus. Morbi at + tellus leo. Cras eu feugiat velit. Praesent a fermentum urna, eget + dapibus felis. Nullam tempor dictum neque semper faucibus. Vestibulum et + sem accumsan, dignissim metus quis, pretium massa. Proin vestibulum + convallis ante, at tempor metus rhoncus vitae. Nunc bibendum nisi ac + magna viverra condimentum. Sed vehicula neque ex, ut auctor leo mollis + eu. Etiam dapibus pellentesque diam, eget cursus odio. Proin sit amet + eleifend est. In eget ex vitae tellus mattis dictum. +

+

+ Vestibulum ullamcorper ut felis vitae placerat. Proin suscipit orci + sapien, in tincidunt magna tempor at. Proin ut dui sed sapien mattis + sollicitudin. Aliquam id velit vitae nunc tincidunt sagittis vitae ut + enim. Nulla vulputate placerat mollis. Nullam facilisis nulla iaculis + risus molestie pulvinar. Quisque iaculis, dui eget vulputate auctor, + lacus turpis ultricies diam, vel faucibus sem nulla quis orci. Nulla et + commodo massa. +

+

+ Proin aliquet purus ut eros tincidunt dignissim. Phasellus vel diam quis + elit malesuada dignissim. Pellentesque habitant morbi tristique senectus + et netus et malesuada fames ac turpis egestas. Sed pretium at purus sed + tempus. Curabitur pulvinar euismod augue, sed convallis sem tempus + fringilla. Curabitur a dictum arcu. Vivamus finibus ante nec ante + consequat venenatis. Nulla mi magna, placerat ut laoreet non, lobortis + nec lorem. Curabitur quis pharetra arcu. Sed sit amet diam in diam + tincidunt iaculis eget a leo. Fusce laoreet felis vitae tristique + efficitur. Fusce feugiat risus non mi scelerisque, nec fringilla risus + efficitur. Aenean arcu enim, condimentum a neque scelerisque, dignissim + gravida quam. Praesent viverra euismod sapien, quis tristique diam + dictum id. +

+

+ Fusce convallis vulputate justo in egestas. Proin at dui volutpat, + eleifend lectus at, pretium nulla. Mauris mi ex, rhoncus non sodales + nec, volutpat vel libero. Praesent nisl tellus, egestas non sem a, + malesuada tincidunt magna. Integer condimentum, lacus nec mattis luctus, + urna risus tristique nibh, nec euismod sapien eros a ex. Morbi pharetra, + ex eget dapibus aliquam, ligula leo semper turpis, sit amet ullamcorper + tortor mi sed neque. Proin congue velit urna, a viverra elit consectetur + et. Pellentesque turpis massa, iaculis maximus nibh ac, elementum + aliquet sapien. Aliquam at nulla nec nisi accumsan pharetra ac a velit. +

+

+ Quisque ac vulputate sapien, nec suscipit augue. Integer vehicula + convallis faucibus. Fusce nec felis auctor, scelerisque augue sit amet, + vulputate risus. Nullam suscipit blandit mauris sed ultricies. Sed non + magna non lorem molestie vestibulum. Proin dictum malesuada nisl, nec + efficitur ipsum venenatis et. Nulla non sapien et tortor ultricies + vulputate et id turpis. Etiam consectetur suscipit quam, in fermentum + augue tincidunt eget. Nullam mattis gravida gravida. Sed posuere quam at + accumsan maximus. Nam commodo elit eu sem dapibus, a ullamcorper tortor + elementum. Vivamus et sapien in nibh bibendum semper vel eget lorem. Sed + nec risus erat. +

+

+ Sed porttitor elementum tempor. Integer egestas scelerisque turpis ut + consectetur. Integer eu nisl nisi. Nunc nec ligula eget neque dapibus + feugiat sit amet quis turpis. Nullam volutpat consequat est, et tempor + neque egestas vel. In sit amet massa sem. Sed nibh libero, elementum ac + maximus a, fringilla vel leo. Praesent at sapien ultrices, interdum elit + eget, scelerisque risus. +

+

+ Morbi dictum urna sit amet augue fringilla pellentesque vitae vitae + dolor. Aliquam dignissim, odio nec blandit tempor, diam nulla blandit + urna, nec sagittis sapien libero id libero. Ut libero sem, ultrices non + viverra non, iaculis sed magna. Aenean at dignissim turpis. Donec nibh + dolor, sodales vitae mollis ut, sodales nec arcu. Sed vitae nunc + ullamcorper augue fermentum tincidunt et et sem. Proin erat dolor, + venenatis non leo eget, cursus facilisis urna. Ut non orci sollicitudin, + blandit neque et, molestie ipsum. Pellentesque finibus, nulla vitae + lobortis luctus, magna est ultrices est, ut aliquam elit nisi sit amet + nisl. Suspendisse id sodales nunc. Maecenas tempus mattis diam ac + feugiat. Donec quis efficitur lorem. Vestibulum lobortis dapibus sem, a + ultricies quam feugiat non. Pellentesque consectetur semper nunc non + iaculis. +

+

+ Nulla ullamcorper eros nec ullamcorper pharetra. Quisque eget mi rutrum + nunc hendrerit porta vel nec ex. Sed lacinia arcu ex, eu faucibus ante + porta quis. Phasellus vitae tincidunt enim. Nunc in purus in justo + luctus dignissim. In pellentesque, lorem id dictum consectetur, dolor + massa sodales tellus, eget efficitur odio nunc vestibulum nunc. Donec + sit amet quam eget erat convallis fringilla. Etiam at pretium sem. + Mauris hendrerit justo mauris, ut ornare felis condimentum eu. + Pellentesque habitant morbi tristique senectus et netus et malesuada + fames ac turpis egestas. +

+

+ Cras ut lectus lacus. In maximus, lectus sit amet ultrices venenatis, + quam urna feugiat velit, vel tempor libero est ut diam. Praesent et + ligula sit amet leo egestas vulputate eget non lorem. Integer a diam ac + justo molestie feugiat vel bibendum diam. Donec aliquam, magna vulputate + auctor volutpat, sem nunc pharetra libero, at condimentum purus tortor a + magna. Maecenas non mollis arcu. Aliquam vulputate neque at lectus + gravida sodales. +

+

+ Sed sit amet maximus lectus. Fusce id lorem quis mi sodales varius a + quis justo. Proin est dui, porta non nisl sodales, feugiat faucibus + nisl. Sed id ex consectetur, faucibus eros sit amet, efficitur quam. Ut + vitae venenatis urna, non convallis magna. Integer dapibus ac sem eget + dictum. Integer ut nisi tincidunt, sollicitudin dui vel, faucibus purus. + Nunc rhoncus turpis eget sem commodo, eu ornare lorem vulputate. + Praesent libero nunc, lacinia sit amet lectus vitae, eleifend hendrerit + diam. In nec lacus mattis, rutrum orci fermentum, vestibulum eros. Nunc + a lobortis purus. +

+

+ Duis nisl diam, pharetra non leo id, facilisis sollicitudin tortor. + Donec efficitur augue lorem, lacinia scelerisque magna eleifend in. + Nulla vestibulum dolor nec fermentum maximus. Maecenas facilisis, nisi + at tempor eleifend, quam tortor ultricies tellus, id convallis enim + dolor nec sapien. Pellentesque sed blandit est. Morbi eu nisi + sollicitudin, elementum libero et, tempor justo. Donec et justo quis + dolor semper tempus et at arcu. Donec in sem id erat maximus feugiat. + Cras ultricies nisi turpis, vitae tincidunt sapien mollis ac. Maecenas + efficitur sed lectus a ullamcorper. Ut lacus tellus, viverra vel + consequat et, suscipit a urna. Proin id ultricies arcu. Etiam non + condimentum enim, sodales laoreet orci. +

+

+ Aliquam bibendum bibendum ornare. Aliquam ultricies diam quis dui + maximus, nec dictum velit convallis. Proin tempor scelerisque libero ac + convallis. Cras sollicitudin dignissim ipsum quis iaculis. Sed aliquam + congue magna, vitae malesuada ipsum dignissim porttitor. Maecenas libero + ante, faucibus nec pretium ut, sollicitudin sit amet neque. Donec + sodales risus neque, a tincidunt purus ultrices quis. In mattis nisi + ipsum, et lacinia dui suscipit ac. Donec dictum, dolor id tincidunt + accumsan, tortor lorem posuere nisl, id consequat dui nisi fringilla + nisi. Fusce arcu justo, ornare nec vehicula eget, egestas tincidunt + lorem. Nunc dignissim lobortis velit, id efficitur magna aliquam id. + Donec at massa at purus elementum ornare. Cras id finibus sapien. In hac + habitasse platea dictumst. +

+

+ Class aptent taciti sociosqu ad litora torquent per conubia nostra, per + inceptos himenaeos. Nunc et urna leo. Etiam mattis ornare eros. Etiam + aliquet nibh orci, in iaculis orci pretium id. Etiam nibh elit, viverra + non viverra eu, imperdiet eu tellus. Pellentesque lobortis leo a finibus + cursus. Orci varius natoque penatibus et magnis dis parturient montes, + nascetur ridiculus mus. Donec tristique tempor tristique. Morbi iaculis + posuere aliquet. Donec mattis sed dui a fringilla. Sed urna tellus, + pulvinar in mollis ut, congue vel risus. +

+

+ Nullam scelerisque quam at lorem tempus, sed vulputate dui venenatis. + Donec porttitor, tellus at vehicula laoreet, lacus nulla consectetur + nisi, ut posuere massa turpis a arcu. Quisque tellus arcu, consectetur + vitae molestie eu, posuere vitae nunc. Sed vestibulum justo ultricies + magna rutrum molestie. Pellentesque lobortis erat vel fermentum + faucibus. Phasellus in arcu sit amet quam tincidunt sollicitudin quis + sed ipsum. Nullam bibendum ac metus et mollis. Nunc tempor vel mi id + fermentum. Morbi maximus turpis lobortis, pretium nibh ac, blandit + metus. In elementum nisl ac ex maximus, in commodo libero egestas. Morbi + molestie cursus massa, laoreet tempor tortor vestibulum venenatis. + Curabitur semper fringilla dolor, ut sagittis lorem elementum ut. +

+

+ Duis porttitor massa nulla, id congue erat luctus at. Aliquam id + tristique quam. Morbi pharetra scelerisque elit. Donec porttitor ipsum + vitae risus hendrerit faucibus. Praesent finibus placerat leo nec + facilisis. Vestibulum ante ipsum primis in faucibus orci luctus et + ultrices posuere cubilia curae; Proin molestie interdum turpis id + ornare. Ut vestibulum libero in magna porta, sed porta dolor viverra. +

+

+ Duis eget congue orci, ac malesuada leo. Fusce ut mattis nibh. Ut + pretium lectus in neque hendrerit, ut eleifend neque ultrices. Nam id + sollicitudin est. Suspendisse eget vehicula urna, a eleifend diam. + Aenean nibh nisl, finibus ullamcorper cursus sit amet, efficitur gravida + nulla. Proin leo massa, volutpat sit amet dolor ut, suscipit rutrum + justo. Proin nec elit blandit, porttitor ipsum sed, sodales ipsum. In + venenatis dolor lacus. Vestibulum et volutpat augue. Cras vehicula sem + ac augue vestibulum, id feugiat elit consectetur. Nullam consectetur + elit enim, eget aliquam eros venenatis eget. +

+

+ Donec sodales ipsum ut ante aliquam, non molestie massa faucibus. + Aliquam eget vehicula metus. Aenean lacinia nulla quis nulla ultricies + tristique. Vestibulum sit amet consequat nunc. Nullam sagittis dolor at + sodales varius. Integer odio eros, sodales quis orci id, commodo luctus + diam. Nullam dapibus ullamcorper lobortis. Suspendisse posuere ipsum + ipsum, ac ultrices quam porttitor quis. Maecenas auctor justo et egestas + congue. Etiam pharetra libero eget nisl rhoncus congue. Cras vehicula + dolor finibus tortor dignissim ultrices. +

+

+ Vestibulum quis aliquet neque, non pretium ligula. Donec imperdiet + tellus nec dolor accumsan, at congue ante euismod. Praesent egestas ac + lectus in auctor. Praesent euismod faucibus enim eget vulputate. Lorem + ipsum dolor sit amet, consectetur adipiscing elit. Nunc vitae convallis + tortor. Sed eleifend tellus quis nisl faucibus, sit amet aliquet tellus + placerat. Morbi ultrices enim mauris, et tincidunt lorem semper sed. +

+

+ Duis tincidunt ligula lacus, a cursus tortor tincidunt ac. Duis nulla + nulla, viverra sit amet augue vitae, lobortis consequat nibh. Morbi + dignissim, est nec consequat elementum, dolor est tempus velit, eu + laoreet mauris nibh eu nunc. Aenean finibus at justo eget consectetur. + Nam cursus sem felis, vitae blandit quam tincidunt sed. Praesent + bibendum luctus enim ut tempor. Phasellus tincidunt lectus vel laoreet + elementum. Maecenas sed quam sodales, porttitor augue in, faucibus eros. + Cras lacinia tortor sed lacus auctor, sit amet imperdiet dolor + hendrerit. +

+

+ Aliquam vel porta libero. In nec aliquam nisi. Donec pulvinar sapien + lacus, eu condimentum enim vestibulum eu. Aliquam erat volutpat. Aliquam + erat volutpat. Integer ac nisl ipsum. Nulla at congue quam. Etiam nec + libero ac dolor efficitur sodales ut et diam. Cras in sodales dolor. + Quisque elementum mattis elit non sagittis. +

+

+ Aliquam maximus nisl semper tristique blandit. Vivamus et porttitor + urna. Nulla facilisi. Nullam vitae condimentum purus. Lorem ipsum dolor + sit amet, consectetur adipiscing elit. Nulla dignissim dolor id felis + pellentesque, quis sodales dolor tincidunt. Morbi non posuere est. + Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere + cubilia curae; +

+

+ Fusce nec metus sit amet ligula pulvinar lobortis. Suspendisse dictum + lorem vitae quam tempor facilisis. Duis cursus eu lacus in volutpat. + Suspendisse fermentum nulla a purus vestibulum, in blandit lacus + hendrerit. Praesent rhoncus, nulla non varius dapibus, sapien nulla + blandit lorem, a aliquet ex ligula a sapien. Vivamus ac tortor + ultricies, molestie ex vitae, placerat elit. Ut lobortis nisl nec sapien + pretium ullamcorper convallis sed tortor. Suspendisse blandit urna eu + dolor pharetra, a pretium nibh consequat. Integer at vulputate erat. Nam + in mi urna. Aenean lectus mauris, condimentum in porttitor et, posuere + vitae elit. Aenean tempor ipsum ut pharetra porta. +

+

+ Fusce efficitur elementum lectus, vitae euismod leo luctus quis. Duis + faucibus, metus non rhoncus ornare, neque sapien pretium nisi, ut + ullamcorper massa justo at turpis. Maecenas vestibulum facilisis nulla + vel tristique. Aliquam vitae mi dolor. Aliquam imperdiet ullamcorper + auctor. Sed nibh nulla, imperdiet vel sagittis in, dapibus a turpis. Ut + pulvinar ac dolor ac euismod. Morbi quis euismod nisl, sagittis interdum + velit. Integer condimentum quam ac quam malesuada, in ultrices risus + pulvinar. +

+
+ ); +} diff --git a/packages/react-client/src/ReactFlightClient.js b/packages/react-client/src/ReactFlightClient.js index 132747e60a883..6cb21229c34e8 100644 --- a/packages/react-client/src/ReactFlightClient.js +++ b/packages/react-client/src/ReactFlightClient.js @@ -366,6 +366,7 @@ type Response = { _debugRootOwner?: null | ReactComponentInfo, // DEV-only _debugRootStack?: null | Error, // DEV-only _debugRootTask?: null | ConsoleTask, // DEV-only + _debugStartTime: number, // DEV-only _debugFindSourceMapURL?: void | FindSourceMapURLCallback, // DEV-only _debugChannel?: void | DebugChannel, // DEV-only _blockedConsole?: null | SomeChunk, // DEV-only @@ -822,6 +823,7 @@ type InitializationReference = { key: string, ) => any, path: Array, + isDebug?: boolean, // DEV-only }; type InitializationHandler = { parent: null | InitializationHandler, @@ -872,6 +874,7 @@ function initializeDebugChunk( response, initializeDebugInfo, [''], // path + true, ); break; } @@ -894,6 +897,7 @@ function initializeDebugChunk( response, initializeDebugInfo, [''], // path + true, ); break; } @@ -1407,8 +1411,6 @@ function fulfillReference( const mappedValue = map(response, value, parentObject, key); parentObject[key] = mappedValue; - transferReferencedDebugInfo(handler.chunk, fulfilledChunk, mappedValue); - // If this is the root object for a model reference, where `handler.value` // is a stale `null`, the resolved value can be used directly. if (key === '' && handler.value === null) { @@ -1427,19 +1429,27 @@ function fulfillReference( const element: any = handler.value; switch (key) { case '3': + transferReferencedDebugInfo(handler.chunk, fulfilledChunk, mappedValue); element.props = mappedValue; break; case '4': + // This path doesn't call transferReferencedDebugInfo because this reference is to a debug chunk. if (__DEV__) { element._owner = mappedValue; } break; case '5': + // This path doesn't call transferReferencedDebugInfo because this reference is to a debug chunk. if (__DEV__) { element._debugStack = mappedValue; } break; + default: + transferReferencedDebugInfo(handler.chunk, fulfilledChunk, mappedValue); + break; } + } else if (__DEV__ && !reference.isDebug) { + transferReferencedDebugInfo(handler.chunk, fulfilledChunk, mappedValue); } handler.deps--; @@ -1518,6 +1528,7 @@ function waitForReference( response: Response, map: (response: Response, model: any, parentObject: Object, key: string) => T, path: Array, + isAwaitingDebugInfo: boolean, // DEV-only ): T { if ( __DEV__ && @@ -1562,6 +1573,9 @@ function waitForReference( map, path, }; + if (__DEV__) { + reference.isDebug = isAwaitingDebugInfo; + } // Add "listener". if (referencedChunk.value === null) { @@ -1865,6 +1879,7 @@ function getOutlinedModel( response, map, path.slice(i - 1), + false, ); } case HALTED: { @@ -1910,11 +1925,27 @@ function getOutlinedModel( value = value[path[i]]; } const chunkValue = map(response, value, parentObject, key); - transferReferencedDebugInfo(initializingChunk, chunk, chunkValue); + if ( + parentObject[0] === REACT_ELEMENT_TYPE && + (key === '4' || key === '5') + ) { + // If we're resolving the "owner" or "stack" slot of an Element array, we don't call + // transferReferencedDebugInfo because this reference is to a debug chunk. + } else { + transferReferencedDebugInfo(initializingChunk, chunk, chunkValue); + } return chunkValue; case PENDING: case BLOCKED: - return waitForReference(chunk, parentObject, key, response, map, path); + return waitForReference( + chunk, + parentObject, + key, + response, + map, + path, + false, + ); case HALTED: { // Add a dependency that will never resolve. // TODO: Mark downstreams as halted too. @@ -2452,6 +2483,13 @@ function ResponseInstance( '"use ' + rootEnv.toLowerCase() + '"', ); } + if (enableAsyncDebugInfo) { + // Track the start of the fetch to the best of our knowledge. + // Note: createFromFetch allows this to be marked at the start of the fetch + // where as if you use createFromReadableStream from the body of the fetch + // then the start time is when the headers resolved. + this._debugStartTime = performance.now(); + } this._debugFindSourceMapURL = findSourceMapURL; this._debugChannel = debugChannel; this._blockedConsole = null; @@ -2520,16 +2558,99 @@ export type StreamState = { _rowTag: number, // 0 indicates that we're currently parsing the row ID _rowLength: number, // remaining bytes in the row. 0 indicates that we're looking for a newline. _buffer: Array, // chunks received so far as part of this row + _debugInfo: ReactIOInfo, // DEV-only + _debugTargetChunkSize: number, // DEV-only }; -export function createStreamState(): StreamState { - return { +export function createStreamState( + weakResponse: WeakResponse, // DEV-only + streamDebugValue: mixed, // DEV-only +): StreamState { + const streamState: StreamState = (({ _rowState: 0, _rowID: 0, _rowTag: 0, _rowLength: 0, _buffer: [], - }; + }: Omit): any); + if (__DEV__ && enableAsyncDebugInfo) { + const response = unwrapWeakResponse(weakResponse); + // Create an entry for the I/O to load the stream itself. + const debugValuePromise = Promise.resolve(streamDebugValue); + (debugValuePromise: any).status = 'fulfilled'; + (debugValuePromise: any).value = streamDebugValue; + streamState._debugInfo = { + name: 'RSC stream', + start: response._debugStartTime, + end: response._debugStartTime, // will be updated once we finish a chunk + byteSize: 0, // will be updated as we resolve a data chunk + value: debugValuePromise, + owner: response._debugRootOwner, + debugStack: response._debugRootStack, + debugTask: response._debugRootTask, + }; + streamState._debugTargetChunkSize = MIN_CHUNK_SIZE; + } + return streamState; +} + +// Depending on set up the chunks of a TLS connection can vary in size. However in practice it's often +// at 64kb or even multiples of 64kb. It can also be smaller but in practice it also happens that 64kb +// is around what you can download on fast 4G connection in 300ms which is what we throttle reveals at +// anyway. The net effect is that in practice, you won't really reveal anything in smaller units than +// 64kb if they're revealing at maximum speed in production. Therefore we group smaller chunks into +// these larger chunks since in production that's more realistic. +// TODO: If the stream is compressed, then you could fit much more in a single 300ms so maybe it should +// actually be larger. +const MIN_CHUNK_SIZE = 65536; + +function incrementChunkDebugInfo( + streamState: StreamState, + chunkLength: number, +): void { + if (__DEV__ && enableAsyncDebugInfo) { + const debugInfo: ReactIOInfo = streamState._debugInfo; + const endTime = performance.now(); + const previousEndTime = debugInfo.end; + const newByteLength = ((debugInfo.byteSize: any): number) + chunkLength; + if ( + newByteLength > streamState._debugTargetChunkSize || + endTime > previousEndTime + 10 + ) { + // This new chunk would overshoot the chunk size so therefore we treat it as its own new chunk + // by cloning the old one. Similarly, if some time has passed we assume that it was actually + // due to the server being unable to flush chunks faster e.g. due to I/O so it would be a + // new chunk in production even if the buffer hasn't been reached. + streamState._debugInfo = { + name: debugInfo.name, + start: debugInfo.start, + end: endTime, + byteSize: newByteLength, + value: debugInfo.value, + owner: debugInfo.owner, + debugStack: debugInfo.debugStack, + debugTask: debugInfo.debugTask, + }; + streamState._debugTargetChunkSize = newByteLength + MIN_CHUNK_SIZE; + } else { + // Otherwise we reuse the old chunk but update the end time and byteSize to the latest. + // $FlowFixMe[cannot-write] + debugInfo.end = endTime; + // $FlowFixMe[cannot-write] + debugInfo.byteSize = newByteLength; + } + } +} + +function resolveChunkDebugInfo( + streamState: StreamState, + chunk: SomeChunk, +): void { + if (__DEV__ && enableAsyncDebugInfo) { + // Push the currently resolving chunk's debug info representing the stream on the Promise + // that was waiting on the stream. + chunk._debugInfo.push({awaited: streamState._debugInfo}); + } } function resolveDebugHalt(response: Response, id: number): void { @@ -2553,17 +2674,33 @@ function resolveModel( response: Response, id: number, model: UninitializedModel, + streamState: StreamState, ): void { const chunks = response._chunks; const chunk = chunks.get(id); if (!chunk) { - chunks.set(id, createResolvedModelChunk(response, model)); + const newChunk: ResolvedModelChunk = createResolvedModelChunk( + response, + model, + ); + if (__DEV__) { + resolveChunkDebugInfo(streamState, newChunk); + } + chunks.set(id, newChunk); } else { + if (__DEV__) { + resolveChunkDebugInfo(streamState, chunk); + } resolveModelChunk(response, chunk, model); } } -function resolveText(response: Response, id: number, text: string): void { +function resolveText( + response: Response, + id: number, + text: string, + streamState: StreamState, +): void { const chunks = response._chunks; const chunk = chunks.get(id); if (chunk && chunk.status !== PENDING) { @@ -2577,13 +2714,18 @@ function resolveText(response: Response, id: number, text: string): void { if (chunk) { releasePendingChunk(response, chunk); } - chunks.set(id, createInitializedTextChunk(response, text)); + const newChunk = createInitializedTextChunk(response, text); + if (__DEV__) { + resolveChunkDebugInfo(streamState, newChunk); + } + chunks.set(id, newChunk); } function resolveBuffer( response: Response, id: number, buffer: $ArrayBufferView | ArrayBuffer, + streamState: StreamState, ): void { const chunks = response._chunks; const chunk = chunks.get(id); @@ -2598,13 +2740,18 @@ function resolveBuffer( if (chunk) { releasePendingChunk(response, chunk); } - chunks.set(id, createInitializedBufferChunk(response, buffer)); + const newChunk = createInitializedBufferChunk(response, buffer); + if (__DEV__) { + resolveChunkDebugInfo(streamState, newChunk); + } + chunks.set(id, newChunk); } function resolveModule( response: Response, id: number, model: UninitializedModel, + streamState: StreamState, ): void { const chunks = response._chunks; const chunk = chunks.get(id); @@ -2641,14 +2788,24 @@ function resolveModule( blockedChunk = (chunk: any); blockedChunk.status = BLOCKED; } + if (__DEV__) { + resolveChunkDebugInfo(streamState, blockedChunk); + } promise.then( () => resolveModuleChunk(response, blockedChunk, clientReference), error => triggerErrorOnChunk(response, blockedChunk, error), ); } else { if (!chunk) { - chunks.set(id, createResolvedModuleChunk(response, clientReference)); + const newChunk = createResolvedModuleChunk(response, clientReference); + if (__DEV__) { + resolveChunkDebugInfo(streamState, newChunk); + } + chunks.set(id, newChunk); } else { + if (__DEV__) { + resolveChunkDebugInfo(streamState, chunk); + } // This can't actually happen because we don't have any forward // references to modules. resolveModuleChunk(response, chunk, clientReference); @@ -2661,13 +2818,21 @@ function resolveStream>( id: number, stream: T, controller: FlightStreamController, + streamState: StreamState, ): void { const chunks = response._chunks; const chunk = chunks.get(id); if (!chunk) { - chunks.set(id, createInitializedStreamChunk(response, stream, controller)); + const newChunk = createInitializedStreamChunk(response, stream, controller); + if (__DEV__) { + resolveChunkDebugInfo(streamState, newChunk); + } + chunks.set(id, newChunk); return; } + if (__DEV__) { + resolveChunkDebugInfo(streamState, chunk); + } if (chunk.status !== PENDING) { // We already resolved. We didn't expect to see this. return; @@ -2723,6 +2888,7 @@ function startReadableStream( response: Response, id: number, type: void | 'bytes', + streamState: StreamState, ): void { let controller: ReadableStreamController = (null: any); const stream = new ReadableStream({ @@ -2803,7 +2969,7 @@ function startReadableStream( } }, }; - resolveStream(response, id, stream, flightController); + resolveStream(response, id, stream, flightController, streamState); } function asyncIterator(this: $AsyncIterator) { @@ -2829,6 +2995,7 @@ function startAsyncIterable( response: Response, id: number, iterator: boolean, + streamState: StreamState, ): void { const buffer: Array>> = []; let closed = false; @@ -2946,6 +3113,7 @@ function startAsyncIterable( id, iterator ? iterable[ASYNC_ITERATOR]() : iterable, flightController, + streamState, ); } @@ -3025,7 +3193,11 @@ function resolveErrorDev( return error; } -function resolvePostponeProd(response: Response, id: number): void { +function resolvePostponeProd( + response: Response, + id: number, + streamState: StreamState, +): void { if (__DEV__) { // These errors should never make it into a build so we don't need to encode them in codes.json // eslint-disable-next-line react-internal/prod-error-codes @@ -3043,7 +3215,11 @@ function resolvePostponeProd(response: Response, id: number): void { const chunks = response._chunks; const chunk = chunks.get(id); if (!chunk) { - chunks.set(id, createErrorChunk(response, postponeInstance)); + const newChunk: ErroredChunk = createErrorChunk( + response, + postponeInstance, + ); + chunks.set(id, newChunk); } else { triggerErrorOnChunk(response, chunk, postponeInstance); } @@ -3055,6 +3231,7 @@ function resolvePostponeDev( reason: string, stack: ReactStackTrace, env: string, + streamState: StreamState, ): void { if (!__DEV__) { // These errors should never make it into a build so we don't need to encode them in codes.json @@ -3082,8 +3259,18 @@ function resolvePostponeDev( const chunks = response._chunks; const chunk = chunks.get(id); if (!chunk) { - chunks.set(id, createErrorChunk(response, postponeInstance)); + const newChunk: ErroredChunk = createErrorChunk( + response, + postponeInstance, + ); + if (__DEV__) { + resolveChunkDebugInfo(streamState, newChunk); + } + chunks.set(id, newChunk); } else { + if (__DEV__) { + resolveChunkDebugInfo(streamState, chunk); + } triggerErrorOnChunk(response, chunk, postponeInstance); } } @@ -3092,6 +3279,7 @@ function resolveErrorModel( response: Response, id: number, row: UninitializedModel, + streamState: StreamState, ): void { const chunks = response._chunks; const chunk = chunks.get(id); @@ -3105,8 +3293,18 @@ function resolveErrorModel( (error: any).digest = errorInfo.digest; const errorWithDigest: ErrorWithDigest = (error: any); if (!chunk) { - chunks.set(id, createErrorChunk(response, errorWithDigest)); + const newChunk: ErroredChunk = createErrorChunk( + response, + errorWithDigest, + ); + if (__DEV__) { + resolveChunkDebugInfo(streamState, newChunk); + } + chunks.set(id, newChunk); } else { + if (__DEV__) { + resolveChunkDebugInfo(streamState, chunk); + } triggerErrorOnChunk(response, chunk, errorWithDigest); } } @@ -3841,6 +4039,7 @@ function resolveTypedArray( lastChunk: Uint8Array, constructor: any, bytesPerElement: number, + streamState: StreamState, ): void { // If the view fits into one original buffer, we just reuse that buffer instead of // copying it out to a separate copy. This means that it's not always possible to @@ -3860,7 +4059,7 @@ function resolveTypedArray( chunk.byteOffset, chunk.byteLength / bytesPerElement, ); - resolveBuffer(response, id, view); + resolveBuffer(response, id, view, streamState); } function logComponentInfo( @@ -4177,6 +4376,7 @@ function flushInitialRenderPerformance(response: Response): void { function processFullBinaryRow( response: Response, + streamState: StreamState, id: number, tag: number, buffer: Array, @@ -4185,47 +4385,125 @@ function processFullBinaryRow( switch (tag) { case 65 /* "A" */: // We must always clone to extract it into a separate buffer instead of just a view. - resolveBuffer(response, id, mergeBuffer(buffer, chunk).buffer); + resolveBuffer( + response, + id, + mergeBuffer(buffer, chunk).buffer, + streamState, + ); return; case 79 /* "O" */: - resolveTypedArray(response, id, buffer, chunk, Int8Array, 1); + resolveTypedArray(response, id, buffer, chunk, Int8Array, 1, streamState); return; case 111 /* "o" */: resolveBuffer( response, id, buffer.length === 0 ? chunk : mergeBuffer(buffer, chunk), + streamState, ); return; case 85 /* "U" */: - resolveTypedArray(response, id, buffer, chunk, Uint8ClampedArray, 1); + resolveTypedArray( + response, + id, + buffer, + chunk, + Uint8ClampedArray, + 1, + streamState, + ); return; case 83 /* "S" */: - resolveTypedArray(response, id, buffer, chunk, Int16Array, 2); + resolveTypedArray( + response, + id, + buffer, + chunk, + Int16Array, + 2, + streamState, + ); return; case 115 /* "s" */: - resolveTypedArray(response, id, buffer, chunk, Uint16Array, 2); + resolveTypedArray( + response, + id, + buffer, + chunk, + Uint16Array, + 2, + streamState, + ); return; case 76 /* "L" */: - resolveTypedArray(response, id, buffer, chunk, Int32Array, 4); + resolveTypedArray( + response, + id, + buffer, + chunk, + Int32Array, + 4, + streamState, + ); return; case 108 /* "l" */: - resolveTypedArray(response, id, buffer, chunk, Uint32Array, 4); + resolveTypedArray( + response, + id, + buffer, + chunk, + Uint32Array, + 4, + streamState, + ); return; case 71 /* "G" */: - resolveTypedArray(response, id, buffer, chunk, Float32Array, 4); + resolveTypedArray( + response, + id, + buffer, + chunk, + Float32Array, + 4, + streamState, + ); return; case 103 /* "g" */: - resolveTypedArray(response, id, buffer, chunk, Float64Array, 8); + resolveTypedArray( + response, + id, + buffer, + chunk, + Float64Array, + 8, + streamState, + ); return; case 77 /* "M" */: - resolveTypedArray(response, id, buffer, chunk, BigInt64Array, 8); + resolveTypedArray( + response, + id, + buffer, + chunk, + BigInt64Array, + 8, + streamState, + ); return; case 109 /* "m" */: - resolveTypedArray(response, id, buffer, chunk, BigUint64Array, 8); + resolveTypedArray( + response, + id, + buffer, + chunk, + BigUint64Array, + 8, + streamState, + ); return; case 86 /* "V" */: - resolveTypedArray(response, id, buffer, chunk, DataView, 1); + resolveTypedArray(response, id, buffer, chunk, DataView, 1, streamState); return; } @@ -4235,18 +4513,19 @@ function processFullBinaryRow( row += readPartialStringChunk(stringDecoder, buffer[i]); } row += readFinalStringChunk(stringDecoder, chunk); - processFullStringRow(response, id, tag, row); + processFullStringRow(response, streamState, id, tag, row); } function processFullStringRow( response: Response, + streamState: StreamState, id: number, tag: number, row: string, ): void { switch (tag) { case 73 /* "I" */: { - resolveModule(response, id, row); + resolveModule(response, id, row, streamState); return; } case 72 /* "H" */: { @@ -4255,11 +4534,11 @@ function processFullStringRow( return; } case 69 /* "E" */: { - resolveErrorModel(response, id, row); + resolveErrorModel(response, id, row, streamState); return; } case 84 /* "T" */: { - resolveText(response, id, row); + resolveText(response, id, row, streamState); return; } case 78 /* "N" */: { @@ -4304,22 +4583,22 @@ function processFullStringRow( ); } case 82 /* "R" */: { - startReadableStream(response, id, undefined); + startReadableStream(response, id, undefined, streamState); return; } // Fallthrough case 114 /* "r" */: { - startReadableStream(response, id, 'bytes'); + startReadableStream(response, id, 'bytes', streamState); return; } // Fallthrough case 88 /* "X" */: { - startAsyncIterable(response, id, false); + startAsyncIterable(response, id, false, streamState); return; } // Fallthrough case 120 /* "x" */: { - startAsyncIterable(response, id, true); + startAsyncIterable(response, id, true, streamState); return; } // Fallthrough @@ -4338,9 +4617,10 @@ function processFullStringRow( postponeInfo.reason, postponeInfo.stack, postponeInfo.env, + streamState, ); } else { - resolvePostponeProd(response, id); + resolvePostponeProd(response, id, streamState); } return; } @@ -4352,7 +4632,7 @@ function processFullStringRow( return; } // We assume anything else is JSON. - resolveModel(response, id, row); + resolveModel(response, id, row, streamState); return; } } @@ -4375,6 +4655,7 @@ export function processBinaryChunk( let rowLength = streamState._rowLength; const buffer = streamState._buffer; const chunkLength = chunk.length; + incrementChunkDebugInfo(streamState, chunkLength); while (i < chunkLength) { let lastIdx = -1; switch (rowState) { @@ -4454,7 +4735,14 @@ export function processBinaryChunk( // We found the last chunk of the row const length = lastIdx - i; const lastChunk = new Uint8Array(chunk.buffer, offset, length); - processFullBinaryRow(response, rowID, rowTag, buffer, lastChunk); + processFullBinaryRow( + response, + streamState, + rowID, + rowTag, + buffer, + lastChunk, + ); // Reset state machine for a new row i = lastIdx; if (rowState === ROW_CHUNK_BY_NEWLINE) { @@ -4509,6 +4797,7 @@ export function processStringChunk( let rowLength = streamState._rowLength; const buffer = streamState._buffer; const chunkLength = chunk.length; + incrementChunkDebugInfo(streamState, chunkLength); while (i < chunkLength) { let lastIdx = -1; switch (rowState) { @@ -4607,7 +4896,7 @@ export function processStringChunk( ); } const lastChunk = chunk.slice(i, lastIdx); - processFullStringRow(response, rowID, rowTag, lastChunk); + processFullStringRow(response, streamState, rowID, rowTag, lastChunk); // Reset state machine for a new row i = lastIdx; if (rowState === ROW_CHUNK_BY_NEWLINE) { diff --git a/packages/react-client/src/__tests__/ReactFlight-test.js b/packages/react-client/src/__tests__/ReactFlight-test.js index 3bcf4988feb86..da1dff04820fc 100644 --- a/packages/react-client/src/__tests__/ReactFlight-test.js +++ b/packages/react-client/src/__tests__/ReactFlight-test.js @@ -85,7 +85,11 @@ function getDebugInfo(obj) { if (debugInfo) { const copy = []; for (let i = 0; i < debugInfo.length; i++) { - copy.push(normalizeComponentInfo(debugInfo[i])); + if (debugInfo[i].awaited && debugInfo[i].awaited.name === 'RSC stream') { + // Ignore RSC stream I/O info. + } else { + copy.push(normalizeComponentInfo(debugInfo[i])); + } } return copy; } @@ -2832,7 +2836,7 @@ describe('ReactFlight', () => { transport: expect.arrayContaining([]), }, }, - {time: gate(flags => flags.enableAsyncDebugInfo) ? 23 : 21}, + {time: gate(flags => flags.enableAsyncDebugInfo) ? 53 : 21}, ] : undefined, ); @@ -2843,7 +2847,7 @@ describe('ReactFlight', () => { expect(getDebugInfo(thirdPartyChildren[0])).toEqual( __DEV__ ? [ - {time: gate(flags => flags.enableAsyncDebugInfo) ? 24 : 22}, // Clamped to the start + {time: gate(flags => flags.enableAsyncDebugInfo) ? 54 : 22}, // Clamped to the start { name: 'ThirdPartyComponent', env: 'third-party', @@ -2851,15 +2855,15 @@ describe('ReactFlight', () => { stack: ' in Object. (at **)', props: {}, }, - {time: gate(flags => flags.enableAsyncDebugInfo) ? 24 : 22}, - {time: gate(flags => flags.enableAsyncDebugInfo) ? 25 : 23}, // This last one is when the promise resolved into the first party. + {time: gate(flags => flags.enableAsyncDebugInfo) ? 54 : 22}, + {time: gate(flags => flags.enableAsyncDebugInfo) ? 55 : 23}, // This last one is when the promise resolved into the first party. ] : undefined, ); expect(getDebugInfo(thirdPartyChildren[1])).toEqual( __DEV__ ? [ - {time: gate(flags => flags.enableAsyncDebugInfo) ? 24 : 22}, // Clamped to the start + {time: gate(flags => flags.enableAsyncDebugInfo) ? 54 : 22}, // Clamped to the start { name: 'ThirdPartyLazyComponent', env: 'third-party', @@ -2867,14 +2871,14 @@ describe('ReactFlight', () => { stack: ' in myLazy (at **)\n in lazyInitializer (at **)', props: {}, }, - {time: gate(flags => flags.enableAsyncDebugInfo) ? 24 : 22}, + {time: gate(flags => flags.enableAsyncDebugInfo) ? 54 : 22}, ] : undefined, ); expect(getDebugInfo(thirdPartyChildren[2])).toEqual( __DEV__ ? [ - {time: gate(flags => flags.enableAsyncDebugInfo) ? 24 : 22}, + {time: gate(flags => flags.enableAsyncDebugInfo) ? 54 : 22}, { name: 'ThirdPartyFragmentComponent', env: 'third-party', @@ -2882,7 +2886,7 @@ describe('ReactFlight', () => { stack: ' in Object. (at **)', props: {}, }, - {time: gate(flags => flags.enableAsyncDebugInfo) ? 24 : 22}, + {time: gate(flags => flags.enableAsyncDebugInfo) ? 54 : 22}, ] : undefined, ); @@ -2963,7 +2967,7 @@ describe('ReactFlight', () => { { time: 16, }, - {time: 17}, + {time: 31}, ] : undefined, ); @@ -2972,7 +2976,7 @@ describe('ReactFlight', () => { expect(getDebugInfo(thirdPartyFragment)).toEqual( __DEV__ ? [ - {time: 18}, + {time: 32}, { name: 'Keyed', env: 'Server', @@ -2983,12 +2987,14 @@ describe('ReactFlight', () => { }, }, { - time: 19, + time: 33, + }, + { + time: 33, }, { - time: 19, + time: 33, }, - {time: 19}, ] : undefined, ); @@ -2996,7 +3002,7 @@ describe('ReactFlight', () => { expect(getDebugInfo(thirdPartyFragment.props.children)).toEqual( __DEV__ ? [ - {time: 19}, // Clamp to the start + {time: 33}, // Clamp to the start { name: 'ThirdPartyAsyncIterableComponent', env: 'third-party', @@ -3004,7 +3010,7 @@ describe('ReactFlight', () => { stack: ' in Object. (at **)', props: {}, }, - {time: 19}, + {time: 33}, ] : undefined, ); @@ -3067,7 +3073,7 @@ describe('ReactFlight', () => { props: {}, }, {time: 16}, - {time: 17}, + {time: gate(flags => flags.enableAsyncDebugInfo) ? 24 : 17}, ] : undefined, ); diff --git a/packages/react-markup/src/ReactMarkupServer.js b/packages/react-markup/src/ReactMarkupServer.js index 5f69c3d44a317..0b35404cb80aa 100644 --- a/packages/react-markup/src/ReactMarkupServer.js +++ b/packages/react-markup/src/ReactMarkupServer.js @@ -81,7 +81,18 @@ export function experimental_renderToHTML( options?: MarkupOptions, ): Promise { return new Promise((resolve, reject) => { - const streamState = createFlightStreamState(); + const flightResponse = createFlightResponse( + null, + null, + null, + noServerCallOrFormAction, + noServerCallOrFormAction, + undefined, + undefined, + undefined, + false, + ); + const streamState = createFlightStreamState(flightResponse, null); const flightDestination = { push(chunk: string | null): boolean { if (chunk !== null) { @@ -175,17 +186,6 @@ export function experimental_renderToHTML( undefined, false, ); - const flightResponse = createFlightResponse( - null, - null, - null, - noServerCallOrFormAction, - noServerCallOrFormAction, - undefined, - undefined, - undefined, - false, - ); const resumableState = createResumableState( options ? options.identifierPrefix : undefined, undefined, diff --git a/packages/react-noop-renderer/src/ReactNoopFlightClient.js b/packages/react-noop-renderer/src/ReactNoopFlightClient.js index 3d8984a07fb18..fb6259f1a6acc 100644 --- a/packages/react-noop-renderer/src/ReactNoopFlightClient.js +++ b/packages/react-noop-renderer/src/ReactNoopFlightClient.js @@ -77,7 +77,7 @@ function read(source: Source, options: ReadOptions): Thenable { ? options.debugChannel.onMessage : undefined, ); - const streamState = createStreamState(); + const streamState = createStreamState(response, source); for (let i = 0; i < source.length; i++) { processBinaryChunk(response, streamState, source[i], 0); } diff --git a/packages/react-server-dom-esm/src/client/ReactFlightDOMClientBrowser.js b/packages/react-server-dom-esm/src/client/ReactFlightDOMClientBrowser.js index d61f132310547..cfc8dcf5f1b25 100644 --- a/packages/react-server-dom-esm/src/client/ReactFlightDOMClientBrowser.js +++ b/packages/react-server-dom-esm/src/client/ReactFlightDOMClientBrowser.js @@ -115,7 +115,7 @@ function startReadingFromUniversalStream( // This is the same as startReadingFromStream except this allows WebSocketStreams which // return ArrayBuffer and string chunks instead of Uint8Array chunks. We could potentially // always allow streams with variable chunk types. - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); const reader = stream.getReader(); function progress({ done, @@ -149,8 +149,9 @@ function startReadingFromStream( response: FlightResponse, stream: ReadableStream, onDone: () => void, + debugValue: mixed, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, debugValue); const reader = stream.getReader(); function progress({ done, @@ -194,9 +195,14 @@ function createFromReadableStream( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, stream, handleDone); + startReadingFromStream(response, stream, handleDone, stream); } else { - startReadingFromStream(response, stream, close.bind(null, response)); + startReadingFromStream( + response, + stream, + close.bind(null, response), + stream, + ); } return getRoot(response); } @@ -225,12 +231,13 @@ function createFromFetch( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, (r.body: any), handleDone); + startReadingFromStream(response, (r.body: any), handleDone, r); } else { startReadingFromStream( response, (r.body: any), close.bind(null, response), + r, ); } }, diff --git a/packages/react-server-dom-esm/src/client/ReactFlightDOMClientNode.js b/packages/react-server-dom-esm/src/client/ReactFlightDOMClientNode.js index 3500b3f41f2b9..2bf32729472d2 100644 --- a/packages/react-server-dom-esm/src/client/ReactFlightDOMClientNode.js +++ b/packages/react-server-dom-esm/src/client/ReactFlightDOMClientNode.js @@ -66,7 +66,7 @@ function startReadingFromStream( stream: Readable, onEnd: () => void, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); stream.on('data', chunk => { if (typeof chunk === 'string') { diff --git a/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientBrowser.js b/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientBrowser.js index 808b49d9d75d0..2f71ce2fa9597 100644 --- a/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientBrowser.js +++ b/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientBrowser.js @@ -141,7 +141,7 @@ function startReadingFromUniversalStream( // This is the same as startReadingFromStream except this allows WebSocketStreams which // return ArrayBuffer and string chunks instead of Uint8Array chunks. We could potentially // always allow streams with variable chunk types. - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); const reader = stream.getReader(); function progress({ done, @@ -175,8 +175,9 @@ function startReadingFromStream( response: FlightResponse, stream: ReadableStream, onDone: () => void, + debugValue: mixed, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, debugValue); const reader = stream.getReader(); function progress({ done, @@ -228,9 +229,14 @@ export function createFromReadableStream( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, stream, handleDone); + startReadingFromStream(response, stream, handleDone, stream); } else { - startReadingFromStream(response, stream, close.bind(null, response)); + startReadingFromStream( + response, + stream, + close.bind(null, response), + stream, + ); } return getRoot(response); } @@ -259,12 +265,13 @@ export function createFromFetch( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, (r.body: any), handleDone); + startReadingFromStream(response, (r.body: any), handleDone, r); } else { startReadingFromStream( response, (r.body: any), close.bind(null, response), + r, ); } }, diff --git a/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientEdge.js b/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientEdge.js index 54c72968c22fe..f9c63ccbc3370 100644 --- a/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientEdge.js +++ b/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientEdge.js @@ -115,8 +115,9 @@ function startReadingFromStream( response: FlightResponse, stream: ReadableStream, onDone: () => void, + debugValue: mixed, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, debugValue); const reader = stream.getReader(); function progress({ done, @@ -158,9 +159,14 @@ export function createFromReadableStream( } }; startReadingFromStream(response, options.debugChannel.readable, handleDone); - startReadingFromStream(response, stream, handleDone); + startReadingFromStream(response, stream, handleDone, stream); } else { - startReadingFromStream(response, stream, close.bind(null, response)); + startReadingFromStream( + response, + stream, + close.bind(null, response), + stream, + ); } return getRoot(response); @@ -190,12 +196,13 @@ export function createFromFetch( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, (r.body: any), handleDone); + startReadingFromStream(response, (r.body: any), handleDone, r); } else { startReadingFromStream( response, (r.body: any), close.bind(null, response), + r, ); } }, diff --git a/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientNode.js b/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientNode.js index b513fd3faca33..b874bcd7d44f5 100644 --- a/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientNode.js +++ b/packages/react-server-dom-parcel/src/client/ReactFlightDOMClientNode.js @@ -61,7 +61,7 @@ function startReadingFromStream( stream: Readable, onEnd: () => void, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); stream.on('data', chunk => { if (typeof chunk === 'string') { diff --git a/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientBrowser.js b/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientBrowser.js index dc4c99dabd055..b4b84f1c41b23 100644 --- a/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientBrowser.js +++ b/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientBrowser.js @@ -114,7 +114,7 @@ function startReadingFromUniversalStream( // This is the same as startReadingFromStream except this allows WebSocketStreams which // return ArrayBuffer and string chunks instead of Uint8Array chunks. We could potentially // always allow streams with variable chunk types. - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); const reader = stream.getReader(); function progress({ done, @@ -148,8 +148,9 @@ function startReadingFromStream( response: FlightResponse, stream: ReadableStream, onDone: () => void, + debugValue: mixed, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, debugValue); const reader = stream.getReader(); function progress({ done, @@ -194,9 +195,14 @@ function createFromReadableStream( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, stream, handleDone); + startReadingFromStream(response, stream, handleDone, stream); } else { - startReadingFromStream(response, stream, close.bind(null, response)); + startReadingFromStream( + response, + stream, + close.bind(null, response), + stream, + ); } return getRoot(response); } @@ -225,12 +231,13 @@ function createFromFetch( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, (r.body: any), handleDone); + startReadingFromStream(response, (r.body: any), handleDone, r); } else { startReadingFromStream( response, (r.body: any), close.bind(null, response), + r, ); } }, diff --git a/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientEdge.js b/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientEdge.js index 245761b2722a6..b994841be18b3 100644 --- a/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientEdge.js +++ b/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientEdge.js @@ -117,8 +117,9 @@ function startReadingFromStream( response: FlightResponse, stream: ReadableStream, onDone: () => void, + debugValue: mixed, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, debugValue); const reader = stream.getReader(); function progress({ done, @@ -160,9 +161,14 @@ function createFromReadableStream( } }; startReadingFromStream(response, options.debugChannel.readable, handleDone); - startReadingFromStream(response, stream, handleDone); + startReadingFromStream(response, stream, handleDone, stream); } else { - startReadingFromStream(response, stream, close.bind(null, response)); + startReadingFromStream( + response, + stream, + close.bind(null, response), + stream, + ); } return getRoot(response); @@ -192,12 +198,13 @@ function createFromFetch( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, (r.body: any), handleDone); + startReadingFromStream(response, (r.body: any), handleDone, r); } else { startReadingFromStream( response, (r.body: any), close.bind(null, response), + r, ); } }, diff --git a/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientNode.js b/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientNode.js index af8b7f41bc837..f174f10c0b88f 100644 --- a/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientNode.js +++ b/packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientNode.js @@ -69,7 +69,7 @@ function startReadingFromStream( stream: Readable, onEnd: () => void, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); stream.on('data', chunk => { if (typeof chunk === 'string') { diff --git a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js index 98bc21576b08a..55b434ce3eeff 100644 --- a/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js +++ b/packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js @@ -1239,17 +1239,24 @@ describe('ReactFlightDOMEdge', () => { name: 'Greeting', env: 'Server', }); - expect(lazyWrapper._debugInfo).toEqual([ - {time: 12}, - greetInfo, - {time: 13}, - expect.objectContaining({ - name: 'Container', - env: 'Server', - owner: greetInfo, - }), - {time: 14}, - ]); + if (gate(flags => flags.enableAsyncDebugInfo)) { + expect(lazyWrapper._debugInfo).toEqual([ + {time: 12}, + greetInfo, + {time: 13}, + expect.objectContaining({ + name: 'Container', + env: 'Server', + owner: greetInfo, + }), + {time: 14}, + expect.objectContaining({ + awaited: expect.objectContaining({ + name: 'RSC stream', + }), + }), + ]); + } // The owner that created the span was the outer server component. // We expect the debug info to be referentially equal to the owner. expect(greeting._owner).toBe(lazyWrapper._debugInfo[1]); diff --git a/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientBrowser.js b/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientBrowser.js index dc4c99dabd055..b4b84f1c41b23 100644 --- a/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientBrowser.js +++ b/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientBrowser.js @@ -114,7 +114,7 @@ function startReadingFromUniversalStream( // This is the same as startReadingFromStream except this allows WebSocketStreams which // return ArrayBuffer and string chunks instead of Uint8Array chunks. We could potentially // always allow streams with variable chunk types. - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); const reader = stream.getReader(); function progress({ done, @@ -148,8 +148,9 @@ function startReadingFromStream( response: FlightResponse, stream: ReadableStream, onDone: () => void, + debugValue: mixed, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, debugValue); const reader = stream.getReader(); function progress({ done, @@ -194,9 +195,14 @@ function createFromReadableStream( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, stream, handleDone); + startReadingFromStream(response, stream, handleDone, stream); } else { - startReadingFromStream(response, stream, close.bind(null, response)); + startReadingFromStream( + response, + stream, + close.bind(null, response), + stream, + ); } return getRoot(response); } @@ -225,12 +231,13 @@ function createFromFetch( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, (r.body: any), handleDone); + startReadingFromStream(response, (r.body: any), handleDone, r); } else { startReadingFromStream( response, (r.body: any), close.bind(null, response), + r, ); } }, diff --git a/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientEdge.js b/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientEdge.js index 7c9a707a546a6..63dae4954550a 100644 --- a/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientEdge.js +++ b/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientEdge.js @@ -117,8 +117,9 @@ function startReadingFromStream( response: FlightResponse, stream: ReadableStream, onDone: () => void, + debugValue: mixed, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, debugValue); const reader = stream.getReader(); function progress({ done, @@ -160,9 +161,14 @@ function createFromReadableStream( } }; startReadingFromStream(response, options.debugChannel.readable, handleDone); - startReadingFromStream(response, stream, handleDone); + startReadingFromStream(response, stream, handleDone, stream); } else { - startReadingFromStream(response, stream, close.bind(null, response)); + startReadingFromStream( + response, + stream, + close.bind(null, response), + stream, + ); } return getRoot(response); @@ -192,12 +198,13 @@ function createFromFetch( options.debugChannel.readable, handleDone, ); - startReadingFromStream(response, (r.body: any), handleDone); + startReadingFromStream(response, (r.body: any), handleDone, r); } else { startReadingFromStream( response, (r.body: any), close.bind(null, response), + r, ); } }, diff --git a/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientNode.js b/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientNode.js index af8b7f41bc837..f174f10c0b88f 100644 --- a/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientNode.js +++ b/packages/react-server-dom-webpack/src/client/ReactFlightDOMClientNode.js @@ -69,7 +69,7 @@ function startReadingFromStream( stream: Readable, onEnd: () => void, ): void { - const streamState = createStreamState(); + const streamState = createStreamState(response, stream); stream.on('data', chunk => { if (typeof chunk === 'string') { diff --git a/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js b/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js index 0a98d87e363ca..ab4a054b019be 100644 --- a/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js +++ b/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js @@ -58,9 +58,16 @@ function normalizeIOInfo(ioInfo) { if (promise) { promise.then(); // init if (promise.status === 'fulfilled') { - copy.value = { - value: promise.value, - }; + if (ioInfo.name === 'RSC stream') { + copy.byteSize = 0; + copy.value = { + value: 'stream', + }; + } else { + copy.value = { + value: promise.value, + }; + } } else if (promise.status === 'rejected') { copy.value = { reason: promise.reason, @@ -76,11 +83,11 @@ function normalizeIOInfo(ioInfo) { function normalizeDebugInfo(original) { const {debugTask, debugStack, debugLocation, ...debugInfo} = original; - if (debugInfo.owner) { - debugInfo.owner = normalizeDebugInfo(debugInfo.owner); + if (original.owner) { + debugInfo.owner = normalizeDebugInfo(original.owner); } - if (debugInfo.awaited) { - debugInfo.awaited = normalizeIOInfo(debugInfo.awaited); + if (original.awaited) { + debugInfo.awaited = normalizeIOInfo(original.awaited); } if (debugInfo.props) { debugInfo.props = {}; @@ -90,8 +97,6 @@ function normalizeDebugInfo(original) { return debugInfo; } else if (typeof debugInfo.time === 'number') { return {...debugInfo, time: 0}; - } else if (debugInfo.awaited) { - return {...debugInfo, awaited: normalizeIOInfo(debugInfo.awaited)}; } else { return debugInfo; } @@ -242,9 +247,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 211, + 216, 109, - 191, + 196, 50, ], ], @@ -266,9 +271,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 211, + 216, 109, - 191, + 196, 50, ], ], @@ -277,25 +282,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 193, + 198, 13, - 192, + 197, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 200, + 205, 26, - 199, + 204, 5, ], ], @@ -314,9 +319,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 211, + 216, 109, - 191, + 196, 50, ], ], @@ -325,17 +330,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 193, + 198, 13, - 192, + 197, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 200, + 205, 26, - 199, + 204, 5, ], ], @@ -360,9 +365,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 211, + 216, 109, - 191, + 196, 50, ], ], @@ -371,25 +376,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 194, + 199, 21, - 192, + 197, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 200, + 205, 20, - 199, + 204, 5, ], ], @@ -408,9 +413,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 211, + 216, 109, - 191, + 196, 50, ], ], @@ -419,17 +424,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 195, + 200, 21, - 192, + 197, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 200, + 205, 20, - 199, + 204, 5, ], ], @@ -449,9 +454,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 202, + 207, 60, - 199, + 204, 5, ], ], @@ -473,9 +478,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 211, + 216, 109, - 191, + 196, 50, ], ], @@ -484,17 +489,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 194, + 199, 21, - 192, + 197, 5, ], ], @@ -513,9 +518,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 202, + 207, 60, - 199, + 204, 5, ], ], @@ -524,9 +529,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "InnerComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 208, + 213, 35, - 205, + 210, 5, ], ], @@ -537,6 +542,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -695,9 +712,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 659, + 676, 40, - 640, + 657, 49, ], [ @@ -727,9 +744,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 659, + 676, 40, - 640, + 657, 49, ], [ @@ -746,25 +763,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 642, + 659, 13, - 641, + 658, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 647, + 664, 36, - 646, + 663, 5, ], ], @@ -783,9 +800,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 659, + 676, 40, - 640, + 657, 49, ], [ @@ -802,17 +819,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 642, + 659, 13, - 641, + 658, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 647, + 664, 36, - 646, + 663, 5, ], ], @@ -832,9 +849,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 649, + 666, 60, - 646, + 663, 5, ], ], @@ -853,9 +870,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 659, + 676, 40, - 640, + 657, 49, ], [ @@ -872,25 +889,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 642, + 659, 13, - 641, + 658, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 648, + 665, 22, - 646, + 663, 5, ], ], @@ -909,9 +926,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 649, + 666, 60, - 646, + 663, 5, ], ], @@ -920,9 +937,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "InnerComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 655, + 672, 40, - 652, + 669, 5, ], ], @@ -933,6 +950,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -985,9 +1014,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 954, + 983, 109, - 941, + 970, 80, ], ], @@ -1006,9 +1035,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 954, + 983, 109, - 941, + 970, 80, ], ], @@ -1025,9 +1054,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 954, + 983, 109, - 941, + 970, 80, ], ], @@ -1039,6 +1068,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -1087,9 +1128,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1056, + 1097, 109, - 1047, + 1088, 94, ], ], @@ -1097,6 +1138,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -1160,9 +1213,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1129, + 1182, 109, - 1105, + 1158, 50, ], ], @@ -1188,6 +1241,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -1244,9 +1309,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1213, + 1278, 109, - 1196, + 1261, 63, ], ], @@ -1263,17 +1328,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 176, + 181, 40, - 174, + 179, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1209, + 1274, 24, - 1208, + 1273, 5, ], ], @@ -1295,17 +1360,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 176, + 181, 40, - 174, + 179, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1209, + 1274, 24, - 1208, + 1273, 5, ], ], @@ -1314,25 +1379,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1198, + 1263, 13, - 1197, + 1262, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1204, + 1269, 24, - 1203, + 1268, 5, ], ], @@ -1351,17 +1416,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 176, + 181, 40, - 174, + 179, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1209, + 1274, 24, - 1208, + 1273, 5, ], ], @@ -1370,17 +1435,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1198, + 1263, 13, - 1197, + 1262, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1204, + 1269, 24, - 1203, + 1268, 5, ], ], @@ -1405,17 +1470,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 176, + 181, 40, - 174, + 179, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1209, + 1274, 24, - 1208, + 1273, 5, ], ], @@ -1424,25 +1489,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1199, + 1264, 13, - 1197, + 1262, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1204, + 1269, 18, - 1203, + 1268, 5, ], ], @@ -1461,17 +1526,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 176, + 181, 40, - 174, + 179, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1209, + 1274, 24, - 1208, + 1273, 5, ], ], @@ -1480,17 +1545,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1199, + 1264, 13, - 1197, + 1262, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1204, + 1269, 18, - 1203, + 1268, 5, ], ], @@ -1501,9 +1566,32 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "start": 0, + "value": { + "value": "stream", + }, + }, + }, { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -1565,9 +1653,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1529, + 1617, 40, - 1512, + 1600, 62, ], [ @@ -1597,9 +1685,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1529, + 1617, 40, - 1512, + 1600, 62, ], [ @@ -1616,25 +1704,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1514, + 1602, 13, - 1513, + 1601, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1524, + 1612, 13, - 1523, + 1611, 5, ], ], @@ -1653,9 +1741,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1529, + 1617, 40, - 1512, + 1600, 62, ], [ @@ -1672,17 +1760,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1514, + 1602, 13, - 1513, + 1601, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1524, + 1612, 13, - 1523, + 1611, 5, ], ], @@ -1702,9 +1790,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1525, + 1613, 60, - 1523, + 1611, 5, ], ], @@ -1726,9 +1814,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1529, + 1617, 40, - 1512, + 1600, 62, ], [ @@ -1745,25 +1833,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1514, + 1602, 13, - 1513, + 1601, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1524, + 1612, 13, - 1523, + 1611, 5, ], ], @@ -1782,9 +1870,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1525, + 1613, 60, - 1523, + 1611, 5, ], ], @@ -1793,9 +1881,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Child", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1519, + 1607, 28, - 1518, + 1606, 5, ], ], @@ -1806,6 +1894,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -1866,9 +1966,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1830, + 1930, 40, - 1814, + 1914, 57, ], [ @@ -1898,9 +1998,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1830, + 1930, 40, - 1814, + 1914, 57, ], [ @@ -1917,25 +2017,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1816, + 1916, 13, - 1815, + 1915, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1825, + 1925, 23, - 1824, + 1924, 5, ], ], @@ -1954,9 +2054,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1830, + 1930, 40, - 1814, + 1914, 57, ], [ @@ -1973,17 +2073,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1816, + 1916, 13, - 1815, + 1915, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1825, + 1925, 23, - 1824, + 1924, 5, ], ], @@ -2003,9 +2103,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1826, + 1926, 60, - 1824, + 1924, 5, ], ], @@ -2024,9 +2124,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1830, + 1930, 40, - 1814, + 1914, 57, ], [ @@ -2043,25 +2143,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1816, + 1916, 13, - 1815, + 1915, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1825, + 1925, 23, - 1824, + 1924, 5, ], ], @@ -2075,9 +2175,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1826, + 1926, 60, - 1824, + 1924, 5, ], ], @@ -2088,6 +2188,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -2150,9 +2262,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2114, + 2226, 40, - 2096, + 2208, 80, ], [ @@ -2182,9 +2294,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2114, + 2226, 40, - 2096, + 2208, 80, ], [ @@ -2201,25 +2313,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2104, + 2216, 13, - 2102, + 2214, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2109, + 2221, 13, - 2108, + 2220, 5, ], ], @@ -2238,9 +2350,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2114, + 2226, 40, - 2096, + 2208, 80, ], [ @@ -2257,17 +2369,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2104, + 2216, 13, - 2102, + 2214, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2109, + 2221, 13, - 2108, + 2220, 5, ], ], @@ -2289,9 +2401,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2114, + 2226, 40, - 2096, + 2208, 80, ], [ @@ -2308,33 +2420,33 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2098, + 2210, 13, - 2097, + 2209, 5, ], [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2103, + 2215, 15, - 2102, + 2214, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2109, + 2221, 13, - 2108, + 2220, 5, ], ], @@ -2353,9 +2465,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2114, + 2226, 40, - 2096, + 2208, 80, ], [ @@ -2372,25 +2484,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2098, + 2210, 13, - 2097, + 2209, 5, ], [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2103, + 2215, 15, - 2102, + 2214, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2109, + 2221, 13, - 2108, + 2220, 5, ], ], @@ -2412,9 +2524,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2114, + 2226, 40, - 2096, + 2208, 80, ], [ @@ -2431,17 +2543,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2099, + 2211, 13, - 2097, + 2209, 5, ], ], @@ -2460,9 +2572,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2114, + 2226, 40, - 2096, + 2208, 80, ], [ @@ -2479,9 +2591,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2099, + 2211, 13, - 2097, + 2209, 5, ], ], @@ -2492,6 +2604,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -2542,9 +2666,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2511, + 2635, 109, - 2500, + 2624, 58, ], ], @@ -2566,9 +2690,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2511, + 2635, 109, - 2500, + 2624, 58, ], ], @@ -2577,25 +2701,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2502, + 2626, 14, - 2501, + 2625, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2508, + 2632, 20, - 2507, + 2631, 5, ], ], @@ -2614,9 +2738,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2511, + 2635, 109, - 2500, + 2624, 58, ], ], @@ -2625,17 +2749,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2502, + 2626, 23, - 2501, + 2625, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2508, + 2632, 20, - 2507, + 2631, 5, ], ], @@ -2646,6 +2770,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -2702,9 +2838,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2666, + 2802, 40, - 2654, + 2790, 56, ], [ @@ -2734,9 +2870,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2666, + 2802, 40, - 2654, + 2790, 56, ], [ @@ -2753,17 +2889,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 169, + 174, 12, - 168, + 173, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2662, + 2798, 20, - 2661, + 2797, 5, ], ], @@ -2782,9 +2918,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2666, + 2802, 40, - 2654, + 2790, 56, ], [ @@ -2801,9 +2937,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2662, + 2798, 20, - 2661, + 2797, 5, ], ], @@ -2814,6 +2950,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); } @@ -2884,9 +3032,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2843, + 2991, 40, - 2822, + 2970, 42, ], [ @@ -2916,9 +3064,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2843, + 2991, 40, - 2822, + 2970, 42, ], [ @@ -2935,17 +3083,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2829, + 2977, 15, - 2828, + 2976, 15, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2838, + 2986, 19, - 2837, + 2985, 5, ], ], @@ -2964,9 +3112,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2843, + 2991, 40, - 2822, + 2970, 42, ], [ @@ -2983,17 +3131,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2829, + 2977, 15, - 2828, + 2976, 15, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2838, + 2986, 19, - 2837, + 2985, 5, ], ], @@ -3015,9 +3163,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2843, + 2991, 40, - 2822, + 2970, 42, ], [ @@ -3034,9 +3182,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2838, + 2986, 25, - 2837, + 2985, 5, ], ], @@ -3055,9 +3203,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2843, + 2991, 40, - 2822, + 2970, 42, ], [ @@ -3074,9 +3222,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2838, + 2986, 25, - 2837, + 2985, 5, ], ], @@ -3087,6 +3235,18 @@ describe('ReactFlightAsyncDebugInfo', () => { { "time": 0, }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, ] `); }