@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.
Files changed (47) hide show
  1. package/dist/cjs/index.d.ts +28 -1
  2. package/dist/cjs/index.d.ts.map +1 -1
  3. package/dist/cjs/index.js.map +1 -1
  4. package/dist/cjs/interaction-tracking.d.ts +71 -0
  5. package/dist/cjs/interaction-tracking.d.ts.map +1 -0
  6. package/dist/cjs/interaction-tracking.js +270 -0
  7. package/dist/cjs/interaction-tracking.js.map +1 -0
  8. package/dist/cjs/section-tracking.d.ts +91 -0
  9. package/dist/cjs/section-tracking.d.ts.map +1 -0
  10. package/dist/cjs/section-tracking.js +373 -0
  11. package/dist/cjs/section-tracking.js.map +1 -0
  12. package/dist/cjs/types/auto-tracking.d.ts +55 -0
  13. package/dist/cjs/types/auto-tracking.d.ts.map +1 -0
  14. package/dist/cjs/types/auto-tracking.js +6 -0
  15. package/dist/cjs/types/auto-tracking.js.map +1 -0
  16. package/dist/esm/index.d.ts +28 -1
  17. package/dist/esm/index.d.ts.map +1 -1
  18. package/dist/esm/index.js.map +1 -1
  19. package/dist/esm/interaction-tracking.d.ts +71 -0
  20. package/dist/esm/interaction-tracking.d.ts.map +1 -0
  21. package/dist/esm/interaction-tracking.js +266 -0
  22. package/dist/esm/interaction-tracking.js.map +1 -0
  23. package/dist/esm/section-tracking.d.ts +91 -0
  24. package/dist/esm/section-tracking.d.ts.map +1 -0
  25. package/dist/esm/section-tracking.js +369 -0
  26. package/dist/esm/section-tracking.js.map +1 -0
  27. package/dist/esm/types/auto-tracking.d.ts +55 -0
  28. package/dist/esm/types/auto-tracking.d.ts.map +1 -0
  29. package/dist/esm/types/auto-tracking.js +5 -0
  30. package/dist/esm/types/auto-tracking.js.map +1 -0
  31. package/dist/index.d.ts +28 -1
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.global.dev.js +711 -1
  34. package/dist/index.global.dev.js.map +4 -4
  35. package/dist/index.global.js +2 -2
  36. package/dist/index.global.js.map +4 -4
  37. package/dist/index.js +124 -0
  38. package/dist/index.mjs +91 -0
  39. package/dist/interaction-tracking.d.ts +71 -0
  40. package/dist/interaction-tracking.d.ts.map +1 -0
  41. package/dist/interaction-tracking.js +270 -0
  42. package/dist/section-tracking.d.ts +91 -0
  43. package/dist/section-tracking.d.ts.map +1 -0
  44. package/dist/section-tracking.js +373 -0
  45. package/dist/types/auto-tracking.d.ts +55 -0
  46. package/dist/types/auto-tracking.d.ts.map +1 -0
  47. 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":"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"}
@@ -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"}