@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.
Files changed (228) hide show
  1. package/README.md +58 -24
  2. package/dist/browser/tracelog.js +1934 -3226
  3. package/dist/cjs/api.d.ts +33 -19
  4. package/dist/cjs/api.js +111 -156
  5. package/dist/cjs/app.constants.d.ts +80 -1
  6. package/dist/cjs/app.constants.js +90 -3
  7. package/dist/cjs/app.d.ts +29 -44
  8. package/dist/cjs/app.js +114 -212
  9. package/dist/cjs/app.types.d.ts +2 -7
  10. package/dist/cjs/app.types.js +10 -21
  11. package/dist/cjs/constants/api.constants.js +11 -5
  12. package/dist/cjs/constants/config.constants.d.ts +75 -0
  13. package/dist/cjs/constants/config.constants.js +178 -0
  14. package/dist/cjs/constants/error.constants.d.ts +29 -0
  15. package/dist/cjs/constants/error.constants.js +50 -0
  16. package/dist/cjs/constants/index.d.ts +3 -6
  17. package/dist/cjs/constants/index.js +3 -6
  18. package/dist/cjs/constants/performance.constants.d.ts +28 -0
  19. package/dist/cjs/constants/performance.constants.js +43 -0
  20. package/dist/cjs/handlers/click.handler.d.ts +1 -0
  21. package/dist/cjs/handlers/click.handler.js +30 -49
  22. package/dist/cjs/handlers/error.handler.d.ts +11 -6
  23. package/dist/cjs/handlers/error.handler.js +91 -51
  24. package/dist/cjs/handlers/page-view.handler.js +38 -29
  25. package/dist/cjs/handlers/performance.handler.d.ts +3 -0
  26. package/dist/cjs/handlers/performance.handler.js +76 -37
  27. package/dist/cjs/handlers/scroll.handler.d.ts +15 -0
  28. package/dist/cjs/handlers/scroll.handler.js +105 -31
  29. package/dist/cjs/handlers/session.handler.d.ts +6 -20
  30. package/dist/cjs/handlers/session.handler.js +38 -326
  31. package/dist/cjs/integrations/google-analytics.integration.d.ts +0 -1
  32. package/dist/cjs/integrations/google-analytics.integration.js +27 -98
  33. package/dist/cjs/listeners/input-listener-managers.d.ts +18 -9
  34. package/dist/cjs/listeners/input-listener-managers.js +24 -33
  35. package/dist/cjs/listeners/touch-listener-manager.d.ts +1 -3
  36. package/dist/cjs/listeners/touch-listener-manager.js +1 -23
  37. package/dist/cjs/listeners/visibility-listener-manager.d.ts +1 -4
  38. package/dist/cjs/listeners/visibility-listener-manager.js +6 -42
  39. package/dist/cjs/managers/api.manager.d.ts +13 -3
  40. package/dist/cjs/managers/api.manager.js +35 -5
  41. package/dist/cjs/managers/config.manager.d.ts +53 -3
  42. package/dist/cjs/managers/config.manager.js +131 -62
  43. package/dist/cjs/managers/event.manager.d.ts +57 -36
  44. package/dist/cjs/managers/event.manager.js +266 -417
  45. package/dist/cjs/managers/sender.manager.d.ts +40 -22
  46. package/dist/cjs/managers/sender.manager.js +200 -198
  47. package/dist/cjs/managers/session.manager.d.ts +80 -66
  48. package/dist/cjs/managers/session.manager.js +267 -522
  49. package/dist/cjs/managers/state.manager.d.ts +33 -0
  50. package/dist/cjs/managers/state.manager.js +79 -6
  51. package/dist/cjs/managers/storage.manager.d.ts +26 -2
  52. package/dist/cjs/managers/storage.manager.js +67 -34
  53. package/dist/cjs/managers/tags.manager.d.ts +31 -7
  54. package/dist/cjs/managers/tags.manager.js +123 -241
  55. package/dist/cjs/managers/user.manager.d.ts +14 -5
  56. package/dist/cjs/managers/user.manager.js +17 -9
  57. package/dist/cjs/public-api.d.ts +10 -1
  58. package/dist/cjs/public-api.js +18 -24
  59. package/dist/cjs/test-bridge.d.ts +48 -0
  60. package/dist/cjs/test-bridge.js +110 -0
  61. package/dist/cjs/types/api.types.d.ts +21 -6
  62. package/dist/cjs/types/api.types.js +21 -6
  63. package/dist/cjs/types/config.types.d.ts +22 -84
  64. package/dist/cjs/types/emitter.types.d.ts +11 -0
  65. package/dist/cjs/types/emitter.types.js +8 -0
  66. package/dist/cjs/types/event.types.d.ts +8 -11
  67. package/dist/cjs/types/index.d.ts +3 -1
  68. package/dist/cjs/types/index.js +3 -1
  69. package/dist/cjs/types/queue.types.d.ts +1 -0
  70. package/dist/cjs/types/session.types.d.ts +0 -64
  71. package/dist/cjs/types/state.types.d.ts +1 -0
  72. package/dist/cjs/types/test-bridge.types.d.ts +38 -0
  73. package/dist/cjs/types/validation-error.types.d.ts +7 -0
  74. package/dist/cjs/types/validation-error.types.js +11 -1
  75. package/dist/cjs/types/window.types.d.ts +1 -8
  76. package/dist/cjs/utils/data/uuid.utils.d.ts +1 -1
  77. package/dist/cjs/utils/data/uuid.utils.js +7 -5
  78. package/dist/cjs/utils/emitter.utils.d.ts +8 -0
  79. package/dist/cjs/utils/emitter.utils.js +33 -0
  80. package/dist/cjs/utils/index.d.ts +1 -0
  81. package/dist/cjs/utils/index.js +1 -0
  82. package/dist/cjs/utils/logging/debug-logger.utils.d.ts +10 -51
  83. package/dist/cjs/utils/logging/debug-logger.utils.js +36 -127
  84. package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +4 -0
  85. package/dist/cjs/utils/network/fetch-with-timeout.utils.js +25 -0
  86. package/dist/cjs/utils/network/index.d.ts +1 -0
  87. package/dist/cjs/utils/network/index.js +1 -0
  88. package/dist/cjs/utils/network/url.utils.js +2 -42
  89. package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -8
  90. package/dist/cjs/utils/security/sanitize.utils.js +7 -41
  91. package/dist/cjs/utils/validations/config-validations.utils.d.ts +7 -0
  92. package/dist/cjs/utils/validations/config-validations.utils.js +77 -22
  93. package/dist/esm/api.d.ts +33 -19
  94. package/dist/esm/api.js +105 -118
  95. package/dist/esm/app.constants.d.ts +80 -1
  96. package/dist/esm/app.constants.js +89 -1
  97. package/dist/esm/app.d.ts +29 -44
  98. package/dist/esm/app.js +115 -213
  99. package/dist/esm/app.types.d.ts +2 -7
  100. package/dist/esm/app.types.js +1 -7
  101. package/dist/esm/constants/api.constants.js +10 -4
  102. package/dist/esm/constants/config.constants.d.ts +75 -0
  103. package/dist/esm/constants/config.constants.js +174 -0
  104. package/dist/esm/constants/error.constants.d.ts +29 -0
  105. package/dist/esm/constants/error.constants.js +47 -0
  106. package/dist/esm/constants/index.d.ts +3 -6
  107. package/dist/esm/constants/index.js +3 -6
  108. package/dist/esm/constants/performance.constants.d.ts +28 -0
  109. package/dist/esm/constants/performance.constants.js +40 -0
  110. package/dist/esm/handlers/click.handler.d.ts +1 -0
  111. package/dist/esm/handlers/click.handler.js +30 -49
  112. package/dist/esm/handlers/error.handler.d.ts +11 -6
  113. package/dist/esm/handlers/error.handler.js +91 -51
  114. package/dist/esm/handlers/page-view.handler.js +38 -29
  115. package/dist/esm/handlers/performance.handler.d.ts +3 -0
  116. package/dist/esm/handlers/performance.handler.js +71 -32
  117. package/dist/esm/handlers/scroll.handler.d.ts +15 -0
  118. package/dist/esm/handlers/scroll.handler.js +106 -32
  119. package/dist/esm/handlers/session.handler.d.ts +6 -20
  120. package/dist/esm/handlers/session.handler.js +38 -326
  121. package/dist/esm/integrations/google-analytics.integration.d.ts +0 -1
  122. package/dist/esm/integrations/google-analytics.integration.js +27 -98
  123. package/dist/esm/listeners/input-listener-managers.d.ts +18 -9
  124. package/dist/esm/listeners/input-listener-managers.js +23 -32
  125. package/dist/esm/listeners/touch-listener-manager.d.ts +1 -3
  126. package/dist/esm/listeners/touch-listener-manager.js +1 -23
  127. package/dist/esm/listeners/visibility-listener-manager.d.ts +1 -4
  128. package/dist/esm/listeners/visibility-listener-manager.js +6 -42
  129. package/dist/esm/managers/api.manager.d.ts +13 -3
  130. package/dist/esm/managers/api.manager.js +34 -3
  131. package/dist/esm/managers/config.manager.d.ts +53 -3
  132. package/dist/esm/managers/config.manager.js +133 -64
  133. package/dist/esm/managers/event.manager.d.ts +57 -36
  134. package/dist/esm/managers/event.manager.js +268 -419
  135. package/dist/esm/managers/sender.manager.d.ts +40 -22
  136. package/dist/esm/managers/sender.manager.js +201 -199
  137. package/dist/esm/managers/session.manager.d.ts +80 -66
  138. package/dist/esm/managers/session.manager.js +269 -524
  139. package/dist/esm/managers/state.manager.d.ts +33 -0
  140. package/dist/esm/managers/state.manager.js +78 -6
  141. package/dist/esm/managers/storage.manager.d.ts +26 -2
  142. package/dist/esm/managers/storage.manager.js +66 -33
  143. package/dist/esm/managers/tags.manager.d.ts +31 -7
  144. package/dist/esm/managers/tags.manager.js +124 -242
  145. package/dist/esm/managers/user.manager.d.ts +14 -5
  146. package/dist/esm/managers/user.manager.js +17 -9
  147. package/dist/esm/public-api.d.ts +10 -1
  148. package/dist/esm/public-api.js +14 -1
  149. package/dist/esm/test-bridge.d.ts +48 -0
  150. package/dist/esm/test-bridge.js +106 -0
  151. package/dist/esm/types/api.types.d.ts +21 -6
  152. package/dist/esm/types/api.types.js +21 -6
  153. package/dist/esm/types/config.types.d.ts +22 -84
  154. package/dist/esm/types/emitter.types.d.ts +11 -0
  155. package/dist/esm/types/emitter.types.js +5 -0
  156. package/dist/esm/types/event.types.d.ts +8 -11
  157. package/dist/esm/types/index.d.ts +3 -1
  158. package/dist/esm/types/index.js +3 -1
  159. package/dist/esm/types/queue.types.d.ts +1 -0
  160. package/dist/esm/types/session.types.d.ts +0 -64
  161. package/dist/esm/types/state.types.d.ts +1 -0
  162. package/dist/esm/types/test-bridge.types.d.ts +38 -0
  163. package/dist/esm/types/validation-error.types.d.ts +7 -0
  164. package/dist/esm/types/validation-error.types.js +9 -0
  165. package/dist/esm/types/window.types.d.ts +1 -8
  166. package/dist/esm/utils/data/uuid.utils.d.ts +1 -1
  167. package/dist/esm/utils/data/uuid.utils.js +7 -5
  168. package/dist/esm/utils/emitter.utils.d.ts +8 -0
  169. package/dist/esm/utils/emitter.utils.js +29 -0
  170. package/dist/esm/utils/index.d.ts +1 -0
  171. package/dist/esm/utils/index.js +1 -0
  172. package/dist/esm/utils/logging/debug-logger.utils.d.ts +10 -51
  173. package/dist/esm/utils/logging/debug-logger.utils.js +36 -127
  174. package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +4 -0
  175. package/dist/esm/utils/network/fetch-with-timeout.utils.js +22 -0
  176. package/dist/esm/utils/network/index.d.ts +1 -0
  177. package/dist/esm/utils/network/index.js +1 -0
  178. package/dist/esm/utils/network/url.utils.js +2 -42
  179. package/dist/esm/utils/security/sanitize.utils.d.ts +1 -8
  180. package/dist/esm/utils/security/sanitize.utils.js +6 -39
  181. package/dist/esm/utils/validations/config-validations.utils.d.ts +7 -0
  182. package/dist/esm/utils/validations/config-validations.utils.js +76 -22
  183. package/package.json +23 -16
  184. package/dist/browser/web-vitals-CCnqwnC8.mjs +0 -198
  185. package/dist/cjs/constants/browser.constants.d.ts +0 -3
  186. package/dist/cjs/constants/browser.constants.js +0 -41
  187. package/dist/cjs/constants/initialization.constants.d.ts +0 -40
  188. package/dist/cjs/constants/initialization.constants.js +0 -48
  189. package/dist/cjs/constants/limits.constants.d.ts +0 -25
  190. package/dist/cjs/constants/limits.constants.js +0 -40
  191. package/dist/cjs/constants/security.constants.d.ts +0 -1
  192. package/dist/cjs/constants/security.constants.js +0 -12
  193. package/dist/cjs/constants/timing.constants.d.ts +0 -22
  194. package/dist/cjs/constants/timing.constants.js +0 -34
  195. package/dist/cjs/constants/validation.constants.d.ts +0 -13
  196. package/dist/cjs/constants/validation.constants.js +0 -31
  197. package/dist/cjs/handlers/network.handler.d.ts +0 -16
  198. package/dist/cjs/handlers/network.handler.js +0 -136
  199. package/dist/cjs/managers/cross-tab-session.manager.d.ts +0 -170
  200. package/dist/cjs/managers/cross-tab-session.manager.js +0 -730
  201. package/dist/cjs/managers/sampling.manager.d.ts +0 -8
  202. package/dist/cjs/managers/sampling.manager.js +0 -53
  203. package/dist/cjs/managers/session-recovery.manager.d.ts +0 -65
  204. package/dist/cjs/managers/session-recovery.manager.js +0 -237
  205. package/dist/cjs/types/web-vitals.types.d.ts +0 -6
  206. package/dist/esm/constants/browser.constants.d.ts +0 -3
  207. package/dist/esm/constants/browser.constants.js +0 -38
  208. package/dist/esm/constants/initialization.constants.d.ts +0 -40
  209. package/dist/esm/constants/initialization.constants.js +0 -45
  210. package/dist/esm/constants/limits.constants.d.ts +0 -25
  211. package/dist/esm/constants/limits.constants.js +0 -37
  212. package/dist/esm/constants/security.constants.d.ts +0 -1
  213. package/dist/esm/constants/security.constants.js +0 -9
  214. package/dist/esm/constants/timing.constants.d.ts +0 -22
  215. package/dist/esm/constants/timing.constants.js +0 -31
  216. package/dist/esm/constants/validation.constants.d.ts +0 -13
  217. package/dist/esm/constants/validation.constants.js +0 -28
  218. package/dist/esm/handlers/network.handler.d.ts +0 -16
  219. package/dist/esm/handlers/network.handler.js +0 -132
  220. package/dist/esm/managers/cross-tab-session.manager.d.ts +0 -170
  221. package/dist/esm/managers/cross-tab-session.manager.js +0 -726
  222. package/dist/esm/managers/sampling.manager.d.ts +0 -8
  223. package/dist/esm/managers/sampling.manager.js +0 -49
  224. package/dist/esm/managers/session-recovery.manager.d.ts +0 -65
  225. package/dist/esm/managers/session-recovery.manager.js +0 -233
  226. package/dist/esm/types/web-vitals.types.d.ts +0 -6
  227. /package/dist/cjs/types/{web-vitals.types.js → test-bridge.types.js} +0 -0
  228. /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 './browser.constants';
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 './timing.constants';
8
- export * from './validation.constants';
4
+ export * from './performance.constants';
5
+ export * from './error.constants';
@@ -1,8 +1,5 @@
1
1
  export * from './api.constants';
2
- export * from './browser.constants';
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 './timing.constants';
8
- export * from './validation.constants';
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;
@@ -8,6 +8,7 @@ export declare class ClickHandler extends StateManager {
8
8
  stopTracking(): void;
9
9
  private findTrackingElement;
10
10
  private getRelevantClickElement;
11
+ private clamp;
11
12
  private calculateClickCoordinates;
12
13
  private extractTrackingData;
13
14
  private generateClickData;
@@ -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 parent element search', {
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 ? Math.max(0, Math.min(1, Number(((x - rect.left) / rect.width).toFixed(3)))) : 0;
107
- const relativeY = rect.height > 0 ? Math.max(0, Math.min(1, Number(((y - rect.top) / rect.height).toFixed(3)))) : 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
- ...(ariaLabel && { ariaLabel }),
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
- // Strategy 1: If clicked element has reasonable text, use it
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
- // Strategy 2: For large containers with excessive text, avoid using container text
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
- // Strategy 4: If clicked text is much shorter than relevant text, prefer clicked text
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 = ['id', 'class', 'data-testid', 'aria-label', 'title', 'href', 'type', 'name'];
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 piiPatterns;
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
  }