@grainql/analytics-web 2.4.0 → 2.5.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/cjs/index.d.ts +28 -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 +71 -0
- package/dist/cjs/interaction-tracking.d.ts.map +1 -0
- package/dist/cjs/interaction-tracking.js +270 -0
- package/dist/cjs/interaction-tracking.js.map +1 -0
- package/dist/cjs/section-tracking.d.ts +91 -0
- package/dist/cjs/section-tracking.d.ts.map +1 -0
- package/dist/cjs/section-tracking.js +373 -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 +28 -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 +71 -0
- package/dist/esm/interaction-tracking.d.ts.map +1 -0
- package/dist/esm/interaction-tracking.js +266 -0
- package/dist/esm/interaction-tracking.js.map +1 -0
- package/dist/esm/section-tracking.d.ts +91 -0
- package/dist/esm/section-tracking.d.ts.map +1 -0
- package/dist/esm/section-tracking.js +369 -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 +28 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +711 -1
- 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 +124 -0
- package/dist/index.mjs +91 -0
- package/dist/interaction-tracking.d.ts +71 -0
- package/dist/interaction-tracking.d.ts.map +1 -0
- package/dist/interaction-tracking.js +270 -0
- package/dist/section-tracking.d.ts +91 -0
- package/dist/section-tracking.d.ts.map +1 -0
- package/dist/section-tracking.js +373 -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,270 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Interaction Tracking Manager for Grain Analytics
|
|
4
|
+
* Automatically attaches click and focus listeners to detected interactive elements
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.InteractionTrackingManager = void 0;
|
|
8
|
+
class InteractionTrackingManager {
|
|
9
|
+
constructor(tracker, interactions, config = {}) {
|
|
10
|
+
this.isDestroyed = false;
|
|
11
|
+
this.attachedListeners = new Map();
|
|
12
|
+
this.xpathCache = new Map();
|
|
13
|
+
this.mutationObserver = null;
|
|
14
|
+
this.mutationDebounceTimer = null;
|
|
15
|
+
this.tracker = tracker;
|
|
16
|
+
this.interactions = interactions;
|
|
17
|
+
this.config = {
|
|
18
|
+
debug: config.debug ?? false,
|
|
19
|
+
enableMutationObserver: config.enableMutationObserver ?? true,
|
|
20
|
+
mutationDebounceDelay: config.mutationDebounceDelay ?? 500,
|
|
21
|
+
};
|
|
22
|
+
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
23
|
+
// Attach listeners after DOM is ready
|
|
24
|
+
if (document.readyState === 'loading') {
|
|
25
|
+
document.addEventListener('DOMContentLoaded', () => this.attachAllListeners());
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
// DOM already loaded
|
|
29
|
+
setTimeout(() => this.attachAllListeners(), 0);
|
|
30
|
+
}
|
|
31
|
+
// Setup mutation observer for dynamic content
|
|
32
|
+
if (this.config.enableMutationObserver) {
|
|
33
|
+
this.setupMutationObserver();
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Attach listeners to all configured interactions
|
|
39
|
+
*/
|
|
40
|
+
attachAllListeners() {
|
|
41
|
+
if (this.isDestroyed)
|
|
42
|
+
return;
|
|
43
|
+
this.log('Attaching interaction listeners for', this.interactions.length, 'interactions');
|
|
44
|
+
for (const interaction of this.interactions) {
|
|
45
|
+
this.attachInteractionListener(interaction);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Attach listener to a specific interaction
|
|
50
|
+
*/
|
|
51
|
+
attachInteractionListener(interaction) {
|
|
52
|
+
if (this.isDestroyed)
|
|
53
|
+
return;
|
|
54
|
+
const element = this.findElementByXPath(interaction.selector);
|
|
55
|
+
if (!element) {
|
|
56
|
+
this.log('Element not found for interaction:', interaction.eventName, 'selector:', interaction.selector);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
// Check if we already attached listeners to this element for this interaction
|
|
60
|
+
if (this.attachedListeners.has(element)) {
|
|
61
|
+
this.log('Listeners already attached for element:', element);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const handlers = [];
|
|
65
|
+
// Click handler
|
|
66
|
+
const clickHandler = (event) => this.handleInteractionClick(interaction, event);
|
|
67
|
+
element.addEventListener('click', clickHandler, { passive: true });
|
|
68
|
+
handlers.push({ event: 'click', handler: clickHandler });
|
|
69
|
+
// Focus handler (for form inputs)
|
|
70
|
+
if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement || element instanceof HTMLSelectElement) {
|
|
71
|
+
const focusHandler = (event) => this.handleInteractionFocus(interaction, event);
|
|
72
|
+
element.addEventListener('focus', focusHandler, { passive: true });
|
|
73
|
+
handlers.push({ event: 'focus', handler: focusHandler });
|
|
74
|
+
}
|
|
75
|
+
this.attachedListeners.set(element, handlers);
|
|
76
|
+
this.log('Attached listeners to element for:', interaction.eventName);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Handle click event on interaction
|
|
80
|
+
*/
|
|
81
|
+
handleInteractionClick(interaction, event) {
|
|
82
|
+
if (this.isDestroyed)
|
|
83
|
+
return;
|
|
84
|
+
if (!this.tracker.hasConsent('analytics'))
|
|
85
|
+
return;
|
|
86
|
+
const element = event.target;
|
|
87
|
+
this.tracker.track(interaction.eventName, {
|
|
88
|
+
interaction_type: 'click',
|
|
89
|
+
interaction_label: interaction.label,
|
|
90
|
+
interaction_description: interaction.description,
|
|
91
|
+
interaction_priority: interaction.priority,
|
|
92
|
+
element_tag: element.tagName?.toLowerCase(),
|
|
93
|
+
element_text: element.textContent?.trim().substring(0, 100),
|
|
94
|
+
element_id: element.id || undefined,
|
|
95
|
+
element_class: element.className || undefined,
|
|
96
|
+
timestamp: Date.now(),
|
|
97
|
+
});
|
|
98
|
+
this.log('Tracked click interaction:', interaction.eventName);
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Handle focus event on interaction (for form fields)
|
|
102
|
+
*/
|
|
103
|
+
handleInteractionFocus(interaction, event) {
|
|
104
|
+
if (this.isDestroyed)
|
|
105
|
+
return;
|
|
106
|
+
if (!this.tracker.hasConsent('analytics'))
|
|
107
|
+
return;
|
|
108
|
+
const element = event.target;
|
|
109
|
+
this.tracker.track(interaction.eventName, {
|
|
110
|
+
interaction_type: 'focus',
|
|
111
|
+
interaction_label: interaction.label,
|
|
112
|
+
interaction_description: interaction.description,
|
|
113
|
+
interaction_priority: interaction.priority,
|
|
114
|
+
element_tag: element.tagName?.toLowerCase(),
|
|
115
|
+
element_id: element.id || undefined,
|
|
116
|
+
element_class: element.className || undefined,
|
|
117
|
+
timestamp: Date.now(),
|
|
118
|
+
});
|
|
119
|
+
this.log('Tracked focus interaction:', interaction.eventName);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Find element by XPath selector
|
|
123
|
+
*/
|
|
124
|
+
findElementByXPath(xpath) {
|
|
125
|
+
// Check cache first
|
|
126
|
+
if (this.xpathCache.has(xpath)) {
|
|
127
|
+
const cached = this.xpathCache.get(xpath);
|
|
128
|
+
// Verify element is still in DOM
|
|
129
|
+
if (cached && document.contains(cached)) {
|
|
130
|
+
return cached;
|
|
131
|
+
}
|
|
132
|
+
// Clear invalid cache entry
|
|
133
|
+
this.xpathCache.delete(xpath);
|
|
134
|
+
}
|
|
135
|
+
try {
|
|
136
|
+
const result = document.evaluate(xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
|
|
137
|
+
const element = result.singleNodeValue;
|
|
138
|
+
// Cache the result
|
|
139
|
+
if (element) {
|
|
140
|
+
this.xpathCache.set(xpath, element);
|
|
141
|
+
}
|
|
142
|
+
return element;
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
this.log('Error evaluating XPath:', xpath, error);
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Setup mutation observer to handle dynamic content
|
|
151
|
+
*/
|
|
152
|
+
setupMutationObserver() {
|
|
153
|
+
if (typeof MutationObserver === 'undefined') {
|
|
154
|
+
this.log('MutationObserver not supported');
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
this.mutationObserver = new MutationObserver((mutations) => {
|
|
158
|
+
// Debounce the re-attachment
|
|
159
|
+
if (this.mutationDebounceTimer !== null) {
|
|
160
|
+
clearTimeout(this.mutationDebounceTimer);
|
|
161
|
+
}
|
|
162
|
+
this.mutationDebounceTimer = window.setTimeout(() => {
|
|
163
|
+
this.handleMutations(mutations);
|
|
164
|
+
this.mutationDebounceTimer = null;
|
|
165
|
+
}, this.config.mutationDebounceDelay);
|
|
166
|
+
});
|
|
167
|
+
this.mutationObserver.observe(document.body, {
|
|
168
|
+
childList: true,
|
|
169
|
+
subtree: true,
|
|
170
|
+
});
|
|
171
|
+
this.log('Mutation observer setup');
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Handle DOM mutations
|
|
175
|
+
*/
|
|
176
|
+
handleMutations(mutations) {
|
|
177
|
+
if (this.isDestroyed)
|
|
178
|
+
return;
|
|
179
|
+
// Clear XPath cache on mutations
|
|
180
|
+
this.xpathCache.clear();
|
|
181
|
+
// Check if any of our tracked elements were removed
|
|
182
|
+
const removedElements = new Set();
|
|
183
|
+
for (const mutation of mutations) {
|
|
184
|
+
mutation.removedNodes.forEach((node) => {
|
|
185
|
+
if (node instanceof Element) {
|
|
186
|
+
removedElements.add(node);
|
|
187
|
+
// Also check for child elements we were tracking
|
|
188
|
+
this.attachedListeners.forEach((handlers, element) => {
|
|
189
|
+
if (node.contains(element)) {
|
|
190
|
+
removedElements.add(element);
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
// Clean up removed elements
|
|
197
|
+
removedElements.forEach((element) => {
|
|
198
|
+
this.detachListeners(element);
|
|
199
|
+
});
|
|
200
|
+
// Try to re-attach listeners for any interactions that might now be available
|
|
201
|
+
this.attachAllListeners();
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Detach listeners from an element
|
|
205
|
+
*/
|
|
206
|
+
detachListeners(element) {
|
|
207
|
+
const handlers = this.attachedListeners.get(element);
|
|
208
|
+
if (!handlers)
|
|
209
|
+
return;
|
|
210
|
+
handlers.forEach(({ event, handler }) => {
|
|
211
|
+
element.removeEventListener(event, handler);
|
|
212
|
+
});
|
|
213
|
+
this.attachedListeners.delete(element);
|
|
214
|
+
this.log('Detached listeners from element');
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Log debug messages
|
|
218
|
+
*/
|
|
219
|
+
log(...args) {
|
|
220
|
+
if (this.config.debug) {
|
|
221
|
+
console.log('[InteractionTracking]', ...args);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Update interactions configuration
|
|
226
|
+
*/
|
|
227
|
+
updateInteractions(interactions) {
|
|
228
|
+
if (this.isDestroyed)
|
|
229
|
+
return;
|
|
230
|
+
this.log('Updating interactions configuration');
|
|
231
|
+
// Detach all existing listeners
|
|
232
|
+
this.attachedListeners.forEach((handlers, element) => {
|
|
233
|
+
this.detachListeners(element);
|
|
234
|
+
});
|
|
235
|
+
// Clear cache
|
|
236
|
+
this.xpathCache.clear();
|
|
237
|
+
// Update configuration
|
|
238
|
+
this.interactions = interactions;
|
|
239
|
+
// Reattach listeners
|
|
240
|
+
this.attachAllListeners();
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Cleanup and destroy
|
|
244
|
+
*/
|
|
245
|
+
destroy() {
|
|
246
|
+
if (this.isDestroyed)
|
|
247
|
+
return;
|
|
248
|
+
this.log('Destroying interaction tracking manager');
|
|
249
|
+
this.isDestroyed = true;
|
|
250
|
+
// Clear debounce timer
|
|
251
|
+
if (this.mutationDebounceTimer !== null) {
|
|
252
|
+
clearTimeout(this.mutationDebounceTimer);
|
|
253
|
+
this.mutationDebounceTimer = null;
|
|
254
|
+
}
|
|
255
|
+
// Disconnect mutation observer
|
|
256
|
+
if (this.mutationObserver) {
|
|
257
|
+
this.mutationObserver.disconnect();
|
|
258
|
+
this.mutationObserver = null;
|
|
259
|
+
}
|
|
260
|
+
// Detach all listeners
|
|
261
|
+
this.attachedListeners.forEach((handlers, element) => {
|
|
262
|
+
this.detachListeners(element);
|
|
263
|
+
});
|
|
264
|
+
// Clear caches
|
|
265
|
+
this.attachedListeners.clear();
|
|
266
|
+
this.xpathCache.clear();
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
exports.InteractionTrackingManager = InteractionTrackingManager;
|
|
270
|
+
//# sourceMappingURL=interaction-tracking.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interaction-tracking.js","sourceRoot":"","sources":["../../src/interaction-tracking.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAgBH,MAAa,0BAA0B;IAUrC,YACE,OAA2B,EAC3B,YAAiC,EACjC,SAAoC,EAAE;QAThC,gBAAW,GAAG,KAAK,CAAC;QACpB,sBAAiB,GAAmE,IAAI,GAAG,EAAE,CAAC;QAC9F,eAAU,GAAgC,IAAI,GAAG,EAAE,CAAC;QACpD,qBAAgB,GAA4B,IAAI,CAAC;QACjD,0BAAqB,GAAkB,IAAI,CAAC;QAOlD,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,MAAM,GAAG;YACZ,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,KAAK;YAC5B,sBAAsB,EAAE,MAAM,CAAC,sBAAsB,IAAI,IAAI;YAC7D,qBAAqB,EAAE,MAAM,CAAC,qBAAqB,IAAI,GAAG;SAC3D,CAAC;QAEF,IAAI,OAAO,MAAM,KAAK,WAAW,IAAI,OAAO,QAAQ,KAAK,WAAW,EAAE,CAAC;YACrE,sCAAsC;YACtC,IAAI,QAAQ,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;gBACtC,QAAQ,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,CAAC,CAAC;YACjF,CAAC;iBAAM,CAAC;gBACN,qBAAqB;gBACrB,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,CAAC;YACjD,CAAC;YAED,8CAA8C;YAC9C,IAAI,IAAI,CAAC,MAAM,CAAC,sBAAsB,EAAE,CAAC;gBACvC,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,kBAAkB;QACxB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,IAAI,CAAC,GAAG,CAAC,qCAAqC,EAAE,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;QAE1F,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5C,IAAI,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,yBAAyB,CAAC,WAA8B;QAC9D,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE9D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,IAAI,CAAC,GAAG,CAAC,oCAAoC,EAAE,WAAW,CAAC,SAAS,EAAE,WAAW,EAAE,WAAW,CAAC,QAAQ,CAAC,CAAC;YACzG,OAAO;QACT,CAAC;QAED,8EAA8E;QAC9E,IAAI,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACxC,IAAI,CAAC,GAAG,CAAC,yCAAyC,EAAE,OAAO,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,MAAM,QAAQ,GAAqD,EAAE,CAAC;QAEtE,gBAAgB;QAChB,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;QACvF,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QAEzD,kCAAkC;QAClC,IAAI,OAAO,YAAY,gBAAgB,IAAI,OAAO,YAAY,mBAAmB,IAAI,OAAO,YAAY,iBAAiB,EAAE,CAAC;YAC1H,MAAM,YAAY,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,IAAI,CAAC,sBAAsB,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC;YACvF,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,YAAY,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;YACnE,QAAQ,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,GAAG,CAAC,oCAAoC,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IACxE,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,WAA8B,EAAE,KAAY;QACzE,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO;QAElD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAqB,CAAC;QAE5C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE;YACxC,gBAAgB,EAAE,OAAO;YACzB,iBAAiB,EAAE,WAAW,CAAC,KAAK;YACpC,uBAAuB,EAAE,WAAW,CAAC,WAAW;YAChD,oBAAoB,EAAE,WAAW,CAAC,QAAQ;YAC1C,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE;YAC3C,YAAY,EAAE,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC;YAC3D,UAAU,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;YACnC,aAAa,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;YAC7C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,4BAA4B,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACK,sBAAsB,CAAC,WAA8B,EAAE,KAAY;QACzE,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC;YAAE,OAAO;QAElD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAqB,CAAC;QAE5C,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,SAAS,EAAE;YACxC,gBAAgB,EAAE,OAAO;YACzB,iBAAiB,EAAE,WAAW,CAAC,KAAK;YACpC,uBAAuB,EAAE,WAAW,CAAC,WAAW;YAChD,oBAAoB,EAAE,WAAW,CAAC,QAAQ;YAC1C,WAAW,EAAE,OAAO,CAAC,OAAO,EAAE,WAAW,EAAE;YAC3C,UAAU,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;YACnC,aAAa,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;YAC7C,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,4BAA4B,EAAE,WAAW,CAAC,SAAS,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACK,kBAAkB,CAAC,KAAa;QACtC,oBAAoB;QACpB,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAC1C,iCAAiC;YACjC,IAAI,MAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACxC,OAAO,MAAM,CAAC;YAChB,CAAC;YACD,4BAA4B;YAC5B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAChC,CAAC;QAED,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,QAAQ,CAAC,QAAQ,CAC9B,KAAK,EACL,QAAQ,EACR,IAAI,EACJ,WAAW,CAAC,uBAAuB,EACnC,IAAI,CACL,CAAC;YAEF,MAAM,OAAO,GAAG,MAAM,CAAC,eAAiC,CAAC;YAEzD,mBAAmB;YACnB,IAAI,OAAO,EAAE,CAAC;gBACZ,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACtC,CAAC;YAED,OAAO,OAAO,CAAC;QACjB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,CAAC,yBAAyB,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;YAClD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;OAEG;IACK,qBAAqB;QAC3B,IAAI,OAAO,gBAAgB,KAAK,WAAW,EAAE,CAAC;YAC5C,IAAI,CAAC,GAAG,CAAC,gCAAgC,CAAC,CAAC;YAC3C,OAAO;QACT,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,gBAAgB,CAAC,CAAC,SAAS,EAAE,EAAE;YACzD,6BAA6B;YAC7B,IAAI,IAAI,CAAC,qBAAqB,KAAK,IAAI,EAAE,CAAC;gBACxC,YAAY,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YAC3C,CAAC;YAED,IAAI,CAAC,qBAAqB,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;gBAClD,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,CAAC;gBAChC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;YACpC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC;QACxC,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE;YAC3C,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,IAAI;SACd,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACtC,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,SAA2B;QACjD,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,iCAAiC;QACjC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAExB,oDAAoD;QACpD,MAAM,eAAe,GAAG,IAAI,GAAG,EAAW,CAAC;QAC3C,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YACjC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE;gBACrC,IAAI,IAAI,YAAY,OAAO,EAAE,CAAC;oBAC5B,eAAe,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;oBAC1B,iDAAiD;oBACjD,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;wBACnD,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;4BAC3B,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;wBAC/B,CAAC;oBACH,CAAC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAED,4BAA4B;QAC5B,eAAe,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;YAClC,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,8EAA8E;QAC9E,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACK,eAAe,CAAC,OAAgB;QACtC,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrD,IAAI,CAAC,QAAQ;YAAE,OAAO;QAEtB,QAAQ,CAAC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;YACtC,OAAO,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC9C,CAAC;IAED;;OAEG;IACK,GAAG,CAAC,GAAG,IAAe;QAC5B,IAAI,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,GAAG,IAAI,CAAC,CAAC;QAChD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,kBAAkB,CAAC,YAAiC;QAClD,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,IAAI,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QAEhD,gCAAgC;QAChC,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;YACnD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,cAAc;QACd,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QAExB,uBAAuB;QACvB,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QAEjC,qBAAqB;QACrB,IAAI,CAAC,kBAAkB,EAAE,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,OAAO;QACL,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAE7B,IAAI,CAAC,GAAG,CAAC,yCAAyC,CAAC,CAAC;QAEpD,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAExB,uBAAuB;QACvB,IAAI,IAAI,CAAC,qBAAqB,KAAK,IAAI,EAAE,CAAC;YACxC,YAAY,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;YACzC,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;QACpC,CAAC;QAED,+BAA+B;QAC/B,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YAC1B,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,uBAAuB;QACvB,IAAI,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE;YACnD,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,eAAe;QACf,IAAI,CAAC,iBAAiB,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;IAC1B,CAAC;CACF;AA3TD,gEA2TC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Section Tracking Manager for Grain Analytics
|
|
3
|
+
* Intelligent scroll tracking with viewport metrics, visible sections, and engagement analysis
|
|
4
|
+
*/
|
|
5
|
+
import type { SectionConfig, SectionTrackingOptions } from './types/auto-tracking';
|
|
6
|
+
export interface SectionTracker {
|
|
7
|
+
trackSystemEvent(eventName: string, properties: Record<string, unknown>): void;
|
|
8
|
+
hasConsent(category: 'analytics' | 'marketing' | 'functional'): boolean;
|
|
9
|
+
log(...args: unknown[]): void;
|
|
10
|
+
}
|
|
11
|
+
export declare class SectionTrackingManager {
|
|
12
|
+
private tracker;
|
|
13
|
+
private sections;
|
|
14
|
+
private options;
|
|
15
|
+
private isDestroyed;
|
|
16
|
+
private sectionStates;
|
|
17
|
+
private intersectionObserver;
|
|
18
|
+
private xpathCache;
|
|
19
|
+
private lastScrollPosition;
|
|
20
|
+
private lastScrollTime;
|
|
21
|
+
private scrollVelocity;
|
|
22
|
+
private scrollDebounceTimer;
|
|
23
|
+
private pendingEvents;
|
|
24
|
+
private batchTimer;
|
|
25
|
+
constructor(tracker: SectionTracker, sections: SectionConfig[], options?: Partial<SectionTrackingOptions>);
|
|
26
|
+
/**
|
|
27
|
+
* Initialize section tracking
|
|
28
|
+
*/
|
|
29
|
+
private initialize;
|
|
30
|
+
/**
|
|
31
|
+
* Setup IntersectionObserver for section visibility
|
|
32
|
+
*/
|
|
33
|
+
private setupIntersectionObserver;
|
|
34
|
+
/**
|
|
35
|
+
* Setup scroll listener for velocity calculation
|
|
36
|
+
*/
|
|
37
|
+
private setupScrollListener;
|
|
38
|
+
/**
|
|
39
|
+
* Initialize sections and start observing
|
|
40
|
+
*/
|
|
41
|
+
private initializeSections;
|
|
42
|
+
/**
|
|
43
|
+
* Handle intersection observer entry
|
|
44
|
+
*/
|
|
45
|
+
private handleIntersection;
|
|
46
|
+
/**
|
|
47
|
+
* Handle section entry (became visible)
|
|
48
|
+
*/
|
|
49
|
+
private handleSectionEntry;
|
|
50
|
+
/**
|
|
51
|
+
* Handle section exit (became invisible)
|
|
52
|
+
*/
|
|
53
|
+
private handleSectionExit;
|
|
54
|
+
/**
|
|
55
|
+
* Update scroll velocity
|
|
56
|
+
*/
|
|
57
|
+
private updateScrollVelocity;
|
|
58
|
+
/**
|
|
59
|
+
* Calculate current scroll depth as percentage
|
|
60
|
+
*/
|
|
61
|
+
private calculateScrollDepth;
|
|
62
|
+
/**
|
|
63
|
+
* Determine if section view should be tracked (sanitization)
|
|
64
|
+
*/
|
|
65
|
+
private shouldTrackSection;
|
|
66
|
+
/**
|
|
67
|
+
* Queue section view for batching
|
|
68
|
+
*/
|
|
69
|
+
private queueSectionView;
|
|
70
|
+
/**
|
|
71
|
+
* Flush pending section view events
|
|
72
|
+
*/
|
|
73
|
+
private flushPendingEvents;
|
|
74
|
+
/**
|
|
75
|
+
* Find element by XPath selector
|
|
76
|
+
*/
|
|
77
|
+
private findElementByXPath;
|
|
78
|
+
/**
|
|
79
|
+
* Log debug messages
|
|
80
|
+
*/
|
|
81
|
+
private log;
|
|
82
|
+
/**
|
|
83
|
+
* Update sections configuration
|
|
84
|
+
*/
|
|
85
|
+
updateSections(sections: SectionConfig[]): void;
|
|
86
|
+
/**
|
|
87
|
+
* Cleanup and destroy
|
|
88
|
+
*/
|
|
89
|
+
destroy(): void;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=section-tracking.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section-tracking.d.ts","sourceRoot":"","sources":["../../src/section-tracking.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAmB,sBAAsB,EAAwB,MAAM,uBAAuB,CAAC;AAE1H,MAAM,WAAW,cAAc;IAC7B,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC/E,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;AAWD,qBAAa,sBAAsB;IACjC,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,OAAO,CAAyB;IACxC,OAAO,CAAC,WAAW,CAAS;IAG5B,OAAO,CAAC,aAAa,CAAgD;IACrE,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,UAAU,CAA0C;IAG5D,OAAO,CAAC,kBAAkB,CAAK;IAC/B,OAAO,CAAC,cAAc,CAAc;IACpC,OAAO,CAAC,cAAc,CAAK;IAC3B,OAAO,CAAC,mBAAmB,CAAuB;IAGlD,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,UAAU,CAAuB;gBAGvC,OAAO,EAAE,cAAc,EACvB,QAAQ,EAAE,aAAa,EAAE,EACzB,OAAO,GAAE,OAAO,CAAC,sBAAsB,CAAM;IAgB/C;;OAEG;IACH,OAAO,CAAC,UAAU;IAelB;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAqBjC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkB3B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAkC1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoCzB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAe5B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoB5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAqB1B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA+B1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgC1B;;OAEG;IACH,OAAO,CAAC,GAAG;IAMX;;OAEG;IACH,cAAc,CAAC,QAAQ,EAAE,aAAa,EAAE,GAAG,IAAI;IAsB/C;;OAEG;IACH,OAAO,IAAI,IAAI;CAgChB"}
|