@probat/react 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -344
- package/dist/index.d.mts +76 -224
- package/dist/index.d.ts +76 -224
- package/dist/index.js +397 -1185
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +394 -1169
- package/dist/index.mjs.map +1 -1
- package/package.json +19 -12
- package/src/__tests__/Experiment.test.tsx +764 -0
- package/src/__tests__/setup.ts +63 -0
- package/src/__tests__/utils.test.ts +79 -0
- package/src/components/Experiment.tsx +291 -0
- package/src/components/ProbatProviderClient.tsx +19 -7
- package/src/context/ProbatContext.tsx +30 -132
- package/src/hooks/useProbatMetrics.ts +18 -134
- package/src/index.ts +9 -32
- package/src/utils/api.ts +96 -577
- package/src/utils/dedupeStorage.ts +40 -0
- package/src/utils/eventContext.ts +94 -0
- package/src/utils/stableInstanceId.ts +113 -0
- package/src/utils/storage.ts +18 -60
- package/src/hoc/itrt-frontend.code-workspace +0 -38
- package/src/hoc/withExperiment.tsx +0 -290
- package/src/hooks/useExperiment.ts +0 -164
- package/src/utils/documentClickTracker.ts +0 -215
- package/src/utils/heatmapTracker.ts +0 -478
|
@@ -1,152 +1,36 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useCallback } from "react";
|
|
4
|
-
import type { MouseEvent } from "react";
|
|
5
4
|
import { useProbatContext } from "../context/ProbatContext";
|
|
6
|
-
import { sendMetric
|
|
5
|
+
import { sendMetric } from "../utils/api";
|
|
7
6
|
|
|
8
7
|
export interface UseProbatMetricsReturn {
|
|
9
8
|
/**
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* @
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
9
|
+
* Send a custom event with arbitrary properties.
|
|
10
|
+
* Never throws — failures are silently dropped.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* ```tsx
|
|
14
|
+
* const { capture } = useProbatMetrics();
|
|
15
|
+
* capture("purchase", { revenue: 42, currency: "USD" });
|
|
16
|
+
* ```
|
|
17
17
|
*/
|
|
18
|
-
|
|
19
|
-
event?: MouseEvent | null,
|
|
20
|
-
options?: {
|
|
21
|
-
force?: boolean;
|
|
22
|
-
proposalId?: string;
|
|
23
|
-
variantLabel?: string;
|
|
24
|
-
dimensions?: Record<string, any>;
|
|
25
|
-
}
|
|
26
|
-
) => boolean;
|
|
27
|
-
/**
|
|
28
|
-
* Track a custom metric
|
|
29
|
-
* @param metricName - Name of the metric
|
|
30
|
-
* @param proposalId - Proposal ID
|
|
31
|
-
* @param variantLabel - Variant label (defaults to "control")
|
|
32
|
-
* @param dimensions - Additional dimensions
|
|
33
|
-
*/
|
|
34
|
-
trackMetric: (
|
|
35
|
-
metricName: string,
|
|
36
|
-
proposalId: string,
|
|
37
|
-
variantLabel?: string,
|
|
38
|
-
dimensions?: Record<string, any>
|
|
39
|
-
) => void;
|
|
40
|
-
/**
|
|
41
|
-
* Track an impression/view
|
|
42
|
-
* @param proposalId - Proposal ID
|
|
43
|
-
* @param variantLabel - Variant label (defaults to "control")
|
|
44
|
-
* @param experimentId - Optional experiment ID
|
|
45
|
-
*/
|
|
46
|
-
trackImpression: (
|
|
47
|
-
proposalId: string,
|
|
48
|
-
variantLabel?: string,
|
|
49
|
-
experimentId?: string
|
|
50
|
-
) => void;
|
|
18
|
+
capture: (event: string, properties?: Record<string, unknown>) => void;
|
|
51
19
|
}
|
|
52
20
|
|
|
53
21
|
/**
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
* @example
|
|
57
|
-
* ```tsx
|
|
58
|
-
* const { trackClick, trackImpression } = useProbatMetrics();
|
|
59
|
-
*
|
|
60
|
-
* // Track click on button
|
|
61
|
-
* <button onClick={(e) => trackClick(e)}>Click me</button>
|
|
62
|
-
*
|
|
63
|
-
* // Track impression
|
|
64
|
-
* useEffect(() => {
|
|
65
|
-
* trackImpression(proposalId, variantLabel, experimentId);
|
|
66
|
-
* }, [proposalId, variantLabel, experimentId]);
|
|
67
|
-
* ```
|
|
22
|
+
* Minimal metrics hook. Provides a single `capture(event, props)` function
|
|
23
|
+
* that sends events to the Probat backend using the provider's host config.
|
|
68
24
|
*/
|
|
69
25
|
export function useProbatMetrics(): UseProbatMetricsReturn {
|
|
70
|
-
const {
|
|
71
|
-
|
|
72
|
-
const trackClick = useCallback(
|
|
73
|
-
(
|
|
74
|
-
event?: MouseEvent | null,
|
|
75
|
-
options?: {
|
|
76
|
-
force?: boolean;
|
|
77
|
-
proposalId?: string;
|
|
78
|
-
variantLabel?: string;
|
|
79
|
-
dimensions?: Record<string, any>;
|
|
80
|
-
}
|
|
81
|
-
) => {
|
|
82
|
-
const meta = extractClickMeta(event ?? undefined);
|
|
83
|
-
if (!options?.force && event && !meta) {
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const proposalId = options?.proposalId;
|
|
88
|
-
const variantLabel = options?.variantLabel || "control";
|
|
89
|
-
|
|
90
|
-
if (!proposalId) {
|
|
91
|
-
console.warn(
|
|
92
|
-
"[Probat] trackClick called without proposalId. Provide it in options or use useExperiment hook."
|
|
93
|
-
);
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
26
|
+
const { host } = useProbatContext();
|
|
96
27
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
"click",
|
|
101
|
-
variantLabel,
|
|
102
|
-
undefined,
|
|
103
|
-
{ ...meta, ...options?.dimensions }
|
|
104
|
-
);
|
|
105
|
-
return true;
|
|
28
|
+
const capture = useCallback(
|
|
29
|
+
(event: string, properties: Record<string, unknown> = {}) => {
|
|
30
|
+
sendMetric(host, event, properties);
|
|
106
31
|
},
|
|
107
|
-
[
|
|
32
|
+
[host]
|
|
108
33
|
);
|
|
109
34
|
|
|
110
|
-
|
|
111
|
-
(
|
|
112
|
-
metricName: string,
|
|
113
|
-
proposalId: string,
|
|
114
|
-
variantLabel: string = "control",
|
|
115
|
-
dimensions: Record<string, any> = {}
|
|
116
|
-
) => {
|
|
117
|
-
void sendMetric(
|
|
118
|
-
apiBaseUrl,
|
|
119
|
-
proposalId,
|
|
120
|
-
metricName,
|
|
121
|
-
variantLabel,
|
|
122
|
-
undefined,
|
|
123
|
-
dimensions
|
|
124
|
-
);
|
|
125
|
-
},
|
|
126
|
-
[apiBaseUrl]
|
|
127
|
-
);
|
|
128
|
-
|
|
129
|
-
const trackImpression = useCallback(
|
|
130
|
-
(
|
|
131
|
-
proposalId: string,
|
|
132
|
-
variantLabel: string = "control",
|
|
133
|
-
experimentId?: string
|
|
134
|
-
) => {
|
|
135
|
-
void sendMetric(
|
|
136
|
-
apiBaseUrl,
|
|
137
|
-
proposalId,
|
|
138
|
-
"visit",
|
|
139
|
-
variantLabel,
|
|
140
|
-
experimentId
|
|
141
|
-
);
|
|
142
|
-
},
|
|
143
|
-
[apiBaseUrl]
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
return {
|
|
147
|
-
trackClick,
|
|
148
|
-
trackMetric,
|
|
149
|
-
trackImpression,
|
|
150
|
-
};
|
|
35
|
+
return { capture };
|
|
151
36
|
}
|
|
152
|
-
|
package/src/index.ts
CHANGED
|
@@ -1,40 +1,17 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
// Provider
|
|
4
|
-
// Note: These are Client Components - use ProbatProviderClient for Next.js App Router
|
|
5
|
-
export { ProbatProvider, useProbatContext } from "./context/ProbatContext";
|
|
6
|
-
export type { ProbatProviderProps, ProbatContextValue } from "./context/ProbatContext";
|
|
7
|
-
|
|
8
|
-
// Next.js App Router compatible - Re-export from client component file
|
|
9
|
-
// This ensures "use client" directive is properly recognized
|
|
3
|
+
// ── Provider ───────────────────────────────────────────────────────────────
|
|
10
4
|
export { ProbatProviderClient } from "./components/ProbatProviderClient";
|
|
11
|
-
export type { ProbatProviderProps
|
|
5
|
+
export type { ProbatProviderProps } from "./context/ProbatContext";
|
|
12
6
|
|
|
13
|
-
//
|
|
14
|
-
|
|
7
|
+
// ── Experiment component ───────────────────────────────────────────────────
|
|
8
|
+
export { Experiment } from "./components/Experiment";
|
|
9
|
+
export type { ExperimentProps, ExperimentTrackOptions } from "./components/Experiment";
|
|
15
10
|
|
|
16
|
-
// Hooks
|
|
11
|
+
// ── Hooks ──────────────────────────────────────────────────────────────────
|
|
17
12
|
export { useProbatMetrics } from "./hooks/useProbatMetrics";
|
|
18
13
|
export type { UseProbatMetricsReturn } from "./hooks/useProbatMetrics";
|
|
19
14
|
|
|
20
|
-
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
// HOC
|
|
24
|
-
export { withExperiment } from "./hoc/withExperiment";
|
|
25
|
-
export type { WithExperimentOptions } from "./hoc/withExperiment";
|
|
26
|
-
|
|
27
|
-
// Utilities (exported for advanced use cases)
|
|
28
|
-
export { detectEnvironment } from "./utils/environment";
|
|
29
|
-
export { fetchDecision, sendMetric, extractClickMeta } from "./utils/api";
|
|
30
|
-
export type { RetrieveResponse } from "./utils/api";
|
|
31
|
-
// Heatmap tracking (automatically initialized by ProbatProvider)
|
|
32
|
-
export { initHeatmapTracking, stopHeatmapTracking, getHeatmapTracker } from "./utils/heatmapTracker";
|
|
33
|
-
export {
|
|
34
|
-
readChoice,
|
|
35
|
-
writeChoice,
|
|
36
|
-
hasTrackedVisit,
|
|
37
|
-
markTrackedVisit,
|
|
38
|
-
} from "./utils/storage";
|
|
39
|
-
export type { Choice } from "./utils/storage";
|
|
40
|
-
|
|
15
|
+
// ── Utilities (advanced) ───────────────────────────────────────────────────
|
|
16
|
+
export { sendMetric, fetchDecision } from "./utils/api";
|
|
17
|
+
export type { MetricPayload, DecisionResponse } from "./utils/api";
|