import { c as _c } from "react-compiler-runtime"; import React, { createContext, useCallback, useContext, useEffect, useMemo } from 'react'; import { saveCurrentProjectConfig } from '../utils/config.js'; export type StatsStore = { increment(name: string, value?: number): void; set(name: string, value: number): void; observe(name: string, value: number): void; add(name: string, value: string): void; getAll(): Record; }; function percentile(sorted: number[], p: number): number { const index = p / 100 * (sorted.length - 1); const lower = Math.floor(index); const upper = Math.ceil(index); if (lower === upper) { return sorted[lower]!; } return sorted[lower]! + (sorted[upper]! - sorted[lower]!) * (index - lower); } const RESERVOIR_SIZE = 1024; type Histogram = { reservoir: number[]; count: number; sum: number; min: number; max: number; }; export function createStatsStore(): StatsStore { const metrics = new Map(); const histograms = new Map(); const sets = new Map>(); return { increment(name: string, value = 1) { metrics.set(name, (metrics.get(name) ?? 0) + value); }, set(name: string, value: number) { metrics.set(name, value); }, observe(name: string, value: number) { let h = histograms.get(name); if (!h) { h = { reservoir: [], count: 0, sum: 0, min: value, max: value }; histograms.set(name, h); } h.count++; h.sum += value; if (value < h.min) { h.min = value; } if (value > h.max) { h.max = value; } // Reservoir sampling (Algorithm R) if (h.reservoir.length < RESERVOIR_SIZE) { h.reservoir.push(value); } else { const j = Math.floor(Math.random() * h.count); if (j < RESERVOIR_SIZE) { h.reservoir[j] = value; } } }, add(name: string, value: string) { let s = sets.get(name); if (!s) { s = new Set(); sets.set(name, s); } s.add(value); }, getAll() { const result: Record = Object.fromEntries(metrics); for (const [name, h] of histograms) { if (h.count === 0) { continue; } result[`${name}_count`] = h.count; result[`${name}_min`] = h.min; result[`${name}_max`] = h.max; result[`${name}_avg`] = h.sum / h.count; const sorted = [...h.reservoir].sort((a, b) => a - b); result[`${name}_p50`] = percentile(sorted, 50); result[`${name}_p95`] = percentile(sorted, 95); result[`${name}_p99`] = percentile(sorted, 99); } for (const [name, s] of sets) { result[name] = s.size; } return result; } }; } export const StatsContext = createContext(null); type Props = { store?: StatsStore; children: React.ReactNode; }; export function StatsProvider(t0) { const $ = _c(7); const { store: externalStore, children } = t0; let t1; if ($[0] === Symbol.for("react.memo_cache_sentinel")) { t1 = createStatsStore(); $[0] = t1; } else { t1 = $[0]; } const internalStore = t1; const store = externalStore ?? internalStore; let t2; let t3; if ($[1] !== store) { t2 = () => { const flush = () => { const metrics = store.getAll(); if (Object.keys(metrics).length > 0) { saveCurrentProjectConfig(current => ({ ...current, lastSessionMetrics: metrics })); } }; process.on("exit", flush); return () => { process.off("exit", flush); }; }; t3 = [store]; $[1] = store; $[2] = t2; $[3] = t3; } else { t2 = $[2]; t3 = $[3]; } useEffect(t2, t3); let t4; if ($[4] !== children || $[5] !== store) { t4 = {children}; $[4] = children; $[5] = store; $[6] = t4; } else { t4 = $[6]; } return t4; } export function useStats() { const store = useContext(StatsContext); if (!store) { throw new Error("useStats must be used within a StatsProvider"); } return store; } export function useCounter(name) { const $ = _c(3); const store = useStats(); let t0; if ($[0] !== name || $[1] !== store) { t0 = value => store.increment(name, value); $[0] = name; $[1] = store; $[2] = t0; } else { t0 = $[2]; } return t0; } export function useGauge(name) { const $ = _c(3); const store = useStats(); let t0; if ($[0] !== name || $[1] !== store) { t0 = value => store.set(name, value); $[0] = name; $[1] = store; $[2] = t0; } else { t0 = $[2]; } return t0; } export function useTimer(name) { const $ = _c(3); const store = useStats(); let t0; if ($[0] !== name || $[1] !== store) { t0 = value => store.observe(name, value); $[0] = name; $[1] = store; $[2] = t0; } else { t0 = $[2]; } return t0; } export function useSet(name) { const $ = _c(3); const store = useStats(); let t0; if ($[0] !== name || $[1] !== store) { t0 = value => store.add(name, value); $[0] = name; $[1] = store; $[2] = t0; } else { t0 = $[2]; } return t0; }