@grainql/analytics-web 2.2.0 → 2.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attribution.d.ts +47 -0
- package/dist/attribution.d.ts.map +1 -0
- package/dist/attribution.js +228 -0
- package/dist/cjs/attribution.d.ts +47 -0
- package/dist/cjs/attribution.d.ts.map +1 -0
- package/dist/cjs/attribution.js +228 -0
- package/dist/cjs/attribution.js.map +1 -0
- package/dist/cjs/heartbeat.d.ts +1 -0
- package/dist/cjs/heartbeat.d.ts.map +1 -1
- package/dist/cjs/heartbeat.js +1 -1
- package/dist/cjs/heartbeat.js.map +1 -1
- package/dist/cjs/index.d.ts +25 -0
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/page-tracking.d.ts +25 -0
- package/dist/cjs/page-tracking.d.ts.map +1 -1
- package/dist/cjs/page-tracking.js +158 -9
- package/dist/cjs/page-tracking.js.map +1 -1
- package/dist/esm/attribution.d.ts +47 -0
- package/dist/esm/attribution.d.ts.map +1 -0
- package/dist/esm/attribution.js +218 -0
- package/dist/esm/attribution.js.map +1 -0
- package/dist/esm/heartbeat.d.ts +1 -0
- package/dist/esm/heartbeat.d.ts.map +1 -1
- package/dist/esm/heartbeat.js +1 -1
- package/dist/esm/heartbeat.js.map +1 -1
- package/dist/esm/index.d.ts +25 -0
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/page-tracking.d.ts +25 -0
- package/dist/esm/page-tracking.d.ts.map +1 -1
- package/dist/esm/page-tracking.js +158 -9
- package/dist/esm/page-tracking.js.map +1 -1
- package/dist/heartbeat.d.ts +1 -0
- package/dist/heartbeat.d.ts.map +1 -1
- package/dist/heartbeat.js +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +464 -11
- package/dist/index.global.dev.js.map +3 -3
- package/dist/index.global.js +2 -2
- package/dist/index.global.js.map +4 -4
- package/dist/index.js +157 -1
- package/dist/index.mjs +155 -0
- package/dist/page-tracking.d.ts +25 -0
- package/dist/page-tracking.d.ts.map +1 -1
- package/dist/page-tracking.js +158 -9
- package/dist/react/index.d.ts +44 -519
- package/dist/react/index.d.ts.map +1 -1
- package/dist/react/index.js +54 -1517
- package/dist/react/index.mjs +42 -1514
- package/package.json +1 -1
- package/dist/react/activity.d.ts +0 -59
- package/dist/react/activity.d.ts.map +0 -1
- package/dist/react/activity.js +0 -130
- package/dist/react/activity.mjs +0 -126
- package/dist/react/consent.d.ts +0 -72
- package/dist/react/consent.d.ts.map +0 -1
- package/dist/react/consent.js +0 -195
- package/dist/react/consent.mjs +0 -191
- package/dist/react/cookies.d.ts +0 -28
- package/dist/react/cookies.d.ts.map +0 -1
- package/dist/react/cookies.js +0 -94
- package/dist/react/cookies.mjs +0 -88
- package/dist/react/heartbeat.d.ts +0 -47
- package/dist/react/heartbeat.d.ts.map +0 -1
- package/dist/react/heartbeat.js +0 -119
- package/dist/react/heartbeat.mjs +0 -115
- package/dist/react/page-tracking.d.ts +0 -60
- package/dist/react/page-tracking.d.ts.map +0 -1
- package/dist/react/page-tracking.js +0 -179
- package/dist/react/page-tracking.mjs +0 -175
- package/dist/react/react/index.d.ts +0 -47
- package/dist/react/react/index.d.ts.map +0 -1
- package/dist/react/react/index.js +0 -58
- package/dist/react/react/index.mjs +0 -44
- /package/dist/react/{react/GrainProvider.d.ts → GrainProvider.d.ts} +0 -0
- /package/dist/react/{react/GrainProvider.d.ts.map → GrainProvider.d.ts.map} +0 -0
- /package/dist/react/{react/GrainProvider.js → GrainProvider.js} +0 -0
- /package/dist/react/{react/GrainProvider.mjs → GrainProvider.mjs} +0 -0
- /package/dist/react/{react/components → components}/ConsentBanner.d.ts +0 -0
- /package/dist/react/{react/components → components}/ConsentBanner.d.ts.map +0 -0
- /package/dist/react/{react/components → components}/ConsentBanner.js +0 -0
- /package/dist/react/{react/components → components}/ConsentBanner.mjs +0 -0
- /package/dist/react/{react/components → components}/CookieNotice.d.ts +0 -0
- /package/dist/react/{react/components → components}/CookieNotice.d.ts.map +0 -0
- /package/dist/react/{react/components → components}/CookieNotice.js +0 -0
- /package/dist/react/{react/components → components}/CookieNotice.mjs +0 -0
- /package/dist/react/{react/components → components}/PrivacyPreferenceCenter.d.ts +0 -0
- /package/dist/react/{react/components → components}/PrivacyPreferenceCenter.d.ts.map +0 -0
- /package/dist/react/{react/components → components}/PrivacyPreferenceCenter.js +0 -0
- /package/dist/react/{react/components → components}/PrivacyPreferenceCenter.mjs +0 -0
- /package/dist/react/{react/context.d.ts → context.d.ts} +0 -0
- /package/dist/react/{react/context.d.ts.map → context.d.ts.map} +0 -0
- /package/dist/react/{react/context.js → context.js} +0 -0
- /package/dist/react/{react/context.mjs → context.mjs} +0 -0
- /package/dist/react/{react/hooks → hooks}/useAllConfigs.d.ts +0 -0
- /package/dist/react/{react/hooks → hooks}/useAllConfigs.d.ts.map +0 -0
- /package/dist/react/{react/hooks → hooks}/useAllConfigs.js +0 -0
- /package/dist/react/{react/hooks → hooks}/useAllConfigs.mjs +0 -0
- /package/dist/react/{react/hooks → hooks}/useConfig.d.ts +0 -0
- /package/dist/react/{react/hooks → hooks}/useConfig.d.ts.map +0 -0
- /package/dist/react/{react/hooks → hooks}/useConfig.js +0 -0
- /package/dist/react/{react/hooks → hooks}/useConfig.mjs +0 -0
- /package/dist/react/{react/hooks → hooks}/useConsent.d.ts +0 -0
- /package/dist/react/{react/hooks → hooks}/useConsent.d.ts.map +0 -0
- /package/dist/react/{react/hooks → hooks}/useConsent.js +0 -0
- /package/dist/react/{react/hooks → hooks}/useConsent.mjs +0 -0
- /package/dist/react/{react/hooks → hooks}/useDataDeletion.d.ts +0 -0
- /package/dist/react/{react/hooks → hooks}/useDataDeletion.d.ts.map +0 -0
- /package/dist/react/{react/hooks → hooks}/useDataDeletion.js +0 -0
- /package/dist/react/{react/hooks → hooks}/useDataDeletion.mjs +0 -0
- /package/dist/react/{react/hooks → hooks}/useGrainAnalytics.d.ts +0 -0
- /package/dist/react/{react/hooks → hooks}/useGrainAnalytics.d.ts.map +0 -0
- /package/dist/react/{react/hooks → hooks}/useGrainAnalytics.js +0 -0
- /package/dist/react/{react/hooks → hooks}/useGrainAnalytics.mjs +0 -0
- /package/dist/react/{react/hooks → hooks}/usePrivacyPreferences.d.ts +0 -0
- /package/dist/react/{react/hooks → hooks}/usePrivacyPreferences.d.ts.map +0 -0
- /package/dist/react/{react/hooks → hooks}/usePrivacyPreferences.js +0 -0
- /package/dist/react/{react/hooks → hooks}/usePrivacyPreferences.mjs +0 -0
- /package/dist/react/{react/hooks → hooks}/useTrack.d.ts +0 -0
- /package/dist/react/{react/hooks → hooks}/useTrack.d.ts.map +0 -0
- /package/dist/react/{react/hooks → hooks}/useTrack.js +0 -0
- /package/dist/react/{react/hooks → hooks}/useTrack.mjs +0 -0
- /package/dist/react/{react/types.d.ts → types.d.ts} +0 -0
- /package/dist/react/{react/types.d.ts.map → types.d.ts.map} +0 -0
- /package/dist/react/{react/types.js → types.js} +0 -0
- /package/dist/react/{react/types.mjs → types.mjs} +0 -0
package/dist/page-tracking.js
CHANGED
|
@@ -5,12 +5,16 @@
|
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.PageTrackingManager = void 0;
|
|
8
|
+
const attribution_1 = require("./attribution");
|
|
8
9
|
class PageTrackingManager {
|
|
9
10
|
constructor(tracker, config) {
|
|
10
11
|
this.isDestroyed = false;
|
|
11
12
|
this.currentPath = null;
|
|
12
13
|
this.originalPushState = null;
|
|
13
14
|
this.originalReplaceState = null;
|
|
15
|
+
this.previousPage = null;
|
|
16
|
+
this.landingPage = null;
|
|
17
|
+
this.pageViewCount = 0;
|
|
14
18
|
/**
|
|
15
19
|
* Handle popstate event (back/forward navigation)
|
|
16
20
|
*/
|
|
@@ -29,8 +33,8 @@ class PageTrackingManager {
|
|
|
29
33
|
};
|
|
30
34
|
this.tracker = tracker;
|
|
31
35
|
this.config = config;
|
|
32
|
-
// Track initial page load
|
|
33
|
-
this.trackCurrentPage();
|
|
36
|
+
// Track initial page load (this is the landing page)
|
|
37
|
+
this.trackCurrentPage(true);
|
|
34
38
|
// Setup listeners
|
|
35
39
|
this.setupHistoryListeners();
|
|
36
40
|
this.setupHashChangeListener();
|
|
@@ -67,16 +71,39 @@ class PageTrackingManager {
|
|
|
67
71
|
/**
|
|
68
72
|
* Track the current page
|
|
69
73
|
*/
|
|
70
|
-
trackCurrentPage() {
|
|
74
|
+
trackCurrentPage(isLanding = false) {
|
|
71
75
|
if (this.isDestroyed || typeof window === 'undefined')
|
|
72
76
|
return;
|
|
73
77
|
const page = this.extractPath(window.location.href);
|
|
74
|
-
// Don't track if it's the same page
|
|
75
|
-
if (page === this.currentPath) {
|
|
78
|
+
// Don't track if it's the same page (unless it's the landing page)
|
|
79
|
+
if (!isLanding && page === this.currentPath) {
|
|
76
80
|
return;
|
|
77
81
|
}
|
|
82
|
+
// Store previous page before updating
|
|
83
|
+
if (this.currentPath) {
|
|
84
|
+
this.previousPage = this.currentPath;
|
|
85
|
+
}
|
|
78
86
|
this.currentPath = page;
|
|
87
|
+
this.pageViewCount++;
|
|
88
|
+
// Set landing page on first view
|
|
89
|
+
if (isLanding) {
|
|
90
|
+
this.landingPage = page;
|
|
91
|
+
}
|
|
79
92
|
const hasConsent = this.tracker.hasConsent('analytics');
|
|
93
|
+
const currentUrl = window.location.href;
|
|
94
|
+
const referrer = document.referrer || '';
|
|
95
|
+
// Parse UTM parameters from current URL
|
|
96
|
+
const utmParams = (0, attribution_1.parseUTMParameters)(currentUrl);
|
|
97
|
+
// Store session UTM if they exist (first time only or if new UTMs appear)
|
|
98
|
+
if (Object.keys(utmParams).length > 0) {
|
|
99
|
+
const existing = (0, attribution_1.getSessionUTMParameters)();
|
|
100
|
+
if (!existing || isLanding) {
|
|
101
|
+
(0, attribution_1.setSessionUTMParameters)(utmParams);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
// Get or create first-touch attribution
|
|
105
|
+
const sessionUTMs = (0, attribution_1.getSessionUTMParameters)() || {};
|
|
106
|
+
const firstTouch = (0, attribution_1.getOrCreateFirstTouchAttribution)(this.config.tenantId, referrer, currentUrl, sessionUTMs);
|
|
80
107
|
// Base properties (always included)
|
|
81
108
|
const properties = {
|
|
82
109
|
page,
|
|
@@ -84,9 +111,47 @@ class PageTrackingManager {
|
|
|
84
111
|
};
|
|
85
112
|
// Enhanced properties when consent is granted
|
|
86
113
|
if (hasConsent) {
|
|
87
|
-
properties.referrer = document.referrer || '';
|
|
88
114
|
properties.title = document.title || '';
|
|
89
|
-
properties.full_url =
|
|
115
|
+
properties.full_url = currentUrl;
|
|
116
|
+
properties.session_id = this.tracker.getSessionId();
|
|
117
|
+
// Add referrer info
|
|
118
|
+
if (referrer) {
|
|
119
|
+
properties.referrer = referrer;
|
|
120
|
+
properties.referrer_domain = this.extractDomain(referrer);
|
|
121
|
+
properties.referrer_category = (0, attribution_1.categorizeReferrer)(referrer, currentUrl);
|
|
122
|
+
}
|
|
123
|
+
// Add landing page if this is not the first view
|
|
124
|
+
if (this.landingPage && !isLanding) {
|
|
125
|
+
properties.landing_page = this.landingPage;
|
|
126
|
+
}
|
|
127
|
+
// Add previous page if available
|
|
128
|
+
if (this.previousPage) {
|
|
129
|
+
properties.previous_page = this.previousPage;
|
|
130
|
+
}
|
|
131
|
+
// Add UTM parameters if present (from session)
|
|
132
|
+
if (sessionUTMs.utm_source)
|
|
133
|
+
properties.utm_source = sessionUTMs.utm_source;
|
|
134
|
+
if (sessionUTMs.utm_medium)
|
|
135
|
+
properties.utm_medium = sessionUTMs.utm_medium;
|
|
136
|
+
if (sessionUTMs.utm_campaign)
|
|
137
|
+
properties.utm_campaign = sessionUTMs.utm_campaign;
|
|
138
|
+
if (sessionUTMs.utm_term)
|
|
139
|
+
properties.utm_term = sessionUTMs.utm_term;
|
|
140
|
+
if (sessionUTMs.utm_content)
|
|
141
|
+
properties.utm_content = sessionUTMs.utm_content;
|
|
142
|
+
// Add first-touch attribution
|
|
143
|
+
properties.first_touch_source = firstTouch.source;
|
|
144
|
+
properties.first_touch_medium = firstTouch.medium;
|
|
145
|
+
properties.first_touch_campaign = firstTouch.campaign;
|
|
146
|
+
properties.first_touch_referrer_category = firstTouch.referrer_category;
|
|
147
|
+
// Browser and device info
|
|
148
|
+
properties.device = this.getDeviceType();
|
|
149
|
+
properties.browser = this.getBrowser();
|
|
150
|
+
properties.os = this.getOS();
|
|
151
|
+
properties.language = navigator.language || '';
|
|
152
|
+
properties.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
153
|
+
properties.screen_resolution = `${screen.width}x${screen.height}`;
|
|
154
|
+
properties.viewport = `${window.innerWidth}x${window.innerHeight}`;
|
|
90
155
|
}
|
|
91
156
|
// Track the page view event
|
|
92
157
|
this.tracker.trackSystemEvent('page_view', properties);
|
|
@@ -94,6 +159,75 @@ class PageTrackingManager {
|
|
|
94
159
|
console.log('[Page Tracking] Tracked page view:', properties);
|
|
95
160
|
}
|
|
96
161
|
}
|
|
162
|
+
/**
|
|
163
|
+
* Extract domain from URL
|
|
164
|
+
*/
|
|
165
|
+
extractDomain(url) {
|
|
166
|
+
try {
|
|
167
|
+
const urlObj = new URL(url);
|
|
168
|
+
return urlObj.hostname;
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
return '';
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Detect browser name
|
|
176
|
+
*/
|
|
177
|
+
getBrowser() {
|
|
178
|
+
const ua = navigator.userAgent;
|
|
179
|
+
if (ua.includes('Firefox/'))
|
|
180
|
+
return 'Firefox';
|
|
181
|
+
if (ua.includes('Edg/'))
|
|
182
|
+
return 'Edge';
|
|
183
|
+
if (ua.includes('Chrome/'))
|
|
184
|
+
return 'Chrome';
|
|
185
|
+
if (ua.includes('Safari/') && !ua.includes('Chrome/'))
|
|
186
|
+
return 'Safari';
|
|
187
|
+
if (ua.includes('Opera/') || ua.includes('OPR/'))
|
|
188
|
+
return 'Opera';
|
|
189
|
+
return 'Unknown';
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Detect operating system
|
|
193
|
+
*/
|
|
194
|
+
getOS() {
|
|
195
|
+
const ua = navigator.userAgent;
|
|
196
|
+
if (ua.includes('Win'))
|
|
197
|
+
return 'Windows';
|
|
198
|
+
if (ua.includes('Mac'))
|
|
199
|
+
return 'macOS';
|
|
200
|
+
if (ua.includes('Linux'))
|
|
201
|
+
return 'Linux';
|
|
202
|
+
if (ua.includes('Android'))
|
|
203
|
+
return 'Android';
|
|
204
|
+
if (ua.includes('iOS') || ua.includes('iPhone') || ua.includes('iPad'))
|
|
205
|
+
return 'iOS';
|
|
206
|
+
return 'Unknown';
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Detect device type (Mobile, Tablet, Desktop)
|
|
210
|
+
*/
|
|
211
|
+
getDeviceType() {
|
|
212
|
+
const ua = navigator.userAgent;
|
|
213
|
+
const width = window.innerWidth;
|
|
214
|
+
// Check for tablet-specific indicators
|
|
215
|
+
if (ua.includes('iPad') || (ua.includes('Android') && !ua.includes('Mobile'))) {
|
|
216
|
+
return 'Tablet';
|
|
217
|
+
}
|
|
218
|
+
// Check for mobile indicators
|
|
219
|
+
if (ua.includes('Mobile') || ua.includes('iPhone') || ua.includes('Android')) {
|
|
220
|
+
return 'Mobile';
|
|
221
|
+
}
|
|
222
|
+
// Fallback to screen width detection
|
|
223
|
+
if (width < 768) {
|
|
224
|
+
return 'Mobile';
|
|
225
|
+
}
|
|
226
|
+
else if (width >= 768 && width < 1024) {
|
|
227
|
+
return 'Tablet';
|
|
228
|
+
}
|
|
229
|
+
return 'Desktop';
|
|
230
|
+
}
|
|
97
231
|
/**
|
|
98
232
|
* Extract path from URL, optionally stripping query parameters
|
|
99
233
|
*/
|
|
@@ -134,22 +268,37 @@ class PageTrackingManager {
|
|
|
134
268
|
...properties,
|
|
135
269
|
};
|
|
136
270
|
// Enhanced properties when consent is granted
|
|
137
|
-
if (hasConsent && typeof document !== 'undefined') {
|
|
271
|
+
if (hasConsent && typeof document !== 'undefined' && typeof window !== 'undefined') {
|
|
138
272
|
if (!baseProperties.referrer) {
|
|
139
273
|
baseProperties.referrer = document.referrer || '';
|
|
140
274
|
}
|
|
141
275
|
if (!baseProperties.title) {
|
|
142
276
|
baseProperties.title = document.title || '';
|
|
143
277
|
}
|
|
144
|
-
if (!baseProperties.full_url
|
|
278
|
+
if (!baseProperties.full_url) {
|
|
145
279
|
baseProperties.full_url = window.location.href;
|
|
146
280
|
}
|
|
281
|
+
if (!baseProperties.session_id) {
|
|
282
|
+
baseProperties.session_id = this.tracker.getSessionId();
|
|
283
|
+
}
|
|
284
|
+
if (!baseProperties.browser) {
|
|
285
|
+
baseProperties.browser = this.getBrowser();
|
|
286
|
+
}
|
|
287
|
+
if (!baseProperties.os) {
|
|
288
|
+
baseProperties.os = this.getOS();
|
|
289
|
+
}
|
|
147
290
|
}
|
|
148
291
|
this.tracker.trackSystemEvent('page_view', baseProperties);
|
|
149
292
|
if (this.config.debug) {
|
|
150
293
|
console.log('[Page Tracking] Manually tracked page:', baseProperties);
|
|
151
294
|
}
|
|
152
295
|
}
|
|
296
|
+
/**
|
|
297
|
+
* Get page view count for current session
|
|
298
|
+
*/
|
|
299
|
+
getPageViewCount() {
|
|
300
|
+
return this.pageViewCount;
|
|
301
|
+
}
|
|
153
302
|
/**
|
|
154
303
|
* Destroy the page tracker
|
|
155
304
|
*/
|