import {use, useContext, useDeferredValue} from 'react';
import type {ReactCallSite} from 'shared/ReactTypes';
import type {SourceMappedLocation} from 'react-devtools-shared/src/symbolicateSource';
import type {SerializedAsyncInfo} from 'react-devtools-shared/src/frontend/types';
import FetchFileWithCachingContext from './Components/FetchFileWithCachingContext';
import {symbolicateSourceWithCache} from 'react-devtools-shared/src/symbolicateSource';
export default function useInferredName(
asyncInfo: SerializedAsyncInfo,
): string {
const fetchFileWithCaching = useContext(FetchFileWithCachingContext);
const name = asyncInfo.awaited.name;
let inferNameFromStack = null;
if (!name || name === 'Promise' || name === 'lazy') {
const bestStack = asyncInfo.awaited.stack || asyncInfo.stack;
if (bestStack !== null && bestStack.length > 1) {
inferNameFromStack = bestStack;
}
}
const shouldSourceMap = useDeferredValue(inferNameFromStack !== null, false);
if (inferNameFromStack !== null) {
if (shouldSourceMap) {
let bestMatch = '';
for (let i = 0; i < inferNameFromStack.length; i++) {
const callSite: ReactCallSite = inferNameFromStack[i];
const [virtualFunctionName, virtualURL, virtualLine, virtualColumn] =
callSite;
const symbolicatedCallSite: null | SourceMappedLocation =
fetchFileWithCaching !== null
? use(
symbolicateSourceWithCache(
fetchFileWithCaching,
virtualURL,
virtualLine,
virtualColumn,
),
)
: null;
if (symbolicatedCallSite === null) {
if (bestMatch === '') {
return virtualFunctionName || name;
} else {
return bestMatch;
}
} else if (!symbolicatedCallSite.ignored) {
if (bestMatch === '') {
return symbolicatedCallSite[0] || virtualFunctionName || name;
} else {
return bestMatch;
}
} else {
bestMatch = symbolicatedCallSite[0] || virtualFunctionName;
}
}
return name;
} else {
return inferNameFromStack[0][0];
}
} else {
return name;
}
}