react-dev-profiler 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/DevProfiler.tsx","../src/types.ts","../src/env.ts","../src/hooks.ts","../src/styles.ts","../src/DevStatsPanel.tsx","../src/ToggleButton.tsx"],"sourcesContent":["/**\n * @module react-dev-profiler\n * @description Main wrapper component — wraps your app and enables profiling.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { Profiler, useRef, useState, useEffect, useCallback, type ReactNode } from 'react'\nimport { type ReactProfilerData, type PanelPosition, INITIAL_PROFILER } from './types'\nimport { __DEV__ } from './env'\nimport { useDomTracker, useRenderRate, useRenderFlash, useLongTasks } from './hooks'\nimport { DevStatsPanel } from './DevStatsPanel'\nimport { ToggleButton } from './ToggleButton'\n\n/*\n * Global keyboard shortcut: Ctrl+I (or Cmd+I) to toggle the profiler.\n * Registered once and kept alive across HMR reloads via a window flag.\n */\nconst TOGGLE_EVENT = 'devprofiler:toggle'\nconst BOUND_KEY = '__devprofiler_bound'\n\nif (typeof window !== 'undefined' && __DEV__ && !(window as any)[BOUND_KEY]) {\n (window as any)[BOUND_KEY] = true\n window.addEventListener('keydown', (e) => {\n if ((e.ctrlKey || e.metaKey) && e.key === 'i') {\n e.preventDefault()\n window.dispatchEvent(new CustomEvent(TOGGLE_EVENT))\n }\n })\n}\n\n/* Module-level registry to track active profiler instances. */\nlet instanceCounter = 0\nconst activeInstances = new Set<string>()\n\n/**\n * Wrap your application (or any subtree) with `<DevProfiler>` to enable\n * real-time performance monitoring during development.\n *\n * In production builds the profiler is completely stripped — children\n * are rendered as-is with zero overhead.\n *\n * @example\n * ```tsx\n * import { DevProfiler } from 'react-dev-profiler'\n *\n * function App() {\n * return (\n * <DevProfiler>\n * <YourApp />\n * </DevProfiler>\n * )\n * }\n * ```\n */\nexport function DevProfiler({\n children,\n position = 'bottom-left',\n id,\n accentColor = '#6366f1',\n}: {\n children: ReactNode\n /** Where to anchor the panel. @default 'bottom-left' */\n position?: PanelPosition\n /** Optional identifier — shown in the panel when multiple instances are active. */\n id?: string\n /** Accent color for the toggle button border/glow. @default '#6366f1' */\n accentColor?: string\n}) {\n const wrapperRef = useRef<HTMLDivElement>(null)\n const [open, setOpen] = useState(false)\n const toggle = useCallback(() => setOpen(prev => !prev), [])\n\n // Generate a stable instance ID (user-provided or auto-incremented).\n const instanceId = useRef(id ?? `profiler-${++instanceCounter}`).current\n\n useEffect(() => {\n activeInstances.add(instanceId)\n return () => { activeInstances.delete(instanceId) }\n }, [instanceId])\n\n const domTracker = useDomTracker(wrapperRef, open)\n const renderRate = useRenderRate()\n const longTasks = useLongTasks(open)\n useRenderFlash(wrapperRef, open)\n\n const profilerData = useRef<ReactProfilerData>({ ...INITIAL_PROFILER })\n const onRender = useCallback((_id: string, phase: string, actualDuration: number, baseDuration: number) => {\n profilerData.current = {\n phase,\n actualDuration,\n baseDuration,\n commitCount: profilerData.current.commitCount + 1,\n }\n renderRate.tick()\n }, [renderRate])\n\n const handleReset = useCallback(() => {\n domTracker.reset()\n renderRate.reset()\n longTasks.reset()\n profilerData.current = { ...INITIAL_PROFILER }\n }, [domTracker, renderRate, longTasks])\n\n useEffect(() => {\n const handler = () => setOpen(prev => !prev)\n window.addEventListener(TOGGLE_EVENT, handler)\n return () => window.removeEventListener(TOGGLE_EVENT, handler)\n }, [])\n\n if (!__DEV__) return <>{children}</>\n\n return (\n <div ref={wrapperRef} style={{ display: 'contents' }}>\n <Profiler id=\"DevProfiler\" onRender={onRender}>\n {children}\n </Profiler>\n {!open && <ToggleButton targetRef={wrapperRef} onClick={toggle} position={position} accentColor={accentColor} />}\n {open && (\n <DevStatsPanel\n targetRef={wrapperRef}\n domTracker={domTracker}\n renderRate={renderRate}\n longTasks={longTasks}\n profilerData={profilerData}\n onClose={toggle}\n onReset={handleReset}\n position={position}\n instanceId={instanceId}\n instanceCount={activeInstances.size}\n />\n )}\n </div>\n )\n}\n","/**\n * @module react-dev-profiler\n * @description Type definitions and constants for the profiler.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\n/** Data captured from React's built-in <Profiler> callback. */\nexport type ReactProfilerData = {\n phase: string\n actualDuration: number\n baseDuration: number\n commitCount: number\n}\n\n/** Aggregated stats displayed in the profiler panel. */\nexport type DevStats = {\n domMutations: number\n domNodes: number\n frameTime: number\n frameTimeMin: number\n frameTimeMax: number\n frameTimeP99: number\n frameTimeHistory: number[]\n longTasks: number\n rendersPerSecond: number\n memory: number\n dimensions: string\n profiler: ReactProfilerData\n}\n\n/** Where the panel anchors relative to the profiled element. */\nexport type PanelPosition = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'\n\n/** How many frames we keep in the rolling history graph. */\nexport const HISTORY_SIZE = 60\n\nexport const INITIAL_PROFILER: ReactProfilerData = {\n phase: 'mount',\n actualDuration: 0,\n baseDuration: 0,\n commitCount: 0,\n}\n\nexport const INITIAL_STATS: DevStats = {\n domMutations: 0,\n domNodes: 0,\n frameTime: 0,\n frameTimeMin: 0,\n frameTimeMax: 0,\n frameTimeP99: 0,\n frameTimeHistory: [],\n longTasks: 0,\n rendersPerSecond: 0,\n memory: 0,\n dimensions: '–',\n profiler: INITIAL_PROFILER,\n}\n\n/** Returns the value at a given percentile from a pre-sorted array. */\nexport function percentile(sorted: number[], p: number): number {\n if (sorted.length === 0) return 0\n const idx = Math.ceil((p / 100) * sorted.length) - 1\n return sorted[Math.max(0, idx)]\n}\n","/**\n * @module react-dev-profiler\n * @description Environment detection — works with Vite, webpack, Next.js, and any bundler.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\n/**\n * True when running in a development environment.\n * Relies on `process.env.NODE_ENV` which all major bundlers replace at build time,\n * enabling dead-code elimination in production.\n */\nexport const __DEV__: boolean =\n typeof process !== 'undefined'\n ? process.env.NODE_ENV !== 'production'\n : true\n","/**\n * @module react-dev-profiler\n * @description Custom hooks that power the profiler's data collection.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react'\nimport { FLASH_OUTLINE } from './styles'\nimport type { PanelPosition } from './types'\n\n/**\n * Returns the effective bounding rect for an element.\n * For `display: contents` elements (which have no box), computes the\n * union rect of all direct children so anchoring still works.\n */\nexport function getEffectiveRect(el: HTMLElement): DOMRect {\n const rect = el.getBoundingClientRect()\n if (rect.width > 0 || rect.height > 0) return rect\n\n const children = el.children\n if (children.length === 0) return rect\n\n let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity\n for (let i = 0; i < children.length; i++) {\n const cr = (children[i] as HTMLElement).getBoundingClientRect()\n if (cr.width === 0 && cr.height === 0) continue\n top = Math.min(top, cr.top)\n left = Math.min(left, cr.left)\n bottom = Math.max(bottom, cr.bottom)\n right = Math.max(right, cr.right)\n }\n if (top === Infinity) return rect\n return new DOMRect(left, top, right - left, bottom - top)\n}\n\n/**\n * Returns the direct children that have a real layout box.\n * Used to attach ResizeObserver when the wrapper itself is `display: contents`.\n */\nexport function getObservableChildren(el: HTMLElement): Element[] {\n const result: Element[] = []\n for (let i = 0; i < el.children.length; i++) {\n const child = el.children[i] as HTMLElement\n const r = child.getBoundingClientRect()\n if (r.width > 0 || r.height > 0) result.push(child)\n }\n return result\n}\n\n/**\n * Tracks a corner position of a referenced element using ResizeObserver.\n * Used to anchor the panel and toggle button near the profiled component.\n * Works transparently with `display: contents` wrappers.\n */\nexport function useAnchorPosition(\n ref: React.RefObject<HTMLDivElement | null>,\n position: PanelPosition = 'bottom-left'\n) {\n const [pos, setPos] = useState({ top: 0, left: 0 })\n\n useEffect(() => {\n if (!ref.current) return\n const el = ref.current\n const update = () => {\n const rect = getEffectiveRect(el)\n switch (position) {\n case 'top-left':\n setPos({ top: rect.top, left: rect.left }); break\n case 'top-right':\n setPos({ top: rect.top, left: rect.right }); break\n case 'bottom-right':\n setPos({ top: rect.bottom, left: rect.right }); break\n case 'bottom-left':\n default:\n setPos({ top: rect.bottom, left: rect.left }); break\n }\n }\n update()\n const observer = new ResizeObserver(update)\n // Observe the element itself (works if it has a box)\n // AND its visible children (needed for display:contents)\n observer.observe(el)\n for (const child of getObservableChildren(el)) observer.observe(child)\n observer.observe(document.documentElement)\n return () => observer.disconnect()\n }, [ref, position])\n\n return pos\n}\n\n/**\n * Makes an element draggable via Pointer Events.\n * Returns an offset to apply as CSS transform and event handlers for the drag handle.\n */\nexport function useDraggable() {\n const [offset, setOffset] = useState({ x: 0, y: 0 })\n const dragging = useRef(false)\n const start = useRef({ x: 0, y: 0 })\n\n const onPointerDown = useCallback((e: React.PointerEvent) => {\n if ((e.target as HTMLElement).closest('button, a, [data-no-drag]')) return\n dragging.current = true\n start.current = { x: e.clientX - offset.x, y: e.clientY - offset.y }\n ;(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId)\n }, [offset])\n\n const onPointerMove = useCallback((e: React.PointerEvent) => {\n if (!dragging.current) return\n setOffset({\n x: e.clientX - start.current.x,\n y: e.clientY - start.current.y,\n })\n }, [])\n\n const onPointerUp = useCallback(() => {\n dragging.current = false\n }, [])\n\n return { offset, handlers: { onPointerDown, onPointerMove, onPointerUp } }\n}\n\n/**\n * Counts real DOM mutations via MutationObserver (ignoring class-only changes).\n * The node count is cached and only recalculated when the DOM actually changes,\n * so we don't pay the cost of querySelectorAll('*') every frame.\n */\nexport function useDomTracker(wrapperRef: React.RefObject<HTMLDivElement | null>, enabled: boolean) {\n const mutations = useRef(0)\n const nodeCount = useRef(0)\n const dirty = useRef(true)\n\n useEffect(() => {\n if (!enabled || !wrapperRef.current) return\n const observer = new MutationObserver(() => {\n mutations.current++\n dirty.current = true\n })\n observer.observe(wrapperRef.current, {\n childList: true,\n subtree: true,\n attributeFilter: ['style'],\n })\n return () => observer.disconnect()\n }, [wrapperRef, enabled])\n\n const getNodeCount = useCallback(() => {\n if (dirty.current && wrapperRef.current) {\n nodeCount.current = wrapperRef.current.querySelectorAll('*').length\n dirty.current = false\n }\n return nodeCount.current\n }, [wrapperRef])\n\n const reset = useCallback(() => {\n mutations.current = 0\n dirty.current = true\n }, [])\n\n return { mutations, getNodeCount, reset }\n}\n\n/**\n * Measures how many React renders happen per second.\n * Call `tick()` from the <Profiler> onRender callback; the hook\n * snapshots the count every second and resets it.\n */\nexport function useRenderRate() {\n const renderCount = useRef(0)\n const rendersPerSecond = useRef(0)\n\n const tick = useCallback(() => {\n renderCount.current++\n }, [])\n\n useEffect(() => {\n const id = setInterval(() => {\n rendersPerSecond.current = renderCount.current\n renderCount.current = 0\n }, 1000)\n return () => clearInterval(id)\n }, [])\n\n const reset = useCallback(() => {\n renderCount.current = 0\n rendersPerSecond.current = 0\n }, [])\n\n return { rendersPerSecond, tick, reset }\n}\n\n/**\n * Flashes a subtle outline on the profiled element whenever the DOM mutates.\n * Skips the very first mutation (the initial mount) to avoid a flash on load.\n */\nexport function useRenderFlash(wrapperRef: React.RefObject<HTMLDivElement | null>, open: boolean) {\n const mutationCount = useRef(0)\n\n useEffect(() => {\n if (!open || !wrapperRef.current) return\n const wrapper = wrapperRef.current\n const observer = new MutationObserver(() => {\n mutationCount.current++\n if (mutationCount.current <= 1) return\n // Target the first visible child (display:contents has no box to outline)\n const target = getObservableChildren(wrapper)[0] as HTMLElement | undefined ?? wrapper\n target.style.outline = FLASH_OUTLINE\n target.style.outlineOffset = '-2px'\n setTimeout(() => {\n target.style.outline = ''\n target.style.outlineOffset = ''\n }, 150)\n })\n observer.observe(wrapper, { childList: true, subtree: true })\n return () => observer.disconnect()\n }, [wrapperRef, open])\n}\n\n/**\n * Detects browser \"long tasks\" (>50 ms) using PerformanceObserver.\n * Falls back silently in browsers that don't support the longtask entry type.\n */\nexport function useLongTasks(enabled: boolean) {\n const count = useRef(0)\n\n useEffect(() => {\n if (!enabled || typeof PerformanceObserver === 'undefined') return\n try {\n const observer = new PerformanceObserver((list) => {\n count.current += list.getEntries().length\n })\n observer.observe({ entryTypes: ['longtask'] })\n return () => observer.disconnect()\n } catch {\n // longtask not supported in this browser\n }\n }, [enabled])\n\n const reset = useCallback(() => { count.current = 0 }, [])\n\n return { count, reset }\n}\n","/**\n * @module react-dev-profiler\n * @description Inline styles for the profiler UI — no external CSS needed.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport type { CSSProperties } from 'react'\n\nexport const s = {\n wrapper: {\n display: 'contents',\n } satisfies CSSProperties,\n\n panel: {\n position: 'fixed',\n zIndex: 99999,\n background: 'rgba(8, 8, 8, 0.95)',\n border: '1px solid #222',\n borderRadius: 10,\n padding: '10px 14px',\n minWidth: 220,\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.7)',\n fontFamily: \"'SF Mono', 'Fira Code', monospace\",\n backdropFilter: 'blur(12px)',\n userSelect: 'none',\n color: '#ccc',\n fontSize: 11,\n cursor: 'grab',\n touchAction: 'none',\n } satisfies CSSProperties,\n\n panelHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: 8,\n } satisfies CSSProperties,\n\n panelTitle: {\n color: '#666',\n fontSize: 9,\n fontWeight: 700,\n letterSpacing: 1.5,\n textTransform: 'uppercase',\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n } satisfies CSSProperties,\n\n instanceBadge: {\n background: '#222',\n color: '#888',\n fontSize: 8,\n padding: '1px 5px',\n borderRadius: 4,\n letterSpacing: 0.5,\n textTransform: 'none',\n } satisfies CSSProperties,\n\n headerActions: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n } satisfies CSSProperties,\n\n iconBtn: {\n background: 'none',\n border: 'none',\n color: '#444',\n cursor: 'pointer',\n padding: 4,\n margin: -4,\n lineHeight: 1,\n display: 'flex',\n alignItems: 'center',\n transition: 'color 0.15s',\n } satisfies CSSProperties,\n\n iconBtnActive: {\n color: '#4ade80',\n } satisfies CSSProperties,\n\n closeBtn: {\n background: 'none',\n border: 'none',\n color: '#444',\n cursor: 'pointer',\n fontSize: 13,\n padding: 4,\n margin: -4,\n lineHeight: 1,\n } satisfies CSSProperties,\n\n body: {\n display: 'flex',\n flexDirection: 'column',\n gap: 5,\n } satisfies CSSProperties,\n\n section: {\n color: '#444',\n fontSize: 8,\n fontWeight: 600,\n letterSpacing: 1,\n textTransform: 'uppercase',\n marginTop: 2,\n } satisfies CSSProperties,\n\n separator: {\n height: 1,\n background: '#1a1a1a',\n margin: '2px 0',\n } satisfies CSSProperties,\n\n row: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '1px 0',\n } satisfies CSSProperties,\n\n rowLabel: {\n color: '#555',\n fontSize: 10,\n } satisfies CSSProperties,\n\n rowValue: {\n fontSize: 11,\n fontWeight: 600,\n } satisfies CSSProperties,\n\n miniRow: {\n display: 'flex',\n justifyContent: 'space-between',\n color: '#444',\n fontSize: 9,\n marginTop: -2,\n marginBottom: 2,\n } satisfies CSSProperties,\n\n graphWrap: {\n marginTop: 4,\n } satisfies CSSProperties,\n\n toggleBtn: {\n position: 'fixed',\n zIndex: 99998,\n height: 26,\n borderRadius: 13,\n border: '1px solid rgba(255, 255, 255, 0.08)',\n background: 'rgba(28, 28, 30, 0.92)',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '0 10px 0 8px',\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.4), inset 0 0.5px 0 rgba(255, 255, 255, 0.06)',\n } satisfies CSSProperties,\n\n toggleDot: {\n width: 6,\n height: 6,\n borderRadius: '50%',\n flexShrink: 0,\n } satisfies CSSProperties,\n\n toggleFps: {\n fontFamily: \"'SF Mono', 'Fira Code', monospace\",\n fontSize: 11,\n fontWeight: 600,\n color: 'rgba(255, 255, 255, 0.85)',\n letterSpacing: -0.3,\n lineHeight: 1,\n } satisfies CSSProperties,\n\n toggleLabel: {\n fontFamily: \"'SF Mono', 'Fira Code', monospace\",\n fontSize: 9,\n fontWeight: 500,\n color: 'rgba(255, 255, 255, 0.35)',\n letterSpacing: 0,\n textTransform: 'lowercase',\n } satisfies CSSProperties,\n\n footer: {\n marginTop: 8,\n color: '#333',\n fontSize: 8,\n textAlign: 'center',\n } satisfies CSSProperties,\n}\n\n/** Flash outline class name applied directly via classList. */\nexport const FLASH_OUTLINE = '2px solid rgba(99, 102, 241, 0.8)'\n","/**\n * @module react-dev-profiler\n * @description The main stats panel — renders all performance metrics in a floating overlay.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { useState, useEffect, useCallback, useRef, type CSSProperties } from 'react'\nimport { createPortal } from 'react-dom'\nimport { s } from './styles'\nimport { useAnchorPosition, useDraggable, useDomTracker, useRenderRate, useLongTasks, getEffectiveRect } from './hooks'\nimport { type ReactProfilerData, type PanelPosition, type DevStats, HISTORY_SIZE, INITIAL_STATS, percentile } from './types'\n\n/** Rolling bar chart of frame times (last 60 samples). */\nfunction FrameTimeGraph({ history }: { history: number[] }) {\n const max = Math.max(33, ...history)\n const w = 140\n const h = 32\n const barW = Math.max(1, w / HISTORY_SIZE - 0.5)\n\n return (\n <div style={s.graphWrap}>\n <svg width={w} height={h} style={{ display: 'block' }}>\n <rect width={w} height={h} rx={3} fill=\"#111\" />\n {/* 60 fps guideline */}\n <line x1={0} y1={h - (16.67 / max) * h} x2={w} y2={h - (16.67 / max) * h}\n stroke=\"#1a3a1a\" strokeWidth={1} />\n {/* 30 fps guideline */}\n <line x1={0} y1={h - (33 / max) * h} x2={w} y2={h - (33 / max) * h}\n stroke=\"#3a1a1a\" strokeWidth={1} />\n {history.map((ms, i) => {\n const x = (i / HISTORY_SIZE) * w\n const barH = Math.min((ms / max) * h, h)\n const color = ms > 33 ? '#ef4444' : ms > 16.67 ? '#f59e0b' : '#4ade80'\n return <rect key={i} x={x} y={h - barH} width={barW} height={barH} fill={color} opacity={0.8} rx={0.5} />\n })}\n </svg>\n </div>\n )\n}\n\n/** Single label → value row used throughout the panel. */\nfunction StatRow({ label, value, sub, color = '#4ade80' }: { label: string, value: string, sub?: string, color?: string }) {\n return (\n <div style={s.row}>\n <span style={s.rowLabel}>{label}</span>\n <span>\n <span style={{ ...s.rowValue, color }}>{value}</span>\n {sub && <span style={{ color: '#444', fontSize: 9, marginLeft: 4 }}>{sub}</span>}\n </span>\n </div>\n )\n}\n\nconst GAP = 8\n\n/** Computes fixed-position styles based on the chosen panel position + drag offset. */\nfunction getPanelStyle(\n pos: { top: number; left: number },\n offset: { x: number; y: number },\n position: PanelPosition,\n): CSSProperties {\n const style: CSSProperties = {\n ...s.panel,\n transform: `translate(${offset.x}px, ${offset.y}px)`,\n }\n if (position.startsWith('bottom')) {\n style.bottom = window.innerHeight - pos.top + GAP\n } else {\n style.top = pos.top + GAP\n }\n if (position.endsWith('right')) {\n style.right = window.innerWidth - pos.left + GAP\n } else {\n style.left = pos.left + GAP\n }\n return style\n}\n\n/** Floating stats panel portaled to document.body. */\nexport function DevStatsPanel({\n targetRef,\n domTracker,\n renderRate,\n longTasks,\n profilerData,\n onClose,\n onReset,\n position = 'bottom-left',\n instanceId,\n instanceCount = 1,\n}: {\n targetRef: React.RefObject<HTMLDivElement | null>\n domTracker: ReturnType<typeof useDomTracker>\n renderRate: ReturnType<typeof useRenderRate>\n longTasks: ReturnType<typeof useLongTasks>\n profilerData: React.RefObject<ReactProfilerData>\n onClose: () => void\n onReset: () => void\n position?: PanelPosition\n instanceId?: string\n instanceCount?: number\n}) {\n const [stats, setStats] = useState<DevStats>(INITIAL_STATS)\n const [exported, setExported] = useState(false)\n const lastFrame = useRef(performance.now())\n const frameTimeHistory = useRef<number[]>([])\n const allFrameTimes = useRef<number[]>([])\n const pos = useAnchorPosition(targetRef, position)\n const { offset, handlers: dragHandlers } = useDraggable()\n\n // Collects frame timing data every rAF, then snapshots stats once per second.\n useEffect(() => {\n let animId: number\n let frameCount = 0\n let frameTotalMs = 0\n let lastSecond = performance.now()\n\n const tick = () => {\n const now = performance.now()\n const delta = now - lastFrame.current\n lastFrame.current = now\n frameCount++\n frameTotalMs += delta\n\n if (now - lastSecond >= 1000) {\n const avgFrameTime = frameTotalMs / frameCount\n\n const hist = frameTimeHistory.current\n if (hist.length >= HISTORY_SIZE) hist.shift()\n hist.push(avgFrameTime)\n\n allFrameTimes.current.push(avgFrameTime)\n const sorted = [...allFrameTimes.current].sort((a, b) => a - b)\n\n const el = targetRef.current\n const r = el ? getEffectiveRect(el) : null\n const dims = r ? `${Math.round(r.width)} x ${Math.round(r.height)}` : '–'\n\n // Chrome-only: performance.memory exposes JS heap usage\n const perf = performance as any\n const mem = perf.memory ? Math.round(perf.memory.usedJSHeapSize / 1024 / 1024) : 0\n\n setStats({\n domMutations: domTracker.mutations.current,\n domNodes: domTracker.getNodeCount(),\n frameTime: avgFrameTime,\n frameTimeMin: sorted[0] ?? 0,\n frameTimeMax: sorted[sorted.length - 1] ?? 0,\n frameTimeP99: percentile(sorted, 99),\n frameTimeHistory: [...hist],\n longTasks: longTasks.count.current,\n rendersPerSecond: renderRate.rendersPerSecond.current,\n memory: mem,\n dimensions: dims,\n profiler: { ...profilerData.current },\n })\n\n frameCount = 0\n frameTotalMs = 0\n lastSecond = now\n }\n animId = requestAnimationFrame(tick)\n }\n animId = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(animId)\n }, [targetRef, domTracker, renderRate, longTasks])\n\n const handleReset = useCallback(() => {\n frameTimeHistory.current = []\n allFrameTimes.current = []\n setStats(INITIAL_STATS)\n onReset()\n }, [onReset])\n\n // Download current stats as a JSON file.\n const handleExport = useCallback(() => {\n const payload = { timestamp: new Date().toISOString(), ...stats }\n const json = JSON.stringify(payload, null, 2)\n const blob = new Blob([json], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `devprofiler-${Date.now()}.json`\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(url)\n setExported(true)\n setTimeout(() => setExported(false), 1200)\n }, [stats])\n\n // Color thresholds: green = good, amber = warning, red = bad\n const ftColor = stats.frameTime > 33 ? '#ef4444' : stats.frameTime > 16.67 ? '#f59e0b' : '#4ade80'\n const rpsColor = stats.rendersPerSecond > 30 ? '#ef4444' : stats.rendersPerSecond > 10 ? '#f59e0b' : '#4ade80'\n const actualColor = stats.profiler.actualDuration > 16 ? '#ef4444' : stats.profiler.actualDuration > 8 ? '#f59e0b' : '#4ade80'\n const fps = stats.frameTime > 0 ? Math.round(1000 / stats.frameTime) : 0\n const memoGain = stats.profiler.baseDuration > 0\n ? Math.round((1 - stats.profiler.actualDuration / stats.profiler.baseDuration) * 100)\n : 0\n const p99Color = stats.frameTimeP99 > 33 ? '#ef4444' : stats.frameTimeP99 > 16.67 ? '#f59e0b' : '#4ade80'\n\n const exportStyle: CSSProperties = exported\n ? { ...s.iconBtn, ...s.iconBtnActive }\n : s.iconBtn\n\n return createPortal(\n <div style={getPanelStyle(pos, offset, position)} {...dragHandlers}>\n <div style={s.panelHeader}>\n <span style={s.panelTitle}>\n Dev Profiler\n {instanceCount > 1 && instanceId && (\n <span style={s.instanceBadge}>{instanceId}</span>\n )}\n </span>\n <div style={s.headerActions}>\n <button\n style={exportStyle}\n onClick={handleExport}\n title={exported ? 'Exported!' : 'Export stats as JSON'}\n >\n {exported ? (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n ) : (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M8 2v8M4 7l4 4 4-4M2 14h12\" />\n </svg>\n )}\n </button>\n <button style={s.iconBtn} onClick={handleReset} title=\"Reset counters\">\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M14 1a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1 0-2h1.6A6 6 0 0 0 2.07 7.5a1 1 0 1 1-1.97-.36A8 8 0 0 1 13 3.35V2a1 1 0 0 1 1-1zM2 15a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h4a1 1 0 0 1 0 2H4.4A6 6 0 0 0 13.93 8.5a1 1 0 1 1 1.97.36A8 8 0 0 1 3 12.65V14a1 1 0 0 1-1 1z\"/>\n </svg>\n </button>\n <button style={s.closeBtn} onClick={onClose}>✕</button>\n </div>\n </div>\n\n <div style={s.body}>\n <span style={s.section}>Rendering</span>\n <StatRow label=\"Frame time\" value={`${stats.frameTime.toFixed(1)}ms`} sub={`${fps} fps`} color={ftColor} />\n <FrameTimeGraph history={stats.frameTimeHistory} />\n <div style={s.miniRow}>\n <span>min {stats.frameTimeMin.toFixed(1)}</span>\n <span>max {stats.frameTimeMax.toFixed(1)}</span>\n <span style={{ color: p99Color }}>p99 {stats.frameTimeP99.toFixed(1)}</span>\n </div>\n <StatRow label=\"Renders/s\" value={String(stats.rendersPerSecond)} color={rpsColor} />\n <StatRow label=\"Long tasks\" value={String(stats.longTasks)} color={stats.longTasks > 0 ? '#f59e0b' : '#4ade80'} />\n\n <div style={s.separator} />\n <span style={s.section}>React Profiler</span>\n <StatRow label=\"Phase\" value={stats.profiler.phase} color=\"#888\" />\n <StatRow label=\"Render\" value={`${stats.profiler.actualDuration.toFixed(2)}ms`} color={actualColor} />\n <StatRow label=\"Base (no memo)\" value={`${stats.profiler.baseDuration.toFixed(2)}ms`} color=\"#888\" />\n <StatRow label=\"Memo gain\" value={`${memoGain}%`} color={memoGain > 50 ? '#4ade80' : memoGain > 20 ? '#f59e0b' : '#ef4444'} />\n <StatRow label=\"Commits\" value={String(stats.profiler.commitCount)} />\n\n <div style={s.separator} />\n <span style={s.section}>DOM</span>\n <StatRow label=\"Nodes\" value={stats.domNodes.toLocaleString()} />\n <StatRow label=\"Mutations\" value={String(stats.domMutations)} />\n <StatRow label=\"Size\" value={stats.dimensions} color=\"#888\" />\n\n <div style={s.separator} />\n <span style={s.section}>Memory</span>\n <StatRow label=\"JS Heap\" value={stats.memory > 0 ? `${stats.memory} MB` : 'N/A'} />\n </div>\n\n <div style={s.footer}>Ctrl+I to toggle</div>\n </div>,\n document.body\n )\n}\n","/**\n * @module react-dev-profiler\n * @description Minimal floating button that shows the current FPS at a glance.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { useState, useEffect, type CSSProperties } from 'react'\nimport { createPortal } from 'react-dom'\nimport { s } from './styles'\nimport { useAnchorPosition } from './hooks'\nimport type { PanelPosition } from './types'\n\n/** Computes fixed-position styles based on the chosen panel position. */\nconst GAP = 8\n\nfunction getButtonStyle(pos: { top: number; left: number }, position: PanelPosition): CSSProperties {\n const style: CSSProperties = { ...s.toggleBtn }\n if (position.startsWith('bottom')) {\n style.bottom = window.innerHeight - pos.top + GAP\n } else {\n style.top = pos.top + GAP\n }\n if (position.endsWith('right')) {\n style.right = window.innerWidth - pos.left + GAP\n } else {\n style.left = pos.left + GAP\n }\n return style\n}\n\n/** Small floating pill showing live FPS — click to open the full panel. */\nexport function ToggleButton({\n targetRef,\n onClick,\n position = 'bottom-left',\n accentColor = '#6366f1',\n}: {\n targetRef: React.RefObject<HTMLDivElement | null>\n onClick: () => void\n position?: PanelPosition\n accentColor?: string\n}) {\n const pos = useAnchorPosition(targetRef, position)\n const [fps, setFps] = useState(0)\n\n useEffect(() => {\n let animId: number\n let count = 0\n let lastSecond = performance.now()\n\n const tick = () => {\n const now = performance.now()\n count++\n if (now - lastSecond >= 1000) {\n setFps(count)\n count = 0\n lastSecond = now\n }\n animId = requestAnimationFrame(tick)\n }\n animId = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(animId)\n }, [])\n\n return createPortal(\n <button\n onClick={onClick}\n title=\"Dev Profiler (Ctrl+I)\"\n style={getButtonStyle(pos, position)}\n >\n <span style={{ ...s.toggleDot, background: accentColor, boxShadow: `0 0 4px ${accentColor}` }} />\n <span style={s.toggleFps as React.CSSProperties}>{fps}</span>\n <span style={s.toggleLabel as React.CSSProperties}>fps</span>\n </button>,\n document.body\n )\n}\n"],"mappings":"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","names":["useRef","useState","useEffect","useCallback","useState","useEffect","useCallback","useRef","useState","useRef","useEffect","useCallback","useState","useEffect","createPortal","jsx","jsxs","GAP","useState","useEffect","createPortal","jsx","jsxs","useRef","useState","useCallback","useEffect"]}
1
+ {"version":3,"sources":["../src/DevProfiler.tsx","../src/types.ts","../src/constants.ts","../src/env.ts","../src/hooks.ts","../src/styles.ts","../src/utils.ts","../src/DevStatsPanel.tsx","../src/FrameTimeGraph.tsx","../src/StatRow.tsx","../src/ToggleButton.tsx"],"sourcesContent":["/**\n * @module react-dev-profiler\n * @description Main wrapper component — wraps your app and enables profiling.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { Profiler, useRef, useState, useEffect, useCallback, type ReactNode } from 'react'\nimport { type ReactProfilerData, type PanelPosition, INITIAL_PROFILER } from './types'\nimport { COLOR_ACCENT } from './constants'\nimport { __DEV__ } from './env'\nimport { useDomTracker, useRenderRate, useRenderFlash, useLongTasks } from './hooks'\nimport { DevStatsPanel } from './DevStatsPanel'\nimport { ToggleButton } from './ToggleButton'\n\n/*\n * Global keyboard shortcut: Ctrl+I (or Cmd+I) to toggle the profiler.\n * Registered once and kept alive across HMR reloads via a window flag.\n */\nconst TOGGLE_EVENT = 'devprofiler:toggle'\nconst BOUND_KEY = '__devprofiler_bound'\n\nif (typeof window !== 'undefined' && __DEV__ && !(window as any)[BOUND_KEY]) {\n (window as any)[BOUND_KEY] = true\n window.addEventListener('keydown', (e) => {\n if ((e.ctrlKey || e.metaKey) && e.key === 'i') {\n e.preventDefault()\n window.dispatchEvent(new CustomEvent(TOGGLE_EVENT))\n }\n })\n}\n\n/* Module-level registry to track active profiler instances. */\nlet instanceCounter = 0\nconst activeInstances = new Set<string>()\n\n/**\n * Wrap your application (or any subtree) with `<DevProfiler>` to enable\n * real-time performance monitoring during development.\n *\n * In production builds the profiler is completely stripped — children\n * are rendered as-is with zero overhead.\n *\n * @example\n * ```tsx\n * import { DevProfiler } from 'react-dev-profiler'\n *\n * function App() {\n * return (\n * <DevProfiler>\n * <YourApp />\n * </DevProfiler>\n * )\n * }\n * ```\n */\nexport function DevProfiler({\n children,\n position = 'bottom-left',\n id,\n accentColor = COLOR_ACCENT,\n}: {\n children: ReactNode\n /** Where to anchor the panel. @default 'bottom-left' */\n position?: PanelPosition\n /** Optional identifier — shown in the panel when multiple instances are active. */\n id?: string\n /** Accent color for the toggle button border/glow. @default COLOR_ACCENT */\n accentColor?: string\n}) {\n const wrapperRef = useRef<HTMLDivElement>(null)\n const [open, setOpen] = useState(false)\n const toggle = useCallback(() => setOpen(prev => !prev), [])\n\n // Generate a stable instance ID (user-provided or auto-incremented).\n const instanceId = useRef(id ?? `profiler-${++instanceCounter}`).current\n\n useEffect(() => {\n activeInstances.add(instanceId)\n return () => { activeInstances.delete(instanceId) }\n }, [instanceId])\n\n const domTracker = useDomTracker(wrapperRef, open)\n const renderRate = useRenderRate()\n const longTasks = useLongTasks(open)\n useRenderFlash(wrapperRef, open)\n\n const profilerData = useRef<ReactProfilerData>({ ...INITIAL_PROFILER })\n const onRender = useCallback((_id: string, phase: string, actualDuration: number, baseDuration: number) => {\n profilerData.current = {\n phase,\n actualDuration,\n baseDuration,\n commitCount: profilerData.current.commitCount + 1,\n }\n renderRate.tick()\n }, [renderRate])\n\n const handleReset = useCallback(() => {\n domTracker.reset()\n renderRate.reset()\n longTasks.reset()\n profilerData.current = { ...INITIAL_PROFILER }\n }, [domTracker, renderRate, longTasks])\n\n useEffect(() => {\n const handler = () => setOpen(prev => !prev)\n window.addEventListener(TOGGLE_EVENT, handler)\n return () => window.removeEventListener(TOGGLE_EVENT, handler)\n }, [])\n\n if (!__DEV__) return <>{children}</>\n\n return (\n <div ref={wrapperRef} style={{ display: 'contents' }}>\n <Profiler id=\"DevProfiler\" onRender={onRender}>\n {children}\n </Profiler>\n {!open && <ToggleButton targetRef={wrapperRef} onClick={toggle} position={position} accentColor={accentColor} />}\n {open && (\n <DevStatsPanel\n targetRef={wrapperRef}\n domTracker={domTracker}\n renderRate={renderRate}\n longTasks={longTasks}\n profilerData={profilerData}\n onClose={toggle}\n onReset={handleReset}\n position={position}\n instanceId={instanceId}\n instanceCount={activeInstances.size}\n />\n )}\n </div>\n )\n}\n","/**\n * @module react-dev-profiler\n * @description Type definitions and constants for the profiler.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\n/** Data captured from React's built-in <Profiler> callback. */\nexport type ReactProfilerData = {\n phase: string\n actualDuration: number\n baseDuration: number\n commitCount: number\n}\n\n/** Aggregated stats displayed in the profiler panel. */\nexport type DevStats = {\n domMutations: number\n domNodes: number\n frameTime: number\n frameTimeMin: number\n frameTimeMax: number\n frameTimeP99: number\n frameTimeHistory: number[]\n longTasks: number\n rendersPerSecond: number\n memory: number\n dimensions: string\n profiler: ReactProfilerData\n}\n\n/** Where the panel anchors relative to the profiled element. */\nexport type PanelPosition = 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'\n\n/** How many frames we keep in the rolling history graph. */\nexport const HISTORY_SIZE = 60\n\nexport const INITIAL_PROFILER: ReactProfilerData = {\n phase: 'mount',\n actualDuration: 0,\n baseDuration: 0,\n commitCount: 0,\n}\n\nexport const INITIAL_STATS: DevStats = {\n domMutations: 0,\n domNodes: 0,\n frameTime: 0,\n frameTimeMin: 0,\n frameTimeMax: 0,\n frameTimeP99: 0,\n frameTimeHistory: [],\n longTasks: 0,\n rendersPerSecond: 0,\n memory: 0,\n dimensions: '–',\n profiler: INITIAL_PROFILER,\n}\n\n/** Returns the value at a given percentile from a pre-sorted array. */\nexport function percentile(sorted: number[], p: number): number {\n if (sorted.length === 0) return 0\n const idx = Math.ceil((p / 100) * sorted.length) - 1\n return sorted[Math.max(0, idx)]\n}\n","/**\n * @module react-dev-profiler\n * @description Shared colors and thresholds used across the profiler UI.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\n// ── Status colors ──────────────────────────────────────────────────\nexport const COLOR_GREEN = '#4ade80'\nexport const COLOR_AMBER = '#f59e0b'\nexport const COLOR_RED = '#ef4444'\nexport const COLOR_MUTED = '#888'\nexport const COLOR_DIM = '#444'\nexport const COLOR_ACCENT = '#6366f1'\n\n// ── Frame-time thresholds (ms) ─────────────────────────────────────\nexport const FPS_60_MS = 16.67\nexport const FPS_30_MS = 33\n\n// ── Graph colors ───────────────────────────────────────────────────\nexport const GRAPH_BG = '#111'\nexport const GRAPH_60FPS_LINE = '#1a3a1a'\nexport const GRAPH_30FPS_LINE = '#3a1a1a'\n\n// ── Layout ─────────────────────────────────────────────────────────\nexport const PANEL_GAP = 8\n\n// ── Helpers ────────────────────────────────────────────────────────\n\n/** Returns green / amber / red based on frame-time thresholds. */\nexport function ftColor(ms: number): string {\n if (ms > FPS_30_MS) return COLOR_RED\n if (ms > FPS_60_MS) return COLOR_AMBER\n return COLOR_GREEN\n}\n","/**\n * @module react-dev-profiler\n * @description Environment detection — works with Vite, webpack, Next.js, and any bundler.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\n/**\n * True when running in a development environment.\n * Relies on `process.env.NODE_ENV` which all major bundlers replace at build time,\n * enabling dead-code elimination in production.\n */\nexport const __DEV__: boolean =\n typeof process !== 'undefined'\n ? process.env.NODE_ENV !== 'production'\n : true\n","/**\n * @module react-dev-profiler\n * @description Custom hooks that power the profiler's data collection.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react'\nimport { FLASH_OUTLINE } from './styles'\nimport type { PanelPosition } from './types'\nimport { getEffectiveRect, getObservableChildren } from './utils'\n\n// Re-export so existing consumers don't break\nexport { getEffectiveRect, getObservableChildren } from './utils'\n\n/**\n * Tracks a corner position of a referenced element using ResizeObserver.\n * Used to anchor the panel and toggle button near the profiled component.\n * Works transparently with `display: contents` wrappers.\n */\nexport function useAnchorPosition(\n ref: React.RefObject<HTMLDivElement | null>,\n position: PanelPosition = 'bottom-left'\n) {\n const [pos, setPos] = useState({ top: 0, left: 0 })\n\n useEffect(() => {\n if (!ref.current) return\n const el = ref.current\n const update = () => {\n const rect = getEffectiveRect(el)\n switch (position) {\n case 'top-left':\n setPos({ top: rect.top, left: rect.left }); break\n case 'top-right':\n setPos({ top: rect.top, left: rect.right }); break\n case 'bottom-right':\n setPos({ top: rect.bottom, left: rect.right }); break\n case 'bottom-left':\n default:\n setPos({ top: rect.bottom, left: rect.left }); break\n }\n }\n update()\n const observer = new ResizeObserver(update)\n // Observe the element itself (works if it has a box)\n // AND its visible children (needed for display:contents)\n observer.observe(el)\n for (const child of getObservableChildren(el)) observer.observe(child)\n observer.observe(document.documentElement)\n return () => observer.disconnect()\n }, [ref, position])\n\n return pos\n}\n\n/**\n * Makes an element draggable via Pointer Events.\n * Returns an offset to apply as CSS transform and event handlers for the drag handle.\n */\nexport function useDraggable() {\n const [offset, setOffset] = useState({ x: 0, y: 0 })\n const dragging = useRef(false)\n const start = useRef({ x: 0, y: 0 })\n\n const onPointerDown = useCallback((e: React.PointerEvent) => {\n if ((e.target as HTMLElement).closest('button, a, [data-no-drag]')) return\n dragging.current = true\n start.current = { x: e.clientX - offset.x, y: e.clientY - offset.y }\n ;(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId)\n }, [offset])\n\n const onPointerMove = useCallback((e: React.PointerEvent) => {\n if (!dragging.current) return\n setOffset({\n x: e.clientX - start.current.x,\n y: e.clientY - start.current.y,\n })\n }, [])\n\n const onPointerUp = useCallback(() => {\n dragging.current = false\n }, [])\n\n return { offset, handlers: { onPointerDown, onPointerMove, onPointerUp } }\n}\n\n/**\n * Counts real DOM mutations via MutationObserver (ignoring class-only changes).\n * The node count is cached and only recalculated when the DOM actually changes,\n * so we don't pay the cost of querySelectorAll('*') every frame.\n */\nexport function useDomTracker(wrapperRef: React.RefObject<HTMLDivElement | null>, enabled: boolean) {\n const mutations = useRef(0)\n const nodeCount = useRef(0)\n const dirty = useRef(true)\n\n useEffect(() => {\n if (!enabled || !wrapperRef.current) return\n const observer = new MutationObserver(() => {\n mutations.current++\n dirty.current = true\n })\n observer.observe(wrapperRef.current, {\n childList: true,\n subtree: true,\n attributeFilter: ['style'],\n })\n return () => observer.disconnect()\n }, [wrapperRef, enabled])\n\n const getNodeCount = useCallback(() => {\n if (dirty.current && wrapperRef.current) {\n nodeCount.current = wrapperRef.current.querySelectorAll('*').length\n dirty.current = false\n }\n return nodeCount.current\n }, [wrapperRef])\n\n const reset = useCallback(() => {\n mutations.current = 0\n dirty.current = true\n }, [])\n\n return { mutations, getNodeCount, reset }\n}\n\n/**\n * Measures how many React renders happen per second.\n * Call `tick()` from the <Profiler> onRender callback; the hook\n * snapshots the count every second and resets it.\n */\nexport function useRenderRate() {\n const renderCount = useRef(0)\n const rendersPerSecond = useRef(0)\n\n const tick = useCallback(() => {\n renderCount.current++\n }, [])\n\n useEffect(() => {\n const id = setInterval(() => {\n rendersPerSecond.current = renderCount.current\n renderCount.current = 0\n }, 1000)\n return () => clearInterval(id)\n }, [])\n\n const reset = useCallback(() => {\n renderCount.current = 0\n rendersPerSecond.current = 0\n }, [])\n\n return { rendersPerSecond, tick, reset }\n}\n\n/**\n * Flashes a subtle outline on the profiled element whenever the DOM mutates.\n * Skips the very first mutation (the initial mount) to avoid a flash on load.\n */\nexport function useRenderFlash(wrapperRef: React.RefObject<HTMLDivElement | null>, open: boolean) {\n const mutationCount = useRef(0)\n\n useEffect(() => {\n if (!open || !wrapperRef.current) return\n const wrapper = wrapperRef.current\n const observer = new MutationObserver(() => {\n mutationCount.current++\n if (mutationCount.current <= 1) return\n // Target the first visible child (display:contents has no box to outline)\n const target = getObservableChildren(wrapper)[0] as HTMLElement | undefined ?? wrapper\n target.style.outline = FLASH_OUTLINE\n target.style.outlineOffset = '-2px'\n setTimeout(() => {\n target.style.outline = ''\n target.style.outlineOffset = ''\n }, 150)\n })\n observer.observe(wrapper, { childList: true, subtree: true })\n return () => observer.disconnect()\n }, [wrapperRef, open])\n}\n\n/**\n * Detects browser \"long tasks\" (>50 ms) using PerformanceObserver.\n * Falls back silently in browsers that don't support the longtask entry type.\n */\nexport function useLongTasks(enabled: boolean) {\n const count = useRef(0)\n\n useEffect(() => {\n if (!enabled || typeof PerformanceObserver === 'undefined') return\n try {\n const observer = new PerformanceObserver((list) => {\n count.current += list.getEntries().length\n })\n observer.observe({ entryTypes: ['longtask'] })\n return () => observer.disconnect()\n } catch {\n // longtask not supported in this browser\n }\n }, [enabled])\n\n const reset = useCallback(() => { count.current = 0 }, [])\n\n return { count, reset }\n}\n","/**\n * @module react-dev-profiler\n * @description Inline styles for the profiler UI — no external CSS needed.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport type { CSSProperties } from 'react'\nimport { COLOR_GREEN, COLOR_DIM, COLOR_MUTED, COLOR_ACCENT } from './constants'\n\nexport const s = {\n wrapper: {\n display: 'contents',\n } satisfies CSSProperties,\n\n panel: {\n position: 'fixed',\n zIndex: 99999,\n background: 'rgba(8, 8, 8, 0.95)',\n border: '1px solid #222',\n borderRadius: 10,\n padding: '10px 14px',\n minWidth: 220,\n boxShadow: '0 8px 32px rgba(0, 0, 0, 0.7)',\n fontFamily: \"'SF Mono', 'Fira Code', monospace\",\n backdropFilter: 'blur(12px)',\n userSelect: 'none',\n color: '#ccc',\n fontSize: 11,\n cursor: 'grab',\n touchAction: 'none',\n } satisfies CSSProperties,\n\n panelHeader: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n marginBottom: 8,\n } satisfies CSSProperties,\n\n panelTitle: {\n color: '#666',\n fontSize: 9,\n fontWeight: 700,\n letterSpacing: 1.5,\n textTransform: 'uppercase',\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n } satisfies CSSProperties,\n\n instanceBadge: {\n background: '#222',\n color: COLOR_MUTED,\n fontSize: 8,\n padding: '1px 5px',\n borderRadius: 4,\n letterSpacing: 0.5,\n textTransform: 'none',\n } satisfies CSSProperties,\n\n headerActions: {\n display: 'flex',\n alignItems: 'center',\n gap: 8,\n } satisfies CSSProperties,\n\n iconBtn: {\n background: 'none',\n border: 'none',\n color: COLOR_DIM,\n cursor: 'pointer',\n padding: 4,\n margin: -4,\n lineHeight: 1,\n display: 'flex',\n alignItems: 'center',\n transition: 'color 0.15s',\n } satisfies CSSProperties,\n\n iconBtnActive: {\n color: COLOR_GREEN,\n } satisfies CSSProperties,\n\n closeBtn: {\n background: 'none',\n border: 'none',\n color: COLOR_DIM,\n cursor: 'pointer',\n fontSize: 13,\n padding: 4,\n margin: -4,\n lineHeight: 1,\n } satisfies CSSProperties,\n\n body: {\n display: 'flex',\n flexDirection: 'column',\n gap: 5,\n } satisfies CSSProperties,\n\n section: {\n color: COLOR_DIM,\n fontSize: 8,\n fontWeight: 600,\n letterSpacing: 1,\n textTransform: 'uppercase',\n marginTop: 2,\n } satisfies CSSProperties,\n\n separator: {\n height: 1,\n background: '#1a1a1a',\n margin: '2px 0',\n } satisfies CSSProperties,\n\n row: {\n display: 'flex',\n justifyContent: 'space-between',\n alignItems: 'center',\n padding: '1px 0',\n } satisfies CSSProperties,\n\n rowLabel: {\n color: '#555',\n fontSize: 10,\n } satisfies CSSProperties,\n\n rowValue: {\n fontSize: 11,\n fontWeight: 600,\n } satisfies CSSProperties,\n\n miniRow: {\n display: 'flex',\n justifyContent: 'space-between',\n color: COLOR_DIM,\n fontSize: 9,\n marginTop: -2,\n marginBottom: 2,\n } satisfies CSSProperties,\n\n graphWrap: {\n marginTop: 4,\n } satisfies CSSProperties,\n\n toggleBtn: {\n position: 'fixed',\n zIndex: 99998,\n height: 26,\n borderRadius: 13,\n border: '1px solid rgba(255, 255, 255, 0.08)',\n background: 'rgba(28, 28, 30, 0.92)',\n cursor: 'pointer',\n display: 'flex',\n alignItems: 'center',\n gap: 6,\n padding: '0 10px 0 8px',\n backdropFilter: 'blur(20px)',\n WebkitBackdropFilter: 'blur(20px)',\n boxShadow: '0 1px 3px rgba(0, 0, 0, 0.4), inset 0 0.5px 0 rgba(255, 255, 255, 0.06)',\n } satisfies CSSProperties,\n\n toggleDot: {\n width: 6,\n height: 6,\n borderRadius: '50%',\n flexShrink: 0,\n } satisfies CSSProperties,\n\n toggleFps: {\n fontFamily: \"'SF Mono', 'Fira Code', monospace\",\n fontSize: 11,\n fontWeight: 600,\n color: 'rgba(255, 255, 255, 0.85)',\n letterSpacing: -0.3,\n lineHeight: 1,\n } satisfies CSSProperties,\n\n toggleLabel: {\n fontFamily: \"'SF Mono', 'Fira Code', monospace\",\n fontSize: 9,\n fontWeight: 500,\n color: 'rgba(255, 255, 255, 0.35)',\n letterSpacing: 0,\n textTransform: 'lowercase',\n } satisfies CSSProperties,\n\n footer: {\n marginTop: 8,\n color: '#333',\n fontSize: 8,\n textAlign: 'center',\n } satisfies CSSProperties,\n}\n\n/** Flash outline class name applied directly via classList. */\nexport const FLASH_OUTLINE = `2px solid ${COLOR_ACCENT}cc`\n","/**\n * @module react-dev-profiler\n * @description Pure utility functions for DOM measurement.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\n/**\n * Returns the effective bounding rect for an element.\n * For `display: contents` elements (which have no box), computes the\n * union rect of all direct children so anchoring still works.\n */\nexport function getEffectiveRect(el: HTMLElement): DOMRect {\n const rect = el.getBoundingClientRect()\n if (rect.width > 0 || rect.height > 0) return rect\n\n const children = el.children\n if (children.length === 0) return rect\n\n let top = Infinity, left = Infinity, bottom = -Infinity, right = -Infinity\n for (let i = 0; i < children.length; i++) {\n const cr = (children[i] as HTMLElement).getBoundingClientRect()\n if (cr.width === 0 && cr.height === 0) continue\n top = Math.min(top, cr.top)\n left = Math.min(left, cr.left)\n bottom = Math.max(bottom, cr.bottom)\n right = Math.max(right, cr.right)\n }\n if (top === Infinity) return rect\n return new DOMRect(left, top, right - left, bottom - top)\n}\n\n/**\n * Returns the direct children that have a real layout box.\n * Used to attach ResizeObserver when the wrapper itself is `display: contents`.\n */\nexport function getObservableChildren(el: HTMLElement): Element[] {\n const result: Element[] = []\n for (let i = 0; i < el.children.length; i++) {\n const child = el.children[i] as HTMLElement\n const r = child.getBoundingClientRect()\n if (r.width > 0 || r.height > 0) result.push(child)\n }\n return result\n}\n","/**\n * @module react-dev-profiler\n * @description The main stats panel — renders all performance metrics in a floating overlay.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { useState, useEffect, useCallback, useRef, type CSSProperties } from 'react'\nimport { createPortal } from 'react-dom'\nimport { s } from './styles'\nimport { useAnchorPosition, useDraggable, useDomTracker, useRenderRate, useLongTasks } from './hooks'\nimport { getEffectiveRect } from './utils'\nimport { type ReactProfilerData, type PanelPosition, type DevStats, HISTORY_SIZE, INITIAL_STATS, percentile } from './types'\nimport { COLOR_GREEN, COLOR_AMBER, COLOR_RED, COLOR_MUTED, PANEL_GAP, ftColor } from './constants'\nimport { FrameTimeGraph } from './FrameTimeGraph'\nimport { StatRow } from './StatRow'\n\nconst GAP = PANEL_GAP\n\n/** Computes fixed-position styles based on the chosen panel position + drag offset. */\nfunction getPanelStyle(\n pos: { top: number; left: number },\n offset: { x: number; y: number },\n position: PanelPosition,\n): CSSProperties {\n const style: CSSProperties = {\n ...s.panel,\n transform: `translate(${offset.x}px, ${offset.y}px)`,\n }\n if (position.startsWith('bottom')) {\n style.bottom = window.innerHeight - pos.top + GAP\n } else {\n style.top = pos.top + GAP\n }\n if (position.endsWith('right')) {\n style.right = window.innerWidth - pos.left + GAP\n } else {\n style.left = pos.left + GAP\n }\n return style\n}\n\n/** Floating stats panel portaled to document.body. */\nexport function DevStatsPanel({\n targetRef,\n domTracker,\n renderRate,\n longTasks,\n profilerData,\n onClose,\n onReset,\n position = 'bottom-left',\n instanceId,\n instanceCount = 1,\n}: {\n targetRef: React.RefObject<HTMLDivElement | null>\n domTracker: ReturnType<typeof useDomTracker>\n renderRate: ReturnType<typeof useRenderRate>\n longTasks: ReturnType<typeof useLongTasks>\n profilerData: React.RefObject<ReactProfilerData>\n onClose: () => void\n onReset: () => void\n position?: PanelPosition\n instanceId?: string\n instanceCount?: number\n}) {\n const [stats, setStats] = useState<DevStats>(INITIAL_STATS)\n const [exported, setExported] = useState(false)\n const lastFrame = useRef(performance.now())\n const frameTimeHistory = useRef<number[]>([])\n const allFrameTimes = useRef<number[]>([])\n const pos = useAnchorPosition(targetRef, position)\n const { offset, handlers: dragHandlers } = useDraggable()\n\n // Collects frame timing data every rAF, then snapshots stats once per second.\n useEffect(() => {\n let animId: number\n let frameCount = 0\n let frameTotalMs = 0\n let lastSecond = performance.now()\n\n const tick = () => {\n const now = performance.now()\n const delta = now - lastFrame.current\n lastFrame.current = now\n frameCount++\n frameTotalMs += delta\n\n if (now - lastSecond >= 1000) {\n const avgFrameTime = frameTotalMs / frameCount\n\n const hist = frameTimeHistory.current\n if (hist.length >= HISTORY_SIZE) hist.shift()\n hist.push(avgFrameTime)\n\n allFrameTimes.current.push(avgFrameTime)\n const sorted = [...allFrameTimes.current].sort((a, b) => a - b)\n\n const el = targetRef.current\n const r = el ? getEffectiveRect(el) : null\n const dims = r ? `${Math.round(r.width)} x ${Math.round(r.height)}` : '–'\n\n // Chrome-only: performance.memory exposes JS heap usage\n const perf = performance as any\n const mem = perf.memory ? Math.round(perf.memory.usedJSHeapSize / 1024 / 1024) : 0\n\n setStats({\n domMutations: domTracker.mutations.current,\n domNodes: domTracker.getNodeCount(),\n frameTime: avgFrameTime,\n frameTimeMin: sorted[0] ?? 0,\n frameTimeMax: sorted[sorted.length - 1] ?? 0,\n frameTimeP99: percentile(sorted, 99),\n frameTimeHistory: [...hist],\n longTasks: longTasks.count.current,\n rendersPerSecond: renderRate.rendersPerSecond.current,\n memory: mem,\n dimensions: dims,\n profiler: { ...profilerData.current },\n })\n\n frameCount = 0\n frameTotalMs = 0\n lastSecond = now\n }\n animId = requestAnimationFrame(tick)\n }\n animId = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(animId)\n }, [targetRef, domTracker, renderRate, longTasks])\n\n const handleReset = useCallback(() => {\n frameTimeHistory.current = []\n allFrameTimes.current = []\n setStats(INITIAL_STATS)\n onReset()\n }, [onReset])\n\n // Download current stats as a JSON file.\n const handleExport = useCallback(() => {\n const payload = { timestamp: new Date().toISOString(), ...stats }\n const json = JSON.stringify(payload, null, 2)\n const blob = new Blob([json], { type: 'application/json' })\n const url = URL.createObjectURL(blob)\n const a = document.createElement('a')\n a.href = url\n a.download = `devprofiler-${Date.now()}.json`\n document.body.appendChild(a)\n a.click()\n document.body.removeChild(a)\n URL.revokeObjectURL(url)\n setExported(true)\n setTimeout(() => setExported(false), 1200)\n }, [stats])\n\n // Color thresholds: green = good, amber = warning, red = bad\n const frameTColor = ftColor(stats.frameTime)\n const rpsColor = stats.rendersPerSecond > 30 ? COLOR_RED : stats.rendersPerSecond > 10 ? COLOR_AMBER : COLOR_GREEN\n const actualColor = stats.profiler.actualDuration > 16 ? COLOR_RED : stats.profiler.actualDuration > 8 ? COLOR_AMBER : COLOR_GREEN\n const fps = stats.frameTime > 0 ? Math.round(1000 / stats.frameTime) : 0\n const memoGain = stats.profiler.baseDuration > 0\n ? Math.round((1 - stats.profiler.actualDuration / stats.profiler.baseDuration) * 100)\n : 0\n const p99Color = ftColor(stats.frameTimeP99)\n\n const exportStyle: CSSProperties = exported\n ? { ...s.iconBtn, ...s.iconBtnActive }\n : s.iconBtn\n\n return createPortal(\n <div style={getPanelStyle(pos, offset, position)} {...dragHandlers}>\n <div style={s.panelHeader}>\n <span style={s.panelTitle}>\n Dev Profiler\n {instanceCount > 1 && instanceId && (\n <span style={s.instanceBadge}>{instanceId}</span>\n )}\n </span>\n <div style={s.headerActions}>\n <button\n style={exportStyle}\n onClick={handleExport}\n title={exported ? 'Exported!' : 'Export stats as JSON'}\n >\n {exported ? (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <polyline points=\"3.5 8.5 6.5 11.5 12.5 4.5\" />\n </svg>\n ) : (\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 16 16\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\">\n <path d=\"M8 2v8M4 7l4 4 4-4M2 14h12\" />\n </svg>\n )}\n </button>\n <button style={s.iconBtn} onClick={handleReset} title=\"Reset counters\">\n <svg width=\"10\" height=\"10\" viewBox=\"0 0 16 16\" fill=\"currentColor\">\n <path d=\"M14 1a1 1 0 0 1 1 1v4a1 1 0 0 1-1 1h-4a1 1 0 0 1 0-2h1.6A6 6 0 0 0 2.07 7.5a1 1 0 1 1-1.97-.36A8 8 0 0 1 13 3.35V2a1 1 0 0 1 1-1zM2 15a1 1 0 0 1-1-1v-4a1 1 0 0 1 1-1h4a1 1 0 0 1 0 2H4.4A6 6 0 0 0 13.93 8.5a1 1 0 1 1 1.97.36A8 8 0 0 1 3 12.65V14a1 1 0 0 1-1 1z\"/>\n </svg>\n </button>\n <button style={s.closeBtn} onClick={onClose}>✕</button>\n </div>\n </div>\n\n <div style={s.body}>\n <span style={s.section}>Rendering</span>\n <StatRow label=\"Frame time\" value={`${stats.frameTime.toFixed(1)}ms`} sub={`${fps} fps`} color={frameTColor} />\n <FrameTimeGraph history={stats.frameTimeHistory} />\n <div style={s.miniRow}>\n <span>min {stats.frameTimeMin.toFixed(1)}</span>\n <span>max {stats.frameTimeMax.toFixed(1)}</span>\n <span style={{ color: p99Color }}>p99 {stats.frameTimeP99.toFixed(1)}</span>\n </div>\n <StatRow label=\"Renders/s\" value={String(stats.rendersPerSecond)} color={rpsColor} />\n <StatRow label=\"Long tasks\" value={String(stats.longTasks)} color={stats.longTasks > 0 ? COLOR_AMBER : COLOR_GREEN} />\n\n <div style={s.separator} />\n <span style={s.section}>React Profiler</span>\n <StatRow label=\"Phase\" value={stats.profiler.phase} color={COLOR_MUTED} />\n <StatRow label=\"Render\" value={`${stats.profiler.actualDuration.toFixed(2)}ms`} color={actualColor} />\n <StatRow label=\"Base (no memo)\" value={`${stats.profiler.baseDuration.toFixed(2)}ms`} color={COLOR_MUTED} />\n <StatRow label=\"Memo gain\" value={`${memoGain}%`} color={memoGain > 50 ? COLOR_GREEN : memoGain > 20 ? COLOR_AMBER : COLOR_RED} />\n <StatRow label=\"Commits\" value={String(stats.profiler.commitCount)} />\n\n <div style={s.separator} />\n <span style={s.section}>DOM</span>\n <StatRow label=\"Nodes\" value={stats.domNodes.toLocaleString()} />\n <StatRow label=\"Mutations\" value={String(stats.domMutations)} />\n <StatRow label=\"Size\" value={stats.dimensions} color={COLOR_MUTED} />\n\n <div style={s.separator} />\n <span style={s.section}>Memory</span>\n <StatRow label=\"JS Heap\" value={stats.memory > 0 ? `${stats.memory} MB` : 'N/A'} />\n </div>\n\n <div style={s.footer}>Ctrl+I to toggle</div>\n </div>,\n document.body\n )\n}\n","/**\n * @module react-dev-profiler\n * @description Rolling bar chart of frame times (last 60 samples).\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { s } from './styles'\nimport { HISTORY_SIZE } from './types'\nimport { GRAPH_BG, GRAPH_60FPS_LINE, GRAPH_30FPS_LINE, FPS_60_MS, FPS_30_MS, ftColor } from './constants'\n\nexport function FrameTimeGraph({ history }: { history: number[] }) {\n const max = Math.max(FPS_30_MS, ...history)\n const w = 140\n const h = 32\n const barW = Math.max(1, w / HISTORY_SIZE - 0.5)\n\n return (\n <div style={s.graphWrap}>\n <svg width={w} height={h} style={{ display: 'block' }}>\n <rect width={w} height={h} rx={3} fill={GRAPH_BG} />\n {/* 60 fps guideline */}\n <line x1={0} y1={h - (FPS_60_MS / max) * h} x2={w} y2={h - (FPS_60_MS / max) * h}\n stroke={GRAPH_60FPS_LINE} strokeWidth={1} />\n {/* 30 fps guideline */}\n <line x1={0} y1={h - (FPS_30_MS / max) * h} x2={w} y2={h - (FPS_30_MS / max) * h}\n stroke={GRAPH_30FPS_LINE} strokeWidth={1} />\n {history.map((ms, i) => {\n const x = (i / HISTORY_SIZE) * w\n const barH = Math.min((ms / max) * h, h)\n return <rect key={i} x={x} y={h - barH} width={barW} height={barH} fill={ftColor(ms)} opacity={0.8} rx={0.5} />\n })}\n </svg>\n </div>\n )\n}\n","/**\n * @module react-dev-profiler\n * @description Single label/value row used throughout the profiler panel.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { s } from './styles'\nimport { COLOR_GREEN, COLOR_DIM } from './constants'\n\nexport function StatRow({ label, value, sub, color = COLOR_GREEN }: { label: string, value: string, sub?: string, color?: string }) {\n return (\n <div style={s.row}>\n <span style={s.rowLabel}>{label}</span>\n <span>\n <span style={{ ...s.rowValue, color }}>{value}</span>\n {sub && <span style={{ color: COLOR_DIM, fontSize: 9, marginLeft: 4 }}>{sub}</span>}\n </span>\n </div>\n )\n}\n","/**\n * @module react-dev-profiler\n * @description Minimal floating button that shows the current FPS at a glance.\n * @author Frederic Denis (billywild87) — https://github.com/billywild87\n * @license MIT\n */\n\nimport { useState, useEffect, type CSSProperties } from 'react'\nimport { createPortal } from 'react-dom'\nimport { s } from './styles'\nimport { useAnchorPosition } from './hooks'\nimport type { PanelPosition } from './types'\nimport { COLOR_ACCENT, PANEL_GAP } from './constants'\n\n/** Computes fixed-position styles based on the chosen panel position. */\nconst GAP = PANEL_GAP\n\nfunction getButtonStyle(pos: { top: number; left: number }, position: PanelPosition): CSSProperties {\n const style: CSSProperties = { ...s.toggleBtn }\n if (position.startsWith('bottom')) {\n style.bottom = window.innerHeight - pos.top + GAP\n } else {\n style.top = pos.top + GAP\n }\n if (position.endsWith('right')) {\n style.right = window.innerWidth - pos.left + GAP\n } else {\n style.left = pos.left + GAP\n }\n return style\n}\n\n/** Small floating pill showing live FPS — click to open the full panel. */\nexport function ToggleButton({\n targetRef,\n onClick,\n position = 'bottom-left',\n accentColor = COLOR_ACCENT,\n}: {\n targetRef: React.RefObject<HTMLDivElement | null>\n onClick: () => void\n position?: PanelPosition\n accentColor?: string\n}) {\n const pos = useAnchorPosition(targetRef, position)\n const [fps, setFps] = useState(0)\n\n useEffect(() => {\n let animId: number\n let count = 0\n let lastSecond = performance.now()\n\n const tick = () => {\n const now = performance.now()\n count++\n if (now - lastSecond >= 1000) {\n setFps(count)\n count = 0\n lastSecond = now\n }\n animId = requestAnimationFrame(tick)\n }\n animId = requestAnimationFrame(tick)\n return () => cancelAnimationFrame(animId)\n }, [])\n\n return createPortal(\n <button\n onClick={onClick}\n title=\"Dev Profiler (Ctrl+I)\"\n style={getButtonStyle(pos, position)}\n >\n <span style={{ ...s.toggleDot, background: accentColor, boxShadow: `0 0 4px ${accentColor}` }} />\n <span style={s.toggleFps as React.CSSProperties}>{fps}</span>\n <span style={s.toggleLabel as React.CSSProperties}>fps</span>\n </button>,\n document.body\n )\n}\n"],"mappings":"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","names":["useRef","useState","useEffect","useCallback","useState","useEffect","useCallback","useRef","jsx","jsxs","jsx","jsxs","useState","useRef","useEffect","useCallback","useState","useEffect","createPortal","jsx","jsxs","GAP","useState","useEffect","createPortal","jsx","jsxs","useRef","useState","useCallback","useEffect"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-dev-profiler",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Real-time React performance monitoring — frame times, FPS, DOM mutations, memory, and more. Zero overhead in production.",
5
5
  "author": "Frederic Denis <billywild87@users.noreply.github.com> (https://github.com/billywild87)",
6
6
  "license": "MIT",
@@ -38,8 +38,7 @@
38
38
  "types": "./dist/index.d.cts",
39
39
  "default": "./dist/index.cjs"
40
40
  }
41
- },
42
- "./styles.css": "./dist/index.css"
41
+ }
43
42
  },
44
43
  "files": [
45
44
  "dist",