@axeptio/behavior-detection 1.0.0

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 (76) hide show
  1. package/README.md +828 -0
  2. package/dist/behavior-detection.esm.min.js +2 -0
  3. package/dist/behavior-detection.esm.min.js.map +7 -0
  4. package/dist/behavior-detection.min.js +2 -0
  5. package/dist/behavior-detection.min.js.map +7 -0
  6. package/dist/behavior-detector.d.ts +102 -0
  7. package/dist/browser.d.ts +33 -0
  8. package/dist/cjs/behavior-detector.d.ts +102 -0
  9. package/dist/cjs/behavior-detector.js +315 -0
  10. package/dist/cjs/browser.d.ts +33 -0
  11. package/dist/cjs/browser.js +226 -0
  12. package/dist/cjs/index.d.ts +38 -0
  13. package/dist/cjs/index.js +55 -0
  14. package/dist/cjs/math-utils.d.ts +84 -0
  15. package/dist/cjs/math-utils.js +141 -0
  16. package/dist/cjs/strategies/click.d.ts +39 -0
  17. package/dist/cjs/strategies/click.js +173 -0
  18. package/dist/cjs/strategies/environment.d.ts +52 -0
  19. package/dist/cjs/strategies/environment.js +148 -0
  20. package/dist/cjs/strategies/index.d.ts +18 -0
  21. package/dist/cjs/strategies/index.js +36 -0
  22. package/dist/cjs/strategies/keyboard.d.ts +43 -0
  23. package/dist/cjs/strategies/keyboard.js +233 -0
  24. package/dist/cjs/strategies/mouse.d.ts +39 -0
  25. package/dist/cjs/strategies/mouse.js +159 -0
  26. package/dist/cjs/strategies/resize.d.ts +21 -0
  27. package/dist/cjs/strategies/resize.js +97 -0
  28. package/dist/cjs/strategies/scroll.d.ts +37 -0
  29. package/dist/cjs/strategies/scroll.js +149 -0
  30. package/dist/cjs/strategies/tap.d.ts +38 -0
  31. package/dist/cjs/strategies/tap.js +214 -0
  32. package/dist/cjs/strategy.d.ts +107 -0
  33. package/dist/cjs/strategy.js +33 -0
  34. package/dist/cjs/types.d.ts +168 -0
  35. package/dist/cjs/types.js +26 -0
  36. package/dist/esm/behavior-detector.d.ts +102 -0
  37. package/dist/esm/behavior-detector.js +311 -0
  38. package/dist/esm/browser.d.ts +33 -0
  39. package/dist/esm/browser.js +224 -0
  40. package/dist/esm/index.d.ts +38 -0
  41. package/dist/esm/index.js +36 -0
  42. package/dist/esm/math-utils.d.ts +84 -0
  43. package/dist/esm/math-utils.js +127 -0
  44. package/dist/esm/strategies/click.d.ts +39 -0
  45. package/dist/esm/strategies/click.js +169 -0
  46. package/dist/esm/strategies/environment.d.ts +52 -0
  47. package/dist/esm/strategies/environment.js +144 -0
  48. package/dist/esm/strategies/index.d.ts +18 -0
  49. package/dist/esm/strategies/index.js +19 -0
  50. package/dist/esm/strategies/keyboard.d.ts +43 -0
  51. package/dist/esm/strategies/keyboard.js +229 -0
  52. package/dist/esm/strategies/mouse.d.ts +39 -0
  53. package/dist/esm/strategies/mouse.js +155 -0
  54. package/dist/esm/strategies/resize.d.ts +21 -0
  55. package/dist/esm/strategies/resize.js +93 -0
  56. package/dist/esm/strategies/scroll.d.ts +37 -0
  57. package/dist/esm/strategies/scroll.js +145 -0
  58. package/dist/esm/strategies/tap.d.ts +38 -0
  59. package/dist/esm/strategies/tap.js +210 -0
  60. package/dist/esm/strategy.d.ts +107 -0
  61. package/dist/esm/strategy.js +29 -0
  62. package/dist/esm/types.d.ts +168 -0
  63. package/dist/esm/types.js +23 -0
  64. package/dist/index.d.ts +38 -0
  65. package/dist/math-utils.d.ts +84 -0
  66. package/dist/strategies/click.d.ts +39 -0
  67. package/dist/strategies/environment.d.ts +52 -0
  68. package/dist/strategies/index.d.ts +18 -0
  69. package/dist/strategies/keyboard.d.ts +43 -0
  70. package/dist/strategies/mouse.d.ts +39 -0
  71. package/dist/strategies/resize.d.ts +21 -0
  72. package/dist/strategies/scroll.d.ts +37 -0
  73. package/dist/strategies/tap.d.ts +38 -0
  74. package/dist/strategy.d.ts +107 -0
  75. package/dist/types.d.ts +168 -0
  76. package/package.json +60 -0
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BehaviorDetector = void 0;
4
+ /**
5
+ * Main class for behavior detection
6
+ * Uses modular strategy pattern for tree-shakeable, autonomous detection modules
7
+ */
8
+ class BehaviorDetector {
9
+ constructor(tickOptions) {
10
+ // Strategy mode
11
+ this.strategies = new Map();
12
+ this.isTracking = false;
13
+ this.isPausedByVisibility = false;
14
+ this.tickInterval = null;
15
+ this.tickIntervalMs = 1000; // Default: 1 second
16
+ this.pauseOnHidden = true;
17
+ this.visibilityChangeHandler = null;
18
+ // Confidence tracking
19
+ this.confidenceScore = 0;
20
+ this.CONFIDENCE_TARGET = 1.0; // Target confidence for reliable classification
21
+ this.CONFIDENCE_DECAY = 0.95; // Per event decay to prevent infinite growth
22
+ if (tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.interval) {
23
+ this.tickIntervalMs = tickOptions.interval;
24
+ }
25
+ if ((tickOptions === null || tickOptions === void 0 ? void 0 : tickOptions.pauseOnHidden) !== undefined) {
26
+ this.pauseOnHidden = tickOptions.pauseOnHidden;
27
+ }
28
+ }
29
+ /**
30
+ * Add a detection strategy
31
+ */
32
+ addStrategy(strategy, weight) {
33
+ const config = {
34
+ strategy,
35
+ weight: weight !== null && weight !== void 0 ? weight : strategy.defaultWeight,
36
+ enabled: true,
37
+ };
38
+ this.strategies.set(strategy.name, config);
39
+ // Set up event callback for confidence tracking
40
+ if (strategy.setEventCallback) {
41
+ strategy.setEventCallback((event) => {
42
+ this.onStrategyEvent(event, config.weight);
43
+ });
44
+ }
45
+ // If already tracking, start this strategy immediately
46
+ if (this.isTracking) {
47
+ strategy.start();
48
+ }
49
+ return this;
50
+ }
51
+ /**
52
+ * Handle event from strategy - update confidence
53
+ */
54
+ onStrategyEvent(event, strategyWeight) {
55
+ // Apply decay to existing confidence to prevent infinite growth
56
+ this.confidenceScore *= this.CONFIDENCE_DECAY;
57
+ // Add weighted contribution from this event
58
+ // eventWeight (0-1) * strategyWeight (e.g. 0.3 for mouse) = contribution
59
+ const contribution = event.weight * strategyWeight;
60
+ this.confidenceScore = Math.min(this.CONFIDENCE_TARGET, this.confidenceScore + contribution);
61
+ }
62
+ /**
63
+ * Remove a detection strategy
64
+ */
65
+ removeStrategy(name) {
66
+ const config = this.strategies.get(name);
67
+ if (config) {
68
+ if (this.isTracking) {
69
+ config.strategy.stop();
70
+ }
71
+ this.strategies.delete(name);
72
+ }
73
+ return this;
74
+ }
75
+ /**
76
+ * Enable/disable a strategy
77
+ */
78
+ setStrategyEnabled(name, enabled) {
79
+ const config = this.strategies.get(name);
80
+ if (config) {
81
+ config.enabled = enabled;
82
+ // If tracking and being disabled, stop it
83
+ if (!enabled && this.isTracking) {
84
+ config.strategy.stop();
85
+ }
86
+ // If tracking and being enabled, start it
87
+ if (enabled && this.isTracking) {
88
+ config.strategy.start();
89
+ }
90
+ }
91
+ return this;
92
+ }
93
+ /**
94
+ * Get all registered strategies
95
+ */
96
+ getStrategies() {
97
+ return this.strategies;
98
+ }
99
+ /**
100
+ * Start tracking
101
+ */
102
+ start() {
103
+ if (this.isTracking)
104
+ return;
105
+ this.isTracking = true;
106
+ // Set up visibility change listener
107
+ if (this.pauseOnHidden && typeof document !== 'undefined') {
108
+ this.visibilityChangeHandler = this.handleVisibilityChange.bind(this);
109
+ document.addEventListener('visibilitychange', this.visibilityChangeHandler);
110
+ // Check initial visibility state
111
+ if (document.hidden) {
112
+ this.isPausedByVisibility = true;
113
+ return; // Don't start strategies if already hidden
114
+ }
115
+ }
116
+ // Start all enabled strategies
117
+ for (const [_, config] of this.strategies) {
118
+ if (config.enabled) {
119
+ config.strategy.start();
120
+ }
121
+ }
122
+ // Start tick mechanism
123
+ this.startTick();
124
+ }
125
+ /**
126
+ * Stop tracking
127
+ */
128
+ stop() {
129
+ if (!this.isTracking)
130
+ return;
131
+ this.isTracking = false;
132
+ this.isPausedByVisibility = false;
133
+ // Remove visibility change listener
134
+ if (this.visibilityChangeHandler && typeof document !== 'undefined') {
135
+ document.removeEventListener('visibilitychange', this.visibilityChangeHandler);
136
+ this.visibilityChangeHandler = null;
137
+ }
138
+ // Stop all strategies
139
+ for (const [_, config] of this.strategies) {
140
+ config.strategy.stop();
141
+ }
142
+ // Stop tick
143
+ this.stopTick();
144
+ }
145
+ /**
146
+ * Reset all data
147
+ */
148
+ reset() {
149
+ this.confidenceScore = 0;
150
+ for (const [_, config] of this.strategies) {
151
+ config.strategy.reset();
152
+ }
153
+ }
154
+ /**
155
+ * Calculate human likelihood score
156
+ */
157
+ async score(options = {}) {
158
+ const breakdown = this.calculateStrategyScore();
159
+ const result = {
160
+ score: breakdown.overall,
161
+ };
162
+ if (options.breakdown) {
163
+ result.breakdown = breakdown;
164
+ }
165
+ // Note: auditTrail not available in strategy mode
166
+ // Each strategy manages its own data independently
167
+ return result;
168
+ }
169
+ /**
170
+ * Check if currently tracking
171
+ */
172
+ isActive() {
173
+ return this.isTracking;
174
+ }
175
+ /**
176
+ * Check if currently paused due to tab visibility
177
+ */
178
+ isPaused() {
179
+ return this.isPausedByVisibility;
180
+ }
181
+ /**
182
+ * Get event count from all strategies
183
+ */
184
+ getEventCount() {
185
+ var _a, _b;
186
+ const counts = {};
187
+ for (const [name, config] of this.strategies) {
188
+ const debug = (_b = (_a = config.strategy).getDebugInfo) === null || _b === void 0 ? void 0 : _b.call(_a);
189
+ if ((debug === null || debug === void 0 ? void 0 : debug.eventCount) !== undefined) {
190
+ counts[name] = debug.eventCount;
191
+ }
192
+ }
193
+ return counts;
194
+ }
195
+ /**
196
+ * Get debug info from all strategies
197
+ */
198
+ getStrategyDebugInfo() {
199
+ const debug = {};
200
+ for (const [name, config] of this.strategies) {
201
+ if (config.strategy.getDebugInfo) {
202
+ debug[name] = config.strategy.getDebugInfo();
203
+ }
204
+ }
205
+ return debug;
206
+ }
207
+ /**
208
+ * Get current confidence score (0-1)
209
+ * Represents how much interaction data we've collected
210
+ * Higher confidence = more reliable classification
211
+ */
212
+ getConfidence() {
213
+ return Math.min(1, this.confidenceScore);
214
+ }
215
+ /**
216
+ * Check if confidence is above threshold for reliable classification
217
+ * @param threshold - Minimum confidence (0-1), default 0.3
218
+ */
219
+ hasConfidentData(threshold = 0.3) {
220
+ return this.getConfidence() >= threshold;
221
+ }
222
+ /**
223
+ * Cleanup resources
224
+ */
225
+ destroy() {
226
+ this.stop();
227
+ this.strategies.clear();
228
+ }
229
+ /**
230
+ * Handle visibility change events
231
+ */
232
+ handleVisibilityChange() {
233
+ if (!this.isTracking)
234
+ return;
235
+ if (document.hidden) {
236
+ // Tab became hidden - pause detection
237
+ if (!this.isPausedByVisibility) {
238
+ this.isPausedByVisibility = true;
239
+ // Stop all strategies
240
+ for (const [_, config] of this.strategies) {
241
+ if (config.enabled) {
242
+ config.strategy.stop();
243
+ }
244
+ }
245
+ // Stop tick
246
+ this.stopTick();
247
+ }
248
+ }
249
+ else {
250
+ // Tab became visible - resume detection
251
+ if (this.isPausedByVisibility) {
252
+ this.isPausedByVisibility = false;
253
+ // Restart all enabled strategies
254
+ for (const [_, config] of this.strategies) {
255
+ if (config.enabled) {
256
+ config.strategy.start();
257
+ }
258
+ }
259
+ // Restart tick
260
+ this.startTick();
261
+ }
262
+ }
263
+ }
264
+ /**
265
+ * Start tick mechanism for strategies
266
+ */
267
+ startTick() {
268
+ if (this.tickInterval !== null)
269
+ return;
270
+ this.tickInterval = window.setInterval(() => {
271
+ const now = Date.now();
272
+ for (const [_, config] of this.strategies) {
273
+ if (config.enabled && config.strategy.onTick) {
274
+ config.strategy.onTick(now);
275
+ }
276
+ }
277
+ }, this.tickIntervalMs);
278
+ }
279
+ /**
280
+ * Stop tick mechanism
281
+ */
282
+ stopTick() {
283
+ if (this.tickInterval !== null) {
284
+ clearInterval(this.tickInterval);
285
+ this.tickInterval = null;
286
+ }
287
+ }
288
+ /**
289
+ * Calculate score using strategies
290
+ */
291
+ calculateStrategyScore() {
292
+ const factors = {};
293
+ const weights = {};
294
+ let totalWeight = 0;
295
+ let weightedSum = 0;
296
+ for (const [name, config] of this.strategies) {
297
+ if (!config.enabled)
298
+ continue;
299
+ const score = config.strategy.score();
300
+ factors[name] = score;
301
+ weights[name] = config.weight;
302
+ if (score !== undefined && score !== null) {
303
+ totalWeight += config.weight;
304
+ weightedSum += score * config.weight;
305
+ }
306
+ }
307
+ const overall = totalWeight > 0 ? weightedSum / totalWeight : 0.5;
308
+ return {
309
+ overall: Math.max(0, Math.min(1, overall)),
310
+ factors,
311
+ weights,
312
+ };
313
+ }
314
+ }
315
+ exports.BehaviorDetector = BehaviorDetector;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Browser Build - Auto-initializing standalone bundle for CDN usage
3
+ *
4
+ * Usage:
5
+ * <script src="https://cdn.../behavior-detector.js"></script>
6
+ * <script>
7
+ * window.bdSettings = {
8
+ * strategies: {
9
+ * mouse: { weight: 0.3 },
10
+ * scroll: { weight: 0.15 },
11
+ * click: { weight: 0.3 },
12
+ * keyboard: { weight: 0.1 },
13
+ * environment: { weight: 0.08 },
14
+ * resize: { weight: 0.02 }
15
+ * },
16
+ * autoStart: true,
17
+ * checkMs: 2000,
18
+ * pauseOnHidden: true, // Auto-pause when tab hidden (default: true)
19
+ * onScore: (result) => {
20
+ * console.log('Human likelihood:', result.score);
21
+ * if (result.score < 0.3) {
22
+ * // Likely bot
23
+ * }
24
+ * },
25
+ * ifBot: (result) => {
26
+ * // Called when score < threshold
27
+ * console.warn('Bot detected:', result);
28
+ * },
29
+ * botThreshold: 0.3
30
+ * }
31
+ * </script>
32
+ */
33
+ export {};
@@ -0,0 +1,226 @@
1
+ "use strict";
2
+ /**
3
+ * Browser Build - Auto-initializing standalone bundle for CDN usage
4
+ *
5
+ * Usage:
6
+ * <script src="https://cdn.../behavior-detector.js"></script>
7
+ * <script>
8
+ * window.bdSettings = {
9
+ * strategies: {
10
+ * mouse: { weight: 0.3 },
11
+ * scroll: { weight: 0.15 },
12
+ * click: { weight: 0.3 },
13
+ * keyboard: { weight: 0.1 },
14
+ * environment: { weight: 0.08 },
15
+ * resize: { weight: 0.02 }
16
+ * },
17
+ * autoStart: true,
18
+ * checkMs: 2000,
19
+ * pauseOnHidden: true, // Auto-pause when tab hidden (default: true)
20
+ * onScore: (result) => {
21
+ * console.log('Human likelihood:', result.score);
22
+ * if (result.score < 0.3) {
23
+ * // Likely bot
24
+ * }
25
+ * },
26
+ * ifBot: (result) => {
27
+ * // Called when score < threshold
28
+ * console.warn('Bot detected:', result);
29
+ * },
30
+ * botThreshold: 0.3
31
+ * }
32
+ * </script>
33
+ */
34
+ Object.defineProperty(exports, "__esModule", { value: true });
35
+ const behavior_detector_1 = require("./behavior-detector");
36
+ const index_js_1 = require("./strategies/index.js");
37
+ /**
38
+ * Detect if the current device is mobile
39
+ */
40
+ function isMobileDevice() {
41
+ const hasTouchScreen = navigator.maxTouchPoints > 0 || 'ontouchstart' in window;
42
+ const mobileUA = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
43
+ const smallScreen = window.innerWidth < 768 && window.innerHeight < 1024;
44
+ return (hasTouchScreen && smallScreen) || mobileUA;
45
+ }
46
+ class BehaviorDetectionAPI {
47
+ constructor() {
48
+ this.detector = null;
49
+ this.checkInterval = null;
50
+ this.settings = null;
51
+ }
52
+ /**
53
+ * Initialize the detector with settings
54
+ */
55
+ init(settings) {
56
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
57
+ if (this.detector) {
58
+ this.stop();
59
+ }
60
+ this.settings = settings;
61
+ this.detector = new behavior_detector_1.BehaviorDetector({
62
+ pauseOnHidden: settings.pauseOnHidden !== undefined ? settings.pauseOnHidden : true
63
+ });
64
+ // Detect if mobile to adjust strategy selection and weights
65
+ const isMobile = isMobileDevice();
66
+ const strategies = settings.strategies || {};
67
+ // Mobile-adjusted default weights
68
+ const defaultWeights = isMobile ? {
69
+ mouse: 0, // Disabled on mobile
70
+ scroll: 0.35, // Increased (more reliable on mobile)
71
+ click: 0, // Disabled on mobile (use tap instead)
72
+ tap: 0.35, // Mobile tap detection
73
+ keyboard: 0.15,
74
+ environment: 0.10,
75
+ resize: 0.05, // Orientation changes
76
+ } : {
77
+ mouse: 0.30,
78
+ scroll: 0.15,
79
+ click: 0.30,
80
+ tap: 0, // Disabled on desktop
81
+ keyboard: 0.10,
82
+ environment: 0.08,
83
+ resize: 0.02,
84
+ };
85
+ // Mouse - Desktop only
86
+ if (!isMobile && ((_a = strategies.mouse) === null || _a === void 0 ? void 0 : _a.enabled) !== false) {
87
+ const strategy = new index_js_1.MouseStrategy();
88
+ const weight = (_c = (_b = strategies.mouse) === null || _b === void 0 ? void 0 : _b.weight) !== null && _c !== void 0 ? _c : defaultWeights.mouse;
89
+ this.detector.addStrategy(strategy, weight);
90
+ }
91
+ // Scroll - Universal
92
+ if (((_d = strategies.scroll) === null || _d === void 0 ? void 0 : _d.enabled) !== false) {
93
+ const strategy = new index_js_1.ScrollStrategy();
94
+ const weight = (_f = (_e = strategies.scroll) === null || _e === void 0 ? void 0 : _e.weight) !== null && _f !== void 0 ? _f : defaultWeights.scroll;
95
+ this.detector.addStrategy(strategy, weight);
96
+ }
97
+ // Click - Desktop only
98
+ if (!isMobile && ((_g = strategies.click) === null || _g === void 0 ? void 0 : _g.enabled) !== false) {
99
+ const strategy = new index_js_1.ClickStrategy();
100
+ const weight = (_j = (_h = strategies.click) === null || _h === void 0 ? void 0 : _h.weight) !== null && _j !== void 0 ? _j : defaultWeights.click;
101
+ this.detector.addStrategy(strategy, weight);
102
+ }
103
+ // Tap - Mobile only
104
+ if (isMobile && ((_k = strategies.tap) === null || _k === void 0 ? void 0 : _k.enabled) !== false) {
105
+ const strategy = new index_js_1.TapStrategy();
106
+ const weight = (_m = (_l = strategies.tap) === null || _l === void 0 ? void 0 : _l.weight) !== null && _m !== void 0 ? _m : defaultWeights.tap;
107
+ this.detector.addStrategy(strategy, weight);
108
+ }
109
+ // Keyboard - Universal
110
+ if (((_o = strategies.keyboard) === null || _o === void 0 ? void 0 : _o.enabled) !== false) {
111
+ const strategy = new index_js_1.KeyboardStrategy();
112
+ const weight = (_q = (_p = strategies.keyboard) === null || _p === void 0 ? void 0 : _p.weight) !== null && _q !== void 0 ? _q : defaultWeights.keyboard;
113
+ this.detector.addStrategy(strategy, weight);
114
+ }
115
+ // Environment - Universal
116
+ if (((_r = strategies.environment) === null || _r === void 0 ? void 0 : _r.enabled) !== false) {
117
+ const strategy = new index_js_1.EnvironmentStrategy();
118
+ const weight = (_t = (_s = strategies.environment) === null || _s === void 0 ? void 0 : _s.weight) !== null && _t !== void 0 ? _t : defaultWeights.environment;
119
+ this.detector.addStrategy(strategy, weight);
120
+ }
121
+ // Resize - Universal
122
+ if (((_u = strategies.resize) === null || _u === void 0 ? void 0 : _u.enabled) !== false) {
123
+ const strategy = new index_js_1.ResizeStrategy();
124
+ const weight = (_w = (_v = strategies.resize) === null || _v === void 0 ? void 0 : _v.weight) !== null && _w !== void 0 ? _w : defaultWeights.resize;
125
+ this.detector.addStrategy(strategy, weight);
126
+ }
127
+ // Start if autoStart is enabled
128
+ if (settings.autoStart !== false) {
129
+ this.start();
130
+ }
131
+ // Set up periodic checking if checkMs is specified
132
+ if (settings.checkMs && settings.checkMs > 0) {
133
+ this.startPeriodicCheck(settings.checkMs);
134
+ }
135
+ // Call onReady callback
136
+ if (settings.onReady) {
137
+ settings.onReady(this);
138
+ }
139
+ }
140
+ /**
141
+ * Start detection
142
+ */
143
+ start() {
144
+ if (!this.detector) {
145
+ console.warn('BehaviorDetector: Call init() before start()');
146
+ return;
147
+ }
148
+ this.detector.start();
149
+ }
150
+ /**
151
+ * Stop detection
152
+ */
153
+ stop() {
154
+ if (this.detector) {
155
+ this.detector.stop();
156
+ }
157
+ if (this.checkInterval !== null) {
158
+ clearInterval(this.checkInterval);
159
+ this.checkInterval = null;
160
+ }
161
+ }
162
+ /**
163
+ * Get current score
164
+ */
165
+ async score() {
166
+ if (!this.detector) {
167
+ console.warn('BehaviorDetector: Call init() before score()');
168
+ return null;
169
+ }
170
+ return this.detector.score({ breakdown: true });
171
+ }
172
+ /**
173
+ * Start periodic checking
174
+ */
175
+ startPeriodicCheck(intervalMs) {
176
+ if (this.checkInterval !== null) {
177
+ clearInterval(this.checkInterval);
178
+ }
179
+ this.checkInterval = window.setInterval(async () => {
180
+ var _a, _b;
181
+ const result = await this.score();
182
+ if (!result || !this.settings)
183
+ return;
184
+ // Call onScore callback
185
+ if (this.settings.onScore) {
186
+ this.settings.onScore(result);
187
+ }
188
+ // Check thresholds
189
+ const botThreshold = (_a = this.settings.botThreshold) !== null && _a !== void 0 ? _a : 0.3;
190
+ const humanThreshold = (_b = this.settings.humanThreshold) !== null && _b !== void 0 ? _b : 0.7;
191
+ if (result.score < botThreshold && this.settings.ifBot) {
192
+ this.settings.ifBot(result);
193
+ }
194
+ else if (result.score >= humanThreshold && this.settings.ifHuman) {
195
+ this.settings.ifHuman(result);
196
+ }
197
+ }, intervalMs);
198
+ }
199
+ /**
200
+ * Get the underlying detector instance for advanced usage
201
+ */
202
+ getDetector() {
203
+ return this.detector;
204
+ }
205
+ }
206
+ // Create global API instance
207
+ const api = new BehaviorDetectionAPI();
208
+ // Auto-initialize if settings are already present
209
+ if (typeof window !== 'undefined') {
210
+ // Expose API globally
211
+ window.BehaviorDetector = api;
212
+ // Check for settings on load
213
+ const checkAndInit = () => {
214
+ const settings = window.bdSettings;
215
+ if (settings) {
216
+ api.init(settings);
217
+ }
218
+ };
219
+ // Try immediate init
220
+ checkAndInit();
221
+ // Also try after DOM ready
222
+ if (document.readyState === 'loading') {
223
+ document.addEventListener('DOMContentLoaded', checkAndInit);
224
+ }
225
+ }
226
+ // No exports needed for browser IIFE build - window.BehaviorDetector is sufficient
@@ -0,0 +1,38 @@
1
+ /**
2
+ * @axeptio/behavior-detection
3
+ *
4
+ * Lightweight behavior detection library to assess human likelihood of user sessions
5
+ *
6
+ * @example Settings-based (all strategies included)
7
+ * ```ts
8
+ * import { BehaviorDetector } from '@axeptio/behavior-detection';
9
+ *
10
+ * const detector = new BehaviorDetector({
11
+ * weights: {
12
+ * mouseMovement: 0.3,
13
+ * clickAccuracy: 0.3,
14
+ * },
15
+ * });
16
+ *
17
+ * detector.start();
18
+ * const result = await detector.score({ breakdown: true });
19
+ * ```
20
+ *
21
+ * @example Strategy-based (tree-shakeable, import only what you need)
22
+ * ```ts
23
+ * import { BehaviorDetector, Mouse, Click, Keyboard } from '@axeptio/behavior-detection';
24
+ *
25
+ * const detector = new BehaviorDetector()
26
+ * .addStrategy(new Mouse())
27
+ * .addStrategy(new Click())
28
+ * .addStrategy(new Keyboard());
29
+ *
30
+ * detector.start();
31
+ * const result = await detector.score();
32
+ * ```
33
+ */
34
+ export { BehaviorDetector } from './behavior-detector';
35
+ export type { DetectionStrategy, StrategyConfig } from './strategy';
36
+ export { Mouse, Scroll, Click, Tap, Keyboard, Environment, Resize, MouseStrategy, ScrollStrategy, ClickStrategy, TapStrategy, KeyboardStrategy, EnvironmentStrategy, ResizeStrategy, } from './strategies/index.js';
37
+ export type { BehaviorSettings, ScoreOptions, ScoreResult, ScoreBreakdown, TrackedEvent, EventType, ScoringFunction, } from './types';
38
+ export { DEFAULT_SETTINGS } from './types';
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ /**
3
+ * @axeptio/behavior-detection
4
+ *
5
+ * Lightweight behavior detection library to assess human likelihood of user sessions
6
+ *
7
+ * @example Settings-based (all strategies included)
8
+ * ```ts
9
+ * import { BehaviorDetector } from '@axeptio/behavior-detection';
10
+ *
11
+ * const detector = new BehaviorDetector({
12
+ * weights: {
13
+ * mouseMovement: 0.3,
14
+ * clickAccuracy: 0.3,
15
+ * },
16
+ * });
17
+ *
18
+ * detector.start();
19
+ * const result = await detector.score({ breakdown: true });
20
+ * ```
21
+ *
22
+ * @example Strategy-based (tree-shakeable, import only what you need)
23
+ * ```ts
24
+ * import { BehaviorDetector, Mouse, Click, Keyboard } from '@axeptio/behavior-detection';
25
+ *
26
+ * const detector = new BehaviorDetector()
27
+ * .addStrategy(new Mouse())
28
+ * .addStrategy(new Click())
29
+ * .addStrategy(new Keyboard());
30
+ *
31
+ * detector.start();
32
+ * const result = await detector.score();
33
+ * ```
34
+ */
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DEFAULT_SETTINGS = exports.ResizeStrategy = exports.EnvironmentStrategy = exports.KeyboardStrategy = exports.TapStrategy = exports.ClickStrategy = exports.ScrollStrategy = exports.MouseStrategy = exports.Resize = exports.Environment = exports.Keyboard = exports.Tap = exports.Click = exports.Scroll = exports.Mouse = exports.BehaviorDetector = void 0;
37
+ var behavior_detector_1 = require("./behavior-detector");
38
+ Object.defineProperty(exports, "BehaviorDetector", { enumerable: true, get: function () { return behavior_detector_1.BehaviorDetector; } });
39
+ var index_js_1 = require("./strategies/index.js");
40
+ Object.defineProperty(exports, "Mouse", { enumerable: true, get: function () { return index_js_1.Mouse; } });
41
+ Object.defineProperty(exports, "Scroll", { enumerable: true, get: function () { return index_js_1.Scroll; } });
42
+ Object.defineProperty(exports, "Click", { enumerable: true, get: function () { return index_js_1.Click; } });
43
+ Object.defineProperty(exports, "Tap", { enumerable: true, get: function () { return index_js_1.Tap; } });
44
+ Object.defineProperty(exports, "Keyboard", { enumerable: true, get: function () { return index_js_1.Keyboard; } });
45
+ Object.defineProperty(exports, "Environment", { enumerable: true, get: function () { return index_js_1.Environment; } });
46
+ Object.defineProperty(exports, "Resize", { enumerable: true, get: function () { return index_js_1.Resize; } });
47
+ Object.defineProperty(exports, "MouseStrategy", { enumerable: true, get: function () { return index_js_1.MouseStrategy; } });
48
+ Object.defineProperty(exports, "ScrollStrategy", { enumerable: true, get: function () { return index_js_1.ScrollStrategy; } });
49
+ Object.defineProperty(exports, "ClickStrategy", { enumerable: true, get: function () { return index_js_1.ClickStrategy; } });
50
+ Object.defineProperty(exports, "TapStrategy", { enumerable: true, get: function () { return index_js_1.TapStrategy; } });
51
+ Object.defineProperty(exports, "KeyboardStrategy", { enumerable: true, get: function () { return index_js_1.KeyboardStrategy; } });
52
+ Object.defineProperty(exports, "EnvironmentStrategy", { enumerable: true, get: function () { return index_js_1.EnvironmentStrategy; } });
53
+ Object.defineProperty(exports, "ResizeStrategy", { enumerable: true, get: function () { return index_js_1.ResizeStrategy; } });
54
+ var types_1 = require("./types");
55
+ Object.defineProperty(exports, "DEFAULT_SETTINGS", { enumerable: true, get: function () { return types_1.DEFAULT_SETTINGS; } });