@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,357 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SessionHandler = void 0;
4
+ const constants_1 = require("../constants");
5
+ const types_1 = require("../types");
6
+ const session_manager_1 = require("../managers/session.manager");
7
+ const session_recovery_manager_1 = require("../managers/session-recovery.manager");
8
+ const cross_tab_session_manager_1 = require("../managers/cross-tab-session.manager");
9
+ const state_manager_1 = require("../managers/state.manager");
10
+ const logging_1 = require("../utils/logging");
11
+ class SessionHandler extends state_manager_1.StateManager {
12
+ get crossTabSessionManager() {
13
+ if (!this._crossTabSessionManager && !this._isInitializingCrossTab && this.shouldUseCrossTabs()) {
14
+ this._isInitializingCrossTab = true;
15
+ try {
16
+ const projectId = this.get('config')?.id;
17
+ if (projectId) {
18
+ this.initializeCrossTabSessionManager(projectId);
19
+ }
20
+ }
21
+ catch (error) {
22
+ logging_1.debugLog.error('SessionHandler', 'Failed to initialize cross-tab session manager', {
23
+ error: error instanceof Error ? error.message : 'Unknown error',
24
+ });
25
+ }
26
+ finally {
27
+ this._isInitializingCrossTab = false;
28
+ }
29
+ }
30
+ return this._crossTabSessionManager;
31
+ }
32
+ shouldUseCrossTabs() {
33
+ // Only initialize if BroadcastChannel is supported (indicates potential for multiple tabs)
34
+ // and ServiceWorker is available (better cross-tab coordination)
35
+ return typeof BroadcastChannel !== 'undefined' && typeof navigator !== 'undefined' && 'serviceWorker' in navigator;
36
+ }
37
+ constructor(storageManager, eventManager) {
38
+ super();
39
+ this.sessionManager = null;
40
+ this.recoveryManager = null;
41
+ this._crossTabSessionManager = null;
42
+ this.heartbeatInterval = null;
43
+ this._isInitializingCrossTab = false;
44
+ this.eventManager = eventManager;
45
+ this.storageManager = storageManager;
46
+ this.sessionStorageKey = (0, constants_1.SESSION_STORAGE_KEY)(this.get('config')?.id);
47
+ const projectId = this.get('config')?.id;
48
+ if (projectId) {
49
+ this.initializeSessionRecoveryManager(projectId);
50
+ // CrossTabSessionManager will be initialized lazily when needed via the getter
51
+ }
52
+ }
53
+ startTracking() {
54
+ if (this.sessionManager) {
55
+ logging_1.debugLog.debug('SessionHandler', 'Session tracking already active');
56
+ return;
57
+ }
58
+ logging_1.debugLog.debug('SessionHandler', 'Starting session tracking');
59
+ this.checkOrphanedSessions();
60
+ const onActivity = async () => {
61
+ if (this.crossTabSessionManager) {
62
+ this.crossTabSessionManager.updateSessionActivity();
63
+ }
64
+ if (this.get('sessionId')) {
65
+ return;
66
+ }
67
+ try {
68
+ const sessionResult = await this.createOrJoinSession();
69
+ this.set('sessionId', sessionResult.sessionId);
70
+ logging_1.debugLog.info('SessionHandler', '🏁 Session started', {
71
+ sessionId: sessionResult.sessionId,
72
+ recovered: sessionResult.recovered,
73
+ crossTabActive: !!this.crossTabSessionManager,
74
+ });
75
+ this.trackSession(types_1.EventType.SESSION_START, sessionResult.recovered);
76
+ this.persistSession(sessionResult.sessionId);
77
+ this.startHeartbeat();
78
+ }
79
+ catch (error) {
80
+ logging_1.debugLog.error('SessionHandler', `Session creation failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
81
+ this.forceCleanupSession();
82
+ }
83
+ };
84
+ const onInactivity = () => {
85
+ if (!this.get('sessionId')) {
86
+ return;
87
+ }
88
+ if (this.crossTabSessionManager && this.crossTabSessionManager.getEffectiveSessionTimeout() > 0) {
89
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
90
+ logging_1.debugLog.debug('SessionHandler', 'Session kept alive by cross-tab activity');
91
+ }
92
+ return;
93
+ }
94
+ this.sessionManager.endSessionManaged('inactivity')
95
+ .then((result) => {
96
+ logging_1.debugLog.info('SessionHandler', '🛑 Session ended by inactivity', {
97
+ sessionId: this.get('sessionId'),
98
+ reason: result.reason,
99
+ success: result.success,
100
+ eventsFlushed: result.eventsFlushed,
101
+ });
102
+ if (this.crossTabSessionManager) {
103
+ this.crossTabSessionManager.endSession('inactivity');
104
+ }
105
+ this.clearPersistedSession();
106
+ this.stopHeartbeat();
107
+ })
108
+ .catch((error) => {
109
+ logging_1.debugLog.error('SessionHandler', `Session end failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
110
+ this.forceCleanupSession();
111
+ });
112
+ };
113
+ const sessionEndConfig = {
114
+ enablePageUnloadHandlers: true,
115
+ debugMode: (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') ?? false,
116
+ syncTimeoutMs: constants_1.SESSION_SYNC_CONSTANTS.SYNC_TIMEOUT_MS,
117
+ maxRetries: constants_1.SESSION_SYNC_CONSTANTS.MAX_RETRY_ATTEMPTS,
118
+ };
119
+ this.sessionManager = new session_manager_1.SessionManager(onActivity, onInactivity, this.eventManager, this.storageManager, sessionEndConfig);
120
+ logging_1.debugLog.debug('SessionHandler', 'Session manager initialized');
121
+ this.startInitialSession();
122
+ }
123
+ stopTracking() {
124
+ logging_1.debugLog.info('SessionHandler', 'Stopping session tracking');
125
+ if (this.sessionManager) {
126
+ if (this.get('sessionId')) {
127
+ try {
128
+ this.sessionManager.endSessionSafely('manual_stop', { forceSync: true });
129
+ this.clearPersistedSession();
130
+ this.stopHeartbeat();
131
+ }
132
+ catch (error) {
133
+ logging_1.debugLog.error('SessionHandler', `Manual session stop failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
134
+ this.forceCleanupSession();
135
+ }
136
+ }
137
+ this.sessionManager.destroy();
138
+ this.sessionManager = null;
139
+ }
140
+ if (this._crossTabSessionManager) {
141
+ this._crossTabSessionManager.destroy();
142
+ this._crossTabSessionManager = null;
143
+ }
144
+ // Reset cross-tab initialization flag
145
+ this._isInitializingCrossTab = false;
146
+ if (this.recoveryManager) {
147
+ this.recoveryManager.cleanupOldRecoveryAttempts();
148
+ this.recoveryManager = null;
149
+ }
150
+ }
151
+ initializeSessionRecoveryManager(projectId) {
152
+ this.recoveryManager = new session_recovery_manager_1.SessionRecoveryManager(this.storageManager, projectId, this.eventManager);
153
+ logging_1.debugLog.debug('SessionHandler', 'Session recovery manager initialized', { projectId });
154
+ }
155
+ initializeCrossTabSessionManager(projectId) {
156
+ const config = {
157
+ debugMode: (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') ?? false,
158
+ };
159
+ const onSessionStart = (sessionId) => {
160
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
161
+ logging_1.debugLog.debug('SessionHandler', `Cross-tab session started: ${sessionId}`);
162
+ }
163
+ this.set('sessionId', sessionId);
164
+ this.trackSession(types_1.EventType.SESSION_START, false);
165
+ this.persistSession(sessionId);
166
+ this.startHeartbeat();
167
+ };
168
+ const onSessionEnd = (reason) => {
169
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
170
+ logging_1.debugLog.debug('SessionHandler', `Cross-tab session ended: ${reason}`);
171
+ }
172
+ this.clearPersistedSession();
173
+ this.trackSession(types_1.EventType.SESSION_END, false, reason);
174
+ };
175
+ const onTabActivity = () => {
176
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
177
+ logging_1.debugLog.debug('SessionHandler', 'Cross-tab activity detected');
178
+ }
179
+ };
180
+ const onCrossTabConflict = () => {
181
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
182
+ logging_1.debugLog.warn('SessionHandler', 'Cross-tab conflict detected');
183
+ }
184
+ // Track cross-tab conflict in session health
185
+ if (this.sessionManager) {
186
+ this.sessionManager.trackSessionHealth('conflict');
187
+ }
188
+ };
189
+ const callbacks = {
190
+ onSessionStart,
191
+ onSessionEnd,
192
+ onTabActivity,
193
+ onCrossTabConflict,
194
+ };
195
+ this._crossTabSessionManager = new cross_tab_session_manager_1.CrossTabSessionManager(this.storageManager, projectId, config, callbacks);
196
+ logging_1.debugLog.debug('SessionHandler', 'Cross-tab session manager initialized', { projectId });
197
+ }
198
+ async createOrJoinSession() {
199
+ if (this.crossTabSessionManager) {
200
+ const existingSessionId = this.crossTabSessionManager.getSessionId();
201
+ if (existingSessionId) {
202
+ return { sessionId: existingSessionId, recovered: false };
203
+ }
204
+ // If cross-tab manager exists but no session, create one through regular session manager
205
+ // The cross-tab manager will coordinate with other tabs automatically
206
+ const sessionResult = this.sessionManager.startSession();
207
+ return { sessionId: sessionResult.sessionId, recovered: sessionResult.recovered ?? false };
208
+ }
209
+ // Fallback: create regular session when no cross-tab manager
210
+ const sessionResult = this.sessionManager.startSession();
211
+ return { sessionId: sessionResult.sessionId, recovered: sessionResult.recovered ?? false };
212
+ }
213
+ forceCleanupSession() {
214
+ // Clear session state
215
+ this.set('sessionId', null);
216
+ // Clear persisted session data
217
+ this.clearPersistedSession();
218
+ // Stop heartbeat timer
219
+ this.stopHeartbeat();
220
+ // Clean up cross-tab session if exists
221
+ if (this.crossTabSessionManager) {
222
+ try {
223
+ this.crossTabSessionManager.endSession('orphaned_cleanup');
224
+ }
225
+ catch (error) {
226
+ // Silent cleanup - we're already in error recovery
227
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
228
+ logging_1.debugLog.warn('SessionHandler', `Cross-tab cleanup failed during force cleanup: ${error instanceof Error ? error.message : 'Unknown error'}`);
229
+ }
230
+ }
231
+ }
232
+ // Track session end for analytics
233
+ try {
234
+ this.trackSession(types_1.EventType.SESSION_END, false, 'orphaned_cleanup');
235
+ }
236
+ catch (error) {
237
+ // Silent tracking failure - we're already in error recovery
238
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
239
+ logging_1.debugLog.warn('SessionHandler', `Session tracking failed during force cleanup: ${error instanceof Error ? error.message : 'Unknown error'}`);
240
+ }
241
+ }
242
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
243
+ logging_1.debugLog.debug('SessionHandler', 'Forced session cleanup completed');
244
+ }
245
+ }
246
+ trackSession(eventType, sessionStartRecovered = false, sessionEndReason) {
247
+ this.eventManager.track({
248
+ type: eventType,
249
+ ...(eventType === types_1.EventType.SESSION_START &&
250
+ sessionStartRecovered && { session_start_recovered: sessionStartRecovered }),
251
+ ...(eventType === types_1.EventType.SESSION_END && { session_end_reason: sessionEndReason ?? 'orphaned_cleanup' }),
252
+ });
253
+ }
254
+ startInitialSession() {
255
+ if (this.get('sessionId')) {
256
+ logging_1.debugLog.debug('SessionHandler', 'Session already exists, skipping initial session creation');
257
+ return;
258
+ }
259
+ logging_1.debugLog.debug('SessionHandler', 'Starting initial session');
260
+ // Check if there's already a cross-tab session active
261
+ if (this.crossTabSessionManager) {
262
+ const existingSessionId = this.crossTabSessionManager.getSessionId();
263
+ if (existingSessionId) {
264
+ // Join existing cross-tab session
265
+ this.set('sessionId', existingSessionId);
266
+ this.persistSession(existingSessionId);
267
+ this.startHeartbeat();
268
+ return;
269
+ }
270
+ // No existing cross-tab session, so trigger activity to potentially create one
271
+ // The cross-tab session manager will handle session creation when activity occurs
272
+ return;
273
+ }
274
+ // Fallback: no cross-tab session manager, start regular session
275
+ logging_1.debugLog.debug('SessionHandler', 'Starting regular session (no cross-tab)');
276
+ const sessionResult = this.sessionManager.startSession();
277
+ this.set('sessionId', sessionResult.sessionId);
278
+ this.trackSession(types_1.EventType.SESSION_START, sessionResult.recovered);
279
+ this.persistSession(sessionResult.sessionId);
280
+ this.startHeartbeat();
281
+ }
282
+ checkOrphanedSessions() {
283
+ const storedSessionData = this.storageManager.getItem(this.sessionStorageKey);
284
+ if (storedSessionData) {
285
+ try {
286
+ const session = JSON.parse(storedSessionData);
287
+ const now = Date.now();
288
+ const timeSinceLastHeartbeat = now - session.lastHeartbeat;
289
+ const sessionTimeout = this.get('config')?.sessionTimeout ?? constants_1.DEFAULT_SESSION_TIMEOUT_MS;
290
+ if (timeSinceLastHeartbeat > sessionTimeout) {
291
+ const canRecover = this.recoveryManager?.hasRecoverableSession();
292
+ if (canRecover) {
293
+ if (this.recoveryManager) {
294
+ const sessionContext = {
295
+ sessionId: session.sessionId,
296
+ startTime: session.startTime,
297
+ lastActivity: session.lastHeartbeat,
298
+ tabCount: 1,
299
+ recoveryAttempts: 0,
300
+ metadata: {
301
+ userAgent: navigator.userAgent,
302
+ pageUrl: this.get('pageUrl'),
303
+ },
304
+ };
305
+ this.recoveryManager.storeSessionContextForRecovery(sessionContext);
306
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
307
+ logging_1.debugLog.debug('SessionHandler', `Orphaned session stored for recovery: ${session.sessionId}`);
308
+ }
309
+ }
310
+ }
311
+ this.trackSession(types_1.EventType.SESSION_END);
312
+ this.clearPersistedSession();
313
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
314
+ logging_1.debugLog.debug('SessionHandler', `Orphaned session ended: ${session.sessionId}, recovery available: ${canRecover}`);
315
+ }
316
+ }
317
+ }
318
+ catch {
319
+ this.clearPersistedSession();
320
+ }
321
+ }
322
+ }
323
+ persistSession(sessionId) {
324
+ const sessionData = {
325
+ sessionId,
326
+ startTime: Date.now(),
327
+ lastHeartbeat: Date.now(),
328
+ };
329
+ this.storageManager.setItem(this.sessionStorageKey, JSON.stringify(sessionData));
330
+ }
331
+ clearPersistedSession() {
332
+ this.storageManager.removeItem(this.sessionStorageKey);
333
+ }
334
+ startHeartbeat() {
335
+ this.stopHeartbeat();
336
+ this.heartbeatInterval = setInterval(() => {
337
+ const storedSessionData = this.storageManager.getItem(this.sessionStorageKey);
338
+ if (storedSessionData) {
339
+ try {
340
+ const session = JSON.parse(storedSessionData);
341
+ session.lastHeartbeat = Date.now();
342
+ this.storageManager.setItem(this.sessionStorageKey, JSON.stringify(session));
343
+ }
344
+ catch {
345
+ this.clearPersistedSession();
346
+ }
347
+ }
348
+ }, constants_1.SESSION_HEARTBEAT_INTERVAL_MS);
349
+ }
350
+ stopHeartbeat() {
351
+ if (this.heartbeatInterval) {
352
+ clearInterval(this.heartbeatInterval);
353
+ this.heartbeatInterval = null;
354
+ }
355
+ }
356
+ }
357
+ exports.SessionHandler = SessionHandler;
@@ -0,0 +1,18 @@
1
+ import { MetadataType } from '../types';
2
+ import { StateManager } from '../managers/state.manager';
3
+ declare global {
4
+ interface Window {
5
+ gtag?: (...args: unknown[]) => void;
6
+ dataLayer?: unknown[];
7
+ }
8
+ }
9
+ export declare class GoogleAnalyticsIntegration extends StateManager {
10
+ private isInitialized;
11
+ constructor();
12
+ initialize(): Promise<void>;
13
+ trackEvent(eventName: string, metadata: Record<string, MetadataType>): void;
14
+ cleanup(): void;
15
+ private isScriptAlreadyLoaded;
16
+ private loadScript;
17
+ private configureGtag;
18
+ }
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.GoogleAnalyticsIntegration = void 0;
4
+ const logging_1 = require("../utils/logging");
5
+ const state_manager_1 = require("../managers/state.manager");
6
+ class GoogleAnalyticsIntegration extends state_manager_1.StateManager {
7
+ constructor() {
8
+ super();
9
+ this.isInitialized = false;
10
+ }
11
+ async initialize() {
12
+ if (this.isInitialized) {
13
+ return;
14
+ }
15
+ const measurementId = this.get('config').integrations?.googleAnalytics?.measurementId;
16
+ if (!measurementId?.trim()) {
17
+ logging_1.debugLog.clientWarn('GoogleAnalytics', 'Google Analytics integration disabled - measurementId not configured', {
18
+ hasIntegrations: !!this.get('config').integrations,
19
+ hasGoogleAnalytics: !!this.get('config').integrations?.googleAnalytics,
20
+ });
21
+ return;
22
+ }
23
+ const userId = this.get('userId');
24
+ if (!userId?.trim()) {
25
+ logging_1.debugLog.warn('GoogleAnalytics', 'Google Analytics initialization delayed - userId not available', {
26
+ measurementId: measurementId.substring(0, 8) + '...',
27
+ });
28
+ return;
29
+ }
30
+ try {
31
+ if (this.isScriptAlreadyLoaded()) {
32
+ logging_1.debugLog.info('GoogleAnalytics', 'Google Analytics script already loaded', { measurementId });
33
+ this.isInitialized = true;
34
+ return;
35
+ }
36
+ await this.loadScript(measurementId);
37
+ this.configureGtag(measurementId, userId);
38
+ this.isInitialized = true;
39
+ logging_1.debugLog.info('GoogleAnalytics', 'Google Analytics integration initialized successfully', {
40
+ measurementId,
41
+ userId,
42
+ });
43
+ }
44
+ catch (error) {
45
+ logging_1.debugLog.error('GoogleAnalytics', 'Google Analytics initialization failed', {
46
+ error: error instanceof Error ? error.message : 'Unknown error',
47
+ measurementId,
48
+ userId,
49
+ });
50
+ }
51
+ }
52
+ trackEvent(eventName, metadata) {
53
+ if (!eventName?.trim()) {
54
+ logging_1.debugLog.clientWarn('GoogleAnalytics', 'Event tracking skipped - invalid event name provided', {
55
+ eventName,
56
+ hasMetadata: !!metadata && Object.keys(metadata).length > 0,
57
+ });
58
+ return;
59
+ }
60
+ if (!this.isInitialized) {
61
+ return;
62
+ }
63
+ if (typeof window.gtag !== 'function') {
64
+ logging_1.debugLog.warn('GoogleAnalytics', 'Event tracking failed - gtag function not available', {
65
+ eventName,
66
+ hasGtag: typeof window.gtag,
67
+ hasDataLayer: Array.isArray(window.dataLayer),
68
+ });
69
+ return;
70
+ }
71
+ try {
72
+ window.gtag('event', eventName, metadata);
73
+ }
74
+ catch (error) {
75
+ logging_1.debugLog.error('GoogleAnalytics', 'Event tracking failed', {
76
+ eventName,
77
+ error: error instanceof Error ? error.message : 'Unknown error',
78
+ metadataKeys: Object.keys(metadata || {}),
79
+ });
80
+ }
81
+ }
82
+ cleanup() {
83
+ this.isInitialized = false;
84
+ const script = document.getElementById('tracelog-ga-script');
85
+ if (script) {
86
+ script.remove();
87
+ }
88
+ logging_1.debugLog.info('GoogleAnalytics', 'Google Analytics integration cleanup completed');
89
+ }
90
+ isScriptAlreadyLoaded() {
91
+ const tracelogScript = document.getElementById('tracelog-ga-script');
92
+ if (tracelogScript) {
93
+ return true;
94
+ }
95
+ const existingGAScript = document.querySelector('script[src*="googletagmanager.com/gtag/js"]');
96
+ if (existingGAScript) {
97
+ logging_1.debugLog.clientWarn('GoogleAnalytics', 'Google Analytics script already loaded from external source', {
98
+ scriptSrc: existingGAScript.getAttribute('src'),
99
+ hasGtag: typeof window.gtag === 'function',
100
+ });
101
+ return true;
102
+ }
103
+ return false;
104
+ }
105
+ async loadScript(measurementId) {
106
+ return new Promise((resolve, reject) => {
107
+ try {
108
+ const script = document.createElement('script');
109
+ script.id = 'tracelog-ga-script';
110
+ script.async = true;
111
+ script.src = `https://www.googletagmanager.com/gtag/js?id=${measurementId}`;
112
+ script.onload = () => {
113
+ resolve();
114
+ };
115
+ script.onerror = () => {
116
+ const error = new Error('Failed to load Google Analytics script');
117
+ logging_1.debugLog.error('GoogleAnalytics', 'Google Analytics script load failed', {
118
+ measurementId,
119
+ error: error.message,
120
+ scriptSrc: script.src,
121
+ });
122
+ reject(error);
123
+ };
124
+ document.head.appendChild(script);
125
+ }
126
+ catch (error) {
127
+ const errorMsg = error instanceof Error ? error : new Error(String(error));
128
+ logging_1.debugLog.error('GoogleAnalytics', 'Error creating Google Analytics script', {
129
+ measurementId,
130
+ error: errorMsg.message,
131
+ });
132
+ reject(errorMsg);
133
+ }
134
+ });
135
+ }
136
+ configureGtag(measurementId, userId) {
137
+ try {
138
+ const gaScriptConfig = document.createElement('script');
139
+ gaScriptConfig.innerHTML = `
140
+ window.dataLayer = window.dataLayer || [];
141
+ function gtag(){dataLayer.push(arguments);}
142
+ gtag('js', new Date());
143
+ gtag('config', '${measurementId}', {
144
+ 'user_id': '${userId}'
145
+ });
146
+ `;
147
+ document.head.appendChild(gaScriptConfig);
148
+ }
149
+ catch (error) {
150
+ logging_1.debugLog.error('GoogleAnalytics', 'Failed to configure Google Analytics', {
151
+ measurementId,
152
+ userId,
153
+ error: error instanceof Error ? error.message : 'Unknown error',
154
+ });
155
+ throw error;
156
+ }
157
+ }
158
+ }
159
+ exports.GoogleAnalyticsIntegration = GoogleAnalyticsIntegration;
@@ -0,0 +1,8 @@
1
+ import { EventListenerManager } from './listeners.types';
2
+ export declare class ActivityListenerManager implements EventListenerManager {
3
+ private readonly onActivity;
4
+ private readonly options;
5
+ constructor(onActivity: () => void);
6
+ setup(): void;
7
+ cleanup(): void;
8
+ }
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActivityListenerManager = void 0;
4
+ const logging_1 = require("../utils/logging");
5
+ class ActivityListenerManager {
6
+ constructor(onActivity) {
7
+ this.options = { passive: true };
8
+ this.onActivity = onActivity;
9
+ }
10
+ setup() {
11
+ try {
12
+ window.addEventListener('scroll', this.onActivity, this.options);
13
+ window.addEventListener('resize', this.onActivity, this.options);
14
+ window.addEventListener('focus', this.onActivity, this.options);
15
+ }
16
+ catch (error) {
17
+ logging_1.debugLog.error('ActivityListenerManager', 'Failed to setup activity listeners', { error });
18
+ throw error;
19
+ }
20
+ }
21
+ cleanup() {
22
+ try {
23
+ window.removeEventListener('scroll', this.onActivity);
24
+ window.removeEventListener('resize', this.onActivity);
25
+ window.removeEventListener('focus', this.onActivity);
26
+ }
27
+ catch (error) {
28
+ logging_1.debugLog.warn('ActivityListenerManager', 'Error during activity listeners cleanup', { error });
29
+ }
30
+ }
31
+ }
32
+ exports.ActivityListenerManager = ActivityListenerManager;
@@ -0,0 +1,6 @@
1
+ export { ActivityListenerManager } from './activity-listener-manager';
2
+ export { TouchListenerManager } from './touch-listener-manager';
3
+ export { MouseListenerManager, KeyboardListenerManager } from './input-listener-managers';
4
+ export { VisibilityListenerManager } from './visibility-listener-manager';
5
+ export { UnloadListenerManager } from './unload-listener-manager';
6
+ export type { EventListenerManager } from './listeners.types';
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnloadListenerManager = exports.VisibilityListenerManager = exports.KeyboardListenerManager = exports.MouseListenerManager = exports.TouchListenerManager = exports.ActivityListenerManager = void 0;
4
+ var activity_listener_manager_1 = require("./activity-listener-manager");
5
+ Object.defineProperty(exports, "ActivityListenerManager", { enumerable: true, get: function () { return activity_listener_manager_1.ActivityListenerManager; } });
6
+ var touch_listener_manager_1 = require("./touch-listener-manager");
7
+ Object.defineProperty(exports, "TouchListenerManager", { enumerable: true, get: function () { return touch_listener_manager_1.TouchListenerManager; } });
8
+ var input_listener_managers_1 = require("./input-listener-managers");
9
+ Object.defineProperty(exports, "MouseListenerManager", { enumerable: true, get: function () { return input_listener_managers_1.MouseListenerManager; } });
10
+ Object.defineProperty(exports, "KeyboardListenerManager", { enumerable: true, get: function () { return input_listener_managers_1.KeyboardListenerManager; } });
11
+ var visibility_listener_manager_1 = require("./visibility-listener-manager");
12
+ Object.defineProperty(exports, "VisibilityListenerManager", { enumerable: true, get: function () { return visibility_listener_manager_1.VisibilityListenerManager; } });
13
+ var unload_listener_manager_1 = require("./unload-listener-manager");
14
+ Object.defineProperty(exports, "UnloadListenerManager", { enumerable: true, get: function () { return unload_listener_manager_1.UnloadListenerManager; } });
@@ -0,0 +1,15 @@
1
+ import { EventListenerManager } from './listeners.types';
2
+ export declare class MouseListenerManager implements EventListenerManager {
3
+ private readonly onActivity;
4
+ private readonly options;
5
+ constructor(onActivity: () => void);
6
+ setup(): void;
7
+ cleanup(): void;
8
+ }
9
+ export declare class KeyboardListenerManager implements EventListenerManager {
10
+ private readonly onActivity;
11
+ private readonly options;
12
+ constructor(onActivity: () => void);
13
+ setup(): void;
14
+ cleanup(): void;
15
+ }
@@ -0,0 +1,58 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KeyboardListenerManager = exports.MouseListenerManager = void 0;
4
+ const logging_1 = require("../utils/logging");
5
+ class MouseListenerManager {
6
+ constructor(onActivity) {
7
+ this.options = { passive: true };
8
+ this.onActivity = onActivity;
9
+ }
10
+ setup() {
11
+ try {
12
+ window.addEventListener('mousemove', this.onActivity, this.options);
13
+ window.addEventListener('mousedown', this.onActivity, this.options);
14
+ window.addEventListener('wheel', this.onActivity, this.options);
15
+ }
16
+ catch (error) {
17
+ logging_1.debugLog.error('MouseListenerManager', 'Failed to setup mouse listeners', { error });
18
+ throw error;
19
+ }
20
+ }
21
+ cleanup() {
22
+ try {
23
+ window.removeEventListener('mousemove', this.onActivity);
24
+ window.removeEventListener('mousedown', this.onActivity);
25
+ window.removeEventListener('wheel', this.onActivity);
26
+ }
27
+ catch (error) {
28
+ logging_1.debugLog.warn('MouseListenerManager', 'Error during mouse listeners cleanup', { error });
29
+ }
30
+ }
31
+ }
32
+ exports.MouseListenerManager = MouseListenerManager;
33
+ class KeyboardListenerManager {
34
+ constructor(onActivity) {
35
+ this.options = { passive: true };
36
+ this.onActivity = onActivity;
37
+ }
38
+ setup() {
39
+ try {
40
+ window.addEventListener('keydown', this.onActivity, this.options);
41
+ window.addEventListener('keypress', this.onActivity, this.options);
42
+ }
43
+ catch (error) {
44
+ logging_1.debugLog.error('KeyboardListenerManager', 'Failed to setup keyboard listeners', { error });
45
+ throw error;
46
+ }
47
+ }
48
+ cleanup() {
49
+ try {
50
+ window.removeEventListener('keydown', this.onActivity);
51
+ window.removeEventListener('keypress', this.onActivity);
52
+ }
53
+ catch (error) {
54
+ logging_1.debugLog.warn('KeyboardListenerManager', 'Error during keyboard listeners cleanup', { error });
55
+ }
56
+ }
57
+ }
58
+ exports.KeyboardListenerManager = KeyboardListenerManager;