@samitouri / QOS-React / commits / 2cfb221937

[Flight] Allow passing DEV only startTime as an option (#34912)

When you use the `createFromFetch` API we assume that the start time of the request is the same time as when you call `createFromFetch` but in principle you could use it with a Promise that starts earlier and just happens to resolve to a `Response`. When you use `createFromReadableStream` that is almost definitely the case. E.g. you might have started it way earlier and you don't call `createFromReadableStream` until you get the headers back (the fetch promise resolves). This adds an option to pass in the start time for debug purposes if you started the request before starting to parse it.

Sebastian Markbåge committed Oct 19, 2025 at 13:38 UTC 2cfb221937eac48209d01d5dda5664de473b1953
13 files changed +52 -1
packages/react-client/src/ReactFlightClient.js
+5 -1
@@ -2561,6 +2561,7 @@ function ResponseInstance(
2561 findSourceMapURL: void | FindSourceMapURLCallback, // DEV-only
2562 replayConsole: boolean, // DEV-only
2563 environmentName: void | string, // DEV-only
2564 + debugStartTime: void | number, // DEV-only
2565 debugChannel: void | DebugChannel, // DEV-only
2566 ) {
2567 const chunks: Map<number, SomeChunk<any>> = new Map();
@@ -2621,7 +2622,8 @@ function ResponseInstance(
2622 // Note: createFromFetch allows this to be marked at the start of the fetch
2623 // where as if you use createFromReadableStream from the body of the fetch
2624 // then the start time is when the headers resolved.
2624 - this._debugStartTime = performance.now();
2625 + this._debugStartTime =
2626 + debugStartTime == null ? performance.now() : debugStartTime;
2627 this._debugIOStarted = false;
2628 // We consider everything before the first setTimeout task to be cached data
2629 // and is not considered I/O required to load the stream.
@@ -2669,6 +2671,7 @@ export function createResponse(
2671 findSourceMapURL: void | FindSourceMapURLCallback, // DEV-only
2672 replayConsole: boolean, // DEV-only
2673 environmentName: void | string, // DEV-only
2674 + debugStartTime: void | number, // DEV-only
2675 debugChannel: void | DebugChannel, // DEV-only
2676 ): WeakResponse {
2677 return getWeakResponse(
@@ -2684,6 +2687,7 @@ export function createResponse(
2687 findSourceMapURL,
2688 replayConsole,
2689 environmentName,
2690 + debugStartTime,
2691 debugChannel,
2692 ),
2693 );
packages/react-markup/src/ReactMarkupServer.js
+3
@@ -91,6 +91,9 @@ export function experimental_renderToHTML(
91 undefined,
92 undefined,
93 false,
94 + undefined,
95 + undefined,
96 + undefined,
97 );
98 const streamState = createFlightStreamState(flightResponse, null);
99 const flightDestination = {
packages/react-server-dom-esm/src/client/ReactFlightDOMClientBrowser.js
+4
@@ -52,6 +52,7 @@ export type Options = {
52 findSourceMapURL?: FindSourceMapURLCallback,
53 replayConsoleLogs?: boolean,
54 environmentName?: string,
55 + startTime?: number,
56 };
57
58 function createDebugCallbackFromWritableStream(
@@ -103,6 +104,9 @@ function createResponseFromOptions(options: void | Options) {
104 __DEV__ && options && options.environmentName
105 ? options.environmentName
106 : undefined,
107 + __DEV__ && options && options.startTime != null
108 + ? options.startTime
109 + : undefined,
110 debugChannel,
111 );
112 }
packages/react-server-dom-esm/src/client/ReactFlightDOMClientNode.js
+4
@@ -57,6 +57,7 @@ export type Options = {
57 findSourceMapURL?: FindSourceMapURLCallback,
58 replayConsoleLogs?: boolean,
59 environmentName?: string,
60 + startTime?: number,
61 // For the Node.js client we only support a single-direction debug channel.
62 debugChannel?: Readable,
63 };
@@ -112,6 +113,9 @@ function createFromNodeStream<T>(
113 __DEV__ && options && options.environmentName
114 ? options.environmentName
115 : undefined,
116 + __DEV__ && options && options.startTime != null
117 + ? options.startTime
118 + : undefined,
119 debugChannel,
120 );
121
packages/react-server-dom-parcel/src/client/ReactFlightDOMClientBrowser.js
+4
@@ -129,6 +129,9 @@ function createResponseFromOptions(options: void | Options) {
129 __DEV__ && options && options.environmentName
130 ? options.environmentName
131 : undefined,
132 + __DEV__ && options && options.startTime != null
133 + ? options.startTime
134 + : undefined,
135 debugChannel,
136 );
137 }
@@ -205,6 +208,7 @@ export type Options = {
208 temporaryReferences?: TemporaryReferenceSet,
209 replayConsoleLogs?: boolean,
210 environmentName?: string,
211 + startTime?: number,
212 };
213
214 export function createFromReadableStream<T>(
packages/react-server-dom-parcel/src/client/ReactFlightDOMClientEdge.js
+4
@@ -79,6 +79,7 @@ export type Options = {
79 temporaryReferences?: TemporaryReferenceSet,
80 replayConsoleLogs?: boolean,
81 environmentName?: string,
82 + startTime?: number,
83 // For the Edge client we only support a single-direction debug channel.
84 debugChannel?: {readable?: ReadableStream, ...},
85 };
@@ -107,6 +108,9 @@ function createResponseFromOptions(options?: Options) {
108 __DEV__ && options && options.environmentName
109 ? options.environmentName
110 : undefined,
111 + __DEV__ && options && options.startTime != null
112 + ? options.startTime
113 + : undefined,
114 debugChannel,
115 );
116 }
packages/react-server-dom-parcel/src/client/ReactFlightDOMClientNode.js
+4
@@ -52,6 +52,7 @@ export type Options = {
52 encodeFormAction?: EncodeFormActionCallback,
53 replayConsoleLogs?: boolean,
54 environmentName?: string,
55 + startTime?: number,
56 // For the Node.js client we only support a single-direction debug channel.
57 debugChannel?: Readable,
58 };
@@ -103,6 +104,9 @@ export function createFromNodeStream<T>(
104 __DEV__ && options && options.environmentName
105 ? options.environmentName
106 : undefined,
107 + __DEV__ && options && options.startTime != null
108 + ? options.startTime
109 + : undefined,
110 debugChannel,
111 );
112
packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientBrowser.js
+4
@@ -51,6 +51,7 @@ export type Options = {
51 findSourceMapURL?: FindSourceMapURLCallback,
52 replayConsoleLogs?: boolean,
53 environmentName?: string,
54 + startTime?: number,
55 };
56
57 function createDebugCallbackFromWritableStream(
@@ -102,6 +103,9 @@ function createResponseFromOptions(options: void | Options) {
103 __DEV__ && options && options.environmentName
104 ? options.environmentName
105 : undefined,
106 + __DEV__ && options && options.startTime != null
107 + ? options.startTime
108 + : undefined,
109 debugChannel,
110 );
111 }
packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientEdge.js
+4
@@ -79,6 +79,7 @@ export type Options = {
79 findSourceMapURL?: FindSourceMapURLCallback,
80 replayConsoleLogs?: boolean,
81 environmentName?: string,
82 + startTime?: number,
83 // For the Edge client we only support a single-direction debug channel.
84 debugChannel?: {readable?: ReadableStream, ...},
85 };
@@ -109,6 +110,9 @@ function createResponseFromOptions(options: Options) {
110 __DEV__ && options && options.environmentName
111 ? options.environmentName
112 : undefined,
113 + __DEV__ && options && options.startTime != null
114 + ? options.startTime
115 + : undefined,
116 debugChannel,
117 );
118 }
packages/react-server-dom-turbopack/src/client/ReactFlightDOMClientNode.js
+4
@@ -60,6 +60,7 @@ export type Options = {
60 findSourceMapURL?: FindSourceMapURLCallback,
61 replayConsoleLogs?: boolean,
62 environmentName?: string,
63 + startTime?: number,
64 // For the Node.js client we only support a single-direction debug channel.
65 debugChannel?: Readable,
66 };
@@ -114,6 +115,9 @@ function createFromNodeStream<T>(
115 __DEV__ && options && options.environmentName
116 ? options.environmentName
117 : undefined,
118 + __DEV__ && options && options.startTime != null
119 + ? options.startTime
120 + : undefined,
121 debugChannel,
122 );
123
packages/react-server-dom-webpack/src/client/ReactFlightDOMClientBrowser.js
+4
@@ -51,6 +51,7 @@ export type Options = {
51 findSourceMapURL?: FindSourceMapURLCallback,
52 replayConsoleLogs?: boolean,
53 environmentName?: string,
54 + startTime?: number,
55 };
56
57 function createDebugCallbackFromWritableStream(
@@ -102,6 +103,9 @@ function createResponseFromOptions(options: void | Options) {
103 __DEV__ && options && options.environmentName
104 ? options.environmentName
105 : undefined,
106 + __DEV__ && options && options.startTime != null
107 + ? options.startTime
108 + : undefined,
109 debugChannel,
110 );
111 }
packages/react-server-dom-webpack/src/client/ReactFlightDOMClientEdge.js
+4
@@ -79,6 +79,7 @@ export type Options = {
79 findSourceMapURL?: FindSourceMapURLCallback,
80 replayConsoleLogs?: boolean,
81 environmentName?: string,
82 + startTime?: number,
83 // For the Edge client we only support a single-direction debug channel.
84 debugChannel?: {readable?: ReadableStream, ...},
85 };
@@ -109,6 +110,9 @@ function createResponseFromOptions(options: Options) {
110 __DEV__ && options && options.environmentName
111 ? options.environmentName
112 : undefined,
113 + __DEV__ && options && options.startTime != null
114 + ? options.startTime
115 + : undefined,
116 debugChannel,
117 );
118 }
packages/react-server-dom-webpack/src/client/ReactFlightDOMClientNode.js
+4
@@ -60,6 +60,7 @@ export type Options = {
60 findSourceMapURL?: FindSourceMapURLCallback,
61 replayConsoleLogs?: boolean,
62 environmentName?: string,
63 + startTime?: number,
64 // For the Node.js client we only support a single-direction debug channel.
65 debugChannel?: Readable,
66 };
@@ -114,6 +115,9 @@ function createFromNodeStream<T>(
115 __DEV__ && options && options.environmentName
116 ? options.environmentName
117 : undefined,
118 + __DEV__ && options && options.startTime != null
119 + ? options.startTime
120 + : undefined,
121 debugChannel,
122 );
123