humanbehavior-js 0.4.12 → 0.4.13
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/canvas-recording-demo.html +143 -0
- package/dist/cjs/angular/index.cjs +22 -6
- package/dist/cjs/angular/index.cjs.map +1 -1
- package/dist/cjs/index.cjs +11 -1
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/cjs/react/index.cjs +19 -11
- package/dist/cjs/react/index.cjs.map +1 -1
- package/dist/cjs/remix/index.cjs +19 -11
- package/dist/cjs/remix/index.cjs.map +1 -1
- package/dist/cjs/svelte/index.cjs +13 -3
- package/dist/cjs/svelte/index.cjs.map +1 -1
- package/dist/cjs/vue/index.cjs +18 -2
- package/dist/cjs/vue/index.cjs.map +1 -1
- package/dist/esm/angular/index.js +22 -6
- package/dist/esm/angular/index.js.map +1 -1
- package/dist/esm/index.js +11 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/react/index.js +19 -11
- package/dist/esm/react/index.js.map +1 -1
- package/dist/esm/remix/index.js +19 -11
- package/dist/esm/remix/index.js.map +1 -1
- package/dist/esm/svelte/index.js +13 -3
- package/dist/esm/svelte/index.js.map +1 -1
- package/dist/esm/vue/index.js +18 -2
- package/dist/esm/vue/index.js.map +1 -1
- package/dist/index.min.js +1 -1
- package/dist/index.min.js.map +1 -1
- package/dist/types/angular/index.d.ts +21 -2
- package/dist/types/index.d.ts +2 -0
- package/dist/types/react/index.d.ts +4 -0
- package/dist/types/remix/index.d.ts +4 -0
- package/dist/types/svelte/index.d.ts +9 -1
- package/dist/types/vue/index.d.ts +5 -0
- package/package.json +1 -1
- package/readme.md +20 -1
- package/src/angular/index.ts +31 -6
- package/src/react/index.tsx +12 -13
- package/src/svelte/index.ts +8 -2
- package/src/tracker.ts +13 -1
- package/src/vue/index.ts +12 -1
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<title>HumanBehavior Canvas Recording Demo</title>
|
|
7
|
+
<style>
|
|
8
|
+
body { font-family: Arial, sans-serif; margin: 20px; }
|
|
9
|
+
.demo-section { margin: 20px 0; padding: 20px; border: 1px solid #ccc; }
|
|
10
|
+
canvas { border: 2px solid #333; margin: 10px; }
|
|
11
|
+
button { padding: 10px 20px; margin: 5px; }
|
|
12
|
+
.info { background: #f0f0f0; padding: 10px; border-radius: 5px; }
|
|
13
|
+
</style>
|
|
14
|
+
</head>
|
|
15
|
+
<body>
|
|
16
|
+
<h1>HumanBehavior Canvas Recording Demo</h1>
|
|
17
|
+
|
|
18
|
+
<div class="info">
|
|
19
|
+
<h3>PostHog-Style Canvas Protection</h3>
|
|
20
|
+
<ul>
|
|
21
|
+
<li><strong>4 FPS Throttling:</strong> Prevents canvas overwhelm (vs 60 FPS default)</li>
|
|
22
|
+
<li><strong>40% Quality:</strong> WebP format with compression</li>
|
|
23
|
+
<li><strong>Opt-in Only:</strong> Disabled by default for safety</li>
|
|
24
|
+
<li><strong>Smart Sampling:</strong> Only captures when canvas changes</li>
|
|
25
|
+
</ul>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<div class="demo-section">
|
|
29
|
+
<h3>Canvas Drawing Demo</h3>
|
|
30
|
+
<canvas id="demoCanvas" width="400" height="300"></canvas>
|
|
31
|
+
<br>
|
|
32
|
+
<button onclick="drawRandom()">Draw Random Shape</button>
|
|
33
|
+
<button onclick="clearCanvas()">Clear Canvas</button>
|
|
34
|
+
<button onclick="animate()">Start Animation</button>
|
|
35
|
+
</div>
|
|
36
|
+
|
|
37
|
+
<div class="demo-section">
|
|
38
|
+
<h3>Canvas Recording Options</h3>
|
|
39
|
+
<button onclick="enableCanvasRecording()">Enable Canvas Recording</button>
|
|
40
|
+
<button onclick="disableCanvasRecording()">Disable Canvas Recording</button>
|
|
41
|
+
<p id="status">Canvas recording: <strong>Disabled</strong></p>
|
|
42
|
+
</div>
|
|
43
|
+
|
|
44
|
+
<script src="./dist/index.min.js"></script>
|
|
45
|
+
<script>
|
|
46
|
+
let tracker;
|
|
47
|
+
let canvas = document.getElementById('demoCanvas');
|
|
48
|
+
let ctx = canvas.getContext('2d');
|
|
49
|
+
let animationId;
|
|
50
|
+
|
|
51
|
+
// Initialize tracker without canvas recording
|
|
52
|
+
function initTracker(enableCanvas = false) {
|
|
53
|
+
tracker = HumanBehaviorTracker.init('13c3e029-ca45-4a3c-a33b-f5dcb297e31c', {
|
|
54
|
+
logLevel: 'warn',
|
|
55
|
+
suppressConsoleErrors: true,
|
|
56
|
+
recordCanvas: enableCanvas // PostHog-style protection
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
updateStatus();
|
|
60
|
+
console.log('✅ Tracker initialized with canvas recording:', enableCanvas);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function updateStatus() {
|
|
64
|
+
const status = document.getElementById('status');
|
|
65
|
+
status.innerHTML = `Canvas recording: <strong>${tracker.recordCanvas ? 'Enabled' : 'Disabled'}</strong>`;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function enableCanvasRecording() {
|
|
69
|
+
if (tracker) {
|
|
70
|
+
tracker.stop();
|
|
71
|
+
}
|
|
72
|
+
initTracker(true);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function disableCanvasRecording() {
|
|
76
|
+
if (tracker) {
|
|
77
|
+
tracker.stop();
|
|
78
|
+
}
|
|
79
|
+
initTracker(false);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function drawRandom() {
|
|
83
|
+
const colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7'];
|
|
84
|
+
const color = colors[Math.floor(Math.random() * colors.length)];
|
|
85
|
+
|
|
86
|
+
ctx.fillStyle = color;
|
|
87
|
+
ctx.beginPath();
|
|
88
|
+
ctx.arc(
|
|
89
|
+
Math.random() * canvas.width,
|
|
90
|
+
Math.random() * canvas.height,
|
|
91
|
+
Math.random() * 50 + 10,
|
|
92
|
+
0,
|
|
93
|
+
2 * Math.PI
|
|
94
|
+
);
|
|
95
|
+
ctx.fill();
|
|
96
|
+
|
|
97
|
+
// Track the drawing event
|
|
98
|
+
if (tracker) {
|
|
99
|
+
tracker.customEvent('canvas_draw', {
|
|
100
|
+
color: color,
|
|
101
|
+
timestamp: Date.now()
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function clearCanvas() {
|
|
107
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
108
|
+
|
|
109
|
+
if (tracker) {
|
|
110
|
+
tracker.customEvent('canvas_clear', {
|
|
111
|
+
timestamp: Date.now()
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
function animate() {
|
|
117
|
+
let angle = 0;
|
|
118
|
+
|
|
119
|
+
function animateFrame() {
|
|
120
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
121
|
+
|
|
122
|
+
// Draw rotating rectangle
|
|
123
|
+
ctx.save();
|
|
124
|
+
ctx.translate(canvas.width / 2, canvas.height / 2);
|
|
125
|
+
ctx.rotate(angle);
|
|
126
|
+
ctx.fillStyle = '#FF6B6B';
|
|
127
|
+
ctx.fillRect(-25, -25, 50, 50);
|
|
128
|
+
ctx.restore();
|
|
129
|
+
|
|
130
|
+
angle += 0.02;
|
|
131
|
+
animationId = requestAnimationFrame(animateFrame);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
animateFrame();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Initialize tracker on page load
|
|
138
|
+
initTracker(false);
|
|
139
|
+
|
|
140
|
+
console.log('🎨 Canvas demo ready! Try drawing or enabling canvas recording.');
|
|
141
|
+
</script>
|
|
142
|
+
</body>
|
|
143
|
+
</html>
|
|
@@ -13171,6 +13171,7 @@ class HumanBehaviorTracker {
|
|
|
13171
13171
|
* This is the main entry point - call this once per page
|
|
13172
13172
|
*/
|
|
13173
13173
|
static init(apiKey, options) {
|
|
13174
|
+
var _a;
|
|
13174
13175
|
// ✅ SUPPRESS COMMON RRWEB ERRORS FOR CLEAN CONSOLE
|
|
13175
13176
|
if (isBrowser && (options === null || options === void 0 ? void 0 : options.suppressConsoleErrors) !== false) {
|
|
13176
13177
|
// Suppress canvas security errors
|
|
@@ -13229,6 +13230,8 @@ class HumanBehaviorTracker {
|
|
|
13229
13230
|
}
|
|
13230
13231
|
// Create new tracker instance
|
|
13231
13232
|
const tracker = new HumanBehaviorTracker(apiKey, options === null || options === void 0 ? void 0 : options.ingestionUrl);
|
|
13233
|
+
// Store canvas recording preference
|
|
13234
|
+
tracker.recordCanvas = (_a = options === null || options === void 0 ? void 0 : options.recordCanvas) !== null && _a !== void 0 ? _a : false;
|
|
13232
13235
|
// Set redacted fields if specified
|
|
13233
13236
|
if (options === null || options === void 0 ? void 0 : options.redactFields) {
|
|
13234
13237
|
tracker.setRedactedFields(options.redactFields);
|
|
@@ -13267,6 +13270,7 @@ class HumanBehaviorTracker {
|
|
|
13267
13270
|
this.sessionStartTime = Date.now();
|
|
13268
13271
|
this.rrwebRecord = null;
|
|
13269
13272
|
this.fullSnapshotTimeout = null;
|
|
13273
|
+
this.recordCanvas = false; // Store canvas recording preference
|
|
13270
13274
|
if (!apiKey) {
|
|
13271
13275
|
throw new Error('Human Behavior API Key is required');
|
|
13272
13276
|
}
|
|
@@ -13851,7 +13855,13 @@ class HumanBehaviorTracker {
|
|
|
13851
13855
|
collectFonts: false, // Disable font collection to reduce errors
|
|
13852
13856
|
inlineStylesheet: true, // Keep styles for proper session replay
|
|
13853
13857
|
recordCrossOriginIframes: false, // Prevent cross-origin iframe errors
|
|
13854
|
-
|
|
13858
|
+
// ✅ CANVAS RECORDING - PostHog-style protection against overwhelm
|
|
13859
|
+
recordCanvas: this.recordCanvas, // Opt-in only
|
|
13860
|
+
sampling: this.recordCanvas ? { canvas: 4 } : undefined, // 4 FPS throttle
|
|
13861
|
+
dataURLOptions: this.recordCanvas ? {
|
|
13862
|
+
type: 'image/webp',
|
|
13863
|
+
quality: 0.4
|
|
13864
|
+
} : undefined, // WebP with 40% quality
|
|
13855
13865
|
// ✅ FULLSNAPSHOT GENERATION - No periodic snapshots to avoid animation issues
|
|
13856
13866
|
// Rely on initial FullSnapshot + navigation-triggered ones only
|
|
13857
13867
|
});
|
|
@@ -14300,7 +14310,13 @@ class HumanBehaviorModule {
|
|
|
14300
14310
|
{
|
|
14301
14311
|
provide: HumanBehaviorTracker,
|
|
14302
14312
|
useFactory: (apiKey) => {
|
|
14303
|
-
return HumanBehaviorTracker.init(apiKey
|
|
14313
|
+
return HumanBehaviorTracker.init(apiKey, {
|
|
14314
|
+
ingestionUrl: config.ingestionUrl,
|
|
14315
|
+
logLevel: config.logLevel,
|
|
14316
|
+
redactFields: config.redactFields,
|
|
14317
|
+
suppressConsoleErrors: config.suppressConsoleErrors,
|
|
14318
|
+
recordCanvas: config.recordCanvas, // Pass canvas recording option
|
|
14319
|
+
});
|
|
14304
14320
|
},
|
|
14305
14321
|
deps: ['HUMANBEHAVIOR_API_KEY']
|
|
14306
14322
|
}
|
|
@@ -14310,8 +14326,8 @@ class HumanBehaviorModule {
|
|
|
14310
14326
|
}
|
|
14311
14327
|
// Angular service for dependency injection
|
|
14312
14328
|
class HumanBehaviorService {
|
|
14313
|
-
constructor(apiKey) {
|
|
14314
|
-
this.tracker = HumanBehaviorTracker.init(apiKey);
|
|
14329
|
+
constructor(apiKey, options) {
|
|
14330
|
+
this.tracker = HumanBehaviorTracker.init(apiKey, options);
|
|
14315
14331
|
}
|
|
14316
14332
|
// Expose core tracker methods
|
|
14317
14333
|
identifyUser(userProperties) {
|
|
@@ -14328,8 +14344,8 @@ class HumanBehaviorService {
|
|
|
14328
14344
|
}
|
|
14329
14345
|
}
|
|
14330
14346
|
// Helper function for standalone Angular initialization
|
|
14331
|
-
function initializeHumanBehavior(apiKey) {
|
|
14332
|
-
return HumanBehaviorTracker.init(apiKey);
|
|
14347
|
+
function initializeHumanBehavior(apiKey, options) {
|
|
14348
|
+
return HumanBehaviorTracker.init(apiKey, options);
|
|
14333
14349
|
}
|
|
14334
14350
|
|
|
14335
14351
|
exports.HumanBehaviorModule = HumanBehaviorModule;
|