humanbehavior-js 0.4.6 → 0.4.7

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.
@@ -34,6 +34,8 @@ declare class HumanBehaviorTracker {
34
34
  private _connectionBlocked;
35
35
  private recordInstance;
36
36
  private sessionStartTime;
37
+ private rrwebRecord;
38
+ private fullSnapshotTimeout;
37
39
  /**
38
40
  * Initialize the HumanBehavior tracker
39
41
  * This is the main entry point - call this once per page
@@ -117,6 +119,11 @@ declare class HumanBehaviorTracker {
117
119
  */
118
120
  getUserAttributes(): Record<string, any>;
119
121
  start(): Promise<void>;
122
+ /**
123
+ * Manually trigger a FullSnapshot (for navigation events)
124
+ * Delays snapshot to avoid capturing mid-animation states
125
+ */
126
+ private takeFullSnapshot;
120
127
  stop(): Promise<void>;
121
128
  /**
122
129
  * Add an event to the ingestion queue
@@ -124,6 +124,8 @@ declare class HumanBehaviorTracker {
124
124
  private _connectionBlocked;
125
125
  private recordInstance;
126
126
  private sessionStartTime;
127
+ private rrwebRecord;
128
+ private fullSnapshotTimeout;
127
129
  /**
128
130
  * Initialize the HumanBehavior tracker
129
131
  * This is the main entry point - call this once per page
@@ -207,6 +209,11 @@ declare class HumanBehaviorTracker {
207
209
  */
208
210
  getUserAttributes(): Record<string, any>;
209
211
  start(): Promise<void>;
212
+ /**
213
+ * Manually trigger a FullSnapshot (for navigation events)
214
+ * Delays snapshot to avoid capturing mid-animation states
215
+ */
216
+ private takeFullSnapshot;
210
217
  stop(): Promise<void>;
211
218
  /**
212
219
  * Add an event to the ingestion queue
@@ -36,6 +36,8 @@ declare class HumanBehaviorTracker {
36
36
  private _connectionBlocked;
37
37
  private recordInstance;
38
38
  private sessionStartTime;
39
+ private rrwebRecord;
40
+ private fullSnapshotTimeout;
39
41
  /**
40
42
  * Initialize the HumanBehavior tracker
41
43
  * This is the main entry point - call this once per page
@@ -119,6 +121,11 @@ declare class HumanBehaviorTracker {
119
121
  */
120
122
  getUserAttributes(): Record<string, any>;
121
123
  start(): Promise<void>;
124
+ /**
125
+ * Manually trigger a FullSnapshot (for navigation events)
126
+ * Delays snapshot to avoid capturing mid-animation states
127
+ */
128
+ private takeFullSnapshot;
122
129
  stop(): Promise<void>;
123
130
  /**
124
131
  * Add an event to the ingestion queue
@@ -37,6 +37,8 @@ declare class HumanBehaviorTracker {
37
37
  private _connectionBlocked;
38
38
  private recordInstance;
39
39
  private sessionStartTime;
40
+ private rrwebRecord;
41
+ private fullSnapshotTimeout;
40
42
  /**
41
43
  * Initialize the HumanBehavior tracker
42
44
  * This is the main entry point - call this once per page
@@ -120,6 +122,11 @@ declare class HumanBehaviorTracker {
120
122
  */
121
123
  getUserAttributes(): Record<string, any>;
122
124
  start(): Promise<void>;
125
+ /**
126
+ * Manually trigger a FullSnapshot (for navigation events)
127
+ * Delays snapshot to avoid capturing mid-animation states
128
+ */
129
+ private takeFullSnapshot;
123
130
  stop(): Promise<void>;
124
131
  /**
125
132
  * Add an event to the ingestion queue
@@ -34,6 +34,8 @@ declare class HumanBehaviorTracker {
34
34
  private _connectionBlocked;
35
35
  private recordInstance;
36
36
  private sessionStartTime;
37
+ private rrwebRecord;
38
+ private fullSnapshotTimeout;
37
39
  /**
38
40
  * Initialize the HumanBehavior tracker
39
41
  * This is the main entry point - call this once per page
@@ -117,6 +119,11 @@ declare class HumanBehaviorTracker {
117
119
  */
118
120
  getUserAttributes(): Record<string, any>;
119
121
  start(): Promise<void>;
122
+ /**
123
+ * Manually trigger a FullSnapshot (for navigation events)
124
+ * Delays snapshot to avoid capturing mid-animation states
125
+ */
126
+ private takeFullSnapshot;
120
127
  stop(): Promise<void>;
121
128
  /**
122
129
  * Add an event to the ingestion queue
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanbehavior-js",
3
- "version": "0.4.6",
3
+ "version": "0.4.7",
4
4
  "description": "SDK for HumanBehavior session and event recording",
5
5
  "type": "module",
6
6
  "main": "./dist/cjs/index.js",
package/src/tracker.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { record } from '@rrweb/record';
2
+ import type { listenerHandler } from '@rrweb/types';
2
3
  import { v1 as uuidv1 } from 'uuid';
3
4
  import { HumanBehaviorAPI } from './api';
4
5
  import { RedactionManager, RedactionOptions } from './redact';
@@ -45,8 +46,10 @@ export class HumanBehaviorTracker {
45
46
  private originalReplaceState: typeof history.replaceState | null = null;
46
47
  private navigationListeners: Array<() => void> = [];
47
48
  private _connectionBlocked: boolean = false;
48
- private recordInstance: any = null;
49
+ private recordInstance: listenerHandler | null = null;
49
50
  private sessionStartTime: number = Date.now();
51
+ private rrwebRecord: any = null;
52
+ private fullSnapshotTimeout: number | null = null;
50
53
 
51
54
  /**
52
55
  * Initialize the HumanBehavior tracker
@@ -225,6 +228,9 @@ export class HumanBehaviorTracker {
225
228
 
226
229
  // Track navigation event
227
230
  this.trackNavigationEvent('pushState', this.previousUrl, this.currentUrl);
231
+
232
+ // Take FullSnapshot on navigation (like PostHog does)
233
+ this.takeFullSnapshot();
228
234
  };
229
235
 
230
236
  // Override replaceState to capture programmatic navigation
@@ -237,6 +243,9 @@ export class HumanBehaviorTracker {
237
243
 
238
244
  // Track navigation event
239
245
  this.trackNavigationEvent('replaceState', this.previousUrl, this.currentUrl);
246
+
247
+ // Take FullSnapshot on navigation (like PostHog does)
248
+ this.takeFullSnapshot();
240
249
  };
241
250
 
242
251
  // Listen for popstate events (back/forward navigation)
@@ -244,6 +253,9 @@ export class HumanBehaviorTracker {
244
253
  this.previousUrl = this.currentUrl;
245
254
  this.currentUrl = window.location.href;
246
255
  this.trackNavigationEvent('popstate', this.previousUrl, this.currentUrl);
256
+
257
+ // Take FullSnapshot on navigation (like PostHog does)
258
+ this.takeFullSnapshot();
247
259
  };
248
260
 
249
261
  window.addEventListener('popstate', popstateListener);
@@ -751,8 +763,8 @@ export class HumanBehaviorTracker {
751
763
  this.flush();
752
764
  }, this.FLUSH_INTERVAL_MS);
753
765
 
754
- // Enable console tracking
755
- this.enableConsoleTracking();
766
+ // Disable console tracking to reduce event pollution
767
+ // this.enableConsoleTracking();
756
768
 
757
769
  // ✅ DOM READY DETECTION
758
770
  // Wait for DOM to be ready before starting recording
@@ -760,6 +772,7 @@ export class HumanBehaviorTracker {
760
772
  logDebug('🎯 DOM ready, starting session recording');
761
773
 
762
774
  // ✅ HUMANBEHAVIOR RRWEB CONFIGURATION
775
+ this.rrwebRecord = record;
763
776
  const recordInstance = record({
764
777
  emit: (event) => {
765
778
  // ✅ DIRECT EVENT HANDLING - Let rrweb handle events natively
@@ -784,13 +797,13 @@ export class HumanBehaviorTracker {
784
797
  // ✅ CANVAS RECORDING - Disabled to prevent large data URIs
785
798
  recordCanvas: false, // Disabled to prevent large data URIs
786
799
 
787
- // ✅ FULLSNAPSHOT GENERATION - Use reasonable intervals
788
- // checkoutEveryNms: 300000, // Take FullSnapshot every 5 minutes
789
- // checkoutEveryNth: 1000, // Take FullSnapshot every 1000 events
800
+ // ✅ FULLSNAPSHOT GENERATION - Following PostHog's approach (no periodic snapshots)
801
+ // PostHog doesn't use checkoutEveryNms or checkoutEveryNth to avoid animation issues
802
+ // They rely on initial FullSnapshot + navigation-triggered ones only
790
803
  });
791
804
 
792
- // Store the record instance for cleanup
793
- this.recordInstance = recordInstance;
805
+ // Store the record instance for cleanup
806
+ this.recordInstance = recordInstance || null;
794
807
  };
795
808
 
796
809
  // ✅ DOM READY DETECTION
@@ -809,6 +822,37 @@ export class HumanBehaviorTracker {
809
822
  }
810
823
  }
811
824
 
825
+ /**
826
+ * Manually trigger a FullSnapshot (for navigation events)
827
+ * Delays snapshot to avoid capturing mid-animation states
828
+ */
829
+ private takeFullSnapshot(): void {
830
+ // Clear any existing timeout to avoid multiple snapshots
831
+ if (this.fullSnapshotTimeout) {
832
+ clearTimeout(this.fullSnapshotTimeout);
833
+ }
834
+
835
+ // Delay FullSnapshot to let animations settle
836
+ this.fullSnapshotTimeout = window.setTimeout(() => {
837
+ try {
838
+ // Wait for any pending animations/transitions to complete
839
+ requestAnimationFrame(() => {
840
+ requestAnimationFrame(() => {
841
+ // Access takeFullSnapshot from the rrweb record function
842
+ if (this.rrwebRecord && typeof this.rrwebRecord.takeFullSnapshot === 'function') {
843
+ this.rrwebRecord.takeFullSnapshot();
844
+ logDebug('✅ FullSnapshot taken for navigation (delayed for animations)');
845
+ } else {
846
+ logWarn('⚠️ takeFullSnapshot not available on record function');
847
+ }
848
+ });
849
+ });
850
+ } catch (error) {
851
+ logError('❌ Failed to take FullSnapshot for navigation:', error);
852
+ }
853
+ }, 1000); // Wait 1 second for animations to settle
854
+ }
855
+
812
856
  public async stop() {
813
857
  await this.ensureInitialized();
814
858
  if (!isBrowser) return;
@@ -823,6 +867,14 @@ export class HumanBehaviorTracker {
823
867
  this.recordInstance();
824
868
  this.recordInstance = null;
825
869
  }
870
+
871
+ // Clear any pending FullSnapshot timeouts
872
+ if (this.fullSnapshotTimeout) {
873
+ clearTimeout(this.fullSnapshotTimeout);
874
+ this.fullSnapshotTimeout = null;
875
+ }
876
+
877
+ this.rrwebRecord = null;
826
878
 
827
879
  // Disable console tracking
828
880
  this.disableConsoleTracking();