@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,61 @@
1
+ import { EventData } from '../types';
2
+ import { StateManager } from './state.manager';
3
+ import { StorageManager } from './storage.manager';
4
+ import { GoogleAnalyticsIntegration } from '../integrations/google-analytics.integration';
5
+ export declare class EventManager extends StateManager {
6
+ private readonly googleAnalytics;
7
+ private readonly samplingManager;
8
+ private readonly tagsManager;
9
+ private readonly dataSender;
10
+ private readonly storageManager;
11
+ private eventsQueue;
12
+ private lastEvent;
13
+ private eventsQueueIntervalId;
14
+ private intervalActive;
15
+ private failureCount;
16
+ private readonly MAX_FAILURES;
17
+ private circuitOpen;
18
+ private circuitOpenTime;
19
+ private backoffDelay;
20
+ private circuitResetTimeoutId;
21
+ private readonly eventFingerprints;
22
+ private readonly PERSISTENCE_KEY;
23
+ constructor(storeManager: StorageManager, googleAnalytics?: GoogleAnalyticsIntegration | null);
24
+ track({ type, page_url, from_page_url, scroll_data, click_data, custom_event, web_vitals, session_end_reason, session_start_recovered, }: Partial<EventData>): void;
25
+ stop(): void;
26
+ private processAndSend;
27
+ private trackGoogleAnalyticsEvent;
28
+ private initEventsQueueInterval;
29
+ flushImmediately(): Promise<boolean>;
30
+ flushImmediatelySync(): boolean;
31
+ getQueueLength(): number;
32
+ private sendEventsQueue;
33
+ private buildEventsPayload;
34
+ private clearQueueInterval;
35
+ private getEventFingerprint;
36
+ private isDuplicatedEvent;
37
+ /**
38
+ * Cleans up old fingerprints to prevent memory leaks
39
+ */
40
+ private cleanupOldFingerprints;
41
+ /**
42
+ * Opens the circuit breaker with time-based recovery and event persistence
43
+ */
44
+ private openCircuitBreaker;
45
+ /**
46
+ * Resets the circuit breaker and attempts to restore persisted events
47
+ */
48
+ private resetCircuitBreaker;
49
+ /**
50
+ * Persists current events queue to localStorage for recovery
51
+ */
52
+ private persistEventsToStorage;
53
+ /**
54
+ * Restores events from localStorage if available and not expired
55
+ */
56
+ private restoreEventsFromStorage;
57
+ /**
58
+ * Clears persisted events from localStorage
59
+ */
60
+ private clearPersistedEvents;
61
+ }
@@ -0,0 +1,508 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.EventManager = void 0;
4
+ const constants_1 = require("../constants");
5
+ const types_1 = require("../types");
6
+ const utils_1 = require("../utils");
7
+ const logging_1 = require("../utils/logging");
8
+ const sender_manager_1 = require("./sender.manager");
9
+ const sampling_manager_1 = require("./sampling.manager");
10
+ const state_manager_1 = require("./state.manager");
11
+ const tags_manager_1 = require("./tags.manager");
12
+ class EventManager extends state_manager_1.StateManager {
13
+ constructor(storeManager, googleAnalytics = null) {
14
+ super();
15
+ this.eventsQueue = [];
16
+ this.lastEvent = null;
17
+ this.eventsQueueIntervalId = null;
18
+ this.intervalActive = false;
19
+ // Circuit breaker properties
20
+ this.failureCount = 0;
21
+ this.MAX_FAILURES = constants_1.CIRCUIT_BREAKER_CONSTANTS.MAX_FAILURES;
22
+ this.circuitOpen = false;
23
+ this.circuitOpenTime = 0;
24
+ this.backoffDelay = constants_1.CIRCUIT_BREAKER_CONSTANTS.INITIAL_BACKOFF_DELAY_MS;
25
+ this.circuitResetTimeoutId = null;
26
+ // Event deduplication properties
27
+ this.eventFingerprints = new Map();
28
+ // Persistence storage key
29
+ this.PERSISTENCE_KEY = 'tl:circuit_breaker_events';
30
+ this.storageManager = storeManager;
31
+ this.googleAnalytics = googleAnalytics;
32
+ this.samplingManager = new sampling_manager_1.SamplingManager();
33
+ this.tagsManager = new tags_manager_1.TagsManager();
34
+ this.dataSender = new sender_manager_1.SenderManager(storeManager);
35
+ // Restore any persisted events on initialization
36
+ this.restoreEventsFromStorage();
37
+ logging_1.debugLog.debug('EventManager', 'EventManager initialized', {
38
+ hasGoogleAnalytics: !!googleAnalytics,
39
+ restoredEventsCount: this.eventsQueue.length,
40
+ });
41
+ }
42
+ track({ type, page_url, from_page_url, scroll_data, click_data, custom_event, web_vitals, session_end_reason, session_start_recovered, }) {
43
+ logging_1.debugLog.info('EventManager', `📥 Event captured: ${type}`, {
44
+ type,
45
+ page_url,
46
+ hasCustomEvent: !!custom_event,
47
+ hasClickData: !!click_data,
48
+ hasScrollData: !!scroll_data,
49
+ hasWebVitals: !!web_vitals,
50
+ });
51
+ if (!this.samplingManager.shouldSampleEvent(type, web_vitals)) {
52
+ logging_1.debugLog.debug('EventManager', 'Event filtered by sampling', { type, samplingActive: true });
53
+ return;
54
+ }
55
+ const isDuplicatedEvent = this.isDuplicatedEvent({
56
+ type,
57
+ page_url,
58
+ scroll_data,
59
+ click_data,
60
+ custom_event,
61
+ web_vitals,
62
+ session_end_reason,
63
+ session_start_recovered,
64
+ });
65
+ if (isDuplicatedEvent) {
66
+ const now = Date.now();
67
+ if (this.eventsQueue && this.eventsQueue.length > 0) {
68
+ const lastEvent = this.eventsQueue.at(-1);
69
+ if (lastEvent) {
70
+ lastEvent.timestamp = now;
71
+ }
72
+ }
73
+ if (this.lastEvent) {
74
+ this.lastEvent.timestamp = now;
75
+ }
76
+ logging_1.debugLog.debug('EventManager', 'Duplicate event detected, timestamp updated', {
77
+ type,
78
+ queueLength: this.eventsQueue.length,
79
+ });
80
+ return;
81
+ }
82
+ const effectivePageUrl = page_url || this.get('pageUrl');
83
+ const isRouteExcluded = (0, utils_1.isUrlPathExcluded)(effectivePageUrl, this.get('config').excludedUrlPaths);
84
+ const hasStartSession = this.get('hasStartSession');
85
+ const isSessionEndEvent = type == types_1.EventType.SESSION_END;
86
+ if (isRouteExcluded && (!isSessionEndEvent || (isSessionEndEvent && !hasStartSession))) {
87
+ if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
88
+ logging_1.debugLog.debug('EventManager', `Event ${type} on excluded route: ${page_url}`);
89
+ }
90
+ return;
91
+ }
92
+ const isSessionStartEvent = type === types_1.EventType.SESSION_START;
93
+ if (isSessionStartEvent) {
94
+ this.set('hasStartSession', true);
95
+ }
96
+ const utmParams = isSessionStartEvent ? (0, utils_1.getUTMParameters)() : undefined;
97
+ const payload = {
98
+ type: type,
99
+ page_url: isRouteExcluded ? 'excluded' : effectivePageUrl,
100
+ timestamp: Date.now(),
101
+ ...(isSessionStartEvent && { referrer: document.referrer || 'Direct' }),
102
+ ...(from_page_url && !isRouteExcluded ? { from_page_url } : {}),
103
+ ...(scroll_data && { scroll_data }),
104
+ ...(click_data && { click_data }),
105
+ ...(custom_event && { custom_event }),
106
+ ...(utmParams && { utm: utmParams }),
107
+ ...(web_vitals && { web_vitals }),
108
+ ...(session_end_reason && { session_end_reason }),
109
+ ...(session_start_recovered && { session_start_recovered }),
110
+ };
111
+ if (this.get('config')?.tags?.length) {
112
+ const matchedTags = this.tagsManager.getEventTagsIds(payload, this.get('device'));
113
+ if (matchedTags?.length) {
114
+ payload.tags =
115
+ this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug'
116
+ ? matchedTags.map((id) => ({
117
+ id,
118
+ key: this.get('config')?.tags?.find((t) => t.id === id)?.key ?? '',
119
+ }))
120
+ : matchedTags;
121
+ }
122
+ }
123
+ this.lastEvent = payload;
124
+ this.processAndSend(payload);
125
+ }
126
+ stop() {
127
+ // Clear interval and reset interval state
128
+ if (this.eventsQueueIntervalId) {
129
+ clearInterval(this.eventsQueueIntervalId);
130
+ this.eventsQueueIntervalId = null;
131
+ this.intervalActive = false;
132
+ }
133
+ // Clean up circuit breaker timeout
134
+ if (this.circuitResetTimeoutId) {
135
+ clearTimeout(this.circuitResetTimeoutId);
136
+ this.circuitResetTimeoutId = null;
137
+ }
138
+ // Persist any remaining events before stopping
139
+ if (this.eventsQueue.length > 0) {
140
+ this.persistEventsToStorage();
141
+ }
142
+ // Clean up all state variables
143
+ this.eventFingerprints.clear();
144
+ this.circuitOpen = false;
145
+ this.circuitOpenTime = 0;
146
+ this.failureCount = 0;
147
+ this.backoffDelay = constants_1.CIRCUIT_BREAKER_CONSTANTS.INITIAL_BACKOFF_DELAY_MS;
148
+ this.lastEvent = null;
149
+ // Stop the data sender to clean up retry timeouts
150
+ this.dataSender.stop();
151
+ }
152
+ processAndSend(payload) {
153
+ logging_1.debugLog.info('EventManager', `🔄 Event processed and queued: ${payload.type}`, {
154
+ type: payload.type,
155
+ timestamp: payload.timestamp,
156
+ page_url: payload.page_url,
157
+ queueLengthBefore: this.eventsQueue.length,
158
+ });
159
+ if (this.get('config').ipExcluded) {
160
+ logging_1.debugLog.info('EventManager', `❌ Event blocked: IP excluded`);
161
+ return;
162
+ }
163
+ this.eventsQueue.push(payload);
164
+ if (this.eventsQueue.length > constants_1.MAX_EVENTS_QUEUE_LENGTH) {
165
+ const removedEvent = this.eventsQueue.shift();
166
+ logging_1.debugLog.warn('EventManager', 'Event queue overflow, oldest event removed', {
167
+ maxLength: constants_1.MAX_EVENTS_QUEUE_LENGTH,
168
+ currentLength: this.eventsQueue.length,
169
+ removedEventType: removedEvent?.type,
170
+ });
171
+ }
172
+ if (!this.eventsQueueIntervalId) {
173
+ this.initEventsQueueInterval();
174
+ logging_1.debugLog.info('EventManager', `⏰ Event sender initialized - queue will be sent periodically`, {
175
+ queueLength: this.eventsQueue.length,
176
+ });
177
+ }
178
+ if (this.googleAnalytics && payload.type === types_1.EventType.CUSTOM) {
179
+ const customEvent = payload.custom_event;
180
+ this.trackGoogleAnalyticsEvent(customEvent);
181
+ }
182
+ }
183
+ trackGoogleAnalyticsEvent(customEvent) {
184
+ if (this.get('config').mode === 'qa' || this.get('config').mode === 'debug') {
185
+ logging_1.debugLog.debug('EventManager', `Google Analytics event: ${JSON.stringify(customEvent)}`);
186
+ }
187
+ else if (this.googleAnalytics) {
188
+ this.googleAnalytics.trackEvent(customEvent.name, customEvent.metadata ?? {});
189
+ }
190
+ }
191
+ initEventsQueueInterval() {
192
+ if (this.eventsQueueIntervalId || this.intervalActive) {
193
+ return;
194
+ }
195
+ const interval = this.get('config')?.id === 'test' ? constants_1.EVENT_SENT_INTERVAL_TEST_MS : constants_1.EVENT_SENT_INTERVAL_MS;
196
+ this.eventsQueueIntervalId = window.setInterval(() => {
197
+ if (this.eventsQueue.length > 0) {
198
+ this.sendEventsQueue();
199
+ }
200
+ }, interval);
201
+ this.intervalActive = true;
202
+ }
203
+ async flushImmediately() {
204
+ if (this.eventsQueue.length === 0) {
205
+ return true;
206
+ }
207
+ const body = this.buildEventsPayload();
208
+ const success = await this.dataSender.sendEventsQueueAsync(body);
209
+ if (success) {
210
+ this.eventsQueue = [];
211
+ this.clearQueueInterval();
212
+ }
213
+ return success;
214
+ }
215
+ flushImmediatelySync() {
216
+ if (this.eventsQueue.length === 0) {
217
+ return true;
218
+ }
219
+ const body = this.buildEventsPayload();
220
+ const success = this.dataSender.sendEventsQueueSync(body);
221
+ if (success) {
222
+ this.eventsQueue = [];
223
+ this.clearQueueInterval();
224
+ }
225
+ return success;
226
+ }
227
+ getQueueLength() {
228
+ return this.eventsQueue.length;
229
+ }
230
+ sendEventsQueue() {
231
+ if (this.eventsQueue.length === 0) {
232
+ return;
233
+ }
234
+ logging_1.debugLog.info('EventManager', `📤 Preparing to send event queue`, {
235
+ queueLength: this.eventsQueue.length,
236
+ hasSessionId: !!this.get('sessionId'),
237
+ circuitOpen: this.circuitOpen,
238
+ });
239
+ // Circuit breaker: check if it should be reset or continue blocking
240
+ if (this.circuitOpen) {
241
+ const timeSinceOpen = Date.now() - this.circuitOpenTime;
242
+ if (timeSinceOpen >= constants_1.CIRCUIT_BREAKER_CONSTANTS.RECOVERY_TIME_MS) {
243
+ this.resetCircuitBreaker();
244
+ logging_1.debugLog.info('EventManager', 'Circuit breaker reset after timeout', {
245
+ timeSinceOpen,
246
+ recoveryTime: constants_1.CIRCUIT_BREAKER_CONSTANTS.RECOVERY_TIME_MS,
247
+ });
248
+ }
249
+ else {
250
+ logging_1.debugLog.debug('EventManager', 'Circuit breaker is open - skipping event sending', {
251
+ queueLength: this.eventsQueue.length,
252
+ failureCount: this.failureCount,
253
+ timeSinceOpen,
254
+ recoveryTime: constants_1.CIRCUIT_BREAKER_CONSTANTS.RECOVERY_TIME_MS,
255
+ });
256
+ return;
257
+ }
258
+ }
259
+ if (!this.get('sessionId')) {
260
+ logging_1.debugLog.info('EventManager', `⏳ Queue waiting: ${this.eventsQueue.length} events waiting for active session`);
261
+ return;
262
+ }
263
+ const body = this.buildEventsPayload();
264
+ const success = this.dataSender.sendEventsQueue(body);
265
+ if (success) {
266
+ logging_1.debugLog.info('EventManager', `✅ Event queue sent successfully`, {
267
+ eventsCount: body.events.length,
268
+ sessionId: body.session_id,
269
+ uniqueEventsAfterDedup: body.events.length,
270
+ });
271
+ this.eventsQueue = [];
272
+ this.failureCount = 0;
273
+ this.backoffDelay = constants_1.CIRCUIT_BREAKER_CONSTANTS.INITIAL_BACKOFF_DELAY_MS;
274
+ // Clear any persisted events on successful send
275
+ this.clearPersistedEvents();
276
+ }
277
+ else {
278
+ logging_1.debugLog.info('EventManager', `❌ Failed to send event queue`, {
279
+ eventsCount: body.events.length,
280
+ failureCount: this.failureCount + 1,
281
+ willOpenCircuit: this.failureCount + 1 >= this.MAX_FAILURES,
282
+ });
283
+ // Persist failed events for recovery instead of restoring queue to prevent duplicates
284
+ this.persistEventsToStorage();
285
+ this.eventsQueue = [];
286
+ this.failureCount++;
287
+ if (this.failureCount >= this.MAX_FAILURES) {
288
+ this.openCircuitBreaker();
289
+ }
290
+ }
291
+ }
292
+ buildEventsPayload() {
293
+ const uniqueEvents = new Map();
294
+ for (const event of this.eventsQueue) {
295
+ let key = `${event.type}_${event.page_url}`;
296
+ if (event.click_data) {
297
+ key += `_${event.click_data.x}_${event.click_data.y}`;
298
+ }
299
+ if (event.scroll_data) {
300
+ key += `_${event.scroll_data.depth}_${event.scroll_data.direction}`;
301
+ }
302
+ if (event.custom_event) {
303
+ key += `_${event.custom_event.name}`;
304
+ }
305
+ if (event.web_vitals) {
306
+ key += `_${event.web_vitals.type}`;
307
+ }
308
+ if (!uniqueEvents.has(key)) {
309
+ uniqueEvents.set(key, event);
310
+ }
311
+ }
312
+ const deduplicatedEvents = [...uniqueEvents.values()];
313
+ deduplicatedEvents.sort((a, b) => a.timestamp - b.timestamp);
314
+ return {
315
+ user_id: this.get('userId'),
316
+ session_id: this.get('sessionId'),
317
+ device: this.get('device'),
318
+ events: deduplicatedEvents,
319
+ ...(this.get('config')?.globalMetadata && { global_metadata: this.get('config')?.globalMetadata }),
320
+ };
321
+ }
322
+ clearQueueInterval() {
323
+ if (this.eventsQueueIntervalId) {
324
+ clearInterval(this.eventsQueueIntervalId);
325
+ this.eventsQueueIntervalId = null;
326
+ this.intervalActive = false;
327
+ }
328
+ }
329
+ getEventFingerprint(event) {
330
+ const key = `${event.type}_${event.page_url}`;
331
+ if (event.click_data) {
332
+ // Round coordinates to reduce false positives
333
+ const x = Math.round((event.click_data.x || 0) / constants_1.CLICK_COORDINATE_PRECISION) * constants_1.CLICK_COORDINATE_PRECISION;
334
+ const y = Math.round((event.click_data.y || 0) / constants_1.CLICK_COORDINATE_PRECISION) * constants_1.CLICK_COORDINATE_PRECISION;
335
+ return `${key}_${x}_${y}_${event.click_data.tag}_${event.click_data.id}`;
336
+ }
337
+ if (event.scroll_data) {
338
+ return `${key}_${event.scroll_data.depth}_${event.scroll_data.direction}`;
339
+ }
340
+ if (event.custom_event) {
341
+ return `${key}_${event.custom_event.name}`;
342
+ }
343
+ if (event.web_vitals) {
344
+ return `${key}_${event.web_vitals.type}`;
345
+ }
346
+ if (event.session_end_reason) {
347
+ return `${key}_${event.session_end_reason}`;
348
+ }
349
+ if (event.session_start_recovered !== undefined) {
350
+ return `${key}_${event.session_start_recovered}`;
351
+ }
352
+ return key;
353
+ }
354
+ isDuplicatedEvent(event) {
355
+ const fingerprint = this.getEventFingerprint(event);
356
+ const lastTime = this.eventFingerprints.get(fingerprint) ?? 0;
357
+ const now = Date.now();
358
+ if (now - lastTime < constants_1.DUPLICATE_EVENT_THRESHOLD_MS) {
359
+ return true;
360
+ }
361
+ this.eventFingerprints.set(fingerprint, now);
362
+ // Clean up old fingerprints to prevent memory leaks
363
+ this.cleanupOldFingerprints();
364
+ return false;
365
+ }
366
+ /**
367
+ * Cleans up old fingerprints to prevent memory leaks
368
+ */
369
+ cleanupOldFingerprints() {
370
+ if (this.eventFingerprints.size <= constants_1.MAX_FINGERPRINTS) {
371
+ return;
372
+ }
373
+ const now = Date.now();
374
+ const cleanupThreshold = constants_1.DUPLICATE_EVENT_THRESHOLD_MS * constants_1.FINGERPRINT_CLEANUP_MULTIPLIER;
375
+ const keysToDelete = [];
376
+ for (const [key, timestamp] of this.eventFingerprints) {
377
+ if (now - timestamp > cleanupThreshold) {
378
+ keysToDelete.push(key);
379
+ }
380
+ }
381
+ // Delete old entries
382
+ for (const key of keysToDelete) {
383
+ this.eventFingerprints.delete(key);
384
+ }
385
+ logging_1.debugLog.debug('EventManager', 'Cleaned up old event fingerprints', {
386
+ totalFingerprints: this.eventFingerprints.size + keysToDelete.length,
387
+ cleanedCount: keysToDelete.length,
388
+ remainingCount: this.eventFingerprints.size,
389
+ cleanupThreshold,
390
+ });
391
+ }
392
+ /**
393
+ * Opens the circuit breaker with time-based recovery and event persistence
394
+ */
395
+ openCircuitBreaker() {
396
+ this.circuitOpen = true;
397
+ this.circuitOpenTime = Date.now();
398
+ // Persist events before clearing queue to prevent data loss
399
+ this.persistEventsToStorage();
400
+ const eventsCount = this.eventsQueue.length;
401
+ this.eventsQueue = []; // Clear memory queue
402
+ logging_1.debugLog.warn('EventManager', 'Circuit breaker opened with time-based recovery', {
403
+ maxFailures: this.MAX_FAILURES,
404
+ persistedEvents: eventsCount,
405
+ failureCount: this.failureCount,
406
+ recoveryTime: constants_1.CIRCUIT_BREAKER_CONSTANTS.RECOVERY_TIME_MS,
407
+ openTime: this.circuitOpenTime,
408
+ });
409
+ // Increase backoff for next failure
410
+ this.backoffDelay = Math.min(this.backoffDelay * constants_1.CIRCUIT_BREAKER_CONSTANTS.BACKOFF_MULTIPLIER, constants_1.CIRCUIT_BREAKER_CONSTANTS.MAX_BACKOFF_DELAY_MS);
411
+ }
412
+ /**
413
+ * Resets the circuit breaker and attempts to restore persisted events
414
+ */
415
+ resetCircuitBreaker() {
416
+ this.circuitOpen = false;
417
+ this.circuitOpenTime = 0;
418
+ this.failureCount = 0;
419
+ this.circuitResetTimeoutId = null;
420
+ logging_1.debugLog.info('EventManager', 'Circuit breaker reset - attempting to restore events', {
421
+ currentQueueLength: this.eventsQueue.length,
422
+ });
423
+ // Restore persisted events
424
+ this.restoreEventsFromStorage();
425
+ logging_1.debugLog.info('EventManager', 'Circuit breaker reset completed', {
426
+ restoredQueueLength: this.eventsQueue.length,
427
+ backoffDelay: this.backoffDelay,
428
+ });
429
+ }
430
+ /**
431
+ * Persists current events queue to localStorage for recovery
432
+ */
433
+ persistEventsToStorage() {
434
+ try {
435
+ if (this.eventsQueue.length === 0) {
436
+ return;
437
+ }
438
+ const persistData = {
439
+ events: this.eventsQueue,
440
+ timestamp: Date.now(),
441
+ failureCount: this.failureCount,
442
+ };
443
+ this.storageManager.setItem(this.PERSISTENCE_KEY, JSON.stringify(persistData));
444
+ logging_1.debugLog.debug('EventManager', 'Events persisted to storage for recovery', {
445
+ eventsCount: this.eventsQueue.length,
446
+ failureCount: this.failureCount,
447
+ });
448
+ }
449
+ catch (error) {
450
+ logging_1.debugLog.warn('EventManager', 'Failed to persist events to storage', {
451
+ error: error instanceof Error ? error.message : 'Unknown error',
452
+ eventsCount: this.eventsQueue.length,
453
+ });
454
+ }
455
+ }
456
+ /**
457
+ * Restores events from localStorage if available and not expired
458
+ */
459
+ restoreEventsFromStorage() {
460
+ try {
461
+ const persistedData = this.storageManager.getItem(this.PERSISTENCE_KEY);
462
+ if (!persistedData) {
463
+ return;
464
+ }
465
+ const parsed = JSON.parse(persistedData);
466
+ const now = Date.now();
467
+ const maxAge = constants_1.EVENT_PERSISTENCE_MAX_AGE_MS;
468
+ // Check if persisted data is not too old
469
+ if (now - parsed.timestamp > maxAge) {
470
+ this.clearPersistedEvents();
471
+ logging_1.debugLog.debug('EventManager', 'Cleared expired persisted events', {
472
+ age: now - parsed.timestamp,
473
+ maxAge,
474
+ });
475
+ return;
476
+ }
477
+ // Restore events if we don't already have events in queue
478
+ if (Array.isArray(parsed.events) && parsed.events.length > 0 && this.eventsQueue.length === 0) {
479
+ this.eventsQueue = parsed.events;
480
+ logging_1.debugLog.info('EventManager', 'Restored events from storage', {
481
+ restoredCount: parsed.events.length,
482
+ originalFailureCount: parsed.failureCount ?? 0,
483
+ });
484
+ }
485
+ }
486
+ catch (error) {
487
+ logging_1.debugLog.warn('EventManager', 'Failed to restore events from storage', {
488
+ error: error instanceof Error ? error.message : 'Unknown error',
489
+ });
490
+ this.clearPersistedEvents();
491
+ }
492
+ }
493
+ /**
494
+ * Clears persisted events from localStorage
495
+ */
496
+ clearPersistedEvents() {
497
+ try {
498
+ this.storageManager.removeItem(this.PERSISTENCE_KEY);
499
+ logging_1.debugLog.debug('EventManager', 'Cleared persisted events from storage');
500
+ }
501
+ catch (error) {
502
+ logging_1.debugLog.warn('EventManager', 'Failed to clear persisted events', {
503
+ error: error instanceof Error ? error.message : 'Unknown error',
504
+ });
505
+ }
506
+ }
507
+ }
508
+ exports.EventManager = EventManager;
@@ -0,0 +1,8 @@
1
+ import { EventType, WebVitalsData } from '../types';
2
+ import { StateManager } from './state.manager';
3
+ export declare class SamplingManager extends StateManager {
4
+ shouldSampleEvent(type: EventType, webVitals?: WebVitalsData): boolean;
5
+ private isSampledIn;
6
+ private isWebVitalEventSampledIn;
7
+ private getHash;
8
+ }
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SamplingManager = void 0;
4
+ const constants_1 = require("../constants");
5
+ const types_1 = require("../types");
6
+ const state_manager_1 = require("./state.manager");
7
+ class SamplingManager extends state_manager_1.StateManager {
8
+ shouldSampleEvent(type, webVitals) {
9
+ const isQaMode = this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug';
10
+ if (isQaMode) {
11
+ return true;
12
+ }
13
+ if (type === types_1.EventType.WEB_VITALS) {
14
+ return this.isWebVitalEventSampledIn(webVitals?.type);
15
+ }
16
+ return this.isSampledIn();
17
+ }
18
+ isSampledIn() {
19
+ const samplingRate = this.get('config').samplingRate ?? constants_1.DEFAULT_SAMPLING_RATE;
20
+ if (samplingRate >= 1.0) {
21
+ return true;
22
+ }
23
+ if (samplingRate <= 0) {
24
+ return false;
25
+ }
26
+ const userHash = this.getHash(this.get('userId'));
27
+ const userValue = (userHash % 100) / 100;
28
+ const isSampled = userValue < samplingRate;
29
+ return isSampled;
30
+ }
31
+ isWebVitalEventSampledIn(type) {
32
+ const isLongTask = type === 'LONG_TASK';
33
+ const rate = isLongTask ? constants_1.WEB_VITALS_LONG_TASK_SAMPLING : constants_1.WEB_VITALS_SAMPLING;
34
+ if (rate >= 1)
35
+ return true;
36
+ if (rate <= 0)
37
+ return false;
38
+ const seed = `${this.get('userId')}|${isLongTask ? 'long_task' : 'web_vitals'}`;
39
+ const hash = this.getHash(seed);
40
+ const value = (hash % 100) / 100;
41
+ return value < rate;
42
+ }
43
+ getHash(input) {
44
+ let hash = 0;
45
+ for (let i = 0; i < input.length; i++) {
46
+ const char = input.charCodeAt(i);
47
+ hash = (hash << 5) - hash + char;
48
+ hash |= 0;
49
+ }
50
+ return Math.abs(hash);
51
+ }
52
+ }
53
+ exports.SamplingManager = SamplingManager;
@@ -0,0 +1,46 @@
1
+ import { BaseEventsQueueDto } from '../types';
2
+ import { StorageManager } from './storage.manager';
3
+ import { StateManager } from './state.manager';
4
+ export declare class SenderManager extends StateManager {
5
+ private readonly storeManager;
6
+ private readonly queueStorageKey;
7
+ private retryDelay;
8
+ private retryTimeoutId;
9
+ private lastAsyncSend;
10
+ private lastSyncSend;
11
+ constructor(storeManager: StorageManager);
12
+ sendEventsQueueAsync(body: BaseEventsQueueDto): Promise<boolean>;
13
+ sendEventsQueueSync(body: BaseEventsQueueDto): boolean;
14
+ sendEventsQueue(body: BaseEventsQueueDto): boolean;
15
+ recoverPersistedEvents(): void;
16
+ stop(): void;
17
+ /**
18
+ * Sends recovered events without re-deduplication since they were already processed
19
+ */
20
+ private sendRecoveredEvents;
21
+ /**
22
+ * Schedules retry for recovered events using the specific recovery method
23
+ */
24
+ private scheduleRetryForRecoveredEvents;
25
+ private canSendAsync;
26
+ private canSendSync;
27
+ private sendQueueAsync;
28
+ private sendQueueSync;
29
+ private sendQueue;
30
+ private sendSyncXHR;
31
+ private prepareRequest;
32
+ private getPersistedData;
33
+ private isDataRecent;
34
+ private createRecoveryBody;
35
+ private logQueue;
36
+ private handleSendFailure;
37
+ private persistFailedEvents;
38
+ private clearPersistedEvents;
39
+ private resetRetryState;
40
+ private scheduleRetry;
41
+ private executeSend;
42
+ private executeSendSync;
43
+ private shouldSkipSend;
44
+ private isSendBeaconAvailable;
45
+ private clearRetryTimeout;
46
+ }