@tracelog/lib 0.0.1

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 (301) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +217 -0
  3. package/dist/browser/tracelog.js +4040 -0
  4. package/dist/browser/web-vitals-CCnqwnC8.mjs +198 -0
  5. package/dist/cjs/api.d.ts +46 -0
  6. package/dist/cjs/api.js +224 -0
  7. package/dist/cjs/app.constants.d.ts +1 -0
  8. package/dist/cjs/app.constants.js +5 -0
  9. package/dist/cjs/app.d.ts +59 -0
  10. package/dist/cjs/app.js +272 -0
  11. package/dist/cjs/app.types.d.ts +6 -0
  12. package/dist/cjs/app.types.js +22 -0
  13. package/dist/cjs/constants/api.constants.d.ts +4 -0
  14. package/dist/cjs/constants/api.constants.js +18 -0
  15. package/dist/cjs/constants/browser.constants.d.ts +3 -0
  16. package/dist/cjs/constants/browser.constants.js +41 -0
  17. package/dist/cjs/constants/index.d.ts +8 -0
  18. package/dist/cjs/constants/index.js +24 -0
  19. package/dist/cjs/constants/initialization.constants.d.ts +40 -0
  20. package/dist/cjs/constants/initialization.constants.js +48 -0
  21. package/dist/cjs/constants/limits.constants.d.ts +25 -0
  22. package/dist/cjs/constants/limits.constants.js +40 -0
  23. package/dist/cjs/constants/security.constants.d.ts +1 -0
  24. package/dist/cjs/constants/security.constants.js +12 -0
  25. package/dist/cjs/constants/storage.constants.d.ts +9 -0
  26. package/dist/cjs/constants/storage.constants.js +22 -0
  27. package/dist/cjs/constants/timing.constants.d.ts +22 -0
  28. package/dist/cjs/constants/timing.constants.js +34 -0
  29. package/dist/cjs/constants/validation.constants.d.ts +13 -0
  30. package/dist/cjs/constants/validation.constants.js +31 -0
  31. package/dist/cjs/handlers/click.handler.d.ts +17 -0
  32. package/dist/cjs/handlers/click.handler.js +199 -0
  33. package/dist/cjs/handlers/error.handler.d.ts +15 -0
  34. package/dist/cjs/handlers/error.handler.js +97 -0
  35. package/dist/cjs/handlers/network.handler.d.ts +16 -0
  36. package/dist/cjs/handlers/network.handler.js +136 -0
  37. package/dist/cjs/handlers/page-view.handler.d.ts +15 -0
  38. package/dist/cjs/handlers/page-view.handler.js +83 -0
  39. package/dist/cjs/handlers/performance.handler.d.ts +19 -0
  40. package/dist/cjs/handlers/performance.handler.js +255 -0
  41. package/dist/cjs/handlers/scroll.handler.d.ts +16 -0
  42. package/dist/cjs/handlers/scroll.handler.js +138 -0
  43. package/dist/cjs/handlers/session.handler.d.ts +29 -0
  44. package/dist/cjs/handlers/session.handler.js +357 -0
  45. package/dist/cjs/integrations/google-analytics.integration.d.ts +18 -0
  46. package/dist/cjs/integrations/google-analytics.integration.js +159 -0
  47. package/dist/cjs/listeners/activity-listener-manager.d.ts +8 -0
  48. package/dist/cjs/listeners/activity-listener-manager.js +32 -0
  49. package/dist/cjs/listeners/index.d.ts +6 -0
  50. package/dist/cjs/listeners/index.js +14 -0
  51. package/dist/cjs/listeners/input-listener-managers.d.ts +15 -0
  52. package/dist/cjs/listeners/input-listener-managers.js +58 -0
  53. package/dist/cjs/listeners/listeners.types.d.ts +4 -0
  54. package/dist/cjs/listeners/listeners.types.js +2 -0
  55. package/dist/cjs/listeners/touch-listener-manager.d.ts +10 -0
  56. package/dist/cjs/listeners/touch-listener-manager.js +56 -0
  57. package/dist/cjs/listeners/unload-listener-manager.d.ts +8 -0
  58. package/dist/cjs/listeners/unload-listener-manager.js +30 -0
  59. package/dist/cjs/listeners/visibility-listener-manager.d.ts +12 -0
  60. package/dist/cjs/listeners/visibility-listener-manager.js +83 -0
  61. package/dist/cjs/managers/api.manager.d.ts +3 -0
  62. package/dist/cjs/managers/api.manager.js +14 -0
  63. package/dist/cjs/managers/config.manager.d.ts +7 -0
  64. package/dist/cjs/managers/config.manager.js +94 -0
  65. package/dist/cjs/managers/cross-tab-session.manager.d.ts +170 -0
  66. package/dist/cjs/managers/cross-tab-session.manager.js +730 -0
  67. package/dist/cjs/managers/event.manager.d.ts +61 -0
  68. package/dist/cjs/managers/event.manager.js +508 -0
  69. package/dist/cjs/managers/sampling.manager.d.ts +8 -0
  70. package/dist/cjs/managers/sampling.manager.js +53 -0
  71. package/dist/cjs/managers/sender.manager.d.ts +46 -0
  72. package/dist/cjs/managers/sender.manager.js +304 -0
  73. package/dist/cjs/managers/session-recovery.manager.d.ts +65 -0
  74. package/dist/cjs/managers/session-recovery.manager.js +237 -0
  75. package/dist/cjs/managers/session.manager.d.ts +72 -0
  76. package/dist/cjs/managers/session.manager.js +587 -0
  77. package/dist/cjs/managers/state.manager.d.ts +5 -0
  78. package/dist/cjs/managers/state.manager.js +23 -0
  79. package/dist/cjs/managers/storage.manager.d.ts +10 -0
  80. package/dist/cjs/managers/storage.manager.js +81 -0
  81. package/dist/cjs/managers/tags.manager.d.ts +12 -0
  82. package/dist/cjs/managers/tags.manager.js +289 -0
  83. package/dist/cjs/managers/user.manager.d.ts +7 -0
  84. package/dist/cjs/managers/user.manager.js +22 -0
  85. package/dist/cjs/public-api.d.ts +1 -0
  86. package/dist/cjs/public-api.js +37 -0
  87. package/dist/cjs/types/api.types.d.ts +21 -0
  88. package/dist/cjs/types/api.types.js +25 -0
  89. package/dist/cjs/types/common.types.d.ts +1 -0
  90. package/dist/cjs/types/common.types.js +2 -0
  91. package/dist/cjs/types/config.types.d.ts +104 -0
  92. package/dist/cjs/types/config.types.js +2 -0
  93. package/dist/cjs/types/device.types.d.ts +6 -0
  94. package/dist/cjs/types/device.types.js +10 -0
  95. package/dist/cjs/types/event.types.d.ts +104 -0
  96. package/dist/cjs/types/event.types.js +25 -0
  97. package/dist/cjs/types/index.d.ts +13 -0
  98. package/dist/cjs/types/index.js +29 -0
  99. package/dist/cjs/types/log.types.d.ts +4 -0
  100. package/dist/cjs/types/log.types.js +2 -0
  101. package/dist/cjs/types/mode.types.d.ts +7 -0
  102. package/dist/cjs/types/mode.types.js +11 -0
  103. package/dist/cjs/types/queue.types.d.ts +23 -0
  104. package/dist/cjs/types/queue.types.js +2 -0
  105. package/dist/cjs/types/session.types.d.ts +65 -0
  106. package/dist/cjs/types/session.types.js +2 -0
  107. package/dist/cjs/types/state.types.d.ts +12 -0
  108. package/dist/cjs/types/state.types.js +2 -0
  109. package/dist/cjs/types/tag.types.d.ts +43 -0
  110. package/dist/cjs/types/tag.types.js +31 -0
  111. package/dist/cjs/types/validation-error.types.d.ts +42 -0
  112. package/dist/cjs/types/validation-error.types.js +68 -0
  113. package/dist/cjs/types/web-vitals.types.d.ts +6 -0
  114. package/dist/cjs/types/web-vitals.types.js +2 -0
  115. package/dist/cjs/types/window.types.d.ts +17 -0
  116. package/dist/cjs/types/window.types.js +2 -0
  117. package/dist/cjs/utils/browser/device-detector.utils.d.ts +6 -0
  118. package/dist/cjs/utils/browser/device-detector.utils.js +71 -0
  119. package/dist/cjs/utils/browser/index.d.ts +2 -0
  120. package/dist/cjs/utils/browser/index.js +18 -0
  121. package/dist/cjs/utils/browser/utm-params.utils.d.ts +6 -0
  122. package/dist/cjs/utils/browser/utm-params.utils.js +37 -0
  123. package/dist/cjs/utils/data/index.d.ts +1 -0
  124. package/dist/cjs/utils/data/index.js +17 -0
  125. package/dist/cjs/utils/data/uuid.utils.d.ts +5 -0
  126. package/dist/cjs/utils/data/uuid.utils.js +18 -0
  127. package/dist/cjs/utils/index.d.ts +6 -0
  128. package/dist/cjs/utils/index.js +22 -0
  129. package/dist/cjs/utils/logging/debug-logger.utils.d.ts +56 -0
  130. package/dist/cjs/utils/logging/debug-logger.utils.js +139 -0
  131. package/dist/cjs/utils/logging/index.d.ts +1 -0
  132. package/dist/cjs/utils/logging/index.js +5 -0
  133. package/dist/cjs/utils/network/index.d.ts +1 -0
  134. package/dist/cjs/utils/network/index.js +17 -0
  135. package/dist/cjs/utils/network/url.utils.d.ts +20 -0
  136. package/dist/cjs/utils/network/url.utils.js +172 -0
  137. package/dist/cjs/utils/security/index.d.ts +1 -0
  138. package/dist/cjs/utils/security/index.js +17 -0
  139. package/dist/cjs/utils/security/sanitize.utils.d.ts +32 -0
  140. package/dist/cjs/utils/security/sanitize.utils.js +319 -0
  141. package/dist/cjs/utils/validations/config-validations.utils.d.ts +42 -0
  142. package/dist/cjs/utils/validations/config-validations.utils.js +297 -0
  143. package/dist/cjs/utils/validations/event-validations.utils.d.ts +12 -0
  144. package/dist/cjs/utils/validations/event-validations.utils.js +30 -0
  145. package/dist/cjs/utils/validations/index.d.ts +5 -0
  146. package/dist/cjs/utils/validations/index.js +21 -0
  147. package/dist/cjs/utils/validations/metadata-validations.utils.d.ts +22 -0
  148. package/dist/cjs/utils/validations/metadata-validations.utils.js +115 -0
  149. package/dist/cjs/utils/validations/type-guards.utils.d.ts +6 -0
  150. package/dist/cjs/utils/validations/type-guards.utils.js +31 -0
  151. package/dist/cjs/utils/validations/url-validations.utils.d.ts +15 -0
  152. package/dist/cjs/utils/validations/url-validations.utils.js +47 -0
  153. package/dist/esm/api.d.ts +46 -0
  154. package/dist/esm/api.js +183 -0
  155. package/dist/esm/app.constants.d.ts +1 -0
  156. package/dist/esm/app.constants.js +1 -0
  157. package/dist/esm/app.d.ts +59 -0
  158. package/dist/esm/app.js +268 -0
  159. package/dist/esm/app.types.d.ts +6 -0
  160. package/dist/esm/app.types.js +6 -0
  161. package/dist/esm/constants/api.constants.d.ts +4 -0
  162. package/dist/esm/constants/api.constants.js +14 -0
  163. package/dist/esm/constants/browser.constants.d.ts +3 -0
  164. package/dist/esm/constants/browser.constants.js +38 -0
  165. package/dist/esm/constants/index.d.ts +8 -0
  166. package/dist/esm/constants/index.js +8 -0
  167. package/dist/esm/constants/initialization.constants.d.ts +40 -0
  168. package/dist/esm/constants/initialization.constants.js +45 -0
  169. package/dist/esm/constants/limits.constants.d.ts +25 -0
  170. package/dist/esm/constants/limits.constants.js +37 -0
  171. package/dist/esm/constants/security.constants.d.ts +1 -0
  172. package/dist/esm/constants/security.constants.js +9 -0
  173. package/dist/esm/constants/storage.constants.d.ts +9 -0
  174. package/dist/esm/constants/storage.constants.js +11 -0
  175. package/dist/esm/constants/timing.constants.d.ts +22 -0
  176. package/dist/esm/constants/timing.constants.js +31 -0
  177. package/dist/esm/constants/validation.constants.d.ts +13 -0
  178. package/dist/esm/constants/validation.constants.js +28 -0
  179. package/dist/esm/handlers/click.handler.d.ts +17 -0
  180. package/dist/esm/handlers/click.handler.js +195 -0
  181. package/dist/esm/handlers/error.handler.d.ts +15 -0
  182. package/dist/esm/handlers/error.handler.js +93 -0
  183. package/dist/esm/handlers/network.handler.d.ts +16 -0
  184. package/dist/esm/handlers/network.handler.js +132 -0
  185. package/dist/esm/handlers/page-view.handler.d.ts +15 -0
  186. package/dist/esm/handlers/page-view.handler.js +79 -0
  187. package/dist/esm/handlers/performance.handler.d.ts +19 -0
  188. package/dist/esm/handlers/performance.handler.js +218 -0
  189. package/dist/esm/handlers/scroll.handler.d.ts +16 -0
  190. package/dist/esm/handlers/scroll.handler.js +134 -0
  191. package/dist/esm/handlers/session.handler.d.ts +29 -0
  192. package/dist/esm/handlers/session.handler.js +353 -0
  193. package/dist/esm/integrations/google-analytics.integration.d.ts +18 -0
  194. package/dist/esm/integrations/google-analytics.integration.js +155 -0
  195. package/dist/esm/listeners/activity-listener-manager.d.ts +8 -0
  196. package/dist/esm/listeners/activity-listener-manager.js +28 -0
  197. package/dist/esm/listeners/index.d.ts +6 -0
  198. package/dist/esm/listeners/index.js +5 -0
  199. package/dist/esm/listeners/input-listener-managers.d.ts +15 -0
  200. package/dist/esm/listeners/input-listener-managers.js +53 -0
  201. package/dist/esm/listeners/listeners.types.d.ts +4 -0
  202. package/dist/esm/listeners/listeners.types.js +1 -0
  203. package/dist/esm/listeners/touch-listener-manager.d.ts +10 -0
  204. package/dist/esm/listeners/touch-listener-manager.js +52 -0
  205. package/dist/esm/listeners/unload-listener-manager.d.ts +8 -0
  206. package/dist/esm/listeners/unload-listener-manager.js +26 -0
  207. package/dist/esm/listeners/visibility-listener-manager.d.ts +12 -0
  208. package/dist/esm/listeners/visibility-listener-manager.js +79 -0
  209. package/dist/esm/managers/api.manager.d.ts +3 -0
  210. package/dist/esm/managers/api.manager.js +10 -0
  211. package/dist/esm/managers/config.manager.d.ts +7 -0
  212. package/dist/esm/managers/config.manager.js +90 -0
  213. package/dist/esm/managers/cross-tab-session.manager.d.ts +170 -0
  214. package/dist/esm/managers/cross-tab-session.manager.js +726 -0
  215. package/dist/esm/managers/event.manager.d.ts +61 -0
  216. package/dist/esm/managers/event.manager.js +504 -0
  217. package/dist/esm/managers/sampling.manager.d.ts +8 -0
  218. package/dist/esm/managers/sampling.manager.js +49 -0
  219. package/dist/esm/managers/sender.manager.d.ts +46 -0
  220. package/dist/esm/managers/sender.manager.js +300 -0
  221. package/dist/esm/managers/session-recovery.manager.d.ts +65 -0
  222. package/dist/esm/managers/session-recovery.manager.js +233 -0
  223. package/dist/esm/managers/session.manager.d.ts +72 -0
  224. package/dist/esm/managers/session.manager.js +583 -0
  225. package/dist/esm/managers/state.manager.d.ts +5 -0
  226. package/dist/esm/managers/state.manager.js +19 -0
  227. package/dist/esm/managers/storage.manager.d.ts +10 -0
  228. package/dist/esm/managers/storage.manager.js +77 -0
  229. package/dist/esm/managers/tags.manager.d.ts +12 -0
  230. package/dist/esm/managers/tags.manager.js +285 -0
  231. package/dist/esm/managers/user.manager.d.ts +7 -0
  232. package/dist/esm/managers/user.manager.js +18 -0
  233. package/dist/esm/public-api.d.ts +1 -0
  234. package/dist/esm/public-api.js +1 -0
  235. package/dist/esm/types/api.types.d.ts +21 -0
  236. package/dist/esm/types/api.types.js +22 -0
  237. package/dist/esm/types/common.types.d.ts +1 -0
  238. package/dist/esm/types/common.types.js +1 -0
  239. package/dist/esm/types/config.types.d.ts +104 -0
  240. package/dist/esm/types/config.types.js +1 -0
  241. package/dist/esm/types/device.types.d.ts +6 -0
  242. package/dist/esm/types/device.types.js +7 -0
  243. package/dist/esm/types/event.types.d.ts +104 -0
  244. package/dist/esm/types/event.types.js +22 -0
  245. package/dist/esm/types/index.d.ts +13 -0
  246. package/dist/esm/types/index.js +13 -0
  247. package/dist/esm/types/log.types.d.ts +4 -0
  248. package/dist/esm/types/log.types.js +1 -0
  249. package/dist/esm/types/mode.types.d.ts +7 -0
  250. package/dist/esm/types/mode.types.js +8 -0
  251. package/dist/esm/types/queue.types.d.ts +23 -0
  252. package/dist/esm/types/queue.types.js +1 -0
  253. package/dist/esm/types/session.types.d.ts +65 -0
  254. package/dist/esm/types/session.types.js +1 -0
  255. package/dist/esm/types/state.types.d.ts +12 -0
  256. package/dist/esm/types/state.types.js +1 -0
  257. package/dist/esm/types/tag.types.d.ts +43 -0
  258. package/dist/esm/types/tag.types.js +28 -0
  259. package/dist/esm/types/validation-error.types.d.ts +42 -0
  260. package/dist/esm/types/validation-error.types.js +59 -0
  261. package/dist/esm/types/web-vitals.types.d.ts +6 -0
  262. package/dist/esm/types/web-vitals.types.js +1 -0
  263. package/dist/esm/types/window.types.d.ts +17 -0
  264. package/dist/esm/types/window.types.js +1 -0
  265. package/dist/esm/utils/browser/device-detector.utils.d.ts +6 -0
  266. package/dist/esm/utils/browser/device-detector.utils.js +67 -0
  267. package/dist/esm/utils/browser/index.d.ts +2 -0
  268. package/dist/esm/utils/browser/index.js +2 -0
  269. package/dist/esm/utils/browser/utm-params.utils.d.ts +6 -0
  270. package/dist/esm/utils/browser/utm-params.utils.js +33 -0
  271. package/dist/esm/utils/data/index.d.ts +1 -0
  272. package/dist/esm/utils/data/index.js +1 -0
  273. package/dist/esm/utils/data/uuid.utils.d.ts +5 -0
  274. package/dist/esm/utils/data/uuid.utils.js +14 -0
  275. package/dist/esm/utils/index.d.ts +6 -0
  276. package/dist/esm/utils/index.js +6 -0
  277. package/dist/esm/utils/logging/debug-logger.utils.d.ts +56 -0
  278. package/dist/esm/utils/logging/debug-logger.utils.js +136 -0
  279. package/dist/esm/utils/logging/index.d.ts +1 -0
  280. package/dist/esm/utils/logging/index.js +1 -0
  281. package/dist/esm/utils/network/index.d.ts +1 -0
  282. package/dist/esm/utils/network/index.js +1 -0
  283. package/dist/esm/utils/network/url.utils.d.ts +20 -0
  284. package/dist/esm/utils/network/url.utils.js +166 -0
  285. package/dist/esm/utils/security/index.d.ts +1 -0
  286. package/dist/esm/utils/security/index.js +1 -0
  287. package/dist/esm/utils/security/sanitize.utils.d.ts +32 -0
  288. package/dist/esm/utils/security/sanitize.utils.js +311 -0
  289. package/dist/esm/utils/validations/config-validations.utils.d.ts +42 -0
  290. package/dist/esm/utils/validations/config-validations.utils.js +289 -0
  291. package/dist/esm/utils/validations/event-validations.utils.d.ts +12 -0
  292. package/dist/esm/utils/validations/event-validations.utils.js +26 -0
  293. package/dist/esm/utils/validations/index.d.ts +5 -0
  294. package/dist/esm/utils/validations/index.js +5 -0
  295. package/dist/esm/utils/validations/metadata-validations.utils.d.ts +22 -0
  296. package/dist/esm/utils/validations/metadata-validations.utils.js +110 -0
  297. package/dist/esm/utils/validations/type-guards.utils.d.ts +6 -0
  298. package/dist/esm/utils/validations/type-guards.utils.js +27 -0
  299. package/dist/esm/utils/validations/url-validations.utils.d.ts +15 -0
  300. package/dist/esm/utils/validations/url-validations.utils.js +42 -0
  301. package/package.json +80 -0
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.MIN_SESSION_RECOVERY_WINDOW_MS = exports.MAX_SESSION_RECOVERY_WINDOW_MS = exports.MAX_SESSION_RECOVERY_ATTEMPTS = exports.SESSION_RECOVERY_WINDOW_MULTIPLIER = exports.TAB_CLEANUP_DELAY_MS = exports.TAB_ELECTION_TIMEOUT_MS = exports.TAB_HEARTBEAT_INTERVAL_MS = exports.SESSION_END_PRIORITY_DELAY_MS = exports.LONG_TASK_THROTTLE_MS = exports.EVENT_PERSISTENCE_MAX_AGE_MS = exports.EVENT_EXPIRY_HOURS = exports.RATE_LIMIT_INTERVAL = exports.RETRY_BACKOFF_MAX = exports.RETRY_BACKOFF_INITIAL = exports.EVENT_SENT_INTERVAL_TEST_MS = exports.EVENT_SENT_INTERVAL_MS = exports.DUPLICATE_EVENT_THRESHOLD_MS = exports.DEFAULT_VISIBILITY_TIMEOUT_MS = exports.SCROLL_DEBOUNCE_TIME_MS = exports.DEFAULT_THROTTLE_DELAY_MS = exports.SESSION_HEARTBEAT_INTERVAL_MS = exports.DEFAULT_SESSION_TIMEOUT_MS = void 0;
4
+ // Session and timeout constants
5
+ exports.DEFAULT_SESSION_TIMEOUT_MS = 15 * 60 * 1000;
6
+ exports.SESSION_HEARTBEAT_INTERVAL_MS = 30000;
7
+ // Throttling and debouncing constants
8
+ exports.DEFAULT_THROTTLE_DELAY_MS = 1000;
9
+ exports.SCROLL_DEBOUNCE_TIME_MS = 250;
10
+ exports.DEFAULT_VISIBILITY_TIMEOUT_MS = 2000;
11
+ exports.DUPLICATE_EVENT_THRESHOLD_MS = 1000;
12
+ // Event processing intervals
13
+ exports.EVENT_SENT_INTERVAL_MS = 10000;
14
+ exports.EVENT_SENT_INTERVAL_TEST_MS = 2500;
15
+ // Network timing
16
+ exports.RETRY_BACKOFF_INITIAL = 1000; // 1 second
17
+ exports.RETRY_BACKOFF_MAX = 30000; // 30 seconds
18
+ exports.RATE_LIMIT_INTERVAL = 1000; // 1 second
19
+ // Event expiry
20
+ exports.EVENT_EXPIRY_HOURS = 24;
21
+ exports.EVENT_PERSISTENCE_MAX_AGE_MS = 24 * 60 * 60 * 1000; // 24 hours
22
+ // Performance metrics
23
+ exports.LONG_TASK_THROTTLE_MS = exports.DEFAULT_THROTTLE_DELAY_MS;
24
+ // Session end coordination
25
+ exports.SESSION_END_PRIORITY_DELAY_MS = 100;
26
+ // Cross-tab session management
27
+ exports.TAB_HEARTBEAT_INTERVAL_MS = 5000; // 5 seconds
28
+ exports.TAB_ELECTION_TIMEOUT_MS = 2000; // 2 seconds
29
+ exports.TAB_CLEANUP_DELAY_MS = 1000; // 1 second
30
+ // Session recovery
31
+ exports.SESSION_RECOVERY_WINDOW_MULTIPLIER = 2; // 2x session timeout
32
+ exports.MAX_SESSION_RECOVERY_ATTEMPTS = 3;
33
+ exports.MAX_SESSION_RECOVERY_WINDOW_MS = 24 * 60 * 60 * 1000; // 24 hours max
34
+ exports.MIN_SESSION_RECOVERY_WINDOW_MS = 2 * 60 * 1000; // 2 minutes minimum
@@ -0,0 +1,13 @@
1
+ import { ApiConfig } from '../types';
2
+ export declare const ALLOWED_API_CONFIG_KEYS: Set<keyof ApiConfig>;
3
+ export declare const VALIDATION_MESSAGES: {
4
+ readonly MISSING_PROJECT_ID: "Project ID is required";
5
+ readonly PROJECT_ID_EMPTY_AFTER_TRIM: "Project ID is required";
6
+ readonly INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)";
7
+ readonly INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1";
8
+ readonly INVALID_ERROR_SAMPLING_RATE: "Error sampling must be between 0 and 1";
9
+ readonly INVALID_GOOGLE_ANALYTICS_ID: "Google Analytics measurement ID is required when integration is enabled";
10
+ readonly INVALID_SCROLL_CONTAINER_SELECTORS: "Scroll container selectors must be valid CSS selectors";
11
+ readonly INVALID_GLOBAL_METADATA: "Global metadata must be an object";
12
+ readonly INVALID_SENSITIVE_QUERY_PARAMS: "Sensitive query params must be an array of strings";
13
+ };
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VALIDATION_MESSAGES = exports.ALLOWED_API_CONFIG_KEYS = void 0;
4
+ const limits_constants_1 = require("./limits.constants");
5
+ // Allowed API config keys for runtime validation
6
+ exports.ALLOWED_API_CONFIG_KEYS = new Set([
7
+ 'mode',
8
+ 'tags',
9
+ 'samplingRate',
10
+ 'excludedUrlPaths',
11
+ 'ipExcluded',
12
+ ]);
13
+ // Validation error messages - standardized across all layers
14
+ exports.VALIDATION_MESSAGES = {
15
+ // Project ID validation - consistent message across all layers
16
+ MISSING_PROJECT_ID: 'Project ID is required',
17
+ PROJECT_ID_EMPTY_AFTER_TRIM: 'Project ID is required',
18
+ // Session timeout validation
19
+ INVALID_SESSION_TIMEOUT: `Session timeout must be between ${limits_constants_1.MIN_SESSION_TIMEOUT_MS}ms (30 seconds) and ${limits_constants_1.MAX_SESSION_TIMEOUT_MS}ms (24 hours)`,
20
+ // Sampling rate validation
21
+ INVALID_SAMPLING_RATE: `Sampling rate must be between ${limits_constants_1.MIN_SAMPLING_RATE} and ${limits_constants_1.MAX_SAMPLING_RATE}`,
22
+ INVALID_ERROR_SAMPLING_RATE: 'Error sampling must be between 0 and 1',
23
+ // Integration validation
24
+ INVALID_GOOGLE_ANALYTICS_ID: 'Google Analytics measurement ID is required when integration is enabled',
25
+ // UI validation
26
+ INVALID_SCROLL_CONTAINER_SELECTORS: 'Scroll container selectors must be valid CSS selectors',
27
+ // Global metadata validation
28
+ INVALID_GLOBAL_METADATA: 'Global metadata must be an object',
29
+ // Array validation
30
+ INVALID_SENSITIVE_QUERY_PARAMS: 'Sensitive query params must be an array of strings',
31
+ };
@@ -0,0 +1,17 @@
1
+ import { EventManager } from '../managers/event.manager';
2
+ import { StateManager } from '../managers/state.manager';
3
+ export declare class ClickHandler extends StateManager {
4
+ private readonly eventManager;
5
+ private clickHandler?;
6
+ constructor(eventManager: EventManager);
7
+ startTracking(): void;
8
+ stopTracking(): void;
9
+ private findTrackingElement;
10
+ private getRelevantClickElement;
11
+ private calculateClickCoordinates;
12
+ private extractTrackingData;
13
+ private generateClickData;
14
+ private getRelevantText;
15
+ private extractElementAttributes;
16
+ private createCustomEventData;
17
+ }
@@ -0,0 +1,199 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ClickHandler = void 0;
4
+ const constants_1 = require("../constants");
5
+ const types_1 = require("../types");
6
+ const state_manager_1 = require("../managers/state.manager");
7
+ const logging_1 = require("../utils/logging");
8
+ class ClickHandler extends state_manager_1.StateManager {
9
+ constructor(eventManager) {
10
+ super();
11
+ this.eventManager = eventManager;
12
+ }
13
+ startTracking() {
14
+ if (this.clickHandler) {
15
+ logging_1.debugLog.debug('ClickHandler', 'Click tracking already active');
16
+ return;
17
+ }
18
+ logging_1.debugLog.debug('ClickHandler', 'Starting click tracking');
19
+ this.clickHandler = (event) => {
20
+ const mouseEvent = event;
21
+ const target = mouseEvent.target;
22
+ const clickedElement = target instanceof HTMLElement
23
+ ? target
24
+ : target instanceof Node && target.parentElement instanceof HTMLElement
25
+ ? target.parentElement
26
+ : null;
27
+ if (!clickedElement) {
28
+ logging_1.debugLog.warn('ClickHandler', 'Click target not found or not an element');
29
+ return;
30
+ }
31
+ logging_1.debugLog.info('ClickHandler', '🖱️ Click detected on element', {
32
+ tagName: clickedElement.tagName,
33
+ className: clickedElement.className || 'none',
34
+ textContent: clickedElement.textContent?.slice(0, 50) ?? 'empty',
35
+ });
36
+ const trackingElement = this.findTrackingElement(clickedElement);
37
+ const relevantClickElement = this.getRelevantClickElement(clickedElement);
38
+ const coordinates = this.calculateClickCoordinates(mouseEvent, clickedElement);
39
+ if (trackingElement) {
40
+ const trackingData = this.extractTrackingData(trackingElement);
41
+ if (trackingData) {
42
+ const attributeData = this.createCustomEventData(trackingData);
43
+ this.eventManager.track({
44
+ type: types_1.EventType.CUSTOM,
45
+ custom_event: {
46
+ name: attributeData.name,
47
+ ...(attributeData.value && { metadata: { value: attributeData.value } }),
48
+ },
49
+ });
50
+ }
51
+ }
52
+ const clickData = this.generateClickData(clickedElement, relevantClickElement, coordinates);
53
+ this.eventManager.track({
54
+ type: types_1.EventType.CLICK,
55
+ click_data: clickData,
56
+ });
57
+ };
58
+ window.addEventListener('click', this.clickHandler, true);
59
+ }
60
+ stopTracking() {
61
+ if (this.clickHandler) {
62
+ window.removeEventListener('click', this.clickHandler, true);
63
+ this.clickHandler = undefined;
64
+ }
65
+ }
66
+ findTrackingElement(element) {
67
+ if (element.hasAttribute(`${constants_1.HTML_DATA_ATTR_PREFIX}-name`)) {
68
+ return element;
69
+ }
70
+ const closest = element.closest(`[${constants_1.HTML_DATA_ATTR_PREFIX}-name]`);
71
+ return closest || undefined;
72
+ }
73
+ getRelevantClickElement(element) {
74
+ for (const selector of constants_1.INTERACTIVE_SELECTORS) {
75
+ try {
76
+ if (element.matches(selector)) {
77
+ return element;
78
+ }
79
+ }
80
+ catch (error) {
81
+ logging_1.debugLog.warn('ClickHandler', 'Invalid selector in interactive elements check', {
82
+ selector,
83
+ error: error instanceof Error ? error.message : 'Unknown error',
84
+ });
85
+ continue;
86
+ }
87
+ }
88
+ for (const selector of constants_1.INTERACTIVE_SELECTORS) {
89
+ try {
90
+ const parent = element.closest(selector);
91
+ if (parent) {
92
+ return parent;
93
+ }
94
+ }
95
+ catch (error) {
96
+ logging_1.debugLog.warn('ClickHandler', 'Invalid selector in parent element search', {
97
+ selector,
98
+ error: error instanceof Error ? error.message : 'Unknown error',
99
+ });
100
+ continue;
101
+ }
102
+ }
103
+ return element;
104
+ }
105
+ calculateClickCoordinates(event, element) {
106
+ const rect = element.getBoundingClientRect();
107
+ const x = event.clientX;
108
+ const y = event.clientY;
109
+ const relativeX = rect.width > 0 ? Math.max(0, Math.min(1, Number(((x - rect.left) / rect.width).toFixed(3)))) : 0;
110
+ const relativeY = rect.height > 0 ? Math.max(0, Math.min(1, Number(((y - rect.top) / rect.height).toFixed(3)))) : 0;
111
+ return { x, y, relativeX, relativeY };
112
+ }
113
+ extractTrackingData(trackingElement) {
114
+ const name = trackingElement.getAttribute(`${constants_1.HTML_DATA_ATTR_PREFIX}-name`);
115
+ const value = trackingElement.getAttribute(`${constants_1.HTML_DATA_ATTR_PREFIX}-value`);
116
+ if (!name) {
117
+ return undefined;
118
+ }
119
+ return {
120
+ element: trackingElement,
121
+ name,
122
+ ...(value && { value }),
123
+ };
124
+ }
125
+ generateClickData(clickedElement, relevantElement, coordinates) {
126
+ const { x, y, relativeX, relativeY } = coordinates;
127
+ const text = this.getRelevantText(clickedElement, relevantElement);
128
+ const attributes = this.extractElementAttributes(relevantElement);
129
+ const href = relevantElement.getAttribute('href');
130
+ const title = relevantElement.getAttribute('title');
131
+ const alt = relevantElement.getAttribute('alt');
132
+ const role = relevantElement.getAttribute('role');
133
+ const ariaLabel = relevantElement.getAttribute('aria-label');
134
+ const className = typeof relevantElement.className === 'string' ? relevantElement.className : String(relevantElement.className);
135
+ return {
136
+ x,
137
+ y,
138
+ relativeX,
139
+ relativeY,
140
+ tag: relevantElement.tagName.toLowerCase(),
141
+ ...(relevantElement.id && { id: relevantElement.id }),
142
+ ...(relevantElement.className && { class: className }),
143
+ ...(text && { text }),
144
+ ...(href && { href }),
145
+ ...(title && { title }),
146
+ ...(alt && { alt }),
147
+ ...(role && { role }),
148
+ ...(ariaLabel && { ariaLabel }),
149
+ ...(Object.keys(attributes).length > 0 && { dataAttributes: attributes }),
150
+ };
151
+ }
152
+ getRelevantText(clickedElement, relevantElement) {
153
+ const LARGE_CONTAINER_TAGS = ['main', 'section', 'article', 'body', 'html', 'header', 'footer', 'aside', 'nav'];
154
+ const clickedText = clickedElement.textContent?.trim() ?? '';
155
+ const relevantText = relevantElement.textContent?.trim() ?? '';
156
+ if (!clickedText && !relevantText) {
157
+ return '';
158
+ }
159
+ // Strategy 1: If clicked element has reasonable text, use it
160
+ if (clickedText && clickedText.length <= constants_1.MAX_TEXT_LENGTH) {
161
+ return clickedText;
162
+ }
163
+ // Strategy 2: For large containers with excessive text, avoid using container text
164
+ const isLargeContainer = LARGE_CONTAINER_TAGS.includes(relevantElement.tagName.toLowerCase());
165
+ const hasExcessiveText = relevantText.length > constants_1.MAX_TEXT_LENGTH * 2; // 510 chars
166
+ if (isLargeContainer && hasExcessiveText) {
167
+ // Use clicked element text if available and reasonable, otherwise empty
168
+ return clickedText && clickedText.length <= constants_1.MAX_TEXT_LENGTH ? clickedText : '';
169
+ }
170
+ // Strategy 3: Use relevant text but truncate if needed
171
+ if (relevantText.length <= constants_1.MAX_TEXT_LENGTH) {
172
+ return relevantText;
173
+ }
174
+ // Strategy 4: If clicked text is much shorter than relevant text, prefer clicked text
175
+ if (clickedText && clickedText.length < relevantText.length * 0.1) {
176
+ return clickedText.length <= constants_1.MAX_TEXT_LENGTH ? clickedText : clickedText.slice(0, constants_1.MAX_TEXT_LENGTH - 3) + '...';
177
+ }
178
+ // Fallback: truncate relevant text to exactly MAX_TEXT_LENGTH including ellipsis
179
+ return relevantText.slice(0, constants_1.MAX_TEXT_LENGTH - 3) + '...';
180
+ }
181
+ extractElementAttributes(element) {
182
+ const commonAttributes = ['id', 'class', 'data-testid', 'aria-label', 'title', 'href', 'type', 'name'];
183
+ const result = {};
184
+ for (const attributeName of commonAttributes) {
185
+ const value = element.getAttribute(attributeName);
186
+ if (value) {
187
+ result[attributeName] = value;
188
+ }
189
+ }
190
+ return result;
191
+ }
192
+ createCustomEventData(trackingData) {
193
+ return {
194
+ name: trackingData.name,
195
+ ...(trackingData.value && { value: trackingData.value }),
196
+ };
197
+ }
198
+ }
199
+ exports.ClickHandler = ClickHandler;
@@ -0,0 +1,15 @@
1
+ import { EventManager } from '../managers/event.manager';
2
+ import { StateManager } from '../managers/state.manager';
3
+ export declare class ErrorHandler extends StateManager {
4
+ private readonly eventManager;
5
+ private readonly piiPatterns;
6
+ constructor(eventManager: EventManager);
7
+ startTracking(): void;
8
+ stopTracking(): void;
9
+ private setupErrorListener;
10
+ private setupUnhandledRejectionListener;
11
+ private readonly handleError;
12
+ private readonly handleUnhandledRejection;
13
+ private sanitizeText;
14
+ private shouldSample;
15
+ }
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ErrorHandler = void 0;
4
+ const state_manager_1 = require("../managers/state.manager");
5
+ const types_1 = require("../types");
6
+ const logging_1 = require("../utils/logging");
7
+ class ErrorHandler extends state_manager_1.StateManager {
8
+ constructor(eventManager) {
9
+ super();
10
+ this.piiPatterns = [
11
+ /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b/g,
12
+ /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,
13
+ /\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,
14
+ /\b[A-Z]{2}\d{2}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,
15
+ ];
16
+ this.handleError = (event) => {
17
+ const config = this.get('config');
18
+ if (!this.shouldSample(config?.errorSampling ?? 0.1)) {
19
+ logging_1.debugLog.debug('ErrorHandler', `Error not sampled, skipping (errorSampling: ${config?.errorSampling})`, {
20
+ errorSampling: config?.errorSampling,
21
+ });
22
+ return;
23
+ }
24
+ logging_1.debugLog.warn('ErrorHandler', `JavaScript error captured: ${event.message} (filename: ${event.filename}, lineno: ${event.lineno})`, {
25
+ message: event.message,
26
+ filename: event.filename,
27
+ lineno: event.lineno,
28
+ });
29
+ this.eventManager.track({
30
+ type: types_1.EventType.ERROR,
31
+ error_data: {
32
+ type: types_1.ErrorType.JS_ERROR,
33
+ message: this.sanitizeText(event.message || 'Unknown error'),
34
+ },
35
+ });
36
+ };
37
+ this.handleUnhandledRejection = (event) => {
38
+ const config = this.get('config');
39
+ if (!this.shouldSample(config?.errorSampling ?? 0.1)) {
40
+ logging_1.debugLog.debug('ErrorHandler', 'Promise rejection not sampled, skipping', {
41
+ errorSampling: config?.errorSampling,
42
+ });
43
+ return;
44
+ }
45
+ logging_1.debugLog.warn('ErrorHandler', `Unhandled promise rejection captured (reason: ${typeof event.reason})`, {
46
+ reason: typeof event.reason,
47
+ });
48
+ let reason = 'Unknown rejection';
49
+ if (event.reason) {
50
+ if (typeof event.reason === 'string') {
51
+ reason = event.reason;
52
+ }
53
+ else if (event.reason instanceof Error) {
54
+ reason = event.reason.message || event.reason.toString();
55
+ }
56
+ else {
57
+ reason = String(event.reason);
58
+ }
59
+ }
60
+ this.eventManager.track({
61
+ type: types_1.EventType.ERROR,
62
+ error_data: {
63
+ type: types_1.ErrorType.PROMISE_REJECTION,
64
+ message: this.sanitizeText(reason),
65
+ },
66
+ });
67
+ };
68
+ this.eventManager = eventManager;
69
+ }
70
+ startTracking() {
71
+ logging_1.debugLog.debug('ErrorHandler', 'Starting error tracking');
72
+ this.setupErrorListener();
73
+ this.setupUnhandledRejectionListener();
74
+ }
75
+ stopTracking() {
76
+ logging_1.debugLog.debug('ErrorHandler', 'Stopping error tracking');
77
+ window.removeEventListener('error', this.handleError);
78
+ window.removeEventListener('unhandledrejection', this.handleUnhandledRejection);
79
+ }
80
+ setupErrorListener() {
81
+ window.addEventListener('error', this.handleError);
82
+ }
83
+ setupUnhandledRejectionListener() {
84
+ window.addEventListener('unhandledrejection', this.handleUnhandledRejection);
85
+ }
86
+ sanitizeText(text) {
87
+ let sanitized = text;
88
+ for (const pattern of this.piiPatterns) {
89
+ sanitized = sanitized.replace(pattern, '[REDACTED]');
90
+ }
91
+ return sanitized;
92
+ }
93
+ shouldSample(rate) {
94
+ return Math.random() < rate;
95
+ }
96
+ }
97
+ exports.ErrorHandler = ErrorHandler;
@@ -0,0 +1,16 @@
1
+ import { EventManager } from '../managers/event.manager';
2
+ import { StateManager } from '../managers/state.manager';
3
+ export declare class NetworkHandler extends StateManager {
4
+ private readonly eventManager;
5
+ private readonly originalFetch;
6
+ private readonly originalXHROpen;
7
+ private readonly originalXHRSend;
8
+ constructor(eventManager: EventManager);
9
+ startTracking(): void;
10
+ stopTracking(): void;
11
+ private interceptFetch;
12
+ private interceptXHR;
13
+ private trackNetworkError;
14
+ private normalizeUrlForTracking;
15
+ private shouldSample;
16
+ }
@@ -0,0 +1,136 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NetworkHandler = void 0;
4
+ const state_manager_1 = require("../managers/state.manager");
5
+ const types_1 = require("../types");
6
+ const utils_1 = require("../utils");
7
+ const logging_1 = require("../utils/logging");
8
+ class NetworkHandler extends state_manager_1.StateManager {
9
+ constructor(eventManager) {
10
+ super();
11
+ this.eventManager = eventManager;
12
+ this.originalFetch = window.fetch;
13
+ this.originalXHROpen = XMLHttpRequest.prototype.open;
14
+ this.originalXHRSend = XMLHttpRequest.prototype.send;
15
+ }
16
+ startTracking() {
17
+ logging_1.debugLog.debug('NetworkHandler', 'Starting network error tracking');
18
+ this.interceptFetch();
19
+ this.interceptXHR();
20
+ }
21
+ stopTracking() {
22
+ logging_1.debugLog.debug('NetworkHandler', 'Stopping network error tracking');
23
+ window.fetch = this.originalFetch;
24
+ XMLHttpRequest.prototype.open = this.originalXHROpen;
25
+ XMLHttpRequest.prototype.send = this.originalXHRSend;
26
+ }
27
+ interceptFetch() {
28
+ window.fetch = async (input, init) => {
29
+ const startTime = Date.now();
30
+ const url = typeof input === 'string' ? input : input.toString();
31
+ const method = init?.method ?? 'GET';
32
+ try {
33
+ const response = await this.originalFetch(input, init);
34
+ const duration = Date.now() - startTime;
35
+ if (!response.ok) {
36
+ logging_1.debugLog.debug('NetworkHandler', 'Fetch error detected', {
37
+ method,
38
+ url: this.normalizeUrlForTracking(url),
39
+ status: response.status,
40
+ statusText: response.statusText,
41
+ });
42
+ this.trackNetworkError(method.toUpperCase(), this.normalizeUrlForTracking(url), response.status, response.statusText, duration);
43
+ }
44
+ return response;
45
+ }
46
+ catch (error) {
47
+ const duration = Date.now() - startTime;
48
+ const errorMessage = error instanceof Error ? error.message : 'Network Error';
49
+ logging_1.debugLog.debug('NetworkHandler', 'Fetch exception caught', {
50
+ method,
51
+ url: this.normalizeUrlForTracking(url),
52
+ error: errorMessage,
53
+ });
54
+ this.trackNetworkError(method.toUpperCase(), this.normalizeUrlForTracking(url), undefined, errorMessage, duration);
55
+ throw error;
56
+ }
57
+ };
58
+ }
59
+ interceptXHR() {
60
+ const trackNetworkError = this.trackNetworkError.bind(this);
61
+ const normalizeUrlForTracking = this.normalizeUrlForTracking.bind(this);
62
+ const originalXHROpen = this.originalXHROpen;
63
+ const originalXHRSend = this.originalXHRSend;
64
+ XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
65
+ const asyncMode = async ?? true;
66
+ const extendedThis = this;
67
+ extendedThis._tracelogStartTime = Date.now();
68
+ extendedThis._tracelogMethod = method.toUpperCase();
69
+ extendedThis._tracelogUrl = url.toString();
70
+ return originalXHROpen.call(this, method, url, asyncMode, user, password);
71
+ };
72
+ XMLHttpRequest.prototype.send = function (body) {
73
+ const xhr = this;
74
+ const startTime = xhr._tracelogStartTime ?? Date.now();
75
+ const method = xhr._tracelogMethod ?? 'GET';
76
+ const url = xhr._tracelogUrl ?? '';
77
+ const originalOnReadyStateChange = xhr.onreadystatechange;
78
+ xhr.onreadystatechange = (ev) => {
79
+ if (xhr.readyState === XMLHttpRequest.DONE) {
80
+ const duration = Date.now() - startTime;
81
+ if (xhr.status === 0 || xhr.status >= 400) {
82
+ const statusText = xhr.statusText || 'Request Failed';
83
+ logging_1.debugLog.debug('NetworkHandler', 'XHR error detected', {
84
+ method,
85
+ url: normalizeUrlForTracking(url),
86
+ status: xhr.status,
87
+ statusText,
88
+ });
89
+ trackNetworkError(method, normalizeUrlForTracking(url), xhr.status, statusText, duration);
90
+ }
91
+ }
92
+ if (originalOnReadyStateChange) {
93
+ return originalOnReadyStateChange.call(xhr, ev);
94
+ }
95
+ };
96
+ return originalXHRSend.call(this, body);
97
+ };
98
+ }
99
+ trackNetworkError(method, url, status, statusText, duration) {
100
+ const config = this.get('config');
101
+ if (!this.shouldSample(config?.errorSampling ?? 0.1)) {
102
+ logging_1.debugLog.debug('NetworkHandler', `Network error not sampled, skipping (errorSampling: ${config?.errorSampling}, method: ${method}, url: ${url})`, {
103
+ errorSampling: config?.errorSampling,
104
+ method,
105
+ url,
106
+ });
107
+ return;
108
+ }
109
+ logging_1.debugLog.warn('NetworkHandler', `Network error tracked: ${method} ${url} (status: ${status}, statusText: ${statusText}, duration: ${duration}ms)`, { method, url, status, statusText, duration });
110
+ this.eventManager.track({
111
+ type: types_1.EventType.ERROR,
112
+ error_data: {
113
+ type: types_1.ErrorType.NETWORK_ERROR,
114
+ message: statusText,
115
+ method,
116
+ url,
117
+ status,
118
+ statusText,
119
+ duration,
120
+ },
121
+ });
122
+ }
123
+ normalizeUrlForTracking(url) {
124
+ try {
125
+ const config = this.get('config');
126
+ return (0, utils_1.normalizeUrl)(url, config?.sensitiveQueryParams);
127
+ }
128
+ catch {
129
+ return url;
130
+ }
131
+ }
132
+ shouldSample(rate) {
133
+ return Math.random() < rate;
134
+ }
135
+ }
136
+ exports.NetworkHandler = NetworkHandler;
@@ -0,0 +1,15 @@
1
+ import { StateManager } from '../managers/state.manager';
2
+ import { EventManager } from '../managers/event.manager';
3
+ export declare class PageViewHandler extends StateManager {
4
+ private readonly eventManager;
5
+ private readonly onTrack;
6
+ private originalPushState?;
7
+ private originalReplaceState?;
8
+ constructor(eventManager: EventManager, onTrack: () => void);
9
+ startTracking(): void;
10
+ stopTracking(): void;
11
+ private patchHistory;
12
+ private readonly trackCurrentPage;
13
+ private trackInitialPageView;
14
+ private extractPageViewData;
15
+ }
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PageViewHandler = void 0;
4
+ const types_1 = require("../types");
5
+ const utils_1 = require("../utils");
6
+ const state_manager_1 = require("../managers/state.manager");
7
+ const logging_1 = require("../utils/logging");
8
+ class PageViewHandler extends state_manager_1.StateManager {
9
+ constructor(eventManager, onTrack) {
10
+ super();
11
+ this.trackCurrentPage = () => {
12
+ const rawUrl = window.location.href;
13
+ const normalizedUrl = (0, utils_1.normalizeUrl)(rawUrl, this.get('config').sensitiveQueryParams);
14
+ if (this.get('pageUrl') !== normalizedUrl) {
15
+ const fromUrl = this.get('pageUrl');
16
+ logging_1.debugLog.debug('PageViewHandler', 'Page navigation detected', { from: fromUrl, to: normalizedUrl });
17
+ this.set('pageUrl', normalizedUrl);
18
+ this.eventManager.track({
19
+ type: types_1.EventType.PAGE_VIEW,
20
+ page_url: this.get('pageUrl'),
21
+ from_page_url: fromUrl,
22
+ ...(this.extractPageViewData() && { page_view: this.extractPageViewData() }),
23
+ });
24
+ this.onTrack();
25
+ }
26
+ };
27
+ this.eventManager = eventManager;
28
+ this.onTrack = onTrack;
29
+ }
30
+ startTracking() {
31
+ logging_1.debugLog.debug('PageViewHandler', 'Starting page view tracking');
32
+ this.trackInitialPageView();
33
+ this.trackCurrentPage();
34
+ window.addEventListener('popstate', this.trackCurrentPage);
35
+ window.addEventListener('hashchange', this.trackCurrentPage);
36
+ this.patchHistory('pushState');
37
+ this.patchHistory('replaceState');
38
+ }
39
+ stopTracking() {
40
+ logging_1.debugLog.debug('PageViewHandler', 'Stopping page view tracking');
41
+ window.removeEventListener('popstate', this.trackCurrentPage);
42
+ window.removeEventListener('hashchange', this.trackCurrentPage);
43
+ if (this.originalPushState) {
44
+ window.history.pushState = this.originalPushState;
45
+ }
46
+ if (this.originalReplaceState) {
47
+ window.history.replaceState = this.originalReplaceState;
48
+ }
49
+ }
50
+ patchHistory(method) {
51
+ if (method === 'pushState' && !this.originalPushState) {
52
+ this.originalPushState = window.history.pushState;
53
+ }
54
+ else if (method === 'replaceState' && !this.originalReplaceState) {
55
+ this.originalReplaceState = window.history.replaceState;
56
+ }
57
+ const original = window.history[method];
58
+ window.history[method] = (...args) => {
59
+ original.apply(window.history, args);
60
+ this.trackCurrentPage();
61
+ };
62
+ }
63
+ trackInitialPageView() {
64
+ this.eventManager.track({
65
+ type: types_1.EventType.PAGE_VIEW,
66
+ page_url: this.get('pageUrl'),
67
+ ...(this.extractPageViewData() && { page_view: this.extractPageViewData() }),
68
+ });
69
+ this.onTrack();
70
+ }
71
+ extractPageViewData() {
72
+ const location = window.location;
73
+ const data = {
74
+ ...(document.referrer && { referrer: document.referrer }),
75
+ ...(document.title && { title: document.title }),
76
+ ...(location.pathname && { pathname: location.pathname }),
77
+ ...(location.search && { search: location.search }),
78
+ ...(location.hash && { hash: location.hash }),
79
+ };
80
+ return Object.values(data).some((value) => !!value) ? data : undefined;
81
+ }
82
+ }
83
+ exports.PageViewHandler = PageViewHandler;