@zaplier/sdk 1.4.1 → 1.6.1

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/sdk.js CHANGED
@@ -19018,14 +19018,20 @@
19018
19018
  * Based on official rrweb example for maximum compatibility
19019
19019
  */
19020
19020
  class SessionReplayEngine {
19021
- constructor(sessionId, config = {}) {
19021
+ constructor(sessionId, visitorId, config = {}) {
19022
19022
  this.events = [];
19023
19023
  this.isActive = false;
19024
+ this.isPaused = false;
19025
+ this.lastActivityTime = Date.now();
19026
+ this.sessionStartTime = Date.now();
19024
19027
  this.sessionId = sessionId;
19028
+ this.visitorId = visitorId;
19025
19029
  this.config = {
19026
19030
  enabled: true,
19027
19031
  sampleRate: 1.0,
19028
19032
  batchInterval: 10000, // 10 seconds like official example
19033
+ inactivityTimeout: 30000, // 30 seconds of inactivity
19034
+ pauseOnInactive: true, // Pause recording during inactivity
19029
19035
  ...config,
19030
19036
  };
19031
19037
  }
@@ -19044,21 +19050,18 @@
19044
19050
  // Simple rrweb recording configuration like official example
19045
19051
  this.rrwebStopRecord = record({
19046
19052
  emit: (event) => {
19047
- // CRITICAL: Ensure FullSnapshot is always first event
19048
- if (this.events.length === 0 && event.type !== 2) {
19049
- console.warn(`[Zaplier] First event is type ${event.type}, not FullSnapshot (2). Skipping until FullSnapshot.`);
19050
- return; // Skip non-FullSnapshot events if no FullSnapshot captured yet
19051
- }
19052
- // Simple event capture
19053
- this.events.push(event);
19054
- if (event.type === 2) {
19055
- console.log(`[Zaplier] ✅ FullSnapshot captured as event #${this.events.length}`);
19053
+ // Update activity time on any event
19054
+ this.onActivity();
19055
+ // Only capture events if not paused
19056
+ if (!this.isPaused) {
19057
+ this.events.push(event);
19056
19058
  }
19057
19059
  },
19058
19060
  });
19059
19061
  this.isActive = true;
19060
19062
  this.startBatchTimer();
19061
- console.log("[Zaplier] Session replay started - simple mode");
19063
+ this.startInactivityTracking();
19064
+ console.log("[Zaplier] Session replay started - with inactivity detection");
19062
19065
  return true;
19063
19066
  }
19064
19067
  catch (error) {
@@ -19082,6 +19085,10 @@
19082
19085
  clearInterval(this.batchTimer);
19083
19086
  this.batchTimer = undefined;
19084
19087
  }
19088
+ if (this.inactivityTimer) {
19089
+ clearTimeout(this.inactivityTimer);
19090
+ this.inactivityTimer = undefined;
19091
+ }
19085
19092
  // Send final batch
19086
19093
  this.sendBatch();
19087
19094
  }
@@ -19100,17 +19107,21 @@
19100
19107
  if (this.events.length === 0) {
19101
19108
  return;
19102
19109
  }
19103
- // Simple payload structure like official example
19110
+ // Enhanced payload structure with visitor linking
19104
19111
  const payload = {
19105
19112
  sessionId: this.sessionId,
19113
+ visitorId: this.visitorId,
19106
19114
  events: [...this.events], // Copy events array
19107
19115
  metadata: {
19108
19116
  userAgent: navigator.userAgent,
19109
19117
  timestamp: Date.now(),
19110
19118
  startUrl: window.location.href,
19111
- duration: Date.now() - (performance.timeOrigin || Date.now()),
19119
+ duration: Date.now() - this.sessionStartTime,
19120
+ activeTime: this.getActiveTime(),
19112
19121
  funnelSteps: [],
19113
19122
  hasConversion: false,
19123
+ eventsCount: this.events.length,
19124
+ isPaused: this.isPaused,
19114
19125
  },
19115
19126
  };
19116
19127
  // Reset events array like official example
@@ -19159,6 +19170,448 @@
19159
19170
  isRecording() {
19160
19171
  return this.isActive;
19161
19172
  }
19173
+ /**
19174
+ * Check if recording is paused
19175
+ */
19176
+ isPausedState() {
19177
+ return this.isPaused;
19178
+ }
19179
+ /**
19180
+ * Start inactivity tracking
19181
+ */
19182
+ startInactivityTracking() {
19183
+ if (!this.config.pauseOnInactive)
19184
+ return;
19185
+ // Listen for user activity events
19186
+ const activityEvents = ['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart', 'click'];
19187
+ activityEvents.forEach(event => {
19188
+ document.addEventListener(event, this.onActivity.bind(this), true);
19189
+ });
19190
+ this.resetInactivityTimer();
19191
+ }
19192
+ /**
19193
+ * Handle activity event
19194
+ */
19195
+ onActivity() {
19196
+ this.lastActivityTime = Date.now();
19197
+ // Resume if paused
19198
+ if (this.isPaused) {
19199
+ this.resume();
19200
+ }
19201
+ this.resetInactivityTimer();
19202
+ }
19203
+ /**
19204
+ * Reset inactivity timer
19205
+ */
19206
+ resetInactivityTimer() {
19207
+ if (this.inactivityTimer) {
19208
+ clearTimeout(this.inactivityTimer);
19209
+ }
19210
+ this.inactivityTimer = window.setTimeout(() => {
19211
+ this.pauseForInactivity();
19212
+ }, this.config.inactivityTimeout);
19213
+ }
19214
+ /**
19215
+ * Pause recording due to inactivity
19216
+ */
19217
+ pauseForInactivity() {
19218
+ if (this.isPaused)
19219
+ return;
19220
+ this.isPaused = true;
19221
+ console.log("[Zaplier] Session replay paused due to inactivity");
19222
+ }
19223
+ /**
19224
+ * Resume recording after activity
19225
+ */
19226
+ resume() {
19227
+ if (!this.isPaused)
19228
+ return;
19229
+ this.isPaused = false;
19230
+ console.log("[Zaplier] Session replay resumed after activity");
19231
+ }
19232
+ /**
19233
+ * Get total active time (excluding paused periods)
19234
+ */
19235
+ getActiveTime() {
19236
+ const totalTime = Date.now() - this.sessionStartTime;
19237
+ // For now, return total time. In production, track pause periods accurately
19238
+ return totalTime;
19239
+ }
19240
+ /**
19241
+ * Get visitor ID
19242
+ */
19243
+ getVisitorId() {
19244
+ return this.visitorId;
19245
+ }
19246
+ }
19247
+
19248
+ /**
19249
+ * Auto Tracker - Sistema de tracking automático via data-* attributes
19250
+ *
19251
+ * Suporta:
19252
+ * - data-track-click="event-name"
19253
+ * - data-track-scroll="event-name"
19254
+ * - data-track-view="event-name"
19255
+ * - data-track-hover="event-name"
19256
+ * - data-track-form="event-name"
19257
+ */
19258
+ class AutoTracker {
19259
+ constructor(sdkInstance, config = {}) {
19260
+ this.observedElements = new Set();
19261
+ /**
19262
+ * Event handlers (bound to this)
19263
+ */
19264
+ this.handleClick = (event) => {
19265
+ const target = event.target;
19266
+ if (target.hasAttribute("data-track-click")) ;
19267
+ };
19268
+ this.handleScroll = () => {
19269
+ // Scroll is handled by element-specific listeners
19270
+ };
19271
+ this.handleHover = (event) => {
19272
+ // Hover is handled by element-specific listeners
19273
+ };
19274
+ this.handleForm = (event) => {
19275
+ // Form is handled by element-specific listeners
19276
+ };
19277
+ this.sdkInstance = sdkInstance;
19278
+ this.config = {
19279
+ enabled: true,
19280
+ trackClicks: true,
19281
+ trackScrolls: true,
19282
+ trackViews: true,
19283
+ trackHovers: true,
19284
+ trackForms: true,
19285
+ debug: false,
19286
+ ...config,
19287
+ };
19288
+ }
19289
+ /**
19290
+ * Inicializar auto tracking
19291
+ */
19292
+ start() {
19293
+ if (!this.config.enabled)
19294
+ return;
19295
+ if (this.config.debug) {
19296
+ console.log("[Zaplier AutoTracker] Iniciando auto tracking");
19297
+ }
19298
+ // Observer para novos elementos no DOM
19299
+ this.observeDOM();
19300
+ // Processar elementos já existentes
19301
+ this.processExistingElements();
19302
+ // Setup intersection observer para views
19303
+ if (this.config.trackViews) {
19304
+ this.setupViewTracking();
19305
+ }
19306
+ }
19307
+ /**
19308
+ * Parar auto tracking
19309
+ */
19310
+ stop() {
19311
+ document.removeEventListener("click", this.handleClick);
19312
+ document.removeEventListener("scroll", this.handleScroll);
19313
+ document.removeEventListener("mouseover", this.handleHover);
19314
+ document.removeEventListener("submit", this.handleForm);
19315
+ if (this.intersectionObserver) {
19316
+ this.intersectionObserver.disconnect();
19317
+ }
19318
+ this.observedElements.clear();
19319
+ }
19320
+ /**
19321
+ * Observar mudanças no DOM para novos elementos
19322
+ */
19323
+ observeDOM() {
19324
+ const observer = new MutationObserver((mutations) => {
19325
+ mutations.forEach((mutation) => {
19326
+ mutation.addedNodes.forEach((node) => {
19327
+ if (node.nodeType === Node.ELEMENT_NODE) {
19328
+ this.processElement(node);
19329
+ }
19330
+ });
19331
+ });
19332
+ });
19333
+ observer.observe(document.body, {
19334
+ childList: true,
19335
+ subtree: true,
19336
+ });
19337
+ }
19338
+ /**
19339
+ * Processar elementos já existentes no DOM
19340
+ */
19341
+ processExistingElements() {
19342
+ // Buscar todos os elementos com data-track-*
19343
+ const trackElements = document.querySelectorAll("[data-track-click], [data-track-scroll], [data-track-view], [data-track-hover], [data-track-form]");
19344
+ trackElements.forEach((element) => {
19345
+ this.processElement(element);
19346
+ });
19347
+ }
19348
+ /**
19349
+ * Processar um elemento específico
19350
+ */
19351
+ processElement(element) {
19352
+ // Click tracking
19353
+ if (this.config.trackClicks && element.hasAttribute("data-track-click")) {
19354
+ this.setupClickTracking(element);
19355
+ }
19356
+ // Scroll tracking
19357
+ if (this.config.trackScrolls && element.hasAttribute("data-track-scroll")) {
19358
+ this.setupScrollTracking(element);
19359
+ }
19360
+ // View tracking
19361
+ if (this.config.trackViews && element.hasAttribute("data-track-view")) {
19362
+ this.setupElementViewTracking(element);
19363
+ }
19364
+ // Hover tracking
19365
+ if (this.config.trackHovers && element.hasAttribute("data-track-hover")) {
19366
+ this.setupHoverTracking(element);
19367
+ }
19368
+ // Form tracking
19369
+ if (this.config.trackForms && element.hasAttribute("data-track-form")) {
19370
+ this.setupFormTracking(element);
19371
+ }
19372
+ }
19373
+ /**
19374
+ * Setup click tracking
19375
+ */
19376
+ setupClickTracking(element) {
19377
+ element.addEventListener("click", (event) => {
19378
+ const eventName = element.getAttribute("data-track-click");
19379
+ if (!eventName)
19380
+ return;
19381
+ const metadata = this.extractMetadata(element);
19382
+ this.trackEvent(eventName, {
19383
+ type: "click",
19384
+ element: element.tagName.toLowerCase(),
19385
+ ...metadata,
19386
+ });
19387
+ if (this.config.debug) {
19388
+ console.log(`[AutoTracker] Click tracked: ${eventName}`, metadata);
19389
+ }
19390
+ });
19391
+ }
19392
+ /**
19393
+ * Setup scroll tracking
19394
+ */
19395
+ setupScrollTracking(element) {
19396
+ let hasTriggered = false;
19397
+ const threshold = parseFloat(element.getAttribute("data-scroll-threshold") || "0.5");
19398
+ const handleScroll = () => {
19399
+ if (hasTriggered)
19400
+ return;
19401
+ const rect = element.getBoundingClientRect();
19402
+ const elementHeight = rect.height;
19403
+ const visibleHeight = Math.min(rect.bottom, window.innerHeight) - Math.max(rect.top, 0);
19404
+ const visibilityRatio = Math.max(0, visibleHeight) / elementHeight;
19405
+ if (visibilityRatio >= threshold) {
19406
+ hasTriggered = true;
19407
+ const eventName = element.getAttribute("data-track-scroll");
19408
+ if (!eventName)
19409
+ return;
19410
+ const metadata = this.extractMetadata(element);
19411
+ this.trackEvent(eventName, {
19412
+ type: "scroll",
19413
+ element: element.tagName.toLowerCase(),
19414
+ threshold,
19415
+ scrollDepth: window.scrollY,
19416
+ ...metadata,
19417
+ });
19418
+ if (this.config.debug) {
19419
+ console.log(`[AutoTracker] Scroll tracked: ${eventName}`, metadata);
19420
+ }
19421
+ }
19422
+ };
19423
+ document.addEventListener("scroll", handleScroll, { passive: true });
19424
+ // Check immediately in case element is already in view
19425
+ setTimeout(handleScroll, 100);
19426
+ }
19427
+ /**
19428
+ * Setup view tracking usando Intersection Observer
19429
+ */
19430
+ setupViewTracking() {
19431
+ this.intersectionObserver = new IntersectionObserver((entries) => {
19432
+ entries.forEach((entry) => {
19433
+ if (entry.isIntersecting) {
19434
+ const element = entry.target;
19435
+ const eventName = element.getAttribute("data-track-view");
19436
+ if (!eventName)
19437
+ return;
19438
+ const metadata = this.extractMetadata(element);
19439
+ this.trackEvent(eventName, {
19440
+ type: "view",
19441
+ element: element.tagName.toLowerCase(),
19442
+ intersectionRatio: entry.intersectionRatio,
19443
+ ...metadata,
19444
+ });
19445
+ if (this.config.debug) {
19446
+ console.log(`[AutoTracker] View tracked: ${eventName}`, metadata);
19447
+ }
19448
+ // Remove from observation after first trigger
19449
+ this.intersectionObserver?.unobserve(element);
19450
+ }
19451
+ });
19452
+ }, {
19453
+ threshold: 0.5, // 50% visible
19454
+ rootMargin: "0px",
19455
+ });
19456
+ }
19457
+ /**
19458
+ * Setup view tracking para elemento específico
19459
+ */
19460
+ setupElementViewTracking(element) {
19461
+ if (!this.intersectionObserver)
19462
+ return;
19463
+ if (!this.observedElements.has(element)) {
19464
+ this.intersectionObserver.observe(element);
19465
+ this.observedElements.add(element);
19466
+ }
19467
+ }
19468
+ /**
19469
+ * Setup hover tracking
19470
+ */
19471
+ setupHoverTracking(element) {
19472
+ let hoverStartTime;
19473
+ const minHoverTime = parseInt(element.getAttribute("data-hover-time") || "1000");
19474
+ element.addEventListener("mouseenter", () => {
19475
+ hoverStartTime = Date.now();
19476
+ });
19477
+ element.addEventListener("mouseleave", () => {
19478
+ const hoverDuration = Date.now() - hoverStartTime;
19479
+ if (hoverDuration >= minHoverTime) {
19480
+ const eventName = element.getAttribute("data-track-hover");
19481
+ if (!eventName)
19482
+ return;
19483
+ const metadata = this.extractMetadata(element);
19484
+ this.trackEvent(eventName, {
19485
+ type: "hover",
19486
+ element: element.tagName.toLowerCase(),
19487
+ hoverDuration,
19488
+ minHoverTime,
19489
+ ...metadata,
19490
+ });
19491
+ if (this.config.debug) {
19492
+ console.log(`[AutoTracker] Hover tracked: ${eventName}`, metadata);
19493
+ }
19494
+ }
19495
+ });
19496
+ }
19497
+ /**
19498
+ * Setup form tracking
19499
+ */
19500
+ setupFormTracking(element) {
19501
+ if (element.tagName.toLowerCase() !== "form")
19502
+ return;
19503
+ element.addEventListener("submit", (event) => {
19504
+ const eventName = element.getAttribute("data-track-form");
19505
+ if (!eventName)
19506
+ return;
19507
+ const formData = new FormData(element);
19508
+ const metadata = this.extractMetadata(element);
19509
+ // Extract form fields (without sensitive data)
19510
+ const fields = {};
19511
+ for (const [key, value] of formData.entries()) {
19512
+ // Skip sensitive fields
19513
+ if (!this.isSensitiveField(key)) {
19514
+ fields[key] =
19515
+ typeof value === "string" ? value.substring(0, 100) : "file";
19516
+ }
19517
+ }
19518
+ this.trackEvent(eventName, {
19519
+ type: "form_submit",
19520
+ element: "form",
19521
+ fieldCount: Array.from(formData.entries()).length,
19522
+ fields,
19523
+ ...metadata,
19524
+ });
19525
+ if (this.config.debug) {
19526
+ console.log(`[AutoTracker] Form submit tracked: ${eventName}`, metadata);
19527
+ }
19528
+ });
19529
+ }
19530
+ /**
19531
+ * Extrair metadata do elemento
19532
+ */
19533
+ extractMetadata(element) {
19534
+ const metadata = {};
19535
+ // Extrair todos os data-meta-* attributes
19536
+ Array.from(element.attributes).forEach((attr) => {
19537
+ if (attr.name.startsWith("data-meta-")) {
19538
+ const key = attr.name.replace("data-meta-", "");
19539
+ metadata[key] = attr.value;
19540
+ }
19541
+ });
19542
+ // Adicionar informações básicas
19543
+ if (element.id)
19544
+ metadata.elementId = element.id;
19545
+ if (element.className)
19546
+ metadata.elementClass = element.className;
19547
+ // Text content (limitado)
19548
+ const textContent = element.textContent?.trim();
19549
+ if (textContent && textContent.length > 0) {
19550
+ metadata.textContent = textContent.substring(0, 50);
19551
+ }
19552
+ // Position info
19553
+ const rect = element.getBoundingClientRect();
19554
+ metadata.elementPosition = {
19555
+ x: Math.round(rect.left),
19556
+ y: Math.round(rect.top),
19557
+ width: Math.round(rect.width),
19558
+ height: Math.round(rect.height),
19559
+ };
19560
+ return metadata;
19561
+ }
19562
+ /**
19563
+ * Verificar se um campo é sensível
19564
+ */
19565
+ isSensitiveField(fieldName) {
19566
+ const sensitivePatterns = [
19567
+ /password/i,
19568
+ /pass/i,
19569
+ /pwd/i,
19570
+ /secret/i,
19571
+ /token/i,
19572
+ /api[_-]?key/i,
19573
+ /credit[_-]?card/i,
19574
+ /ssn/i,
19575
+ /social/i,
19576
+ /tax/i,
19577
+ ];
19578
+ return sensitivePatterns.some((pattern) => pattern.test(fieldName));
19579
+ }
19580
+ /**
19581
+ * Enviar evento para o SDK
19582
+ */
19583
+ trackEvent(eventName, metadata) {
19584
+ if (!this.sdkInstance)
19585
+ return;
19586
+ try {
19587
+ this.sdkInstance.trackCustomEvent(eventName, {
19588
+ autoTracked: true,
19589
+ timestamp: Date.now(),
19590
+ url: window.location.href,
19591
+ ...metadata,
19592
+ });
19593
+ }
19594
+ catch (error) {
19595
+ if (this.config.debug) {
19596
+ console.error("[AutoTracker] Error sending event:", error);
19597
+ }
19598
+ }
19599
+ }
19600
+ /**
19601
+ * Configurar tracking
19602
+ */
19603
+ configure(config) {
19604
+ this.config = { ...this.config, ...config };
19605
+ }
19606
+ /**
19607
+ * Obter estatísticas
19608
+ */
19609
+ getStats() {
19610
+ return {
19611
+ observedElements: this.observedElements.size,
19612
+ config: this.config,
19613
+ };
19614
+ }
19162
19615
  }
