@devskin/browser-sdk 1.0.24 → 1.0.26

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.
@@ -13871,7 +13871,7 @@ class DevSkinSDK {
13871
13871
  * Initialize the DevSkin SDK
13872
13872
  */
13873
13873
  init(config) {
13874
- var _a, _b, _c, _d;
13874
+ var _a;
13875
13875
  if (this.initialized) {
13876
13876
  console.warn('[DevSkin] SDK already initialized');
13877
13877
  return;
@@ -13907,24 +13907,20 @@ class DevSkinSDK {
13907
13907
  this.networkCollector = new NetworkCollector(this.config, this.transport);
13908
13908
  this.networkCollector.start();
13909
13909
  }
13910
- // Initialize heatmap collector
13911
- // Auto-enable heatmap if session recording is enabled
13912
- const heatmapEnabled = ((_a = this.config.heatmapOptions) === null || _a === void 0 ? void 0 : _a.enabled) || ((_b = this.config.sessionRecording) === null || _b === void 0 ? void 0 : _b.enabled);
13913
- if (heatmapEnabled) {
13914
- // Merge default heatmap config with user config
13915
- const heatmapConfig = Object.assign({ enabled: true, trackClicks: true, trackScroll: true, trackMouseMovement: true, mouseMoveSampling: 0.05 }, this.config.heatmapOptions);
13916
- this.config.heatmapOptions = heatmapConfig;
13917
- this.heatmapCollector = new HeatmapCollector(this.config, this.transport);
13918
- this.heatmapCollector.start();
13919
- // Initialize screenshot collector and capture page
13920
- this.screenshotCollector = new ScreenshotCollector(this.config, this.transport);
13921
- this.screenshotCollector.captureAndSend(this.sessionId, window.location.href);
13922
- if (this.config.debug) {
13923
- console.log('[DevSkin] Heatmap collection enabled', ((_c = this.config.sessionRecording) === null || _c === void 0 ? void 0 : _c.enabled) ? '(auto-enabled with session recording)' : '');
13924
- }
13910
+ // Initialize heatmap collector - SEMPRE habilitado
13911
+ // Merge default heatmap config with user config
13912
+ const heatmapConfig = Object.assign({ enabled: true, trackClicks: true, trackScroll: true, trackMouseMovement: true, mouseMoveSampling: 0.1 }, this.config.heatmapOptions);
13913
+ this.config.heatmapOptions = heatmapConfig;
13914
+ this.heatmapCollector = new HeatmapCollector(this.config, this.transport);
13915
+ this.heatmapCollector.start();
13916
+ // Initialize screenshot collector and capture page
13917
+ this.screenshotCollector = new ScreenshotCollector(this.config, this.transport);
13918
+ this.screenshotCollector.captureAndSend(this.sessionId, window.location.href);
13919
+ if (this.config.debug) {
13920
+ console.log('[DevSkin] Heatmap collection enabled (always on)');
13925
13921
  }
13926
13922
  // Initialize session recording with rrweb
13927
- if ((_d = this.config.sessionRecording) === null || _d === void 0 ? void 0 : _d.enabled) {
13923
+ if ((_a = this.config.sessionRecording) === null || _a === void 0 ? void 0 : _a.enabled) {
13928
13924
  // Use RRWebRecorder for complete DOM recording
13929
13925
  this.rrwebRecorder = new RRWebRecorder(this.sessionId, {
13930
13926
  enabled: true,
@@ -14068,11 +14064,32 @@ class DevSkinSDK {
14068
14064
  * Private methods
14069
14065
  */
14070
14066
  startSession() {
14071
- var _a;
14067
+ var _a, _b, _c;
14068
+ // Check if there's an active session (stored in sessionStorage to persist across page navigations)
14069
+ const existingSessionId = sessionStorage.getItem('devskin_session_id');
14070
+ const existingSessionStart = sessionStorage.getItem('devskin_session_start');
14071
+ if (existingSessionId && existingSessionStart) {
14072
+ // Resume existing session
14073
+ this.sessionId = existingSessionId;
14074
+ this.sessionStartTime = parseInt(existingSessionStart, 10);
14075
+ if ((_a = this.config) === null || _a === void 0 ? void 0 : _a.debug) {
14076
+ console.log('[DevSkin] Resuming existing session:', this.sessionId);
14077
+ }
14078
+ // Send page view but DON'T create a new session
14079
+ // The session is already created, just continue it
14080
+ return;
14081
+ }
14082
+ // Create new session
14072
14083
  this.sessionId = this.generateId();
14073
14084
  this.sessionStartTime = Date.now();
14085
+ // Store in sessionStorage (persists across page navigations in same tab)
14086
+ sessionStorage.setItem('devskin_session_id', this.sessionId);
14087
+ sessionStorage.setItem('devskin_session_start', this.sessionStartTime.toString());
14074
14088
  const sessionData = Object.assign({ session_id: this.sessionId, user_id: this.userId || undefined, anonymous_id: this.anonymousId, started_at: new Date().toISOString() }, this.getContextData());
14075
- (_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(sessionData);
14089
+ (_b = this.transport) === null || _b === void 0 ? void 0 : _b.startSession(sessionData);
14090
+ if ((_c = this.config) === null || _c === void 0 ? void 0 : _c.debug) {
14091
+ console.log('[DevSkin] New session created:', this.sessionId);
14092
+ }
14076
14093
  }
14077
14094
  getContextData() {
14078
14095
  const context = {};
@@ -14109,16 +14126,26 @@ class DevSkinSDK {
14109
14126
  });
14110
14127
  }
14111
14128
  setupUnloadTracking() {
14112
- window.addEventListener('beforeunload', () => {
14129
+ // Use pagehide event which is more reliable than beforeunload
14130
+ window.addEventListener('pagehide', (event) => {
14113
14131
  var _a, _b;
14114
- this.track('page_unload');
14115
- // Send session end update with duration AND context data
14116
- if (this.sessionId && this.sessionStartTime) {
14117
- const endedAt = new Date();
14118
- const durationMs = Date.now() - this.sessionStartTime;
14119
- (_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(Object.assign({ session_id: this.sessionId, user_id: this.userId || undefined, anonymous_id: this.anonymousId, ended_at: endedAt.toISOString(), duration_ms: durationMs }, this.getContextData()));
14132
+ // Only end session if tab is actually closing (not just navigating)
14133
+ // persisted = false means the page is going into bfcache (navigation)
14134
+ // persisted = true OR event doesn't exist means actual close
14135
+ const isActualClose = !event.persisted;
14136
+ if (isActualClose) {
14137
+ this.track('page_unload');
14138
+ // Only send session end if tab is actually closing
14139
+ if (this.sessionId && this.sessionStartTime) {
14140
+ const endedAt = new Date();
14141
+ const durationMs = Date.now() - this.sessionStartTime;
14142
+ (_a = this.transport) === null || _a === void 0 ? void 0 : _a.startSession(Object.assign({ session_id: this.sessionId, user_id: this.userId || undefined, anonymous_id: this.anonymousId, ended_at: endedAt.toISOString(), duration_ms: durationMs }, this.getContextData()));
14143
+ // Clear session storage since session is ending
14144
+ sessionStorage.removeItem('devskin_session_id');
14145
+ sessionStorage.removeItem('devskin_session_start');
14146
+ }
14120
14147
  }
14121
- // Send any pending data
14148
+ // Always flush pending data (whether navigation or close)
14122
14149
  (_b = this.transport) === null || _b === void 0 ? void 0 : _b.flush(true); // Use beacon for reliability
14123
14150
  });
14124
14151
  }