@metrone-io/react 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -4
- package/dist/index.d.ts +70 -0
- package/dist/index.esm.js +32 -197
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +30 -196
- package/dist/index.js.map +1 -1
- package/package.json +2 -3
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
React bindings for [Metrone](https://metrone.io) analytics.
|
|
4
4
|
|
|
5
|
-
Provider component, hooks, and HOC for integrating Metrone into React and Next.js applications
|
|
5
|
+
Provider component, hooks, and HOC for integrating Metrone into React and Next.js applications.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
@@ -29,7 +29,7 @@ function App() {
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
function MyComponent() {
|
|
32
|
-
const { trackEvent, trackConversion } = useMetrone()
|
|
32
|
+
const { trackEvent, trackConversion, trackAICall } = useMetrone()
|
|
33
33
|
return (
|
|
34
34
|
<button onClick={() => trackEvent('button_click', { button_id: 'cta' })}>
|
|
35
35
|
Click Me
|
|
@@ -41,9 +41,23 @@ function MyComponent() {
|
|
|
41
41
|
## API
|
|
42
42
|
|
|
43
43
|
- **`MetroneProvider`** — Context provider, initializes the SDK
|
|
44
|
-
- **`useMetrone()`** — Hook returning
|
|
44
|
+
- **`useMetrone()`** — Hook returning all tracking methods
|
|
45
45
|
- **`withMetrone(Component)`** — HOC injecting Metrone props
|
|
46
|
-
- **Automatic route tracking** —
|
|
46
|
+
- **Automatic route tracking** — SPA pageviews handled by the SDK (`autoTrackSPA: true`)
|
|
47
|
+
- **Automatic click tracking** — Outbound links, tel:, mailto:, downloads, and `data-track` elements
|
|
48
|
+
|
|
49
|
+
### Available tracking methods from `useMetrone()`
|
|
50
|
+
|
|
51
|
+
| Method | Description |
|
|
52
|
+
|--------|-------------|
|
|
53
|
+
| `trackEvent(name, data?)` | Track a custom event |
|
|
54
|
+
| `trackConversion(type, value?, data?)` | Track a conversion |
|
|
55
|
+
| `trackPageView(url?, title?)` | Manually track a pageview |
|
|
56
|
+
| `trackAICall(data)` | Track an AI voice call |
|
|
57
|
+
| `trackAIChat(data)` | Track an AI chat session |
|
|
58
|
+
| `trackAIIntent(data)` | Track AI intent detection |
|
|
59
|
+
| `trackAISession(data)` | Track AI session lifecycle |
|
|
60
|
+
| `flush()` | Flush pending events |
|
|
47
61
|
|
|
48
62
|
## Documentation
|
|
49
63
|
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Metrone React Integration
|
|
3
|
+
* React components and hooks for easy analytics integration
|
|
4
|
+
*/
|
|
5
|
+
import React, { ReactNode } from 'react';
|
|
6
|
+
import { Metrone, AnalyticsConfig, EventData, CampaignData } from '@metrone-io/sdk';
|
|
7
|
+
export interface MetroneProviderProps {
|
|
8
|
+
config: AnalyticsConfig;
|
|
9
|
+
children: ReactNode;
|
|
10
|
+
/**
|
|
11
|
+
* @deprecated The SDK now handles SPA route tracking automatically via
|
|
12
|
+
* `autoTrackSPA` (default: true). This prop is ignored and will be
|
|
13
|
+
* removed in a future version.
|
|
14
|
+
*/
|
|
15
|
+
trackRouteChanges?: boolean;
|
|
16
|
+
eventPrefix?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function MetroneProvider({ config, children, }: MetroneProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export interface UseMetroneReturn {
|
|
20
|
+
analytics: Metrone | null;
|
|
21
|
+
isInitialized: boolean;
|
|
22
|
+
trackPageView: (url?: string, title?: string, metadata?: EventData) => void;
|
|
23
|
+
trackEvent: (eventName: string, data?: EventData) => void;
|
|
24
|
+
trackConversion: (conversionType: string, value?: number, data?: EventData) => void;
|
|
25
|
+
trackInteraction: (action: string, element?: string, data?: EventData) => void;
|
|
26
|
+
trackCampaign: (campaignData: CampaignData) => void;
|
|
27
|
+
trackProductView: (productId: string, productName: string, price?: number, metadata?: EventData) => void;
|
|
28
|
+
trackWhatsAppClick: (productId?: string, productName?: string) => void;
|
|
29
|
+
trackAICall: (data: {
|
|
30
|
+
call_id: string;
|
|
31
|
+
provider?: string;
|
|
32
|
+
duration?: number;
|
|
33
|
+
intent?: string;
|
|
34
|
+
transcript_snippet?: string;
|
|
35
|
+
outcome?: string;
|
|
36
|
+
metadata?: EventData;
|
|
37
|
+
}) => void;
|
|
38
|
+
trackAIChat: (data: {
|
|
39
|
+
session_id: string;
|
|
40
|
+
provider?: string;
|
|
41
|
+
message_count?: number;
|
|
42
|
+
intent?: string;
|
|
43
|
+
resolved?: boolean;
|
|
44
|
+
duration?: number;
|
|
45
|
+
metadata?: EventData;
|
|
46
|
+
}) => void;
|
|
47
|
+
trackAIIntent: (data: {
|
|
48
|
+
intent: string;
|
|
49
|
+
confidence?: number;
|
|
50
|
+
source?: 'voice' | 'chat' | 'assistant';
|
|
51
|
+
metadata?: EventData;
|
|
52
|
+
}) => void;
|
|
53
|
+
trackAISession: (data: {
|
|
54
|
+
session_id: string;
|
|
55
|
+
provider?: string;
|
|
56
|
+
action: 'start' | 'end' | 'timeout';
|
|
57
|
+
duration?: number;
|
|
58
|
+
metadata?: EventData;
|
|
59
|
+
}) => void;
|
|
60
|
+
flush: () => void;
|
|
61
|
+
hasConsent: () => boolean;
|
|
62
|
+
requestConsent: () => Promise<boolean>;
|
|
63
|
+
revokeConsent: () => void;
|
|
64
|
+
}
|
|
65
|
+
export declare function useMetrone(): UseMetroneReturn;
|
|
66
|
+
export declare function withMetrone<P extends object>(Component: React.ComponentType<P>, options?: {
|
|
67
|
+
trackPageViews?: boolean;
|
|
68
|
+
trackInteractions?: boolean;
|
|
69
|
+
}): (props: P) => import("react/jsx-runtime").JSX.Element;
|
|
70
|
+
export type { MetroneProviderProps, UseMetroneReturn, EventData, CampaignData, AnalyticsConfig };
|
package/dist/index.esm.js
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import { jsx } from 'react/jsx-runtime';
|
|
2
|
-
import { createContext, useState, useEffect,
|
|
2
|
+
import { createContext, useState, useEffect, useContext, useCallback } from 'react';
|
|
3
3
|
import { Metrone } from '@metrone-io/sdk';
|
|
4
4
|
|
|
5
|
-
// Create analytics context
|
|
6
5
|
const AnalyticsContext = createContext(null);
|
|
7
|
-
|
|
8
|
-
function MetroneProvider({ config, children, trackRouteChanges = true, eventPrefix = '' }) {
|
|
6
|
+
function MetroneProvider({ config, children, }) {
|
|
9
7
|
const [analytics, setAnalytics] = useState(null);
|
|
10
8
|
const [isInitialized, setIsInitialized] = useState(false);
|
|
11
9
|
const [session, setSession] = useState(null);
|
|
12
10
|
const [device, setDevice] = useState(null);
|
|
13
11
|
const [location, setLocation] = useState(null);
|
|
14
|
-
// Initialize analytics
|
|
15
12
|
useEffect(() => {
|
|
16
13
|
try {
|
|
17
14
|
const analyticsInstance = new Metrone(config);
|
|
18
15
|
setAnalytics(analyticsInstance);
|
|
19
16
|
setIsInitialized(true);
|
|
20
|
-
// Set up session info
|
|
21
17
|
const sessionInfo = {
|
|
22
18
|
sessionId: analyticsInstance.getSessionId(),
|
|
23
19
|
startTime: new Date(),
|
|
@@ -27,7 +23,6 @@ function MetroneProvider({ config, children, trackRouteChanges = true, eventPref
|
|
|
27
23
|
eventCount: 0
|
|
28
24
|
};
|
|
29
25
|
setSession(sessionInfo);
|
|
30
|
-
// Set up device info
|
|
31
26
|
const deviceInfo = {
|
|
32
27
|
type: analyticsInstance.getScreenSize(),
|
|
33
28
|
width: window.screen.width,
|
|
@@ -37,104 +32,15 @@ function MetroneProvider({ config, children, trackRouteChanges = true, eventPref
|
|
|
37
32
|
userAgent: navigator.userAgent
|
|
38
33
|
};
|
|
39
34
|
setDevice(deviceInfo);
|
|
40
|
-
|
|
41
|
-
const locationInfo = {};
|
|
42
|
-
setLocation(locationInfo);
|
|
43
|
-
// Track route changes if enabled
|
|
44
|
-
if (trackRouteChanges) {
|
|
45
|
-
trackRouteChange();
|
|
46
|
-
}
|
|
47
|
-
// Set up event listeners
|
|
48
|
-
setupEventListeners(analyticsInstance);
|
|
49
|
-
// Cleanup on unmount
|
|
35
|
+
setLocation({});
|
|
50
36
|
return () => {
|
|
51
37
|
analyticsInstance.destroy();
|
|
52
38
|
};
|
|
53
39
|
}
|
|
54
40
|
catch (error) {
|
|
55
|
-
console.error('Failed to initialize
|
|
41
|
+
console.error('[MetroneProvider] Failed to initialize:', error);
|
|
56
42
|
}
|
|
57
|
-
}, [config
|
|
58
|
-
// Track route changes
|
|
59
|
-
const trackRouteChange = useCallback(() => {
|
|
60
|
-
if (!analytics)
|
|
61
|
-
return;
|
|
62
|
-
const handleRouteChange = () => {
|
|
63
|
-
analytics.pageview();
|
|
64
|
-
// Update session info
|
|
65
|
-
setSession(prev => prev ? {
|
|
66
|
-
...prev,
|
|
67
|
-
lastActivity: new Date(),
|
|
68
|
-
duration: Date.now() - prev.startTime.getTime(),
|
|
69
|
-
pageViews: prev.pageViews + 1
|
|
70
|
-
} : null);
|
|
71
|
-
};
|
|
72
|
-
// Listen for popstate events (back/forward navigation)
|
|
73
|
-
window.addEventListener('popstate', handleRouteChange);
|
|
74
|
-
// Listen for pushstate/replacestate (programmatic navigation)
|
|
75
|
-
const originalPushState = history.pushState;
|
|
76
|
-
const originalReplaceState = history.replaceState;
|
|
77
|
-
history.pushState = function (...args) {
|
|
78
|
-
originalPushState.apply(history, args);
|
|
79
|
-
handleRouteChange();
|
|
80
|
-
};
|
|
81
|
-
history.replaceState = function (...args) {
|
|
82
|
-
originalReplaceState.apply(history, args);
|
|
83
|
-
handleRouteChange();
|
|
84
|
-
};
|
|
85
|
-
return () => {
|
|
86
|
-
window.removeEventListener('popstate', handleRouteChange);
|
|
87
|
-
history.pushState = originalPushState;
|
|
88
|
-
history.replaceState = originalReplaceState;
|
|
89
|
-
};
|
|
90
|
-
}, [analytics]);
|
|
91
|
-
// Set up event listeners
|
|
92
|
-
const setupEventListeners = useCallback((analyticsInstance) => {
|
|
93
|
-
// Listen for custom analytics events
|
|
94
|
-
const handleAnalyticsEvent = (event) => {
|
|
95
|
-
if (event.type === 'metrone-update') {
|
|
96
|
-
console.log('📢 SDK update available:', event.detail);
|
|
97
|
-
}
|
|
98
|
-
else if (event.type === 'metrone-consent-request') {
|
|
99
|
-
// Handle consent request
|
|
100
|
-
const { resolve } = event.detail;
|
|
101
|
-
// You can implement your own consent UI here
|
|
102
|
-
resolve(true); // Default to accepting consent
|
|
103
|
-
}
|
|
104
|
-
else if (event.type === 'metrone-consent-revoked') {
|
|
105
|
-
console.log('🔒 Consent revoked');
|
|
106
|
-
}
|
|
107
|
-
else if (event.type === 'metrone-error') {
|
|
108
|
-
console.error('Analytics error:', event.detail);
|
|
109
|
-
}
|
|
110
|
-
else if (event.type === 'metrone-flush') {
|
|
111
|
-
console.log('📦 Events flushed:', event.detail.eventCount);
|
|
112
|
-
}
|
|
113
|
-
else if (event.type === 'metrone-online') {
|
|
114
|
-
console.log('🌐 Back online');
|
|
115
|
-
}
|
|
116
|
-
else if (event.type === 'metrone-offline') {
|
|
117
|
-
console.log('📴 Gone offline, queued events:', event.detail.queuedEvents);
|
|
118
|
-
}
|
|
119
|
-
};
|
|
120
|
-
window.addEventListener('metrone-update', handleAnalyticsEvent);
|
|
121
|
-
window.addEventListener('metrone-consent-request', handleAnalyticsEvent);
|
|
122
|
-
window.addEventListener('metrone-consent-revoked', handleAnalyticsEvent);
|
|
123
|
-
window.addEventListener('metrone-error', handleAnalyticsEvent);
|
|
124
|
-
window.addEventListener('metrone-flush', handleAnalyticsEvent);
|
|
125
|
-
window.addEventListener('metrone-online', handleAnalyticsEvent);
|
|
126
|
-
window.addEventListener('metrone-offline', handleAnalyticsEvent);
|
|
127
|
-
return () => {
|
|
128
|
-
window.removeEventListener('metrone-update', handleAnalyticsEvent);
|
|
129
|
-
window.removeEventListener('metrone-consent-request', handleAnalyticsEvent);
|
|
130
|
-
window.removeEventListener('metrone-consent-revoked', handleAnalyticsEvent);
|
|
131
|
-
window.removeEventListener('metrone-error', handleAnalyticsEvent);
|
|
132
|
-
window.removeEventListener('metrone-flush', handleAnalyticsEvent);
|
|
133
|
-
window.removeEventListener('metrone-online', handleAnalyticsEvent);
|
|
134
|
-
window.removeEventListener('metrone-offline', handleAnalyticsEvent);
|
|
135
|
-
};
|
|
136
|
-
}, []);
|
|
137
|
-
// Context value
|
|
43
|
+
}, [config]);
|
|
138
44
|
const contextValue = {
|
|
139
45
|
analytics,
|
|
140
46
|
isInitialized,
|
|
@@ -144,98 +50,56 @@ function MetroneProvider({ config, children, trackRouteChanges = true, eventPref
|
|
|
144
50
|
};
|
|
145
51
|
return (jsx(AnalyticsContext.Provider, { value: contextValue, children: children }));
|
|
146
52
|
}
|
|
147
|
-
// Hook to use analytics
|
|
148
53
|
function useMetrone() {
|
|
149
54
|
const context = useContext(AnalyticsContext);
|
|
150
55
|
if (!context) {
|
|
151
56
|
throw new Error('useMetrone must be used within a MetroneProvider');
|
|
152
57
|
}
|
|
153
58
|
const { analytics, isInitialized } = context;
|
|
154
|
-
// Track page view
|
|
155
59
|
const trackPageView = useCallback((url, title, metadata) => {
|
|
156
|
-
|
|
157
|
-
analytics.pageview(url, title, metadata);
|
|
158
|
-
}
|
|
60
|
+
analytics?.pageview(url, title, metadata);
|
|
159
61
|
}, [analytics]);
|
|
160
|
-
// Track custom event
|
|
161
62
|
const trackEvent = useCallback((eventName, data) => {
|
|
162
|
-
|
|
163
|
-
analytics.track(eventName, data);
|
|
164
|
-
}
|
|
63
|
+
analytics?.track(eventName, data);
|
|
165
64
|
}, [analytics]);
|
|
166
|
-
// Track conversion
|
|
167
65
|
const trackConversion = useCallback((conversionType, value, data) => {
|
|
168
|
-
|
|
169
|
-
analytics.conversion(conversionType, value, data);
|
|
170
|
-
}
|
|
66
|
+
analytics?.conversion(conversionType, value, data);
|
|
171
67
|
}, [analytics]);
|
|
172
|
-
// Track interaction
|
|
173
68
|
const trackInteraction = useCallback((action, element, data) => {
|
|
174
|
-
|
|
175
|
-
analytics.interaction(action, element, data);
|
|
176
|
-
}
|
|
69
|
+
analytics?.interaction(action, element, data);
|
|
177
70
|
}, [analytics]);
|
|
178
|
-
// Track campaign
|
|
179
71
|
const trackCampaign = useCallback((campaignData) => {
|
|
180
|
-
|
|
181
|
-
analytics.campaign(campaignData);
|
|
182
|
-
}
|
|
72
|
+
analytics?.campaign(campaignData);
|
|
183
73
|
}, [analytics]);
|
|
184
|
-
// Track product view
|
|
185
74
|
const trackProductView = useCallback((productId, productName, price, metadata) => {
|
|
186
|
-
|
|
187
|
-
analytics.productView(productId, productName, price, metadata);
|
|
188
|
-
}
|
|
75
|
+
analytics?.productView(productId, productName, price, metadata);
|
|
189
76
|
}, [analytics]);
|
|
190
|
-
// Track WhatsApp click
|
|
191
77
|
const trackWhatsAppClick = useCallback((productId, productName) => {
|
|
192
|
-
|
|
193
|
-
analytics.whatsAppClick(productId, productName);
|
|
194
|
-
}
|
|
78
|
+
analytics?.whatsAppClick(productId, productName);
|
|
195
79
|
}, [analytics]);
|
|
196
|
-
// Track AI call
|
|
197
80
|
const trackAICall = useCallback((data) => {
|
|
198
|
-
|
|
199
|
-
analytics.trackAICall(data);
|
|
200
|
-
}
|
|
81
|
+
analytics?.trackAICall(data);
|
|
201
82
|
}, [analytics]);
|
|
202
|
-
// Track AI chat
|
|
203
83
|
const trackAIChat = useCallback((data) => {
|
|
204
|
-
|
|
205
|
-
analytics.trackAIChat(data);
|
|
206
|
-
}
|
|
84
|
+
analytics?.trackAIChat(data);
|
|
207
85
|
}, [analytics]);
|
|
208
|
-
// Track AI intent
|
|
209
86
|
const trackAIIntent = useCallback((data) => {
|
|
210
|
-
|
|
211
|
-
analytics.trackAIIntent(data);
|
|
212
|
-
}
|
|
87
|
+
analytics?.trackAIIntent(data);
|
|
213
88
|
}, [analytics]);
|
|
214
|
-
// Track AI session
|
|
215
89
|
const trackAISession = useCallback((data) => {
|
|
216
|
-
|
|
217
|
-
analytics.trackAISession(data);
|
|
218
|
-
}
|
|
90
|
+
analytics?.trackAISession(data);
|
|
219
91
|
}, [analytics]);
|
|
220
|
-
// Flush events
|
|
221
92
|
const flush = useCallback(() => {
|
|
222
|
-
|
|
223
|
-
analytics.flush();
|
|
224
|
-
}
|
|
93
|
+
analytics?.flush();
|
|
225
94
|
}, [analytics]);
|
|
226
|
-
// Check consent
|
|
227
95
|
const hasConsent = useCallback(() => {
|
|
228
96
|
return analytics ? analytics.hasConsent() : false;
|
|
229
97
|
}, [analytics]);
|
|
230
|
-
// Request consent
|
|
231
98
|
const requestConsent = useCallback(async () => {
|
|
232
99
|
return analytics ? analytics.requestConsent() : false;
|
|
233
100
|
}, [analytics]);
|
|
234
|
-
// Revoke consent
|
|
235
101
|
const revokeConsent = useCallback(() => {
|
|
236
|
-
|
|
237
|
-
analytics.revokeConsent();
|
|
238
|
-
}
|
|
102
|
+
analytics?.revokeConsent();
|
|
239
103
|
}, [analytics]);
|
|
240
104
|
return {
|
|
241
105
|
analytics,
|
|
@@ -257,40 +121,14 @@ function useMetrone() {
|
|
|
257
121
|
revokeConsent
|
|
258
122
|
};
|
|
259
123
|
}
|
|
260
|
-
// Hook for analytics with options
|
|
261
|
-
function useAnalytics(options = {}) {
|
|
262
|
-
const analytics = useMetrone();
|
|
263
|
-
// Auto-track page views if enabled
|
|
264
|
-
useEffect(() => {
|
|
265
|
-
if (options.autoTrack && analytics.isInitialized) {
|
|
266
|
-
analytics.trackPageView();
|
|
267
|
-
}
|
|
268
|
-
}, [options.autoTrack, analytics.isInitialized]);
|
|
269
|
-
// Track route changes if enabled
|
|
270
|
-
useEffect(() => {
|
|
271
|
-
if (options.trackRouteChanges && analytics.isInitialized) {
|
|
272
|
-
const handleRouteChange = () => {
|
|
273
|
-
analytics.trackPageView();
|
|
274
|
-
};
|
|
275
|
-
window.addEventListener('popstate', handleRouteChange);
|
|
276
|
-
return () => {
|
|
277
|
-
window.removeEventListener('popstate', handleRouteChange);
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
}, [options.trackRouteChanges, analytics.isInitialized]);
|
|
281
|
-
return analytics;
|
|
282
|
-
}
|
|
283
|
-
// Higher-order component for analytics
|
|
284
124
|
function withMetrone(Component, options = {}) {
|
|
285
125
|
return function MetroneWrappedComponent(props) {
|
|
286
126
|
const analytics = useMetrone();
|
|
287
|
-
// Track page views if enabled
|
|
288
127
|
useEffect(() => {
|
|
289
128
|
if (options.trackPageViews && analytics.isInitialized) {
|
|
290
129
|
analytics.trackPageView();
|
|
291
130
|
}
|
|
292
131
|
}, [options.trackPageViews, analytics.isInitialized]);
|
|
293
|
-
// Track interactions if enabled
|
|
294
132
|
useEffect(() => {
|
|
295
133
|
if (options.trackInteractions && analytics.isInitialized) {
|
|
296
134
|
const handleClick = (event) => {
|
|
@@ -304,43 +142,40 @@ function withMetrone(Component, options = {}) {
|
|
|
304
142
|
}
|
|
305
143
|
};
|
|
306
144
|
document.addEventListener('click', handleClick);
|
|
307
|
-
return () =>
|
|
308
|
-
document.removeEventListener('click', handleClick);
|
|
309
|
-
};
|
|
145
|
+
return () => document.removeEventListener('click', handleClick);
|
|
310
146
|
}
|
|
311
147
|
}, [options.trackInteractions, analytics.isInitialized]);
|
|
312
148
|
return jsx(Component, { ...props });
|
|
313
149
|
};
|
|
314
150
|
}
|
|
315
|
-
// Utility functions
|
|
316
151
|
function getBrowserName() {
|
|
317
|
-
const
|
|
318
|
-
if (
|
|
152
|
+
const ua = navigator.userAgent;
|
|
153
|
+
if (ua.includes('Chrome'))
|
|
319
154
|
return 'Chrome';
|
|
320
|
-
if (
|
|
155
|
+
if (ua.includes('Firefox'))
|
|
321
156
|
return 'Firefox';
|
|
322
|
-
if (
|
|
157
|
+
if (ua.includes('Safari'))
|
|
323
158
|
return 'Safari';
|
|
324
|
-
if (
|
|
159
|
+
if (ua.includes('Edge'))
|
|
325
160
|
return 'Edge';
|
|
326
|
-
if (
|
|
161
|
+
if (ua.includes('Opera'))
|
|
327
162
|
return 'Opera';
|
|
328
163
|
return 'Unknown';
|
|
329
164
|
}
|
|
330
165
|
function getOSName() {
|
|
331
|
-
const
|
|
332
|
-
if (
|
|
166
|
+
const ua = navigator.userAgent;
|
|
167
|
+
if (ua.includes('Windows'))
|
|
333
168
|
return 'Windows';
|
|
334
|
-
if (
|
|
169
|
+
if (ua.includes('Mac'))
|
|
335
170
|
return 'macOS';
|
|
336
|
-
if (
|
|
171
|
+
if (ua.includes('Linux'))
|
|
337
172
|
return 'Linux';
|
|
338
|
-
if (
|
|
173
|
+
if (ua.includes('Android'))
|
|
339
174
|
return 'Android';
|
|
340
|
-
if (
|
|
175
|
+
if (ua.includes('iOS'))
|
|
341
176
|
return 'iOS';
|
|
342
177
|
return 'Unknown';
|
|
343
178
|
}
|
|
344
179
|
|
|
345
|
-
export { MetroneProvider,
|
|
180
|
+
export { MetroneProvider, useMetrone, withMetrone };
|
|
346
181
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/index.tsx"],"sourcesContent":["/**\n * Metrone React Integration\n * React components and hooks for easy analytics integration\n */\n\nimport React, { createContext, useContext, useEffect, useState, useCallback, ReactNode } from 'react'\nimport { Metrone, AnalyticsConfig, AnalyticsContextValue, UseAnalyticsReturn, EventData, CampaignData, SessionInfo, DeviceInfo, LocationInfo } from '@metrone-io/sdk'\n\n// Create analytics context\nconst AnalyticsContext = createContext<AnalyticsContextValue | null>(null)\n\n// Analytics Provider Props\nexport interface MetroneProviderProps {\n /** Analytics configuration */\n config: AnalyticsConfig\n /** Child components */\n children: ReactNode\n /** Whether to auto-track route changes */\n trackRouteChanges?: boolean\n /** Custom event prefix */\n eventPrefix?: string\n}\n\n// Analytics Provider Component\nexport function MetroneProvider({ \n config, \n children, \n trackRouteChanges = true,\n eventPrefix = ''\n}: MetroneProviderProps) {\n const [analytics, setAnalytics] = useState<Metrone | null>(null)\n const [isInitialized, setIsInitialized] = useState(false)\n const [session, setSession] = useState<SessionInfo | null>(null)\n const [device, setDevice] = useState<DeviceInfo | null>(null)\n const [location, setLocation] = useState<LocationInfo | null>(null)\n\n // Initialize analytics\n useEffect(() => {\n try {\n const analyticsInstance = new Metrone(config)\n setAnalytics(analyticsInstance)\n setIsInitialized(true)\n\n // Set up session info\n const sessionInfo: SessionInfo = {\n sessionId: analyticsInstance.getSessionId(),\n startTime: new Date(),\n lastActivity: new Date(),\n duration: 0,\n pageViews: 0,\n eventCount: 0\n }\n setSession(sessionInfo)\n\n // Set up device info\n const deviceInfo: DeviceInfo = {\n type: analyticsInstance.getScreenSize() as 'mobile' | 'tablet' | 'desktop',\n width: window.screen.width,\n height: window.screen.height,\n browser: getBrowserName(),\n os: getOSName(),\n userAgent: navigator.userAgent\n }\n setDevice(deviceInfo)\n\n // Set up location info (will be populated by API)\n const locationInfo: LocationInfo = {}\n setLocation(locationInfo)\n\n // Track route changes if enabled\n if (trackRouteChanges) {\n trackRouteChange()\n }\n\n // Set up event listeners\n setupEventListeners(analyticsInstance)\n\n // Cleanup on unmount\n return () => {\n analyticsInstance.destroy()\n }\n } catch (error) {\n console.error('Failed to initialize Metrone Analytics:', error)\n }\n }, [config, trackRouteChanges])\n\n // Track route changes\n const trackRouteChange = useCallback(() => {\n if (!analytics) return\n\n const handleRouteChange = () => {\n analytics.pageview()\n \n // Update session info\n setSession(prev => prev ? {\n ...prev,\n lastActivity: new Date(),\n duration: Date.now() - prev.startTime.getTime(),\n pageViews: prev.pageViews + 1\n } : null)\n }\n\n // Listen for popstate events (back/forward navigation)\n window.addEventListener('popstate', handleRouteChange)\n\n // Listen for pushstate/replacestate (programmatic navigation)\n const originalPushState = history.pushState\n const originalReplaceState = history.replaceState\n\n history.pushState = function(...args) {\n originalPushState.apply(history, args)\n handleRouteChange()\n }\n\n history.replaceState = function(...args) {\n originalReplaceState.apply(history, args)\n handleRouteChange()\n }\n\n return () => {\n window.removeEventListener('popstate', handleRouteChange)\n history.pushState = originalPushState\n history.replaceState = originalReplaceState\n }\n }, [analytics])\n\n // Set up event listeners\n const setupEventListeners = useCallback((analyticsInstance: Metrone) => {\n // Listen for custom analytics events\n const handleAnalyticsEvent = (event: CustomEvent) => {\n if (event.type === 'metrone-update') {\n console.log('📢 SDK update available:', event.detail)\n } else if (event.type === 'metrone-consent-request') {\n // Handle consent request\n const { resolve } = event.detail\n // You can implement your own consent UI here\n resolve(true) // Default to accepting consent\n } else if (event.type === 'metrone-consent-revoked') {\n console.log('🔒 Consent revoked')\n } else if (event.type === 'metrone-error') {\n console.error('Analytics error:', event.detail)\n } else if (event.type === 'metrone-flush') {\n console.log('📦 Events flushed:', event.detail.eventCount)\n } else if (event.type === 'metrone-online') {\n console.log('🌐 Back online')\n } else if (event.type === 'metrone-offline') {\n console.log('📴 Gone offline, queued events:', event.detail.queuedEvents)\n }\n }\n\n window.addEventListener('metrone-update', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-consent-request', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-consent-revoked', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-error', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-flush', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-online', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-offline', handleAnalyticsEvent as EventListener)\n\n return () => {\n window.removeEventListener('metrone-update', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-consent-request', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-consent-revoked', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-error', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-flush', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-online', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-offline', handleAnalyticsEvent as EventListener)\n }\n }, [])\n\n // Context value\n const contextValue: AnalyticsContextValue = {\n analytics,\n isInitialized,\n session,\n device,\n location\n }\n\n return (\n <AnalyticsContext.Provider value={contextValue}>\n {children}\n </AnalyticsContext.Provider>\n )\n}\n\n// Hook to use analytics\nexport function useMetrone(): UseAnalyticsReturn {\n const context = useContext(AnalyticsContext)\n \n if (!context) {\n throw new Error('useMetrone must be used within a MetroneProvider')\n }\n\n const { analytics, isInitialized } = context\n\n // Track page view\n const trackPageView = useCallback((url?: string, title?: string, metadata?: EventData) => {\n if (analytics) {\n analytics.pageview(url, title, metadata)\n }\n }, [analytics])\n\n // Track custom event\n const trackEvent = useCallback((eventName: string, data?: EventData) => {\n if (analytics) {\n analytics.track(eventName, data)\n }\n }, [analytics])\n\n // Track conversion\n const trackConversion = useCallback((conversionType: string, value?: number, data?: EventData) => {\n if (analytics) {\n analytics.conversion(conversionType, value, data)\n }\n }, [analytics])\n\n // Track interaction\n const trackInteraction = useCallback((action: string, element?: string, data?: EventData) => {\n if (analytics) {\n analytics.interaction(action, element, data)\n }\n }, [analytics])\n\n // Track campaign\n const trackCampaign = useCallback((campaignData: CampaignData) => {\n if (analytics) {\n analytics.campaign(campaignData)\n }\n }, [analytics])\n\n // Track product view\n const trackProductView = useCallback((productId: string, productName: string, price?: number, metadata?: EventData) => {\n if (analytics) {\n analytics.productView(productId, productName, price, metadata)\n }\n }, [analytics])\n\n // Track WhatsApp click\n const trackWhatsAppClick = useCallback((productId?: string, productName?: string) => {\n if (analytics) {\n analytics.whatsAppClick(productId, productName)\n }\n }, [analytics])\n\n // Track AI call\n const trackAICall = useCallback((data: {\n call_id: string\n provider?: string\n duration?: number\n intent?: string\n transcript_snippet?: string\n outcome?: string\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAICall(data)\n }\n }, [analytics])\n\n // Track AI chat\n const trackAIChat = useCallback((data: {\n session_id: string\n provider?: string\n message_count?: number\n intent?: string\n resolved?: boolean\n duration?: number\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAIChat(data)\n }\n }, [analytics])\n\n // Track AI intent\n const trackAIIntent = useCallback((data: {\n intent: string\n confidence?: number\n source?: 'voice' | 'chat' | 'assistant'\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAIIntent(data)\n }\n }, [analytics])\n\n // Track AI session\n const trackAISession = useCallback((data: {\n session_id: string\n provider?: string\n action: 'start' | 'end' | 'timeout'\n duration?: number\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAISession(data)\n }\n }, [analytics])\n\n // Flush events\n const flush = useCallback(() => {\n if (analytics) {\n analytics.flush()\n }\n }, [analytics])\n\n // Check consent\n const hasConsent = useCallback(() => {\n return analytics ? analytics.hasConsent() : false\n }, [analytics])\n\n // Request consent\n const requestConsent = useCallback(async () => {\n return analytics ? analytics.requestConsent() : false\n }, [analytics])\n\n // Revoke consent\n const revokeConsent = useCallback(() => {\n if (analytics) {\n analytics.revokeConsent()\n }\n }, [analytics])\n\n return {\n analytics,\n isInitialized,\n trackPageView,\n trackEvent,\n trackConversion,\n trackInteraction,\n trackCampaign,\n trackProductView,\n trackWhatsAppClick,\n trackAICall,\n trackAIChat,\n trackAIIntent,\n trackAISession,\n flush,\n hasConsent,\n requestConsent,\n revokeConsent\n }\n}\n\n// Hook for analytics with options\nexport function useAnalytics(options: {\n autoTrack?: boolean\n trackRouteChanges?: boolean\n eventPrefix?: string\n} = {}): UseAnalyticsReturn {\n const analytics = useMetrone()\n \n // Auto-track page views if enabled\n useEffect(() => {\n if (options.autoTrack && analytics.isInitialized) {\n analytics.trackPageView()\n }\n }, [options.autoTrack, analytics.isInitialized])\n\n // Track route changes if enabled\n useEffect(() => {\n if (options.trackRouteChanges && analytics.isInitialized) {\n const handleRouteChange = () => {\n analytics.trackPageView()\n }\n\n window.addEventListener('popstate', handleRouteChange)\n \n return () => {\n window.removeEventListener('popstate', handleRouteChange)\n }\n }\n }, [options.trackRouteChanges, analytics.isInitialized])\n\n return analytics\n}\n\n// Higher-order component for analytics\nexport function withMetrone<P extends object>(\n Component: React.ComponentType<P>,\n options: {\n trackPageViews?: boolean\n trackInteractions?: boolean\n eventPrefix?: string\n } = {}\n) {\n return function MetroneWrappedComponent(props: P) {\n const analytics = useMetrone()\n\n // Track page views if enabled\n useEffect(() => {\n if (options.trackPageViews && analytics.isInitialized) {\n analytics.trackPageView()\n }\n }, [options.trackPageViews, analytics.isInitialized])\n\n // Track interactions if enabled\n useEffect(() => {\n if (options.trackInteractions && analytics.isInitialized) {\n const handleClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n if (target) {\n analytics.trackInteraction('click', target.tagName.toLowerCase(), {\n id: target.id,\n className: target.className,\n text: target.textContent?.substring(0, 100)\n })\n }\n }\n\n document.addEventListener('click', handleClick)\n \n return () => {\n document.removeEventListener('click', handleClick)\n }\n }\n }, [options.trackInteractions, analytics.isInitialized])\n\n return <Component {...props} />\n }\n}\n\n// Utility functions\nfunction getBrowserName(): string {\n const userAgent = navigator.userAgent\n \n if (userAgent.includes('Chrome')) return 'Chrome'\n if (userAgent.includes('Firefox')) return 'Firefox'\n if (userAgent.includes('Safari')) return 'Safari'\n if (userAgent.includes('Edge')) return 'Edge'\n if (userAgent.includes('Opera')) return 'Opera'\n \n return 'Unknown'\n}\n\nfunction getOSName(): string {\n const userAgent = navigator.userAgent\n \n if (userAgent.includes('Windows')) return 'Windows'\n if (userAgent.includes('Mac')) return 'macOS'\n if (userAgent.includes('Linux')) return 'Linux'\n if (userAgent.includes('Android')) return 'Android'\n if (userAgent.includes('iOS')) return 'iOS'\n \n return 'Unknown'\n}\n\n// Export types\nexport type {\n MetroneProviderProps,\n AnalyticsContextValue,\n UseAnalyticsReturn\n} from '@metrone-io/sdk'\n"],"names":["_jsx"],"mappings":";;;;AAQA;AACA,MAAM,gBAAgB,GAAG,aAAa,CAA+B,IAAI,CAAC;AAc1E;AACM,SAAU,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACR,iBAAiB,GAAG,IAAI,EACxB,WAAW,GAAG,EAAE,EACK,EAAA;IACrB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAiB,IAAI,CAAC;IAChE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACzD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAqB,IAAI,CAAC;IAChE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAoB,IAAI,CAAC;IAC7D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAsB,IAAI,CAAC;;IAGnE,SAAS,CAAC,MAAK;AACb,QAAA,IAAI;AACF,YAAA,MAAM,iBAAiB,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;YAC7C,YAAY,CAAC,iBAAiB,CAAC;YAC/B,gBAAgB,CAAC,IAAI,CAAC;;AAGtB,YAAA,MAAM,WAAW,GAAgB;AAC/B,gBAAA,SAAS,EAAE,iBAAiB,CAAC,YAAY,EAAE;gBAC3C,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,YAAY,EAAE,IAAI,IAAI,EAAE;AACxB,gBAAA,QAAQ,EAAE,CAAC;AACX,gBAAA,SAAS,EAAE,CAAC;AACZ,gBAAA,UAAU,EAAE;aACb;YACD,UAAU,CAAC,WAAW,CAAC;;AAGvB,YAAA,MAAM,UAAU,GAAe;AAC7B,gBAAA,IAAI,EAAE,iBAAiB,CAAC,aAAa,EAAqC;AAC1E,gBAAA,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;AAC1B,gBAAA,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;gBAC5B,OAAO,EAAE,cAAc,EAAE;gBACzB,EAAE,EAAE,SAAS,EAAE;gBACf,SAAS,EAAE,SAAS,CAAC;aACtB;YACD,SAAS,CAAC,UAAU,CAAC;;YAGrB,MAAM,YAAY,GAAiB,EAAE;YACrC,WAAW,CAAC,YAAY,CAAC;;YAGzB,IAAI,iBAAiB,EAAE;AACrB,gBAAA,gBAAgB,EAAE;YACpB;;YAGA,mBAAmB,CAAC,iBAAiB,CAAC;;AAGtC,YAAA,OAAO,MAAK;gBACV,iBAAiB,CAAC,OAAO,EAAE;AAC7B,YAAA,CAAC;QACH;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC;QACjE;AACF,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;;AAG/B,IAAA,MAAM,gBAAgB,GAAG,WAAW,CAAC,MAAK;AACxC,QAAA,IAAI,CAAC,SAAS;YAAE;QAEhB,MAAM,iBAAiB,GAAG,MAAK;YAC7B,SAAS,CAAC,QAAQ,EAAE;;YAGpB,UAAU,CAAC,IAAI,IAAI,IAAI,GAAG;AACxB,gBAAA,GAAG,IAAI;gBACP,YAAY,EAAE,IAAI,IAAI,EAAE;gBACxB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;AAC/C,gBAAA,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG;AAC7B,aAAA,GAAG,IAAI,CAAC;AACX,QAAA,CAAC;;AAGD,QAAA,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,iBAAiB,CAAC;;AAGtD,QAAA,MAAM,iBAAiB,GAAG,OAAO,CAAC,SAAS;AAC3C,QAAA,MAAM,oBAAoB,GAAG,OAAO,CAAC,YAAY;AAEjD,QAAA,OAAO,CAAC,SAAS,GAAG,UAAS,GAAG,IAAI,EAAA;AAClC,YAAA,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AACtC,YAAA,iBAAiB,EAAE;AACrB,QAAA,CAAC;AAED,QAAA,OAAO,CAAC,YAAY,GAAG,UAAS,GAAG,IAAI,EAAA;AACrC,YAAA,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AACzC,YAAA,iBAAiB,EAAE;AACrB,QAAA,CAAC;AAED,QAAA,OAAO,MAAK;AACV,YAAA,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,CAAC;AACzD,YAAA,OAAO,CAAC,SAAS,GAAG,iBAAiB;AACrC,YAAA,OAAO,CAAC,YAAY,GAAG,oBAAoB;AAC7C,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,mBAAmB,GAAG,WAAW,CAAC,CAAC,iBAA0B,KAAI;;AAErE,QAAA,MAAM,oBAAoB,GAAG,CAAC,KAAkB,KAAI;AAClD,YAAA,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE;gBACnC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,MAAM,CAAC;YACvD;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB,EAAE;;AAEnD,gBAAA,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM;;AAEhC,gBAAA,OAAO,CAAC,IAAI,CAAC,CAAA;YACf;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB,EAAE;AACnD,gBAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;YACnC;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE;gBACzC,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC;YACjD;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE;gBACzC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;YAC5D;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE;AAC1C,gBAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAC/B;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE;gBAC3C,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC;YAC3E;AACF,QAAA,CAAC;AAED,QAAA,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AAChF,QAAA,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AACzF,QAAA,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AACzF,QAAA,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAC/E,QAAA,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAC/E,QAAA,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AAChF,QAAA,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,oBAAqC,CAAC;AAEjF,QAAA,OAAO,MAAK;AACV,YAAA,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AACnF,YAAA,MAAM,CAAC,mBAAmB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AAC5F,YAAA,MAAM,CAAC,mBAAmB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AAC5F,YAAA,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAClF,YAAA,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAClF,YAAA,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AACnF,YAAA,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,oBAAqC,CAAC;AACtF,QAAA,CAAC;IACH,CAAC,EAAE,EAAE,CAAC;;AAGN,IAAA,MAAM,YAAY,GAA0B;QAC1C,SAAS;QACT,aAAa;QACb,OAAO;QACP,MAAM;QACN;KACD;AAED,IAAA,QACEA,GAAA,CAAC,gBAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,YAAY,EAAA,QAAA,EAC3C,QAAQ,EAAA,CACiB;AAEhC;AAEA;SACgB,UAAU,GAAA;AACxB,IAAA,MAAM,OAAO,GAAG,UAAU,CAAC,gBAAgB,CAAC;IAE5C,IAAI,CAAC,OAAO,EAAE;AACZ,QAAA,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC;IACrE;AAEA,IAAA,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,OAAO;;IAG5C,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,GAAY,EAAE,KAAc,EAAE,QAAoB,KAAI;QACvF,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC;QAC1C;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,UAAU,GAAG,WAAW,CAAC,CAAC,SAAiB,EAAE,IAAgB,KAAI;QACrE,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC;QAClC;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,eAAe,GAAG,WAAW,CAAC,CAAC,cAAsB,EAAE,KAAc,EAAE,IAAgB,KAAI;QAC/F,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,UAAU,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC;QACnD;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,MAAc,EAAE,OAAgB,EAAE,IAAgB,KAAI;QAC1F,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;QAC9C;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,YAA0B,KAAI;QAC/D,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;QAClC;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,gBAAgB,GAAG,WAAW,CAAC,CAAC,SAAiB,EAAE,WAAmB,EAAE,KAAc,EAAE,QAAoB,KAAI;QACpH,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC;QAChE;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,kBAAkB,GAAG,WAAW,CAAC,CAAC,SAAkB,EAAE,WAAoB,KAAI;QAClF,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,CAAC;QACjD;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,IAQhC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC;QAC7B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,CAAC,IAQhC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC;QAC7B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,aAAa,GAAG,WAAW,CAAC,CAAC,IAKlC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC;QAC/B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,cAAc,GAAG,WAAW,CAAC,CAAC,IAMnC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC;QAChC;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,KAAK,GAAG,WAAW,CAAC,MAAK;QAC7B,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,KAAK,EAAE;QACnB;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,UAAU,GAAG,WAAW,CAAC,MAAK;AAClC,QAAA,OAAO,SAAS,GAAG,SAAS,CAAC,UAAU,EAAE,GAAG,KAAK;AACnD,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,cAAc,GAAG,WAAW,CAAC,YAAW;AAC5C,QAAA,OAAO,SAAS,GAAG,SAAS,CAAC,cAAc,EAAE,GAAG,KAAK;AACvD,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,aAAa,GAAG,WAAW,CAAC,MAAK;QACrC,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,aAAa,EAAE;QAC3B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAEf,OAAO;QACL,SAAS;QACT,aAAa;QACb,aAAa;QACb,UAAU;QACV,eAAe;QACf,gBAAgB;QAChB,aAAa;QACb,gBAAgB;QAChB,kBAAkB;QAClB,WAAW;QACX,WAAW;QACX,aAAa;QACb,cAAc;QACd,KAAK;QACL,UAAU;QACV,cAAc;QACd;KACD;AACH;AAEA;AACM,SAAU,YAAY,CAAC,OAAA,GAIzB,EAAE,EAAA;AACJ,IAAA,MAAM,SAAS,GAAG,UAAU,EAAE;;IAG9B,SAAS,CAAC,MAAK;QACb,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,aAAa,EAAE;YAChD,SAAS,CAAC,aAAa,EAAE;QAC3B;IACF,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;;IAGhD,SAAS,CAAC,MAAK;QACb,IAAI,OAAO,CAAC,iBAAiB,IAAI,SAAS,CAAC,aAAa,EAAE;YACxD,MAAM,iBAAiB,GAAG,MAAK;gBAC7B,SAAS,CAAC,aAAa,EAAE;AAC3B,YAAA,CAAC;AAED,YAAA,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,iBAAiB,CAAC;AAEtD,YAAA,OAAO,MAAK;AACV,gBAAA,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,CAAC;AAC3D,YAAA,CAAC;QACH;IACF,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;AAExD,IAAA,OAAO,SAAS;AAClB;AAEA;SACgB,WAAW,CACzB,SAAiC,EACjC,UAII,EAAE,EAAA;IAEN,OAAO,SAAS,uBAAuB,CAAC,KAAQ,EAAA;AAC9C,QAAA,MAAM,SAAS,GAAG,UAAU,EAAE;;QAG9B,SAAS,CAAC,MAAK;YACb,IAAI,OAAO,CAAC,cAAc,IAAI,SAAS,CAAC,aAAa,EAAE;gBACrD,SAAS,CAAC,aAAa,EAAE;YAC3B;QACF,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;;QAGrD,SAAS,CAAC,MAAK;YACb,IAAI,OAAO,CAAC,iBAAiB,IAAI,SAAS,CAAC,aAAa,EAAE;AACxD,gBAAA,MAAM,WAAW,GAAG,CAAC,KAAiB,KAAI;AACxC,oBAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB;oBAC1C,IAAI,MAAM,EAAE;wBACV,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE;4BAChE,EAAE,EAAE,MAAM,CAAC,EAAE;4BACb,SAAS,EAAE,MAAM,CAAC,SAAS;4BAC3B,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG;AAC3C,yBAAA,CAAC;oBACJ;AACF,gBAAA,CAAC;AAED,gBAAA,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC;AAE/C,gBAAA,OAAO,MAAK;AACV,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC;AACpD,gBAAA,CAAC;YACH;QACF,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;AAExD,QAAA,OAAOA,GAAA,CAAC,SAAS,EAAA,EAAA,GAAK,KAAK,GAAI;AACjC,IAAA,CAAC;AACH;AAEA;AACA,SAAS,cAAc,GAAA;AACrB,IAAA,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS;AAErC,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,QAAQ;AACjD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AACnD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,QAAQ;AACjD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;AAAE,QAAA,OAAO,MAAM;AAC7C,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;AAAE,QAAA,OAAO,OAAO;AAE/C,IAAA,OAAO,SAAS;AAClB;AAEA,SAAS,SAAS,GAAA;AAChB,IAAA,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS;AAErC,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AACnD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,OAAO;AAC7C,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;AAAE,QAAA,OAAO,OAAO;AAC/C,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AACnD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK;AAE3C,IAAA,OAAO,SAAS;AAClB;;;;"}
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/index.tsx"],"sourcesContent":["/**\n * Metrone React Integration\n * React components and hooks for easy analytics integration\n */\n\nimport React, { createContext, useContext, useEffect, useState, useCallback, ReactNode } from 'react'\nimport { Metrone, AnalyticsConfig, EventData, CampaignData, SessionInfo, DeviceInfo, LocationInfo } from '@metrone-io/sdk'\n\ninterface AnalyticsContextValue {\n analytics: Metrone | null\n isInitialized: boolean\n session: SessionInfo | null\n device: DeviceInfo | null\n location: LocationInfo | null\n}\n\nconst AnalyticsContext = createContext<AnalyticsContextValue | null>(null)\n\nexport interface MetroneProviderProps {\n config: AnalyticsConfig\n children: ReactNode\n /**\n * @deprecated The SDK now handles SPA route tracking automatically via\n * `autoTrackSPA` (default: true). This prop is ignored and will be\n * removed in a future version.\n */\n trackRouteChanges?: boolean\n eventPrefix?: string\n}\n\nexport function MetroneProvider({\n config,\n children,\n}: MetroneProviderProps) {\n const [analytics, setAnalytics] = useState<Metrone | null>(null)\n const [isInitialized, setIsInitialized] = useState(false)\n const [session, setSession] = useState<SessionInfo | null>(null)\n const [device, setDevice] = useState<DeviceInfo | null>(null)\n const [location, setLocation] = useState<LocationInfo | null>(null)\n\n useEffect(() => {\n try {\n const analyticsInstance = new Metrone(config)\n setAnalytics(analyticsInstance)\n setIsInitialized(true)\n\n const sessionInfo: SessionInfo = {\n sessionId: analyticsInstance.getSessionId(),\n startTime: new Date(),\n lastActivity: new Date(),\n duration: 0,\n pageViews: 0,\n eventCount: 0\n }\n setSession(sessionInfo)\n\n const deviceInfo: DeviceInfo = {\n type: analyticsInstance.getScreenSize() as 'mobile' | 'tablet' | 'desktop',\n width: window.screen.width,\n height: window.screen.height,\n browser: getBrowserName(),\n os: getOSName(),\n userAgent: navigator.userAgent\n }\n setDevice(deviceInfo)\n\n setLocation({})\n\n return () => {\n analyticsInstance.destroy()\n }\n } catch (error) {\n console.error('[MetroneProvider] Failed to initialize:', error)\n }\n }, [config])\n\n const contextValue: AnalyticsContextValue = {\n analytics,\n isInitialized,\n session,\n device,\n location\n }\n\n return (\n <AnalyticsContext.Provider value={contextValue}>\n {children}\n </AnalyticsContext.Provider>\n )\n}\n\nexport interface UseMetroneReturn {\n analytics: Metrone | null\n isInitialized: boolean\n trackPageView: (url?: string, title?: string, metadata?: EventData) => void\n trackEvent: (eventName: string, data?: EventData) => void\n trackConversion: (conversionType: string, value?: number, data?: EventData) => void\n trackInteraction: (action: string, element?: string, data?: EventData) => void\n trackCampaign: (campaignData: CampaignData) => void\n trackProductView: (productId: string, productName: string, price?: number, metadata?: EventData) => void\n trackWhatsAppClick: (productId?: string, productName?: string) => void\n trackAICall: (data: { call_id: string; provider?: string; duration?: number; intent?: string; transcript_snippet?: string; outcome?: string; metadata?: EventData }) => void\n trackAIChat: (data: { session_id: string; provider?: string; message_count?: number; intent?: string; resolved?: boolean; duration?: number; metadata?: EventData }) => void\n trackAIIntent: (data: { intent: string; confidence?: number; source?: 'voice' | 'chat' | 'assistant'; metadata?: EventData }) => void\n trackAISession: (data: { session_id: string; provider?: string; action: 'start' | 'end' | 'timeout'; duration?: number; metadata?: EventData }) => void\n flush: () => void\n hasConsent: () => boolean\n requestConsent: () => Promise<boolean>\n revokeConsent: () => void\n}\n\nexport function useMetrone(): UseMetroneReturn {\n const context = useContext(AnalyticsContext)\n\n if (!context) {\n throw new Error('useMetrone must be used within a MetroneProvider')\n }\n\n const { analytics, isInitialized } = context\n\n const trackPageView = useCallback((url?: string, title?: string, metadata?: EventData) => {\n analytics?.pageview(url, title, metadata)\n }, [analytics])\n\n const trackEvent = useCallback((eventName: string, data?: EventData) => {\n analytics?.track(eventName, data)\n }, [analytics])\n\n const trackConversion = useCallback((conversionType: string, value?: number, data?: EventData) => {\n analytics?.conversion(conversionType, value, data)\n }, [analytics])\n\n const trackInteraction = useCallback((action: string, element?: string, data?: EventData) => {\n analytics?.interaction(action, element, data)\n }, [analytics])\n\n const trackCampaign = useCallback((campaignData: CampaignData) => {\n analytics?.campaign(campaignData)\n }, [analytics])\n\n const trackProductView = useCallback((productId: string, productName: string, price?: number, metadata?: EventData) => {\n analytics?.productView(productId, productName, price, metadata)\n }, [analytics])\n\n const trackWhatsAppClick = useCallback((productId?: string, productName?: string) => {\n analytics?.whatsAppClick(productId, productName)\n }, [analytics])\n\n const trackAICall = useCallback((data: Parameters<Metrone['trackAICall']>[0]) => {\n analytics?.trackAICall(data)\n }, [analytics])\n\n const trackAIChat = useCallback((data: Parameters<Metrone['trackAIChat']>[0]) => {\n analytics?.trackAIChat(data)\n }, [analytics])\n\n const trackAIIntent = useCallback((data: Parameters<Metrone['trackAIIntent']>[0]) => {\n analytics?.trackAIIntent(data)\n }, [analytics])\n\n const trackAISession = useCallback((data: Parameters<Metrone['trackAISession']>[0]) => {\n analytics?.trackAISession(data)\n }, [analytics])\n\n const flush = useCallback(() => {\n analytics?.flush()\n }, [analytics])\n\n const hasConsent = useCallback(() => {\n return analytics ? analytics.hasConsent() : false\n }, [analytics])\n\n const requestConsent = useCallback(async () => {\n return analytics ? analytics.requestConsent() : false\n }, [analytics])\n\n const revokeConsent = useCallback(() => {\n analytics?.revokeConsent()\n }, [analytics])\n\n return {\n analytics,\n isInitialized,\n trackPageView,\n trackEvent,\n trackConversion,\n trackInteraction,\n trackCampaign,\n trackProductView,\n trackWhatsAppClick,\n trackAICall,\n trackAIChat,\n trackAIIntent,\n trackAISession,\n flush,\n hasConsent,\n requestConsent,\n revokeConsent\n }\n}\n\nexport function withMetrone<P extends object>(\n Component: React.ComponentType<P>,\n options: {\n trackPageViews?: boolean\n trackInteractions?: boolean\n } = {}\n) {\n return function MetroneWrappedComponent(props: P) {\n const analytics = useMetrone()\n\n useEffect(() => {\n if (options.trackPageViews && analytics.isInitialized) {\n analytics.trackPageView()\n }\n }, [options.trackPageViews, analytics.isInitialized])\n\n useEffect(() => {\n if (options.trackInteractions && analytics.isInitialized) {\n const handleClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n if (target) {\n analytics.trackInteraction('click', target.tagName.toLowerCase(), {\n id: target.id,\n className: target.className,\n text: target.textContent?.substring(0, 100)\n })\n }\n }\n\n document.addEventListener('click', handleClick)\n return () => document.removeEventListener('click', handleClick)\n }\n }, [options.trackInteractions, analytics.isInitialized])\n\n return <Component {...props} />\n }\n}\n\nfunction getBrowserName(): string {\n const ua = navigator.userAgent\n if (ua.includes('Chrome')) return 'Chrome'\n if (ua.includes('Firefox')) return 'Firefox'\n if (ua.includes('Safari')) return 'Safari'\n if (ua.includes('Edge')) return 'Edge'\n if (ua.includes('Opera')) return 'Opera'\n return 'Unknown'\n}\n\nfunction getOSName(): string {\n const ua = navigator.userAgent\n if (ua.includes('Windows')) return 'Windows'\n if (ua.includes('Mac')) return 'macOS'\n if (ua.includes('Linux')) return 'Linux'\n if (ua.includes('Android')) return 'Android'\n if (ua.includes('iOS')) return 'iOS'\n return 'Unknown'\n}\n\nexport type { MetroneProviderProps, UseMetroneReturn, EventData, CampaignData, AnalyticsConfig }\n"],"names":["_jsx"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,22 +4,18 @@ var jsxRuntime = require('react/jsx-runtime');
|
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var sdk = require('@metrone-io/sdk');
|
|
6
6
|
|
|
7
|
-
// Create analytics context
|
|
8
7
|
const AnalyticsContext = react.createContext(null);
|
|
9
|
-
|
|
10
|
-
function MetroneProvider({ config, children, trackRouteChanges = true, eventPrefix = '' }) {
|
|
8
|
+
function MetroneProvider({ config, children, }) {
|
|
11
9
|
const [analytics, setAnalytics] = react.useState(null);
|
|
12
10
|
const [isInitialized, setIsInitialized] = react.useState(false);
|
|
13
11
|
const [session, setSession] = react.useState(null);
|
|
14
12
|
const [device, setDevice] = react.useState(null);
|
|
15
13
|
const [location, setLocation] = react.useState(null);
|
|
16
|
-
// Initialize analytics
|
|
17
14
|
react.useEffect(() => {
|
|
18
15
|
try {
|
|
19
16
|
const analyticsInstance = new sdk.Metrone(config);
|
|
20
17
|
setAnalytics(analyticsInstance);
|
|
21
18
|
setIsInitialized(true);
|
|
22
|
-
// Set up session info
|
|
23
19
|
const sessionInfo = {
|
|
24
20
|
sessionId: analyticsInstance.getSessionId(),
|
|
25
21
|
startTime: new Date(),
|
|
@@ -29,7 +25,6 @@ function MetroneProvider({ config, children, trackRouteChanges = true, eventPref
|
|
|
29
25
|
eventCount: 0
|
|
30
26
|
};
|
|
31
27
|
setSession(sessionInfo);
|
|
32
|
-
// Set up device info
|
|
33
28
|
const deviceInfo = {
|
|
34
29
|
type: analyticsInstance.getScreenSize(),
|
|
35
30
|
width: window.screen.width,
|
|
@@ -39,104 +34,15 @@ function MetroneProvider({ config, children, trackRouteChanges = true, eventPref
|
|
|
39
34
|
userAgent: navigator.userAgent
|
|
40
35
|
};
|
|
41
36
|
setDevice(deviceInfo);
|
|
42
|
-
|
|
43
|
-
const locationInfo = {};
|
|
44
|
-
setLocation(locationInfo);
|
|
45
|
-
// Track route changes if enabled
|
|
46
|
-
if (trackRouteChanges) {
|
|
47
|
-
trackRouteChange();
|
|
48
|
-
}
|
|
49
|
-
// Set up event listeners
|
|
50
|
-
setupEventListeners(analyticsInstance);
|
|
51
|
-
// Cleanup on unmount
|
|
37
|
+
setLocation({});
|
|
52
38
|
return () => {
|
|
53
39
|
analyticsInstance.destroy();
|
|
54
40
|
};
|
|
55
41
|
}
|
|
56
42
|
catch (error) {
|
|
57
|
-
console.error('Failed to initialize
|
|
43
|
+
console.error('[MetroneProvider] Failed to initialize:', error);
|
|
58
44
|
}
|
|
59
|
-
}, [config
|
|
60
|
-
// Track route changes
|
|
61
|
-
const trackRouteChange = react.useCallback(() => {
|
|
62
|
-
if (!analytics)
|
|
63
|
-
return;
|
|
64
|
-
const handleRouteChange = () => {
|
|
65
|
-
analytics.pageview();
|
|
66
|
-
// Update session info
|
|
67
|
-
setSession(prev => prev ? {
|
|
68
|
-
...prev,
|
|
69
|
-
lastActivity: new Date(),
|
|
70
|
-
duration: Date.now() - prev.startTime.getTime(),
|
|
71
|
-
pageViews: prev.pageViews + 1
|
|
72
|
-
} : null);
|
|
73
|
-
};
|
|
74
|
-
// Listen for popstate events (back/forward navigation)
|
|
75
|
-
window.addEventListener('popstate', handleRouteChange);
|
|
76
|
-
// Listen for pushstate/replacestate (programmatic navigation)
|
|
77
|
-
const originalPushState = history.pushState;
|
|
78
|
-
const originalReplaceState = history.replaceState;
|
|
79
|
-
history.pushState = function (...args) {
|
|
80
|
-
originalPushState.apply(history, args);
|
|
81
|
-
handleRouteChange();
|
|
82
|
-
};
|
|
83
|
-
history.replaceState = function (...args) {
|
|
84
|
-
originalReplaceState.apply(history, args);
|
|
85
|
-
handleRouteChange();
|
|
86
|
-
};
|
|
87
|
-
return () => {
|
|
88
|
-
window.removeEventListener('popstate', handleRouteChange);
|
|
89
|
-
history.pushState = originalPushState;
|
|
90
|
-
history.replaceState = originalReplaceState;
|
|
91
|
-
};
|
|
92
|
-
}, [analytics]);
|
|
93
|
-
// Set up event listeners
|
|
94
|
-
const setupEventListeners = react.useCallback((analyticsInstance) => {
|
|
95
|
-
// Listen for custom analytics events
|
|
96
|
-
const handleAnalyticsEvent = (event) => {
|
|
97
|
-
if (event.type === 'metrone-update') {
|
|
98
|
-
console.log('📢 SDK update available:', event.detail);
|
|
99
|
-
}
|
|
100
|
-
else if (event.type === 'metrone-consent-request') {
|
|
101
|
-
// Handle consent request
|
|
102
|
-
const { resolve } = event.detail;
|
|
103
|
-
// You can implement your own consent UI here
|
|
104
|
-
resolve(true); // Default to accepting consent
|
|
105
|
-
}
|
|
106
|
-
else if (event.type === 'metrone-consent-revoked') {
|
|
107
|
-
console.log('🔒 Consent revoked');
|
|
108
|
-
}
|
|
109
|
-
else if (event.type === 'metrone-error') {
|
|
110
|
-
console.error('Analytics error:', event.detail);
|
|
111
|
-
}
|
|
112
|
-
else if (event.type === 'metrone-flush') {
|
|
113
|
-
console.log('📦 Events flushed:', event.detail.eventCount);
|
|
114
|
-
}
|
|
115
|
-
else if (event.type === 'metrone-online') {
|
|
116
|
-
console.log('🌐 Back online');
|
|
117
|
-
}
|
|
118
|
-
else if (event.type === 'metrone-offline') {
|
|
119
|
-
console.log('📴 Gone offline, queued events:', event.detail.queuedEvents);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
window.addEventListener('metrone-update', handleAnalyticsEvent);
|
|
123
|
-
window.addEventListener('metrone-consent-request', handleAnalyticsEvent);
|
|
124
|
-
window.addEventListener('metrone-consent-revoked', handleAnalyticsEvent);
|
|
125
|
-
window.addEventListener('metrone-error', handleAnalyticsEvent);
|
|
126
|
-
window.addEventListener('metrone-flush', handleAnalyticsEvent);
|
|
127
|
-
window.addEventListener('metrone-online', handleAnalyticsEvent);
|
|
128
|
-
window.addEventListener('metrone-offline', handleAnalyticsEvent);
|
|
129
|
-
return () => {
|
|
130
|
-
window.removeEventListener('metrone-update', handleAnalyticsEvent);
|
|
131
|
-
window.removeEventListener('metrone-consent-request', handleAnalyticsEvent);
|
|
132
|
-
window.removeEventListener('metrone-consent-revoked', handleAnalyticsEvent);
|
|
133
|
-
window.removeEventListener('metrone-error', handleAnalyticsEvent);
|
|
134
|
-
window.removeEventListener('metrone-flush', handleAnalyticsEvent);
|
|
135
|
-
window.removeEventListener('metrone-online', handleAnalyticsEvent);
|
|
136
|
-
window.removeEventListener('metrone-offline', handleAnalyticsEvent);
|
|
137
|
-
};
|
|
138
|
-
}, []);
|
|
139
|
-
// Context value
|
|
45
|
+
}, [config]);
|
|
140
46
|
const contextValue = {
|
|
141
47
|
analytics,
|
|
142
48
|
isInitialized,
|
|
@@ -146,98 +52,56 @@ function MetroneProvider({ config, children, trackRouteChanges = true, eventPref
|
|
|
146
52
|
};
|
|
147
53
|
return (jsxRuntime.jsx(AnalyticsContext.Provider, { value: contextValue, children: children }));
|
|
148
54
|
}
|
|
149
|
-
// Hook to use analytics
|
|
150
55
|
function useMetrone() {
|
|
151
56
|
const context = react.useContext(AnalyticsContext);
|
|
152
57
|
if (!context) {
|
|
153
58
|
throw new Error('useMetrone must be used within a MetroneProvider');
|
|
154
59
|
}
|
|
155
60
|
const { analytics, isInitialized } = context;
|
|
156
|
-
// Track page view
|
|
157
61
|
const trackPageView = react.useCallback((url, title, metadata) => {
|
|
158
|
-
|
|
159
|
-
analytics.pageview(url, title, metadata);
|
|
160
|
-
}
|
|
62
|
+
analytics?.pageview(url, title, metadata);
|
|
161
63
|
}, [analytics]);
|
|
162
|
-
// Track custom event
|
|
163
64
|
const trackEvent = react.useCallback((eventName, data) => {
|
|
164
|
-
|
|
165
|
-
analytics.track(eventName, data);
|
|
166
|
-
}
|
|
65
|
+
analytics?.track(eventName, data);
|
|
167
66
|
}, [analytics]);
|
|
168
|
-
// Track conversion
|
|
169
67
|
const trackConversion = react.useCallback((conversionType, value, data) => {
|
|
170
|
-
|
|
171
|
-
analytics.conversion(conversionType, value, data);
|
|
172
|
-
}
|
|
68
|
+
analytics?.conversion(conversionType, value, data);
|
|
173
69
|
}, [analytics]);
|
|
174
|
-
// Track interaction
|
|
175
70
|
const trackInteraction = react.useCallback((action, element, data) => {
|
|
176
|
-
|
|
177
|
-
analytics.interaction(action, element, data);
|
|
178
|
-
}
|
|
71
|
+
analytics?.interaction(action, element, data);
|
|
179
72
|
}, [analytics]);
|
|
180
|
-
// Track campaign
|
|
181
73
|
const trackCampaign = react.useCallback((campaignData) => {
|
|
182
|
-
|
|
183
|
-
analytics.campaign(campaignData);
|
|
184
|
-
}
|
|
74
|
+
analytics?.campaign(campaignData);
|
|
185
75
|
}, [analytics]);
|
|
186
|
-
// Track product view
|
|
187
76
|
const trackProductView = react.useCallback((productId, productName, price, metadata) => {
|
|
188
|
-
|
|
189
|
-
analytics.productView(productId, productName, price, metadata);
|
|
190
|
-
}
|
|
77
|
+
analytics?.productView(productId, productName, price, metadata);
|
|
191
78
|
}, [analytics]);
|
|
192
|
-
// Track WhatsApp click
|
|
193
79
|
const trackWhatsAppClick = react.useCallback((productId, productName) => {
|
|
194
|
-
|
|
195
|
-
analytics.whatsAppClick(productId, productName);
|
|
196
|
-
}
|
|
80
|
+
analytics?.whatsAppClick(productId, productName);
|
|
197
81
|
}, [analytics]);
|
|
198
|
-
// Track AI call
|
|
199
82
|
const trackAICall = react.useCallback((data) => {
|
|
200
|
-
|
|
201
|
-
analytics.trackAICall(data);
|
|
202
|
-
}
|
|
83
|
+
analytics?.trackAICall(data);
|
|
203
84
|
}, [analytics]);
|
|
204
|
-
// Track AI chat
|
|
205
85
|
const trackAIChat = react.useCallback((data) => {
|
|
206
|
-
|
|
207
|
-
analytics.trackAIChat(data);
|
|
208
|
-
}
|
|
86
|
+
analytics?.trackAIChat(data);
|
|
209
87
|
}, [analytics]);
|
|
210
|
-
// Track AI intent
|
|
211
88
|
const trackAIIntent = react.useCallback((data) => {
|
|
212
|
-
|
|
213
|
-
analytics.trackAIIntent(data);
|
|
214
|
-
}
|
|
89
|
+
analytics?.trackAIIntent(data);
|
|
215
90
|
}, [analytics]);
|
|
216
|
-
// Track AI session
|
|
217
91
|
const trackAISession = react.useCallback((data) => {
|
|
218
|
-
|
|
219
|
-
analytics.trackAISession(data);
|
|
220
|
-
}
|
|
92
|
+
analytics?.trackAISession(data);
|
|
221
93
|
}, [analytics]);
|
|
222
|
-
// Flush events
|
|
223
94
|
const flush = react.useCallback(() => {
|
|
224
|
-
|
|
225
|
-
analytics.flush();
|
|
226
|
-
}
|
|
95
|
+
analytics?.flush();
|
|
227
96
|
}, [analytics]);
|
|
228
|
-
// Check consent
|
|
229
97
|
const hasConsent = react.useCallback(() => {
|
|
230
98
|
return analytics ? analytics.hasConsent() : false;
|
|
231
99
|
}, [analytics]);
|
|
232
|
-
// Request consent
|
|
233
100
|
const requestConsent = react.useCallback(async () => {
|
|
234
101
|
return analytics ? analytics.requestConsent() : false;
|
|
235
102
|
}, [analytics]);
|
|
236
|
-
// Revoke consent
|
|
237
103
|
const revokeConsent = react.useCallback(() => {
|
|
238
|
-
|
|
239
|
-
analytics.revokeConsent();
|
|
240
|
-
}
|
|
104
|
+
analytics?.revokeConsent();
|
|
241
105
|
}, [analytics]);
|
|
242
106
|
return {
|
|
243
107
|
analytics,
|
|
@@ -259,40 +123,14 @@ function useMetrone() {
|
|
|
259
123
|
revokeConsent
|
|
260
124
|
};
|
|
261
125
|
}
|
|
262
|
-
// Hook for analytics with options
|
|
263
|
-
function useAnalytics(options = {}) {
|
|
264
|
-
const analytics = useMetrone();
|
|
265
|
-
// Auto-track page views if enabled
|
|
266
|
-
react.useEffect(() => {
|
|
267
|
-
if (options.autoTrack && analytics.isInitialized) {
|
|
268
|
-
analytics.trackPageView();
|
|
269
|
-
}
|
|
270
|
-
}, [options.autoTrack, analytics.isInitialized]);
|
|
271
|
-
// Track route changes if enabled
|
|
272
|
-
react.useEffect(() => {
|
|
273
|
-
if (options.trackRouteChanges && analytics.isInitialized) {
|
|
274
|
-
const handleRouteChange = () => {
|
|
275
|
-
analytics.trackPageView();
|
|
276
|
-
};
|
|
277
|
-
window.addEventListener('popstate', handleRouteChange);
|
|
278
|
-
return () => {
|
|
279
|
-
window.removeEventListener('popstate', handleRouteChange);
|
|
280
|
-
};
|
|
281
|
-
}
|
|
282
|
-
}, [options.trackRouteChanges, analytics.isInitialized]);
|
|
283
|
-
return analytics;
|
|
284
|
-
}
|
|
285
|
-
// Higher-order component for analytics
|
|
286
126
|
function withMetrone(Component, options = {}) {
|
|
287
127
|
return function MetroneWrappedComponent(props) {
|
|
288
128
|
const analytics = useMetrone();
|
|
289
|
-
// Track page views if enabled
|
|
290
129
|
react.useEffect(() => {
|
|
291
130
|
if (options.trackPageViews && analytics.isInitialized) {
|
|
292
131
|
analytics.trackPageView();
|
|
293
132
|
}
|
|
294
133
|
}, [options.trackPageViews, analytics.isInitialized]);
|
|
295
|
-
// Track interactions if enabled
|
|
296
134
|
react.useEffect(() => {
|
|
297
135
|
if (options.trackInteractions && analytics.isInitialized) {
|
|
298
136
|
const handleClick = (event) => {
|
|
@@ -306,46 +144,42 @@ function withMetrone(Component, options = {}) {
|
|
|
306
144
|
}
|
|
307
145
|
};
|
|
308
146
|
document.addEventListener('click', handleClick);
|
|
309
|
-
return () =>
|
|
310
|
-
document.removeEventListener('click', handleClick);
|
|
311
|
-
};
|
|
147
|
+
return () => document.removeEventListener('click', handleClick);
|
|
312
148
|
}
|
|
313
149
|
}, [options.trackInteractions, analytics.isInitialized]);
|
|
314
150
|
return jsxRuntime.jsx(Component, { ...props });
|
|
315
151
|
};
|
|
316
152
|
}
|
|
317
|
-
// Utility functions
|
|
318
153
|
function getBrowserName() {
|
|
319
|
-
const
|
|
320
|
-
if (
|
|
154
|
+
const ua = navigator.userAgent;
|
|
155
|
+
if (ua.includes('Chrome'))
|
|
321
156
|
return 'Chrome';
|
|
322
|
-
if (
|
|
157
|
+
if (ua.includes('Firefox'))
|
|
323
158
|
return 'Firefox';
|
|
324
|
-
if (
|
|
159
|
+
if (ua.includes('Safari'))
|
|
325
160
|
return 'Safari';
|
|
326
|
-
if (
|
|
161
|
+
if (ua.includes('Edge'))
|
|
327
162
|
return 'Edge';
|
|
328
|
-
if (
|
|
163
|
+
if (ua.includes('Opera'))
|
|
329
164
|
return 'Opera';
|
|
330
165
|
return 'Unknown';
|
|
331
166
|
}
|
|
332
167
|
function getOSName() {
|
|
333
|
-
const
|
|
334
|
-
if (
|
|
168
|
+
const ua = navigator.userAgent;
|
|
169
|
+
if (ua.includes('Windows'))
|
|
335
170
|
return 'Windows';
|
|
336
|
-
if (
|
|
171
|
+
if (ua.includes('Mac'))
|
|
337
172
|
return 'macOS';
|
|
338
|
-
if (
|
|
173
|
+
if (ua.includes('Linux'))
|
|
339
174
|
return 'Linux';
|
|
340
|
-
if (
|
|
175
|
+
if (ua.includes('Android'))
|
|
341
176
|
return 'Android';
|
|
342
|
-
if (
|
|
177
|
+
if (ua.includes('iOS'))
|
|
343
178
|
return 'iOS';
|
|
344
179
|
return 'Unknown';
|
|
345
180
|
}
|
|
346
181
|
|
|
347
182
|
exports.MetroneProvider = MetroneProvider;
|
|
348
|
-
exports.useAnalytics = useAnalytics;
|
|
349
183
|
exports.useMetrone = useMetrone;
|
|
350
184
|
exports.withMetrone = withMetrone;
|
|
351
185
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["/**\n * Metrone React Integration\n * React components and hooks for easy analytics integration\n */\n\nimport React, { createContext, useContext, useEffect, useState, useCallback, ReactNode } from 'react'\nimport { Metrone, AnalyticsConfig, AnalyticsContextValue, UseAnalyticsReturn, EventData, CampaignData, SessionInfo, DeviceInfo, LocationInfo } from '@metrone-io/sdk'\n\n// Create analytics context\nconst AnalyticsContext = createContext<AnalyticsContextValue | null>(null)\n\n// Analytics Provider Props\nexport interface MetroneProviderProps {\n /** Analytics configuration */\n config: AnalyticsConfig\n /** Child components */\n children: ReactNode\n /** Whether to auto-track route changes */\n trackRouteChanges?: boolean\n /** Custom event prefix */\n eventPrefix?: string\n}\n\n// Analytics Provider Component\nexport function MetroneProvider({ \n config, \n children, \n trackRouteChanges = true,\n eventPrefix = ''\n}: MetroneProviderProps) {\n const [analytics, setAnalytics] = useState<Metrone | null>(null)\n const [isInitialized, setIsInitialized] = useState(false)\n const [session, setSession] = useState<SessionInfo | null>(null)\n const [device, setDevice] = useState<DeviceInfo | null>(null)\n const [location, setLocation] = useState<LocationInfo | null>(null)\n\n // Initialize analytics\n useEffect(() => {\n try {\n const analyticsInstance = new Metrone(config)\n setAnalytics(analyticsInstance)\n setIsInitialized(true)\n\n // Set up session info\n const sessionInfo: SessionInfo = {\n sessionId: analyticsInstance.getSessionId(),\n startTime: new Date(),\n lastActivity: new Date(),\n duration: 0,\n pageViews: 0,\n eventCount: 0\n }\n setSession(sessionInfo)\n\n // Set up device info\n const deviceInfo: DeviceInfo = {\n type: analyticsInstance.getScreenSize() as 'mobile' | 'tablet' | 'desktop',\n width: window.screen.width,\n height: window.screen.height,\n browser: getBrowserName(),\n os: getOSName(),\n userAgent: navigator.userAgent\n }\n setDevice(deviceInfo)\n\n // Set up location info (will be populated by API)\n const locationInfo: LocationInfo = {}\n setLocation(locationInfo)\n\n // Track route changes if enabled\n if (trackRouteChanges) {\n trackRouteChange()\n }\n\n // Set up event listeners\n setupEventListeners(analyticsInstance)\n\n // Cleanup on unmount\n return () => {\n analyticsInstance.destroy()\n }\n } catch (error) {\n console.error('Failed to initialize Metrone Analytics:', error)\n }\n }, [config, trackRouteChanges])\n\n // Track route changes\n const trackRouteChange = useCallback(() => {\n if (!analytics) return\n\n const handleRouteChange = () => {\n analytics.pageview()\n \n // Update session info\n setSession(prev => prev ? {\n ...prev,\n lastActivity: new Date(),\n duration: Date.now() - prev.startTime.getTime(),\n pageViews: prev.pageViews + 1\n } : null)\n }\n\n // Listen for popstate events (back/forward navigation)\n window.addEventListener('popstate', handleRouteChange)\n\n // Listen for pushstate/replacestate (programmatic navigation)\n const originalPushState = history.pushState\n const originalReplaceState = history.replaceState\n\n history.pushState = function(...args) {\n originalPushState.apply(history, args)\n handleRouteChange()\n }\n\n history.replaceState = function(...args) {\n originalReplaceState.apply(history, args)\n handleRouteChange()\n }\n\n return () => {\n window.removeEventListener('popstate', handleRouteChange)\n history.pushState = originalPushState\n history.replaceState = originalReplaceState\n }\n }, [analytics])\n\n // Set up event listeners\n const setupEventListeners = useCallback((analyticsInstance: Metrone) => {\n // Listen for custom analytics events\n const handleAnalyticsEvent = (event: CustomEvent) => {\n if (event.type === 'metrone-update') {\n console.log('📢 SDK update available:', event.detail)\n } else if (event.type === 'metrone-consent-request') {\n // Handle consent request\n const { resolve } = event.detail\n // You can implement your own consent UI here\n resolve(true) // Default to accepting consent\n } else if (event.type === 'metrone-consent-revoked') {\n console.log('🔒 Consent revoked')\n } else if (event.type === 'metrone-error') {\n console.error('Analytics error:', event.detail)\n } else if (event.type === 'metrone-flush') {\n console.log('📦 Events flushed:', event.detail.eventCount)\n } else if (event.type === 'metrone-online') {\n console.log('🌐 Back online')\n } else if (event.type === 'metrone-offline') {\n console.log('📴 Gone offline, queued events:', event.detail.queuedEvents)\n }\n }\n\n window.addEventListener('metrone-update', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-consent-request', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-consent-revoked', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-error', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-flush', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-online', handleAnalyticsEvent as EventListener)\n window.addEventListener('metrone-offline', handleAnalyticsEvent as EventListener)\n\n return () => {\n window.removeEventListener('metrone-update', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-consent-request', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-consent-revoked', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-error', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-flush', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-online', handleAnalyticsEvent as EventListener)\n window.removeEventListener('metrone-offline', handleAnalyticsEvent as EventListener)\n }\n }, [])\n\n // Context value\n const contextValue: AnalyticsContextValue = {\n analytics,\n isInitialized,\n session,\n device,\n location\n }\n\n return (\n <AnalyticsContext.Provider value={contextValue}>\n {children}\n </AnalyticsContext.Provider>\n )\n}\n\n// Hook to use analytics\nexport function useMetrone(): UseAnalyticsReturn {\n const context = useContext(AnalyticsContext)\n \n if (!context) {\n throw new Error('useMetrone must be used within a MetroneProvider')\n }\n\n const { analytics, isInitialized } = context\n\n // Track page view\n const trackPageView = useCallback((url?: string, title?: string, metadata?: EventData) => {\n if (analytics) {\n analytics.pageview(url, title, metadata)\n }\n }, [analytics])\n\n // Track custom event\n const trackEvent = useCallback((eventName: string, data?: EventData) => {\n if (analytics) {\n analytics.track(eventName, data)\n }\n }, [analytics])\n\n // Track conversion\n const trackConversion = useCallback((conversionType: string, value?: number, data?: EventData) => {\n if (analytics) {\n analytics.conversion(conversionType, value, data)\n }\n }, [analytics])\n\n // Track interaction\n const trackInteraction = useCallback((action: string, element?: string, data?: EventData) => {\n if (analytics) {\n analytics.interaction(action, element, data)\n }\n }, [analytics])\n\n // Track campaign\n const trackCampaign = useCallback((campaignData: CampaignData) => {\n if (analytics) {\n analytics.campaign(campaignData)\n }\n }, [analytics])\n\n // Track product view\n const trackProductView = useCallback((productId: string, productName: string, price?: number, metadata?: EventData) => {\n if (analytics) {\n analytics.productView(productId, productName, price, metadata)\n }\n }, [analytics])\n\n // Track WhatsApp click\n const trackWhatsAppClick = useCallback((productId?: string, productName?: string) => {\n if (analytics) {\n analytics.whatsAppClick(productId, productName)\n }\n }, [analytics])\n\n // Track AI call\n const trackAICall = useCallback((data: {\n call_id: string\n provider?: string\n duration?: number\n intent?: string\n transcript_snippet?: string\n outcome?: string\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAICall(data)\n }\n }, [analytics])\n\n // Track AI chat\n const trackAIChat = useCallback((data: {\n session_id: string\n provider?: string\n message_count?: number\n intent?: string\n resolved?: boolean\n duration?: number\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAIChat(data)\n }\n }, [analytics])\n\n // Track AI intent\n const trackAIIntent = useCallback((data: {\n intent: string\n confidence?: number\n source?: 'voice' | 'chat' | 'assistant'\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAIIntent(data)\n }\n }, [analytics])\n\n // Track AI session\n const trackAISession = useCallback((data: {\n session_id: string\n provider?: string\n action: 'start' | 'end' | 'timeout'\n duration?: number\n metadata?: EventData\n }) => {\n if (analytics) {\n analytics.trackAISession(data)\n }\n }, [analytics])\n\n // Flush events\n const flush = useCallback(() => {\n if (analytics) {\n analytics.flush()\n }\n }, [analytics])\n\n // Check consent\n const hasConsent = useCallback(() => {\n return analytics ? analytics.hasConsent() : false\n }, [analytics])\n\n // Request consent\n const requestConsent = useCallback(async () => {\n return analytics ? analytics.requestConsent() : false\n }, [analytics])\n\n // Revoke consent\n const revokeConsent = useCallback(() => {\n if (analytics) {\n analytics.revokeConsent()\n }\n }, [analytics])\n\n return {\n analytics,\n isInitialized,\n trackPageView,\n trackEvent,\n trackConversion,\n trackInteraction,\n trackCampaign,\n trackProductView,\n trackWhatsAppClick,\n trackAICall,\n trackAIChat,\n trackAIIntent,\n trackAISession,\n flush,\n hasConsent,\n requestConsent,\n revokeConsent\n }\n}\n\n// Hook for analytics with options\nexport function useAnalytics(options: {\n autoTrack?: boolean\n trackRouteChanges?: boolean\n eventPrefix?: string\n} = {}): UseAnalyticsReturn {\n const analytics = useMetrone()\n \n // Auto-track page views if enabled\n useEffect(() => {\n if (options.autoTrack && analytics.isInitialized) {\n analytics.trackPageView()\n }\n }, [options.autoTrack, analytics.isInitialized])\n\n // Track route changes if enabled\n useEffect(() => {\n if (options.trackRouteChanges && analytics.isInitialized) {\n const handleRouteChange = () => {\n analytics.trackPageView()\n }\n\n window.addEventListener('popstate', handleRouteChange)\n \n return () => {\n window.removeEventListener('popstate', handleRouteChange)\n }\n }\n }, [options.trackRouteChanges, analytics.isInitialized])\n\n return analytics\n}\n\n// Higher-order component for analytics\nexport function withMetrone<P extends object>(\n Component: React.ComponentType<P>,\n options: {\n trackPageViews?: boolean\n trackInteractions?: boolean\n eventPrefix?: string\n } = {}\n) {\n return function MetroneWrappedComponent(props: P) {\n const analytics = useMetrone()\n\n // Track page views if enabled\n useEffect(() => {\n if (options.trackPageViews && analytics.isInitialized) {\n analytics.trackPageView()\n }\n }, [options.trackPageViews, analytics.isInitialized])\n\n // Track interactions if enabled\n useEffect(() => {\n if (options.trackInteractions && analytics.isInitialized) {\n const handleClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n if (target) {\n analytics.trackInteraction('click', target.tagName.toLowerCase(), {\n id: target.id,\n className: target.className,\n text: target.textContent?.substring(0, 100)\n })\n }\n }\n\n document.addEventListener('click', handleClick)\n \n return () => {\n document.removeEventListener('click', handleClick)\n }\n }\n }, [options.trackInteractions, analytics.isInitialized])\n\n return <Component {...props} />\n }\n}\n\n// Utility functions\nfunction getBrowserName(): string {\n const userAgent = navigator.userAgent\n \n if (userAgent.includes('Chrome')) return 'Chrome'\n if (userAgent.includes('Firefox')) return 'Firefox'\n if (userAgent.includes('Safari')) return 'Safari'\n if (userAgent.includes('Edge')) return 'Edge'\n if (userAgent.includes('Opera')) return 'Opera'\n \n return 'Unknown'\n}\n\nfunction getOSName(): string {\n const userAgent = navigator.userAgent\n \n if (userAgent.includes('Windows')) return 'Windows'\n if (userAgent.includes('Mac')) return 'macOS'\n if (userAgent.includes('Linux')) return 'Linux'\n if (userAgent.includes('Android')) return 'Android'\n if (userAgent.includes('iOS')) return 'iOS'\n \n return 'Unknown'\n}\n\n// Export types\nexport type {\n MetroneProviderProps,\n AnalyticsContextValue,\n UseAnalyticsReturn\n} from '@metrone-io/sdk'\n"],"names":["createContext","useState","useEffect","Metrone","useCallback","_jsx","useContext"],"mappings":";;;;;;AAQA;AACA,MAAM,gBAAgB,GAAGA,mBAAa,CAA+B,IAAI,CAAC;AAc1E;AACM,SAAU,eAAe,CAAC,EAC9B,MAAM,EACN,QAAQ,EACR,iBAAiB,GAAG,IAAI,EACxB,WAAW,GAAG,EAAE,EACK,EAAA;IACrB,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAGC,cAAQ,CAAiB,IAAI,CAAC;IAChE,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAGA,cAAQ,CAAC,KAAK,CAAC;IACzD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAGA,cAAQ,CAAqB,IAAI,CAAC;IAChE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAGA,cAAQ,CAAoB,IAAI,CAAC;IAC7D,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAGA,cAAQ,CAAsB,IAAI,CAAC;;IAGnEC,eAAS,CAAC,MAAK;AACb,QAAA,IAAI;AACF,YAAA,MAAM,iBAAiB,GAAG,IAAIC,WAAO,CAAC,MAAM,CAAC;YAC7C,YAAY,CAAC,iBAAiB,CAAC;YAC/B,gBAAgB,CAAC,IAAI,CAAC;;AAGtB,YAAA,MAAM,WAAW,GAAgB;AAC/B,gBAAA,SAAS,EAAE,iBAAiB,CAAC,YAAY,EAAE;gBAC3C,SAAS,EAAE,IAAI,IAAI,EAAE;gBACrB,YAAY,EAAE,IAAI,IAAI,EAAE;AACxB,gBAAA,QAAQ,EAAE,CAAC;AACX,gBAAA,SAAS,EAAE,CAAC;AACZ,gBAAA,UAAU,EAAE;aACb;YACD,UAAU,CAAC,WAAW,CAAC;;AAGvB,YAAA,MAAM,UAAU,GAAe;AAC7B,gBAAA,IAAI,EAAE,iBAAiB,CAAC,aAAa,EAAqC;AAC1E,gBAAA,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK;AAC1B,gBAAA,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM;gBAC5B,OAAO,EAAE,cAAc,EAAE;gBACzB,EAAE,EAAE,SAAS,EAAE;gBACf,SAAS,EAAE,SAAS,CAAC;aACtB;YACD,SAAS,CAAC,UAAU,CAAC;;YAGrB,MAAM,YAAY,GAAiB,EAAE;YACrC,WAAW,CAAC,YAAY,CAAC;;YAGzB,IAAI,iBAAiB,EAAE;AACrB,gBAAA,gBAAgB,EAAE;YACpB;;YAGA,mBAAmB,CAAC,iBAAiB,CAAC;;AAGtC,YAAA,OAAO,MAAK;gBACV,iBAAiB,CAAC,OAAO,EAAE;AAC7B,YAAA,CAAC;QACH;QAAE,OAAO,KAAK,EAAE;AACd,YAAA,OAAO,CAAC,KAAK,CAAC,yCAAyC,EAAE,KAAK,CAAC;QACjE;AACF,IAAA,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;;AAG/B,IAAA,MAAM,gBAAgB,GAAGC,iBAAW,CAAC,MAAK;AACxC,QAAA,IAAI,CAAC,SAAS;YAAE;QAEhB,MAAM,iBAAiB,GAAG,MAAK;YAC7B,SAAS,CAAC,QAAQ,EAAE;;YAGpB,UAAU,CAAC,IAAI,IAAI,IAAI,GAAG;AACxB,gBAAA,GAAG,IAAI;gBACP,YAAY,EAAE,IAAI,IAAI,EAAE;gBACxB,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;AAC/C,gBAAA,SAAS,EAAE,IAAI,CAAC,SAAS,GAAG;AAC7B,aAAA,GAAG,IAAI,CAAC;AACX,QAAA,CAAC;;AAGD,QAAA,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,iBAAiB,CAAC;;AAGtD,QAAA,MAAM,iBAAiB,GAAG,OAAO,CAAC,SAAS;AAC3C,QAAA,MAAM,oBAAoB,GAAG,OAAO,CAAC,YAAY;AAEjD,QAAA,OAAO,CAAC,SAAS,GAAG,UAAS,GAAG,IAAI,EAAA;AAClC,YAAA,iBAAiB,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AACtC,YAAA,iBAAiB,EAAE;AACrB,QAAA,CAAC;AAED,QAAA,OAAO,CAAC,YAAY,GAAG,UAAS,GAAG,IAAI,EAAA;AACrC,YAAA,oBAAoB,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;AACzC,YAAA,iBAAiB,EAAE;AACrB,QAAA,CAAC;AAED,QAAA,OAAO,MAAK;AACV,YAAA,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,CAAC;AACzD,YAAA,OAAO,CAAC,SAAS,GAAG,iBAAiB;AACrC,YAAA,OAAO,CAAC,YAAY,GAAG,oBAAoB;AAC7C,QAAA,CAAC;AACH,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,mBAAmB,GAAGA,iBAAW,CAAC,CAAC,iBAA0B,KAAI;;AAErE,QAAA,MAAM,oBAAoB,GAAG,CAAC,KAAkB,KAAI;AAClD,YAAA,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE;gBACnC,OAAO,CAAC,GAAG,CAAC,0BAA0B,EAAE,KAAK,CAAC,MAAM,CAAC;YACvD;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB,EAAE;;AAEnD,gBAAA,MAAM,EAAE,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM;;AAEhC,gBAAA,OAAO,CAAC,IAAI,CAAC,CAAA;YACf;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,yBAAyB,EAAE;AACnD,gBAAA,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC;YACnC;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE;gBACzC,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,MAAM,CAAC;YACjD;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE;gBACzC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;YAC5D;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE;AAC1C,gBAAA,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAC/B;AAAO,iBAAA,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE;gBAC3C,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC;YAC3E;AACF,QAAA,CAAC;AAED,QAAA,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AAChF,QAAA,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AACzF,QAAA,MAAM,CAAC,gBAAgB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AACzF,QAAA,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAC/E,QAAA,MAAM,CAAC,gBAAgB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAC/E,QAAA,MAAM,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AAChF,QAAA,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,oBAAqC,CAAC;AAEjF,QAAA,OAAO,MAAK;AACV,YAAA,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AACnF,YAAA,MAAM,CAAC,mBAAmB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AAC5F,YAAA,MAAM,CAAC,mBAAmB,CAAC,yBAAyB,EAAE,oBAAqC,CAAC;AAC5F,YAAA,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAClF,YAAA,MAAM,CAAC,mBAAmB,CAAC,eAAe,EAAE,oBAAqC,CAAC;AAClF,YAAA,MAAM,CAAC,mBAAmB,CAAC,gBAAgB,EAAE,oBAAqC,CAAC;AACnF,YAAA,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,oBAAqC,CAAC;AACtF,QAAA,CAAC;IACH,CAAC,EAAE,EAAE,CAAC;;AAGN,IAAA,MAAM,YAAY,GAA0B;QAC1C,SAAS;QACT,aAAa;QACb,OAAO;QACP,MAAM;QACN;KACD;AAED,IAAA,QACEC,cAAA,CAAC,gBAAgB,CAAC,QAAQ,EAAA,EAAC,KAAK,EAAE,YAAY,EAAA,QAAA,EAC3C,QAAQ,EAAA,CACiB;AAEhC;AAEA;SACgB,UAAU,GAAA;AACxB,IAAA,MAAM,OAAO,GAAGC,gBAAU,CAAC,gBAAgB,CAAC;IAE5C,IAAI,CAAC,OAAO,EAAE;AACZ,QAAA,MAAM,IAAI,KAAK,CAAC,kDAAkD,CAAC;IACrE;AAEA,IAAA,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,GAAG,OAAO;;IAG5C,MAAM,aAAa,GAAGF,iBAAW,CAAC,CAAC,GAAY,EAAE,KAAc,EAAE,QAAoB,KAAI;QACvF,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC;QAC1C;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,UAAU,GAAGA,iBAAW,CAAC,CAAC,SAAiB,EAAE,IAAgB,KAAI;QACrE,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC;QAClC;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,eAAe,GAAGA,iBAAW,CAAC,CAAC,cAAsB,EAAE,KAAc,EAAE,IAAgB,KAAI;QAC/F,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,UAAU,CAAC,cAAc,EAAE,KAAK,EAAE,IAAI,CAAC;QACnD;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,gBAAgB,GAAGA,iBAAW,CAAC,CAAC,MAAc,EAAE,OAAgB,EAAE,IAAgB,KAAI;QAC1F,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC;QAC9C;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,aAAa,GAAGA,iBAAW,CAAC,CAAC,YAA0B,KAAI;QAC/D,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,QAAQ,CAAC,YAAY,CAAC;QAClC;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,gBAAgB,GAAGA,iBAAW,CAAC,CAAC,SAAiB,EAAE,WAAmB,EAAE,KAAc,EAAE,QAAoB,KAAI;QACpH,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,WAAW,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,CAAC;QAChE;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;IAGf,MAAM,kBAAkB,GAAGA,iBAAW,CAAC,CAAC,SAAkB,EAAE,WAAoB,KAAI;QAClF,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,WAAW,CAAC;QACjD;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,WAAW,GAAGA,iBAAW,CAAC,CAAC,IAQhC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC;QAC7B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,WAAW,GAAGA,iBAAW,CAAC,CAAC,IAQhC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC;QAC7B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,aAAa,GAAGA,iBAAW,CAAC,CAAC,IAKlC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,aAAa,CAAC,IAAI,CAAC;QAC/B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,cAAc,GAAGA,iBAAW,CAAC,CAAC,IAMnC,KAAI;QACH,IAAI,SAAS,EAAE;AACb,YAAA,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC;QAChC;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,KAAK,GAAGA,iBAAW,CAAC,MAAK;QAC7B,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,KAAK,EAAE;QACnB;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,UAAU,GAAGA,iBAAW,CAAC,MAAK;AAClC,QAAA,OAAO,SAAS,GAAG,SAAS,CAAC,UAAU,EAAE,GAAG,KAAK;AACnD,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,cAAc,GAAGA,iBAAW,CAAC,YAAW;AAC5C,QAAA,OAAO,SAAS,GAAG,SAAS,CAAC,cAAc,EAAE,GAAG,KAAK;AACvD,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;;AAGf,IAAA,MAAM,aAAa,GAAGA,iBAAW,CAAC,MAAK;QACrC,IAAI,SAAS,EAAE;YACb,SAAS,CAAC,aAAa,EAAE;QAC3B;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC;IAEf,OAAO;QACL,SAAS;QACT,aAAa;QACb,aAAa;QACb,UAAU;QACV,eAAe;QACf,gBAAgB;QAChB,aAAa;QACb,gBAAgB;QAChB,kBAAkB;QAClB,WAAW;QACX,WAAW;QACX,aAAa;QACb,cAAc;QACd,KAAK;QACL,UAAU;QACV,cAAc;QACd;KACD;AACH;AAEA;AACM,SAAU,YAAY,CAAC,OAAA,GAIzB,EAAE,EAAA;AACJ,IAAA,MAAM,SAAS,GAAG,UAAU,EAAE;;IAG9BF,eAAS,CAAC,MAAK;QACb,IAAI,OAAO,CAAC,SAAS,IAAI,SAAS,CAAC,aAAa,EAAE;YAChD,SAAS,CAAC,aAAa,EAAE;QAC3B;IACF,CAAC,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;;IAGhDA,eAAS,CAAC,MAAK;QACb,IAAI,OAAO,CAAC,iBAAiB,IAAI,SAAS,CAAC,aAAa,EAAE;YACxD,MAAM,iBAAiB,GAAG,MAAK;gBAC7B,SAAS,CAAC,aAAa,EAAE;AAC3B,YAAA,CAAC;AAED,YAAA,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,iBAAiB,CAAC;AAEtD,YAAA,OAAO,MAAK;AACV,gBAAA,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,iBAAiB,CAAC;AAC3D,YAAA,CAAC;QACH;IACF,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;AAExD,IAAA,OAAO,SAAS;AAClB;AAEA;SACgB,WAAW,CACzB,SAAiC,EACjC,UAII,EAAE,EAAA;IAEN,OAAO,SAAS,uBAAuB,CAAC,KAAQ,EAAA;AAC9C,QAAA,MAAM,SAAS,GAAG,UAAU,EAAE;;QAG9BA,eAAS,CAAC,MAAK;YACb,IAAI,OAAO,CAAC,cAAc,IAAI,SAAS,CAAC,aAAa,EAAE;gBACrD,SAAS,CAAC,aAAa,EAAE;YAC3B;QACF,CAAC,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;;QAGrDA,eAAS,CAAC,MAAK;YACb,IAAI,OAAO,CAAC,iBAAiB,IAAI,SAAS,CAAC,aAAa,EAAE;AACxD,gBAAA,MAAM,WAAW,GAAG,CAAC,KAAiB,KAAI;AACxC,oBAAA,MAAM,MAAM,GAAG,KAAK,CAAC,MAAqB;oBAC1C,IAAI,MAAM,EAAE;wBACV,SAAS,CAAC,gBAAgB,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE;4BAChE,EAAE,EAAE,MAAM,CAAC,EAAE;4BACb,SAAS,EAAE,MAAM,CAAC,SAAS;4BAC3B,IAAI,EAAE,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC,EAAE,GAAG;AAC3C,yBAAA,CAAC;oBACJ;AACF,gBAAA,CAAC;AAED,gBAAA,QAAQ,CAAC,gBAAgB,CAAC,OAAO,EAAE,WAAW,CAAC;AAE/C,gBAAA,OAAO,MAAK;AACV,oBAAA,QAAQ,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC;AACpD,gBAAA,CAAC;YACH;QACF,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,EAAE,SAAS,CAAC,aAAa,CAAC,CAAC;AAExD,QAAA,OAAOG,cAAA,CAAC,SAAS,EAAA,EAAA,GAAK,KAAK,GAAI;AACjC,IAAA,CAAC;AACH;AAEA;AACA,SAAS,cAAc,GAAA;AACrB,IAAA,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS;AAErC,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,QAAQ;AACjD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AACnD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;AAAE,QAAA,OAAO,QAAQ;AACjD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;AAAE,QAAA,OAAO,MAAM;AAC7C,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;AAAE,QAAA,OAAO,OAAO;AAE/C,IAAA,OAAO,SAAS;AAClB;AAEA,SAAS,SAAS,GAAA;AAChB,IAAA,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS;AAErC,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AACnD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,OAAO;AAC7C,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;AAAE,QAAA,OAAO,OAAO;AAC/C,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,SAAS,CAAC;AAAE,QAAA,OAAO,SAAS;AACnD,IAAA,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC;AAAE,QAAA,OAAO,KAAK;AAE3C,IAAA,OAAO,SAAS;AAClB;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["/**\n * Metrone React Integration\n * React components and hooks for easy analytics integration\n */\n\nimport React, { createContext, useContext, useEffect, useState, useCallback, ReactNode } from 'react'\nimport { Metrone, AnalyticsConfig, EventData, CampaignData, SessionInfo, DeviceInfo, LocationInfo } from '@metrone-io/sdk'\n\ninterface AnalyticsContextValue {\n analytics: Metrone | null\n isInitialized: boolean\n session: SessionInfo | null\n device: DeviceInfo | null\n location: LocationInfo | null\n}\n\nconst AnalyticsContext = createContext<AnalyticsContextValue | null>(null)\n\nexport interface MetroneProviderProps {\n config: AnalyticsConfig\n children: ReactNode\n /**\n * @deprecated The SDK now handles SPA route tracking automatically via\n * `autoTrackSPA` (default: true). This prop is ignored and will be\n * removed in a future version.\n */\n trackRouteChanges?: boolean\n eventPrefix?: string\n}\n\nexport function MetroneProvider({\n config,\n children,\n}: MetroneProviderProps) {\n const [analytics, setAnalytics] = useState<Metrone | null>(null)\n const [isInitialized, setIsInitialized] = useState(false)\n const [session, setSession] = useState<SessionInfo | null>(null)\n const [device, setDevice] = useState<DeviceInfo | null>(null)\n const [location, setLocation] = useState<LocationInfo | null>(null)\n\n useEffect(() => {\n try {\n const analyticsInstance = new Metrone(config)\n setAnalytics(analyticsInstance)\n setIsInitialized(true)\n\n const sessionInfo: SessionInfo = {\n sessionId: analyticsInstance.getSessionId(),\n startTime: new Date(),\n lastActivity: new Date(),\n duration: 0,\n pageViews: 0,\n eventCount: 0\n }\n setSession(sessionInfo)\n\n const deviceInfo: DeviceInfo = {\n type: analyticsInstance.getScreenSize() as 'mobile' | 'tablet' | 'desktop',\n width: window.screen.width,\n height: window.screen.height,\n browser: getBrowserName(),\n os: getOSName(),\n userAgent: navigator.userAgent\n }\n setDevice(deviceInfo)\n\n setLocation({})\n\n return () => {\n analyticsInstance.destroy()\n }\n } catch (error) {\n console.error('[MetroneProvider] Failed to initialize:', error)\n }\n }, [config])\n\n const contextValue: AnalyticsContextValue = {\n analytics,\n isInitialized,\n session,\n device,\n location\n }\n\n return (\n <AnalyticsContext.Provider value={contextValue}>\n {children}\n </AnalyticsContext.Provider>\n )\n}\n\nexport interface UseMetroneReturn {\n analytics: Metrone | null\n isInitialized: boolean\n trackPageView: (url?: string, title?: string, metadata?: EventData) => void\n trackEvent: (eventName: string, data?: EventData) => void\n trackConversion: (conversionType: string, value?: number, data?: EventData) => void\n trackInteraction: (action: string, element?: string, data?: EventData) => void\n trackCampaign: (campaignData: CampaignData) => void\n trackProductView: (productId: string, productName: string, price?: number, metadata?: EventData) => void\n trackWhatsAppClick: (productId?: string, productName?: string) => void\n trackAICall: (data: { call_id: string; provider?: string; duration?: number; intent?: string; transcript_snippet?: string; outcome?: string; metadata?: EventData }) => void\n trackAIChat: (data: { session_id: string; provider?: string; message_count?: number; intent?: string; resolved?: boolean; duration?: number; metadata?: EventData }) => void\n trackAIIntent: (data: { intent: string; confidence?: number; source?: 'voice' | 'chat' | 'assistant'; metadata?: EventData }) => void\n trackAISession: (data: { session_id: string; provider?: string; action: 'start' | 'end' | 'timeout'; duration?: number; metadata?: EventData }) => void\n flush: () => void\n hasConsent: () => boolean\n requestConsent: () => Promise<boolean>\n revokeConsent: () => void\n}\n\nexport function useMetrone(): UseMetroneReturn {\n const context = useContext(AnalyticsContext)\n\n if (!context) {\n throw new Error('useMetrone must be used within a MetroneProvider')\n }\n\n const { analytics, isInitialized } = context\n\n const trackPageView = useCallback((url?: string, title?: string, metadata?: EventData) => {\n analytics?.pageview(url, title, metadata)\n }, [analytics])\n\n const trackEvent = useCallback((eventName: string, data?: EventData) => {\n analytics?.track(eventName, data)\n }, [analytics])\n\n const trackConversion = useCallback((conversionType: string, value?: number, data?: EventData) => {\n analytics?.conversion(conversionType, value, data)\n }, [analytics])\n\n const trackInteraction = useCallback((action: string, element?: string, data?: EventData) => {\n analytics?.interaction(action, element, data)\n }, [analytics])\n\n const trackCampaign = useCallback((campaignData: CampaignData) => {\n analytics?.campaign(campaignData)\n }, [analytics])\n\n const trackProductView = useCallback((productId: string, productName: string, price?: number, metadata?: EventData) => {\n analytics?.productView(productId, productName, price, metadata)\n }, [analytics])\n\n const trackWhatsAppClick = useCallback((productId?: string, productName?: string) => {\n analytics?.whatsAppClick(productId, productName)\n }, [analytics])\n\n const trackAICall = useCallback((data: Parameters<Metrone['trackAICall']>[0]) => {\n analytics?.trackAICall(data)\n }, [analytics])\n\n const trackAIChat = useCallback((data: Parameters<Metrone['trackAIChat']>[0]) => {\n analytics?.trackAIChat(data)\n }, [analytics])\n\n const trackAIIntent = useCallback((data: Parameters<Metrone['trackAIIntent']>[0]) => {\n analytics?.trackAIIntent(data)\n }, [analytics])\n\n const trackAISession = useCallback((data: Parameters<Metrone['trackAISession']>[0]) => {\n analytics?.trackAISession(data)\n }, [analytics])\n\n const flush = useCallback(() => {\n analytics?.flush()\n }, [analytics])\n\n const hasConsent = useCallback(() => {\n return analytics ? analytics.hasConsent() : false\n }, [analytics])\n\n const requestConsent = useCallback(async () => {\n return analytics ? analytics.requestConsent() : false\n }, [analytics])\n\n const revokeConsent = useCallback(() => {\n analytics?.revokeConsent()\n }, [analytics])\n\n return {\n analytics,\n isInitialized,\n trackPageView,\n trackEvent,\n trackConversion,\n trackInteraction,\n trackCampaign,\n trackProductView,\n trackWhatsAppClick,\n trackAICall,\n trackAIChat,\n trackAIIntent,\n trackAISession,\n flush,\n hasConsent,\n requestConsent,\n revokeConsent\n }\n}\n\nexport function withMetrone<P extends object>(\n Component: React.ComponentType<P>,\n options: {\n trackPageViews?: boolean\n trackInteractions?: boolean\n } = {}\n) {\n return function MetroneWrappedComponent(props: P) {\n const analytics = useMetrone()\n\n useEffect(() => {\n if (options.trackPageViews && analytics.isInitialized) {\n analytics.trackPageView()\n }\n }, [options.trackPageViews, analytics.isInitialized])\n\n useEffect(() => {\n if (options.trackInteractions && analytics.isInitialized) {\n const handleClick = (event: MouseEvent) => {\n const target = event.target as HTMLElement\n if (target) {\n analytics.trackInteraction('click', target.tagName.toLowerCase(), {\n id: target.id,\n className: target.className,\n text: target.textContent?.substring(0, 100)\n })\n }\n }\n\n document.addEventListener('click', handleClick)\n return () => document.removeEventListener('click', handleClick)\n }\n }, [options.trackInteractions, analytics.isInitialized])\n\n return <Component {...props} />\n }\n}\n\nfunction getBrowserName(): string {\n const ua = navigator.userAgent\n if (ua.includes('Chrome')) return 'Chrome'\n if (ua.includes('Firefox')) return 'Firefox'\n if (ua.includes('Safari')) return 'Safari'\n if (ua.includes('Edge')) return 'Edge'\n if (ua.includes('Opera')) return 'Opera'\n return 'Unknown'\n}\n\nfunction getOSName(): string {\n const ua = navigator.userAgent\n if (ua.includes('Windows')) return 'Windows'\n if (ua.includes('Mac')) return 'macOS'\n if (ua.includes('Linux')) return 'Linux'\n if (ua.includes('Android')) return 'Android'\n if (ua.includes('iOS')) return 'iOS'\n return 'Unknown'\n}\n\nexport type { MetroneProviderProps, UseMetroneReturn, EventData, CampaignData, AnalyticsConfig }\n"],"names":["createContext","useState","useEffect","Metrone","_jsx","useContext","useCallback"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@metrone-io/react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Metrone React integration - Privacy-first analytics for React",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.esm.js",
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
"node": ">=16.0.0"
|
|
45
45
|
},
|
|
46
46
|
"peerDependencies": {
|
|
47
|
-
"@metrone-io/sdk": "^1.
|
|
47
|
+
"@metrone-io/sdk": "^1.4.0",
|
|
48
48
|
"react": ">=16.8.0"
|
|
49
49
|
},
|
|
50
50
|
"devDependencies": {
|
|
@@ -62,7 +62,6 @@
|
|
|
62
62
|
"react": "^18.2.0",
|
|
63
63
|
"rimraf": "^5.0.5",
|
|
64
64
|
"rollup": "^4.6.1",
|
|
65
|
-
"rollup-plugin-terser": "^7.0.2",
|
|
66
65
|
"ts-jest": "^29.1.1",
|
|
67
66
|
"typescript": "^5.3.2"
|
|
68
67
|
},
|