humanbehavior-js 0.3.6 → 0.3.8

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.
Files changed (59) hide show
  1. package/WIZARD_USAGE_GUIDE.md +381 -0
  2. package/dist/cjs/angular/index.cjs +53 -0
  3. package/dist/cjs/angular/index.cjs.map +1 -0
  4. package/dist/cjs/index.cjs +14230 -0
  5. package/dist/cjs/index.cjs.map +1 -0
  6. package/dist/cjs/install-wizard.cjs +1157 -0
  7. package/dist/cjs/install-wizard.cjs.map +1 -0
  8. package/dist/cjs/react/index.cjs +14387 -0
  9. package/dist/cjs/react/index.cjs.map +1 -0
  10. package/dist/cjs/remix/index.cjs +57 -0
  11. package/dist/cjs/remix/index.cjs.map +1 -0
  12. package/dist/cjs/svelte/index.cjs +13 -0
  13. package/dist/cjs/svelte/index.cjs.map +1 -0
  14. package/dist/cjs/vue/index.cjs +16 -0
  15. package/dist/cjs/vue/index.cjs.map +1 -0
  16. package/dist/cli/auto-install.js +1170 -0
  17. package/dist/cli/auto-install.js.map +1 -0
  18. package/dist/esm/angular/index.js +49 -0
  19. package/dist/esm/angular/index.js.map +1 -0
  20. package/dist/esm/index.js +12160 -3894
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/install-wizard.js +1134 -0
  23. package/dist/esm/install-wizard.js.map +1 -0
  24. package/dist/esm/react/index.js +14113 -70
  25. package/dist/esm/react/index.js.map +1 -1
  26. package/dist/esm/remix/index.js +47 -0
  27. package/dist/esm/remix/index.js.map +1 -0
  28. package/dist/esm/svelte/index.js +11 -0
  29. package/dist/esm/svelte/index.js.map +1 -0
  30. package/dist/esm/vue/index.js +14 -0
  31. package/dist/esm/vue/index.js.map +1 -0
  32. package/dist/index.min.js +1 -15
  33. package/dist/index.min.js.map +1 -1
  34. package/dist/types/angular/index.d.ts +240 -0
  35. package/dist/types/index.d.ts +2 -2
  36. package/dist/types/install-wizard.d.ts +126 -0
  37. package/dist/types/react/index.d.ts +212 -3
  38. package/dist/types/remix/index.d.ts +10 -0
  39. package/dist/types/svelte/index.d.ts +216 -0
  40. package/dist/types/vue/index.d.ts +10 -0
  41. package/package.json +41 -9
  42. package/readme.md +72 -3
  43. package/rollup.config.js +263 -13
  44. package/src/angular/index.ts +54 -0
  45. package/src/api.ts +19 -2
  46. package/src/cli/auto-install.ts +225 -0
  47. package/src/index.ts +5 -2
  48. package/src/install-wizard.ts +1304 -0
  49. package/src/react/AutoInstallWizard.tsx +557 -0
  50. package/src/react/browser.ts +8 -0
  51. package/src/react/index.tsx +2 -4
  52. package/src/remix/index.ts +16 -0
  53. package/src/svelte/index.ts +8 -0
  54. package/src/tracker.ts +54 -24
  55. package/src/vue/index.ts +18 -0
  56. package/dist/cjs/index.js +0 -5967
  57. package/dist/cjs/index.js.map +0 -1
  58. package/dist/cjs/react/index.js +0 -346
  59. package/dist/cjs/react/index.js.map +0 -1
package/src/tracker.ts CHANGED
@@ -1,4 +1,4 @@
1
- import * as rrweb from 'rrweb';
1
+ import { record } from '@rrweb/record';
2
2
  import { v1 as uuidv1 } from 'uuid';
3
3
  import { HumanBehaviorAPI } from './api';
4
4
  import { RedactionManager, RedactionOptions } from './redact';
