mirror of
https://github.com/codeflash-ai/codeflash-internal.git
synced 2026-05-04 18:25:18 +00:00
## Summary - **Fix CI build failure**: Auth0Client crashes during Next.js prerendering when env vars aren't set. Returns a no-op stub (`getSession → null`) when domain is missing — semantically correct for static generation - **Lazy-load markdown libs (~260kb)**: ReactMarkdown, remarkGfm, and react-syntax-highlighter were eagerly imported in monaco-diff-viewer but only rendered when user expands "Generated Tests". Extracted into a dynamic component - **Parallelize repo detail query**: `getRepositoryById` ran the activity count sequentially after the repo lookup. Since `repoId` is already available, all three queries now run in parallel ## Test plan - [ ] CI `build` check passes (was failing since #2598) - [ ] Trace page still renders generated tests correctly when expanded - [ ] Repository detail page loads correctly with activity status
171 lines
5.3 KiB
TypeScript
171 lines
5.3 KiB
TypeScript
"use client"
|
|
|
|
import React from "react"
|
|
import { useRouter } from "next/navigation"
|
|
import { ArrowLeft, Zap, AlertTriangle } from "lucide-react"
|
|
import dynamic from "next/dynamic"
|
|
import { Skeleton } from "@/components/ui/skeleton"
|
|
|
|
const LineProfilerView = dynamic(
|
|
() => import("@/components/LineProfiler").then(mod => mod.LineProfilerView),
|
|
{
|
|
ssr: false,
|
|
loading: () => <Skeleton className="h-full w-full" />,
|
|
},
|
|
)
|
|
|
|
// Error boundary to gracefully handle parsing failures or rendering issues
|
|
interface ErrorBoundaryState {
|
|
hasError: boolean
|
|
error?: Error
|
|
}
|
|
|
|
class ProfilerErrorBoundary extends React.Component<
|
|
{ children: React.ReactNode; onRetry?: () => void },
|
|
ErrorBoundaryState
|
|
> {
|
|
constructor(props: { children: React.ReactNode; onRetry?: () => void }) {
|
|
super(props)
|
|
this.state = { hasError: false }
|
|
}
|
|
|
|
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
|
return { hasError: true, error }
|
|
}
|
|
|
|
componentDidCatch(error: Error, errorInfo: React.ErrorInfo) {
|
|
console.error("ProfilerErrorBoundary caught an error:", error, errorInfo)
|
|
}
|
|
|
|
render() {
|
|
if (this.state.hasError) {
|
|
return (
|
|
<div className="flex-1 flex items-center justify-center p-8">
|
|
<div className="text-center">
|
|
<AlertTriangle className="w-12 h-12 mx-auto mb-4 text-destructive" />
|
|
<h2 className="text-xl font-semibold mb-2">Failed to load profiler data</h2>
|
|
<p className="text-muted-foreground mb-4">
|
|
There was an error parsing or rendering the profiler data.
|
|
</p>
|
|
{this.props.onRetry && (
|
|
<button
|
|
onClick={() => {
|
|
this.setState({ hasError: false, error: undefined })
|
|
this.props.onRetry?.()
|
|
}}
|
|
className="px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
|
|
>
|
|
Try Again
|
|
</button>
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
return this.props.children
|
|
}
|
|
}
|
|
|
|
export interface ProfilerClientProps {
|
|
traceId: string
|
|
functionName: string | null
|
|
filePath: string | null
|
|
speedupX: number | null
|
|
originalLineProfiler?: string
|
|
optimizedLineProfiler?: string
|
|
originalRuntime?: string
|
|
bestRuntime?: string
|
|
}
|
|
|
|
export function ProfilerClient({
|
|
traceId,
|
|
functionName,
|
|
filePath,
|
|
speedupX,
|
|
originalLineProfiler,
|
|
optimizedLineProfiler,
|
|
originalRuntime,
|
|
bestRuntime,
|
|
}: ProfilerClientProps) {
|
|
const router = useRouter()
|
|
|
|
const handleBack = () => {
|
|
router.push(`/review-optimizations/${traceId}`)
|
|
}
|
|
|
|
const hasProfilerData = originalLineProfiler || optimizedLineProfiler
|
|
|
|
if (!hasProfilerData) {
|
|
return (
|
|
<div className="min-h-screen flex items-center justify-center p-4">
|
|
<div className="text-center">
|
|
<h2 className="text-2xl font-semibold mb-2">No Profiler Data</h2>
|
|
<p className="text-muted-foreground mb-4">
|
|
This optimization doesn't have line profiler data available.
|
|
</p>
|
|
<button
|
|
onClick={handleBack}
|
|
className="inline-flex items-center gap-2 px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90"
|
|
>
|
|
<ArrowLeft className="h-4 w-4" />
|
|
Go Back
|
|
</button>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background flex flex-col">
|
|
{/* Header */}
|
|
<div className="px-4 py-3 bg-muted/30 border-b border-border">
|
|
<div className="flex items-center justify-between">
|
|
<div className="flex items-center gap-4">
|
|
<button
|
|
onClick={handleBack}
|
|
className="p-2 hover:bg-muted rounded-md transition-colors"
|
|
title="Back to optimization details"
|
|
>
|
|
<ArrowLeft className="h-5 w-5" />
|
|
</button>
|
|
<div className="flex items-center gap-3">
|
|
<Zap className="w-6 h-6 text-primary" />
|
|
<h1 className="text-xl font-semibold">
|
|
Line Profiler Report
|
|
{functionName && (
|
|
<>
|
|
{" - "}
|
|
<code className="font-mono text-primary">{functionName}()</code>
|
|
</>
|
|
)}
|
|
</h1>
|
|
{speedupX && (
|
|
<span className="flex items-center gap-2 rounded-md bg-gradient-to-r from-primary to-yellow-500 px-3 py-1 text-xs font-bold text-gray-900">
|
|
<svg className="h-3.5 w-3.5" fill="currentColor" viewBox="0 0 24 24">
|
|
<path d="M13 10V3L4 14h7v7l9-11h-7z" />
|
|
</svg>
|
|
{speedupX.toFixed(2)}x faster
|
|
</span>
|
|
)}
|
|
</div>
|
|
</div>
|
|
|
|
{filePath && <span className="text-sm text-muted-foreground font-mono">{filePath}</span>}
|
|
</div>
|
|
</div>
|
|
|
|
{/* Line Profiler View */}
|
|
<div className="flex-1 overflow-hidden">
|
|
<ProfilerErrorBoundary>
|
|
<LineProfilerView
|
|
originalProfiler={originalLineProfiler}
|
|
optimizedProfiler={optimizedLineProfiler}
|
|
functionName={functionName || undefined}
|
|
originalRuntime={originalRuntime}
|
|
optimizedRuntime={bestRuntime}
|
|
/>
|
|
</ProfilerErrorBoundary>
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|