diff --git a/compiler/scripts/release/publish.js b/compiler/scripts/release/publish.js index 99c47384251cc..4ff332d300a30 100755 --- a/compiler/scripts/release/publish.js +++ b/compiler/scripts/release/publish.js @@ -68,7 +68,7 @@ async function main() { .option('tag', { description: 'Tag to publish to npm', type: 'choices', - choices: ['experimental', 'beta', 'rc'], + choices: ['experimental', 'beta', 'rc', 'latest'], default: 'experimental', }) .option('tag-version', { @@ -145,10 +145,15 @@ async function main() { files: {exclude: ['.DS_Store']}, }); const truncatedHash = hash.slice(0, 7); - let newVersion = - argv.tagVersion == null || argv.tagVersion === '' - ? `${argv.versionName}-${argv.tag}` - : `${argv.versionName}-${argv.tag}.${argv.tagVersion}`; + let newVersion; + if (argv.tag === 'latest') { + newVersion = argv.versionName; + } else { + newVersion = + argv.tagVersion == null || argv.tagVersion === '' + ? `${argv.versionName}-${argv.tag}` + : `${argv.versionName}-${argv.tag}.${argv.tagVersion}`; + } if (argv.tag === 'experimental' || argv.tag === 'beta') { newVersion = `${newVersion}-${truncatedHash}-${dateString}`; } @@ -181,21 +186,9 @@ async function main() { if (otp != null) { opts.push(`--otp=${otp}`); } - /** - * Typically, the `latest` tag is reserved for stable package versions. Since the the compiler - * is still pre-release, until we have a stable release let's only add the - * `latest` tag to non-experimental releases. - * - * `latest` is added by default, so we only override it for experimental releases so that - * those don't get the `latest` tag. - * - * TODO: Update this when we have a stable release. - */ - if (argv.tag === 'experimental') { - opts.push('--tag=experimental'); - } else { - opts.push('--tag=latest'); - } + + opts.push(`--tag=${argv.tag}`); + try { await spawnHelper( 'npm', diff --git a/packages/react-server/src/ReactFlightServer.js b/packages/react-server/src/ReactFlightServer.js index d170787dc7997..546e1bbb64f08 100644 --- a/packages/react-server/src/ReactFlightServer.js +++ b/packages/react-server/src/ReactFlightServer.js @@ -849,6 +849,49 @@ export function resolveRequest(): null | Request { return null; } +function isTypedArray(value: any): boolean { + if (value instanceof ArrayBuffer) { + return true; + } + if (value instanceof Int8Array) { + return true; + } + if (value instanceof Uint8Array) { + return true; + } + if (value instanceof Uint8ClampedArray) { + return true; + } + if (value instanceof Int16Array) { + return true; + } + if (value instanceof Uint16Array) { + return true; + } + if (value instanceof Int32Array) { + return true; + } + if (value instanceof Uint32Array) { + return true; + } + if (value instanceof Float32Array) { + return true; + } + if (value instanceof Float64Array) { + return true; + } + if (value instanceof BigInt64Array) { + return true; + } + if (value instanceof BigUint64Array) { + return true; + } + if (value instanceof DataView) { + return true; + } + return false; +} + function serializeDebugThenable( request: Request, counter: {objectLimit: number}, @@ -906,6 +949,17 @@ function serializeDebugThenable( enqueueFlush(request); return; } + if ( + (isArray(value) && value.length > 200) || + (isTypedArray(value) && value.byteLength > 1000) + ) { + // If this should be deferred, but we don't have a debug channel installed + // it would get omitted. We can't omit outlined models but we can avoid + // resolving the Promise at all by halting it. + emitDebugHaltChunk(request, id); + enqueueFlush(request); + return; + } emitOutlinedDebugModelChunk(request, id, counter, value); enqueueFlush(request); }, @@ -3066,6 +3120,10 @@ function serializeDebugTypedArray( tag: string, typedArray: $ArrayBufferView, ): string { + if (typedArray.byteLength > 1000 && !doNotLimit.has(typedArray)) { + // Defer large typed arrays. + return serializeDeferredObject(request, typedArray); + } request.pendingDebugChunks++; const bufferId = request.nextChunkId++; emitTypedArrayChunk(request, bufferId, tag, typedArray, true); @@ -4820,9 +4878,17 @@ function renderDebugModel( } if (isArray(value)) { + if (value.length > 200 && !doNotLimit.has(value)) { + // Defer large arrays. They're heavy to serialize. + // TODO: Consider doing the same for objects with many properties too. + return serializeDeferredObject(request, value); + } return value; } + if (value instanceof Date) { + return serializeDate(value); + } if (value instanceof Map) { return serializeDebugMap(request, counter, value); } @@ -4930,15 +4996,6 @@ function renderDebugModel( } if (typeof value === 'string') { - if (value[value.length - 1] === 'Z') { - // Possibly a Date, whose toJSON automatically calls toISOString - // Make sure that `parent[parentPropertyName]` wasn't JSONified before `value` was passed to us - // $FlowFixMe[incompatible-use] - const originalValue = parent[parentPropertyName]; - if (originalValue instanceof Date) { - return serializeDateFromDateJSON(value); - } - } if (value.length >= 1024) { // Large strings are counted towards the object limit. if (counter.objectLimit <= 0) { @@ -5036,10 +5093,6 @@ function renderDebugModel( return serializeBigInt(value); } - if (value instanceof Date) { - return serializeDate(value); - } - return 'unknown type ' + typeof value; } @@ -5058,12 +5111,15 @@ function serializeDebugModel( value: ReactClientValue, ): ReactJSONValue { try { + // By-pass toJSON and use the original value. + // $FlowFixMe[incompatible-use] + const originalValue = this[parentPropertyName]; return renderDebugModel( request, counter, this, parentPropertyName, - value, + originalValue, ); } catch (x) { return ( @@ -5114,12 +5170,15 @@ function emitOutlinedDebugModelChunk( value: ReactClientValue, ): ReactJSONValue { try { + // By-pass toJSON and use the original value. + // $FlowFixMe[incompatible-use] + const originalValue = this[parentPropertyName]; return renderDebugModel( request, counter, this, parentPropertyName, - value, + originalValue, ); } catch (x) { return ( diff --git a/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js b/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js index b7d7959f21db3..9253371f54a69 100644 --- a/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js +++ b/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js @@ -5,6 +5,9 @@ import {patchSetImmediate} from '../../../../scripts/jest/patchSetImmediate'; +import fs from 'fs/promises'; +import path from 'path'; + let React; let ReactServer; let cache; @@ -156,9 +159,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 125, + 128, 109, - 105, + 108, 50, ], ], @@ -180,9 +183,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 125, + 128, 109, - 105, + 108, 50, ], ], @@ -191,25 +194,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 107, + 110, 13, - 106, + 109, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 114, + 117, 26, - 113, + 116, 5, ], ], @@ -228,9 +231,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 125, + 128, 109, - 105, + 108, 50, ], ], @@ -239,17 +242,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 107, + 110, 13, - 106, + 109, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 114, + 117, 26, - 113, + 116, 5, ], ], @@ -274,9 +277,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 125, + 128, 109, - 105, + 108, 50, ], ], @@ -285,25 +288,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 108, + 111, 21, - 106, + 109, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 114, + 117, 20, - 113, + 116, 5, ], ], @@ -322,9 +325,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 125, + 128, 109, - 105, + 108, 50, ], ], @@ -333,17 +336,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 109, + 112, 21, - 106, + 109, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 114, + 117, 20, - 113, + 116, 5, ], ], @@ -363,9 +366,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 116, + 119, 60, - 113, + 116, 5, ], ], @@ -387,9 +390,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 125, + 128, 109, - 105, + 108, 50, ], ], @@ -398,17 +401,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 108, + 111, 21, - 106, + 109, 5, ], ], @@ -427,9 +430,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 116, + 119, 60, - 113, + 116, 5, ], ], @@ -438,9 +441,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "InnerComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 122, + 125, 35, - 119, + 122, 5, ], ], @@ -621,9 +624,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 585, + 588, 40, - 566, + 569, 49, ], [ @@ -653,9 +656,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 585, + 588, 40, - 566, + 569, 49, ], [ @@ -672,25 +675,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 568, + 571, 13, - 567, + 570, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 573, + 576, 36, - 572, + 575, 5, ], ], @@ -709,9 +712,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 585, + 588, 40, - 566, + 569, 49, ], [ @@ -728,17 +731,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 568, + 571, 13, - 567, + 570, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 573, + 576, 36, - 572, + 575, 5, ], ], @@ -758,9 +761,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 575, + 578, 60, - 572, + 575, 5, ], ], @@ -779,9 +782,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 585, + 588, 40, - 566, + 569, 49, ], [ @@ -798,25 +801,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 568, + 571, 13, - 567, + 570, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 574, + 577, 22, - 572, + 575, 5, ], ], @@ -835,9 +838,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 575, + 578, 60, - 572, + 575, 5, ], ], @@ -846,9 +849,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "InnerComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 581, + 584, 40, - 578, + 581, 5, ], ], @@ -923,9 +926,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 892, + 895, 109, - 879, + 882, 80, ], ], @@ -944,9 +947,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 892, + 895, 109, - 879, + 882, 80, ], ], @@ -963,9 +966,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 892, + 895, 109, - 879, + 882, 80, ], ], @@ -1037,9 +1040,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1006, + 1009, 109, - 997, + 1000, 94, ], ], @@ -1122,9 +1125,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1091, + 1094, 109, - 1067, + 1070, 50, ], ], @@ -1218,9 +1221,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1187, + 1190, 109, - 1170, + 1173, 63, ], ], @@ -1237,17 +1240,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 90, + 93, 40, - 88, + 91, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1183, + 1186, 24, - 1182, + 1185, 5, ], ], @@ -1269,17 +1272,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 90, + 93, 40, - 88, + 91, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1183, + 1186, 24, - 1182, + 1185, 5, ], ], @@ -1288,25 +1291,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1172, + 1175, 13, - 1171, + 1174, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1178, + 1181, 24, - 1177, + 1180, 5, ], ], @@ -1325,17 +1328,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 90, + 93, 40, - 88, + 91, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1183, + 1186, 24, - 1182, + 1185, 5, ], ], @@ -1344,17 +1347,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1172, + 1175, 13, - 1171, + 1174, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1178, + 1181, 24, - 1177, + 1180, 5, ], ], @@ -1379,17 +1382,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 90, + 93, 40, - 88, + 91, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1183, + 1186, 24, - 1182, + 1185, 5, ], ], @@ -1398,25 +1401,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1173, + 1176, 13, - 1171, + 1174, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1178, + 1181, 18, - 1177, + 1180, 5, ], ], @@ -1435,17 +1438,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "fetchThirdParty", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 90, + 93, 40, - 88, + 91, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1183, + 1186, 24, - 1182, + 1185, 5, ], ], @@ -1454,17 +1457,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1173, + 1176, 13, - 1171, + 1174, 5, ], [ "ThirdPartyComponent", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1178, + 1181, 18, - 1177, + 1180, 5, ], ], @@ -1562,9 +1565,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1526, + 1529, 40, - 1509, + 1512, 62, ], [ @@ -1594,9 +1597,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1526, + 1529, 40, - 1509, + 1512, 62, ], [ @@ -1613,25 +1616,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1511, + 1514, 13, - 1510, + 1513, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1521, + 1524, 13, - 1520, + 1523, 5, ], ], @@ -1650,9 +1653,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1526, + 1529, 40, - 1509, + 1512, 62, ], [ @@ -1669,17 +1672,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1511, + 1514, 13, - 1510, + 1513, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1521, + 1524, 13, - 1520, + 1523, 5, ], ], @@ -1699,9 +1702,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1522, + 1525, 60, - 1520, + 1523, 5, ], ], @@ -1723,9 +1726,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1526, + 1529, 40, - 1509, + 1512, 62, ], [ @@ -1742,25 +1745,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1511, + 1514, 13, - 1510, + 1513, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1521, + 1524, 13, - 1520, + 1523, 5, ], ], @@ -1779,9 +1782,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1522, + 1525, 60, - 1520, + 1523, 5, ], ], @@ -1790,9 +1793,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Child", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1516, + 1519, 28, - 1515, + 1518, 5, ], ], @@ -1875,9 +1878,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1839, + 1842, 40, - 1823, + 1826, 57, ], [ @@ -1907,9 +1910,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1839, + 1842, 40, - 1823, + 1826, 57, ], [ @@ -1926,25 +1929,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1825, + 1828, 13, - 1824, + 1827, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1834, + 1837, 23, - 1833, + 1836, 5, ], ], @@ -1963,9 +1966,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1839, + 1842, 40, - 1823, + 1826, 57, ], [ @@ -1982,17 +1985,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1825, + 1828, 13, - 1824, + 1827, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1834, + 1837, 23, - 1833, + 1836, 5, ], ], @@ -2012,9 +2015,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1835, + 1838, 60, - 1833, + 1836, 5, ], ], @@ -2033,9 +2036,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1839, + 1842, 40, - 1823, + 1826, 57, ], [ @@ -2052,25 +2055,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1825, + 1828, 13, - 1824, + 1827, 25, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1834, + 1837, 23, - 1833, + 1836, 5, ], ], @@ -2084,9 +2087,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 1835, + 1838, 60, - 1833, + 1836, 5, ], ], @@ -2171,9 +2174,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2135, + 2138, 40, - 2117, + 2120, 80, ], [ @@ -2203,9 +2206,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2135, + 2138, 40, - 2117, + 2120, 80, ], [ @@ -2222,25 +2225,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2125, + 2128, 13, - 2123, + 2126, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2130, + 2133, 13, - 2129, + 2132, 5, ], ], @@ -2259,9 +2262,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2135, + 2138, 40, - 2117, + 2120, 80, ], [ @@ -2278,17 +2281,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2125, + 2128, 13, - 2123, + 2126, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2130, + 2133, 13, - 2129, + 2132, 5, ], ], @@ -2310,9 +2313,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2135, + 2138, 40, - 2117, + 2120, 80, ], [ @@ -2329,33 +2332,33 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2119, + 2122, 13, - 2118, + 2121, 5, ], [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2124, + 2127, 15, - 2123, + 2126, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2130, + 2133, 13, - 2129, + 2132, 5, ], ], @@ -2374,9 +2377,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2135, + 2138, 40, - 2117, + 2120, 80, ], [ @@ -2393,25 +2396,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2119, + 2122, 13, - 2118, + 2121, 5, ], [ "delayTrice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2124, + 2127, 15, - 2123, + 2126, 5, ], [ "Bar", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2130, + 2133, 13, - 2129, + 2132, 5, ], ], @@ -2433,9 +2436,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2135, + 2138, 40, - 2117, + 2120, 80, ], [ @@ -2452,17 +2455,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2120, + 2123, 13, - 2118, + 2121, 5, ], ], @@ -2481,9 +2484,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2135, + 2138, 40, - 2117, + 2120, 80, ], [ @@ -2500,9 +2503,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delayTwice", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2120, + 2123, 13, - 2118, + 2121, 5, ], ], @@ -2575,9 +2578,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2544, + 2547, 109, - 2533, + 2536, 58, ], ], @@ -2599,9 +2602,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2544, + 2547, 109, - 2533, + 2536, 58, ], ], @@ -2610,25 +2613,25 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2535, + 2538, 14, - 2534, + 2537, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2541, + 2544, 20, - 2540, + 2543, 5, ], ], @@ -2647,9 +2650,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2544, + 2547, 109, - 2533, + 2536, 58, ], ], @@ -2658,17 +2661,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "getData", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2535, + 2538, 23, - 2534, + 2537, 5, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2541, + 2544, 20, - 2540, + 2543, 5, ], ], @@ -2747,9 +2750,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2711, + 2714, 40, - 2699, + 2702, 56, ], [ @@ -2779,9 +2782,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2711, + 2714, 40, - 2699, + 2702, 56, ], [ @@ -2798,17 +2801,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "delay", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 83, + 86, 12, - 82, + 85, 3, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2707, + 2710, 20, - 2706, + 2709, 5, ], ], @@ -2827,9 +2830,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2711, + 2714, 40, - 2699, + 2702, 56, ], [ @@ -2846,9 +2849,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2707, + 2710, 20, - 2706, + 2709, 5, ], ], @@ -2941,9 +2944,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2900, + 2903, 40, - 2879, + 2882, 42, ], [ @@ -2973,9 +2976,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2900, + 2903, 40, - 2879, + 2882, 42, ], [ @@ -2992,17 +2995,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2886, + 2889, 15, - 2885, + 2888, 15, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2895, + 2898, 19, - 2894, + 2897, 5, ], ], @@ -3021,9 +3024,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2900, + 2903, 40, - 2879, + 2882, 42, ], [ @@ -3040,17 +3043,17 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2886, + 2889, 15, - 2885, + 2888, 15, ], [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2895, + 2898, 19, - 2894, + 2897, 5, ], ], @@ -3072,9 +3075,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2900, + 2903, 40, - 2879, + 2882, 42, ], [ @@ -3091,9 +3094,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2895, + 2898, 25, - 2894, + 2897, 5, ], ], @@ -3112,9 +3115,9 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Object.", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2900, + 2903, 40, - 2879, + 2882, 42, ], [ @@ -3131,9 +3134,154 @@ describe('ReactFlightAsyncDebugInfo', () => { [ "Component", "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", - 2895, + 2898, 25, - 2894, + 2897, + 5, + ], + ], + }, + { + "time": 0, + }, + { + "time": 0, + }, + { + "awaited": { + "byteSize": 0, + "end": 0, + "name": "RSC stream", + "owner": null, + "start": 0, + "value": { + "value": "stream", + }, + }, + }, + ] + `); + } + }); + + it('can track async file reads', async () => { + const filename = path.join(__dirname, 'test-file.txt'); + async function Component() { + const buffer = await fs + .readFile(filename) // This loads a Buffer. + // TODO: For some reason, without this we're extracting the wrong promise. + .then(v => v); + const text = buffer.toString('utf8'); + return text.slice(0, 26); + } + + const stream = ReactServerDOMServer.renderToPipeableStream( + , + {}, + ); + + const readable = new Stream.PassThrough(streamOptions); + + const result = ReactServerDOMClient.createFromNodeStream(readable, { + moduleMap: {}, + moduleLoading: {}, + }); + stream.pipe(readable); + + expect(await result).toBe('Lorem ipsum dolor sit amet'); + + await finishLoadingStream(readable); + if ( + __DEV__ && + gate( + flags => + flags.enableComponentPerformanceTrack && flags.enableAsyncDebugInfo, + ) + ) { + expect(getDebugInfo(result)).toMatchInlineSnapshot(` + [ + { + "time": 0, + }, + { + "env": "Server", + "key": null, + "name": "Component", + "props": {}, + "stack": [ + [ + "Object.", + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", + 3179, + 40, + 3167, + 36, + ], + ], + }, + { + "time": 0, + }, + { + "awaited": { + "end": 0, + "env": "Server", + "name": "Object.readFile", + "owner": { + "env": "Server", + "key": null, + "name": "Component", + "props": {}, + "stack": [ + [ + "Object.", + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", + 3179, + 40, + 3167, + 36, + ], + ], + }, + "stack": [ + [ + "Component", + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", + 3171, + 7, + 3169, + 5, + ], + ], + "start": 0, + "value": { + "status": "halted", + }, + }, + "env": "Server", + "owner": { + "env": "Server", + "key": null, + "name": "Component", + "props": {}, + "stack": [ + [ + "Object.", + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", + 3179, + 40, + 3167, + 36, + ], + ], + }, + "stack": [ + [ + "Component", + "/packages/react-server/src/__tests__/ReactFlightAsyncDebugInfo-test.js", + 3173, + 7, + 3169, 5, ], ], diff --git a/packages/react-server/src/__tests__/test-file.txt b/packages/react-server/src/__tests__/test-file.txt new file mode 100644 index 0000000000000..fb4f66d7e8769 --- /dev/null +++ b/packages/react-server/src/__tests__/test-file.txt @@ -0,0 +1,31 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed varius diam ut lectus suscipit, ac faucibus tellus fermentum. Phasellus rutrum bibendum tellus, eu malesuada metus dignissim sed. Pellentesque et quam libero. Donec ultricies massa vitae justo maximus, ultricies ultrices diam dictum. Ut in lectus non diam porttitor accumsan ac hendrerit tortor. Interdum et malesuada fames ac ante ipsum primis in faucibus. Donec a massa augue. Sed vitae purus id sapien luctus mattis. Maecenas imperdiet vehicula rhoncus. + +Etiam non tincidunt sapien, rhoncus fermentum ipsum. Cras id gravida felis. Phasellus finibus, mauris eu viverra auctor, augue tellus elementum sem, a vestibulum ligula purus vel erat. Nulla facilisi. Curabitur nulla ligula, viverra et elementum quis, sollicitudin sit amet nisl. Aenean vitae tortor mauris. Fusce iaculis risus eget lacus faucibus, quis congue dolor egestas. Integer viverra tellus tortor, vitae malesuada lorem ultricies vitae. Ut lacinia diam non ante pellentesque posuere. Suspendisse at posuere nunc, eget viverra elit. Vestibulum sit amet maximus lorem. + +Proin fermentum lacus non convallis gravida. Morbi a blandit nisi. Nam posuere lacus vitae molestie aliquam. Cras enim orci, elementum et urna vel, vehicula gravida neque. Etiam quis odio at odio aliquet lobortis ac et sapien. Nulla commodo, ante eget sodales facilisis, magna elit pretium odio, a consectetur dui tortor at erat. Morbi quis laoreet metus. Sed iaculis sodales nisi, ut pharetra magna laoreet eu. + +In iaculis, dolor quis consectetur fringilla, justo quam viverra turpis, eget dictum lectus nisl nec mi. Phasellus suscipit, leo ut tincidunt molestie, odio purus ornare ex, sagittis ornare erat nunc vel magna. Morbi malesuada risus nec turpis ultricies molestie dapibus nec justo. Vestibulum tempus bibendum purus, nec sodales libero convallis at. Fusce ipsum nibh, fringilla at sapien sit amet, malesuada suscipit lorem. Fusce et libero a dui gravida ultrices. Vestibulum quis lobortis velit. Morbi ut nisl lobortis, tempus sapien et, convallis mi. Integer varius, felis eu egestas dignissim, risus augue tristique elit, ultricies interdum arcu nibh et lectus. Integer enim mi, viverra eget scelerisque at, gravida eget justo. Nullam eget dolor id orci fringilla ultricies. In id luctus erat. Donec quis magna quis neque congue venenatis sit amet vel turpis. Donec congue tortor eu massa ullamcorper, ut imperdiet lectus posuere. Maecenas quis lorem quis nulla vehicula varius. + +Suspendisse tristique elit et luctus suscipit. Nunc quis justo luctus, malesuada velit vitae, accumsan tellus. Nunc ex sem, efficitur vitae semper et, consectetur quis turpis. Donec et tincidunt est, vitae varius sem. Aliquam at luctus dolor. Etiam pretium justo lectus, quis tempus quam feugiat ac. Suspendisse vitae sollicitudin erat, ut interdum felis. Cras lacinia tincidunt tempus. Vivamus congue et lectus quis suscipit. Fusce ultricies justo eget mi elementum, vitae consectetur lacus varius. Praesent fermentum in risus sit amet malesuada. Mauris semper sapien ornare pulvinar venenatis. Suspendisse potenti. + +Donec vestibulum purus et est cursus hendrerit. Vivamus pharetra ligula dolor, ut commodo felis accumsan sed. Integer pulvinar mollis metus, at cursus turpis laoreet ac. Maecenas lectus felis, dapibus eu ligula at, lacinia pharetra ex. Duis id tortor a metus pulvinar tincidunt. Suspendisse at lacus a nulla feugiat malesuada. Ut tincidunt interdum placerat. Fusce tincidunt elit in convallis elementum. Etiam commodo felis ut neque dapibus, ac finibus ante auctor. Sed tincidunt massa vitae sapien semper suscipit. + +Donec euismod sagittis lacus, eu lacinia tortor rutrum eu. Donec et sapien lacus. Aliquam non commodo magna, vitae commodo tortor. Vivamus vel urna eget ante varius condimentum. Etiam non purus pharetra, pharetra sem eu, maximus felis. Integer nec urna justo. Etiam a dolor tempor, posuere odio non, maximus metus. Vivamus malesuada mi libero, a viverra velit tempus vitae. Quisque accumsan sed nisi a venenatis. Donec malesuada erat at lacus tincidunt, sed euismod est ultricies. Fusce id posuere nisl. Aliquam erat volutpat. Morbi non erat iaculis turpis interdum facilisis. Nunc risus elit, laoreet quis ante sed, aliquam pharetra massa. Fusce cursus urna nec pharetra interdum. + +Etiam pharetra, metus nec malesuada efficitur, dui ipsum blandit felis, id cursus elit orci at eros. Phasellus suscipit lobortis est. Praesent egestas, est et scelerisque consectetur, neque velit dapibus elit, quis hendrerit nisi felis a nulla. Quisque facilisis rutrum varius. Integer quis libero sit amet erat tincidunt semper a vel quam. Curabitur rutrum fringilla consequat. Fusce in metus ut odio luctus viverra viverra et nulla. Vestibulum a lacinia augue, feugiat egestas diam. Proin elit arcu, venenatis quis elementum in, rutrum quis tortor. Integer vel lacus urna. Suspendisse pharetra sapien at ullamcorper hendrerit. Etiam nibh ipsum, vulputate eu pulvinar nec, pulvinar id odio. + +Proin tincidunt, augue id tristique dictum, nisi sem congue orci, non faucibus erat nibh ac metus. Curabitur leo massa, hendrerit a venenatis sed, aliquam ac ligula. Fusce facilisis vulputate dui ut sollicitudin. Phasellus tellus lacus, viverra at dui sit amet, facilisis accumsan nisi. Phasellus dui lectus, lobortis consequat convallis sed, luctus non dui. Duis tempus urna sed libero ullamcorper, placerat luctus enim dignissim. Mauris vitae odio mauris. Donec eget tortor vitae nibh laoreet viverra at eget urna. Integer in ex arcu. Vestibulum tellus erat, tempus sit amet neque nec, tristique maximus neque. Vivamus efficitur nisi massa, ut tempus lacus interdum quis. Cras posuere erat nec convallis viverra. Aenean efficitur nibh et augue maximus pretium. Aliquam hendrerit nulla dui. Donec elit enim, hendrerit ultricies orci sed, blandit elementum quam. + +Donec fringilla pretium ligula, sed imperdiet orci mattis quis. Mauris ullamcorper fermentum libero fringilla molestie. Sed laoreet, nisl in viverra convallis, enim tortor tincidunt elit, in consequat diam metus non libero. Quisque eleifend lobortis lobortis. Donec porta eget justo faucibus sagittis. Phasellus lacus diam, convallis tristique metus at, placerat luctus justo. Fusce vestibulum urna eget dictum vulputate. Nam non nisl bibendum risus vehicula rutrum nec vel purus. Morbi nec diam laoreet quam sodales malesuada. Suspendisse efficitur, magna vel sodales semper, neque nulla aliquam nisi, hendrerit mollis justo libero vel mi. + +Etiam tellus neque, vulputate quis justo sit amet, dapibus suscipit est. Morbi pulvinar ipsum risus, eu lacinia felis viverra eget. Quisque massa justo, aliquam non ornare sit amet, maximus maximus dui. Pellentesque aliquam fermentum libero sed aliquet. Nulla consequat ultrices commodo. Donec condimentum consectetur nulla, id euismod metus facilisis eget. Fusce at mauris blandit, mollis ex nec, dignissim ex. Proin nec facilisis arcu. In vestibulum at erat vel ultrices. Mauris lacinia elementum nibh rhoncus egestas. Duis lobortis magna eget sem consequat, ac malesuada orci gravida. Duis cursus quam augue, a condimentum velit scelerisque eget. Donec dapibus pellentesque tellus. Nulla malesuada, purus id efficitur volutpat, felis odio faucibus metus, scelerisque hendrerit enim velit in urna. + +Nulla massa felis, semper eget consectetur ac, scelerisque vitae mi. Praesent sit amet sagittis metus. Curabitur mollis ex quis erat faucibus mattis. Nullam risus lacus, suscipit sed luctus vel, dictum id odio. In et dictum elit. Aliquam quis consectetur metus. In feugiat, urna ac porttitor auctor, est arcu porta est, vel lobortis erat elit quis nunc. Nulla quis nibh vel sem fringilla semper sed quis ipsum. Morbi vehicula, urna non rhoncus hendrerit, velit purus accumsan purus, vel elementum arcu dui sit amet leo. Aenean ultricies orci ac ante placerat, id auctor magna sodales. Nam sit amet laoreet lectus. Etiam ligula velit, dignissim vel tincidunt at, dictum nec lacus. Nam non eleifend enim, sit amet dictum lectus. Suspendisse potenti. Suspendisse eget ante a mauris placerat lobortis sed eu dui. + +Nam et porta elit, vel interdum mauris. Vivamus eu elit nec nisl bibendum hendrerit. Morbi ornare mollis lacus non finibus. Praesent id orci ex. Donec commodo viverra dictum. Phasellus in lacus tellus. Curabitur at lorem efficitur leo dignissim varius at eu est. Vivamus justo erat, hendrerit id volutpat nec, euismod eget odio. Mauris et vulputate tellus, in maximus nunc. Vestibulum ante ligula, suscipit nec nibh in, placerat pellentesque neque. + +Nunc in accumsan ligula, quis accumsan diam. Fusce tincidunt neque a turpis ornare, id convallis quam convallis. Donec at luctus ipsum. Nam id enim ante. Fusce condimentum consectetur justo, in hendrerit lacus vehicula ut. Vestibulum ut hendrerit risus. Donec blandit ut magna eget aliquet. Donec sit amet faucibus ante. Suspendisse condimentum, mauris id aliquam ultricies, erat mi tincidunt eros, sit amet blandit urna purus vitae orci. Maecenas in faucibus ipsum, quis gravida ex. Sed tincidunt in ipsum id dignissim. Duis dui nisl, interdum at est non, rutrum porttitor felis. Sed at nibh dolor. Etiam cursus scelerisque leo. + +Morbi vel arcu ullamcorper, tristique eros sed, condimentum sapien. Duis suscipit consequat tincidunt. Proin commodo erat in velit cursus lobortis. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Pellentesque id metus luctus, commodo sapien iaculis, pharetra massa. Phasellus fringilla sagittis lacus, ac laoreet massa sollicitudin ac. Aliquam luctus ex non semper dictum. Morbi vel arcu vel purus aliquet tempus. Curabitur ultrices rutrum facilisis. Morbi enim lectus, ornare quis sem bibendum, aliquet imperdiet ex. Vestibulum commodo sed neque et fermentum. Vestibulum enim elit, lobortis vitae convallis ut, auctor in velit. + +Vestibulum semper vulputate elit, at volutpat quam. Nullam id scelerisque libero, nec facilisis lacus. Nulla quis rhoncus arcu. Aliquam erat volutpat. In viverra, diam id rutrum volutpat, ligula dui tristique ex, et pulvinar elit ex a est. Cras magna augue, porta vel tempus vitae, placerat et felis. In ex elit, mattis vitae molestie pretium, tempus vitae tortor. Integer vehicula orci magna, in ultrices nulla volutpat sit amet. Pellentesque odio erat, hendrerit at lacinia sit amet, tempus sit amet risus. Curabitur ut laoreet justo, nec fermentum nibh. Integer tincidunt mattis sem eu cursus.