Introduces comprehensive request initiator visualization and JavaScript performance analysis capabilities. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
97 lines
2.6 KiB
TypeScript
97 lines
2.6 KiB
TypeScript
// Utility functions for formatting JavaScript performance data
|
|
|
|
export const formatDuration = (microseconds?: number): string => {
|
|
if (!microseconds || microseconds === 0) return '0ms'
|
|
|
|
const ms = microseconds / 1000
|
|
|
|
if (ms < 1) {
|
|
return `${microseconds.toFixed(0)}μs`
|
|
} else if (ms < 10) {
|
|
return `${ms.toFixed(2)}ms`
|
|
} else if (ms < 100) {
|
|
return `${ms.toFixed(1)}ms`
|
|
} else {
|
|
return `${ms.toFixed(0)}ms`
|
|
}
|
|
}
|
|
|
|
export const formatEventType = (eventName: string): string => {
|
|
switch (eventName) {
|
|
case 'EvaluateScript':
|
|
return 'Script Evaluation'
|
|
case 'v8.compile':
|
|
return 'Compilation'
|
|
case 'v8.callFunction':
|
|
return 'Function Call'
|
|
case 'v8.newInstance':
|
|
return 'Object Creation'
|
|
case 'V8.DeoptimizeAllOptimizedCodeWithFunction':
|
|
return 'Deoptimization'
|
|
case 'CpuProfiler::StartProfiling':
|
|
return 'Profiler Start'
|
|
case 'ScriptCatchup':
|
|
return 'Script Catchup'
|
|
default:
|
|
return eventName
|
|
}
|
|
}
|
|
|
|
export const getEventIcon = (eventName: string): string => {
|
|
switch (eventName) {
|
|
case 'EvaluateScript':
|
|
return '▶️'
|
|
case 'v8.compile':
|
|
return '⚙️'
|
|
case 'v8.callFunction':
|
|
return '📞'
|
|
case 'v8.newInstance':
|
|
return '🆕'
|
|
case 'V8.DeoptimizeAllOptimizedCodeWithFunction':
|
|
return '⚠️'
|
|
case 'CpuProfiler::StartProfiling':
|
|
return '📊'
|
|
case 'ScriptCatchup':
|
|
return '🔄'
|
|
default:
|
|
return '🔧'
|
|
}
|
|
}
|
|
|
|
export const truncateUrl = (url: string, maxLength: number = 80): string => {
|
|
if (!url || url.length <= maxLength) return url
|
|
|
|
// For file URLs, show the filename
|
|
if (url.includes('/')) {
|
|
const parts = url.split('/')
|
|
const filename = parts[parts.length - 1]
|
|
if (filename.length <= maxLength) {
|
|
return `.../${filename}`
|
|
}
|
|
}
|
|
|
|
// General truncation
|
|
return url.length > maxLength
|
|
? `${url.substring(0, maxLength - 3)}...`
|
|
: url
|
|
}
|
|
|
|
export const getScriptType = (event: { url?: string, isInlineScript: boolean }): string => {
|
|
if (event.isInlineScript) return 'Inline'
|
|
if (!event.url) return 'Unknown'
|
|
|
|
if (event.url.includes('.min.js')) return 'Minified'
|
|
if (event.url.includes('chunk') || event.url.includes('bundle')) return 'Bundle'
|
|
if (event.url.startsWith('chrome-extension://')) return 'Extension'
|
|
|
|
return 'External'
|
|
}
|
|
|
|
export const formatLocation = (lineNumber?: number, columnNumber?: number): string => {
|
|
if (lineNumber !== undefined && columnNumber !== undefined) {
|
|
return `${lineNumber}:${columnNumber}`
|
|
} else if (lineNumber !== undefined) {
|
|
return `Line ${lineNumber}`
|
|
}
|
|
return '-'
|
|
} |