humanbehavior-js 0.2.5 → 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.
- package/dist/cjs/index.js +102 -3
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +102 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/index.min.js +2 -2
- package/dist/index.min.js.map +1 -1
- package/dist/types/index.d.ts +12 -0
- package/package.json +1 -1
- package/src/tracker.ts +127 -13
package/dist/esm/index.js
CHANGED
|
@@ -4956,6 +4956,9 @@ class HumanBehaviorTracker {
|
|
|
4956
4956
|
this.originalReplaceState = null;
|
|
4957
4957
|
this.navigationListeners = [];
|
|
4958
4958
|
this._connectionBlocked = false;
|
|
4959
|
+
this.recordInstance = null;
|
|
4960
|
+
this.frequencyUpdateInterval = null;
|
|
4961
|
+
this.sessionStartTime = Date.now();
|
|
4959
4962
|
if (!apiKey) {
|
|
4960
4963
|
throw new Error('Human Behavior API Key is required');
|
|
4961
4964
|
}
|
|
@@ -5514,9 +5517,50 @@ class HumanBehaviorTracker {
|
|
|
5514
5517
|
}, this.FLUSH_INTERVAL_MS);
|
|
5515
5518
|
// Enable console tracking
|
|
5516
5519
|
this.enableConsoleTracking();
|
|
5517
|
-
//
|
|
5518
|
-
|
|
5520
|
+
// Adaptive snapshot configuration based on session duration
|
|
5521
|
+
const sessionStartTime = Date.now();
|
|
5522
|
+
let snapshotInterval = 5000; // Start with 5 seconds
|
|
5523
|
+
let eventThreshold = 100; // Start with 100 events
|
|
5524
|
+
// Function to update snapshot frequency based on session duration
|
|
5525
|
+
const updateSnapshotFrequency = () => {
|
|
5526
|
+
const sessionDuration = Date.now() - sessionStartTime;
|
|
5527
|
+
const thirtyMinutes = 30 * 60 * 1000;
|
|
5528
|
+
const twoHours = 2 * 60 * 60 * 1000;
|
|
5529
|
+
if (sessionDuration > twoHours) {
|
|
5530
|
+
// After 2 hours, very infrequent snapshots
|
|
5531
|
+
snapshotInterval = 30000; // 30 seconds
|
|
5532
|
+
eventThreshold = 500; // 500 events
|
|
5533
|
+
logDebug('Reduced snapshot frequency: 30s/500 events (2+ hours)');
|
|
5534
|
+
}
|
|
5535
|
+
else if (sessionDuration > thirtyMinutes) {
|
|
5536
|
+
// After 30 minutes, moderate frequency
|
|
5537
|
+
snapshotInterval = 15000; // 15 seconds
|
|
5538
|
+
eventThreshold = 300; // 300 events
|
|
5539
|
+
logDebug('Reduced snapshot frequency: 15s/300 events (30+ minutes)');
|
|
5540
|
+
}
|
|
5541
|
+
// First 30 minutes: 5s/100 events (default)
|
|
5542
|
+
};
|
|
5543
|
+
// Update frequency every 5 minutes
|
|
5544
|
+
const frequencyUpdateInterval = setInterval(updateSnapshotFrequency, 5 * 60 * 1000);
|
|
5545
|
+
// Start recording with adaptive redaction enabled
|
|
5546
|
+
const recordInstance = record({
|
|
5519
5547
|
emit: (event) => {
|
|
5548
|
+
// Add additional validation for FullSnapshot events
|
|
5549
|
+
if (event.type === 2) { // FullSnapshot event
|
|
5550
|
+
if (!event.data || !event.data.node) {
|
|
5551
|
+
logWarn('rrweb generated malformed FullSnapshot event:', {
|
|
5552
|
+
hasData: !!event.data,
|
|
5553
|
+
hasNode: !!(event.data && event.data.node),
|
|
5554
|
+
dataType: typeof event.data,
|
|
5555
|
+
eventType: event.type,
|
|
5556
|
+
timestamp: event.timestamp
|
|
5557
|
+
});
|
|
5558
|
+
// Don't skip - let the addEvent method handle it
|
|
5559
|
+
}
|
|
5560
|
+
else {
|
|
5561
|
+
logDebug('Valid FullSnapshot event received from rrweb');
|
|
5562
|
+
}
|
|
5563
|
+
}
|
|
5520
5564
|
this.addEvent(event);
|
|
5521
5565
|
},
|
|
5522
5566
|
inlineStylesheet: true,
|
|
@@ -5525,8 +5569,14 @@ class HumanBehaviorTracker {
|
|
|
5525
5569
|
inlineImages: true,
|
|
5526
5570
|
blockClass: 'rr-block',
|
|
5527
5571
|
ignoreClass: 'rr-ignore',
|
|
5528
|
-
maskTextClass: 'rr-ignore'
|
|
5572
|
+
maskTextClass: 'rr-ignore',
|
|
5573
|
+
// Adaptive configuration
|
|
5574
|
+
checkoutEveryNms: snapshotInterval,
|
|
5575
|
+
checkoutEveryNth: eventThreshold
|
|
5529
5576
|
});
|
|
5577
|
+
// Store the record instance and interval for cleanup
|
|
5578
|
+
this.recordInstance = recordInstance;
|
|
5579
|
+
this.frequencyUpdateInterval = frequencyUpdateInterval;
|
|
5530
5580
|
});
|
|
5531
5581
|
}
|
|
5532
5582
|
stop() {
|
|
@@ -5538,6 +5588,16 @@ class HumanBehaviorTracker {
|
|
|
5538
5588
|
clearInterval(this.flushInterval);
|
|
5539
5589
|
this.flushInterval = null;
|
|
5540
5590
|
}
|
|
5591
|
+
// Cleanup adaptive snapshot intervals
|
|
5592
|
+
if (this.frequencyUpdateInterval) {
|
|
5593
|
+
clearInterval(this.frequencyUpdateInterval);
|
|
5594
|
+
this.frequencyUpdateInterval = null;
|
|
5595
|
+
}
|
|
5596
|
+
// Stop rrweb recording
|
|
5597
|
+
if (this.recordInstance) {
|
|
5598
|
+
this.recordInstance();
|
|
5599
|
+
this.recordInstance = null;
|
|
5600
|
+
}
|
|
5541
5601
|
// Disable console tracking
|
|
5542
5602
|
this.disableConsoleTracking();
|
|
5543
5603
|
// Cleanup navigation tracking
|
|
@@ -5547,6 +5607,18 @@ class HumanBehaviorTracker {
|
|
|
5547
5607
|
addEvent(event) {
|
|
5548
5608
|
return __awaiter$1(this, void 0, void 0, function* () {
|
|
5549
5609
|
yield this.ensureInitialized();
|
|
5610
|
+
// Validate FullSnapshot events before processing
|
|
5611
|
+
if (event.type === 2) { // FullSnapshot event
|
|
5612
|
+
if (!event.data || !event.data.node) {
|
|
5613
|
+
logWarn('Malformed FullSnapshot event detected, skipping:', {
|
|
5614
|
+
hasData: !!event.data,
|
|
5615
|
+
hasNode: !!(event.data && event.data.node),
|
|
5616
|
+
dataType: typeof event.data,
|
|
5617
|
+
eventType: event.type
|
|
5618
|
+
});
|
|
5619
|
+
return; // Skip malformed FullSnapshot events
|
|
5620
|
+
}
|
|
5621
|
+
}
|
|
5550
5622
|
// Process event through redaction manager if active
|
|
5551
5623
|
const processedEvent = this.redactionManager.processEvent(event);
|
|
5552
5624
|
const eventSize = new TextEncoder().encode(JSON.stringify(processedEvent)).length;
|
|
@@ -5759,6 +5831,33 @@ class HumanBehaviorTracker {
|
|
|
5759
5831
|
getCurrentUrl() {
|
|
5760
5832
|
return this.currentUrl;
|
|
5761
5833
|
}
|
|
5834
|
+
/**
|
|
5835
|
+
* Get current snapshot frequency info
|
|
5836
|
+
*/
|
|
5837
|
+
getSnapshotFrequencyInfo() {
|
|
5838
|
+
const sessionDuration = Date.now() - this.sessionStartTime;
|
|
5839
|
+
const thirtyMinutes = 30 * 60 * 1000;
|
|
5840
|
+
const twoHours = 2 * 60 * 60 * 1000;
|
|
5841
|
+
let phase = 'initial';
|
|
5842
|
+
let interval = 5000;
|
|
5843
|
+
let threshold = 100;
|
|
5844
|
+
if (sessionDuration > twoHours) {
|
|
5845
|
+
phase = 'extended';
|
|
5846
|
+
interval = 30000;
|
|
5847
|
+
threshold = 500;
|
|
5848
|
+
}
|
|
5849
|
+
else if (sessionDuration > thirtyMinutes) {
|
|
5850
|
+
phase = 'moderate';
|
|
5851
|
+
interval = 15000;
|
|
5852
|
+
threshold = 300;
|
|
5853
|
+
}
|
|
5854
|
+
return {
|
|
5855
|
+
sessionDuration,
|
|
5856
|
+
currentInterval: interval,
|
|
5857
|
+
currentThreshold: threshold,
|
|
5858
|
+
phase
|
|
5859
|
+
};
|
|
5860
|
+
}
|
|
5762
5861
|
/**
|
|
5763
5862
|
* Test if the tracker can reach the ingestion server
|
|
5764
5863
|
*/
|