@probat/react 0.1.1 → 0.1.3

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/utils/environment.ts","../src/utils/api.ts","../src/utils/documentClickTracker.ts","../src/context/ProbatContext.tsx","../src/components/ProbatProviderClient.tsx","../src/hooks/useProbatMetrics.ts","../src/utils/storage.ts","../src/hooks/useExperiment.ts","../src/hoc/withExperiment.tsx"],"names":["React","now","createContext","useMemo","useEffect","useContext","useCallback","useState","meta","label"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Detect if the code is running on localhost (development environment).\n * Returns \"dev\" for localhost, \"prod\" for production.\n */\nexport function detectEnvironment(): \"dev\" | \"prod\" {\n if (typeof window === \"undefined\") {\n return \"prod\"; // Server-side, default to prod\n }\n\n const hostname = window.location.hostname;\n\n // Check for localhost, 127.0.0.1, or local IP addresses\n if (\n hostname === \"localhost\" ||\n hostname === \"127.0.0.1\" ||\n hostname === \"0.0.0.0\" ||\n hostname.startsWith(\"192.168.\") ||\n hostname.startsWith(\"10.\") ||\n hostname.startsWith(\"172.16.\") ||\n hostname.startsWith(\"172.17.\") ||\n hostname.startsWith(\"172.18.\") ||\n hostname.startsWith(\"172.19.\") ||\n hostname.startsWith(\"172.20.\") ||\n hostname.startsWith(\"172.21.\") ||\n hostname.startsWith(\"172.22.\") ||\n hostname.startsWith(\"172.23.\") ||\n hostname.startsWith(\"172.24.\") ||\n hostname.startsWith(\"172.25.\") ||\n hostname.startsWith(\"172.26.\") ||\n hostname.startsWith(\"172.27.\") ||\n hostname.startsWith(\"172.28.\") ||\n hostname.startsWith(\"172.29.\") ||\n hostname.startsWith(\"172.30.\") ||\n hostname.startsWith(\"172.31.\")\n ) {\n return \"dev\";\n }\n\n return \"prod\";\n}\n\n","import React from \"react\";\nimport { detectEnvironment } from \"./environment\";\n\nexport type RetrieveResponse = {\n proposal_id: string;\n experiment_id: string | null;\n label: string | null;\n};\n\nexport type ComponentVariantInfo = {\n experiment_id: string;\n label: string;\n file_path: string | null;\n};\n\nexport type ComponentExperimentConfig = {\n proposal_id: string;\n variants: Record<string, ComponentVariantInfo>;\n};\n\n// Shared promise cache to prevent multiple simultaneous API calls for the same proposal\nconst pendingFetches = new Map<\n string,\n Promise<{ experiment_id: string; label: string }>\n>();\n\nexport async function fetchDecision(\n baseUrl: string,\n proposalId: string\n): Promise<{ experiment_id: string; label: string }> {\n // Check if there's already a pending fetch for this proposal\n const existingFetch = pendingFetches.get(proposalId);\n if (existingFetch) {\n return existingFetch;\n }\n\n // Create new fetch promise\n const fetchPromise = (async () => {\n try {\n const url = `${baseUrl.replace(/\\/$/, \"\")}/retrieve_react_experiment/${encodeURIComponent(proposalId)}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { Accept: \"application/json\" },\n credentials: \"include\", // Include cookies for user identification\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = (await res.json()) as RetrieveResponse;\n\n const experiment_id = (data.experiment_id || `exp_${proposalId}`).toString();\n const label = data.label && data.label.trim() ? data.label : \"control\";\n\n return { experiment_id, label };\n } finally {\n // Remove from pending cache after completion\n pendingFetches.delete(proposalId);\n }\n })();\n\n // Store the promise so other components can wait for the same call\n pendingFetches.set(proposalId, fetchPromise);\n return fetchPromise;\n}\n\nexport async function sendMetric(\n baseUrl: string,\n proposalId: string,\n metricName: \"visit\" | \"click\" | string,\n variantLabel: string = \"control\",\n experimentId?: string,\n dimensions: Record<string, any> = {}\n) {\n const url = `${baseUrl.replace(/\\/$/, \"\")}/send_metrics/${encodeURIComponent(proposalId)}`;\n const body = {\n experiment_id: experimentId ?? null,\n variant_label: variantLabel,\n metric_name: metricName,\n metric_value: 1,\n metric_unit: \"count\",\n source: \"react\",\n environment: detectEnvironment(), // Include environment (dev or prod)\n dimensions,\n captured_at: new Date().toISOString(),\n };\n try {\n await fetch(url, {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n credentials: \"include\", // CRITICAL: Include cookies to distinguish different users\n body: JSON.stringify(body),\n });\n } catch {\n // Silently fail - metrics should not break the app\n }\n}\n\nexport function extractClickMeta(\n event?: { target?: EventTarget | null } | null\n): Record<string, any> | undefined {\n if (!event || !event.target) return undefined;\n const rawTarget = event.target as HTMLElement | null;\n if (!rawTarget) return undefined;\n const actionable = rawTarget.closest(\n \"[data-probat-conversion='true'], button, a, [role='button']\"\n );\n if (!actionable) return undefined;\n const meta: Record<string, any> = {\n target_tag: actionable.tagName,\n };\n if (actionable.id) meta.target_id = actionable.id;\n const attr = actionable.getAttribute(\"data-probat-conversion\");\n if (attr) meta.conversion_attr = attr;\n const text = actionable.textContent?.trim();\n if (text) meta.target_text = text.slice(0, 120);\n return meta;\n}\n\n// Cache for component config fetches\nconst componentConfigCache = new Map<\n string,\n Promise<ComponentExperimentConfig | null>\n>();\n\nexport async function fetchComponentExperimentConfig(\n baseUrl: string,\n repoFullName: string,\n componentPath: string\n): Promise<ComponentExperimentConfig | null> {\n const cacheKey = `${repoFullName}:${componentPath}`;\n\n // Check cache\n const existingFetch = componentConfigCache.get(cacheKey);\n if (existingFetch) {\n return existingFetch;\n }\n\n // Create new fetch promise\n const fetchPromise = (async () => {\n try {\n const url = new URL(`${baseUrl.replace(/\\/$/, \"\")}/get_component_experiment_config`);\n url.searchParams.set(\"repo_full_name\", repoFullName);\n url.searchParams.set(\"component_path\", componentPath);\n\n const res = await fetch(url.toString(), {\n method: \"GET\",\n headers: { Accept: \"application/json\" },\n credentials: \"include\",\n });\n\n if (res.status === 404) {\n // No experiments for this component - return null\n return null;\n }\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as ComponentExperimentConfig;\n return data;\n } catch (e) {\n console.warn(`[PROBAT] Failed to fetch component config: ${e}`);\n return null;\n } finally {\n // Remove from cache after completion\n componentConfigCache.delete(cacheKey);\n }\n })();\n\n // Store the promise\n componentConfigCache.set(cacheKey, fetchPromise);\n return fetchPromise;\n}\n\n// Cache for variant component loads\nconst variantComponentCache = new Map<string, Promise<React.ComponentType<any> | null>>();\n\n// Make React available globally for variant components\nif (typeof window !== \"undefined\") {\n (window as any).__probatReact = React;\n (window as any).React = (window as any).React || React;\n}\n\nexport async function loadVariantComponent(\n baseUrl: string,\n proposalId: string,\n experimentId: string,\n filePath: string | null\n): Promise<React.ComponentType<any> | null> {\n if (!filePath) {\n return null;\n }\n\n const cacheKey = `${proposalId}:${experimentId}`;\n\n // Check cache\n const existingLoad = variantComponentCache.get(cacheKey);\n if (existingLoad) {\n return existingLoad;\n }\n\n // Create new load promise\n const loadPromise = (async () => {\n try {\n // Fetch the variant code (server compiles TSX/JSX to JS)\n const variantUrl = `${baseUrl.replace(/\\/$/, \"\")}/variants/${filePath}`;\n\n const res = await fetch(variantUrl, {\n method: \"GET\",\n headers: { Accept: \"text/javascript\" },\n credentials: \"include\",\n });\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n\n const code = await res.text();\n\n // The server returns an IIFE that assigns to __probatVariant\n // Execute the code to get the component\n // First, ensure React is available globally\n if (typeof window !== \"undefined\") {\n (window as any).React = (window as any).React || React;\n }\n\n // Execute the IIFE code\n const evalFunc = new Function(`\n var __probatVariant;\n ${code}\n return __probatVariant;\n `);\n\n const result = evalFunc();\n\n // The result is { default: Component } from esbuild's IIFE output\n const VariantComponent = result?.default || result;\n\n if (typeof VariantComponent === \"function\") {\n return VariantComponent as React.ComponentType<any>;\n }\n\n console.warn(\"[PROBAT] Variant component is not a function\", result);\n return null;\n } catch (e) {\n console.warn(`[PROBAT] Failed to load variant component: ${e}`);\n return null;\n } finally {\n // Remove from cache after completion\n variantComponentCache.delete(cacheKey);\n }\n })();\n\n // Store the promise\n variantComponentCache.set(cacheKey, loadPromise);\n return loadPromise;\n}\n\n","/**\n * Document-level click tracking for Probat experiments\n * \n * This module implements event delegation at the document level to track clicks\n * even when components don't have onClick handlers or when stopPropagation() is called.\n */\n\nimport { sendMetric } from './api';\nimport { extractClickMeta } from './api';\n\n// Cache for proposal metadata to avoid repeated DOM queries\nconst proposalCache = new Map<string, {\n proposalId: string;\n experimentId: string | null;\n variantLabel: string;\n apiBaseUrl: string;\n}>();\n\n// Track if listener is already attached\nlet isListenerAttached = false;\n\n// Rate limiting: prevent duplicate rapid clicks\nconst lastClickTime = new Map<string, number>();\nconst DEBOUNCE_MS = 100; // Ignore clicks within 100ms of each other\n\n/**\n * Get proposal metadata from DOM element\n * Looks for the nearest [data-probat-proposal] wrapper\n */\nfunction getProposalMetadata(element: HTMLElement): {\n proposalId: string;\n experimentId: string | null;\n variantLabel: string;\n apiBaseUrl: string;\n} | null {\n // Find the nearest probat wrapper\n const probatWrapper = element.closest('[data-probat-proposal]') as HTMLElement | null;\n \n if (!probatWrapper) return null;\n \n const proposalId = probatWrapper.getAttribute('data-probat-proposal');\n if (!proposalId) return null;\n \n // Check cache first\n const cacheKey = `${proposalId}`;\n const cached = proposalCache.get(cacheKey);\n if (cached) return cached;\n \n // Extract metadata from data attributes\n const experimentId = probatWrapper.getAttribute('data-probat-experiment-id');\n const variantLabel = probatWrapper.getAttribute('data-probat-variant-label') || 'control';\n const apiBaseUrl = probatWrapper.getAttribute('data-probat-api-base-url') || \n (typeof window !== 'undefined' && (window as any).__PROBAT_API) ||\n 'https://gushi.onrender.com';\n \n const metadata = {\n proposalId,\n experimentId: experimentId || null,\n variantLabel,\n apiBaseUrl,\n };\n \n // Cache it\n proposalCache.set(cacheKey, metadata);\n return metadata;\n}\n\n/**\n * Handle click event at document level\n * Uses capture phase to catch events before stopPropagation()\n */\nfunction handleDocumentClick(event: MouseEvent): void {\n const target = event.target as HTMLElement | null;\n if (!target) return;\n \n // Get proposal metadata\n const metadata = getProposalMetadata(target);\n if (!metadata) return;\n \n // Rate limiting: prevent duplicate rapid clicks\n const now = Date.now();\n const lastClick = lastClickTime.get(metadata.proposalId) || 0;\n if (now - lastClick < DEBOUNCE_MS) {\n return; // Ignore rapid duplicate clicks\n }\n lastClickTime.set(metadata.proposalId, now);\n \n // Extract click metadata (your existing function)\n const clickMeta = extractClickMeta(event);\n \n // Determine if we should track this click\n // Track if:\n // 1. It's an actionable element (button, link, etc.) - clickMeta exists\n // 2. Element has data-probat-track attribute\n // 3. Parent has data-probat-track attribute\n const hasTrackAttribute = target.hasAttribute('data-probat-track') || \n target.closest('[data-probat-track]') !== null;\n \n const shouldTrack = clickMeta !== undefined || hasTrackAttribute;\n \n if (!shouldTrack) {\n // Optional: Track \"dead clicks\" for UX insights\n // Uncomment the code below if you want to track clicks on non-interactive elements\n /*\n const deadClickMeta = {\n dead_click: true,\n target_tag: target.tagName,\n target_class: target.className || '',\n target_id: target.id || '',\n };\n \n void sendMetric(\n metadata.apiBaseUrl,\n metadata.proposalId,\n 'dead_click',\n metadata.variantLabel,\n metadata.experimentId,\n deadClickMeta\n );\n */\n return;\n }\n \n // Send click metric\n void sendMetric(\n metadata.apiBaseUrl,\n metadata.proposalId,\n 'click',\n metadata.variantLabel,\n metadata.experimentId || undefined,\n clickMeta\n );\n}\n\n/**\n * Initialize document-level click tracking\n * Call this once when your app initializes (typically in ProbatProvider)\n */\nexport function initDocumentClickTracking(): void {\n if (isListenerAttached) {\n console.warn('[PROBAT] Document click listener already attached');\n return;\n }\n \n if (typeof document === 'undefined') {\n // Server-side rendering - skip\n return;\n }\n \n // Use capture phase (true) to catch events before they bubble\n // This ensures we catch clicks even if stopPropagation() is called\n document.addEventListener('click', handleDocumentClick, true);\n \n isListenerAttached = true;\n console.log('[PROBAT] Document-level click tracking initialized');\n}\n\n/**\n * Clean up the listener (useful for testing or cleanup)\n */\nexport function cleanupDocumentClickTracking(): void {\n if (!isListenerAttached) return;\n \n if (typeof document !== 'undefined') {\n document.removeEventListener('click', handleDocumentClick, true);\n }\n \n isListenerAttached = false;\n proposalCache.clear();\n lastClickTime.clear();\n}\n\n/**\n * Update proposal metadata cache (call this when proposal data changes)\n * This is useful if you want to update the cache without waiting for DOM queries\n */\nexport function updateProposalMetadata(\n proposalId: string,\n metadata: {\n experimentId?: string | null;\n variantLabel?: string;\n apiBaseUrl?: string;\n }\n): void {\n const existing = proposalCache.get(proposalId);\n if (existing) {\n proposalCache.set(proposalId, {\n ...existing,\n ...metadata,\n });\n }\n}\n\n/**\n * Clear the proposal cache (useful for testing)\n */\nexport function clearProposalCache(): void {\n proposalCache.clear();\n}\n\n","\"use client\";\n\nimport React, { createContext, useContext, useMemo, useEffect } from \"react\";\nimport { detectEnvironment } from \"../utils/environment\";\nimport { initDocumentClickTracking, cleanupDocumentClickTracking } from \"../utils/documentClickTracker\";\n\ndeclare global {\n interface Window {\n __PROBAT_API?: string;\n }\n}\n\nexport interface ProbatContextValue {\n apiBaseUrl: string;\n environment: \"dev\" | \"prod\";\n clientKey?: string;\n repoFullName?: string; // Repository full name (e.g., \"owner/repo\") for component-based experiments\n}\n\nconst ProbatContext = createContext<ProbatContextValue | null>(null);\n\nexport interface ProbatProviderProps {\n /**\n * The base URL for the Probat API.\n * If not provided, will try to read from:\n * - VITE_PROBAT_API (Vite)\n * - NEXT_PUBLIC_PROBAT_API (Next.js)\n * - window.__PROBAT_API\n * - Default: \"https://gushi.onrender.com\"\n */\n apiBaseUrl?: string;\n /**\n * Client key for identification (optional)\n */\n clientKey?: string;\n /**\n * Explicitly set environment. If not provided, will auto-detect based on hostname.\n * \"dev\" for localhost, \"prod\" for production.\n */\n environment?: \"dev\" | \"prod\";\n /**\n * Repository full name (e.g., \"owner/repo\") for component-based experiments.\n * If not provided, will try to read from:\n * - NEXT_PUBLIC_PROBAT_REPO (Next.js)\n * - VITE_PROBAT_REPO (Vite)\n * - window.__PROBAT_REPO\n */\n repoFullName?: string;\n children: React.ReactNode;\n}\n\nexport function ProbatProvider({\n apiBaseUrl,\n clientKey,\n environment: explicitEnvironment,\n repoFullName: explicitRepoFullName,\n children,\n}: ProbatProviderProps) {\n const contextValue = useMemo<ProbatContextValue>(() => {\n // Determine API base URL\n const resolvedApiBaseUrl =\n apiBaseUrl ||\n (typeof import.meta !== \"undefined\" &&\n (import.meta as any).env?.VITE_PROBAT_API) ||\n (typeof globalThis !== \"undefined\" &&\n (globalThis as any).process?.env?.NEXT_PUBLIC_PROBAT_API) ||\n (typeof window !== \"undefined\" && window.__PROBAT_API) ||\n \"https://gushi.onrender.com\";\n\n // Determine environment\n const environment = explicitEnvironment || detectEnvironment();\n\n // Determine repo full name\n const resolvedRepoFullName =\n explicitRepoFullName ||\n (typeof globalThis !== \"undefined\" &&\n (globalThis as any).process?.env?.NEXT_PUBLIC_PROBAT_REPO) ||\n (typeof import.meta !== \"undefined\" &&\n (import.meta as any).env?.VITE_PROBAT_REPO) ||\n (typeof window !== \"undefined\" && (window as any).__PROBAT_REPO) ||\n undefined;\n\n return {\n apiBaseUrl: resolvedApiBaseUrl,\n environment,\n clientKey,\n repoFullName: resolvedRepoFullName,\n };\n }, [apiBaseUrl, clientKey, explicitEnvironment, explicitRepoFullName]);\n\n // Initialize document-level click tracking when provider mounts\n useEffect(() => {\n initDocumentClickTracking();\n \n // Cleanup on unmount (optional, but good practice)\n return () => {\n cleanupDocumentClickTracking();\n };\n }, []);\n\n return (\n <ProbatContext.Provider value={contextValue}>\n {children}\n </ProbatContext.Provider>\n );\n}\n\nexport function useProbatContext(): ProbatContextValue {\n const context = useContext(ProbatContext);\n if (!context) {\n throw new Error(\n \"useProbatContext must be used within a ProbatProvider. Please wrap your app with <ProbatProvider>.\"\n );\n }\n return context;\n}\n\n","\"use client\";\n\nimport React from \"react\";\nimport { ProbatProvider as BaseProbatProvider } from \"../context/ProbatContext\";\nimport type { ProbatProviderProps } from \"../context/ProbatContext\";\n\n/**\n * ProbatProviderClient - Can be imported directly in Next.js Server Components\n * This is a re-export with \"use client\" directive to ensure it works in Server Components\n */\nexport function ProbatProviderClient(props: ProbatProviderProps) {\n return React.createElement(BaseProbatProvider, props);\n}\n\n// Also export as ProbatProvider for convenience\nexport { ProbatProviderClient as ProbatProvider };\nexport type { ProbatProviderProps };\n\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport type { MouseEvent } from \"react\";\nimport { useProbatContext } from \"../context/ProbatContext\";\nimport { sendMetric, extractClickMeta } from \"../utils/api\";\n\nexport interface UseProbatMetricsReturn {\n /**\n * Track a click event\n * @param event - Optional React mouse event (will extract metadata automatically)\n * @param options - Optional configuration\n * @param options.force - Force tracking even if no actionable element is found\n * @param options.proposalId - Override the proposal ID (usually not needed)\n * @param options.variantLabel - Override the variant label (usually not needed)\n * @param options.dimensions - Additional dimensions to include\n */\n trackClick: (\n event?: MouseEvent | null,\n options?: {\n force?: boolean;\n proposalId?: string;\n variantLabel?: string;\n dimensions?: Record<string, any>;\n }\n ) => boolean;\n /**\n * Track a custom metric\n * @param metricName - Name of the metric\n * @param proposalId - Proposal ID\n * @param variantLabel - Variant label (defaults to \"control\")\n * @param dimensions - Additional dimensions\n */\n trackMetric: (\n metricName: string,\n proposalId: string,\n variantLabel?: string,\n dimensions?: Record<string, any>\n ) => void;\n /**\n * Track an impression/view\n * @param proposalId - Proposal ID\n * @param variantLabel - Variant label (defaults to \"control\")\n * @param experimentId - Optional experiment ID\n */\n trackImpression: (\n proposalId: string,\n variantLabel?: string,\n experimentId?: string\n ) => void;\n}\n\n/**\n * Hook for tracking Probat metrics (clicks, impressions, custom metrics)\n *\n * @example\n * ```tsx\n * const { trackClick, trackImpression } = useProbatMetrics();\n *\n * // Track click on button\n * <button onClick={(e) => trackClick(e)}>Click me</button>\n *\n * // Track impression\n * useEffect(() => {\n * trackImpression(proposalId, variantLabel, experimentId);\n * }, [proposalId, variantLabel, experimentId]);\n * ```\n */\nexport function useProbatMetrics(): UseProbatMetricsReturn {\n const { apiBaseUrl } = useProbatContext();\n\n const trackClick = useCallback(\n (\n event?: MouseEvent | null,\n options?: {\n force?: boolean;\n proposalId?: string;\n variantLabel?: string;\n dimensions?: Record<string, any>;\n }\n ) => {\n const meta = extractClickMeta(event ?? undefined);\n if (!options?.force && event && !meta) {\n return false;\n }\n\n const proposalId = options?.proposalId;\n const variantLabel = options?.variantLabel || \"control\";\n\n if (!proposalId) {\n console.warn(\n \"[Probat] trackClick called without proposalId. Provide it in options or use useExperiment hook.\"\n );\n return false;\n }\n\n void sendMetric(\n apiBaseUrl,\n proposalId,\n \"click\",\n variantLabel,\n undefined,\n { ...meta, ...options?.dimensions }\n );\n return true;\n },\n [apiBaseUrl]\n );\n\n const trackMetric = useCallback(\n (\n metricName: string,\n proposalId: string,\n variantLabel: string = \"control\",\n dimensions: Record<string, any> = {}\n ) => {\n void sendMetric(\n apiBaseUrl,\n proposalId,\n metricName,\n variantLabel,\n undefined,\n dimensions\n );\n },\n [apiBaseUrl]\n );\n\n const trackImpression = useCallback(\n (\n proposalId: string,\n variantLabel: string = \"control\",\n experimentId?: string\n ) => {\n void sendMetric(\n apiBaseUrl,\n proposalId,\n \"visit\",\n variantLabel,\n experimentId\n );\n },\n [apiBaseUrl]\n );\n\n return {\n trackClick,\n trackMetric,\n trackImpression,\n };\n}\n\n","const TTL_MS = 6 * 60 * 60 * 1000; // 6 hours\n\nexport type Choice = {\n experiment_id: string;\n label: string;\n ts: number;\n};\n\nexport function safeGet(k: string): any | null {\n try {\n const raw = localStorage.getItem(k);\n return raw ? JSON.parse(raw) : null;\n } catch {\n return null;\n }\n}\n\nexport function safeSet(k: string, v: any) {\n try {\n localStorage.setItem(k, JSON.stringify(v));\n } catch { }\n}\n\nexport function now() {\n return Date.now();\n}\n\nexport function fresh(ts: number) {\n return now() - ts <= TTL_MS;\n}\n\nexport const KEY = (proposalId: string) => `probat_choice_v3:${proposalId}`;\nexport const VISIT_KEY = (proposalId: string, label: string) =>\n `probat_visit_v1:${proposalId}:${label}`;\n\nexport function readChoice(proposalId: string): Choice | null {\n const c = safeGet(KEY(proposalId)) as Choice | null;\n return c && fresh(c.ts) ? c : null;\n}\n\nexport function writeChoice(\n proposalId: string,\n experiment_id: string,\n label: string\n) {\n safeSet(KEY(proposalId), { experiment_id, label, ts: now() } as Choice);\n}\n\nconst visitMemo = new Set<string>();\n\nexport function hasTrackedVisit(proposalId: string, label: string): boolean {\n const key = VISIT_KEY(proposalId, label);\n if (visitMemo.has(key)) return true;\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return false;\n const ts = Number(raw);\n if (!Number.isFinite(ts) || ts <= 0) return false;\n if (now() - ts > TTL_MS) {\n localStorage.removeItem(key);\n return false;\n }\n visitMemo.add(key);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function markTrackedVisit(proposalId: string, label: string) {\n const key = VISIT_KEY(proposalId, label);\n visitMemo.add(key);\n try {\n localStorage.setItem(key, now().toString());\n } catch { }\n}\n\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport type { MouseEvent } from \"react\";\nimport { useProbatContext } from \"../context/ProbatContext\";\nimport { fetchDecision } from \"../utils/api\";\nimport {\n readChoice,\n writeChoice,\n hasTrackedVisit,\n markTrackedVisit,\n} from \"../utils/storage\";\nimport { sendMetric } from \"../utils/api\";\n\nexport interface UseExperimentReturn {\n /**\n * The current variant label (e.g., \"control\", \"variant-a\")\n */\n variantLabel: string;\n /**\n * The experiment ID\n */\n experimentId: string | null;\n /**\n * Whether the experiment decision is still loading\n */\n isLoading: boolean;\n /**\n * Any error that occurred while fetching the experiment\n */\n error: Error | null;\n /**\n * Manually track a click for this experiment\n */\n trackClick: (event?: MouseEvent | null) => void;\n}\n\n/**\n * Hook for fetching and applying experiment variants\n *\n * @param proposalId - The proposal ID for the experiment\n * @param options - Optional configuration\n * @param options.autoTrackImpression - Automatically track impression when variant is loaded (default: true)\n *\n * @example\n * ```tsx\n * const { variantLabel, isLoading, trackClick } = useExperiment(\"proposal-id\");\n *\n * if (isLoading) return <div>Loading...</div>;\n *\n * return (\n * <div onClick={trackClick}>\n * {variantLabel === \"control\" ? <ControlComponent /> : <VariantComponent />}\n * </div>\n * );\n * ```\n */\nexport function useExperiment(\n proposalId: string,\n options?: { autoTrackImpression?: boolean }\n): UseExperimentReturn {\n const { apiBaseUrl } = useProbatContext();\n const [choice, setChoice] = useState<{\n experiment_id: string;\n label: string;\n } | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const autoTrackImpression = options?.autoTrackImpression !== false;\n\n // Fetch experiment decision\n useEffect(() => {\n let alive = true;\n\n const cached = readChoice(proposalId);\n if (cached) {\n setChoice({ experiment_id: cached.experiment_id, label: cached.label });\n setIsLoading(false);\n } else {\n setIsLoading(true);\n (async () => {\n try {\n const { experiment_id, label } = await fetchDecision(\n apiBaseUrl,\n proposalId\n );\n if (!alive) return;\n writeChoice(proposalId, experiment_id, label);\n setChoice({ experiment_id, label });\n setError(null);\n } catch (e) {\n if (!alive) return;\n const err = e instanceof Error ? e : new Error(String(e));\n setError(err);\n setChoice({\n experiment_id: `exp_${proposalId}`,\n label: \"control\",\n });\n } finally {\n if (alive) {\n setIsLoading(false);\n }\n }\n })();\n }\n\n return () => {\n alive = false;\n };\n }, [proposalId, apiBaseUrl]);\n\n // Track impression when variant is determined\n useEffect(() => {\n if (!autoTrackImpression || !choice) return;\n\n const exp = choice.experiment_id;\n const lbl = choice.label ?? \"control\";\n if (!lbl) return;\n\n // Only track if we haven't already tracked this visit\n if (hasTrackedVisit(proposalId, lbl)) return;\n markTrackedVisit(proposalId, lbl);\n void sendMetric(apiBaseUrl, proposalId, \"visit\", lbl, exp);\n }, [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl, autoTrackImpression]);\n\n const trackClick = useCallback(\n (event?: MouseEvent | null) => {\n const exp = choice?.experiment_id;\n const lbl = choice?.label ?? \"control\";\n const meta = event\n ? (() => {\n const rawTarget = event.target as HTMLElement | null;\n if (!rawTarget) return undefined;\n const actionable = rawTarget.closest(\n \"[data-probat-conversion='true'], button, a, [role='button']\"\n );\n if (!actionable) return undefined;\n const meta: Record<string, any> = {\n target_tag: actionable.tagName,\n };\n if (actionable.id) meta.target_id = actionable.id;\n const attr = actionable.getAttribute(\"data-probat-conversion\");\n if (attr) meta.conversion_attr = attr;\n const text = actionable.textContent?.trim();\n if (text) meta.target_text = text.slice(0, 120);\n return meta;\n })()\n : undefined;\n\n void sendMetric(apiBaseUrl, proposalId, \"click\", lbl, undefined, meta);\n },\n [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl]\n );\n\n return {\n variantLabel: choice?.label ?? \"control\",\n experimentId: choice?.experiment_id ?? null,\n isLoading,\n error,\n trackClick,\n };\n}\n\n","\"use client\";\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport type { MouseEvent } from \"react\";\nimport { useProbatContext } from \"../context/ProbatContext\";\nimport {\n fetchDecision,\n fetchComponentExperimentConfig,\n loadVariantComponent,\n sendMetric,\n extractClickMeta,\n} from \"../utils/api\";\nimport {\n readChoice,\n writeChoice,\n hasTrackedVisit,\n markTrackedVisit,\n} from \"../utils/storage\";\n\n// Support both old and new API for backward compatibility\nexport interface WithExperimentOptions {\n // New API: component-based\n componentPath?: string;\n repoFullName?: string;\n\n // Old API: direct proposal/registry (for backward compatibility)\n proposalId?: string;\n registry?: Record<string, React.ComponentType<any>>;\n}\n\n/**\n * Higher-Order Component for wrapping components with experiment variants\n */\nexport function withExperiment<P = any>(\n Control: React.ComponentType<P>,\n options: WithExperimentOptions\n): React.ComponentType<P & { probat?: { trackClick: () => void } }> {\n // Validate inputs at HOC level (not in component)\n if (!Control) {\n console.error(\"[PROBAT] withExperiment: Control component is required\");\n return ((props: P) => null) as any;\n }\n\n if (!options || typeof options !== 'object') {\n console.error(\"[PROBAT] withExperiment: options is required\");\n return Control as any;\n }\n\n const useNewAPI = !!options.componentPath;\n const useOldAPI = !!(options.proposalId && options.registry);\n\n if (!useNewAPI && !useOldAPI) {\n console.warn(\"[PROBAT] withExperiment: Invalid config, returning Control\");\n return Control as any;\n }\n\n const ControlComponent = Control;\n\n function Wrapped(props: P) {\n // ============================================================\n // ALL HOOKS MUST BE AT THE TOP - BEFORE ANY CONDITIONAL RETURNS\n // ============================================================\n\n // 1. Context hook - always called first\n const context = useProbatContext();\n const apiBaseUrl = context?.apiBaseUrl || \"https://gushi.onrender.com\";\n const contextRepoFullName = context?.repoFullName;\n\n // 2. State hooks - always called in same order\n const [config, setConfig] = useState<{\n proposalId: string;\n variants: Record<string, React.ComponentType<any>>;\n } | null>(null);\n const [configLoading, setConfigLoading] = useState(useNewAPI);\n const [choice, setChoice] = useState<{\n experiment_id: string;\n label: string;\n } | null>(null);\n\n // Derived values\n const repoFullName = options.repoFullName || contextRepoFullName;\n const proposalId = useNewAPI ? config?.proposalId : options.proposalId;\n\n // 3. Effect hooks - always called\n // Load component config (new API)\n useEffect(() => {\n if (!useNewAPI) return;\n if (!repoFullName) {\n console.warn(\"[PROBAT] componentPath provided but repoFullName not found\");\n setConfigLoading(false);\n return;\n }\n\n let alive = true;\n setConfigLoading(true);\n\n (async () => {\n try {\n const componentConfig = await fetchComponentExperimentConfig(\n apiBaseUrl,\n repoFullName,\n options.componentPath!\n );\n\n if (!alive) return;\n\n if (!componentConfig) {\n setConfig(null);\n setConfigLoading(false);\n return;\n }\n\n const variantComponents: Record<string, React.ComponentType<any>> = {\n control: ControlComponent,\n };\n\n for (const [label, variantInfo] of Object.entries(componentConfig.variants)) {\n if (label === \"control\") continue;\n if (variantInfo?.file_path) {\n try {\n const VariantComp = await loadVariantComponent(\n apiBaseUrl,\n componentConfig.proposal_id,\n variantInfo.experiment_id,\n variantInfo.file_path\n );\n if (VariantComp && typeof VariantComp === 'function' && alive) {\n variantComponents[label] = VariantComp;\n }\n } catch (e) {\n console.warn(`[PROBAT] Failed to load variant ${label}:`, e);\n }\n }\n }\n\n if (alive) {\n setConfig({\n proposalId: componentConfig.proposal_id,\n variants: variantComponents,\n });\n setConfigLoading(false);\n }\n } catch (e) {\n console.warn(\"[PROBAT] Failed to load component config:\", e);\n if (alive) {\n setConfig(null);\n setConfigLoading(false);\n }\n }\n })();\n\n return () => { alive = false; };\n }, [useNewAPI, options.componentPath, repoFullName, apiBaseUrl]);\n\n // Fetch experiment decision\n useEffect(() => {\n if (!proposalId) return;\n if (useNewAPI && configLoading) return;\n\n let alive = true;\n const cached = readChoice(proposalId);\n\n if (cached) {\n setChoice({\n experiment_id: cached.experiment_id,\n label: cached.label,\n });\n } else {\n (async () => {\n try {\n const { experiment_id, label } = await fetchDecision(apiBaseUrl, proposalId);\n if (!alive) return;\n writeChoice(proposalId, experiment_id, label);\n setChoice({ experiment_id, label });\n } catch (e) {\n if (!alive) return;\n setChoice({\n experiment_id: `exp_${proposalId}`,\n label: \"control\",\n });\n }\n })();\n }\n\n return () => { alive = false; };\n }, [proposalId, apiBaseUrl, useNewAPI, configLoading]);\n\n // Track visit\n useEffect(() => {\n if (!proposalId) return;\n const lbl = choice?.label ?? \"control\";\n if (!lbl || hasTrackedVisit(proposalId, lbl)) return;\n markTrackedVisit(proposalId, lbl);\n void sendMetric(apiBaseUrl, proposalId, \"visit\", lbl, choice?.experiment_id);\n }, [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl]);\n\n // 4. Callback hooks - always called\n const trackClick = useCallback(\n (event?: MouseEvent | null, opts?: { force?: boolean }) => {\n if (!proposalId) return false;\n const lbl = choice?.label ?? \"control\";\n const meta = extractClickMeta(event ?? undefined);\n if (!opts?.force && event && !meta) return false;\n void sendMetric(apiBaseUrl, proposalId, \"click\", lbl, undefined, meta);\n return true;\n },\n [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl]\n );\n\n // ============================================================\n // NOW WE CAN DO CONDITIONAL RETURNS - AFTER ALL HOOKS\n // ============================================================\n\n // Loading state - return control\n if (useNewAPI && (configLoading || !config || !proposalId)) {\n return React.createElement(ControlComponent as any, props as any);\n }\n\n // No proposalId - return control\n if (!proposalId) {\n return React.createElement(ControlComponent as any, props as any);\n }\n\n // Build registry - always has control\n const registry: Record<string, React.ComponentType<any>> = { control: ControlComponent };\n\n if (useNewAPI && config?.variants) {\n for (const [key, value] of Object.entries(config.variants)) {\n if (key !== 'control' && value && typeof value === 'function') {\n registry[key] = value;\n }\n }\n } else if (!useNewAPI && options.registry) {\n for (const [key, value] of Object.entries(options.registry)) {\n if (key !== 'control' && value && typeof value === 'function') {\n registry[key] = value;\n }\n }\n }\n\n // Select variant\n const label = choice?.label ?? \"control\";\n const Variant = registry[label] || registry.control || ControlComponent;\n\n return (\n <div\n onClick={(event) => {\n // Keep existing onClick for backward compatibility\n // Document-level listener will also catch it (in capture phase)\n trackClick(event);\n }}\n data-probat-proposal={proposalId}\n data-probat-experiment-id={choice?.experiment_id || ''}\n data-probat-variant-label={label}\n data-probat-api-base-url={apiBaseUrl}\n >\n {React.createElement(Variant, {\n key: `${proposalId}:${label}`,\n ...(props as any),\n probat: { trackClick: () => trackClick(null, { force: true }) },\n })}\n </div>\n );\n }\n\n Wrapped.displayName = `withExperiment(${Control.displayName || Control.name || \"Component\"})`;\n return Wrapped as any;\n}\n"]}
1
+ {"version":3,"sources":["../src/utils/environment.ts","../src/context/ProbatContext.tsx","../src/components/ProbatProviderClient.tsx","../src/utils/api.ts","../src/hooks/useProbatMetrics.ts","../src/utils/storage.ts","../src/hooks/useExperiment.ts","../src/hoc/withExperiment.tsx"],"names":["createContext","useMemo","useContext","React","VariantComponent","useCallback","useState","useEffect","meta","label"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Detect if the code is running on localhost (development environment).\n * Returns \"dev\" for localhost, \"prod\" for production.\n */\nexport function detectEnvironment(): \"dev\" | \"prod\" {\n if (typeof window === \"undefined\") {\n return \"prod\"; // Server-side, default to prod\n }\n\n const hostname = window.location.hostname;\n\n // Check for localhost, 127.0.0.1, or local IP addresses\n if (\n hostname === \"localhost\" ||\n hostname === \"127.0.0.1\" ||\n hostname === \"0.0.0.0\" ||\n hostname.startsWith(\"192.168.\") ||\n hostname.startsWith(\"10.\") ||\n hostname.startsWith(\"172.16.\") ||\n hostname.startsWith(\"172.17.\") ||\n hostname.startsWith(\"172.18.\") ||\n hostname.startsWith(\"172.19.\") ||\n hostname.startsWith(\"172.20.\") ||\n hostname.startsWith(\"172.21.\") ||\n hostname.startsWith(\"172.22.\") ||\n hostname.startsWith(\"172.23.\") ||\n hostname.startsWith(\"172.24.\") ||\n hostname.startsWith(\"172.25.\") ||\n hostname.startsWith(\"172.26.\") ||\n hostname.startsWith(\"172.27.\") ||\n hostname.startsWith(\"172.28.\") ||\n hostname.startsWith(\"172.29.\") ||\n hostname.startsWith(\"172.30.\") ||\n hostname.startsWith(\"172.31.\")\n ) {\n return \"dev\";\n }\n\n return \"prod\";\n}\n\n","\"use client\";\n\nimport React, { createContext, useContext, useMemo } from \"react\";\nimport { detectEnvironment } from \"../utils/environment\";\n\ndeclare global {\n interface Window {\n __PROBAT_API?: string;\n }\n}\n\nexport interface ProbatContextValue {\n apiBaseUrl: string;\n environment: \"dev\" | \"prod\";\n clientKey?: string;\n repoFullName?: string; // Repository full name (e.g., \"owner/repo\") for component-based experiments\n}\n\nconst ProbatContext = createContext<ProbatContextValue | null>(null);\n\nexport interface ProbatProviderProps {\n /**\n * The base URL for the Probat API.\n * If not provided, will try to read from:\n * - VITE_PROBAT_API (Vite)\n * - NEXT_PUBLIC_PROBAT_API (Next.js)\n * - window.__PROBAT_API\n * - Default: \"https://gushi.onrender.com\"\n */\n apiBaseUrl?: string;\n /**\n * Client key for identification (optional)\n */\n clientKey?: string;\n /**\n * Explicitly set environment. If not provided, will auto-detect based on hostname.\n * \"dev\" for localhost, \"prod\" for production.\n */\n environment?: \"dev\" | \"prod\";\n /**\n * Repository full name (e.g., \"owner/repo\") for component-based experiments.\n * If not provided, will try to read from:\n * - NEXT_PUBLIC_PROBAT_REPO (Next.js)\n * - VITE_PROBAT_REPO (Vite)\n * - window.__PROBAT_REPO\n */\n repoFullName?: string;\n children: React.ReactNode;\n}\n\nexport function ProbatProvider({\n apiBaseUrl,\n clientKey,\n environment: explicitEnvironment,\n repoFullName: explicitRepoFullName,\n children,\n}: ProbatProviderProps) {\n const contextValue = useMemo<ProbatContextValue>(() => {\n // Determine API base URL\n const resolvedApiBaseUrl =\n apiBaseUrl ||\n (typeof import.meta !== \"undefined\" &&\n (import.meta as any).env?.VITE_PROBAT_API) ||\n (typeof globalThis !== \"undefined\" &&\n (globalThis as any).process?.env?.NEXT_PUBLIC_PROBAT_API) ||\n (typeof window !== \"undefined\" && window.__PROBAT_API) ||\n \"https://gushi.onrender.com\";\n\n // Determine environment\n const environment = explicitEnvironment || detectEnvironment();\n\n // Determine repo full name\n const resolvedRepoFullName =\n explicitRepoFullName ||\n (typeof globalThis !== \"undefined\" &&\n (globalThis as any).process?.env?.NEXT_PUBLIC_PROBAT_REPO) ||\n (typeof import.meta !== \"undefined\" &&\n (import.meta as any).env?.VITE_PROBAT_REPO) ||\n (typeof window !== \"undefined\" && (window as any).__PROBAT_REPO) ||\n undefined;\n\n return {\n apiBaseUrl: resolvedApiBaseUrl,\n environment,\n clientKey,\n repoFullName: resolvedRepoFullName,\n };\n }, [apiBaseUrl, clientKey, explicitEnvironment, explicitRepoFullName]);\n\n return (\n <ProbatContext.Provider value={contextValue}>\n {children}\n </ProbatContext.Provider>\n );\n}\n\nexport function useProbatContext(): ProbatContextValue {\n const context = useContext(ProbatContext);\n if (!context) {\n throw new Error(\n \"useProbatContext must be used within a ProbatProvider. Please wrap your app with <ProbatProvider>.\"\n );\n }\n return context;\n}\n\n","\"use client\";\n\nimport React from \"react\";\nimport { ProbatProvider as BaseProbatProvider } from \"../context/ProbatContext\";\nimport type { ProbatProviderProps } from \"../context/ProbatContext\";\n\n/**\n * ProbatProviderClient - Can be imported directly in Next.js Server Components\n * This is a re-export with \"use client\" directive to ensure it works in Server Components\n */\nexport function ProbatProviderClient(props: ProbatProviderProps) {\n return React.createElement(BaseProbatProvider, props);\n}\n\n// Also export as ProbatProvider for convenience\nexport { ProbatProviderClient as ProbatProvider };\nexport type { ProbatProviderProps };\n\n","import React from \"react\";\nimport { detectEnvironment } from \"./environment\";\n\nexport type RetrieveResponse = {\n proposal_id: string;\n experiment_id: string | null;\n label: string | null;\n};\n\nexport type ComponentVariantInfo = {\n experiment_id: string;\n label: string;\n file_path: string | null;\n};\n\nexport type ComponentExperimentConfig = {\n proposal_id: string;\n repo_full_name: string;\n base_ref?: string; // Git branch/ref (default: \"main\")\n variants: Record<string, ComponentVariantInfo>;\n};\n\n// Shared promise cache to prevent multiple simultaneous API calls for the same proposal\nconst pendingFetches = new Map<\n string,\n Promise<{ experiment_id: string; label: string }>\n>();\n\nexport async function fetchDecision(\n baseUrl: string,\n proposalId: string\n): Promise<{ experiment_id: string; label: string }> {\n // Check if there's already a pending fetch for this proposal\n const existingFetch = pendingFetches.get(proposalId);\n if (existingFetch) {\n return existingFetch;\n }\n\n // Create new fetch promise\n const fetchPromise = (async () => {\n try {\n const url = `${baseUrl.replace(/\\/$/, \"\")}/retrieve_react_experiment/${encodeURIComponent(proposalId)}`;\n const res = await fetch(url, {\n method: \"POST\",\n headers: { Accept: \"application/json\" },\n credentials: \"include\", // Include cookies for user identification\n });\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n const data = (await res.json()) as RetrieveResponse;\n\n const experiment_id = (data.experiment_id || `exp_${proposalId}`).toString();\n const label = data.label && data.label.trim() ? data.label : \"control\";\n\n return { experiment_id, label };\n } finally {\n // Remove from pending cache after completion\n pendingFetches.delete(proposalId);\n }\n })();\n\n // Store the promise so other components can wait for the same call\n pendingFetches.set(proposalId, fetchPromise);\n return fetchPromise;\n}\n\nexport async function sendMetric(\n baseUrl: string,\n proposalId: string,\n metricName: \"visit\" | \"click\" | string,\n variantLabel: string = \"control\",\n experimentId?: string,\n dimensions: Record<string, any> = {}\n) {\n const url = `${baseUrl.replace(/\\/$/, \"\")}/send_metrics/${encodeURIComponent(proposalId)}`;\n const body = {\n experiment_id: experimentId ?? null,\n variant_label: variantLabel,\n metric_name: metricName,\n metric_value: 1,\n metric_unit: \"count\",\n source: \"react\",\n environment: detectEnvironment(), // Include environment (dev or prod)\n dimensions,\n captured_at: new Date().toISOString(),\n };\n try {\n await fetch(url, {\n method: \"POST\",\n headers: {\n Accept: \"application/json\",\n \"Content-Type\": \"application/json\",\n },\n credentials: \"include\", // CRITICAL: Include cookies to distinguish different users\n body: JSON.stringify(body),\n });\n } catch {\n // Silently fail - metrics should not break the app\n }\n}\n\nexport function extractClickMeta(\n event?: { target?: EventTarget | null } | null\n): Record<string, any> | undefined {\n if (!event || !event.target) return undefined;\n const rawTarget = event.target as HTMLElement | null;\n if (!rawTarget) return undefined;\n const actionable = rawTarget.closest(\n \"[data-probat-conversion='true'], button, a, [role='button']\"\n );\n if (!actionable) return undefined;\n const meta: Record<string, any> = {\n target_tag: actionable.tagName,\n };\n if (actionable.id) meta.target_id = actionable.id;\n const attr = actionable.getAttribute(\"data-probat-conversion\");\n if (attr) meta.conversion_attr = attr;\n const text = actionable.textContent?.trim();\n if (text) meta.target_text = text.slice(0, 120);\n return meta;\n}\n\n// Cache for component config fetches\nconst componentConfigCache = new Map<\n string,\n Promise<ComponentExperimentConfig | null>\n>();\n\nexport async function fetchComponentExperimentConfig(\n baseUrl: string,\n repoFullName: string,\n componentPath: string\n): Promise<ComponentExperimentConfig | null> {\n const cacheKey = `${repoFullName}:${componentPath}`;\n\n // Check cache\n const existingFetch = componentConfigCache.get(cacheKey);\n if (existingFetch) {\n return existingFetch;\n }\n\n // Create new fetch promise\n const fetchPromise = (async () => {\n try {\n const url = new URL(`${baseUrl.replace(/\\/$/, \"\")}/get_component_experiment_config`);\n url.searchParams.set(\"repo_full_name\", repoFullName);\n url.searchParams.set(\"component_path\", componentPath);\n\n const res = await fetch(url.toString(), {\n method: \"GET\",\n headers: { Accept: \"application/json\" },\n credentials: \"include\",\n });\n\n if (res.status === 404) {\n // No experiments for this component - return null\n return null;\n }\n\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n\n const data = (await res.json()) as ComponentExperimentConfig;\n return data;\n } catch (e) {\n console.warn(`[PROBAT] Failed to fetch component config: ${e}`);\n return null;\n } finally {\n // Remove from cache after completion\n componentConfigCache.delete(cacheKey);\n }\n })();\n\n // Store the promise\n componentConfigCache.set(cacheKey, fetchPromise);\n return fetchPromise;\n}\n\n// Cache for variant component loads\nconst variantComponentCache = new Map<string, Promise<React.ComponentType<any> | null>>();\n\n// Make React available globally for variant components\nif (typeof window !== \"undefined\") {\n (window as any).__probatReact = React;\n (window as any).React = (window as any).React || React;\n}\n\nexport async function loadVariantComponent(\n baseUrl: string,\n proposalId: string,\n experimentId: string,\n filePath: string | null,\n repoFullName?: string,\n baseRef?: string\n): Promise<React.ComponentType<any> | null> {\n if (!filePath) {\n return null;\n }\n\n const cacheKey = `${proposalId}:${experimentId}`;\n\n // Check cache\n const existingLoad = variantComponentCache.get(cacheKey);\n if (existingLoad) {\n return existingLoad;\n }\n\n // Create new load promise\n const loadPromise = (async () => {\n try {\n // ============================================\n // Preferred path: dynamic ESM import (Vite/Next can resolve deps)\n // ============================================\n try {\n const variantUrl = `/probat/${filePath}`;\n const mod = await import(/* @vite-ignore */ variantUrl);\n const VariantComponent = (mod as any)?.default || mod;\n if (VariantComponent && typeof VariantComponent === \"function\") {\n return VariantComponent as React.ComponentType<any>;\n }\n } catch {\n // Fall through to legacy path\n }\n\n // Legacy path (fetch + babel + eval) retained for non-Vite envs\n let code: string = \"\";\n let rawCode: string = \"\";\n let rawCodeFetched = false;\n\n const localUrl = `/probat/${filePath}`;\n try {\n const localRes = await fetch(localUrl, {\n method: \"GET\",\n headers: { Accept: \"text/plain\" },\n });\n if (localRes.ok) {\n rawCode = await localRes.text();\n rawCodeFetched = true;\n console.log(`[PROBAT] ✅ Loaded variant from local (user's repo): ${localUrl}`);\n }\n } catch {\n console.debug(`[PROBAT] Local file not available (${localUrl}), trying GitHub...`);\n }\n\n if (!rawCodeFetched && repoFullName) {\n const githubPath = `probat/${filePath}`;\n const gitRef = baseRef || \"main\";\n const githubUrl = `https://raw.githubusercontent.com/${repoFullName}/${gitRef}/${githubPath}`;\n const res = await fetch(githubUrl, { method: \"GET\", headers: { Accept: \"text/plain\" } });\n if (res.ok) {\n rawCode = await res.text();\n rawCodeFetched = true;\n console.log(`[PROBAT] ⚠️ Loaded variant from GitHub (fallback): ${githubUrl}`);\n } else {\n console.warn(`[PROBAT] ⚠️ GitHub fetch failed (${res.status}), falling back to server compilation`);\n }\n }\n\n if (rawCodeFetched && rawCode) {\n let Babel: any;\n if (typeof window !== \"undefined\" && (window as any).Babel) {\n Babel = (window as any).Babel;\n } else {\n try {\n // @ts-ignore\n const babelModule = await import(\"@babel/standalone\");\n Babel = babelModule.default || babelModule;\n } catch (importError) {\n try {\n await new Promise<void>((resolve, reject) => {\n if (typeof document === \"undefined\") {\n reject(new Error(\"Document not available\"));\n return;\n }\n if ((window as any).Babel) {\n Babel = (window as any).Babel;\n resolve();\n return;\n }\n const script = document.createElement(\"script\");\n script.src = \"https://unpkg.com/@babel/standalone/babel.min.js\";\n script.async = true;\n script.onload = () => {\n Babel = (window as any).Babel;\n if (!Babel) reject(new Error(\"Babel not found after script load\"));\n else resolve();\n };\n script.onerror = () => reject(new Error(\"Failed to load Babel from CDN\"));\n document.head.appendChild(script);\n });\n } catch (babelError) {\n console.error(\"[PROBAT] Failed to load Babel, falling back to server compilation\", babelError);\n rawCodeFetched = false;\n }\n }\n }\n\n if (rawCodeFetched && rawCode && Babel) {\n const isTSX = filePath.endsWith(\".tsx\");\n rawCode = rawCode.replace(/^import\\s+['\"].*\\.css['\"];?\\s*$/gm, \"\");\n rawCode = rawCode.replace(/^import\\s+.*from\\s+['\"].*\\.css['\"];?\\s*$/gm, \"\");\n rawCode = rawCode.replace(\n /^import\\s+React(?:\\s*,\\s*\\{[^}]*\\})?\\s+from\\s+['\"]react['\"];?\\s*$/m,\n \"const React = window.React || globalThis.React;\"\n );\n rawCode = rawCode.replace(\n /^import\\s+\\*\\s+as\\s+React\\s+from\\s+['\"]react['\"];?\\s*$/m,\n \"const React = window.React || globalThis.React;\"\n );\n rawCode = rawCode.replace(\n /^import\\s+\\{([^}]+)\\}\\s+from\\s+['\"]react['\"];?\\s*$/m,\n (match, imports) => `const {${imports}} = window.React || globalThis.React;`\n );\n rawCode = rawCode.replace(/import\\.meta\\.env\\.[\\w$]+/g, \"undefined\");\n rawCode = rawCode.replace(/\\bimport\\.meta\\b/g, \"({})\");\n rawCode = rawCode.replace(/^import\\s+.*\\/@vite\\/client.*$/gm, \"\");\n rawCode = rawCode.replace(/import\\.meta\\.hot(?:\\.[\\w$]+)*/g, \"undefined\");\n\n const compiled = Babel.transform(rawCode, {\n presets: [\n [\"react\", { runtime: \"classic\" }],\n [\"typescript\", { allExtensions: true, isTSX }],\n ],\n plugins: [[\"transform-modules-commonjs\", { allowTopLevelThis: true }]],\n sourceType: \"module\",\n filename: filePath,\n }).code;\n\n code = `\n var __probatVariant = (function() {\n var require = function(name) {\n if (name === \"react\" || name === \"react/jsx-runtime\") {\n return window.React || globalThis.React;\n }\n if (name.startsWith(\"/@vite\") || name.includes(\"@vite/client\") || name.includes(\".vite/deps\")) {\n return {};\n }\n if (name === \"react/jsx-runtime.js\") {\n return window.React || globalThis.React;\n }\n throw new Error(\"Unsupported module: \" + name);\n };\n var module = { exports: {} };\n var exports = module.exports;\n ${compiled}\n return module.exports.default || module.exports;\n })();\n `;\n } else {\n rawCodeFetched = false;\n code = \"\";\n }\n }\n\n if (!rawCodeFetched || code === \"\") {\n const variantUrl = `${baseUrl.replace(/\\/$/, \"\")}/variants/${filePath}`;\n const serverRes = await fetch(variantUrl, {\n method: \"GET\",\n headers: { Accept: \"text/javascript\" },\n credentials: \"include\",\n });\n if (!serverRes.ok) {\n throw new Error(`HTTP ${serverRes.status}`);\n }\n code = await serverRes.text();\n }\n\n if (typeof window !== \"undefined\") {\n (window as any).React = (window as any).React || React;\n }\n\n const evalFunc = new Function(`\n var __probatVariant;\n ${code}\n return __probatVariant;\n `);\n\n const result = evalFunc();\n const VariantComponent = result?.default || result;\n if (typeof VariantComponent === \"function\") {\n return VariantComponent as React.ComponentType<any>;\n }\n\n console.warn(\"[PROBAT] Variant component is not a function\", result);\n return null;\n } catch (e) {\n console.warn(`[PROBAT] Failed to load variant component: ${e}`);\n return null;\n } finally {\n // Remove from cache after completion\n variantComponentCache.delete(cacheKey);\n }\n })();\n\n // Store the promise\n variantComponentCache.set(cacheKey, loadPromise);\n return loadPromise;\n}\n\n","\"use client\";\n\nimport { useCallback } from \"react\";\nimport type { MouseEvent } from \"react\";\nimport { useProbatContext } from \"../context/ProbatContext\";\nimport { sendMetric, extractClickMeta } from \"../utils/api\";\n\nexport interface UseProbatMetricsReturn {\n /**\n * Track a click event\n * @param event - Optional React mouse event (will extract metadata automatically)\n * @param options - Optional configuration\n * @param options.force - Force tracking even if no actionable element is found\n * @param options.proposalId - Override the proposal ID (usually not needed)\n * @param options.variantLabel - Override the variant label (usually not needed)\n * @param options.dimensions - Additional dimensions to include\n */\n trackClick: (\n event?: MouseEvent | null,\n options?: {\n force?: boolean;\n proposalId?: string;\n variantLabel?: string;\n dimensions?: Record<string, any>;\n }\n ) => boolean;\n /**\n * Track a custom metric\n * @param metricName - Name of the metric\n * @param proposalId - Proposal ID\n * @param variantLabel - Variant label (defaults to \"control\")\n * @param dimensions - Additional dimensions\n */\n trackMetric: (\n metricName: string,\n proposalId: string,\n variantLabel?: string,\n dimensions?: Record<string, any>\n ) => void;\n /**\n * Track an impression/view\n * @param proposalId - Proposal ID\n * @param variantLabel - Variant label (defaults to \"control\")\n * @param experimentId - Optional experiment ID\n */\n trackImpression: (\n proposalId: string,\n variantLabel?: string,\n experimentId?: string\n ) => void;\n}\n\n/**\n * Hook for tracking Probat metrics (clicks, impressions, custom metrics)\n *\n * @example\n * ```tsx\n * const { trackClick, trackImpression } = useProbatMetrics();\n *\n * // Track click on button\n * <button onClick={(e) => trackClick(e)}>Click me</button>\n *\n * // Track impression\n * useEffect(() => {\n * trackImpression(proposalId, variantLabel, experimentId);\n * }, [proposalId, variantLabel, experimentId]);\n * ```\n */\nexport function useProbatMetrics(): UseProbatMetricsReturn {\n const { apiBaseUrl } = useProbatContext();\n\n const trackClick = useCallback(\n (\n event?: MouseEvent | null,\n options?: {\n force?: boolean;\n proposalId?: string;\n variantLabel?: string;\n dimensions?: Record<string, any>;\n }\n ) => {\n const meta = extractClickMeta(event ?? undefined);\n if (!options?.force && event && !meta) {\n return false;\n }\n\n const proposalId = options?.proposalId;\n const variantLabel = options?.variantLabel || \"control\";\n\n if (!proposalId) {\n console.warn(\n \"[Probat] trackClick called without proposalId. Provide it in options or use useExperiment hook.\"\n );\n return false;\n }\n\n void sendMetric(\n apiBaseUrl,\n proposalId,\n \"click\",\n variantLabel,\n undefined,\n { ...meta, ...options?.dimensions }\n );\n return true;\n },\n [apiBaseUrl]\n );\n\n const trackMetric = useCallback(\n (\n metricName: string,\n proposalId: string,\n variantLabel: string = \"control\",\n dimensions: Record<string, any> = {}\n ) => {\n void sendMetric(\n apiBaseUrl,\n proposalId,\n metricName,\n variantLabel,\n undefined,\n dimensions\n );\n },\n [apiBaseUrl]\n );\n\n const trackImpression = useCallback(\n (\n proposalId: string,\n variantLabel: string = \"control\",\n experimentId?: string\n ) => {\n void sendMetric(\n apiBaseUrl,\n proposalId,\n \"visit\",\n variantLabel,\n experimentId\n );\n },\n [apiBaseUrl]\n );\n\n return {\n trackClick,\n trackMetric,\n trackImpression,\n };\n}\n\n","const TTL_MS = 6 * 60 * 60 * 1000; // 6 hours\n\nexport type Choice = {\n experiment_id: string;\n label: string;\n ts: number;\n};\n\nexport function safeGet(k: string): any | null {\n try {\n const raw = localStorage.getItem(k);\n return raw ? JSON.parse(raw) : null;\n } catch {\n return null;\n }\n}\n\nexport function safeSet(k: string, v: any) {\n try {\n localStorage.setItem(k, JSON.stringify(v));\n } catch { }\n}\n\nexport function now() {\n return Date.now();\n}\n\nexport function fresh(ts: number) {\n return now() - ts <= TTL_MS;\n}\n\nexport const KEY = (proposalId: string) => `probat_choice_v3:${proposalId}`;\nexport const VISIT_KEY = (proposalId: string, label: string) =>\n `probat_visit_v1:${proposalId}:${label}`;\n\nexport function readChoice(proposalId: string): Choice | null {\n const c = safeGet(KEY(proposalId)) as Choice | null;\n return c && fresh(c.ts) ? c : null;\n}\n\nexport function writeChoice(\n proposalId: string,\n experiment_id: string,\n label: string\n) {\n safeSet(KEY(proposalId), { experiment_id, label, ts: now() } as Choice);\n}\n\nconst visitMemo = new Set<string>();\n\nexport function hasTrackedVisit(proposalId: string, label: string): boolean {\n const key = VISIT_KEY(proposalId, label);\n if (visitMemo.has(key)) return true;\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return false;\n const ts = Number(raw);\n if (!Number.isFinite(ts) || ts <= 0) return false;\n if (now() - ts > TTL_MS) {\n localStorage.removeItem(key);\n return false;\n }\n visitMemo.add(key);\n return true;\n } catch {\n return false;\n }\n}\n\nexport function markTrackedVisit(proposalId: string, label: string) {\n const key = VISIT_KEY(proposalId, label);\n visitMemo.add(key);\n try {\n localStorage.setItem(key, now().toString());\n } catch { }\n}\n\n","\"use client\";\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport type { MouseEvent } from \"react\";\nimport { useProbatContext } from \"../context/ProbatContext\";\nimport { fetchDecision } from \"../utils/api\";\nimport {\n readChoice,\n writeChoice,\n hasTrackedVisit,\n markTrackedVisit,\n} from \"../utils/storage\";\nimport { sendMetric } from \"../utils/api\";\n\nexport interface UseExperimentReturn {\n /**\n * The current variant label (e.g., \"control\", \"variant-a\")\n */\n variantLabel: string;\n /**\n * The experiment ID\n */\n experimentId: string | null;\n /**\n * Whether the experiment decision is still loading\n */\n isLoading: boolean;\n /**\n * Any error that occurred while fetching the experiment\n */\n error: Error | null;\n /**\n * Manually track a click for this experiment\n */\n trackClick: (event?: MouseEvent | null) => void;\n}\n\n/**\n * Hook for fetching and applying experiment variants\n *\n * @param proposalId - The proposal ID for the experiment\n * @param options - Optional configuration\n * @param options.autoTrackImpression - Automatically track impression when variant is loaded (default: true)\n *\n * @example\n * ```tsx\n * const { variantLabel, isLoading, trackClick } = useExperiment(\"proposal-id\");\n *\n * if (isLoading) return <div>Loading...</div>;\n *\n * return (\n * <div onClick={trackClick}>\n * {variantLabel === \"control\" ? <ControlComponent /> : <VariantComponent />}\n * </div>\n * );\n * ```\n */\nexport function useExperiment(\n proposalId: string,\n options?: { autoTrackImpression?: boolean }\n): UseExperimentReturn {\n const { apiBaseUrl } = useProbatContext();\n const [choice, setChoice] = useState<{\n experiment_id: string;\n label: string;\n } | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n const autoTrackImpression = options?.autoTrackImpression !== false;\n\n // Fetch experiment decision\n useEffect(() => {\n let alive = true;\n\n const cached = readChoice(proposalId);\n if (cached) {\n setChoice({ experiment_id: cached.experiment_id, label: cached.label });\n setIsLoading(false);\n } else {\n setIsLoading(true);\n (async () => {\n try {\n const { experiment_id, label } = await fetchDecision(\n apiBaseUrl,\n proposalId\n );\n if (!alive) return;\n writeChoice(proposalId, experiment_id, label);\n setChoice({ experiment_id, label });\n setError(null);\n } catch (e) {\n if (!alive) return;\n const err = e instanceof Error ? e : new Error(String(e));\n setError(err);\n setChoice({\n experiment_id: `exp_${proposalId}`,\n label: \"control\",\n });\n } finally {\n if (alive) {\n setIsLoading(false);\n }\n }\n })();\n }\n\n return () => {\n alive = false;\n };\n }, [proposalId, apiBaseUrl]);\n\n // Track impression when variant is determined\n useEffect(() => {\n if (!autoTrackImpression || !choice) return;\n\n const exp = choice.experiment_id;\n const lbl = choice.label ?? \"control\";\n if (!lbl) return;\n\n // Only track if we haven't already tracked this visit\n if (hasTrackedVisit(proposalId, lbl)) return;\n markTrackedVisit(proposalId, lbl);\n void sendMetric(apiBaseUrl, proposalId, \"visit\", lbl, exp);\n }, [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl, autoTrackImpression]);\n\n const trackClick = useCallback(\n (event?: MouseEvent | null) => {\n const exp = choice?.experiment_id;\n const lbl = choice?.label ?? \"control\";\n const meta = event\n ? (() => {\n const rawTarget = event.target as HTMLElement | null;\n if (!rawTarget) return undefined;\n const actionable = rawTarget.closest(\n \"[data-probat-conversion='true'], button, a, [role='button']\"\n );\n if (!actionable) return undefined;\n const meta: Record<string, any> = {\n target_tag: actionable.tagName,\n };\n if (actionable.id) meta.target_id = actionable.id;\n const attr = actionable.getAttribute(\"data-probat-conversion\");\n if (attr) meta.conversion_attr = attr;\n const text = actionable.textContent?.trim();\n if (text) meta.target_text = text.slice(0, 120);\n return meta;\n })()\n : undefined;\n\n void sendMetric(apiBaseUrl, proposalId, \"click\", lbl, undefined, meta);\n },\n [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl]\n );\n\n return {\n variantLabel: choice?.label ?? \"control\",\n experimentId: choice?.experiment_id ?? null,\n isLoading,\n error,\n trackClick,\n };\n}\n\n","\"use client\";\n\nimport React, { useState, useEffect, useCallback } from \"react\";\nimport type { MouseEvent } from \"react\";\nimport { useProbatContext } from \"../context/ProbatContext\";\nimport {\n fetchDecision,\n fetchComponentExperimentConfig,\n loadVariantComponent,\n sendMetric,\n extractClickMeta,\n} from \"../utils/api\";\nimport {\n readChoice,\n writeChoice,\n hasTrackedVisit,\n markTrackedVisit,\n} from \"../utils/storage\";\n\n// Support both old and new API for backward compatibility\nexport interface WithExperimentOptions {\n // New API: component-based\n componentPath?: string;\n repoFullName?: string;\n\n // Old API: direct proposal/registry (for backward compatibility)\n proposalId?: string;\n registry?: Record<string, React.ComponentType<any>>;\n}\n\n/**\n * Higher-Order Component for wrapping components with experiment variants\n */\nexport function withExperiment<P = any>(\n Control: React.ComponentType<P>,\n options: WithExperimentOptions\n): React.ComponentType<P & { probat?: { trackClick: () => void } }> {\n // Validate inputs at HOC level (not in component)\n if (!Control) {\n console.error(\"[PROBAT] withExperiment: Control component is required\");\n return ((props: P) => null) as any;\n }\n\n if (!options || typeof options !== 'object') {\n console.error(\"[PROBAT] withExperiment: options is required\");\n return Control as any;\n }\n\n const useNewAPI = !!options.componentPath;\n const useOldAPI = !!(options.proposalId && options.registry);\n\n if (!useNewAPI && !useOldAPI) {\n console.warn(\"[PROBAT] withExperiment: Invalid config, returning Control\");\n return Control as any;\n }\n\n const ControlComponent = Control;\n\n function Wrapped(props: P) {\n // ============================================================\n // ALL HOOKS MUST BE AT THE TOP - BEFORE ANY CONDITIONAL RETURNS\n // ============================================================\n\n // 1. Context hook - always called first\n const context = useProbatContext();\n const apiBaseUrl = context?.apiBaseUrl || \"https://gushi.onrender.com\";\n const contextRepoFullName = context?.repoFullName;\n\n // 2. State hooks - always called in same order\n const [config, setConfig] = useState<{\n proposalId: string;\n variants: Record<string, React.ComponentType<any>>;\n } | null>(null);\n const [configLoading, setConfigLoading] = useState(useNewAPI);\n const [choice, setChoice] = useState<{\n experiment_id: string;\n label: string;\n } | null>(null);\n\n // Derived values\n const repoFullName = options.repoFullName || contextRepoFullName;\n const proposalId = useNewAPI ? config?.proposalId : options.proposalId;\n\n // 3. Effect hooks - always called\n // Load component config (new API)\n useEffect(() => {\n if (!useNewAPI) return;\n if (!repoFullName) {\n console.warn(\"[PROBAT] componentPath provided but repoFullName not found\");\n setConfigLoading(false);\n return;\n }\n\n let alive = true;\n setConfigLoading(true);\n\n (async () => {\n try {\n const componentConfig = await fetchComponentExperimentConfig(\n apiBaseUrl,\n repoFullName,\n options.componentPath!\n );\n\n if (!alive) return;\n\n if (!componentConfig) {\n setConfig(null);\n setConfigLoading(false);\n return;\n }\n\n const variantComponents: Record<string, React.ComponentType<any>> = {\n control: ControlComponent,\n };\n\n for (const [label, variantInfo] of Object.entries(componentConfig.variants)) {\n if (label === \"control\") continue;\n if (variantInfo?.file_path) {\n try {\n const VariantComp = await loadVariantComponent(\n apiBaseUrl,\n componentConfig.proposal_id,\n variantInfo.experiment_id,\n variantInfo.file_path,\n componentConfig.repo_full_name,\n componentConfig.base_ref\n );\n if (VariantComp && typeof VariantComp === 'function' && alive) {\n variantComponents[label] = VariantComp;\n }\n } catch (e) {\n console.warn(`[PROBAT] Failed to load variant ${label}:`, e);\n }\n }\n }\n\n if (alive) {\n setConfig({\n proposalId: componentConfig.proposal_id,\n variants: variantComponents,\n });\n setConfigLoading(false);\n }\n } catch (e) {\n console.warn(\"[PROBAT] Failed to load component config:\", e);\n if (alive) {\n setConfig(null);\n setConfigLoading(false);\n }\n }\n })();\n\n return () => { alive = false; };\n }, [useNewAPI, options.componentPath, repoFullName, apiBaseUrl]);\n\n // Fetch experiment decision\n useEffect(() => {\n if (!proposalId) return;\n if (useNewAPI && configLoading) return;\n\n let alive = true;\n const cached = readChoice(proposalId);\n\n if (cached) {\n setChoice({\n experiment_id: cached.experiment_id,\n label: cached.label,\n });\n } else {\n (async () => {\n try {\n const { experiment_id, label } = await fetchDecision(apiBaseUrl, proposalId);\n if (!alive) return;\n writeChoice(proposalId, experiment_id, label);\n setChoice({ experiment_id, label });\n } catch (e) {\n if (!alive) return;\n setChoice({\n experiment_id: `exp_${proposalId}`,\n label: \"control\",\n });\n }\n })();\n }\n\n return () => { alive = false; };\n }, [proposalId, apiBaseUrl, useNewAPI, configLoading]);\n\n // Track visit\n useEffect(() => {\n if (!proposalId) return;\n const lbl = choice?.label ?? \"control\";\n if (!lbl || hasTrackedVisit(proposalId, lbl)) return;\n markTrackedVisit(proposalId, lbl);\n void sendMetric(apiBaseUrl, proposalId, \"visit\", lbl, choice?.experiment_id);\n }, [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl]);\n\n // 4. Callback hooks - always called\n const trackClick = useCallback(\n (event?: MouseEvent | null, opts?: { force?: boolean }) => {\n if (!proposalId) return false;\n const lbl = choice?.label ?? \"control\";\n const meta = extractClickMeta(event ?? undefined);\n if (!opts?.force && event && !meta) return false;\n void sendMetric(apiBaseUrl, proposalId, \"click\", lbl, undefined, meta);\n return true;\n },\n [proposalId, choice?.experiment_id, choice?.label, apiBaseUrl]\n );\n\n // ============================================================\n // NOW WE CAN DO CONDITIONAL RETURNS - AFTER ALL HOOKS\n // ============================================================\n\n // Loading state - return control\n if (useNewAPI && (configLoading || !config || !proposalId)) {\n return React.createElement(ControlComponent as any, props as any);\n }\n\n // No proposalId - return control\n if (!proposalId) {\n return React.createElement(ControlComponent as any, props as any);\n }\n\n // Build registry - always has control\n const registry: Record<string, React.ComponentType<any>> = { control: ControlComponent };\n\n if (useNewAPI && config?.variants) {\n for (const [key, value] of Object.entries(config.variants)) {\n if (key !== 'control' && value && typeof value === 'function') {\n registry[key] = value;\n }\n }\n } else if (!useNewAPI && options.registry) {\n for (const [key, value] of Object.entries(options.registry)) {\n if (key !== 'control' && value && typeof value === 'function') {\n registry[key] = value;\n }\n }\n }\n\n // Select variant\n const label = choice?.label ?? \"control\";\n const Variant = registry[label] || registry.control || ControlComponent;\n\n return (\n <div onClick={(event) => trackClick(event)} data-probat-proposal={proposalId}>\n {React.createElement(Variant, {\n key: `${proposalId}:${label}`,\n ...(props as any),\n probat: { trackClick: () => trackClick(null, { force: true }) },\n })}\n </div>\n );\n }\n\n Wrapped.displayName = `withExperiment(${Control.displayName || Control.name || \"Component\"})`;\n return Wrapped as any;\n}\n"]}