user-analytics-tracker 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.
@@ -0,0 +1,415 @@
1
+ /**
2
+ * Core types for the analytics tracker package
3
+ */
4
+ type NetworkType = 'wifi' | 'hotspot' | 'cellular' | 'ethernet' | 'unknown';
5
+ type DeviceType = 'mobile' | 'tablet' | 'desktop' | 'unknown';
6
+ interface NetworkInfo {
7
+ type: NetworkType;
8
+ effectiveType?: string;
9
+ downlink?: number;
10
+ rtt?: number;
11
+ saveData?: boolean;
12
+ connectionType?: string;
13
+ }
14
+ interface DeviceInfo {
15
+ type: DeviceType;
16
+ os: string;
17
+ osVersion: string;
18
+ browser: string;
19
+ browserVersion: string;
20
+ screenResolution: string;
21
+ deviceModel: string;
22
+ deviceBrand: string;
23
+ language: string;
24
+ timezone: string;
25
+ userAgent: string;
26
+ deviceMemory?: number;
27
+ hardwareConcurrency?: number;
28
+ touchSupport: boolean;
29
+ pixelRatio: number;
30
+ colorDepth: number;
31
+ orientation: string;
32
+ cpuArchitecture: string;
33
+ }
34
+ interface LocationInfo {
35
+ lat?: number | null;
36
+ lon?: number | null;
37
+ accuracy?: number | null;
38
+ permission?: 'granted' | 'denied' | 'prompt' | 'unsupported';
39
+ source: 'gps' | 'ip' | 'unknown';
40
+ ts?: string;
41
+ ip?: string | null;
42
+ country?: string;
43
+ countryCode?: string;
44
+ city?: string;
45
+ region?: string;
46
+ timezone?: string;
47
+ }
48
+ interface AttributionInfo {
49
+ landingUrl: string;
50
+ path: string;
51
+ hostname: string;
52
+ referrerUrl: string | null;
53
+ referrerDomain: string | null;
54
+ navigationType: 'navigate' | 'reload' | 'back_forward' | 'prerender' | 'unknown';
55
+ isReload: boolean;
56
+ isBackForward: boolean;
57
+ sessionStart?: string | null;
58
+ utm_source?: string | null;
59
+ utm_medium?: string | null;
60
+ utm_campaign?: string | null;
61
+ utm_term?: string | null;
62
+ utm_content?: string | null;
63
+ gclid?: string | null;
64
+ fbclid?: string | null;
65
+ ttclid?: string | null;
66
+ msclkid?: string | null;
67
+ dmclid?: string | null;
68
+ firstTouch?: Record<string, string | null> | null;
69
+ lastTouch?: Record<string, string | null> | null;
70
+ }
71
+ interface IPLocation {
72
+ ip: string;
73
+ country?: string;
74
+ countryCode?: string;
75
+ region?: string;
76
+ regionName?: string;
77
+ city?: string;
78
+ lat?: number;
79
+ lon?: number;
80
+ timezone?: string;
81
+ isp?: string;
82
+ org?: string;
83
+ as?: string;
84
+ query?: string;
85
+ }
86
+ interface AnalyticsConfig {
87
+ apiEndpoint: string;
88
+ autoSend?: boolean;
89
+ enableLocation?: boolean;
90
+ enableIPGeolocation?: boolean;
91
+ enableNetworkDetection?: boolean;
92
+ enableDeviceDetection?: boolean;
93
+ enableAttribution?: boolean;
94
+ sessionStoragePrefix?: string;
95
+ localStoragePrefix?: string;
96
+ }
97
+ interface AnalyticsEvent {
98
+ sessionId: string;
99
+ pageUrl: string;
100
+ timestamp: Date | string;
101
+ networkInfo?: NetworkInfo;
102
+ deviceInfo?: DeviceInfo;
103
+ location?: LocationInfo;
104
+ attribution?: AttributionInfo;
105
+ ipLocation?: IPLocation;
106
+ userId?: string;
107
+ customData?: Record<string, any>;
108
+ eventId?: string;
109
+ eventName?: string;
110
+ eventParameters?: Record<string, any>;
111
+ }
112
+ interface UseAnalyticsReturn {
113
+ sessionId: string | null;
114
+ networkInfo: NetworkInfo | null;
115
+ deviceInfo: DeviceInfo | null;
116
+ location: LocationInfo | null;
117
+ attribution: AttributionInfo | null;
118
+ pageVisits: number;
119
+ interactions: number;
120
+ logEvent: (customData?: Record<string, any>) => Promise<void>;
121
+ trackEvent: (eventName: string, parameters?: Record<string, any>) => Promise<void>;
122
+ trackPageView: (pageName?: string, parameters?: Record<string, any>) => Promise<void>;
123
+ incrementInteraction: () => void;
124
+ refresh: () => Promise<{
125
+ net: NetworkInfo;
126
+ dev: DeviceInfo;
127
+ attr: AttributionInfo;
128
+ loc: LocationInfo;
129
+ }>;
130
+ }
131
+
132
+ /**
133
+ * Network Type Detector
134
+ * Detects WiFi, Mobile Data (Cellular), Hotspot, Ethernet, or Unknown
135
+ */
136
+ declare class NetworkDetector {
137
+ static detect(): NetworkInfo;
138
+ }
139
+
140
+ /**
141
+ * Device Information Detector
142
+ * Detects device type, OS, browser, and hardware specs
143
+ */
144
+ declare class DeviceDetector {
145
+ private static getRealDeviceInfo;
146
+ private static detectBrowser;
147
+ static detect(): Promise<DeviceInfo>;
148
+ private static detectBrand;
149
+ private static getDefaultDeviceInfo;
150
+ }
151
+
152
+ /**
153
+ * Location Detector
154
+ * Detects GPS location with consent management, falls back to IP-based location API
155
+ * IP-based location works automatically without user permission
156
+ */
157
+ declare class LocationDetector {
158
+ private static locationFetchingRef;
159
+ private static lastLocationRef;
160
+ private static locationConsentLoggedRef;
161
+ private static ipLocationFetchingRef;
162
+ private static lastIPLocationRef;
163
+ /**
164
+ * Detect location using IP-based API only (no GPS, no permission needed)
165
+ * Fast and automatic - works immediately without user interaction
166
+ */
167
+ static detectIPOnly(): Promise<LocationInfo>;
168
+ /**
169
+ * Detect location with automatic consent granted
170
+ * Tries GPS first (if available), then falls back to IP-based location
171
+ * Automatically sets location consent to bypass permission checks
172
+ */
173
+ static detectWithAutoConsent(): Promise<LocationInfo>;
174
+ /**
175
+ * Get browser GPS location
176
+ * Respects location consent (set via MSISDN entry)
177
+ * Falls back to IP-based location automatically if GPS fails
178
+ */
179
+ static detect(): Promise<LocationInfo>;
180
+ /**
181
+ * Get location from IP-based public API (client-side)
182
+ * Works without user permission, good fallback when GPS is unavailable
183
+ * Uses ip-api.com free tier (no API key required, 45 requests/minute)
184
+ */
185
+ private static getIPBasedLocation;
186
+ /**
187
+ * Clear location cache (useful when consent is granted)
188
+ */
189
+ static clearCache(): void;
190
+ }
191
+
192
+ /**
193
+ * Attribution Detector
194
+ * Detects UTM parameters, referrer, navigation type, and tracks first/last touch
195
+ */
196
+ declare class AttributionDetector {
197
+ static detect(): AttributionInfo;
198
+ private static getDefaultAttribution;
199
+ }
200
+
201
+ /**
202
+ * Analytics Service
203
+ * Sends analytics events to your backend API
204
+ *
205
+ * Supports both relative paths (e.g., '/api/analytics') and full URLs (e.g., 'https://your-server.com/api/analytics')
206
+ */
207
+ declare class AnalyticsService {
208
+ private static apiEndpoint;
209
+ /**
210
+ * Configure the analytics API endpoint
211
+ *
212
+ * @param config - Configuration object
213
+ * @param config.apiEndpoint - Your backend API endpoint URL
214
+ * - Relative path: '/api/analytics' (sends to same domain)
215
+ * - Full URL: 'https://your-server.com/api/analytics' (sends to your server)
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * // Use your own server
220
+ * AnalyticsService.configure({
221
+ * apiEndpoint: 'https://api.yourcompany.com/analytics'
222
+ * });
223
+ *
224
+ * // Or use relative path (same domain)
225
+ * AnalyticsService.configure({
226
+ * apiEndpoint: '/api/analytics'
227
+ * });
228
+ * ```
229
+ */
230
+ static configure(config: {
231
+ apiEndpoint: string;
232
+ }): void;
233
+ /**
234
+ * Generate a random event ID
235
+ */
236
+ private static generateEventId;
237
+ /**
238
+ * Track user journey/analytics event
239
+ */
240
+ static trackEvent(event: Omit<AnalyticsEvent, 'eventId' | 'timestamp'>): Promise<void>;
241
+ /**
242
+ * Track user journey with full context
243
+ */
244
+ static trackUserJourney({ sessionId, pageUrl, networkInfo, deviceInfo, location, attribution, ipLocation, userId, customData, pageVisits, interactions, }: {
245
+ sessionId: string;
246
+ pageUrl: string;
247
+ networkInfo?: NetworkInfo;
248
+ deviceInfo?: DeviceInfo;
249
+ location?: any;
250
+ attribution?: AttributionInfo;
251
+ ipLocation?: any;
252
+ userId?: string;
253
+ customData?: Record<string, any>;
254
+ pageVisits?: number;
255
+ interactions?: number;
256
+ }): Promise<void>;
257
+ /**
258
+ * Track a custom event (Firebase/GA-style)
259
+ * Automatically collects device, network, location context if available
260
+ *
261
+ * @param eventName - Name of the event (e.g., 'button_click', 'purchase', 'sign_up')
262
+ * @param parameters - Event-specific parameters (optional)
263
+ * @param context - Optional context override (auto-collected if not provided)
264
+ *
265
+ * @example
266
+ * ```typescript
267
+ * // Simple event tracking
268
+ * AnalyticsService.logEvent('button_click', {
269
+ * button_name: 'signup',
270
+ * button_location: 'header'
271
+ * });
272
+ *
273
+ * // Purchase event
274
+ * AnalyticsService.logEvent('purchase', {
275
+ * transaction_id: 'T12345',
276
+ * value: 29.99,
277
+ * currency: 'USD',
278
+ * items: [{ id: 'item1', name: 'Product 1', price: 29.99 }]
279
+ * });
280
+ * ```
281
+ */
282
+ static logEvent(eventName: string, parameters?: Record<string, any>, context?: {
283
+ sessionId?: string;
284
+ pageUrl?: string;
285
+ networkInfo?: NetworkInfo;
286
+ deviceInfo?: DeviceInfo;
287
+ location?: any;
288
+ attribution?: AttributionInfo;
289
+ userId?: string;
290
+ }): Promise<void>;
291
+ /**
292
+ * Track a page view event (Firebase/GA-style)
293
+ * Automatically collects device, network, location context
294
+ *
295
+ * @param pageName - Optional page name (defaults to current URL pathname)
296
+ * @param parameters - Optional page view parameters
297
+ *
298
+ * @example
299
+ * ```typescript
300
+ * // Track current page view
301
+ * AnalyticsService.trackPageView();
302
+ *
303
+ * // Track with custom page name
304
+ * AnalyticsService.trackPageView('/dashboard', {
305
+ * page_title: 'Dashboard',
306
+ * user_type: 'premium'
307
+ * });
308
+ * ```
309
+ */
310
+ static trackPageView(pageName?: string, parameters?: Record<string, any>): Promise<void>;
311
+ }
312
+
313
+ interface UseAnalyticsOptions {
314
+ autoSend?: boolean;
315
+ config?: Partial<AnalyticsConfig>;
316
+ onReady?: (data: {
317
+ sessionId: string;
318
+ networkInfo: NetworkInfo;
319
+ deviceInfo: DeviceInfo;
320
+ location: LocationInfo;
321
+ attribution: AttributionInfo;
322
+ }) => void;
323
+ }
324
+ /**
325
+ * React hook for analytics tracking
326
+ *
327
+ * @example
328
+ * ```tsx
329
+ * const { sessionId, networkInfo, deviceInfo, logEvent } = useAnalytics({
330
+ * autoSend: true,
331
+ * config: { apiEndpoint: '/api/analytics' }
332
+ * });
333
+ * ```
334
+ */
335
+ declare function useAnalytics(options?: UseAnalyticsOptions): UseAnalyticsReturn;
336
+
337
+ /**
338
+ * Storage utilities for analytics tracking
339
+ */
340
+ declare const loadJSON: <T>(key: string) => T | null;
341
+ declare const saveJSON: (key: string, obj: unknown) => void;
342
+ declare const loadSessionJSON: <T>(key: string) => T | null;
343
+ declare const saveSessionJSON: (key: string, obj: unknown) => void;
344
+ /**
345
+ * Generate or retrieve a user ID from localStorage
346
+ */
347
+ declare function getOrCreateUserId(length?: number): string;
348
+ /**
349
+ * Track page visits with localStorage
350
+ */
351
+ declare function trackPageVisit(): number;
352
+
353
+ /**
354
+ * Location Consent Manager
355
+ * When user enters MSISDN, they implicitly consent to location tracking
356
+ * This utility manages the consent state and prevents unnecessary permission prompts
357
+ */
358
+ /**
359
+ * Set location consent as granted (when MSISDN is provided)
360
+ */
361
+ declare function setLocationConsentGranted(): void;
362
+ /**
363
+ * Check if location consent has been granted
364
+ */
365
+ declare function hasLocationConsent(): boolean;
366
+ /**
367
+ * Get location consent timestamp
368
+ */
369
+ declare function getLocationConsentTimestamp(): string | null;
370
+ /**
371
+ * Clear location consent (for testing or user revocation)
372
+ */
373
+ declare function clearLocationConsent(): void;
374
+ /**
375
+ * Check if MSISDN is provided and set consent accordingly
376
+ * Call this whenever MSISDN is detected
377
+ */
378
+ declare function checkAndSetLocationConsent(msisdn?: string | null): boolean;
379
+
380
+ /**
381
+ * IP Geolocation Service
382
+ * Fetches location data (country, region, city) from user's IP address
383
+ * Uses free tier of ip-api.com (no API key required, 45 requests/minute)
384
+ */
385
+ /**
386
+ * Get public IP address using ip-api.com
387
+ * Free tier: 45 requests/minute, no API key required
388
+ *
389
+ * @returns Promise<string | null> - The public IP address, or null if unavailable
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * const ip = await getPublicIP();
394
+ * console.log('Your IP:', ip); // e.g., "203.0.113.42"
395
+ * ```
396
+ */
397
+ declare function getPublicIP(): Promise<string | null>;
398
+ /**
399
+ * Get location from IP address using ip-api.com
400
+ * Free tier: 45 requests/minute, no API key required
401
+ *
402
+ * Alternative services:
403
+ * - ipapi.co (requires API key for production)
404
+ * - ipgeolocation.io (requires API key)
405
+ * - ip-api.com (free tier available)
406
+ */
407
+ declare function getIPLocation(ip: string): Promise<IPLocation | null>;
408
+ /**
409
+ * Get IP address from request headers
410
+ * Handles various proxy headers (x-forwarded-for, x-real-ip, etc.)
411
+ */
412
+ declare function getIPFromRequest(req: Request | any): string;
413
+
414
+ export { AnalyticsService, AttributionDetector, DeviceDetector, LocationDetector, NetworkDetector, checkAndSetLocationConsent, clearLocationConsent, useAnalytics as default, getIPFromRequest, getIPLocation, getLocationConsentTimestamp, getOrCreateUserId, getPublicIP, hasLocationConsent, loadJSON, loadSessionJSON, saveJSON, saveSessionJSON, setLocationConsentGranted, trackPageVisit, useAnalytics };
415
+ export type { AnalyticsConfig, AnalyticsEvent, AttributionInfo, DeviceInfo, DeviceType, IPLocation, LocationInfo, NetworkInfo, NetworkType, UseAnalyticsOptions, UseAnalyticsReturn };