@grainql/analytics-web 2.4.0 → 2.5.3
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/cjs/index.d.ts +29 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/interaction-tracking.d.ts +74 -0
- package/dist/cjs/interaction-tracking.d.ts.map +1 -0
- package/dist/cjs/interaction-tracking.js +292 -0
- package/dist/cjs/interaction-tracking.js.map +1 -0
- package/dist/cjs/section-tracking.d.ts +101 -0
- package/dist/cjs/section-tracking.d.ts.map +1 -0
- package/dist/cjs/section-tracking.js +455 -0
- package/dist/cjs/section-tracking.js.map +1 -0
- package/dist/cjs/types/auto-tracking.d.ts +55 -0
- package/dist/cjs/types/auto-tracking.d.ts.map +1 -0
- package/dist/cjs/types/auto-tracking.js +6 -0
- package/dist/cjs/types/auto-tracking.js.map +1 -0
- package/dist/esm/index.d.ts +29 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/interaction-tracking.d.ts +74 -0
- package/dist/esm/interaction-tracking.d.ts.map +1 -0
- package/dist/esm/interaction-tracking.js +288 -0
- package/dist/esm/interaction-tracking.js.map +1 -0
- package/dist/esm/section-tracking.d.ts +101 -0
- package/dist/esm/section-tracking.d.ts.map +1 -0
- package/dist/esm/section-tracking.js +451 -0
- package/dist/esm/section-tracking.js.map +1 -0
- package/dist/esm/types/auto-tracking.d.ts +55 -0
- package/dist/esm/types/auto-tracking.d.ts.map +1 -0
- package/dist/esm/types/auto-tracking.js +5 -0
- package/dist/esm/types/auto-tracking.js.map +1 -0
- package/dist/index.d.ts +29 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +821 -3
- 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 +149 -4
- package/dist/index.mjs +116 -4
- package/dist/interaction-tracking.d.ts +74 -0
- package/dist/interaction-tracking.d.ts.map +1 -0
- package/dist/interaction-tracking.js +292 -0
- package/dist/section-tracking.d.ts +101 -0
- package/dist/section-tracking.d.ts.map +1 -0
- package/dist/section-tracking.js +455 -0
- package/dist/types/auto-tracking.d.ts +55 -0
- package/dist/types/auto-tracking.d.ts.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,455 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Section Tracking Manager for Grain Analytics
|
|
4
|
+
* Intelligent scroll tracking with viewport metrics, visible sections, and engagement analysis
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.SectionTrackingManager = void 0;
|
|
8
|
+
const DEFAULT_OPTIONS = {
|
|
9
|
+
minDwellTime: 1000, // 1 second minimum
|
|
10
|
+
scrollVelocityThreshold: 500, // 500px/s
|
|
11
|
+
intersectionThreshold: 0.1, // 10% visible
|
|
12
|
+
debounceDelay: 100,
|
|
13
|
+
batchDelay: 2000, // 2 seconds
|
|
14
|
+
debug: false,
|
|
15
|
+
};
|
|
16
|
+
class SectionTrackingManager {
|
|
17
|
+
constructor(tracker, sections, options = {}) {
|
|
18
|
+
this.isDestroyed = false;
|
|
19
|
+
// Tracking state
|
|
20
|
+
this.sectionStates = new Map();
|
|
21
|
+
this.intersectionObserver = null;
|
|
22
|
+
this.xpathCache = new Map();
|
|
23
|
+
// Scroll tracking
|
|
24
|
+
this.lastScrollPosition = 0;
|
|
25
|
+
this.lastScrollTime = Date.now();
|
|
26
|
+
this.scrollVelocity = 0;
|
|
27
|
+
this.scrollDebounceTimer = null;
|
|
28
|
+
// Event batching
|
|
29
|
+
this.pendingEvents = [];
|
|
30
|
+
this.batchTimer = null;
|
|
31
|
+
// Periodic tracking for long-duration views
|
|
32
|
+
this.sectionTimers = new Map(); // sectionName -> timer ID
|
|
33
|
+
this.SPLIT_DURATION = 3000; // 3 seconds
|
|
34
|
+
this.tracker = tracker;
|
|
35
|
+
this.sections = sections;
|
|
36
|
+
this.options = { ...DEFAULT_OPTIONS, ...options };
|
|
37
|
+
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
38
|
+
// Initialize after DOM is ready
|
|
39
|
+
if (document.readyState === 'loading') {
|
|
40
|
+
document.addEventListener('DOMContentLoaded', () => this.initialize());
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
setTimeout(() => this.initialize(), 0);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Initialize section tracking
|
|
49
|
+
*/
|
|
50
|
+
initialize() {
|
|
51
|
+
if (this.isDestroyed)
|
|
52
|
+
return;
|
|
53
|
+
this.log('Initializing section tracking for', this.sections.length, 'sections');
|
|
54
|
+
// Setup intersection observer
|
|
55
|
+
this.setupIntersectionObserver();
|
|
56
|
+
// Setup scroll listener for velocity tracking
|
|
57
|
+
this.setupScrollListener();
|
|
58
|
+
// Initialize sections
|
|
59
|
+
this.initializeSections();
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Setup IntersectionObserver for section visibility
|
|
63
|
+
*/
|
|
64
|
+
setupIntersectionObserver() {
|
|
65
|
+
if (typeof IntersectionObserver === 'undefined') {
|
|
66
|
+
this.log('IntersectionObserver not supported');
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
this.intersectionObserver = new IntersectionObserver((entries) => {
|
|
70
|
+
entries.forEach((entry) => {
|
|
71
|
+
this.handleIntersection(entry);
|
|
72
|
+
});
|
|
73
|
+
}, {
|
|
74
|
+
threshold: [0, 0.1, 0.25, 0.5, 0.75, 1.0],
|
|
75
|
+
rootMargin: '0px',
|
|
76
|
+
});
|
|
77
|
+
this.log('IntersectionObserver created');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Setup scroll listener for velocity calculation
|
|
81
|
+
*/
|
|
82
|
+
setupScrollListener() {
|
|
83
|
+
if (typeof window === 'undefined')
|
|
84
|
+
return;
|
|
85
|
+
const scrollHandler = () => {
|
|
86
|
+
if (this.scrollDebounceTimer !== null) {
|
|
87
|
+
clearTimeout(this.scrollDebounceTimer);
|
|
88
|
+
}
|
|
89
|
+
this.scrollDebounceTimer = window.setTimeout(() => {
|
|
90
|
+
this.updateScrollVelocity();
|
|
91
|
+
this.scrollDebounceTimer = null;
|
|
92
|
+
}, this.options.debounceDelay);
|
|
93
|
+
};
|
|
94
|
+
window.addEventListener('scroll', scrollHandler, { passive: true });
|
|
95
|
+
this.log('Scroll listener attached');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Initialize sections and start observing
|
|
99
|
+
*/
|
|
100
|
+
initializeSections() {
|
|
101
|
+
for (const section of this.sections) {
|
|
102
|
+
const element = this.findElementByXPath(section.selector);
|
|
103
|
+
if (!element) {
|
|
104
|
+
this.log('Section element not found:', section.sectionName, 'selector:', section.selector);
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
// Initialize state
|
|
108
|
+
const state = {
|
|
109
|
+
element,
|
|
110
|
+
config: section,
|
|
111
|
+
entryTime: null,
|
|
112
|
+
exitTime: null,
|
|
113
|
+
isVisible: false,
|
|
114
|
+
lastScrollPosition: window.scrollY,
|
|
115
|
+
lastScrollTime: Date.now(),
|
|
116
|
+
entryScrollSpeed: 0,
|
|
117
|
+
exitScrollSpeed: 0,
|
|
118
|
+
maxVisibleArea: 0,
|
|
119
|
+
};
|
|
120
|
+
this.sectionStates.set(section.sectionName, state);
|
|
121
|
+
// Start observing
|
|
122
|
+
if (this.intersectionObserver) {
|
|
123
|
+
this.intersectionObserver.observe(element);
|
|
124
|
+
}
|
|
125
|
+
this.log('Section initialized and observed:', section.sectionName);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Handle intersection observer entry
|
|
130
|
+
*/
|
|
131
|
+
handleIntersection(entry) {
|
|
132
|
+
if (this.isDestroyed)
|
|
133
|
+
return;
|
|
134
|
+
// Find which section this element belongs to
|
|
135
|
+
const state = Array.from(this.sectionStates.values()).find((s) => s.element === entry.target);
|
|
136
|
+
if (!state)
|
|
137
|
+
return;
|
|
138
|
+
const isVisible = entry.isIntersecting && entry.intersectionRatio >= this.options.intersectionThreshold;
|
|
139
|
+
const visibleArea = entry.intersectionRatio;
|
|
140
|
+
// Update max visible area
|
|
141
|
+
if (visibleArea > state.maxVisibleArea) {
|
|
142
|
+
state.maxVisibleArea = visibleArea;
|
|
143
|
+
}
|
|
144
|
+
// Handle visibility change
|
|
145
|
+
if (isVisible && !state.isVisible) {
|
|
146
|
+
// Section became visible
|
|
147
|
+
this.handleSectionEntry(state);
|
|
148
|
+
}
|
|
149
|
+
else if (!isVisible && state.isVisible) {
|
|
150
|
+
// Section became invisible
|
|
151
|
+
this.handleSectionExit(state);
|
|
152
|
+
}
|
|
153
|
+
state.isVisible = isVisible;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Handle section entry (became visible)
|
|
157
|
+
*/
|
|
158
|
+
handleSectionEntry(state) {
|
|
159
|
+
this.log('Section entered view:', state.config.sectionName);
|
|
160
|
+
state.entryTime = Date.now();
|
|
161
|
+
state.entryScrollSpeed = this.scrollVelocity;
|
|
162
|
+
state.lastScrollPosition = window.scrollY;
|
|
163
|
+
state.lastScrollTime = Date.now();
|
|
164
|
+
state.maxVisibleArea = 0;
|
|
165
|
+
// Start periodic tracking timer (3 second intervals)
|
|
166
|
+
this.startPeriodicTracking(state);
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Start periodic tracking for a section (sends events every 3 seconds)
|
|
170
|
+
*/
|
|
171
|
+
startPeriodicTracking(state) {
|
|
172
|
+
// Clear any existing timer for this section
|
|
173
|
+
this.stopPeriodicTracking(state.config.sectionName);
|
|
174
|
+
const timerId = window.setInterval(() => {
|
|
175
|
+
if (this.isDestroyed || !state.isVisible || state.entryTime === null) {
|
|
176
|
+
this.stopPeriodicTracking(state.config.sectionName);
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const now = Date.now();
|
|
180
|
+
const duration = now - state.entryTime;
|
|
181
|
+
// Only track if minimum dwell time has passed
|
|
182
|
+
if (duration >= this.options.minDwellTime) {
|
|
183
|
+
// Create partial section view data
|
|
184
|
+
const viewData = {
|
|
185
|
+
sectionName: state.config.sectionName,
|
|
186
|
+
sectionType: state.config.sectionType,
|
|
187
|
+
entryTime: state.entryTime,
|
|
188
|
+
exitTime: now, // Current time as "exit" for this split
|
|
189
|
+
duration,
|
|
190
|
+
viewportWidth: window.innerWidth,
|
|
191
|
+
viewportHeight: window.innerHeight,
|
|
192
|
+
scrollDepth: this.calculateScrollDepth(),
|
|
193
|
+
visibleAreaPercentage: Math.round(state.maxVisibleArea * 100),
|
|
194
|
+
scrollSpeedAtEntry: state.entryScrollSpeed,
|
|
195
|
+
scrollSpeedAtExit: this.scrollVelocity,
|
|
196
|
+
};
|
|
197
|
+
// Track this split immediately (don't queue for batching)
|
|
198
|
+
if (this.shouldTrackSection(viewData)) {
|
|
199
|
+
this.tracker.trackSystemEvent('_grain_section_view', {
|
|
200
|
+
section_name: viewData.sectionName,
|
|
201
|
+
section_type: viewData.sectionType,
|
|
202
|
+
duration_ms: viewData.duration,
|
|
203
|
+
viewport_width: viewData.viewportWidth,
|
|
204
|
+
viewport_height: viewData.viewportHeight,
|
|
205
|
+
scroll_depth_percent: viewData.scrollDepth,
|
|
206
|
+
visible_area_percent: viewData.visibleAreaPercentage,
|
|
207
|
+
scroll_speed_entry: Math.round(viewData.scrollSpeedAtEntry || 0),
|
|
208
|
+
scroll_speed_exit: Math.round(viewData.scrollSpeedAtExit || 0),
|
|
209
|
+
entry_timestamp: viewData.entryTime,
|
|
210
|
+
exit_timestamp: viewData.exitTime,
|
|
211
|
+
is_split: true, // Flag to indicate this is a periodic split, not final exit
|
|
212
|
+
});
|
|
213
|
+
this.log('Tracked periodic section view split:', state.config.sectionName, 'duration:', duration);
|
|
214
|
+
// Reset entry time for next split (but keep tracking)
|
|
215
|
+
state.entryTime = now;
|
|
216
|
+
state.entryScrollSpeed = this.scrollVelocity;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}, this.SPLIT_DURATION);
|
|
220
|
+
this.sectionTimers.set(state.config.sectionName, timerId);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Stop periodic tracking for a section
|
|
224
|
+
*/
|
|
225
|
+
stopPeriodicTracking(sectionName) {
|
|
226
|
+
const timerId = this.sectionTimers.get(sectionName);
|
|
227
|
+
if (timerId !== undefined) {
|
|
228
|
+
clearInterval(timerId);
|
|
229
|
+
this.sectionTimers.delete(sectionName);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Handle section exit (became invisible)
|
|
234
|
+
*/
|
|
235
|
+
handleSectionExit(state) {
|
|
236
|
+
this.log('Section exited view:', state.config.sectionName);
|
|
237
|
+
// Stop periodic tracking
|
|
238
|
+
this.stopPeriodicTracking(state.config.sectionName);
|
|
239
|
+
if (state.entryTime === null)
|
|
240
|
+
return;
|
|
241
|
+
state.exitTime = Date.now();
|
|
242
|
+
state.exitScrollSpeed = this.scrollVelocity;
|
|
243
|
+
const duration = state.exitTime - state.entryTime;
|
|
244
|
+
// Create section view data
|
|
245
|
+
const viewData = {
|
|
246
|
+
sectionName: state.config.sectionName,
|
|
247
|
+
sectionType: state.config.sectionType,
|
|
248
|
+
entryTime: state.entryTime,
|
|
249
|
+
exitTime: state.exitTime,
|
|
250
|
+
duration,
|
|
251
|
+
viewportWidth: window.innerWidth,
|
|
252
|
+
viewportHeight: window.innerHeight,
|
|
253
|
+
scrollDepth: this.calculateScrollDepth(),
|
|
254
|
+
visibleAreaPercentage: Math.round(state.maxVisibleArea * 100),
|
|
255
|
+
scrollSpeedAtEntry: state.entryScrollSpeed,
|
|
256
|
+
scrollSpeedAtExit: state.exitScrollSpeed,
|
|
257
|
+
};
|
|
258
|
+
// Apply sanitization and track if valid
|
|
259
|
+
if (this.shouldTrackSection(viewData)) {
|
|
260
|
+
this.queueSectionView(viewData);
|
|
261
|
+
}
|
|
262
|
+
else {
|
|
263
|
+
this.log('Section view filtered out:', state.config.sectionName, 'duration:', duration);
|
|
264
|
+
}
|
|
265
|
+
// Reset entry time
|
|
266
|
+
state.entryTime = null;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Update scroll velocity
|
|
270
|
+
*/
|
|
271
|
+
updateScrollVelocity() {
|
|
272
|
+
const now = Date.now();
|
|
273
|
+
const currentPosition = window.scrollY;
|
|
274
|
+
const timeDelta = now - this.lastScrollTime;
|
|
275
|
+
const positionDelta = Math.abs(currentPosition - this.lastScrollPosition);
|
|
276
|
+
if (timeDelta > 0) {
|
|
277
|
+
this.scrollVelocity = (positionDelta / timeDelta) * 1000; // pixels per second
|
|
278
|
+
}
|
|
279
|
+
this.lastScrollPosition = currentPosition;
|
|
280
|
+
this.lastScrollTime = now;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Calculate current scroll depth as percentage
|
|
284
|
+
*/
|
|
285
|
+
calculateScrollDepth() {
|
|
286
|
+
if (typeof window === 'undefined' || typeof document === 'undefined')
|
|
287
|
+
return 0;
|
|
288
|
+
const windowHeight = window.innerHeight;
|
|
289
|
+
const documentHeight = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.clientHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
|
|
290
|
+
const scrollTop = window.scrollY;
|
|
291
|
+
const scrollableHeight = documentHeight - windowHeight;
|
|
292
|
+
if (scrollableHeight <= 0)
|
|
293
|
+
return 100;
|
|
294
|
+
return Math.round((scrollTop / scrollableHeight) * 100);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Determine if section view should be tracked (sanitization)
|
|
298
|
+
*/
|
|
299
|
+
shouldTrackSection(viewData) {
|
|
300
|
+
// Minimum dwell time check
|
|
301
|
+
if (viewData.duration < this.options.minDwellTime) {
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
// Check if user was rapidly scrolling through
|
|
305
|
+
const avgScrollSpeed = (viewData.scrollSpeedAtEntry + viewData.scrollSpeedAtExit) / 2;
|
|
306
|
+
if (avgScrollSpeed > this.options.scrollVelocityThreshold * 2) {
|
|
307
|
+
// Very fast scroll - likely not engaged
|
|
308
|
+
return false;
|
|
309
|
+
}
|
|
310
|
+
// Must have had some meaningful visible area
|
|
311
|
+
if (viewData.visibleAreaPercentage < 10) {
|
|
312
|
+
return false;
|
|
313
|
+
}
|
|
314
|
+
return true;
|
|
315
|
+
}
|
|
316
|
+
/**
|
|
317
|
+
* Queue section view for batching
|
|
318
|
+
*/
|
|
319
|
+
queueSectionView(viewData) {
|
|
320
|
+
this.pendingEvents.push(viewData);
|
|
321
|
+
this.log('Queued section view:', viewData.sectionName, 'duration:', viewData.duration);
|
|
322
|
+
// Setup batch timer if not already set
|
|
323
|
+
if (this.batchTimer === null) {
|
|
324
|
+
this.batchTimer = window.setTimeout(() => {
|
|
325
|
+
this.flushPendingEvents();
|
|
326
|
+
}, this.options.batchDelay);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* Flush pending section view events
|
|
331
|
+
*/
|
|
332
|
+
flushPendingEvents() {
|
|
333
|
+
if (this.isDestroyed || this.pendingEvents.length === 0)
|
|
334
|
+
return;
|
|
335
|
+
if (!this.tracker.hasConsent('analytics')) {
|
|
336
|
+
this.pendingEvents = [];
|
|
337
|
+
return;
|
|
338
|
+
}
|
|
339
|
+
this.log('Flushing', this.pendingEvents.length, 'section view events');
|
|
340
|
+
// Track each section view
|
|
341
|
+
for (const viewData of this.pendingEvents) {
|
|
342
|
+
this.tracker.trackSystemEvent('_grain_section_view', {
|
|
343
|
+
section_name: viewData.sectionName,
|
|
344
|
+
section_type: viewData.sectionType,
|
|
345
|
+
duration_ms: viewData.duration,
|
|
346
|
+
viewport_width: viewData.viewportWidth,
|
|
347
|
+
viewport_height: viewData.viewportHeight,
|
|
348
|
+
scroll_depth_percent: viewData.scrollDepth,
|
|
349
|
+
visible_area_percent: viewData.visibleAreaPercentage,
|
|
350
|
+
scroll_speed_entry: Math.round(viewData.scrollSpeedAtEntry || 0),
|
|
351
|
+
scroll_speed_exit: Math.round(viewData.scrollSpeedAtExit || 0),
|
|
352
|
+
entry_timestamp: viewData.entryTime,
|
|
353
|
+
exit_timestamp: viewData.exitTime,
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
// Clear pending events
|
|
357
|
+
this.pendingEvents = [];
|
|
358
|
+
this.batchTimer = null;
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Find element by XPath selector
|
|
362
|
+
*/
|
|
363
|
+
findElementByXPath(xpath) {
|
|
364
|
+
// Check cache first
|
|
365
|
+
if (this.xpathCache.has(xpath)) {
|
|
366
|
+
const cached = this.xpathCache.get(xpath);
|
|
367
|
+
if (cached && document.contains(cached)) {
|
|
368
|
+
return cached;
|
|
369
|
+
}
|
|
370
|
+
this.xpathCache.delete(xpath);
|
|
371
|
+
}
|
|
372
|
+
try {
|
|
373
|
+
// Strip the xpath= prefix if present (from Stagehand selectors)
|
|
374
|
+
let cleanXpath = xpath;
|
|
375
|
+
if (xpath.startsWith('xpath=')) {
|
|
376
|
+
cleanXpath = xpath.substring(6); // Remove 'xpath=' prefix
|
|
377
|
+
}
|
|
378
|
+
const result = document.evaluate(cleanXpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
379
|
+
const element = result.singleNodeValue;
|
|
380
|
+
// Cache the result (use original xpath as key)
|
|
381
|
+
if (element) {
|
|
382
|
+
this.xpathCache.set(xpath, element);
|
|
383
|
+
}
|
|
384
|
+
return element;
|
|
385
|
+
}
|
|
386
|
+
catch (error) {
|
|
387
|
+
this.log('Error evaluating XPath:', xpath, error);
|
|
388
|
+
return null;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Log debug messages
|
|
393
|
+
*/
|
|
394
|
+
log(...args) {
|
|
395
|
+
if (this.options.debug) {
|
|
396
|
+
console.log('[SectionTracking]', ...args);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Update sections configuration
|
|
401
|
+
*/
|
|
402
|
+
updateSections(sections) {
|
|
403
|
+
if (this.isDestroyed)
|
|
404
|
+
return;
|
|
405
|
+
this.log('Updating sections configuration');
|
|
406
|
+
// Disconnect observer
|
|
407
|
+
if (this.intersectionObserver) {
|
|
408
|
+
this.intersectionObserver.disconnect();
|
|
409
|
+
}
|
|
410
|
+
// Clear state
|
|
411
|
+
this.sectionStates.clear();
|
|
412
|
+
this.xpathCache.clear();
|
|
413
|
+
// Update configuration
|
|
414
|
+
this.sections = sections;
|
|
415
|
+
// Reinitialize
|
|
416
|
+
this.setupIntersectionObserver();
|
|
417
|
+
this.initializeSections();
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Cleanup and destroy
|
|
421
|
+
*/
|
|
422
|
+
destroy() {
|
|
423
|
+
if (this.isDestroyed)
|
|
424
|
+
return;
|
|
425
|
+
this.log('Destroying section tracking manager');
|
|
426
|
+
this.isDestroyed = true;
|
|
427
|
+
// Stop all periodic tracking timers
|
|
428
|
+
this.sectionTimers.forEach((timerId) => {
|
|
429
|
+
clearInterval(timerId);
|
|
430
|
+
});
|
|
431
|
+
this.sectionTimers.clear();
|
|
432
|
+
// Flush any pending events
|
|
433
|
+
this.flushPendingEvents();
|
|
434
|
+
// Clear timers
|
|
435
|
+
if (this.scrollDebounceTimer !== null) {
|
|
436
|
+
clearTimeout(this.scrollDebounceTimer);
|
|
437
|
+
this.scrollDebounceTimer = null;
|
|
438
|
+
}
|
|
439
|
+
if (this.batchTimer !== null) {
|
|
440
|
+
clearTimeout(this.batchTimer);
|
|
441
|
+
this.batchTimer = null;
|
|
442
|
+
}
|
|
443
|
+
// Disconnect intersection observer
|
|
444
|
+
if (this.intersectionObserver) {
|
|
445
|
+
this.intersectionObserver.disconnect();
|
|
446
|
+
this.intersectionObserver = null;
|
|
447
|
+
}
|
|
448
|
+
// Clear state
|
|
449
|
+
this.sectionStates.clear();
|
|
450
|
+
this.xpathCache.clear();
|
|
451
|
+
this.pendingEvents = [];
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
exports.SectionTrackingManager = SectionTrackingManager;
|
|
455
|
+
//# sourceMappingURL=section-tracking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section-tracking.js","sourceRoot":"","sources":["../../src/section-tracking.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-tracking types for Grain Analytics SDK
|
|
3
|
+
*/
|
|
4
|
+
export interface InteractionConfig {
|
|
5
|
+
eventName: string;
|
|
6
|
+
description: string;
|
|
7
|
+
selector: string;
|
|
8
|
+
priority: number;
|
|
9
|
+
label: string;
|
|
10
|
+
}
|
|
11
|
+
export interface SectionConfig {
|
|
12
|
+
sectionName: string;
|
|
13
|
+
description: string;
|
|
14
|
+
sectionType: string;
|
|
15
|
+
selector: string;
|
|
16
|
+
importance: number;
|
|
17
|
+
}
|
|
18
|
+
export interface AutoTrackingConfig {
|
|
19
|
+
interactions: InteractionConfig[];
|
|
20
|
+
sections: SectionConfig[];
|
|
21
|
+
}
|
|
22
|
+
export interface SectionViewData {
|
|
23
|
+
sectionName: string;
|
|
24
|
+
sectionType: string;
|
|
25
|
+
entryTime: number;
|
|
26
|
+
exitTime: number;
|
|
27
|
+
duration: number;
|
|
28
|
+
viewportWidth: number;
|
|
29
|
+
viewportHeight: number;
|
|
30
|
+
scrollDepth: number;
|
|
31
|
+
visibleAreaPercentage: number;
|
|
32
|
+
scrollSpeedAtEntry?: number;
|
|
33
|
+
scrollSpeedAtExit?: number;
|
|
34
|
+
}
|
|
35
|
+
export interface SectionTrackingOptions {
|
|
36
|
+
minDwellTime: number;
|
|
37
|
+
scrollVelocityThreshold: number;
|
|
38
|
+
intersectionThreshold: number;
|
|
39
|
+
debounceDelay: number;
|
|
40
|
+
batchDelay: number;
|
|
41
|
+
debug?: boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface SectionTrackingState {
|
|
44
|
+
element: Element;
|
|
45
|
+
config: SectionConfig;
|
|
46
|
+
entryTime: number | null;
|
|
47
|
+
exitTime: number | null;
|
|
48
|
+
isVisible: boolean;
|
|
49
|
+
lastScrollPosition: number;
|
|
50
|
+
lastScrollTime: number;
|
|
51
|
+
entryScrollSpeed: number;
|
|
52
|
+
exitScrollSpeed: number;
|
|
53
|
+
maxVisibleArea: number;
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=auto-tracking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-tracking.d.ts","sourceRoot":"","sources":["../../../src/types/auto-tracking.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,sBAAsB;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,uBAAuB,EAAE,MAAM,CAAC;IAChC,qBAAqB,EAAE,MAAM,CAAC;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,CAAC;IACtB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-tracking.js","sourceRoot":"","sources":["../../../src/types/auto-tracking.ts"],"names":[],"mappings":";AAAA;;GAEG"}
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { categorizeReferrer, parseUTMParameters, type ReferrerCategory, type UTM
|
|
|
10
10
|
export type { ReferrerCategory, UTMParameters, FirstTouchAttribution };
|
|
11
11
|
export { categorizeReferrer, parseUTMParameters };
|
|
12
12
|
export { getCountry, getCountryCodeFromTimezone, getState } from './countries';
|
|
13
|
+
export type { InteractionConfig, SectionConfig, AutoTrackingConfig, SectionViewData, SectionTrackingOptions, } from './types/auto-tracking';
|
|
13
14
|
export interface GrainEvent {
|
|
14
15
|
eventName: string;
|
|
15
16
|
userId?: string;
|
|
@@ -75,6 +76,7 @@ export interface RemoteConfigRequest {
|
|
|
75
76
|
userId: string;
|
|
76
77
|
immediateKeys: string[];
|
|
77
78
|
properties?: Record<string, string>;
|
|
79
|
+
currentUrl?: string;
|
|
78
80
|
}
|
|
79
81
|
export interface RemoteConfigResponse {
|
|
80
82
|
userId: string;
|
|
@@ -85,6 +87,22 @@ export interface RemoteConfigResponse {
|
|
|
85
87
|
qualifiedRuleSets: string[];
|
|
86
88
|
timestamp: string;
|
|
87
89
|
isFromCache: boolean;
|
|
90
|
+
autoTrackingConfig?: {
|
|
91
|
+
interactions: Array<{
|
|
92
|
+
eventName: string;
|
|
93
|
+
description: string;
|
|
94
|
+
selector: string;
|
|
95
|
+
priority: number;
|
|
96
|
+
label: string;
|
|
97
|
+
}>;
|
|
98
|
+
sections: Array<{
|
|
99
|
+
sectionName: string;
|
|
100
|
+
description: string;
|
|
101
|
+
sectionType: string;
|
|
102
|
+
selector: string;
|
|
103
|
+
importance: number;
|
|
104
|
+
}>;
|
|
105
|
+
};
|
|
88
106
|
}
|
|
89
107
|
export interface RemoteConfigOptions {
|
|
90
108
|
immediateKeys?: string[];
|
|
@@ -217,6 +235,8 @@ export declare class GrainAnalytics implements HeartbeatTracker, PageTracker {
|
|
|
217
235
|
private pageTrackingManager;
|
|
218
236
|
private ephemeralSessionId;
|
|
219
237
|
private eventCountSinceLastHeartbeat;
|
|
238
|
+
private interactionTrackingManager;
|
|
239
|
+
private sectionTrackingManager;
|
|
220
240
|
private sessionStartTime;
|
|
221
241
|
private sessionEventCount;
|
|
222
242
|
constructor(config: GrainConfig);
|
|
@@ -262,7 +282,7 @@ export declare class GrainAnalytics implements HeartbeatTracker, PageTracker {
|
|
|
262
282
|
* this should not be called. Use getEphemeralSessionId() instead.
|
|
263
283
|
*/
|
|
264
284
|
private getEffectiveUserIdInternal;
|
|
265
|
-
|
|
285
|
+
log(...args: unknown[]): void;
|
|
266
286
|
/**
|
|
267
287
|
* Create error digest from events
|
|
268
288
|
*/
|
|
@@ -291,6 +311,14 @@ export declare class GrainAnalytics implements HeartbeatTracker, PageTracker {
|
|
|
291
311
|
* Initialize automatic tracking (heartbeat and page views)
|
|
292
312
|
*/
|
|
293
313
|
private initializeAutomaticTracking;
|
|
314
|
+
/**
|
|
315
|
+
* Initialize auto-tracking (interactions and sections)
|
|
316
|
+
*/
|
|
317
|
+
private initializeAutoTracking;
|
|
318
|
+
/**
|
|
319
|
+
* Setup auto-tracking managers
|
|
320
|
+
*/
|
|
321
|
+
private setupAutoTrackingManagers;
|
|
294
322
|
/**
|
|
295
323
|
* Track session start event
|
|
296
324
|
*/
|