@tracelog/lib 0.0.8 → 0.2.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.
- package/README.md +58 -24
- package/dist/browser/tracelog.js +1934 -3226
- package/dist/cjs/api.d.ts +33 -19
- package/dist/cjs/api.js +111 -156
- package/dist/cjs/app.constants.d.ts +80 -1
- package/dist/cjs/app.constants.js +90 -3
- package/dist/cjs/app.d.ts +29 -44
- package/dist/cjs/app.js +114 -212
- package/dist/cjs/app.types.d.ts +2 -7
- package/dist/cjs/app.types.js +10 -21
- package/dist/cjs/constants/api.constants.js +11 -5
- package/dist/cjs/constants/config.constants.d.ts +75 -0
- package/dist/cjs/constants/config.constants.js +178 -0
- package/dist/cjs/constants/error.constants.d.ts +29 -0
- package/dist/cjs/constants/error.constants.js +50 -0
- package/dist/cjs/constants/index.d.ts +3 -6
- package/dist/cjs/constants/index.js +3 -6
- package/dist/cjs/constants/performance.constants.d.ts +28 -0
- package/dist/cjs/constants/performance.constants.js +43 -0
- package/dist/cjs/handlers/click.handler.d.ts +1 -0
- package/dist/cjs/handlers/click.handler.js +30 -49
- package/dist/cjs/handlers/error.handler.d.ts +11 -6
- package/dist/cjs/handlers/error.handler.js +91 -51
- package/dist/cjs/handlers/page-view.handler.js +38 -29
- package/dist/cjs/handlers/performance.handler.d.ts +3 -0
- package/dist/cjs/handlers/performance.handler.js +76 -37
- package/dist/cjs/handlers/scroll.handler.d.ts +15 -0
- package/dist/cjs/handlers/scroll.handler.js +105 -31
- package/dist/cjs/handlers/session.handler.d.ts +6 -20
- package/dist/cjs/handlers/session.handler.js +38 -326
- package/dist/cjs/integrations/google-analytics.integration.d.ts +0 -1
- package/dist/cjs/integrations/google-analytics.integration.js +27 -98
- package/dist/cjs/listeners/input-listener-managers.d.ts +18 -9
- package/dist/cjs/listeners/input-listener-managers.js +24 -33
- package/dist/cjs/listeners/touch-listener-manager.d.ts +1 -3
- package/dist/cjs/listeners/touch-listener-manager.js +1 -23
- package/dist/cjs/listeners/visibility-listener-manager.d.ts +1 -4
- package/dist/cjs/listeners/visibility-listener-manager.js +6 -42
- package/dist/cjs/managers/api.manager.d.ts +13 -3
- package/dist/cjs/managers/api.manager.js +35 -5
- package/dist/cjs/managers/config.manager.d.ts +53 -3
- package/dist/cjs/managers/config.manager.js +131 -62
- package/dist/cjs/managers/event.manager.d.ts +57 -36
- package/dist/cjs/managers/event.manager.js +266 -417
- package/dist/cjs/managers/sender.manager.d.ts +40 -22
- package/dist/cjs/managers/sender.manager.js +200 -198
- package/dist/cjs/managers/session.manager.d.ts +80 -66
- package/dist/cjs/managers/session.manager.js +267 -522
- package/dist/cjs/managers/state.manager.d.ts +33 -0
- package/dist/cjs/managers/state.manager.js +79 -6
- package/dist/cjs/managers/storage.manager.d.ts +26 -2
- package/dist/cjs/managers/storage.manager.js +67 -34
- package/dist/cjs/managers/tags.manager.d.ts +31 -7
- package/dist/cjs/managers/tags.manager.js +123 -241
- package/dist/cjs/managers/user.manager.d.ts +14 -5
- package/dist/cjs/managers/user.manager.js +17 -9
- package/dist/cjs/public-api.d.ts +10 -1
- package/dist/cjs/public-api.js +18 -24
- package/dist/cjs/test-bridge.d.ts +48 -0
- package/dist/cjs/test-bridge.js +110 -0
- package/dist/cjs/types/api.types.d.ts +21 -6
- package/dist/cjs/types/api.types.js +21 -6
- package/dist/cjs/types/config.types.d.ts +22 -84
- package/dist/cjs/types/emitter.types.d.ts +11 -0
- package/dist/cjs/types/emitter.types.js +8 -0
- package/dist/cjs/types/event.types.d.ts +8 -11
- package/dist/cjs/types/index.d.ts +3 -1
- package/dist/cjs/types/index.js +3 -1
- package/dist/cjs/types/queue.types.d.ts +1 -0
- package/dist/cjs/types/session.types.d.ts +0 -64
- package/dist/cjs/types/state.types.d.ts +1 -0
- package/dist/cjs/types/test-bridge.types.d.ts +38 -0
- package/dist/cjs/types/validation-error.types.d.ts +7 -0
- package/dist/cjs/types/validation-error.types.js +11 -1
- package/dist/cjs/types/window.types.d.ts +1 -8
- package/dist/cjs/utils/data/uuid.utils.d.ts +1 -1
- package/dist/cjs/utils/data/uuid.utils.js +7 -5
- package/dist/cjs/utils/emitter.utils.d.ts +8 -0
- package/dist/cjs/utils/emitter.utils.js +33 -0
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +1 -0
- package/dist/cjs/utils/logging/debug-logger.utils.d.ts +10 -51
- package/dist/cjs/utils/logging/debug-logger.utils.js +36 -127
- package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +4 -0
- package/dist/cjs/utils/network/fetch-with-timeout.utils.js +25 -0
- package/dist/cjs/utils/network/index.d.ts +1 -0
- package/dist/cjs/utils/network/index.js +1 -0
- package/dist/cjs/utils/network/url.utils.js +2 -42
- package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -8
- package/dist/cjs/utils/security/sanitize.utils.js +7 -41
- package/dist/cjs/utils/validations/config-validations.utils.d.ts +7 -0
- package/dist/cjs/utils/validations/config-validations.utils.js +77 -22
- package/dist/esm/api.d.ts +33 -19
- package/dist/esm/api.js +105 -118
- package/dist/esm/app.constants.d.ts +80 -1
- package/dist/esm/app.constants.js +89 -1
- package/dist/esm/app.d.ts +29 -44
- package/dist/esm/app.js +115 -213
- package/dist/esm/app.types.d.ts +2 -7
- package/dist/esm/app.types.js +1 -7
- package/dist/esm/constants/api.constants.js +10 -4
- package/dist/esm/constants/config.constants.d.ts +75 -0
- package/dist/esm/constants/config.constants.js +174 -0
- package/dist/esm/constants/error.constants.d.ts +29 -0
- package/dist/esm/constants/error.constants.js +47 -0
- package/dist/esm/constants/index.d.ts +3 -6
- package/dist/esm/constants/index.js +3 -6
- package/dist/esm/constants/performance.constants.d.ts +28 -0
- package/dist/esm/constants/performance.constants.js +40 -0
- package/dist/esm/handlers/click.handler.d.ts +1 -0
- package/dist/esm/handlers/click.handler.js +30 -49
- package/dist/esm/handlers/error.handler.d.ts +11 -6
- package/dist/esm/handlers/error.handler.js +91 -51
- package/dist/esm/handlers/page-view.handler.js +38 -29
- package/dist/esm/handlers/performance.handler.d.ts +3 -0
- package/dist/esm/handlers/performance.handler.js +71 -32
- package/dist/esm/handlers/scroll.handler.d.ts +15 -0
- package/dist/esm/handlers/scroll.handler.js +106 -32
- package/dist/esm/handlers/session.handler.d.ts +6 -20
- package/dist/esm/handlers/session.handler.js +38 -326
- package/dist/esm/integrations/google-analytics.integration.d.ts +0 -1
- package/dist/esm/integrations/google-analytics.integration.js +27 -98
- package/dist/esm/listeners/input-listener-managers.d.ts +18 -9
- package/dist/esm/listeners/input-listener-managers.js +23 -32
- package/dist/esm/listeners/touch-listener-manager.d.ts +1 -3
- package/dist/esm/listeners/touch-listener-manager.js +1 -23
- package/dist/esm/listeners/visibility-listener-manager.d.ts +1 -4
- package/dist/esm/listeners/visibility-listener-manager.js +6 -42
- package/dist/esm/managers/api.manager.d.ts +13 -3
- package/dist/esm/managers/api.manager.js +34 -3
- package/dist/esm/managers/config.manager.d.ts +53 -3
- package/dist/esm/managers/config.manager.js +133 -64
- package/dist/esm/managers/event.manager.d.ts +57 -36
- package/dist/esm/managers/event.manager.js +268 -419
- package/dist/esm/managers/sender.manager.d.ts +40 -22
- package/dist/esm/managers/sender.manager.js +201 -199
- package/dist/esm/managers/session.manager.d.ts +80 -66
- package/dist/esm/managers/session.manager.js +269 -524
- package/dist/esm/managers/state.manager.d.ts +33 -0
- package/dist/esm/managers/state.manager.js +78 -6
- package/dist/esm/managers/storage.manager.d.ts +26 -2
- package/dist/esm/managers/storage.manager.js +66 -33
- package/dist/esm/managers/tags.manager.d.ts +31 -7
- package/dist/esm/managers/tags.manager.js +124 -242
- package/dist/esm/managers/user.manager.d.ts +14 -5
- package/dist/esm/managers/user.manager.js +17 -9
- package/dist/esm/public-api.d.ts +10 -1
- package/dist/esm/public-api.js +14 -1
- package/dist/esm/test-bridge.d.ts +48 -0
- package/dist/esm/test-bridge.js +106 -0
- package/dist/esm/types/api.types.d.ts +21 -6
- package/dist/esm/types/api.types.js +21 -6
- package/dist/esm/types/config.types.d.ts +22 -84
- package/dist/esm/types/emitter.types.d.ts +11 -0
- package/dist/esm/types/emitter.types.js +5 -0
- package/dist/esm/types/event.types.d.ts +8 -11
- package/dist/esm/types/index.d.ts +3 -1
- package/dist/esm/types/index.js +3 -1
- package/dist/esm/types/queue.types.d.ts +1 -0
- package/dist/esm/types/session.types.d.ts +0 -64
- package/dist/esm/types/state.types.d.ts +1 -0
- package/dist/esm/types/test-bridge.types.d.ts +38 -0
- package/dist/esm/types/validation-error.types.d.ts +7 -0
- package/dist/esm/types/validation-error.types.js +9 -0
- package/dist/esm/types/window.types.d.ts +1 -8
- package/dist/esm/utils/data/uuid.utils.d.ts +1 -1
- package/dist/esm/utils/data/uuid.utils.js +7 -5
- package/dist/esm/utils/emitter.utils.d.ts +8 -0
- package/dist/esm/utils/emitter.utils.js +29 -0
- package/dist/esm/utils/index.d.ts +1 -0
- package/dist/esm/utils/index.js +1 -0
- package/dist/esm/utils/logging/debug-logger.utils.d.ts +10 -51
- package/dist/esm/utils/logging/debug-logger.utils.js +36 -127
- package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +4 -0
- package/dist/esm/utils/network/fetch-with-timeout.utils.js +22 -0
- package/dist/esm/utils/network/index.d.ts +1 -0
- package/dist/esm/utils/network/index.js +1 -0
- package/dist/esm/utils/network/url.utils.js +2 -42
- package/dist/esm/utils/security/sanitize.utils.d.ts +1 -8
- package/dist/esm/utils/security/sanitize.utils.js +6 -39
- package/dist/esm/utils/validations/config-validations.utils.d.ts +7 -0
- package/dist/esm/utils/validations/config-validations.utils.js +76 -22
- package/package.json +23 -16
- package/dist/browser/web-vitals-CCnqwnC8.mjs +0 -198
- package/dist/cjs/constants/browser.constants.d.ts +0 -3
- package/dist/cjs/constants/browser.constants.js +0 -41
- package/dist/cjs/constants/initialization.constants.d.ts +0 -40
- package/dist/cjs/constants/initialization.constants.js +0 -48
- package/dist/cjs/constants/limits.constants.d.ts +0 -25
- package/dist/cjs/constants/limits.constants.js +0 -40
- package/dist/cjs/constants/security.constants.d.ts +0 -1
- package/dist/cjs/constants/security.constants.js +0 -12
- package/dist/cjs/constants/timing.constants.d.ts +0 -22
- package/dist/cjs/constants/timing.constants.js +0 -34
- package/dist/cjs/constants/validation.constants.d.ts +0 -13
- package/dist/cjs/constants/validation.constants.js +0 -31
- package/dist/cjs/handlers/network.handler.d.ts +0 -16
- package/dist/cjs/handlers/network.handler.js +0 -136
- package/dist/cjs/managers/cross-tab-session.manager.d.ts +0 -170
- package/dist/cjs/managers/cross-tab-session.manager.js +0 -730
- package/dist/cjs/managers/sampling.manager.d.ts +0 -8
- package/dist/cjs/managers/sampling.manager.js +0 -53
- package/dist/cjs/managers/session-recovery.manager.d.ts +0 -65
- package/dist/cjs/managers/session-recovery.manager.js +0 -237
- package/dist/cjs/types/web-vitals.types.d.ts +0 -6
- package/dist/esm/constants/browser.constants.d.ts +0 -3
- package/dist/esm/constants/browser.constants.js +0 -38
- package/dist/esm/constants/initialization.constants.d.ts +0 -40
- package/dist/esm/constants/initialization.constants.js +0 -45
- package/dist/esm/constants/limits.constants.d.ts +0 -25
- package/dist/esm/constants/limits.constants.js +0 -37
- package/dist/esm/constants/security.constants.d.ts +0 -1
- package/dist/esm/constants/security.constants.js +0 -9
- package/dist/esm/constants/timing.constants.d.ts +0 -22
- package/dist/esm/constants/timing.constants.js +0 -31
- package/dist/esm/constants/validation.constants.d.ts +0 -13
- package/dist/esm/constants/validation.constants.js +0 -28
- package/dist/esm/handlers/network.handler.d.ts +0 -16
- package/dist/esm/handlers/network.handler.js +0 -132
- package/dist/esm/managers/cross-tab-session.manager.d.ts +0 -170
- package/dist/esm/managers/cross-tab-session.manager.js +0 -726
- package/dist/esm/managers/sampling.manager.d.ts +0 -8
- package/dist/esm/managers/sampling.manager.js +0 -49
- package/dist/esm/managers/session-recovery.manager.d.ts +0 -65
- package/dist/esm/managers/session-recovery.manager.js +0 -233
- package/dist/esm/types/web-vitals.types.d.ts +0 -6
- /package/dist/cjs/types/{web-vitals.types.js → test-bridge.types.js} +0 -0
- /package/dist/esm/types/{web-vitals.types.js → test-bridge.types.js} +0 -0
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consolidated configuration constants for TraceLog
|
|
3
|
+
* This file centralizes all timing, limits, browser, and initialization constants
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// SESSION & TIMING
|
|
7
|
+
// ============================================================================
|
|
8
|
+
export const DEFAULT_SESSION_TIMEOUT = 15 * 60 * 1000; // 15 minutes
|
|
9
|
+
export const DUPLICATE_EVENT_THRESHOLD_MS = 1000; // 1 second
|
|
10
|
+
export const EVENT_SENT_INTERVAL_MS = 10000; // 10 seconds
|
|
11
|
+
// Throttling and debouncing
|
|
12
|
+
export const SCROLL_DEBOUNCE_TIME_MS = 250;
|
|
13
|
+
export const DEFAULT_VISIBILITY_TIMEOUT_MS = 2000;
|
|
14
|
+
// Event expiry
|
|
15
|
+
export const EVENT_EXPIRY_HOURS = 24;
|
|
16
|
+
export const EVENT_PERSISTENCE_MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
17
|
+
// ============================================================================
|
|
18
|
+
// LIMITS & RETRIES
|
|
19
|
+
// ============================================================================
|
|
20
|
+
export const MAX_EVENTS_QUEUE_LENGTH = 500;
|
|
21
|
+
export const MAX_RETRIES = 3;
|
|
22
|
+
export const RETRY_DELAY_MS = 5000;
|
|
23
|
+
export const REQUEST_TIMEOUT_MS = 10000;
|
|
24
|
+
export const MAX_METADATA_SIZE = 5000;
|
|
25
|
+
// Motion and interaction thresholds
|
|
26
|
+
export const DEFAULT_MOTION_THRESHOLD = 2;
|
|
27
|
+
export const SIGNIFICANT_SCROLL_DELTA = 10;
|
|
28
|
+
export const MIN_SCROLL_DEPTH_CHANGE = 5;
|
|
29
|
+
export const SCROLL_MIN_EVENT_INTERVAL_MS = 500;
|
|
30
|
+
export const MAX_SCROLL_EVENTS_PER_SESSION = 120;
|
|
31
|
+
// Sampling and rate limits
|
|
32
|
+
export const DEFAULT_SAMPLING_RATE = 1;
|
|
33
|
+
export const MIN_SAMPLING_RATE = 0;
|
|
34
|
+
export const MAX_SAMPLING_RATE = 1;
|
|
35
|
+
// Queue and batch limits
|
|
36
|
+
export const BATCH_SIZE_THRESHOLD = 50;
|
|
37
|
+
// Session timeout validation limits
|
|
38
|
+
export const MIN_SESSION_TIMEOUT_MS = 30000; // 30 seconds minimum
|
|
39
|
+
export const MAX_SESSION_TIMEOUT_MS = 86400000; // 24 hours maximum
|
|
40
|
+
// Custom event validation limits
|
|
41
|
+
export const MAX_CUSTOM_EVENT_NAME_LENGTH = 120;
|
|
42
|
+
export const MAX_CUSTOM_EVENT_STRING_SIZE = 8 * 1024; // 8KB
|
|
43
|
+
export const MAX_CUSTOM_EVENT_KEYS = 10;
|
|
44
|
+
export const MAX_CUSTOM_EVENT_ARRAY_SIZE = 10;
|
|
45
|
+
// Text content limits
|
|
46
|
+
export const MAX_TEXT_LENGTH = 255; // For click tracking text content
|
|
47
|
+
// Data sanitization limits
|
|
48
|
+
export const MAX_STRING_LENGTH = 1000;
|
|
49
|
+
export const MAX_ARRAY_LENGTH = 100;
|
|
50
|
+
export const MAX_OBJECT_DEPTH = 3;
|
|
51
|
+
// Precision for numeric metrics
|
|
52
|
+
export const PRECISION_TWO_DECIMALS = 2;
|
|
53
|
+
// Sync XHR timeout
|
|
54
|
+
export const SYNC_XHR_TIMEOUT_MS = 2000; // 2 seconds
|
|
55
|
+
// Event fingerprint management
|
|
56
|
+
export const MAX_FINGERPRINTS = 1000; // Maximum fingerprints stored before cleanup
|
|
57
|
+
export const FINGERPRINT_CLEANUP_MULTIPLIER = 10; // Cleanup fingerprints older than 10x threshold
|
|
58
|
+
export const MAX_FINGERPRINTS_HARD_LIMIT = 2000; // Hard limit for aggressive cleanup
|
|
59
|
+
// ============================================================================
|
|
60
|
+
// BROWSER & HTML
|
|
61
|
+
// ============================================================================
|
|
62
|
+
export const HTML_DATA_ATTR_PREFIX = 'data-tl';
|
|
63
|
+
// Interactive element selectors for click tracking
|
|
64
|
+
export const INTERACTIVE_SELECTORS = [
|
|
65
|
+
'button',
|
|
66
|
+
'a',
|
|
67
|
+
'input[type="button"]',
|
|
68
|
+
'input[type="submit"]',
|
|
69
|
+
'input[type="reset"]',
|
|
70
|
+
'input[type="checkbox"]',
|
|
71
|
+
'input[type="radio"]',
|
|
72
|
+
'select',
|
|
73
|
+
'textarea',
|
|
74
|
+
'[role="button"]',
|
|
75
|
+
'[role="link"]',
|
|
76
|
+
'[role="tab"]',
|
|
77
|
+
'[role="menuitem"]',
|
|
78
|
+
'[role="option"]',
|
|
79
|
+
'[role="checkbox"]',
|
|
80
|
+
'[role="radio"]',
|
|
81
|
+
'[role="switch"]',
|
|
82
|
+
'[routerLink]',
|
|
83
|
+
'[ng-click]',
|
|
84
|
+
'[data-action]',
|
|
85
|
+
'[data-click]',
|
|
86
|
+
'[data-navigate]',
|
|
87
|
+
'[data-toggle]',
|
|
88
|
+
'[onclick]',
|
|
89
|
+
'.btn',
|
|
90
|
+
'.button',
|
|
91
|
+
'.clickable',
|
|
92
|
+
'.nav-link',
|
|
93
|
+
'.menu-item',
|
|
94
|
+
'[data-testid]',
|
|
95
|
+
'[tabindex="0"]',
|
|
96
|
+
];
|
|
97
|
+
// UTM parameters for tracking
|
|
98
|
+
export const UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content'];
|
|
99
|
+
// ============================================================================
|
|
100
|
+
// ============================================================================
|
|
101
|
+
// INITIALIZATION
|
|
102
|
+
// ============================================================================
|
|
103
|
+
export const INITIALIZATION_MAX_CONCURRENT_RETRIES = 20;
|
|
104
|
+
export const INITIALIZATION_CONCURRENT_RETRY_DELAY_MS = 50;
|
|
105
|
+
export const INITIALIZATION_TIMEOUT_MS = 10000;
|
|
106
|
+
// ============================================================================
|
|
107
|
+
// SESSION MANAGEMENT
|
|
108
|
+
// ============================================================================
|
|
109
|
+
export const SESSION_SYNC_TIMEOUT_MS = 2000;
|
|
110
|
+
export const SESSION_MAX_RETRY_ATTEMPTS = 3;
|
|
111
|
+
export const SESSION_CLEANUP_DELAY_MS = 100;
|
|
112
|
+
// Cross-tab coordination
|
|
113
|
+
export const CROSS_TAB_INITIALIZATION_LOCK_TIMEOUT_MS = 5000;
|
|
114
|
+
export const TAB_HEARTBEAT_INTERVAL_MS = 5000; // 5 seconds
|
|
115
|
+
export const TAB_ELECTION_TIMEOUT_MS = 2000; // 2 seconds
|
|
116
|
+
export const TAB_CLEANUP_DELAY_MS = 1000; // 1 second
|
|
117
|
+
// Session recovery
|
|
118
|
+
export const SESSION_RECOVERY_WINDOW_MULTIPLIER = 2; // 2x session timeout
|
|
119
|
+
export const MAX_SESSION_RECOVERY_ATTEMPTS = 3;
|
|
120
|
+
export const MAX_SESSION_RECOVERY_WINDOW_MS = 24 * 60 * 60 * 1000; // 24 hours max
|
|
121
|
+
export const MIN_SESSION_RECOVERY_WINDOW_MS = 2 * 60 * 1000; // 2 minutes minimum
|
|
122
|
+
// ============================================================================
|
|
123
|
+
// SCROLL SUPPRESSION
|
|
124
|
+
// ============================================================================
|
|
125
|
+
export const SCROLL_SUPPRESS_MULTIPLIER = 2;
|
|
126
|
+
// ============================================================================
|
|
127
|
+
// NETWORK TIMING
|
|
128
|
+
// ============================================================================
|
|
129
|
+
export const RETRY_BACKOFF_INITIAL = 1000; // 1 second
|
|
130
|
+
export const RETRY_BACKOFF_MAX = 30000; // 30 seconds
|
|
131
|
+
export const RATE_LIMIT_INTERVAL = 1000; // 1 second
|
|
132
|
+
export const MAX_RETRY_ATTEMPTS = 10;
|
|
133
|
+
// ============================================================================
|
|
134
|
+
// VALIDATION
|
|
135
|
+
// ============================================================================
|
|
136
|
+
// Allowed API config keys for runtime validation
|
|
137
|
+
export const ALLOWED_API_CONFIG_KEYS = new Set([
|
|
138
|
+
'mode',
|
|
139
|
+
'tags',
|
|
140
|
+
'samplingRate',
|
|
141
|
+
'excludedUrlPaths',
|
|
142
|
+
'ipExcluded',
|
|
143
|
+
]);
|
|
144
|
+
// Validation error messages - standardized across all layers
|
|
145
|
+
export const VALIDATION_MESSAGES = {
|
|
146
|
+
// Project ID validation - consistent message across all layers
|
|
147
|
+
MISSING_PROJECT_ID: 'Project ID is required',
|
|
148
|
+
PROJECT_ID_EMPTY_AFTER_TRIM: 'Project ID is required',
|
|
149
|
+
// Session timeout validation
|
|
150
|
+
INVALID_SESSION_TIMEOUT: `Session timeout must be between ${MIN_SESSION_TIMEOUT_MS}ms (30 seconds) and ${MAX_SESSION_TIMEOUT_MS}ms (24 hours)`,
|
|
151
|
+
// Sampling rate validation
|
|
152
|
+
INVALID_SAMPLING_RATE: 'Sampling rate must be greater than 0 and less than or equal to 1',
|
|
153
|
+
INVALID_ERROR_SAMPLING_RATE: 'Error sampling must be between 0 and 1',
|
|
154
|
+
// Integration validation
|
|
155
|
+
INVALID_GOOGLE_ANALYTICS_ID: 'Google Analytics measurement ID is required when integration is enabled',
|
|
156
|
+
// UI validation
|
|
157
|
+
INVALID_SCROLL_CONTAINER_SELECTORS: 'Scroll container selectors must be valid CSS selectors',
|
|
158
|
+
// Global metadata validation
|
|
159
|
+
INVALID_GLOBAL_METADATA: 'Global metadata must be an object',
|
|
160
|
+
// Array validation
|
|
161
|
+
INVALID_SENSITIVE_QUERY_PARAMS: 'Sensitive query params must be an array of strings',
|
|
162
|
+
};
|
|
163
|
+
// ============================================================================
|
|
164
|
+
// SECURITY
|
|
165
|
+
// ============================================================================
|
|
166
|
+
// XSS protection patterns
|
|
167
|
+
export const XSS_PATTERNS = [
|
|
168
|
+
/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,
|
|
169
|
+
/javascript:/gi,
|
|
170
|
+
/on\w+\s*=/gi,
|
|
171
|
+
/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,
|
|
172
|
+
/<embed\b[^>]*>/gi,
|
|
173
|
+
/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi,
|
|
174
|
+
];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling and PII sanitization constants for TraceLog
|
|
3
|
+
* Centralizes patterns and limits for error tracking and data protection
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Regular expressions for detecting and sanitizing Personally Identifiable Information (PII)
|
|
7
|
+
* These patterns are used to replace sensitive information with [REDACTED] in error messages
|
|
8
|
+
*/
|
|
9
|
+
export declare const PII_PATTERNS: readonly [RegExp, RegExp, RegExp, RegExp];
|
|
10
|
+
/**
|
|
11
|
+
* Maximum length for error messages before truncation
|
|
12
|
+
* Prevents extremely long error messages from consuming excessive storage
|
|
13
|
+
*/
|
|
14
|
+
export declare const MAX_ERROR_MESSAGE_LENGTH = 500;
|
|
15
|
+
/**
|
|
16
|
+
* Time window for error suppression in milliseconds
|
|
17
|
+
* Prevents duplicate errors from flooding the system within this timeframe
|
|
18
|
+
*/
|
|
19
|
+
export declare const ERROR_SUPPRESSION_WINDOW_MS = 60000;
|
|
20
|
+
/**
|
|
21
|
+
* Maximum number of unique errors to track for suppression
|
|
22
|
+
* Prevents memory usage from growing indefinitely
|
|
23
|
+
*/
|
|
24
|
+
export declare const MAX_TRACKED_ERRORS = 50;
|
|
25
|
+
/**
|
|
26
|
+
* Default error sampling rate
|
|
27
|
+
* Controls what percentage of errors are actually reported
|
|
28
|
+
*/
|
|
29
|
+
export declare const DEFAULT_ERROR_SAMPLING_RATE = 0.1;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error handling and PII sanitization constants for TraceLog
|
|
3
|
+
* Centralizes patterns and limits for error tracking and data protection
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// PII SANITIZATION PATTERNS
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Regular expressions for detecting and sanitizing Personally Identifiable Information (PII)
|
|
10
|
+
* These patterns are used to replace sensitive information with [REDACTED] in error messages
|
|
11
|
+
*/
|
|
12
|
+
export const PII_PATTERNS = [
|
|
13
|
+
// Email addresses
|
|
14
|
+
/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/gi,
|
|
15
|
+
// US Phone numbers (various formats)
|
|
16
|
+
/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,
|
|
17
|
+
// Credit card numbers (16 digits with optional separators)
|
|
18
|
+
/\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,
|
|
19
|
+
// IBAN (International Bank Account Number)
|
|
20
|
+
/\b[A-Z]{2}\d{2}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/gi,
|
|
21
|
+
];
|
|
22
|
+
// ============================================================================
|
|
23
|
+
// ERROR TRACKING LIMITS
|
|
24
|
+
// ============================================================================
|
|
25
|
+
/**
|
|
26
|
+
* Maximum length for error messages before truncation
|
|
27
|
+
* Prevents extremely long error messages from consuming excessive storage
|
|
28
|
+
*/
|
|
29
|
+
export const MAX_ERROR_MESSAGE_LENGTH = 500;
|
|
30
|
+
/**
|
|
31
|
+
* Time window for error suppression in milliseconds
|
|
32
|
+
* Prevents duplicate errors from flooding the system within this timeframe
|
|
33
|
+
*/
|
|
34
|
+
export const ERROR_SUPPRESSION_WINDOW_MS = 60000; // 1 minute
|
|
35
|
+
/**
|
|
36
|
+
* Maximum number of unique errors to track for suppression
|
|
37
|
+
* Prevents memory usage from growing indefinitely
|
|
38
|
+
*/
|
|
39
|
+
export const MAX_TRACKED_ERRORS = 50;
|
|
40
|
+
// ============================================================================
|
|
41
|
+
// ERROR SAMPLING
|
|
42
|
+
// ============================================================================
|
|
43
|
+
/**
|
|
44
|
+
* Default error sampling rate
|
|
45
|
+
* Controls what percentage of errors are actually reported
|
|
46
|
+
*/
|
|
47
|
+
export const DEFAULT_ERROR_SAMPLING_RATE = 0.1; // 10% of errors
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
export * from './api.constants';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './initialization.constants';
|
|
4
|
-
export * from './limits.constants';
|
|
5
|
-
export * from './security.constants';
|
|
2
|
+
export * from './config.constants';
|
|
6
3
|
export * from './storage.constants';
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
4
|
+
export * from './performance.constants';
|
|
5
|
+
export * from './error.constants';
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
export * from './api.constants';
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './initialization.constants';
|
|
4
|
-
export * from './limits.constants';
|
|
5
|
-
export * from './security.constants';
|
|
2
|
+
export * from './config.constants';
|
|
6
3
|
export * from './storage.constants';
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
4
|
+
export * from './performance.constants';
|
|
5
|
+
export * from './error.constants';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance monitoring and web vitals constants for TraceLog
|
|
3
|
+
* Centralizes thresholds and configuration for performance tracking
|
|
4
|
+
*/
|
|
5
|
+
import { WebVitalType } from '../types';
|
|
6
|
+
/**
|
|
7
|
+
* Web Vitals thresholds in milliseconds (except CLS which is unitless)
|
|
8
|
+
* These define the minimum values required to report a web vital metric
|
|
9
|
+
*
|
|
10
|
+
* Based on Core Web Vitals standards:
|
|
11
|
+
* - LCP (Largest Contentful Paint): 4000ms threshold
|
|
12
|
+
* - FCP (First Contentful Paint): 1800ms threshold
|
|
13
|
+
* - CLS (Cumulative Layout Shift): 0.25 threshold (unitless)
|
|
14
|
+
* - INP (Interaction to Next Paint): 200ms threshold
|
|
15
|
+
* - TTFB (Time to First Byte): 600ms threshold
|
|
16
|
+
* - LONG_TASK: 50ms threshold for long task detection
|
|
17
|
+
*/
|
|
18
|
+
export declare const WEB_VITALS_THRESHOLDS: Record<WebVitalType, number>;
|
|
19
|
+
/**
|
|
20
|
+
* Long task throttling interval in milliseconds
|
|
21
|
+
* Prevents excessive long task events from being sent
|
|
22
|
+
*/
|
|
23
|
+
export declare const LONG_TASK_THROTTLE_MS = 1000;
|
|
24
|
+
/**
|
|
25
|
+
* Precision for performance metric values
|
|
26
|
+
* All performance metrics are rounded to 2 decimal places
|
|
27
|
+
*/
|
|
28
|
+
export declare const PERFORMANCE_PRECISION_DECIMALS: 2;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Performance monitoring and web vitals constants for TraceLog
|
|
3
|
+
* Centralizes thresholds and configuration for performance tracking
|
|
4
|
+
*/
|
|
5
|
+
// ============================================================================
|
|
6
|
+
// WEB VITALS THRESHOLDS
|
|
7
|
+
// ============================================================================
|
|
8
|
+
/**
|
|
9
|
+
* Web Vitals thresholds in milliseconds (except CLS which is unitless)
|
|
10
|
+
* These define the minimum values required to report a web vital metric
|
|
11
|
+
*
|
|
12
|
+
* Based on Core Web Vitals standards:
|
|
13
|
+
* - LCP (Largest Contentful Paint): 4000ms threshold
|
|
14
|
+
* - FCP (First Contentful Paint): 1800ms threshold
|
|
15
|
+
* - CLS (Cumulative Layout Shift): 0.25 threshold (unitless)
|
|
16
|
+
* - INP (Interaction to Next Paint): 200ms threshold
|
|
17
|
+
* - TTFB (Time to First Byte): 600ms threshold
|
|
18
|
+
* - LONG_TASK: 50ms threshold for long task detection
|
|
19
|
+
*/
|
|
20
|
+
export const WEB_VITALS_THRESHOLDS = {
|
|
21
|
+
LCP: 4000,
|
|
22
|
+
FCP: 1800,
|
|
23
|
+
CLS: 0.25,
|
|
24
|
+
INP: 200,
|
|
25
|
+
TTFB: 600,
|
|
26
|
+
LONG_TASK: 50,
|
|
27
|
+
};
|
|
28
|
+
// ============================================================================
|
|
29
|
+
// PERFORMANCE MONITORING LIMITS
|
|
30
|
+
// ============================================================================
|
|
31
|
+
/**
|
|
32
|
+
* Long task throttling interval in milliseconds
|
|
33
|
+
* Prevents excessive long task events from being sent
|
|
34
|
+
*/
|
|
35
|
+
export const LONG_TASK_THROTTLE_MS = 1000;
|
|
36
|
+
/**
|
|
37
|
+
* Precision for performance metric values
|
|
38
|
+
* All performance metrics are rounded to 2 decimal places
|
|
39
|
+
*/
|
|
40
|
+
export const PERFORMANCE_PRECISION_DECIMALS = 2;
|
|
@@ -9,10 +9,8 @@ export class ClickHandler extends StateManager {
|
|
|
9
9
|
}
|
|
10
10
|
startTracking() {
|
|
11
11
|
if (this.clickHandler) {
|
|
12
|
-
debugLog.debug('ClickHandler', 'Click tracking already active');
|
|
13
12
|
return;
|
|
14
13
|
}
|
|
15
|
-
debugLog.debug('ClickHandler', 'Starting click tracking');
|
|
16
14
|
this.clickHandler = (event) => {
|
|
17
15
|
const mouseEvent = event;
|
|
18
16
|
const target = mouseEvent.target;
|
|
@@ -25,11 +23,6 @@ export class ClickHandler extends StateManager {
|
|
|
25
23
|
debugLog.warn('ClickHandler', 'Click target not found or not an element');
|
|
26
24
|
return;
|
|
27
25
|
}
|
|
28
|
-
debugLog.info('ClickHandler', '🖱️ Click detected on element', {
|
|
29
|
-
tagName: clickedElement.tagName,
|
|
30
|
-
className: clickedElement.className || 'none',
|
|
31
|
-
textContent: clickedElement.textContent?.slice(0, 50) ?? 'empty',
|
|
32
|
-
});
|
|
33
26
|
const trackingElement = this.findTrackingElement(clickedElement);
|
|
34
27
|
const relevantClickElement = this.getRelevantClickElement(clickedElement);
|
|
35
28
|
const coordinates = this.calculateClickCoordinates(mouseEvent, clickedElement);
|
|
@@ -70,27 +63,18 @@ export class ClickHandler extends StateManager {
|
|
|
70
63
|
getRelevantClickElement(element) {
|
|
71
64
|
for (const selector of INTERACTIVE_SELECTORS) {
|
|
72
65
|
try {
|
|
66
|
+
// First check if the element itself matches
|
|
73
67
|
if (element.matches(selector)) {
|
|
74
68
|
return element;
|
|
75
69
|
}
|
|
76
|
-
|
|
77
|
-
catch (error) {
|
|
78
|
-
debugLog.warn('ClickHandler', 'Invalid selector in interactive elements check', {
|
|
79
|
-
selector,
|
|
80
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
81
|
-
});
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
for (const selector of INTERACTIVE_SELECTORS) {
|
|
86
|
-
try {
|
|
70
|
+
// If not, search for matching ancestors
|
|
87
71
|
const parent = element.closest(selector);
|
|
88
72
|
if (parent) {
|
|
89
73
|
return parent;
|
|
90
74
|
}
|
|
91
75
|
}
|
|
92
76
|
catch (error) {
|
|
93
|
-
debugLog.warn('ClickHandler', 'Invalid selector in
|
|
77
|
+
debugLog.warn('ClickHandler', 'Invalid selector in element search', {
|
|
94
78
|
selector,
|
|
95
79
|
error: error instanceof Error ? error.message : 'Unknown error',
|
|
96
80
|
});
|
|
@@ -99,12 +83,15 @@ export class ClickHandler extends StateManager {
|
|
|
99
83
|
}
|
|
100
84
|
return element;
|
|
101
85
|
}
|
|
86
|
+
clamp(value) {
|
|
87
|
+
return Math.max(0, Math.min(1, Number(value.toFixed(3))));
|
|
88
|
+
}
|
|
102
89
|
calculateClickCoordinates(event, element) {
|
|
103
90
|
const rect = element.getBoundingClientRect();
|
|
104
91
|
const x = event.clientX;
|
|
105
92
|
const y = event.clientY;
|
|
106
|
-
const relativeX = rect.width > 0 ?
|
|
107
|
-
const relativeY = rect.height > 0 ?
|
|
93
|
+
const relativeX = rect.width > 0 ? this.clamp((x - rect.left) / rect.width) : 0;
|
|
94
|
+
const relativeY = rect.height > 0 ? this.clamp((y - rect.top) / rect.height) : 0;
|
|
108
95
|
return { x, y, relativeX, relativeY };
|
|
109
96
|
}
|
|
110
97
|
extractTrackingData(trackingElement) {
|
|
@@ -123,12 +110,6 @@ export class ClickHandler extends StateManager {
|
|
|
123
110
|
const { x, y, relativeX, relativeY } = coordinates;
|
|
124
111
|
const text = this.getRelevantText(clickedElement, relevantElement);
|
|
125
112
|
const attributes = this.extractElementAttributes(relevantElement);
|
|
126
|
-
const href = relevantElement.getAttribute('href');
|
|
127
|
-
const title = relevantElement.getAttribute('title');
|
|
128
|
-
const alt = relevantElement.getAttribute('alt');
|
|
129
|
-
const role = relevantElement.getAttribute('role');
|
|
130
|
-
const ariaLabel = relevantElement.getAttribute('aria-label');
|
|
131
|
-
const className = typeof relevantElement.className === 'string' ? relevantElement.className : String(relevantElement.className);
|
|
132
113
|
return {
|
|
133
114
|
x,
|
|
134
115
|
y,
|
|
@@ -136,47 +117,47 @@ export class ClickHandler extends StateManager {
|
|
|
136
117
|
relativeY,
|
|
137
118
|
tag: relevantElement.tagName.toLowerCase(),
|
|
138
119
|
...(relevantElement.id && { id: relevantElement.id }),
|
|
139
|
-
...(relevantElement.className && { class: className }),
|
|
120
|
+
...(relevantElement.className && { class: relevantElement.className }),
|
|
140
121
|
...(text && { text }),
|
|
141
|
-
...(href && { href }),
|
|
142
|
-
...(title && { title }),
|
|
143
|
-
...(alt && { alt }),
|
|
144
|
-
...(role && { role }),
|
|
145
|
-
...(
|
|
122
|
+
...(attributes.href && { href: attributes.href }),
|
|
123
|
+
...(attributes.title && { title: attributes.title }),
|
|
124
|
+
...(attributes.alt && { alt: attributes.alt }),
|
|
125
|
+
...(attributes.role && { role: attributes.role }),
|
|
126
|
+
...(attributes['aria-label'] && { ariaLabel: attributes['aria-label'] }),
|
|
146
127
|
...(Object.keys(attributes).length > 0 && { dataAttributes: attributes }),
|
|
147
128
|
};
|
|
148
129
|
}
|
|
149
130
|
getRelevantText(clickedElement, relevantElement) {
|
|
150
|
-
const LARGE_CONTAINER_TAGS = ['main', 'section', 'article', 'body', 'html', 'header', 'footer', 'aside', 'nav'];
|
|
151
131
|
const clickedText = clickedElement.textContent?.trim() ?? '';
|
|
152
132
|
const relevantText = relevantElement.textContent?.trim() ?? '';
|
|
133
|
+
// No text available
|
|
153
134
|
if (!clickedText && !relevantText) {
|
|
154
135
|
return '';
|
|
155
136
|
}
|
|
156
|
-
//
|
|
137
|
+
// Prefer clicked element text if it's reasonable length
|
|
157
138
|
if (clickedText && clickedText.length <= MAX_TEXT_LENGTH) {
|
|
158
139
|
return clickedText;
|
|
159
140
|
}
|
|
160
|
-
//
|
|
161
|
-
const isLargeContainer = LARGE_CONTAINER_TAGS.includes(relevantElement.tagName.toLowerCase());
|
|
162
|
-
const hasExcessiveText = relevantText.length > MAX_TEXT_LENGTH * 2; // 510 chars
|
|
163
|
-
if (isLargeContainer && hasExcessiveText) {
|
|
164
|
-
// Use clicked element text if available and reasonable, otherwise empty
|
|
165
|
-
return clickedText && clickedText.length <= MAX_TEXT_LENGTH ? clickedText : '';
|
|
166
|
-
}
|
|
167
|
-
// Strategy 3: Use relevant text but truncate if needed
|
|
141
|
+
// Use relevant element text if it fits
|
|
168
142
|
if (relevantText.length <= MAX_TEXT_LENGTH) {
|
|
169
143
|
return relevantText;
|
|
170
144
|
}
|
|
171
|
-
//
|
|
172
|
-
if (clickedText && clickedText.length < relevantText.length * 0.1) {
|
|
173
|
-
return clickedText.length <= MAX_TEXT_LENGTH ? clickedText : clickedText.slice(0, MAX_TEXT_LENGTH - 3) + '...';
|
|
174
|
-
}
|
|
175
|
-
// Fallback: truncate relevant text to exactly MAX_TEXT_LENGTH including ellipsis
|
|
145
|
+
// Truncate relevant text if too long
|
|
176
146
|
return relevantText.slice(0, MAX_TEXT_LENGTH - 3) + '...';
|
|
177
147
|
}
|
|
178
148
|
extractElementAttributes(element) {
|
|
179
|
-
const commonAttributes = [
|
|
149
|
+
const commonAttributes = [
|
|
150
|
+
'id',
|
|
151
|
+
'class',
|
|
152
|
+
'data-testid',
|
|
153
|
+
'aria-label',
|
|
154
|
+
'title',
|
|
155
|
+
'href',
|
|
156
|
+
'type',
|
|
157
|
+
'name',
|
|
158
|
+
'alt',
|
|
159
|
+
'role',
|
|
160
|
+
];
|
|
180
161
|
const result = {};
|
|
181
162
|
for (const attributeName of commonAttributes) {
|
|
182
163
|
const value = element.getAttribute(attributeName);
|
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import { EventManager } from '../managers/event.manager';
|
|
2
2
|
import { StateManager } from '../managers/state.manager';
|
|
3
|
+
/**
|
|
4
|
+
* Simplified error handler for tracking JavaScript errors and unhandled promise rejections
|
|
5
|
+
* Includes PII sanitization and sampling support
|
|
6
|
+
*/
|
|
3
7
|
export declare class ErrorHandler extends StateManager {
|
|
4
8
|
private readonly eventManager;
|
|
5
|
-
private readonly
|
|
9
|
+
private readonly recentErrors;
|
|
6
10
|
constructor(eventManager: EventManager);
|
|
7
11
|
startTracking(): void;
|
|
8
12
|
stopTracking(): void;
|
|
9
|
-
private setupErrorListener;
|
|
10
|
-
private setupUnhandledRejectionListener;
|
|
11
|
-
private readonly handleError;
|
|
12
|
-
private readonly handleUnhandledRejection;
|
|
13
|
-
private sanitizeText;
|
|
14
13
|
private shouldSample;
|
|
14
|
+
private readonly handleError;
|
|
15
|
+
private readonly handleRejection;
|
|
16
|
+
private extractRejectionMessage;
|
|
17
|
+
private sanitize;
|
|
18
|
+
private shouldSuppressError;
|
|
19
|
+
private pruneOldErrors;
|
|
15
20
|
}
|