19163
19616
 
19164
19617
  /**
@@ -19192,7 +19645,7 @@
19192
19645
  */
19193
19646
  class ZaplierSDK {
19194
19647
  constructor(userConfig) {
19195
- this.version = "1.3.7";
19648
+ this.version = "1.6.0";
19196
19649
  this.isInitialized = false;
19197
19650
  this.eventQueue = [];
19198
19651
  /**
@@ -19263,8 +19716,10 @@
19263
19716
  }
19264
19717
  const sessionId = this.sessionId;
19265
19718
  // When explicitly enabled, use 100% sample rate
19266
- this.replayEngine = new SessionReplayEngine(sessionId, {
19719
+ this.replayEngine = new SessionReplayEngine(sessionId, this.backendVisitorId || 'unknown', {
19267
19720
  sampleRate: 1.0, // Force 100% when explicitly enabled
19721
+ inactivityTimeout: 30000,
19722
+ pauseOnInactive: true,
19268
19723
  });
19269
19724
  // Connect to anti-adblock manager
19270
19725
  if (this.antiAdblockManager) {
@@ -19289,8 +19744,10 @@
19289
19744
  this.sessionId = this.generateSessionId();
19290
19745
  }
19291
19746
  const sessionId = this.sessionId;
19292
- this.replayEngine = new SessionReplayEngine(sessionId, {
19747
+ this.replayEngine = new SessionReplayEngine(sessionId, this.backendVisitorId || 'unknown', {
19293
19748
  sampleRate: 1.0, // Force 100% when explicitly enabled
19749
+ inactivityTimeout: 30000,
19750
+ pauseOnInactive: true,
19294
19751
  });
19295
19752
  // Connect to anti-adblock manager
19296
19753
  if (this.antiAdblockManager) {
@@ -19329,8 +19786,10 @@
19329
19786
  this.sessionId = this.generateSessionId();
19330
19787
  }
19331
19788
  const sessionId = this.sessionId;
19332
- this.replayEngine = new SessionReplayEngine(sessionId, {
19789
+ this.replayEngine = new SessionReplayEngine(sessionId, this.backendVisitorId || 'unknown', {
19333
19790
  sampleRate: 1.0, // Force recording when manually started
19791
+ inactivityTimeout: 30000,
19792
+ pauseOnInactive: true,
19334
19793
  });
19335
19794
  // Connect to anti-adblock manager
19336
19795
  if (this.antiAdblockManager) {
@@ -19362,6 +19821,45 @@
19362
19821
  this.trackConversion("funnel_conversion", data.value, data.currency, data);
19363
19822
  },
19364
19823
  };
19824
+ /**
19825
+ * Auto Tracker API
19826
+ */
19827
+ this.autoTrack = {
19828
+ enable: () => {
19829
+ if (!this.autoTracker) {
19830
+ this.initializeAutoTracker();
19831
+ }
19832
+ else {
19833
+ this.autoTracker.configure({ enabled: true });
19834
+ }
19835
+ if (this.config.debug) {
19836
+ console.log("[Zaplier] Auto tracking enabled");
19837
+ }
19838
+ },
19839
+ disable: () => {
19840
+ if (this.autoTracker) {
19841
+ this.autoTracker.stop();
19842
+ this.autoTracker = undefined;
19843
+ }
19844
+ if (this.config.debug) {
19845
+ console.log("[Zaplier] Auto tracking disabled");
19846
+ }
19847
+ },
19848
+ configure: (config) => {
19849
+ if (this.autoTracker) {
19850
+ this.autoTracker.configure(config);
19851
+ }
19852
+ if (this.config.debug) {
19853
+ console.log("[Zaplier] Auto tracking configured:", config);
19854
+ }
19855
+ },
19856
+ getStats: () => {
19857
+ return this.autoTracker ? this.autoTracker.getStats() : null;
19858
+ },
19859
+ isEnabled: () => {
19860
+ return !!this.autoTracker;
19861
+ },
19862
+ };
19365
19863
  // Validate required config
19366
19864
  if (!userConfig.token) {
19367
19865
  throw new Error("Zaplier: token is required");
@@ -19403,6 +19901,8 @@
19403
19901
  this.initializeAntiAdblock();
19404
19902
  // Then initialize tracking engines (they'll connect to anti-adblock)
19405
19903
  this.initializeTrackingEngines();
19904
+ // Initialize auto tracker
19905
+ this.initializeAutoTracker();
19406
19906
  // Process queued events
19407
19907
  this.processEventQueue();
19408
19908
  if (this.config.debug) {
@@ -19433,8 +19933,10 @@
19433
19933
  // When replay is explicitly enabled, use 100% sample rate to ensure recording
19434
19934
  // The default replaySampling (0.1) is only for automatic/production sampling
19435
19935
  const sampleRate = this.config.replay === true ? 1.0 : this.config.replaySampling;
19436
- this.replayEngine = new SessionReplayEngine(this.sessionId, {
19936
+ this.replayEngine = new SessionReplayEngine(this.sessionId, this.backendVisitorId || 'unknown', {
19437
19937
  sampleRate: sampleRate,
19938
+ inactivityTimeout: 30000,
19939
+ pauseOnInactive: true,
19438
19940
  });
19439
19941
  // Connect SDK instance for transport
19440
19942
  this.replayEngine.setSDKInstance(this);
@@ -19469,6 +19971,29 @@
19469
19971
  console.error("[Zaplier] Failed to initialize tracking engines:", error);
19470
19972
  }
19471
19973
  }
19974
+ /**
19975
+ * Initialize Auto Tracker for data-* attributes
19976
+ */
19977
+ initializeAutoTracker() {
19978
+ try {
19979
+ this.autoTracker = new AutoTracker(this, {
19980
+ enabled: true,
19981
+ trackClicks: true,
19982
+ trackScrolls: true,
19983
+ trackViews: true,
19984
+ trackHovers: true,
19985
+ trackForms: true,
19986
+ debug: this.config.debug,
19987
+ });
19988
+ this.autoTracker.start();
19989
+ if (this.config.debug) {
19990
+ console.log("[Zaplier] Auto Tracker initialized and started");
19991
+ }
19992
+ }
19993
+ catch (error) {
19994
+ console.error("[Zaplier] Failed to initialize Auto Tracker:", error);
19995
+ }
19996
+ }
19472
19997
  /**
19473
19998
  * Generate session ID
19474
19999
  */
@@ -20411,6 +20936,44 @@
20411
20936
  globalInstance.replay.markConversion(data);
20412
20937
  }
20413
20938
  },
20939
+ /**
20940
+ * Auto Tracker API
20941
+ */
20942
+ autoTrack: {
20943
+ enable: () => {
20944
+ if (!globalInstance) {
20945
+ console.warn('[Zaplier] SDK not initialized. Call Zaplier.init() first');
20946
+ return;
20947
+ }
20948
+ globalInstance.autoTrack.enable();
20949
+ },
20950
+ disable: () => {
20951
+ if (!globalInstance) {
20952
+ console.warn('[Zaplier] SDK not initialized. Call Zaplier.init() first');
20953
+ return;
20954
+ }
20955
+ globalInstance.autoTrack.disable();
20956
+ },
20957
+ configure: (config) => {
20958
+ if (!globalInstance) {
20959
+ console.warn('[Zaplier] SDK not initialized. Call Zaplier.init() first');
20960
+ return;
20961
+ }
20962
+ globalInstance.autoTrack.configure(config);
20963
+ },
20964
+ getStats: () => {
20965
+ if (!globalInstance) {
20966
+ return null;
20967
+ }
20968
+ return globalInstance.autoTrack.getStats();
20969
+ },
20970
+ isEnabled: () => {
20971
+ if (!globalInstance) {
20972
+ return false;
20973
+ }
20974
+ return globalInstance.autoTrack.isEnabled();
20975
+ }
20976
+ },
20414
20977
  /**
20415
20978
  * Debug and utility functions
20416
20979
  */
@@ -20437,7 +21000,7 @@
20437
21000
  /**
20438
21001
  * Version info
20439
21002
  */
20440
- version: '3.0.0'
21003
+ version: '1.6.0'
20441
21004
  };
20442
21005
  /**
20443
21006
  * Auto-initialization from script tag data attributes