{"version":3,"sources":["../src/Overlay.tsx"],"sourcesContent":["'use client';\n\n/**\n * @file Overlay.tsx\n * @description Development-only floating UI overlay for the API Visual Debugger.\n *\n * - Returns null immediately in production (process.env.NODE_ENV !== 'development').\n * - Reads config.position from the store to dynamically position badge + panel.\n * - Shows a compact floating badge (active/total count) that expands into a\n *   tabbed detail panel (All / Pending / Success / Error).\n * - Each request row expands to show full URL, timing, and formatted call stack.\n *\n * SSR Bridge (added):\n * - Polls GET /api/dev/api-debugger every 1 000 ms to fetch SSR request logs.\n * - Merges SSR + Client requests into a single sorted list (newest first).\n * - \"Clear\" now also sends DELETE /api/dev/api-debugger to wipe the server cache.\n * - Footer shows per-environment breakdown (SSR / Client counts).\n */\n\nimport { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react';\n\nimport { useApiDebuggerStore } from './store';\nimport { extractTrigger, formatStackFrames, parseStackTrace } from './utils';\n\nimport type { ApiRequest, ApiRequestStatus } from './types';\n\n// ─── Constants ────────────────────────────────────────────────────────────────\n\nconst METHOD_COLORS: Record<string, string> = {\n  GET: 'bg-sky-500/20 text-sky-300 border border-sky-500/30',\n  POST: 'bg-emerald-500/20 text-emerald-300 border border-emerald-500/30',\n  PUT: 'bg-amber-500/20 text-amber-300 border border-amber-500/30',\n  PATCH: 'bg-violet-500/20 text-violet-300 border border-violet-500/30',\n  DELETE: 'bg-rose-500/20 text-rose-300 border border-rose-500/30',\n  HEAD: 'bg-slate-500/20 text-slate-300 border border-slate-500/30',\n};\n\nconst STATUS_COLORS: Record<ApiRequestStatus, string> = {\n  pending: 'text-amber-400',\n  success: 'text-emerald-400',\n  error: 'text-rose-400',\n};\n\nconst STATUS_ICONS: Record<ApiRequestStatus, string> = {\n  pending: '⏳',\n  success: '✓',\n  error: '✕',\n};\n\n/** Polling interval in milliseconds for fetching SSR requests from the server. */\nconst SSR_POLL_INTERVAL_MS = 1_000;\n\ntype FilterTab = 'all' | ApiRequestStatus;\n\n// ─── Sub-components ───────────────────────────────────────────────────────────\n\nfunction MethodBadge({ method }: { method: string }) {\n  const cls =\n    METHOD_COLORS[method.toUpperCase()] ??\n    'bg-slate-500/20 text-slate-300 border border-slate-500/30';\n  return (\n    <span\n      className={`\n        inline-flex items-center rounded-sm px-1.5 py-0.5 font-mono text-[10px] leading-none font-bold\n        ${cls}\n      `}\n    >\n      {method.toUpperCase()}\n    </span>\n  );\n}\n\nfunction EnvPill({ env }: { env: 'SSR' | 'Client' }) {\n  return (\n    <span\n      className={`\n        inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] leading-none font-semibold\n        ${\n          env === 'SSR'\n            ? 'border border-purple-500/30 bg-purple-500/20 text-purple-300'\n            : 'text-cyan-300 border border-cyan-500/30 bg-cyan-500/20'\n        }\n      `}\n    >\n      {env}\n    </span>\n  );\n}\n\nfunction PulsingDot() {\n  return (\n    <span className=\"relative flex size-2\">\n      <span className=\"bg-amber-400 absolute inline-flex size-full animate-ping rounded-full opacity-75\" />\n      <span className=\"bg-amber-400 relative inline-flex size-2 rounded-full\" />\n    </span>\n  );\n}\n\nconst RequestRow = memo(function RequestRow({ req }: { req: ApiRequest }) {\n  const [expanded, setExpanded] = useState(false);\n\n  const shortUrl = useMemo(() => {\n    try {\n      const u = new URL(req.url);\n      return (\n        u.pathname +\n        (u.search\n          ? u.search.slice(0, 40) + (u.search.length > 40 ? '…' : '')\n          : '')\n      );\n    } catch {\n      return req.url;\n    }\n  }, [req.url]);\n\n  // ── Lazy stack parsing ─────────────────────────────────────────────────────\n  // The interceptor deliberately does **not** run `parseStackTrace` /\n  // `extractTrigger` synchronously on the request hot path — those regex\n  // walks are one of the primary contributors to main-thread stalls under\n  // heavy concurrent load. Instead we parse here at render time, and only\n  // once per RequestRow (which is `memo`'d on `req`, and `req` objects are\n  // immutable after `updateRequest` patches them once).\n  const stackFrames = useMemo(\n    () => req.stackFrames ?? parseStackTrace(req.stackTrace),\n    [req.stackFrames, req.stackTrace],\n  );\n\n  const trigger = useMemo(\n    () => req.trigger ?? extractTrigger(req.stackTrace),\n    [req.trigger, req.stackTrace],\n  );\n\n  const formattedStack = useMemo(\n    () =>\n      stackFrames.length > 0\n        ? formatStackFrames(stackFrames)\n        : req.stackTrace,\n    [stackFrames, req.stackTrace],\n  );\n\n  return (\n    <div\n      className=\"\n        border-b border-white/5\n        last:border-0\n      \"\n    >\n      {/* Row summary */}\n      <button\n        type=\"button\"\n        className=\"\n          flex w-full items-start gap-2 px-3 py-2.5 text-left transition-colors\n          hover:bg-white/5\n          active:bg-white/10\n        \"\n        onClick={() => setExpanded((v) => !v)}\n      >\n        {/* Status icon */}\n        <span\n          className={`\n            mt-px shrink-0 text-xs font-bold\n            ${STATUS_COLORS[req.status]}\n          `}\n        >\n          {STATUS_ICONS[req.status]}\n        </span>\n\n        {/* Method + URL */}\n        <div className=\"min-w-0 flex-1 space-y-1\">\n          <div className=\"flex flex-wrap items-center gap-1.5\">\n            <MethodBadge method={req.method} />\n            <EnvPill env={req.environment} />\n            {req.statusCode !== null && (\n              <span\n                className={`\n                  font-mono text-[10px] font-semibold\n                  ${\n                    req.statusCode >= 400 ? 'text-rose-400' : 'text-emerald-400'\n                  }\n                `}\n              >\n                {req.statusCode}\n              </span>\n            )}\n            {req.duration !== null && (\n              <span className=\"text-slate-400 font-mono text-[10px]\">\n                {req.duration}ms\n              </span>\n            )}\n          </div>\n          <p className=\"text-slate-300 truncate font-mono text-[11px]\">\n            {shortUrl}\n          </p>\n          {trigger && trigger !== 'Unknown' && (\n            <p className=\"text-indigo-400 font-mono text-[9px] mt-0.5\">⚡ {trigger}</p>\n          )}\n        </div>\n\n        {/* Expand chevron */}\n        <span\n          aria-hidden\n          className={`\n            text-slate-500 mt-0.5 shrink-0 transition-transform duration-200\n            ${expanded ? 'rotate-180' : ''}\n          `}\n        >\n          ▾\n        </span>\n      </button>\n\n      {/* Expanded detail */}\n      {expanded && (\n        <div className=\"space-y-2 border-t border-white/5 bg-black/30 px-3 py-2.5\">\n          {/* Full URL */}\n          <div>\n            <p className=\"text-slate-500 mb-1 text-[9px] font-semibold tracking-widest uppercase\">\n              Full URL\n            </p>\n            <p className=\"text-slate-300 font-mono text-[10px] break-all\">\n              {req.url}\n            </p>\n          </div>\n\n          {/* Timing */}\n          <div className=\"flex gap-4\">\n            <div>\n              <p className=\"text-slate-500 mb-0.5 text-[9px] font-semibold tracking-widest uppercase\">\n                Started\n              </p>\n              <p className=\"text-slate-300 font-mono text-[10px]\">\n                {new Date(req.startedAt).toLocaleTimeString([], {\n                  hour12: false,\n                })}\n              </p>\n            </div>\n            {req.duration !== null && (\n              <div>\n                <p className=\"text-slate-500 mb-0.5 text-[9px] font-semibold tracking-widest uppercase\">\n                  Duration\n                </p>\n                <p className=\"text-slate-300 font-mono text-[10px]\">\n                  {req.duration}ms\n                </p>\n              </div>\n            )}\n          </div>\n\n          {/* Call stack */}\n          {formattedStack && (\n            <div>\n              <p className=\"text-slate-500 mb-1 text-[9px] font-semibold tracking-widest uppercase\">\n                Call Stack\n              </p>\n              <pre className=\"text-emerald-300/80 overflow-x-auto rounded-sm bg-black/50 p-2 font-mono text-[10px] leading-relaxed ring-1 ring-white/5\">\n                {formattedStack}\n              </pre>\n            </div>\n          )}\n        </div>\n      )}\n    </div>\n  );\n});\n\n// ─── Main Component ───────────────────────────────────────────────────────────\n\n/**\n * The top-level overlay component. Renders null in production.\n * Mount once in your root layout (e.g. app/[locale]/layout.tsx).\n */\nexport function ApiDebuggerOverlay() {\n  return <ApiDebuggerInner />;\n}\n\n// ─── Inner Component (only rendered in dev) ───────────────────────────────────\n\nfunction ApiDebuggerInner() {\n  const requests = useApiDebuggerStore((s) => s.requests);\n  const ssrRequests = useApiDebuggerStore((s) => s.ssrRequests);\n  const setSsrRequests = useApiDebuggerStore((s) => s.setSsrRequests);\n  const clearRequests = useApiDebuggerStore((s) => s.clearRequests);\n  const enabled = useApiDebuggerStore((s) => s.config.enabled);\n\n  const [isOpen, setIsOpen] = useState(false);\n  const [filter, setFilter] = useState<FilterTab>('all');\n  const [isMounted, setIsMounted] = useState(false);\n\n  useEffect(() => setIsMounted(true), []);\n\n  // ── Drag state ──────────────────────────────────────────────────────────────\n  // Initial position: left-middle of the screen (left: 16px, top: 50vh).\n  const [pos, setPos] = useState<{ x: number; y: number }>(() => ({\n    x: 16,\n    y: typeof window !== 'undefined' ? window.innerHeight / 2 : 300,\n  }));\n  const isDragging = useRef(false);\n  const dragOffset = useRef({ x: 0, y: 0 });\n  // Store exact mousedown coords so we can measure true travel distance.\n  const dragStart = useRef({ x: 0, y: 0 });\n  // Only flipped true once travel distance exceeds DRAG_THRESHOLD px.\n  const hasDragged = useRef(false);\n  const DRAG_THRESHOLD = 3; // px\n\n  const handleMouseDown = useCallback(\n    (e: React.MouseEvent<HTMLButtonElement>) => {\n      // Only primary button.\n      if (e.button !== 0) return;\n      isDragging.current = true;\n      hasDragged.current = false;\n      dragStart.current = { x: e.clientX, y: e.clientY };\n      dragOffset.current = { x: e.clientX - pos.x, y: e.clientY - pos.y };\n\n      const onMouseMove = (ev: MouseEvent) => {\n        if (!isDragging.current) return;\n        const dx = ev.clientX - dragStart.current.x;\n        const dy = ev.clientY - dragStart.current.y;\n        // Upgrade to \"drag\" only once we've moved beyond the dead-zone.\n        if (!hasDragged.current && Math.sqrt(dx * dx + dy * dy) > DRAG_THRESHOLD) {\n          hasDragged.current = true;\n        }\n        if (hasDragged.current) {\n          setPos({\n            x: ev.clientX - dragOffset.current.x,\n            y: ev.clientY - dragOffset.current.y,\n          });\n        }\n      };\n\n      const onMouseUp = () => {\n        isDragging.current = false;\n        window.removeEventListener('mousemove', onMouseMove);\n        window.removeEventListener('mouseup', onMouseUp);\n      };\n\n      window.addEventListener('mousemove', onMouseMove);\n      window.addEventListener('mouseup', onMouseUp);\n\n      // Prevent text selection while dragging.\n      e.preventDefault();\n    },\n    [pos.x, pos.y],\n  );\n\n  const handleBadgeClick = useCallback(() => {\n    // If the pointer travelled beyond the threshold this was a drag — ignore.\n    if (hasDragged.current) return;\n    setIsOpen((v) => !v);\n  }, []);\n\n  // ── SSR polling effect ──────────────────────────────────────────────────────\n  useEffect(() => {\n    async function pollSsrRequests() {\n      // Skip polling when the tab is backgrounded. Complex host pages (e.g.\n      // Checkout) can spend long stretches hidden while the user is on other\n      // tabs; polling in that state just spams the network panel and burns\n      // CPU on the eventual re-render. Fetching resumes on the next interval\n      // tick once the tab is visible again.\n      if (typeof document !== 'undefined' && document.hidden) return;\n\n      try {\n        const res = await fetch('/api/dev/api-debugger', { cache: 'no-store' });\n        if (res.ok) {\n          const data = await res.json();\n          setSsrRequests(data);\n        }\n      } catch {\n        // Swallow errors silently — the overlay should never break the app.\n      }\n    }\n\n    // Run once immediately, then on each interval tick.\n    pollSsrRequests();\n    const intervalId = setInterval(pollSsrRequests, SSR_POLL_INTERVAL_MS);\n\n    return () => clearInterval(intervalId);\n  }, [setSsrRequests]);\n\n  // ── Merged request list (Client + SSR), sorted newest first ─────────────────\n  const mergedRequests = useMemo<ApiRequest[]>(() => {\n    return [...requests, ...ssrRequests].sort(\n      (a, b) => b.startedAt - a.startedAt,\n    );\n  }, [requests, ssrRequests]);\n\n  // ── Derived counts ──────────────────────────────────────────────────────────\n  const activeCount = useMemo(\n    () => mergedRequests.filter((r) => r.status === 'pending').length,\n    [mergedRequests],\n  );\n  const totalCount = mergedRequests.length;\n  const pendingCount = activeCount;\n\n  const successCount = useMemo(\n    () => mergedRequests.filter((r) => r.status === 'success').length,\n    [mergedRequests],\n  );\n\n  const errorCount = useMemo(\n    () => mergedRequests.filter((r) => r.status === 'error').length,\n    [mergedRequests],\n  );\n\n  const ssrCount = useMemo(\n    () => mergedRequests.filter((r) => r.environment === 'SSR').length,\n    [mergedRequests],\n  );\n\n  const clientCount = useMemo(\n    () => mergedRequests.filter((r) => r.environment === 'Client').length,\n    [mergedRequests],\n  );\n\n  const filtered = useMemo(\n    () =>\n      filter === 'all'\n        ? mergedRequests\n        : mergedRequests.filter((r) => r.status === filter),\n    [mergedRequests, filter],\n  );\n\n  // ── Clear handler — wipes both client Zustand state and server cache ────────\n  const handleClear = useCallback(async () => {\n    // Optimistically clear locally first for instant feedback.\n    clearRequests();\n\n    try {\n      await fetch('/api/dev/api-debugger', { method: 'DELETE' });\n    } catch {\n      // Swallow — the server cache will be cleared on the next interaction.\n    }\n  }, [clearRequests]);\n\n  const TABS: { key: FilterTab; label: string; count: number }[] = [\n    { key: 'all', label: 'All', count: totalCount },\n    { key: 'pending', label: 'Pending', count: pendingCount },\n    { key: 'success', label: 'Success', count: successCount },\n    { key: 'error', label: 'Error', count: errorCount },\n  ];\n\n  if (!isMounted || !enabled) return null;\n\n  return (\n    /*\n     * ── Shared draggable container ──────────────────────────────────────────\n     * Both the badge AND the expanded panel live inside this single fixed div.\n     * The panel renders below the badge naturally via flex-col — no manual\n     * top/left pixel arithmetic is needed.\n     *\n     * pointer-events: none on the container prevents it from inadvertently\n     * eating clicks on the page backdrop; pointer-events: auto is restored on\n     * the interactive children.\n     */\n    <div\n      style={{\n        position: 'fixed',\n        left: pos.x,\n        top: pos.y,\n        transform: 'translateY(-50%)',\n        zIndex: 9999,\n        display: 'flex',\n        flexDirection: 'column',\n        alignItems: 'flex-start',\n        gap: '8px',\n        pointerEvents: 'none',\n        userSelect: 'none',\n      }}\n    >\n      {/* ── Floating badge (drag handle) ── */}\n      <button\n        id=\"api-debugger-badge\"\n        title=\"Toggle API Debugger\"\n        type=\"button\"\n        style={{\n          pointerEvents: 'auto',\n          cursor: isDragging.current ? 'grabbing' : 'grab',\n        }}\n        className=\"\n          group bg-slate-900/90 relative flex items-center gap-2 rounded-full px-3 py-2 shadow-2xl ring-1 ring-white/10 backdrop-blur-md transition-all\n          duration-200 select-none\n          hover:scale-105 hover:ring-white/25\n          active:scale-95\n        \"\n        onMouseDown={handleMouseDown}\n        onClick={handleBadgeClick}\n      >\n        {/* Activity indicator dot */}\n        {activeCount > 0 ? (\n          <PulsingDot />\n        ) : (\n          <span className=\"bg-emerald-500 size-2 rounded-full\" />\n        )}\n\n        {/* Request counter label */}\n        <span className=\"text-slate-200 font-mono text-[11px] leading-none font-semibold\">\n          {activeCount > 0 ? (\n            <>\n              <span className=\"text-amber-400\">{activeCount}</span> /{' '}\n              {totalCount}\n            </>\n          ) : (\n            <>\n              {totalCount} req{totalCount !== 1 ? 's' : ''}\n            </>\n          )}\n        </span>\n\n        {/* Module badge */}\n        <span className=\"bg-indigo-500/20 text-indigo-300 border-indigo-500/30 rounded-sm border px-1 py-0.5 text-[9px] font-bold tracking-widest uppercase\">\n          API\n        </span>\n      </button>\n\n      {/* ── Expanded panel — sits naturally below the badge via flex-col ── */}\n      {isOpen && (\n        <div\n          id=\"api-debugger-panel\"\n          style={{\n            pointerEvents: 'auto',\n            width: 420,\n            maxWidth: 'calc(100vw - 2rem)',\n            maxHeight: 'min(600px, calc(100vh - 5rem))',\n          }}\n          className=\"\n            bg-slate-900/95 flex flex-col overflow-hidden rounded-xl shadow-2xl ring-1 ring-white/10 backdrop-blur-xl\n          \"\n        >\n          {/* Panel header */}\n          <div className=\"flex items-center justify-between border-b border-white/8 px-4 py-3\">\n            <div className=\"flex items-center gap-2\">\n              <span className=\"text-[13px] font-semibold text-white\">\n                API Debugger\n              </span>\n              {activeCount > 0 && <PulsingDot />}\n            </div>\n            <div className=\"flex items-center gap-2\">\n              <button\n                type=\"button\"\n                className=\"\n                  text-slate-400 rounded-sm px-2 py-1 text-[10px] font-semibold tracking-wider uppercase transition\n                  hover:bg-white/10 hover:text-white\n                \"\n                onClick={handleClear}\n              >\n                Clear\n              </button>\n              <button\n                aria-label=\"Close API Debugger\"\n                type=\"button\"\n                className=\"\n                  text-slate-400 flex size-6 items-center justify-center rounded-sm transition\n                  hover:bg-white/10 hover:text-white\n                \"\n                onClick={() => setIsOpen(false)}\n              >\n                ✕\n              </button>\n            </div>\n          </div>\n\n          {/* Filter tabs */}\n          <div className=\"flex gap-1 border-b border-white/8 px-3 py-2\">\n            {TABS.map(({ key, label, count }) => (\n              <button\n                key={key}\n                type=\"button\"\n                className={`\n                  rounded-sm px-2 py-1 text-[10px] font-semibold transition-colors\n                  ${\n                    filter === key\n                      ? 'bg-indigo-500/25 text-indigo-300 ring-indigo-500/40 ring-1'\n                      : `\n                        text-slate-400\n                        hover:text-slate-200 hover:bg-white/8\n                      `\n                  }\n                `}\n                onClick={() => setFilter(key)}\n              >\n                {label} ({count})\n              </button>\n            ))}\n          </div>\n\n          {/* Request list */}\n          <div className=\"min-h-0 flex-1 overflow-y-auto\">\n            {filtered.length === 0 ? (\n              <div className=\"flex flex-col items-center justify-center gap-2 py-12 text-center\">\n                <span className=\"text-2xl opacity-30\">📡</span>\n                <p className=\"text-slate-500 text-[11px]\">\n                  {totalCount === 0\n                    ? 'No requests captured yet'\n                    : 'No requests match this filter'}\n                </p>\n              </div>\n            ) : (\n              filtered.map((req) => <RequestRow key={req.id} req={req} />)\n            )}\n          </div>\n\n          {/* Panel footer */}\n          <div className=\"flex items-center justify-between border-t border-white/8 px-4 py-2\">\n            <span className=\"text-slate-600 font-mono text-[9px] tracking-widest uppercase\">\n              {process.env.NODE_ENV === 'development' ? 'dev mode' : 'forced debug mode'}\n            </span>\n            <span className=\"text-slate-600 font-mono text-[9px]\">\n              {ssrCount > 0 && (\n                <span className=\"text-purple-500/70\">{ssrCount} SSR</span>\n              )}\n              {ssrCount > 0 && clientCount > 0 && (\n                <span className=\"text-slate-700\"> · </span>\n              )}\n              {clientCount > 0 && (\n                <span className=\"text-cyan-500/70\">{clientCount} Client</span>\n              )}\n              {ssrCount === 0 && clientCount === 0 && (\n                <span>{totalCount} total · {activeCount} in-flight</span>\n              )}\n            </span>\n          </div>\n        </div>\n      )}\n    </div>\n  );\n}\n"],"mappings":"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","names":["RequestRow"]}