humanbehavior-js 0.2.6 → 0.2.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.
@@ -109,6 +109,9 @@ declare class HumanBehaviorTracker {
109
109
  private originalReplaceState;
110
110
  private navigationListeners;
111
111
  private _connectionBlocked;
112
+ private recordInstance;
113
+ private frequencyUpdateInterval;
114
+ private sessionStartTime;
112
115
  /**
113
116
  * Initialize the HumanBehavior tracker
114
117
  * This is the main entry point - call this once per page
@@ -240,6 +243,15 @@ declare class HumanBehaviorTracker {
240
243
  * Get the current URL being tracked
241
244
  */
242
245
  getCurrentUrl(): string;
246
+ /**
247
+ * Get current snapshot frequency info
248
+ */
249
+ getSnapshotFrequencyInfo(): {
250
+ sessionDuration: number;
251
+ currentInterval: number;
252
+ currentThreshold: number;
253
+ phase: string;
254
+ };
243
255
  /**
244
256
  * Test if the tracker can reach the ingestion server
245
257
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "humanbehavior-js",
3
- "version": "0.2.6",
3
+ "version": "0.2.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
@@ -47,6 +47,9 @@ export class HumanBehaviorTracker {
47
47
  private originalReplaceState: typeof history.replaceState | null = null;
48
48
  private navigationListeners: Array<() => void> = [];
49
49
  private _connectionBlocked: boolean = false;
50
+ private recordInstance: any = null;
51
+ private frequencyUpdateInterval: any = null;
52
+ private sessionStartTime: number = Date.now();
50
53
 
51
54
  /**
52
55
  * Initialize the HumanBehavior tracker
@@ -759,37 +762,70 @@ export class HumanBehaviorTracker {
759
762
  // Enable console tracking
760
763
  this.enableConsoleTracking();
761
764
 
762
- // Start recording with redaction enabled
763
- rrweb.record({
764
- emit: (event) => {
765
- // Add additional validation for FullSnapshot events
766
- if (event.type === 2) { // FullSnapshot event
767
- if (!event.data || !event.data.node) {
768
- logWarn('rrweb generated malformed FullSnapshot event:', {
769
- hasData: !!event.data,
770
- hasNode: !!(event.data && event.data.node),
771
- dataType: typeof event.data,
772
- eventType: event.type,
773
- timestamp: event.timestamp
774
- });
775
- // Don't skip - let the addEvent method handle it
776
- } else {
777
- logDebug('Valid FullSnapshot event received from rrweb');
778
- }
765
+ // Adaptive snapshot configuration based on session duration
766
+ const sessionStartTime = Date.now();
767
+ let snapshotInterval = 5000; // Start with 5 seconds
768
+ let eventThreshold = 100; // Start with 100 events
769
+
770
+ // Function to update snapshot frequency based on session duration
771
+ const updateSnapshotFrequency = () => {
772
+ const sessionDuration = Date.now() - sessionStartTime;
773
+ const thirtyMinutes = 30 * 60 * 1000;
774
+ const twoHours = 2 * 60 * 60 * 1000;
775
+ const fourHours = 4 * 60 * 60 * 1000;
776
+
777
+ if (sessionDuration > twoHours) {
778
+ // After 2 hours, very infrequent snapshots
779
+ snapshotInterval = 30000; // 30 seconds
780
+ eventThreshold = 500; // 500 events
781
+ logDebug('Reduced snapshot frequency: 30s/500 events (2+ hours)');
782
+ } else if (sessionDuration > thirtyMinutes) {
783
+ // After 30 minutes, moderate frequency
784
+ snapshotInterval = 15000; // 15 seconds
785
+ eventThreshold = 300; // 300 events
786
+ logDebug('Reduced snapshot frequency: 15s/300 events (30+ minutes)');
787
+ }
788
+ // First 30 minutes: 5s/100 events (default)
789
+ };
790
+
791
+ // Update frequency every 5 minutes
792
+ const frequencyUpdateInterval = setInterval(updateSnapshotFrequency, 5 * 60 * 1000);
793
+
794
+ // Start recording with adaptive redaction enabled
795
+ const recordInstance = rrweb.record({
796
+ emit: (event) => {
797
+ // Add additional validation for FullSnapshot events
798
+ if (event.type === 2) { // FullSnapshot event
799
+ if (!event.data || !event.data.node) {
800
+ logWarn('rrweb generated malformed FullSnapshot event:', {
801
+ hasData: !!event.data,
802
+ hasNode: !!(event.data && event.data.node),
803
+ dataType: typeof event.data,
804
+ eventType: event.type,
805
+ timestamp: event.timestamp
806
+ });
807
+ // Don't skip - let the addEvent method handle it
808
+ } else {
809
+ logDebug('Valid FullSnapshot event received from rrweb');
779
810
  }
780
- this.addEvent(event);
781
- },
782
- inlineStylesheet: true,
783
- recordCanvas: true,
784
- collectFonts: true,
785
- inlineImages: true,
786
- blockClass: 'rr-block',
787
- ignoreClass: 'rr-ignore',
788
- maskTextClass: 'rr-ignore',
789
- // Add more robust configuration
790
- checkoutEveryNms: 5000, // Take full snapshot every 5 seconds
791
- checkoutEveryNth: 100 // Take full snapshot every 100 events
792
- });
811
+ }
812
+ this.addEvent(event);
813
+ },
814
+ inlineStylesheet: true,
815
+ recordCanvas: true,
816
+ collectFonts: true,
817
+ inlineImages: true,
818
+ blockClass: 'rr-block',
819
+ ignoreClass: 'rr-ignore',
820
+ maskTextClass: 'rr-ignore',
821
+ // Adaptive configuration
822
+ checkoutEveryNms: snapshotInterval,
823
+ checkoutEveryNth: eventThreshold
824
+ });
825
+
826
+ // Store the record instance and interval for cleanup
827
+ this.recordInstance = recordInstance;
828
+ this.frequencyUpdateInterval = frequencyUpdateInterval;
793
829
  }
794
830
 
795
831
  public async stop() {
@@ -801,6 +837,18 @@ export class HumanBehaviorTracker {
801
837
  this.flushInterval = null;
802
838
  }
803
839
 
840
+ // Cleanup adaptive snapshot intervals
841
+ if (this.frequencyUpdateInterval) {
842
+ clearInterval(this.frequencyUpdateInterval);
843
+ this.frequencyUpdateInterval = null;
844
+ }
845
+
846
+ // Stop rrweb recording
847
+ if (this.recordInstance) {
848
+ this.recordInstance();
849
+ this.recordInstance = null;
850
+ }
851
+
804
852
  // Disable console tracking
805
853
  this.disableConsoleTracking();
806
854
 
@@ -1041,6 +1089,41 @@ export class HumanBehaviorTracker {
1041
1089
  return this.currentUrl;
1042
1090
  }
1043
1091
 
1092
+ /**
1093
+ * Get current snapshot frequency info
1094
+ */
1095
+ public getSnapshotFrequencyInfo(): {
1096
+ sessionDuration: number;
1097
+ currentInterval: number;
1098
+ currentThreshold: number;
1099
+ phase: string;
1100
+ } {
1101
+ const sessionDuration = Date.now() - this.sessionStartTime;
1102
+ const thirtyMinutes = 30 * 60 * 1000;
1103
+ const twoHours = 2 * 60 * 60 * 1000;
1104
+
1105
+ let phase = 'initial';
1106
+ let interval = 5000;
1107
+ let threshold = 100;
1108
+
1109
+ if (sessionDuration > twoHours) {
1110
+ phase = 'extended';
1111
+ interval = 30000;
1112
+ threshold = 500;
1113
+ } else if (sessionDuration > thirtyMinutes) {
1114
+ phase = 'moderate';
1115
+ interval = 15000;
1116
+ threshold = 300;
1117
+ }
1118
+
1119
+ return {
1120
+ sessionDuration,
1121
+ currentInterval: interval,
1122
+ currentThreshold: threshold,
1123
+ phase
1124
+ };
1125
+ }
1126
+
1044
1127
  /**
1045
1128
  * Test if the tracker can reach the ingestion server
1046
1129
  */