Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion packages/react-client/src/ReactFlightClient.js
Original file line number Diff line number Diff line change
Expand Up @@ -2561,6 +2561,7 @@ function ResponseInstance(
findSourceMapURL: void | FindSourceMapURLCallback, // DEV-only
replayConsole: boolean, // DEV-only
environmentName: void | string, // DEV-only
debugStartTime: void | number, // DEV-only
debugChannel: void | DebugChannel, // DEV-only
) {
const chunks: Map<number, SomeChunk<any>> = new Map();
Expand Down Expand Up @@ -2621,7 +2622,8 @@ function ResponseInstance(
// 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._debugStartTime =
debugStartTime == null ? performance.now() : debugStartTime;
this._debugIOStarted = false;
// We consider everything before the first setTimeout task to be cached data
// and is not considered I/O required to load the stream.
Expand Down Expand Up @@ -2669,6 +2671,7 @@ export function createResponse(
findSourceMapURL: void | FindSourceMapURLCallback, // DEV-only
replayConsole: boolean, // DEV-only
environmentName: void | string, // DEV-only
debugStartTime: void | number, // DEV-only
debugChannel: void | DebugChannel, // DEV-only
): WeakResponse {
return getWeakResponse(
Expand All @@ -2684,6 +2687,7 @@ export function createResponse(
findSourceMapURL,
replayConsole,
environmentName,
debugStartTime,
debugChannel,
),
);
Expand Down
5 changes: 4 additions & 1 deletion packages/react-devtools-shared/src/backend/fiber/renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2862,7 +2862,10 @@ export function attach(
let parentInstance = reconcilingParent;
while (
parentInstance.kind === FILTERED_FIBER_INSTANCE &&
parentInstance.parent !== null
parentInstance.parent !== null &&
// We can't move past the parent Suspense node.
// The Suspense node holding async info must be a parent of the devtools instance (or the instance itself)
parentInstance !== parentSuspenseNode.instance
) {
parentInstance = parentInstance.parent;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function useInferredName(
const fetchFileWithCaching = useContext(FetchFileWithCachingContext);
const name = asyncInfo.awaited.name;
let inferNameFromStack = null;
if (!name || name === 'Promise') {
if (!name || name === 'Promise' || name === 'lazy') {
// If all we have is a generic name, we can try to infer a better name from
// the stack. We only do this if the stack has more than one frame since
// otherwise it's likely to just be the name of the component which isn't better.
Expand Down
3 changes: 3 additions & 0 deletions packages/react-markup/src/ReactMarkupServer.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,9 @@ export function experimental_renderToHTML(
undefined,
undefined,
false,
undefined,
undefined,
undefined,
);
const streamState = createFlightStreamState(flightResponse, null);
const flightDestination = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
};

function createDebugCallbackFromWritableStream(
Expand Down Expand Up @@ -103,6 +104,9 @@ function createResponseFromOptions(options: void | Options) {
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
// For the Node.js client we only support a single-direction debug channel.
debugChannel?: Readable,
};
Expand Down Expand Up @@ -112,6 +113,9 @@ function createFromNodeStream<T>(
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,9 @@ function createResponseFromOptions(options: void | Options) {
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);
}
Expand Down Expand Up @@ -205,6 +208,7 @@ export type Options = {
temporaryReferences?: TemporaryReferenceSet,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
};

export function createFromReadableStream<T>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export type Options = {
temporaryReferences?: TemporaryReferenceSet,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
// For the Edge client we only support a single-direction debug channel.
debugChannel?: {readable?: ReadableStream, ...},
};
Expand Down Expand Up @@ -107,6 +108,9 @@ function createResponseFromOptions(options?: Options) {
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export type Options = {
encodeFormAction?: EncodeFormActionCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
// For the Node.js client we only support a single-direction debug channel.
debugChannel?: Readable,
};
Expand Down Expand Up @@ -103,6 +104,9 @@ export function createFromNodeStream<T>(
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
};

function createDebugCallbackFromWritableStream(
Expand Down Expand Up @@ -102,6 +103,9 @@ function createResponseFromOptions(options: void | Options) {
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
// For the Edge client we only support a single-direction debug channel.
debugChannel?: {readable?: ReadableStream, ...},
};
Expand Down Expand Up @@ -109,6 +110,9 @@ function createResponseFromOptions(options: Options) {
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
// For the Node.js client we only support a single-direction debug channel.
debugChannel?: Readable,
};
Expand Down Expand Up @@ -114,6 +115,9 @@ function createFromNodeStream<T>(
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
};

function createDebugCallbackFromWritableStream(
Expand Down Expand Up @@ -102,6 +103,9 @@ function createResponseFromOptions(options: void | Options) {
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
// For the Edge client we only support a single-direction debug channel.
debugChannel?: {readable?: ReadableStream, ...},
};
Expand Down Expand Up @@ -109,6 +110,9 @@ function createResponseFromOptions(options: Options) {
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export type Options = {
findSourceMapURL?: FindSourceMapURLCallback,
replayConsoleLogs?: boolean,
environmentName?: string,
startTime?: number,
// For the Node.js client we only support a single-direction debug channel.
debugChannel?: Readable,
};
Expand Down Expand Up @@ -114,6 +115,9 @@ function createFromNodeStream<T>(
__DEV__ && options && options.environmentName
? options.environmentName
: undefined,
__DEV__ && options && options.startTime != null
? options.startTime
: undefined,
debugChannel,
);

Expand Down
31 changes: 21 additions & 10 deletions packages/react-server/src/ReactFlightServerConfigDebugNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,28 @@ export function initAsyncDebugInfo(): void {
}: UnresolvedPromiseNode);
}
} else if (
type !== 'Microtask' &&
type !== 'TickObject' &&
type !== 'Immediate'
// bound-anonymous-fn is the default name for snapshots and .bind() without a name.
// This isn't I/O by itself but likely just a continuation. If the bound function
// has a name, we might treat it as I/O but we can't tell the difference.
type === 'bound-anonymous-fn' ||
// queueMicroTask, process.nextTick and setImmediate aren't considered new I/O
// for our purposes but just continuation of existing I/O.
type === 'Microtask' ||
type === 'TickObject' ||
type === 'Immediate'
) {
// Treat the trigger as the node to carry along the sequence.
// For "bound-anonymous-fn" this will be the callsite of the .bind() which may not
// be the best if the callsite of the .run() call is within I/O which should be
// tracked. It might be better to track the execution context of "before()" as the
// execution context for anything spawned from within the run(). Basically as if
// it wasn't an AsyncResource at all.
if (trigger === undefined) {
return;
}
node = trigger;
} else {
// New I/O
if (trigger === undefined) {
// We have begun a new I/O sequence.
const owner = resolveOwner();
Expand Down Expand Up @@ -181,13 +199,6 @@ export function initAsyncDebugInfo(): void {
// Otherwise, this is just a continuation of the same I/O sequence.
node = trigger;
}
} else {
// Ignore nextTick and microtasks as they're not considered I/O operations.
// we just treat the trigger as the node to carry along the sequence.
if (trigger === undefined) {
return;
}
node = trigger;
}
pendingOperations.set(asyncId, node);
},
Expand Down
31 changes: 27 additions & 4 deletions packages/react/src/ReactLazy.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags';

import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';

import noop from 'shared/noop';

const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
Expand Down Expand Up @@ -67,12 +69,20 @@ export type LazyComponent<T, P> = {

function lazyInitializer<T>(payload: Payload<T>): T {
if (payload._status === Uninitialized) {
let resolveDebugValue: (void | T) => void = (null: any);
let rejectDebugValue: mixed => void = (null: any);
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Mark when we first kicked off the lazy request.
// $FlowFixMe[cannot-write]
ioInfo.start = ioInfo.end = performance.now();
// Stash a Promise for introspection of the value later.
// $FlowFixMe[cannot-write]
ioInfo.value = new Promise((resolve, reject) => {
resolveDebugValue = resolve;
rejectDebugValue = reject;
});
}
}
const ctor = payload._result;
Expand All @@ -92,12 +102,20 @@ function lazyInitializer<T>(payload: Payload<T>): T {
const resolved: ResolvedPayload<T> = (payload: any);
resolved._status = Resolved;
resolved._result = moduleObject;
if (__DEV__) {
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Mark the end time of when we resolved.
// $FlowFixMe[cannot-write]
ioInfo.end = performance.now();
// Surface the default export as the resolved "value" for debug purposes.
const debugValue =
moduleObject == null ? undefined : moduleObject.default;
resolveDebugValue(debugValue);
// $FlowFixMe
ioInfo.value.status = 'fulfilled';
// $FlowFixMe
ioInfo.value.value = debugValue;
}
// Make the thenable introspectable
if (thenable.status === undefined) {
Expand All @@ -124,6 +142,14 @@ function lazyInitializer<T>(payload: Payload<T>): T {
// Mark the end time of when we rejected.
// $FlowFixMe[cannot-write]
ioInfo.end = performance.now();
// Hide unhandled rejections.
// $FlowFixMe
ioInfo.value.then(noop, noop);
rejectDebugValue(error);
// $FlowFixMe
ioInfo.value.status = 'rejected';
// $FlowFixMe
ioInfo.value.reason = error;
}
// Make the thenable introspectable
if (thenable.status === undefined) {
Expand All @@ -139,9 +165,6 @@ function lazyInitializer<T>(payload: Payload<T>): T {
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Stash the thenable for introspection of the value later.
// $FlowFixMe[cannot-write]
ioInfo.value = thenable;
const displayName = thenable.displayName;
if (typeof displayName === 'string') {
// $FlowFixMe[cannot-write]
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/ReactIODescription.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export function getIODescription(value: mixed): string {
}
try {
switch (typeof value) {
case 'function':
return value.name || '';
case 'object':
// Test the object for a bunch of common property names that are useful identifiers.
// While we only have the return value here, it should ideally be a name that
Expand Down
Loading