@zaplier/sdk 1.6.9 → 1.7.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/index.cjs +373 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.esm.js +373 -44
- package/dist/index.esm.js.map +1 -1
- package/dist/sdk.js +373 -44
- package/dist/sdk.js.map +1 -1
- package/dist/sdk.min.js +1 -1
- package/dist/src/modules/auto-tracker.d.ts +58 -3
- package/dist/src/modules/auto-tracker.d.ts.map +1 -1
- package/dist/src/modules/global-interface.d.ts +2 -0
- package/dist/src/modules/global-interface.d.ts.map +1 -1
- package/dist/src/sdk.d.ts +16 -0
- package/dist/src/sdk.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -19266,6 +19266,8 @@ class AutoTracker {
|
|
|
19266
19266
|
constructor(sdkInstance, config = {}) {
|
|
19267
19267
|
this.observedElements = new Set();
|
|
19268
19268
|
this.scrollThrottle = 0;
|
|
19269
|
+
this.isInitialized = false;
|
|
19270
|
+
this.delegationHandlers = new Map();
|
|
19269
19271
|
this.handleScroll = () => {
|
|
19270
19272
|
if (!this.config.trackScrolls)
|
|
19271
19273
|
return;
|
|
@@ -19370,30 +19372,29 @@ class AutoTracker {
|
|
|
19370
19372
|
trackScrolls: this.config.trackScrolls,
|
|
19371
19373
|
trackViews: this.config.trackViews,
|
|
19372
19374
|
trackHovers: this.config.trackHovers,
|
|
19373
|
-
trackForms: this.config.trackForms
|
|
19375
|
+
trackForms: this.config.trackForms,
|
|
19376
|
+
domReady: document.readyState
|
|
19374
19377
|
});
|
|
19375
|
-
|
|
19376
|
-
|
|
19377
|
-
|
|
19378
|
-
|
|
19379
|
-
|
|
19380
|
-
|
|
19381
|
-
|
|
19382
|
-
|
|
19383
|
-
|
|
19384
|
-
scrollElements: scrollElements.length,
|
|
19385
|
-
viewElements: viewElements.length,
|
|
19386
|
-
hoverElements: hoverElements.length,
|
|
19387
|
-
formElements: formElements.length
|
|
19388
|
-
});
|
|
19389
|
-
if (scrollElements.length > 0) {
|
|
19390
|
-
console.log("[Zaplier AutoTracker] Elementos de scroll:", Array.from(scrollElements).map(el => ({
|
|
19391
|
-
tagName: el.tagName,
|
|
19392
|
-
trackEvent: el.getAttribute('data-track-scroll'),
|
|
19393
|
-
threshold: el.getAttribute('data-scroll-threshold') || '0.5'
|
|
19394
|
-
})));
|
|
19378
|
+
}
|
|
19379
|
+
// Aguardar DOM ready se necessário
|
|
19380
|
+
if (document.readyState === 'loading') {
|
|
19381
|
+
if (this.config.debug) {
|
|
19382
|
+
console.log("[Zaplier AutoTracker] DOM still loading, waiting for DOMContentLoaded...");
|
|
19383
|
+
}
|
|
19384
|
+
document.addEventListener('DOMContentLoaded', () => {
|
|
19385
|
+
if (this.config.debug) {
|
|
19386
|
+
console.log("[Zaplier AutoTracker] DOMContentLoaded fired, initializing tracking...");
|
|
19395
19387
|
}
|
|
19396
|
-
|
|
19388
|
+
this.initializeTracking();
|
|
19389
|
+
}, { once: true });
|
|
19390
|
+
}
|
|
19391
|
+
else {
|
|
19392
|
+
this.initializeTracking();
|
|
19393
|
+
}
|
|
19394
|
+
}
|
|
19395
|
+
initializeTracking() {
|
|
19396
|
+
if (this.config.debug) {
|
|
19397
|
+
console.log("[Zaplier AutoTracker] Initializing tracking...");
|
|
19397
19398
|
}
|
|
19398
19399
|
// Observer para novos elementos no DOM
|
|
19399
19400
|
this.observeDOM();
|
|
@@ -19403,42 +19404,269 @@ class AutoTracker {
|
|
|
19403
19404
|
if (this.config.trackViews) {
|
|
19404
19405
|
this.setupViewTracking();
|
|
19405
19406
|
}
|
|
19406
|
-
// Setup
|
|
19407
|
+
// Setup event delegation (modern approach)
|
|
19408
|
+
this.setupEventDelegation();
|
|
19409
|
+
// Debug: Log elementos encontrados após inicialização
|
|
19410
|
+
if (this.config.debug) {
|
|
19411
|
+
this.logFoundElements();
|
|
19412
|
+
// Também agendar uma verificação após delay para elementos React
|
|
19413
|
+
setTimeout(() => {
|
|
19414
|
+
console.log("[Zaplier AutoTracker] Re-checking elements after 500ms...");
|
|
19415
|
+
this.logFoundElements();
|
|
19416
|
+
}, 500);
|
|
19417
|
+
setTimeout(() => {
|
|
19418
|
+
console.log("[Zaplier AutoTracker] Re-checking elements after 2s...");
|
|
19419
|
+
this.logFoundElements();
|
|
19420
|
+
}, 2000);
|
|
19421
|
+
}
|
|
19422
|
+
}
|
|
19423
|
+
logFoundElements() {
|
|
19424
|
+
const clickElements = document.querySelectorAll('[data-track-click]');
|
|
19425
|
+
const scrollElements = document.querySelectorAll('[data-track-scroll]');
|
|
19426
|
+
const viewElements = document.querySelectorAll('[data-track-view]');
|
|
19427
|
+
const hoverElements = document.querySelectorAll('[data-track-hover]');
|
|
19428
|
+
const formElements = document.querySelectorAll('[data-track-form]');
|
|
19429
|
+
console.log("[Zaplier AutoTracker] Elementos encontrados:", {
|
|
19430
|
+
clickElements: clickElements.length,
|
|
19431
|
+
scrollElements: scrollElements.length,
|
|
19432
|
+
viewElements: viewElements.length,
|
|
19433
|
+
hoverElements: hoverElements.length,
|
|
19434
|
+
formElements: formElements.length,
|
|
19435
|
+
totalElements: clickElements.length + scrollElements.length + viewElements.length + hoverElements.length + formElements.length
|
|
19436
|
+
});
|
|
19437
|
+
if (scrollElements.length > 0) {
|
|
19438
|
+
console.log("[Zaplier AutoTracker] Elementos de scroll:", Array.from(scrollElements).map(el => ({
|
|
19439
|
+
tagName: el.tagName,
|
|
19440
|
+
trackEvent: el.getAttribute('data-track-scroll'),
|
|
19441
|
+
threshold: el.getAttribute('data-scroll-threshold') || '0.5',
|
|
19442
|
+
id: el.id || 'no-id',
|
|
19443
|
+
classes: el.className || 'no-classes'
|
|
19444
|
+
})));
|
|
19445
|
+
}
|
|
19446
|
+
}
|
|
19447
|
+
/**
|
|
19448
|
+
* Setup Event Delegation (Industry Best Practice)
|
|
19449
|
+
* Uses single document-level listeners instead of individual element listeners
|
|
19450
|
+
*/
|
|
19451
|
+
setupEventDelegation() {
|
|
19452
|
+
if (this.config.debug) {
|
|
19453
|
+
console.log("[AutoTracker] Setting up event delegation...");
|
|
19454
|
+
}
|
|
19455
|
+
// Click delegation
|
|
19407
19456
|
if (this.config.trackClicks) {
|
|
19408
|
-
|
|
19457
|
+
const clickHandler = this.createDelegatedClickHandler();
|
|
19458
|
+
this.delegationHandlers.set('click', clickHandler);
|
|
19459
|
+
document.addEventListener('click', clickHandler, { passive: true });
|
|
19409
19460
|
}
|
|
19461
|
+
// Scroll delegation (using global handler with element detection)
|
|
19410
19462
|
if (this.config.trackScrolls) {
|
|
19411
|
-
|
|
19463
|
+
const scrollHandler = this.createDelegatedScrollHandler();
|
|
19464
|
+
this.delegationHandlers.set('scroll', scrollHandler);
|
|
19465
|
+
document.addEventListener('scroll', scrollHandler, { passive: true });
|
|
19412
19466
|
}
|
|
19467
|
+
// Setup debounced mutation observer for dynamic content
|
|
19468
|
+
this.setupIntelligentMutationObserver();
|
|
19469
|
+
this.isInitialized = true;
|
|
19413
19470
|
}
|
|
19414
19471
|
/**
|
|
19415
|
-
*
|
|
19472
|
+
* Create delegated click handler (no individual listeners needed)
|
|
19416
19473
|
*/
|
|
19417
|
-
|
|
19418
|
-
|
|
19419
|
-
|
|
19420
|
-
|
|
19421
|
-
|
|
19474
|
+
createDelegatedClickHandler() {
|
|
19475
|
+
return (event) => {
|
|
19476
|
+
const target = event.target;
|
|
19477
|
+
if (!target || !this.config.trackClicks)
|
|
19478
|
+
return;
|
|
19479
|
+
// Check if target or any parent has data-track-click
|
|
19480
|
+
const trackingElement = target.closest('[data-track-click]');
|
|
19481
|
+
if (!trackingElement)
|
|
19482
|
+
return;
|
|
19483
|
+
const eventName = trackingElement.getAttribute('data-track-click');
|
|
19484
|
+
if (!eventName)
|
|
19485
|
+
return;
|
|
19486
|
+
const metadata = this.extractMetadata(trackingElement);
|
|
19487
|
+
this.trackEvent(eventName, {
|
|
19488
|
+
type: 'click',
|
|
19489
|
+
element: trackingElement.tagName.toLowerCase(),
|
|
19490
|
+
...metadata,
|
|
19491
|
+
});
|
|
19492
|
+
if (this.config.debug) {
|
|
19493
|
+
console.log(`[AutoTracker] Click tracked via delegation: ${eventName}`, {
|
|
19494
|
+
element: trackingElement.tagName.toLowerCase(),
|
|
19495
|
+
...metadata
|
|
19496
|
+
});
|
|
19497
|
+
}
|
|
19498
|
+
};
|
|
19499
|
+
}
|
|
19500
|
+
/**
|
|
19501
|
+
* Create delegated scroll handler (efficient global approach)
|
|
19502
|
+
*/
|
|
19503
|
+
createDelegatedScrollHandler() {
|
|
19504
|
+
return () => {
|
|
19505
|
+
if (!this.config.trackScrolls)
|
|
19506
|
+
return;
|
|
19507
|
+
// Throttle scroll events for performance
|
|
19508
|
+
const now = Date.now();
|
|
19509
|
+
if (now - this.scrollThrottle < 100)
|
|
19510
|
+
return;
|
|
19511
|
+
this.scrollThrottle = now;
|
|
19512
|
+
// Find all scroll tracking elements and check visibility
|
|
19513
|
+
const scrollElements = document.querySelectorAll('[data-track-scroll]');
|
|
19514
|
+
if (this.config.debug && scrollElements.length > 0) {
|
|
19515
|
+
console.log(`[AutoTracker] Checking ${scrollElements.length} scroll elements via delegation`);
|
|
19516
|
+
}
|
|
19517
|
+
scrollElements.forEach((element) => {
|
|
19518
|
+
this.processScrollElement(element);
|
|
19519
|
+
});
|
|
19520
|
+
};
|
|
19521
|
+
}
|
|
19522
|
+
/**
|
|
19523
|
+
* Process individual scroll element (extracted for reusability)
|
|
19524
|
+
*/
|
|
19525
|
+
processScrollElement(element) {
|
|
19526
|
+
const hasTriggered = element.getAttribute('data-scroll-triggered') === 'true';
|
|
19527
|
+
if (hasTriggered)
|
|
19528
|
+
return;
|
|
19529
|
+
const threshold = parseFloat(element.getAttribute('data-scroll-threshold') || '0.5');
|
|
19530
|
+
const rect = element.getBoundingClientRect();
|
|
19531
|
+
const elementHeight = rect.height;
|
|
19532
|
+
const visibleHeight = Math.min(rect.bottom, window.innerHeight) - Math.max(rect.top, 0);
|
|
19533
|
+
const visibilityRatio = Math.max(0, visibleHeight) / elementHeight;
|
|
19534
|
+
if (this.config.debug) {
|
|
19535
|
+
console.log(`[AutoTracker] Scroll element check via delegation:`, {
|
|
19536
|
+
elementId: element.id || element.className,
|
|
19537
|
+
visibilityRatio: Math.round(visibilityRatio * 100) / 100,
|
|
19538
|
+
threshold,
|
|
19539
|
+
triggered: hasTriggered
|
|
19540
|
+
});
|
|
19541
|
+
}
|
|
19542
|
+
if (visibilityRatio >= threshold) {
|
|
19543
|
+
element.setAttribute('data-scroll-triggered', 'true');
|
|
19544
|
+
const eventName = element.getAttribute('data-track-scroll');
|
|
19545
|
+
if (!eventName)
|
|
19546
|
+
return;
|
|
19547
|
+
const metadata = this.extractMetadata(element);
|
|
19548
|
+
this.trackEvent(eventName, {
|
|
19549
|
+
type: 'scroll',
|
|
19550
|
+
element: element.tagName.toLowerCase(),
|
|
19551
|
+
threshold,
|
|
19552
|
+
scrollDepth: window.scrollY,
|
|
19553
|
+
visibilityRatio: Math.round(visibilityRatio * 100) / 100,
|
|
19554
|
+
...metadata,
|
|
19555
|
+
});
|
|
19556
|
+
if (this.config.debug) {
|
|
19557
|
+
console.log(`[AutoTracker] Scroll tracked via delegation: ${eventName}`, {
|
|
19558
|
+
threshold,
|
|
19559
|
+
visibilityRatio,
|
|
19560
|
+
scrollDepth: window.scrollY,
|
|
19561
|
+
...metadata
|
|
19562
|
+
});
|
|
19563
|
+
}
|
|
19422
19564
|
}
|
|
19423
|
-
this.observedElements.clear();
|
|
19424
19565
|
}
|
|
19425
19566
|
/**
|
|
19426
|
-
*
|
|
19567
|
+
* Setup intelligent mutation observer (debounced for performance)
|
|
19427
19568
|
*/
|
|
19428
|
-
|
|
19429
|
-
|
|
19430
|
-
|
|
19431
|
-
|
|
19569
|
+
setupIntelligentMutationObserver() {
|
|
19570
|
+
if (this.mutationObserver)
|
|
19571
|
+
return; // Already setup
|
|
19572
|
+
const debouncedCallback = this.debounce((mutations) => {
|
|
19573
|
+
let hasRelevantChanges = false;
|
|
19574
|
+
mutations.forEach(mutation => {
|
|
19575
|
+
mutation.addedNodes.forEach(node => {
|
|
19432
19576
|
if (node.nodeType === Node.ELEMENT_NODE) {
|
|
19433
|
-
|
|
19577
|
+
const element = node;
|
|
19578
|
+
if (this.hasTrackingAttributes(element) || this.hasTrackingDescendants(element)) {
|
|
19579
|
+
hasRelevantChanges = true;
|
|
19580
|
+
if (this.config.debug) {
|
|
19581
|
+
console.log('[AutoTracker] New trackable element detected via mutation observer:', element);
|
|
19582
|
+
}
|
|
19583
|
+
}
|
|
19434
19584
|
}
|
|
19435
19585
|
});
|
|
19436
19586
|
});
|
|
19437
|
-
|
|
19438
|
-
|
|
19587
|
+
if (hasRelevantChanges) {
|
|
19588
|
+
if (this.config.debug) {
|
|
19589
|
+
console.log('[AutoTracker] Processing new elements from mutations...');
|
|
19590
|
+
}
|
|
19591
|
+
// Process elements for view tracking (only thing that needs setup)
|
|
19592
|
+
this.processExistingElements();
|
|
19593
|
+
}
|
|
19594
|
+
}, 150);
|
|
19595
|
+
this.mutationObserver = new MutationObserver(debouncedCallback);
|
|
19596
|
+
this.mutationObserver.observe(document.body, {
|
|
19439
19597
|
childList: true,
|
|
19440
19598
|
subtree: true,
|
|
19441
19599
|
});
|
|
19600
|
+
if (this.config.debug) {
|
|
19601
|
+
console.log('[AutoTracker] Intelligent mutation observer setup complete');
|
|
19602
|
+
}
|
|
19603
|
+
}
|
|
19604
|
+
/**
|
|
19605
|
+
* Check if element has tracking attributes
|
|
19606
|
+
*/
|
|
19607
|
+
hasTrackingAttributes(element) {
|
|
19608
|
+
return element.hasAttribute && (element.hasAttribute('data-track-click') ||
|
|
19609
|
+
element.hasAttribute('data-track-scroll') ||
|
|
19610
|
+
element.hasAttribute('data-track-view') ||
|
|
19611
|
+
element.hasAttribute('data-track-hover') ||
|
|
19612
|
+
element.hasAttribute('data-track-form'));
|
|
19613
|
+
}
|
|
19614
|
+
/**
|
|
19615
|
+
* Check if element has tracking descendants
|
|
19616
|
+
*/
|
|
19617
|
+
hasTrackingDescendants(element) {
|
|
19618
|
+
if (!element.querySelector)
|
|
19619
|
+
return false;
|
|
19620
|
+
return !!(element.querySelector('[data-track-click]') ||
|
|
19621
|
+
element.querySelector('[data-track-scroll]') ||
|
|
19622
|
+
element.querySelector('[data-track-view]') ||
|
|
19623
|
+
element.querySelector('[data-track-hover]') ||
|
|
19624
|
+
element.querySelector('[data-track-form]'));
|
|
19625
|
+
}
|
|
19626
|
+
/**
|
|
19627
|
+
* Utility: Debounce function for performance optimization
|
|
19628
|
+
*/
|
|
19629
|
+
debounce(func, wait) {
|
|
19630
|
+
let timeout;
|
|
19631
|
+
return (...args) => {
|
|
19632
|
+
clearTimeout(timeout);
|
|
19633
|
+
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
19634
|
+
};
|
|
19635
|
+
}
|
|
19636
|
+
/**
|
|
19637
|
+
* Parar auto tracking (with proper cleanup)
|
|
19638
|
+
*/
|
|
19639
|
+
stop() {
|
|
19640
|
+
if (this.config.debug) {
|
|
19641
|
+
console.log('[AutoTracker] Stopping auto tracking and cleaning up...');
|
|
19642
|
+
}
|
|
19643
|
+
// Remove delegation handlers
|
|
19644
|
+
this.delegationHandlers.forEach((handler, eventType) => {
|
|
19645
|
+
document.removeEventListener(eventType, handler);
|
|
19646
|
+
});
|
|
19647
|
+
this.delegationHandlers.clear();
|
|
19648
|
+
// Disconnect observers
|
|
19649
|
+
if (this.intersectionObserver) {
|
|
19650
|
+
this.intersectionObserver.disconnect();
|
|
19651
|
+
this.intersectionObserver = undefined;
|
|
19652
|
+
}
|
|
19653
|
+
if (this.mutationObserver) {
|
|
19654
|
+
this.mutationObserver.disconnect();
|
|
19655
|
+
this.mutationObserver = undefined;
|
|
19656
|
+
}
|
|
19657
|
+
// Clear caches
|
|
19658
|
+
this.observedElements.clear();
|
|
19659
|
+
this.isInitialized = false;
|
|
19660
|
+
}
|
|
19661
|
+
/**
|
|
19662
|
+
* Legacy method - now handled by intelligent mutation observer
|
|
19663
|
+
* @deprecated Use setupIntelligentMutationObserver instead
|
|
19664
|
+
*/
|
|
19665
|
+
observeDOM() {
|
|
19666
|
+
// This is now handled by setupIntelligentMutationObserver in setupEventDelegation
|
|
19667
|
+
if (this.config.debug) {
|
|
19668
|
+
console.log('[AutoTracker] observeDOM() is deprecated - using intelligent mutation observer');
|
|
19669
|
+
}
|
|
19442
19670
|
}
|
|
19443
19671
|
/**
|
|
19444
19672
|
* Processar elementos já existentes no DOM
|
|
@@ -19626,15 +19854,35 @@ class AutoTracker {
|
|
|
19626
19854
|
* Enviar evento para o SDK
|
|
19627
19855
|
*/
|
|
19628
19856
|
trackEvent(eventName, metadata) {
|
|
19629
|
-
if (
|
|
19857
|
+
if (this.config.debug) {
|
|
19858
|
+
console.log("[AutoTracker] trackEvent called:", { eventName, metadata });
|
|
19859
|
+
}
|
|
19860
|
+
if (!this.sdkInstance) {
|
|
19861
|
+
if (this.config.debug) {
|
|
19862
|
+
console.error("[AutoTracker] SDK instance is null!");
|
|
19863
|
+
}
|
|
19864
|
+
return;
|
|
19865
|
+
}
|
|
19866
|
+
if (typeof this.sdkInstance.trackCustomEvent !== 'function') {
|
|
19867
|
+
if (this.config.debug) {
|
|
19868
|
+
console.error("[AutoTracker] trackCustomEvent is not a function:", typeof this.sdkInstance.trackCustomEvent);
|
|
19869
|
+
}
|
|
19630
19870
|
return;
|
|
19871
|
+
}
|
|
19631
19872
|
try {
|
|
19632
|
-
|
|
19873
|
+
const eventData = {
|
|
19633
19874
|
autoTracked: true,
|
|
19634
19875
|
timestamp: Date.now(),
|
|
19635
19876
|
url: window.location.href,
|
|
19636
19877
|
...metadata,
|
|
19637
|
-
}
|
|
19878
|
+
};
|
|
19879
|
+
if (this.config.debug) {
|
|
19880
|
+
console.log("[AutoTracker] Calling trackCustomEvent:", { eventName, eventData });
|
|
19881
|
+
}
|
|
19882
|
+
const result = this.sdkInstance.trackCustomEvent(eventName, eventData);
|
|
19883
|
+
if (this.config.debug) {
|
|
19884
|
+
console.log("[AutoTracker] trackCustomEvent result:", result);
|
|
19885
|
+
}
|
|
19638
19886
|
}
|
|
19639
19887
|
catch (error) {
|
|
19640
19888
|
if (this.config.debug) {
|
|
@@ -19642,6 +19890,55 @@ class AutoTracker {
|
|
|
19642
19890
|
}
|
|
19643
19891
|
}
|
|
19644
19892
|
}
|
|
19893
|
+
/**
|
|
19894
|
+
* Modern API: Refresh tracking for dynamic content (React/SPA support)
|
|
19895
|
+
* Industry best practice for SPA route changes
|
|
19896
|
+
*/
|
|
19897
|
+
refreshTracking() {
|
|
19898
|
+
if (!this.isInitialized) {
|
|
19899
|
+
if (this.config.debug) {
|
|
19900
|
+
console.log('[AutoTracker] Not initialized, cannot refresh tracking');
|
|
19901
|
+
}
|
|
19902
|
+
return;
|
|
19903
|
+
}
|
|
19904
|
+
if (this.config.debug) {
|
|
19905
|
+
console.log('[AutoTracker] Refreshing tracking for dynamic content...');
|
|
19906
|
+
}
|
|
19907
|
+
// Re-process elements for view tracking (only thing that needs setup)
|
|
19908
|
+
this.processExistingElements();
|
|
19909
|
+
// Log current state
|
|
19910
|
+
if (this.config.debug) {
|
|
19911
|
+
this.logFoundElements();
|
|
19912
|
+
}
|
|
19913
|
+
}
|
|
19914
|
+
/**
|
|
19915
|
+
* Legacy method - use refreshTracking() instead
|
|
19916
|
+
* @deprecated Use refreshTracking() for better performance
|
|
19917
|
+
*/
|
|
19918
|
+
rescan() {
|
|
19919
|
+
this.refreshTracking();
|
|
19920
|
+
}
|
|
19921
|
+
/**
|
|
19922
|
+
* Get diagnostic information for debugging
|
|
19923
|
+
*/
|
|
19924
|
+
getDiagnostics() {
|
|
19925
|
+
return {
|
|
19926
|
+
isInitialized: this.isInitialized,
|
|
19927
|
+
hasClickHandler: this.delegationHandlers.has('click'),
|
|
19928
|
+
hasScrollHandler: this.delegationHandlers.has('scroll'),
|
|
19929
|
+
observedElements: this.observedElements.size,
|
|
19930
|
+
hasMutationObserver: !!this.mutationObserver,
|
|
19931
|
+
hasIntersectionObserver: !!this.intersectionObserver,
|
|
19932
|
+
config: this.config,
|
|
19933
|
+
elementsFound: {
|
|
19934
|
+
click: document.querySelectorAll('[data-track-click]').length,
|
|
19935
|
+
scroll: document.querySelectorAll('[data-track-scroll]').length,
|
|
19936
|
+
view: document.querySelectorAll('[data-track-view]').length,
|
|
19937
|
+
hover: document.querySelectorAll('[data-track-hover]').length,
|
|
19938
|
+
form: document.querySelectorAll('[data-track-form]').length
|
|
19939
|
+
}
|
|
19940
|
+
};
|
|
19941
|
+
}
|
|
19645
19942
|
/**
|
|
19646
19943
|
* Configurar tracking
|
|
19647
19944
|
*/
|
|
@@ -19649,12 +19946,14 @@ class AutoTracker {
|
|
|
19649
19946
|
this.config = { ...this.config, ...config };
|
|
19650
19947
|
}
|
|
19651
19948
|
/**
|
|
19652
|
-
*
|
|
19949
|
+
* Enhanced stats with diagnostic information
|
|
19653
19950
|
*/
|
|
19654
19951
|
getStats() {
|
|
19655
19952
|
return {
|
|
19656
19953
|
observedElements: this.observedElements.size,
|
|
19657
19954
|
config: this.config,
|
|
19955
|
+
isModern: this.isInitialized, // Indicates if using new delegation system
|
|
19956
|
+
diagnostics: this.config.debug ? this.getDiagnostics() : undefined
|
|
19658
19957
|
};
|
|
19659
19958
|
}
|
|
19660
19959
|
}
|
|
@@ -20203,6 +20502,36 @@ class ZaplierSDK {
|
|
|
20203
20502
|
console.log("[Zaplier] Auto tracking configured:", config);
|
|
20204
20503
|
}
|
|
20205
20504
|
},
|
|
20505
|
+
/**
|
|
20506
|
+
* Refresh tracking for dynamic content (React/SPA route changes)
|
|
20507
|
+
* Modern alternative to rescan() - follows GA4/industry best practices
|
|
20508
|
+
*/
|
|
20509
|
+
refreshTracking: () => {
|
|
20510
|
+
if (this.autoTracker) {
|
|
20511
|
+
this.autoTracker.refreshTracking();
|
|
20512
|
+
}
|
|
20513
|
+
if (this.config.debug) {
|
|
20514
|
+
console.log("[Zaplier] Auto tracking refreshed");
|
|
20515
|
+
}
|
|
20516
|
+
},
|
|
20517
|
+
/**
|
|
20518
|
+
* Legacy rescan method - use refreshTracking() instead
|
|
20519
|
+
* @deprecated Use refreshTracking() for better performance
|
|
20520
|
+
*/
|
|
20521
|
+
rescan: () => {
|
|
20522
|
+
if (this.autoTracker) {
|
|
20523
|
+
this.autoTracker.rescan();
|
|
20524
|
+
}
|
|
20525
|
+
if (this.config.debug) {
|
|
20526
|
+
console.log("[Zaplier] Auto tracking rescanned (deprecated - use refreshTracking)");
|
|
20527
|
+
}
|
|
20528
|
+
},
|
|
20529
|
+
/**
|
|
20530
|
+
* Get diagnostic information for debugging
|
|
20531
|
+
*/
|
|
20532
|
+
getDiagnostics: () => {
|
|
20533
|
+
return this.autoTracker ? this.autoTracker.getDiagnostics() : null;
|
|
20534
|
+
},
|
|
20206
20535
|
getStats: () => {
|
|
20207
20536
|
return this.autoTracker ? this.autoTracker.getStats() : null;
|
|
20208
20537
|
},
|