@probat/react 0.1.2 → 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.d.mts CHANGED
@@ -190,33 +190,4 @@ declare function writeChoice(proposalId: string, experiment_id: string, label: s
190
190
  declare function hasTrackedVisit(proposalId: string, label: string): boolean;
191
191
  declare function markTrackedVisit(proposalId: string, label: string): void;
192
192
 
193
- /**
194
- * Document-level click tracking for Probat experiments
195
- *
196
- * This module implements event delegation at the document level to track clicks
197
- * even when components don't have onClick handlers or when stopPropagation() is called.
198
- */
199
- /**
200
- * Initialize document-level click tracking
201
- * Call this once when your app initializes (typically in ProbatProvider)
202
- */
203
- declare function initDocumentClickTracking(): void;
204
- /**
205
- * Clean up the listener (useful for testing or cleanup)
206
- */
207
- declare function cleanupDocumentClickTracking(): void;
208
- /**
209
- * Update proposal metadata cache (call this when proposal data changes)
210
- * This is useful if you want to update the cache without waiting for DOM queries
211
- */
212
- declare function updateProposalMetadata(proposalId: string, metadata: {
213
- experimentId?: string | null;
214
- variantLabel?: string;
215
- apiBaseUrl?: string;
216
- }): void;
217
- /**
218
- * Clear the proposal cache (useful for testing)
219
- */
220
- declare function clearProposalCache(): void;
221
-
222
- export { type Choice, type ProbatContextValue, ProbatProvider, ProbatProviderClient, type ProbatProviderProps as ProbatProviderClientProps, type ProbatProviderProps, type RetrieveResponse, type UseExperimentReturn, type UseProbatMetricsReturn, type WithExperimentOptions, cleanupDocumentClickTracking, clearProposalCache, detectEnvironment, extractClickMeta, fetchDecision, hasTrackedVisit, initDocumentClickTracking, markTrackedVisit, readChoice, sendMetric, updateProposalMetadata, useExperiment, useProbatContext, useProbatMetrics, withExperiment, writeChoice };
193
+ export { type Choice, type ProbatContextValue, ProbatProvider, ProbatProviderClient, type ProbatProviderProps as ProbatProviderClientProps, type ProbatProviderProps, type RetrieveResponse, type UseExperimentReturn, type UseProbatMetricsReturn, type WithExperimentOptions, detectEnvironment, extractClickMeta, fetchDecision, hasTrackedVisit, markTrackedVisit, readChoice, sendMetric, useExperiment, useProbatContext, useProbatMetrics, withExperiment, writeChoice };
package/dist/index.d.ts CHANGED
@@ -190,33 +190,4 @@ declare function writeChoice(proposalId: string, experiment_id: string, label: s
190
190
  declare function hasTrackedVisit(proposalId: string, label: string): boolean;
191
191
  declare function markTrackedVisit(proposalId: string, label: string): void;
192
192
 
193
- /**
194
- * Document-level click tracking for Probat experiments
195
- *
196
- * This module implements event delegation at the document level to track clicks
197
- * even when components don't have onClick handlers or when stopPropagation() is called.
198
- */
199
- /**
200
- * Initialize document-level click tracking
201
- * Call this once when your app initializes (typically in ProbatProvider)
202
- */
203
- declare function initDocumentClickTracking(): void;
204
- /**
205
- * Clean up the listener (useful for testing or cleanup)
206
- */
207
- declare function cleanupDocumentClickTracking(): void;
208
- /**
209
- * Update proposal metadata cache (call this when proposal data changes)
210
- * This is useful if you want to update the cache without waiting for DOM queries
211
- */
212
- declare function updateProposalMetadata(proposalId: string, metadata: {
213
- experimentId?: string | null;
214
- variantLabel?: string;
215
- apiBaseUrl?: string;
216
- }): void;
217
- /**
218
- * Clear the proposal cache (useful for testing)
219
- */
220
- declare function clearProposalCache(): void;
221
-
222
- export { type Choice, type ProbatContextValue, ProbatProvider, ProbatProviderClient, type ProbatProviderProps as ProbatProviderClientProps, type ProbatProviderProps, type RetrieveResponse, type UseExperimentReturn, type UseProbatMetricsReturn, type WithExperimentOptions, cleanupDocumentClickTracking, clearProposalCache, detectEnvironment, extractClickMeta, fetchDecision, hasTrackedVisit, initDocumentClickTracking, markTrackedVisit, readChoice, sendMetric, updateProposalMetadata, useExperiment, useProbatContext, useProbatMetrics, withExperiment, writeChoice };
193
+ export { type Choice, type ProbatContextValue, ProbatProvider, ProbatProviderClient, type ProbatProviderProps as ProbatProviderClientProps, type ProbatProviderProps, type RetrieveResponse, type UseExperimentReturn, type UseProbatMetricsReturn, type WithExperimentOptions, detectEnvironment, extractClickMeta, fetchDecision, hasTrackedVisit, markTrackedVisit, readChoice, sendMetric, useExperiment, useProbatContext, useProbatMetrics, withExperiment, writeChoice };
package/dist/index.js CHANGED
@@ -20,6 +20,41 @@ function detectEnvironment() {
20
20
  }
21
21
  return "prod";
22
22
  }
23
+
24
+ // src/context/ProbatContext.tsx
25
+ var ProbatContext = React4.createContext(null);
26
+ function ProbatProvider({
27
+ apiBaseUrl,
28
+ clientKey,
29
+ environment: explicitEnvironment,
30
+ repoFullName: explicitRepoFullName,
31
+ children
32
+ }) {
33
+ const contextValue = React4.useMemo(() => {
34
+ const resolvedApiBaseUrl = apiBaseUrl || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== "undefined" && undefined?.VITE_PROBAT_API || typeof globalThis !== "undefined" && globalThis.process?.env?.NEXT_PUBLIC_PROBAT_API || typeof window !== "undefined" && window.__PROBAT_API || "https://gushi.onrender.com";
35
+ const environment = explicitEnvironment || detectEnvironment();
36
+ const resolvedRepoFullName = explicitRepoFullName || typeof globalThis !== "undefined" && globalThis.process?.env?.NEXT_PUBLIC_PROBAT_REPO || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== "undefined" && undefined?.VITE_PROBAT_REPO || typeof window !== "undefined" && window.__PROBAT_REPO || void 0;
37
+ return {
38
+ apiBaseUrl: resolvedApiBaseUrl,
39
+ environment,
40
+ clientKey,
41
+ repoFullName: resolvedRepoFullName
42
+ };
43
+ }, [apiBaseUrl, clientKey, explicitEnvironment, explicitRepoFullName]);
44
+ return /* @__PURE__ */ React4__default.default.createElement(ProbatContext.Provider, { value: contextValue }, children);
45
+ }
46
+ function useProbatContext() {
47
+ const context = React4.useContext(ProbatContext);
48
+ if (!context) {
49
+ throw new Error(
50
+ "useProbatContext must be used within a ProbatProvider. Please wrap your app with <ProbatProvider>."
51
+ );
52
+ }
53
+ return context;
54
+ }
55
+ function ProbatProviderClient(props) {
56
+ return React4__default.default.createElement(ProbatProvider, props);
57
+ }
23
58
  var pendingFetches = /* @__PURE__ */ new Map();
24
59
  async function fetchDecision(baseUrl, proposalId) {
25
60
  const existingFetch = pendingFetches.get(proposalId);
@@ -62,7 +97,7 @@ async function sendMetric(baseUrl, proposalId, metricName, variantLabel = "contr
62
97
  captured_at: (/* @__PURE__ */ new Date()).toISOString()
63
98
  };
64
99
  try {
65
- const response = await fetch(url, {
100
+ await fetch(url, {
66
101
  method: "POST",
67
102
  headers: {
68
103
  Accept: "application/json",
@@ -72,26 +107,7 @@ async function sendMetric(baseUrl, proposalId, metricName, variantLabel = "contr
72
107
  // CRITICAL: Include cookies to distinguish different users
73
108
  body: JSON.stringify(body)
74
109
  });
75
- if (!response.ok) {
76
- console.warn("[PROBAT] Metric send failed:", {
77
- status: response.status,
78
- statusText: response.statusText,
79
- url,
80
- body
81
- });
82
- } else {
83
- console.log("[PROBAT] Metric sent successfully:", {
84
- metricName,
85
- proposalId,
86
- variantLabel
87
- });
88
- }
89
- } catch (error) {
90
- console.error("[PROBAT] Error sending metric:", {
91
- error: error instanceof Error ? error.message : String(error),
92
- url,
93
- body
94
- });
110
+ } catch {
95
111
  }
96
112
  }
97
113
  function extractClickMeta(event) {
@@ -152,7 +168,7 @@ if (typeof window !== "undefined") {
152
168
  window.__probatReact = React4__default.default;
153
169
  window.React = window.React || React4__default.default;
154
170
  }
155
- async function loadVariantComponent(baseUrl, proposalId, experimentId, filePath) {
171
+ async function loadVariantComponent(baseUrl, proposalId, experimentId, filePath, repoFullName, baseRef) {
156
172
  if (!filePath) {
157
173
  return null;
158
174
  }
@@ -163,16 +179,151 @@ async function loadVariantComponent(baseUrl, proposalId, experimentId, filePath)
163
179
  }
164
180
  const loadPromise = (async () => {
165
181
  try {
166
- const variantUrl = `${baseUrl.replace(/\/$/, "")}/variants/${filePath}`;
167
- const res = await fetch(variantUrl, {
168
- method: "GET",
169
- headers: { Accept: "text/javascript" },
170
- credentials: "include"
171
- });
172
- if (!res.ok) {
173
- throw new Error(`HTTP ${res.status}`);
182
+ try {
183
+ const variantUrl = `/probat/${filePath}`;
184
+ const mod = await import(
185
+ /* @vite-ignore */
186
+ variantUrl
187
+ );
188
+ const VariantComponent2 = mod?.default || mod;
189
+ if (VariantComponent2 && typeof VariantComponent2 === "function") {
190
+ return VariantComponent2;
191
+ }
192
+ } catch {
193
+ }
194
+ let code = "";
195
+ let rawCode = "";
196
+ let rawCodeFetched = false;
197
+ const localUrl = `/probat/${filePath}`;
198
+ try {
199
+ const localRes = await fetch(localUrl, {
200
+ method: "GET",
201
+ headers: { Accept: "text/plain" }
202
+ });
203
+ if (localRes.ok) {
204
+ rawCode = await localRes.text();
205
+ rawCodeFetched = true;
206
+ console.log(`[PROBAT] \u2705 Loaded variant from local (user's repo): ${localUrl}`);
207
+ }
208
+ } catch {
209
+ console.debug(`[PROBAT] Local file not available (${localUrl}), trying GitHub...`);
210
+ }
211
+ if (!rawCodeFetched && repoFullName) {
212
+ const githubPath = `probat/${filePath}`;
213
+ const gitRef = baseRef || "main";
214
+ const githubUrl = `https://raw.githubusercontent.com/${repoFullName}/${gitRef}/${githubPath}`;
215
+ const res = await fetch(githubUrl, { method: "GET", headers: { Accept: "text/plain" } });
216
+ if (res.ok) {
217
+ rawCode = await res.text();
218
+ rawCodeFetched = true;
219
+ console.log(`[PROBAT] \u26A0\uFE0F Loaded variant from GitHub (fallback): ${githubUrl}`);
220
+ } else {
221
+ console.warn(`[PROBAT] \u26A0\uFE0F GitHub fetch failed (${res.status}), falling back to server compilation`);
222
+ }
223
+ }
224
+ if (rawCodeFetched && rawCode) {
225
+ let Babel;
226
+ if (typeof window !== "undefined" && window.Babel) {
227
+ Babel = window.Babel;
228
+ } else {
229
+ try {
230
+ const babelModule = await import('@babel/standalone');
231
+ Babel = babelModule.default || babelModule;
232
+ } catch (importError) {
233
+ try {
234
+ await new Promise((resolve, reject) => {
235
+ if (typeof document === "undefined") {
236
+ reject(new Error("Document not available"));
237
+ return;
238
+ }
239
+ if (window.Babel) {
240
+ Babel = window.Babel;
241
+ resolve();
242
+ return;
243
+ }
244
+ const script = document.createElement("script");
245
+ script.src = "https://unpkg.com/@babel/standalone/babel.min.js";
246
+ script.async = true;
247
+ script.onload = () => {
248
+ Babel = window.Babel;
249
+ if (!Babel) reject(new Error("Babel not found after script load"));
250
+ else resolve();
251
+ };
252
+ script.onerror = () => reject(new Error("Failed to load Babel from CDN"));
253
+ document.head.appendChild(script);
254
+ });
255
+ } catch (babelError) {
256
+ console.error("[PROBAT] Failed to load Babel, falling back to server compilation", babelError);
257
+ rawCodeFetched = false;
258
+ }
259
+ }
260
+ }
261
+ if (rawCodeFetched && rawCode && Babel) {
262
+ const isTSX = filePath.endsWith(".tsx");
263
+ rawCode = rawCode.replace(/^import\s+['"].*\.css['"];?\s*$/gm, "");
264
+ rawCode = rawCode.replace(/^import\s+.*from\s+['"].*\.css['"];?\s*$/gm, "");
265
+ rawCode = rawCode.replace(
266
+ /^import\s+React(?:\s*,\s*\{[^}]*\})?\s+from\s+['"]react['"];?\s*$/m,
267
+ "const React = window.React || globalThis.React;"
268
+ );
269
+ rawCode = rawCode.replace(
270
+ /^import\s+\*\s+as\s+React\s+from\s+['"]react['"];?\s*$/m,
271
+ "const React = window.React || globalThis.React;"
272
+ );
273
+ rawCode = rawCode.replace(
274
+ /^import\s+\{([^}]+)\}\s+from\s+['"]react['"];?\s*$/m,
275
+ (match, imports) => `const {${imports}} = window.React || globalThis.React;`
276
+ );
277
+ rawCode = rawCode.replace(/import\.meta\.env\.[\w$]+/g, "undefined");
278
+ rawCode = rawCode.replace(/\bimport\.meta\b/g, "({})");
279
+ rawCode = rawCode.replace(/^import\s+.*\/@vite\/client.*$/gm, "");
280
+ rawCode = rawCode.replace(/import\.meta\.hot(?:\.[\w$]+)*/g, "undefined");
281
+ const compiled = Babel.transform(rawCode, {
282
+ presets: [
283
+ ["react", { runtime: "classic" }],
284
+ ["typescript", { allExtensions: true, isTSX }]
285
+ ],
286
+ plugins: [["transform-modules-commonjs", { allowTopLevelThis: true }]],
287
+ sourceType: "module",
288
+ filename: filePath
289
+ }).code;
290
+ code = `
291
+ var __probatVariant = (function() {
292
+ var require = function(name) {
293
+ if (name === "react" || name === "react/jsx-runtime") {
294
+ return window.React || globalThis.React;
295
+ }
296
+ if (name.startsWith("/@vite") || name.includes("@vite/client") || name.includes(".vite/deps")) {
297
+ return {};
298
+ }
299
+ if (name === "react/jsx-runtime.js") {
300
+ return window.React || globalThis.React;
301
+ }
302
+ throw new Error("Unsupported module: " + name);
303
+ };
304
+ var module = { exports: {} };
305
+ var exports = module.exports;
306
+ ${compiled}
307
+ return module.exports.default || module.exports;
308
+ })();
309
+ `;
310
+ } else {
311
+ rawCodeFetched = false;
312
+ code = "";
313
+ }
314
+ }
315
+ if (!rawCodeFetched || code === "") {
316
+ const variantUrl = `${baseUrl.replace(/\/$/, "")}/variants/${filePath}`;
317
+ const serverRes = await fetch(variantUrl, {
318
+ method: "GET",
319
+ headers: { Accept: "text/javascript" },
320
+ credentials: "include"
321
+ });
322
+ if (!serverRes.ok) {
323
+ throw new Error(`HTTP ${serverRes.status}`);
324
+ }
325
+ code = await serverRes.text();
174
326
  }
175
- const code = await res.text();
176
327
  if (typeof window !== "undefined") {
177
328
  window.React = window.React || React4__default.default;
178
329
  }
@@ -199,146 +350,7 @@ async function loadVariantComponent(baseUrl, proposalId, experimentId, filePath)
199
350
  return loadPromise;
200
351
  }
201
352
 
202
- // src/utils/documentClickTracker.ts
203
- var proposalCache = /* @__PURE__ */ new Map();
204
- var isListenerAttached = false;
205
- var lastClickTime = /* @__PURE__ */ new Map();
206
- var DEBOUNCE_MS = 100;
207
- function getProposalMetadata(element) {
208
- const probatWrapper = element.closest("[data-probat-proposal]");
209
- if (!probatWrapper) return null;
210
- const proposalId = probatWrapper.getAttribute("data-probat-proposal");
211
- if (!proposalId) return null;
212
- const cacheKey = `${proposalId}`;
213
- const cached = proposalCache.get(cacheKey);
214
- if (cached) return cached;
215
- const experimentId = probatWrapper.getAttribute("data-probat-experiment-id");
216
- const variantLabel = probatWrapper.getAttribute("data-probat-variant-label") || "control";
217
- const apiBaseUrl = probatWrapper.getAttribute("data-probat-api-base-url") || typeof window !== "undefined" && window.__PROBAT_API || "https://gushi.onrender.com";
218
- const metadata = {
219
- proposalId,
220
- experimentId: experimentId || null,
221
- variantLabel,
222
- apiBaseUrl
223
- };
224
- proposalCache.set(cacheKey, metadata);
225
- return metadata;
226
- }
227
- function handleDocumentClick(event) {
228
- const target = event.target;
229
- if (!target) return;
230
- const metadata = getProposalMetadata(target);
231
- if (!metadata) {
232
- return;
233
- }
234
- const now2 = Date.now();
235
- const lastClick = lastClickTime.get(metadata.proposalId) || 0;
236
- if (now2 - lastClick < DEBOUNCE_MS) {
237
- return;
238
- }
239
- lastClickTime.set(metadata.proposalId, now2);
240
- const clickMeta = extractClickMeta(event);
241
- target.hasAttribute("data-probat-track") || target.closest("[data-probat-track]") !== null;
242
- const finalMeta = clickMeta || {
243
- target_tag: target.tagName,
244
- target_class: target.className || "",
245
- target_id: target.id || "",
246
- clicked_inside_probat: true
247
- // Flag to indicate this was tracked via document-level listener
248
- };
249
- const experimentId = metadata.variantLabel === "control" ? void 0 : metadata.experimentId && !metadata.experimentId.startsWith("exp_") ? metadata.experimentId : void 0;
250
- void sendMetric(
251
- metadata.apiBaseUrl,
252
- metadata.proposalId,
253
- "click",
254
- metadata.variantLabel,
255
- experimentId,
256
- finalMeta
257
- );
258
- console.log("[PROBAT] Click tracked:", {
259
- proposalId: metadata.proposalId,
260
- variantLabel: metadata.variantLabel,
261
- target: target.tagName,
262
- targetId: target.id || "none",
263
- targetClass: target.className || "none",
264
- meta: finalMeta
265
- });
266
- console.log("[PROBAT] Sending metric to:", `${metadata.apiBaseUrl}/send_metrics/${metadata.proposalId}`);
267
- }
268
- function initDocumentClickTracking() {
269
- if (isListenerAttached) {
270
- console.warn("[PROBAT] Document click listener already attached");
271
- return;
272
- }
273
- if (typeof document === "undefined") {
274
- return;
275
- }
276
- document.addEventListener("click", handleDocumentClick, true);
277
- isListenerAttached = true;
278
- console.log("[PROBAT] Document-level click tracking initialized");
279
- }
280
- function cleanupDocumentClickTracking() {
281
- if (!isListenerAttached) return;
282
- if (typeof document !== "undefined") {
283
- document.removeEventListener("click", handleDocumentClick, true);
284
- }
285
- isListenerAttached = false;
286
- proposalCache.clear();
287
- lastClickTime.clear();
288
- }
289
- function updateProposalMetadata(proposalId, metadata) {
290
- const existing = proposalCache.get(proposalId);
291
- if (existing) {
292
- proposalCache.set(proposalId, {
293
- ...existing,
294
- ...metadata
295
- });
296
- }
297
- }
298
- function clearProposalCache() {
299
- proposalCache.clear();
300
- }
301
-
302
- // src/context/ProbatContext.tsx
303
- var ProbatContext = React4.createContext(null);
304
- function ProbatProvider({
305
- apiBaseUrl,
306
- clientKey,
307
- environment: explicitEnvironment,
308
- repoFullName: explicitRepoFullName,
309
- children
310
- }) {
311
- const contextValue = React4.useMemo(() => {
312
- const resolvedApiBaseUrl = apiBaseUrl || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== "undefined" && undefined?.VITE_PROBAT_API || typeof globalThis !== "undefined" && globalThis.process?.env?.NEXT_PUBLIC_PROBAT_API || typeof window !== "undefined" && window.__PROBAT_API || "https://gushi.onrender.com";
313
- const environment = explicitEnvironment || detectEnvironment();
314
- const resolvedRepoFullName = explicitRepoFullName || typeof globalThis !== "undefined" && globalThis.process?.env?.NEXT_PUBLIC_PROBAT_REPO || typeof ({ url: (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)) }) !== "undefined" && undefined?.VITE_PROBAT_REPO || typeof window !== "undefined" && window.__PROBAT_REPO || void 0;
315
- return {
316
- apiBaseUrl: resolvedApiBaseUrl,
317
- environment,
318
- clientKey,
319
- repoFullName: resolvedRepoFullName
320
- };
321
- }, [apiBaseUrl, clientKey, explicitEnvironment, explicitRepoFullName]);
322
- React4.useEffect(() => {
323
- initDocumentClickTracking();
324
- return () => {
325
- cleanupDocumentClickTracking();
326
- };
327
- }, []);
328
- return /* @__PURE__ */ React4__default.default.createElement(ProbatContext.Provider, { value: contextValue }, children);
329
- }
330
- function useProbatContext() {
331
- const context = React4.useContext(ProbatContext);
332
- if (!context) {
333
- throw new Error(
334
- "useProbatContext must be used within a ProbatProvider. Please wrap your app with <ProbatProvider>."
335
- );
336
- }
337
- return context;
338
- }
339
- function ProbatProviderClient(props) {
340
- return React4__default.default.createElement(ProbatProvider, props);
341
- }
353
+ // src/hooks/useProbatMetrics.ts
342
354
  function useProbatMetrics() {
343
355
  const { apiBaseUrl } = useProbatContext();
344
356
  const trackClick = React4.useCallback(
@@ -602,7 +614,9 @@ function withExperiment(Control, options) {
602
614
  apiBaseUrl,
603
615
  componentConfig.proposal_id,
604
616
  variantInfo.experiment_id,
605
- variantInfo.file_path
617
+ variantInfo.file_path,
618
+ componentConfig.repo_full_name,
619
+ componentConfig.base_ref
606
620
  );
607
621
  if (VariantComp && typeof VariantComp === "function" && alive) {
608
622
  variantComponents[label2] = VariantComp;
@@ -701,23 +715,11 @@ function withExperiment(Control, options) {
701
715
  }
702
716
  const label = choice?.label ?? "control";
703
717
  const Variant = registry[label] || registry.control || ControlComponent;
704
- return /* @__PURE__ */ React4__default.default.createElement(
705
- "div",
706
- {
707
- onClick: (event) => {
708
- trackClick(event);
709
- },
710
- "data-probat-proposal": proposalId,
711
- "data-probat-experiment-id": choice?.experiment_id || "",
712
- "data-probat-variant-label": label,
713
- "data-probat-api-base-url": apiBaseUrl
714
- },
715
- React4__default.default.createElement(Variant, {
716
- key: `${proposalId}:${label}`,
717
- ...props,
718
- probat: { trackClick: () => trackClick(null, { force: true }) }
719
- })
720
- );
718
+ return /* @__PURE__ */ React4__default.default.createElement("div", { onClick: (event) => trackClick(event), "data-probat-proposal": proposalId }, React4__default.default.createElement(Variant, {
719
+ key: `${proposalId}:${label}`,
720
+ ...props,
721
+ probat: { trackClick: () => trackClick(null, { force: true }) }
722
+ }));
721
723
  }
722
724
  Wrapped.displayName = `withExperiment(${Control.displayName || Control.name || "Component"})`;
723
725
  return Wrapped;
@@ -725,17 +727,13 @@ function withExperiment(Control, options) {
725
727
 
726
728
  exports.ProbatProvider = ProbatProvider;
727
729
  exports.ProbatProviderClient = ProbatProviderClient;
728
- exports.cleanupDocumentClickTracking = cleanupDocumentClickTracking;
729
- exports.clearProposalCache = clearProposalCache;
730
730
  exports.detectEnvironment = detectEnvironment;
731
731
  exports.extractClickMeta = extractClickMeta;
732
732
  exports.fetchDecision = fetchDecision;
733
733
  exports.hasTrackedVisit = hasTrackedVisit;
734
- exports.initDocumentClickTracking = initDocumentClickTracking;
735
734
  exports.markTrackedVisit = markTrackedVisit;
736
735
  exports.readChoice = readChoice;
737
736
  exports.sendMetric = sendMetric;
738
- exports.updateProposalMetadata = updateProposalMetadata;
739
737
  exports.useExperiment = useExperiment;
740
738
  exports.useProbatContext = useProbatContext;
741
739
  exports.useProbatMetrics = useProbatMetrics;