@grainql/analytics-web 2.5.4 → 2.6.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 +3 -1
- package/dist/activity.js +1 -1
- package/dist/cjs/activity.js +1 -1
- package/dist/cjs/activity.js.map +1 -1
- package/dist/cjs/consent.js +4 -4
- package/dist/cjs/consent.js.map +1 -1
- package/dist/cjs/heartbeat.d.ts.map +1 -1
- package/dist/cjs/heartbeat.js +0 -6
- package/dist/cjs/heartbeat.js.map +1 -1
- package/dist/cjs/heatmap-tracking.d.ts +90 -0
- package/dist/cjs/heatmap-tracking.d.ts.map +1 -0
- package/dist/cjs/heatmap-tracking.js +465 -0
- package/dist/cjs/heatmap-tracking.js.map +1 -0
- package/dist/cjs/index.d.ts +6 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interaction-tracking.d.ts.map +1 -1
- package/dist/cjs/interaction-tracking.js +9 -18
- package/dist/cjs/interaction-tracking.js.map +1 -1
- package/dist/cjs/page-tracking.d.ts.map +1 -1
- package/dist/cjs/page-tracking.js +0 -9
- package/dist/cjs/page-tracking.js.map +1 -1
- package/dist/cjs/section-tracking.d.ts.map +1 -1
- package/dist/cjs/section-tracking.js +1 -7
- package/dist/cjs/section-tracking.js.map +1 -1
- package/dist/cjs/types/heatmap-tracking.d.ts +41 -0
- package/dist/cjs/types/heatmap-tracking.d.ts.map +1 -0
- package/dist/cjs/types/heatmap-tracking.js +6 -0
- package/dist/cjs/types/heatmap-tracking.js.map +1 -0
- package/dist/consent.js +4 -4
- package/dist/esm/activity.js +1 -1
- package/dist/esm/activity.js.map +1 -1
- package/dist/esm/consent.js +4 -4
- package/dist/esm/consent.js.map +1 -1
- package/dist/esm/heartbeat.d.ts.map +1 -1
- package/dist/esm/heartbeat.js +0 -6
- package/dist/esm/heartbeat.js.map +1 -1
- package/dist/esm/heatmap-tracking.d.ts +90 -0
- package/dist/esm/heatmap-tracking.d.ts.map +1 -0
- package/dist/esm/heatmap-tracking.js +461 -0
- package/dist/esm/heatmap-tracking.js.map +1 -0
- package/dist/esm/index.d.ts +6 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interaction-tracking.d.ts.map +1 -1
- package/dist/esm/interaction-tracking.js +9 -18
- package/dist/esm/interaction-tracking.js.map +1 -1
- package/dist/esm/page-tracking.d.ts.map +1 -1
- package/dist/esm/page-tracking.js +0 -9
- package/dist/esm/page-tracking.js.map +1 -1
- package/dist/esm/section-tracking.d.ts.map +1 -1
- package/dist/esm/section-tracking.js +1 -7
- package/dist/esm/section-tracking.js.map +1 -1
- package/dist/esm/types/heatmap-tracking.d.ts +41 -0
- package/dist/esm/types/heatmap-tracking.d.ts.map +1 -0
- package/dist/esm/types/heatmap-tracking.js +5 -0
- package/dist/esm/types/heatmap-tracking.js.map +1 -0
- package/dist/heartbeat.d.ts.map +1 -1
- package/dist/heartbeat.js +0 -6
- package/dist/heatmap-tracking.d.ts +90 -0
- package/dist/heatmap-tracking.d.ts.map +1 -0
- package/dist/heatmap-tracking.js +465 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +503 -79
- package/dist/index.global.dev.js.map +4 -4
- package/dist/index.global.js +2 -2
- package/dist/index.global.js.map +4 -4
- package/dist/index.js +61 -38
- package/dist/index.mjs +61 -38
- package/dist/interaction-tracking.d.ts.map +1 -1
- package/dist/interaction-tracking.js +9 -18
- package/dist/page-tracking.d.ts.map +1 -1
- package/dist/page-tracking.js +0 -9
- package/dist/section-tracking.d.ts.map +1 -1
- package/dist/section-tracking.js +1 -7
- package/dist/types/heatmap-tracking.d.ts +41 -0
- package/dist/types/heatmap-tracking.d.ts.map +1 -0
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -75,6 +75,7 @@ class GrainAnalytics {
|
|
|
75
75
|
// Auto-tracking properties
|
|
76
76
|
this.interactionTrackingManager = null;
|
|
77
77
|
this.sectionTrackingManager = null;
|
|
78
|
+
this.heatmapTrackingManager = null;
|
|
78
79
|
// Session tracking
|
|
79
80
|
this.sessionStartTime = Date.now();
|
|
80
81
|
this.sessionEventCount = 0;
|
|
@@ -104,6 +105,8 @@ class GrainAnalytics {
|
|
|
104
105
|
heartbeatInactiveInterval: 300000, // 5 minutes
|
|
105
106
|
enableAutoPageView: true,
|
|
106
107
|
stripQueryParams: true,
|
|
108
|
+
// Heatmap Tracking defaults
|
|
109
|
+
enableHeatmapTracking: true,
|
|
107
110
|
...config,
|
|
108
111
|
tenantId: config.tenantId,
|
|
109
112
|
};
|
|
@@ -132,6 +135,10 @@ class GrainAnalytics {
|
|
|
132
135
|
this.initializeAutomaticTracking();
|
|
133
136
|
// Track session start
|
|
134
137
|
this.trackSessionStart();
|
|
138
|
+
// Initialize heatmap tracking if enabled
|
|
139
|
+
if (this.config.enableHeatmapTracking) {
|
|
140
|
+
this.initializeHeatmapTracking();
|
|
141
|
+
}
|
|
135
142
|
}
|
|
136
143
|
// Set up consent change listener to flush waiting events and handle consent upgrade
|
|
137
144
|
this.consentManager.addListener((state) => {
|
|
@@ -381,6 +388,9 @@ class GrainAnalytics {
|
|
|
381
388
|
* Log formatted error gracefully
|
|
382
389
|
*/
|
|
383
390
|
logError(formattedError) {
|
|
391
|
+
// Only log errors in debug mode to reduce noise in production
|
|
392
|
+
if (!this.config.debug)
|
|
393
|
+
return;
|
|
384
394
|
const { code, message, digest, timestamp, context } = formattedError;
|
|
385
395
|
const errorOutput = {
|
|
386
396
|
'🚨 Grain Analytics Error': {
|
|
@@ -398,10 +408,7 @@ class GrainAnalytics {
|
|
|
398
408
|
}
|
|
399
409
|
};
|
|
400
410
|
console.error('🚨 Grain Analytics Error:', errorOutput);
|
|
401
|
-
|
|
402
|
-
if (this.config.debug) {
|
|
403
|
-
console.error(`[Grain Analytics] ${code}: ${message} (${context}) - Events: ${digest.eventCount}, Props: ${digest.totalProperties}, Size: ${digest.totalSize}B`);
|
|
404
|
-
}
|
|
411
|
+
console.error(`[Grain Analytics] ${code}: ${message} (${context}) - Events: ${digest.eventCount}, Props: ${digest.totalProperties}, Size: ${digest.totalSize}B`);
|
|
405
412
|
}
|
|
406
413
|
/**
|
|
407
414
|
* Safely execute a function with error handling
|
|
@@ -509,7 +516,6 @@ class GrainAnalytics {
|
|
|
509
516
|
try {
|
|
510
517
|
const headers = await this.getAuthHeaders();
|
|
511
518
|
const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`;
|
|
512
|
-
this.log(`Sending ${events.length} events to ${url} (attempt ${attempt + 1})`);
|
|
513
519
|
const response = await fetch(url, {
|
|
514
520
|
method: 'POST',
|
|
515
521
|
headers,
|
|
@@ -582,7 +588,6 @@ class GrainAnalytics {
|
|
|
582
588
|
body,
|
|
583
589
|
keepalive: true,
|
|
584
590
|
});
|
|
585
|
-
this.log(`Successfully sent ${events.length} events via fetch (keepalive)`);
|
|
586
591
|
}
|
|
587
592
|
catch (error) {
|
|
588
593
|
// Log error gracefully for beacon failures (page unload scenarios)
|
|
@@ -654,7 +659,6 @@ class GrainAnalytics {
|
|
|
654
659
|
inactiveInterval: this.config.heartbeatInactiveInterval,
|
|
655
660
|
debug: this.config.debug,
|
|
656
661
|
});
|
|
657
|
-
this.log('Heartbeat tracking initialized');
|
|
658
662
|
}
|
|
659
663
|
catch (error) {
|
|
660
664
|
this.log('Failed to initialize heartbeat tracking:', error);
|
|
@@ -667,7 +671,6 @@ class GrainAnalytics {
|
|
|
667
671
|
debug: this.config.debug,
|
|
668
672
|
tenantId: this.config.tenantId,
|
|
669
673
|
});
|
|
670
|
-
this.log('Auto page view tracking initialized');
|
|
671
674
|
}
|
|
672
675
|
catch (error) {
|
|
673
676
|
this.log('Failed to initialize page view tracking:', error);
|
|
@@ -676,12 +679,41 @@ class GrainAnalytics {
|
|
|
676
679
|
// Initialize auto-tracking when config is available
|
|
677
680
|
this.initializeAutoTracking();
|
|
678
681
|
}
|
|
682
|
+
/**
|
|
683
|
+
* Initialize heatmap tracking
|
|
684
|
+
*/
|
|
685
|
+
initializeHeatmapTracking() {
|
|
686
|
+
if (typeof window === 'undefined')
|
|
687
|
+
return;
|
|
688
|
+
try {
|
|
689
|
+
this.log('Initializing heatmap tracking');
|
|
690
|
+
Promise.resolve().then(() => __importStar(require('./heatmap-tracking'))).then(({ HeatmapTrackingManager }) => {
|
|
691
|
+
try {
|
|
692
|
+
this.heatmapTrackingManager = new HeatmapTrackingManager(this, {
|
|
693
|
+
scrollDebounceDelay: 100,
|
|
694
|
+
batchDelay: 2000,
|
|
695
|
+
maxBatchSize: 20,
|
|
696
|
+
debug: this.config.debug,
|
|
697
|
+
});
|
|
698
|
+
this.log('Heatmap tracking initialized');
|
|
699
|
+
}
|
|
700
|
+
catch (error) {
|
|
701
|
+
this.log('Failed to initialize heatmap tracking:', error);
|
|
702
|
+
}
|
|
703
|
+
}).catch((error) => {
|
|
704
|
+
this.log('Failed to load heatmap tracking module:', error);
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
catch (error) {
|
|
708
|
+
this.log('Failed to initialize heatmap tracking:', error);
|
|
709
|
+
}
|
|
710
|
+
}
|
|
679
711
|
/**
|
|
680
712
|
* Initialize auto-tracking (interactions and sections)
|
|
681
713
|
*/
|
|
682
714
|
async initializeAutoTracking() {
|
|
683
715
|
try {
|
|
684
|
-
this.log('Initializing auto-tracking
|
|
716
|
+
this.log('Initializing auto-tracking');
|
|
685
717
|
// Fetch remote config to get auto-tracking configuration
|
|
686
718
|
const userId = this.globalUserId || this.persistentAnonymousUserId || this.generateUUID();
|
|
687
719
|
const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
|
|
@@ -694,25 +726,20 @@ class GrainAnalytics {
|
|
|
694
726
|
};
|
|
695
727
|
const headers = await this.getAuthHeaders();
|
|
696
728
|
const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;
|
|
697
|
-
this.log('Fetching auto-tracking config from:', url);
|
|
698
729
|
const response = await fetch(url, {
|
|
699
730
|
method: 'POST',
|
|
700
731
|
headers,
|
|
701
732
|
body: JSON.stringify(request),
|
|
702
733
|
});
|
|
703
734
|
if (!response.ok) {
|
|
704
|
-
this.log('Failed to fetch auto-tracking config:', response.status
|
|
735
|
+
this.log('Failed to fetch auto-tracking config:', response.status);
|
|
705
736
|
return;
|
|
706
737
|
}
|
|
707
738
|
const configResponse = await response.json();
|
|
708
|
-
this.log('Received config response:', configResponse);
|
|
709
739
|
if (configResponse.autoTrackingConfig) {
|
|
710
|
-
this.log('Auto-tracking config
|
|
740
|
+
this.log('Auto-tracking config loaded');
|
|
711
741
|
this.setupAutoTrackingManagers(configResponse.autoTrackingConfig);
|
|
712
742
|
}
|
|
713
|
-
else {
|
|
714
|
-
this.log('No auto-tracking config in response');
|
|
715
|
-
}
|
|
716
743
|
}
|
|
717
744
|
catch (error) {
|
|
718
745
|
this.log('Failed to initialize auto-tracking:', error);
|
|
@@ -723,10 +750,10 @@ class GrainAnalytics {
|
|
|
723
750
|
* Setup auto-tracking managers
|
|
724
751
|
*/
|
|
725
752
|
setupAutoTrackingManagers(config) {
|
|
726
|
-
this.log('Setting up auto-tracking managers
|
|
753
|
+
this.log('Setting up auto-tracking managers');
|
|
727
754
|
// Lazy load the managers to avoid bundling them if not needed
|
|
728
755
|
if (config.interactions && config.interactions.length > 0) {
|
|
729
|
-
this.log('Loading interaction tracking
|
|
756
|
+
this.log('Loading interaction tracking:', config.interactions.length, 'interactions');
|
|
730
757
|
Promise.resolve().then(() => __importStar(require('./interaction-tracking'))).then(({ InteractionTrackingManager }) => {
|
|
731
758
|
try {
|
|
732
759
|
this.interactionTrackingManager = new InteractionTrackingManager(this, config.interactions, {
|
|
@@ -734,20 +761,17 @@ class GrainAnalytics {
|
|
|
734
761
|
enableMutationObserver: true,
|
|
735
762
|
mutationDebounceDelay: 500,
|
|
736
763
|
});
|
|
737
|
-
this.log('
|
|
764
|
+
this.log('Interaction tracking initialized');
|
|
738
765
|
}
|
|
739
766
|
catch (error) {
|
|
740
|
-
this.log('
|
|
767
|
+
this.log('Failed to initialize interaction tracking:', error);
|
|
741
768
|
}
|
|
742
769
|
}).catch((error) => {
|
|
743
|
-
this.log('
|
|
770
|
+
this.log('Failed to load interaction tracking module:', error);
|
|
744
771
|
});
|
|
745
772
|
}
|
|
746
|
-
else {
|
|
747
|
-
this.log('No interactions configured for auto-tracking');
|
|
748
|
-
}
|
|
749
773
|
if (config.sections && config.sections.length > 0) {
|
|
750
|
-
this.log('Loading section tracking
|
|
774
|
+
this.log('Loading section tracking:', config.sections.length, 'sections');
|
|
751
775
|
Promise.resolve().then(() => __importStar(require('./section-tracking'))).then(({ SectionTrackingManager }) => {
|
|
752
776
|
try {
|
|
753
777
|
this.sectionTrackingManager = new SectionTrackingManager(this, config.sections, {
|
|
@@ -758,18 +782,15 @@ class GrainAnalytics {
|
|
|
758
782
|
batchDelay: 2000,
|
|
759
783
|
debug: this.config.debug,
|
|
760
784
|
});
|
|
761
|
-
this.log('
|
|
785
|
+
this.log('Section tracking initialized');
|
|
762
786
|
}
|
|
763
787
|
catch (error) {
|
|
764
|
-
this.log('
|
|
788
|
+
this.log('Failed to initialize section tracking:', error);
|
|
765
789
|
}
|
|
766
790
|
}).catch((error) => {
|
|
767
|
-
this.log('
|
|
791
|
+
this.log('Failed to load section tracking module:', error);
|
|
768
792
|
});
|
|
769
793
|
}
|
|
770
|
-
else {
|
|
771
|
-
this.log('No sections configured for auto-tracking');
|
|
772
|
-
}
|
|
773
794
|
}
|
|
774
795
|
/**
|
|
775
796
|
* Track session start event
|
|
@@ -827,7 +848,7 @@ class GrainAnalytics {
|
|
|
827
848
|
properties.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
828
849
|
}
|
|
829
850
|
this.trackSystemEvent('_grain_session_start', properties);
|
|
830
|
-
this.log('Session started
|
|
851
|
+
this.log('Session started');
|
|
831
852
|
}
|
|
832
853
|
/**
|
|
833
854
|
* Track session end event
|
|
@@ -850,7 +871,7 @@ class GrainAnalytics {
|
|
|
850
871
|
properties.page_count = pageCount; // Keep for backward compatibility
|
|
851
872
|
}
|
|
852
873
|
this.trackSystemEvent('_grain_session_end', properties);
|
|
853
|
-
this.log('Session ended
|
|
874
|
+
this.log('Session ended');
|
|
854
875
|
}
|
|
855
876
|
/**
|
|
856
877
|
* Detect browser name
|
|
@@ -954,7 +975,7 @@ class GrainAnalytics {
|
|
|
954
975
|
// Bypass consent check for necessary system events
|
|
955
976
|
this.eventQueue.push(event);
|
|
956
977
|
this.eventCountSinceLastHeartbeat++;
|
|
957
|
-
this.log(`Queued system event: ${eventName}
|
|
978
|
+
this.log(`Queued system event: ${eventName}`);
|
|
958
979
|
// Consider flushing
|
|
959
980
|
if (this.eventQueue.length >= this.config.batchSize) {
|
|
960
981
|
this.flush().catch((error) => {
|
|
@@ -1049,7 +1070,7 @@ class GrainAnalytics {
|
|
|
1049
1070
|
this.eventQueue.push(formattedEvent);
|
|
1050
1071
|
this.eventCountSinceLastHeartbeat++;
|
|
1051
1072
|
this.sessionEventCount++;
|
|
1052
|
-
this.log(`Queued event: ${event.eventName}
|
|
1073
|
+
this.log(`Queued event: ${event.eventName}`);
|
|
1053
1074
|
// Check if we should flush immediately
|
|
1054
1075
|
if (opts.flush || this.eventQueue.length >= this.config.batchSize) {
|
|
1055
1076
|
await this.flush();
|
|
@@ -1275,7 +1296,6 @@ class GrainAnalytics {
|
|
|
1275
1296
|
try {
|
|
1276
1297
|
const headers = await this.getAuthHeaders();
|
|
1277
1298
|
const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`;
|
|
1278
|
-
this.log(`Setting properties for user ${payload.userId} (attempt ${attempt + 1})`);
|
|
1279
1299
|
const response = await fetch(url, {
|
|
1280
1300
|
method: 'POST',
|
|
1281
1301
|
headers,
|
|
@@ -1520,7 +1540,6 @@ class GrainAnalytics {
|
|
|
1520
1540
|
try {
|
|
1521
1541
|
const headers = await this.getAuthHeaders();
|
|
1522
1542
|
const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;
|
|
1523
|
-
this.log(`Fetching configurations for user ${userId} (attempt ${attempt + 1})`);
|
|
1524
1543
|
const response = await fetch(url, {
|
|
1525
1544
|
method: 'POST',
|
|
1526
1545
|
headers,
|
|
@@ -1549,7 +1568,7 @@ class GrainAnalytics {
|
|
|
1549
1568
|
if (configResponse.configurations) {
|
|
1550
1569
|
this.updateConfigCache(configResponse, userId);
|
|
1551
1570
|
}
|
|
1552
|
-
this.log(
|
|
1571
|
+
this.log('Successfully fetched configurations');
|
|
1553
1572
|
return configResponse;
|
|
1554
1573
|
}
|
|
1555
1574
|
catch (error) {
|
|
@@ -1825,6 +1844,10 @@ class GrainAnalytics {
|
|
|
1825
1844
|
this.sectionTrackingManager.destroy();
|
|
1826
1845
|
this.sectionTrackingManager = null;
|
|
1827
1846
|
}
|
|
1847
|
+
if (this.heatmapTrackingManager) {
|
|
1848
|
+
this.heatmapTrackingManager.destroy();
|
|
1849
|
+
this.heatmapTrackingManager = null;
|
|
1850
|
+
}
|
|
1828
1851
|
// Send any remaining events (in chunks if necessary)
|
|
1829
1852
|
if (this.eventQueue.length > 0) {
|
|
1830
1853
|
const eventsToSend = [...this.eventQueue];
|
package/dist/index.mjs
CHANGED
|
@@ -34,6 +34,7 @@ export class GrainAnalytics {
|
|
|
34
34
|
// Auto-tracking properties
|
|
35
35
|
this.interactionTrackingManager = null;
|
|
36
36
|
this.sectionTrackingManager = null;
|
|
37
|
+
this.heatmapTrackingManager = null;
|
|
37
38
|
// Session tracking
|
|
38
39
|
this.sessionStartTime = Date.now();
|
|
39
40
|
this.sessionEventCount = 0;
|
|
@@ -63,6 +64,8 @@ export class GrainAnalytics {
|
|
|
63
64
|
heartbeatInactiveInterval: 300000, // 5 minutes
|
|
64
65
|
enableAutoPageView: true,
|
|
65
66
|
stripQueryParams: true,
|
|
67
|
+
// Heatmap Tracking defaults
|
|
68
|
+
enableHeatmapTracking: true,
|
|
66
69
|
...config,
|
|
67
70
|
tenantId: config.tenantId,
|
|
68
71
|
};
|
|
@@ -91,6 +94,10 @@ export class GrainAnalytics {
|
|
|
91
94
|
this.initializeAutomaticTracking();
|
|
92
95
|
// Track session start
|
|
93
96
|
this.trackSessionStart();
|
|
97
|
+
// Initialize heatmap tracking if enabled
|
|
98
|
+
if (this.config.enableHeatmapTracking) {
|
|
99
|
+
this.initializeHeatmapTracking();
|
|
100
|
+
}
|
|
94
101
|
}
|
|
95
102
|
// Set up consent change listener to flush waiting events and handle consent upgrade
|
|
96
103
|
this.consentManager.addListener((state) => {
|
|
@@ -340,6 +347,9 @@ export class GrainAnalytics {
|
|
|
340
347
|
* Log formatted error gracefully
|
|
341
348
|
*/
|
|
342
349
|
logError(formattedError) {
|
|
350
|
+
// Only log errors in debug mode to reduce noise in production
|
|
351
|
+
if (!this.config.debug)
|
|
352
|
+
return;
|
|
343
353
|
const { code, message, digest, timestamp, context } = formattedError;
|
|
344
354
|
const errorOutput = {
|
|
345
355
|
'🚨 Grain Analytics Error': {
|
|
@@ -357,10 +367,7 @@ export class GrainAnalytics {
|
|
|
357
367
|
}
|
|
358
368
|
};
|
|
359
369
|
console.error('🚨 Grain Analytics Error:', errorOutput);
|
|
360
|
-
|
|
361
|
-
if (this.config.debug) {
|
|
362
|
-
console.error(`[Grain Analytics] ${code}: ${message} (${context}) - Events: ${digest.eventCount}, Props: ${digest.totalProperties}, Size: ${digest.totalSize}B`);
|
|
363
|
-
}
|
|
370
|
+
console.error(`[Grain Analytics] ${code}: ${message} (${context}) - Events: ${digest.eventCount}, Props: ${digest.totalProperties}, Size: ${digest.totalSize}B`);
|
|
364
371
|
}
|
|
365
372
|
/**
|
|
366
373
|
* Safely execute a function with error handling
|
|
@@ -468,7 +475,6 @@ export class GrainAnalytics {
|
|
|
468
475
|
try {
|
|
469
476
|
const headers = await this.getAuthHeaders();
|
|
470
477
|
const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`;
|
|
471
|
-
this.log(`Sending ${events.length} events to ${url} (attempt ${attempt + 1})`);
|
|
472
478
|
const response = await fetch(url, {
|
|
473
479
|
method: 'POST',
|
|
474
480
|
headers,
|
|
@@ -541,7 +547,6 @@ export class GrainAnalytics {
|
|
|
541
547
|
body,
|
|
542
548
|
keepalive: true,
|
|
543
549
|
});
|
|
544
|
-
this.log(`Successfully sent ${events.length} events via fetch (keepalive)`);
|
|
545
550
|
}
|
|
546
551
|
catch (error) {
|
|
547
552
|
// Log error gracefully for beacon failures (page unload scenarios)
|
|
@@ -613,7 +618,6 @@ export class GrainAnalytics {
|
|
|
613
618
|
inactiveInterval: this.config.heartbeatInactiveInterval,
|
|
614
619
|
debug: this.config.debug,
|
|
615
620
|
});
|
|
616
|
-
this.log('Heartbeat tracking initialized');
|
|
617
621
|
}
|
|
618
622
|
catch (error) {
|
|
619
623
|
this.log('Failed to initialize heartbeat tracking:', error);
|
|
@@ -626,7 +630,6 @@ export class GrainAnalytics {
|
|
|
626
630
|
debug: this.config.debug,
|
|
627
631
|
tenantId: this.config.tenantId,
|
|
628
632
|
});
|
|
629
|
-
this.log('Auto page view tracking initialized');
|
|
630
633
|
}
|
|
631
634
|
catch (error) {
|
|
632
635
|
this.log('Failed to initialize page view tracking:', error);
|
|
@@ -635,12 +638,41 @@ export class GrainAnalytics {
|
|
|
635
638
|
// Initialize auto-tracking when config is available
|
|
636
639
|
this.initializeAutoTracking();
|
|
637
640
|
}
|
|
641
|
+
/**
|
|
642
|
+
* Initialize heatmap tracking
|
|
643
|
+
*/
|
|
644
|
+
initializeHeatmapTracking() {
|
|
645
|
+
if (typeof window === 'undefined')
|
|
646
|
+
return;
|
|
647
|
+
try {
|
|
648
|
+
this.log('Initializing heatmap tracking');
|
|
649
|
+
import('./heatmap-tracking').then(({ HeatmapTrackingManager }) => {
|
|
650
|
+
try {
|
|
651
|
+
this.heatmapTrackingManager = new HeatmapTrackingManager(this, {
|
|
652
|
+
scrollDebounceDelay: 100,
|
|
653
|
+
batchDelay: 2000,
|
|
654
|
+
maxBatchSize: 20,
|
|
655
|
+
debug: this.config.debug,
|
|
656
|
+
});
|
|
657
|
+
this.log('Heatmap tracking initialized');
|
|
658
|
+
}
|
|
659
|
+
catch (error) {
|
|
660
|
+
this.log('Failed to initialize heatmap tracking:', error);
|
|
661
|
+
}
|
|
662
|
+
}).catch((error) => {
|
|
663
|
+
this.log('Failed to load heatmap tracking module:', error);
|
|
664
|
+
});
|
|
665
|
+
}
|
|
666
|
+
catch (error) {
|
|
667
|
+
this.log('Failed to initialize heatmap tracking:', error);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
638
670
|
/**
|
|
639
671
|
* Initialize auto-tracking (interactions and sections)
|
|
640
672
|
*/
|
|
641
673
|
async initializeAutoTracking() {
|
|
642
674
|
try {
|
|
643
|
-
this.log('Initializing auto-tracking
|
|
675
|
+
this.log('Initializing auto-tracking');
|
|
644
676
|
// Fetch remote config to get auto-tracking configuration
|
|
645
677
|
const userId = this.globalUserId || this.persistentAnonymousUserId || this.generateUUID();
|
|
646
678
|
const currentUrl = typeof window !== 'undefined' ? window.location.href : '';
|
|
@@ -653,25 +685,20 @@ export class GrainAnalytics {
|
|
|
653
685
|
};
|
|
654
686
|
const headers = await this.getAuthHeaders();
|
|
655
687
|
const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;
|
|
656
|
-
this.log('Fetching auto-tracking config from:', url);
|
|
657
688
|
const response = await fetch(url, {
|
|
658
689
|
method: 'POST',
|
|
659
690
|
headers,
|
|
660
691
|
body: JSON.stringify(request),
|
|
661
692
|
});
|
|
662
693
|
if (!response.ok) {
|
|
663
|
-
this.log('Failed to fetch auto-tracking config:', response.status
|
|
694
|
+
this.log('Failed to fetch auto-tracking config:', response.status);
|
|
664
695
|
return;
|
|
665
696
|
}
|
|
666
697
|
const configResponse = await response.json();
|
|
667
|
-
this.log('Received config response:', configResponse);
|
|
668
698
|
if (configResponse.autoTrackingConfig) {
|
|
669
|
-
this.log('Auto-tracking config
|
|
699
|
+
this.log('Auto-tracking config loaded');
|
|
670
700
|
this.setupAutoTrackingManagers(configResponse.autoTrackingConfig);
|
|
671
701
|
}
|
|
672
|
-
else {
|
|
673
|
-
this.log('No auto-tracking config in response');
|
|
674
|
-
}
|
|
675
702
|
}
|
|
676
703
|
catch (error) {
|
|
677
704
|
this.log('Failed to initialize auto-tracking:', error);
|
|
@@ -682,10 +709,10 @@ export class GrainAnalytics {
|
|
|
682
709
|
* Setup auto-tracking managers
|
|
683
710
|
*/
|
|
684
711
|
setupAutoTrackingManagers(config) {
|
|
685
|
-
this.log('Setting up auto-tracking managers
|
|
712
|
+
this.log('Setting up auto-tracking managers');
|
|
686
713
|
// Lazy load the managers to avoid bundling them if not needed
|
|
687
714
|
if (config.interactions && config.interactions.length > 0) {
|
|
688
|
-
this.log('Loading interaction tracking
|
|
715
|
+
this.log('Loading interaction tracking:', config.interactions.length, 'interactions');
|
|
689
716
|
import('./interaction-tracking').then(({ InteractionTrackingManager }) => {
|
|
690
717
|
try {
|
|
691
718
|
this.interactionTrackingManager = new InteractionTrackingManager(this, config.interactions, {
|
|
@@ -693,20 +720,17 @@ export class GrainAnalytics {
|
|
|
693
720
|
enableMutationObserver: true,
|
|
694
721
|
mutationDebounceDelay: 500,
|
|
695
722
|
});
|
|
696
|
-
this.log('
|
|
723
|
+
this.log('Interaction tracking initialized');
|
|
697
724
|
}
|
|
698
725
|
catch (error) {
|
|
699
|
-
this.log('
|
|
726
|
+
this.log('Failed to initialize interaction tracking:', error);
|
|
700
727
|
}
|
|
701
728
|
}).catch((error) => {
|
|
702
|
-
this.log('
|
|
729
|
+
this.log('Failed to load interaction tracking module:', error);
|
|
703
730
|
});
|
|
704
731
|
}
|
|
705
|
-
else {
|
|
706
|
-
this.log('No interactions configured for auto-tracking');
|
|
707
|
-
}
|
|
708
732
|
if (config.sections && config.sections.length > 0) {
|
|
709
|
-
this.log('Loading section tracking
|
|
733
|
+
this.log('Loading section tracking:', config.sections.length, 'sections');
|
|
710
734
|
import('./section-tracking').then(({ SectionTrackingManager }) => {
|
|
711
735
|
try {
|
|
712
736
|
this.sectionTrackingManager = new SectionTrackingManager(this, config.sections, {
|
|
@@ -717,18 +741,15 @@ export class GrainAnalytics {
|
|
|
717
741
|
batchDelay: 2000,
|
|
718
742
|
debug: this.config.debug,
|
|
719
743
|
});
|
|
720
|
-
this.log('
|
|
744
|
+
this.log('Section tracking initialized');
|
|
721
745
|
}
|
|
722
746
|
catch (error) {
|
|
723
|
-
this.log('
|
|
747
|
+
this.log('Failed to initialize section tracking:', error);
|
|
724
748
|
}
|
|
725
749
|
}).catch((error) => {
|
|
726
|
-
this.log('
|
|
750
|
+
this.log('Failed to load section tracking module:', error);
|
|
727
751
|
});
|
|
728
752
|
}
|
|
729
|
-
else {
|
|
730
|
-
this.log('No sections configured for auto-tracking');
|
|
731
|
-
}
|
|
732
753
|
}
|
|
733
754
|
/**
|
|
734
755
|
* Track session start event
|
|
@@ -786,7 +807,7 @@ export class GrainAnalytics {
|
|
|
786
807
|
properties.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
787
808
|
}
|
|
788
809
|
this.trackSystemEvent('_grain_session_start', properties);
|
|
789
|
-
this.log('Session started
|
|
810
|
+
this.log('Session started');
|
|
790
811
|
}
|
|
791
812
|
/**
|
|
792
813
|
* Track session end event
|
|
@@ -809,7 +830,7 @@ export class GrainAnalytics {
|
|
|
809
830
|
properties.page_count = pageCount; // Keep for backward compatibility
|
|
810
831
|
}
|
|
811
832
|
this.trackSystemEvent('_grain_session_end', properties);
|
|
812
|
-
this.log('Session ended
|
|
833
|
+
this.log('Session ended');
|
|
813
834
|
}
|
|
814
835
|
/**
|
|
815
836
|
* Detect browser name
|
|
@@ -913,7 +934,7 @@ export class GrainAnalytics {
|
|
|
913
934
|
// Bypass consent check for necessary system events
|
|
914
935
|
this.eventQueue.push(event);
|
|
915
936
|
this.eventCountSinceLastHeartbeat++;
|
|
916
|
-
this.log(`Queued system event: ${eventName}
|
|
937
|
+
this.log(`Queued system event: ${eventName}`);
|
|
917
938
|
// Consider flushing
|
|
918
939
|
if (this.eventQueue.length >= this.config.batchSize) {
|
|
919
940
|
this.flush().catch((error) => {
|
|
@@ -1008,7 +1029,7 @@ export class GrainAnalytics {
|
|
|
1008
1029
|
this.eventQueue.push(formattedEvent);
|
|
1009
1030
|
this.eventCountSinceLastHeartbeat++;
|
|
1010
1031
|
this.sessionEventCount++;
|
|
1011
|
-
this.log(`Queued event: ${event.eventName}
|
|
1032
|
+
this.log(`Queued event: ${event.eventName}`);
|
|
1012
1033
|
// Check if we should flush immediately
|
|
1013
1034
|
if (opts.flush || this.eventQueue.length >= this.config.batchSize) {
|
|
1014
1035
|
await this.flush();
|
|
@@ -1234,7 +1255,6 @@ export class GrainAnalytics {
|
|
|
1234
1255
|
try {
|
|
1235
1256
|
const headers = await this.getAuthHeaders();
|
|
1236
1257
|
const url = `${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`;
|
|
1237
|
-
this.log(`Setting properties for user ${payload.userId} (attempt ${attempt + 1})`);
|
|
1238
1258
|
const response = await fetch(url, {
|
|
1239
1259
|
method: 'POST',
|
|
1240
1260
|
headers,
|
|
@@ -1479,7 +1499,6 @@ export class GrainAnalytics {
|
|
|
1479
1499
|
try {
|
|
1480
1500
|
const headers = await this.getAuthHeaders();
|
|
1481
1501
|
const url = `${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;
|
|
1482
|
-
this.log(`Fetching configurations for user ${userId} (attempt ${attempt + 1})`);
|
|
1483
1502
|
const response = await fetch(url, {
|
|
1484
1503
|
method: 'POST',
|
|
1485
1504
|
headers,
|
|
@@ -1508,7 +1527,7 @@ export class GrainAnalytics {
|
|
|
1508
1527
|
if (configResponse.configurations) {
|
|
1509
1528
|
this.updateConfigCache(configResponse, userId);
|
|
1510
1529
|
}
|
|
1511
|
-
this.log(
|
|
1530
|
+
this.log('Successfully fetched configurations');
|
|
1512
1531
|
return configResponse;
|
|
1513
1532
|
}
|
|
1514
1533
|
catch (error) {
|
|
@@ -1784,6 +1803,10 @@ export class GrainAnalytics {
|
|
|
1784
1803
|
this.sectionTrackingManager.destroy();
|
|
1785
1804
|
this.sectionTrackingManager = null;
|
|
1786
1805
|
}
|
|
1806
|
+
if (this.heatmapTrackingManager) {
|
|
1807
|
+
this.heatmapTrackingManager.destroy();
|
|
1808
|
+
this.heatmapTrackingManager = null;
|
|
1809
|
+
}
|
|
1787
1810
|
// Send any remaining events (in chunks if necessary)
|
|
1788
1811
|
if (this.eventQueue.length > 0) {
|
|
1789
1812
|
const eventsToSend = [...this.eventQueue];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interaction-tracking.d.ts","sourceRoot":"","sources":["../src/interaction-tracking.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjH,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;IACxE,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAA6E;IACtG,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,qBAAqB,CAAuB;gBAGlD,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,iBAAiB,EAAE,EACjC,MAAM,GAAE,yBAA8B;IA0BxC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,yBAAyB;
|
|
1
|
+
{"version":3,"file":"interaction-tracking.d.ts","sourceRoot":"","sources":["../src/interaction-tracking.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjH,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,CAAC;IACxE,GAAG,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,yBAAyB;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,qBAAa,0BAA0B;IACrC,OAAO,CAAC,OAAO,CAAqB;IACpC,OAAO,CAAC,YAAY,CAAsB;IAC1C,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,iBAAiB,CAA6E;IACtG,OAAO,CAAC,UAAU,CAA0C;IAC5D,OAAO,CAAC,gBAAgB,CAAiC;IACzD,OAAO,CAAC,qBAAqB,CAAuB;gBAGlD,OAAO,EAAE,kBAAkB,EAC3B,YAAY,EAAE,iBAAiB,EAAE,EACjC,MAAM,GAAE,yBAA8B;IA0BxC;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAiCjC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiC9B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAkB9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAyC1B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA0B7B;;OAEG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACH,OAAO,CAAC,eAAe;IAWvB;;OAEG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;IACH,kBAAkB,CAAC,YAAY,EAAE,iBAAiB,EAAE,GAAG,IAAI;IAoB3D;;OAEG;IACH,OAAO,IAAI,IAAI;CA4BhB"}
|
|
@@ -40,7 +40,7 @@ class InteractionTrackingManager {
|
|
|
40
40
|
attachAllListeners() {
|
|
41
41
|
if (this.isDestroyed)
|
|
42
42
|
return;
|
|
43
|
-
this.log('Attaching interaction listeners
|
|
43
|
+
this.log('Attaching interaction listeners');
|
|
44
44
|
for (const interaction of this.interactions) {
|
|
45
45
|
this.attachInteractionListener(interaction);
|
|
46
46
|
}
|
|
@@ -73,7 +73,6 @@ class InteractionTrackingManager {
|
|
|
73
73
|
handlers.push({ event: 'focus', handler: focusHandler });
|
|
74
74
|
}
|
|
75
75
|
this.attachedListeners.set(element, handlers);
|
|
76
|
-
this.log('Attached listeners to element for:', interaction.eventName);
|
|
77
76
|
}
|
|
78
77
|
/**
|
|
79
78
|
* Handle click event on interaction
|
|
@@ -98,21 +97,15 @@ class InteractionTrackingManager {
|
|
|
98
97
|
...(isNavigationLink && { href: element.href }),
|
|
99
98
|
timestamp: Date.now(),
|
|
100
99
|
};
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
});
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
else {
|
|
113
|
-
this.tracker.track(interaction.eventName, eventProperties);
|
|
100
|
+
// Always use flush for auto-tracked clicks to ensure delivery
|
|
101
|
+
// This is especially important for navigation links and quick interactions
|
|
102
|
+
const result = this.tracker.track(interaction.eventName, eventProperties, { flush: true });
|
|
103
|
+
if (result instanceof Promise) {
|
|
104
|
+
result.catch((error) => {
|
|
105
|
+
// Log error but don't block interaction
|
|
106
|
+
this.log('Failed to track click:', error);
|
|
107
|
+
});
|
|
114
108
|
}
|
|
115
|
-
this.log('Tracked click interaction:', interaction.eventName);
|
|
116
109
|
}
|
|
117
110
|
/**
|
|
118
111
|
* Handle focus event on interaction (for form fields)
|
|
@@ -133,7 +126,6 @@ class InteractionTrackingManager {
|
|
|
133
126
|
element_class: element.className || undefined,
|
|
134
127
|
timestamp: Date.now(),
|
|
135
128
|
});
|
|
136
|
-
this.log('Tracked focus interaction:', interaction.eventName);
|
|
137
129
|
}
|
|
138
130
|
/**
|
|
139
131
|
* Find element by XPath selector
|
|
@@ -233,7 +225,6 @@ class InteractionTrackingManager {
|
|
|
233
225
|
element.removeEventListener(event, handler);
|
|
234
226
|
});
|
|
235
227
|
this.attachedListeners.delete(element);
|
|
236
|
-
this.log('Detached listeners from element');
|
|
237
228
|
}
|
|
238
229
|
/**
|
|
239
230
|
* Log debug messages
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"page-tracking.d.ts","sourceRoot":"","sources":["../src/page-tracking.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/E,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,kBAAkB,IAAI,MAAM,CAAC;IAC7B,qBAAqB,IAAI,MAAM,CAAC;IAChC,YAAY,IAAI,MAAM,CAAC;CACxB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,oBAAoB,CAA4C;IACxE,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAK;gBAEd,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB;IAY5D;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAqB7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAK/B;;OAEG;IACH,OAAO,CAAC,cAAc,CAGpB;IAEF;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAGtB;IAEF;;OAEG;IACH,OAAO,CAAC,gBAAgB;
|
|
1
|
+
{"version":3,"file":"page-tracking.d.ts","sourceRoot":"","sources":["../src/page-tracking.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAaH,MAAM,WAAW,kBAAkB;IACjC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/E,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC;IACvC,kBAAkB,IAAI,MAAM,CAAC;IAC7B,qBAAqB,IAAI,MAAM,CAAC;IAChC,YAAY,IAAI,MAAM,CAAC;CACxB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,OAAO,CAAc;IAC7B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,oBAAoB,CAA4C;IACxE,OAAO,CAAC,YAAY,CAAuB;IAC3C,OAAO,CAAC,WAAW,CAAuB;IAC1C,OAAO,CAAC,aAAa,CAAK;gBAEd,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,kBAAkB;IAY5D;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAqB7B;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAK/B;;OAEG;IACH,OAAO,CAAC,cAAc,CAGpB;IAEF;;OAEG;IACH,OAAO,CAAC,gBAAgB,CAGtB;IAEF;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA4GxB;;OAEG;IACH,OAAO,CAAC,aAAa;IASrB;;OAEG;IACH,OAAO,CAAC,UAAU;IAUlB;;OAEG;IACH,OAAO,CAAC,KAAK;IAUb;;OAEG;IACH,OAAO,CAAC,aAAa;IAwBrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAmBnB;;OAEG;IACH,cAAc,IAAI,MAAM,GAAG,IAAI;IAI/B;;OAEG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAqCnE;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAI1B;;OAEG;IACH,OAAO,IAAI,IAAI;CAqBhB"}
|
package/dist/page-tracking.js
CHANGED
|
@@ -159,9 +159,6 @@ class PageTrackingManager {
|
|
|
159
159
|
}
|
|
160
160
|
// Track the page view event
|
|
161
161
|
this.tracker.trackSystemEvent('page_view', properties);
|
|
162
|
-
if (this.config.debug) {
|
|
163
|
-
console.log('[Page Tracking] Tracked page view:', properties);
|
|
164
|
-
}
|
|
165
162
|
}
|
|
166
163
|
/**
|
|
167
164
|
* Extract domain from URL
|
|
@@ -293,9 +290,6 @@ class PageTrackingManager {
|
|
|
293
290
|
}
|
|
294
291
|
}
|
|
295
292
|
this.tracker.trackSystemEvent('page_view', baseProperties);
|
|
296
|
-
if (this.config.debug) {
|
|
297
|
-
console.log('[Page Tracking] Manually tracked page:', baseProperties);
|
|
298
|
-
}
|
|
299
293
|
}
|
|
300
294
|
/**
|
|
301
295
|
* Get page view count for current session
|
|
@@ -324,9 +318,6 @@ class PageTrackingManager {
|
|
|
324
318
|
window.removeEventListener('hashchange', this.handleHashChange);
|
|
325
319
|
}
|
|
326
320
|
this.isDestroyed = true;
|
|
327
|
-
if (this.config.debug) {
|
|
328
|
-
console.log('[Page Tracking] Destroyed');
|
|
329
|
-
}
|
|
330
321
|
}
|
|
331
322
|
}
|
|
332
323
|
exports.PageTrackingManager = PageTrackingManager;
|