@@ -128,10 +128,10 @@ export class HumanBehaviorTracker {
128
128
  if (isBrowser) {
129
129
  const existingSessionId = localStorage.getItem('human_behavior_session_id');
130
130
  const lastActivity = localStorage.getItem('human_behavior_last_activity');
131
- const thirtyMinutesAgo = Date.now() - (30 * 60 * 1000);
131
+ const fifteenMinutesAgo = Date.now() - (15 * 60 * 1000);
132
132
 
133
133
  // Check if we have an existing session that's still within the activity window
134
- if (existingSessionId && lastActivity && parseInt(lastActivity) > thirtyMinutesAgo) {
134
+ if (existingSessionId && lastActivity && parseInt(lastActivity) > fifteenMinutesAgo) {
135
135
  this.sessionId = existingSessionId;
136
136
  logDebug(`Reusing existing session: ${this.sessionId}`);
137
137
  // Update activity timestamp to extend the session window
@@ -754,9 +754,13 @@ export class HumanBehaviorTracker {
754
754
  // Enable console tracking
755
755
  this.enableConsoleTracking();
756
756
 
757
- // ✅ SIMPLIFIED RECORDING - Use rrweb's proven defaults
758
- // No complex adaptive logic - rrweb's defaults work well for most use cases
759
- const recordInstance = rrweb.record({
757
+ // ✅ DOM READY DETECTION
758
+ // Wait for DOM to be ready before starting recording
759
+ const startRecording = () => {
760
+ logDebug('🎯 DOM ready, starting session recording');
761
+
762
+ // ✅ HUMANBEHAVIOR RRWEB CONFIGURATION
763
+ const recordInstance = record({
760
764
  emit: (event) => {
761
765
  // ✅ DIRECT EVENT HANDLING - Let rrweb handle events natively
762
766
  this.addEvent(event);
@@ -766,28 +770,43 @@ export class HumanBehaviorTracker {
766
770
  logDebug(`🎯 FullSnapshot generated at ${new Date().toISOString()}`);
767
771
  }
768
772
  },
769
- inlineStylesheet: true,
770
- recordCanvas: true,
771
- collectFonts: true,
772
- inlineImages: true,
773
- blockClass: 'rr-block',
774
- ignoreClass: 'rr-ignore',
775
- maskTextClass: 'rr-mask',
776
-
777
- // ✅ RRWEB BUILT-IN MASKING - More reliable than custom redaction
778
- maskAllInputs: false, // Let users control this via selectors
773
+ // ✅ HUMANBEHAVIOR'S CUSTOM SETTINGS
779
774
  maskTextSelector: this.redactionManager.getMaskTextSelector() || undefined,
775
+ maskTextFn: undefined,
776
+ maskAllInputs: true, // HumanBehavior default
777
+ maskInputOptions: { password: true }, // HumanBehavior default
778
+ maskInputFn: undefined,
779
+ slimDOMOptions: {},
780
+ collectFonts: false, // HumanBehavior default
781
+ inlineStylesheet: true, // HumanBehavior default
782
+ recordCrossOriginIframes: false, // HumanBehavior default
780
783
 
781
- // ✅ FULLSNAPSHOT GENERATION - Use reasonable intervals (PostHog-style)
782
- checkoutEveryNms: 300000, // Take FullSnapshot every 5 minutes (like PostHog)
783
- checkoutEveryNth: 1000, // Take FullSnapshot every 1000 events
784
+ // ✅ CANVAS RECORDING - Disabled to prevent large data URIs
785
+ recordCanvas: false, // Disabled to prevent large data URIs
784
786
 
785
- // ✅ SELECTOR-BASED REDACTION - Users control via CSS selectors
786
- // No custom masking functions needed - rrweb handles this natively
787
+ // ✅ FULLSNAPSHOT GENERATION - Use reasonable intervals
788
+ checkoutEveryNms: 300000, // Take FullSnapshot every 5 minutes
789
+ checkoutEveryNth: 1000, // Take FullSnapshot every 1000 events
787
790
  });
788
791
 
789
792
  // Store the record instance for cleanup
790
793
  this.recordInstance = recordInstance;
794
+ };
795
+
796
+ // ✅ DOM READY DETECTION
797
+ logDebug(`🎯 DOM ready state: ${document.readyState}`);
798
+ if (document.readyState === 'complete') {
799
+ // DOM already ready, start immediately
800
+ logDebug('🎯 DOM already complete, starting recording immediately');
801
+ startRecording();
802
+ } else {
803
+ // Wait for DOM to be ready
804
+ logDebug('🎯 DOM not ready, waiting for DOMContentLoaded event');
805
+ document.addEventListener('DOMContentLoaded', () => {
806
+ logDebug('🎯 DOMContentLoaded fired, starting recording');
807
+ startRecording();
808
+ }, { once: true });
809
+ }
791
810
  }
792
811
 
793
812
  public async stop() {
@@ -822,11 +841,22 @@ export class HumanBehaviorTracker {
822
841
  // ✅ DIRECT EVENT HANDLING - No custom processing to avoid corruption
823
842
  // Events flow directly from rrweb to ingestion server
824
843
 
844
+ // ✅ EVENT VALIDATION
845
+ if (!event || typeof event !== 'object') {
846
+ logDebug('⚠️ Skipping invalid event:', event);
847
+ return;
848
+ }
849
+
825
850
  // ✅ LOG FULLSNAPSHOT STATUS FOR DEBUGGING
826
851
  if (event.type === 2) { // FullSnapshot
827
852
  const hasData = !!event.data;
828
853
  const hasNode = !!(event.data && event.data.node);
829
- logDebug(`[FIXED] FullSnapshot event: hasData=${hasData}, hasNode=${hasNode}, dataType=${event.data?.node?.type}`);
854
+
855
+ if (!hasData || !hasNode) {
856
+ logDebug(`⚠️ Empty FullSnapshot detected: hasData=${hasData}, hasNode=${hasNode} - continuing session`);
857
+ } else {
858
+ logDebug(`✅ Valid FullSnapshot: hasData=${hasData}, hasNode=${hasNode}, dataType=${event.data?.node?.type}`);
859
+ }
830
860
  }
831
861
 
832
862
  this.eventIngestionQueue.push(event); // Direct event handling
@@ -1072,7 +1102,7 @@ export class HumanBehaviorTracker {
1072
1102
 
1073
1103
  /**
1074
1104
  * Get current snapshot frequency info
1075
- * Uses configured values (5 minutes, 1000 events) - PostHog-style
1105
+ * Uses configured values (5 minutes, 1000 events)
1076
1106
  */
1077
1107
  public getSnapshotFrequencyInfo(): {
1078
1108
  sessionDuration: number;
@@ -1084,7 +1114,7 @@ export class HumanBehaviorTracker {
1084
1114
 
1085
1115
  return {
1086
1116
  sessionDuration,
1087
- currentInterval: 300000, // Configured - 5 minutes (PostHog-style)
1117
+ currentInterval: 300000, // Configured - 5 minutes
1088
1118
  currentThreshold: 1000, // Configured - 1000 events
1089
1119
  phase: 'configured' // Using explicit configuration
1090
1120
  };
@@ -0,0 +1,18 @@
1
+ import { HumanBehaviorTracker } from '../index';
2
+ import type { App } from 'vue';
3
+
4
+ interface HumanBehaviorPluginOptions {
5
+ apiKey: string;
6
+ }
7
+
8
+ export const HumanBehaviorPlugin = {
9
+ install: (app: App, options: HumanBehaviorPluginOptions) => {
10
+ const tracker = HumanBehaviorTracker.init(options.apiKey);
11
+
12
+ // Make tracker available globally
13
+ app.config.globalProperties.$humanBehavior = tracker;
14
+
15
+ // Also provide it via inject/provide
16
+ app.provide('humanBehavior', tracker);
17
+ }
18
+ };