@tracelog/lib 0.5.5 → 0.6.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 (202) hide show
  1. package/README.md +157 -180
  2. package/dist/browser/tracelog.esm.js +1124 -1377
  3. package/dist/browser/tracelog.esm.js.map +1 -0
  4. package/dist/browser/tracelog.js +2 -2
  5. package/dist/browser/tracelog.js.map +1 -0
  6. package/dist/cjs/api.d.ts +12 -2
  7. package/dist/cjs/api.js +74 -29
  8. package/dist/cjs/app.d.ts +2 -2
  9. package/dist/cjs/app.js +26 -32
  10. package/dist/cjs/constants/config.constants.d.ts +7 -2
  11. package/dist/cjs/constants/config.constants.js +9 -18
  12. package/dist/cjs/constants/index.d.ts +0 -1
  13. package/dist/cjs/constants/index.js +0 -1
  14. package/dist/cjs/constants/storage.constants.d.ts +3 -2
  15. package/dist/cjs/constants/storage.constants.js +4 -4
  16. package/dist/cjs/handlers/click.handler.js +3 -6
  17. package/dist/cjs/handlers/error.handler.js +1 -11
  18. package/dist/cjs/handlers/page-view.handler.js +0 -4
  19. package/dist/cjs/handlers/performance.handler.js +14 -29
  20. package/dist/cjs/handlers/scroll.handler.js +7 -6
  21. package/dist/cjs/handlers/session.handler.js +7 -6
  22. package/dist/cjs/integrations/google-analytics.integration.js +2 -6
  23. package/dist/cjs/listeners/activity-listener-manager.js +3 -3
  24. package/dist/cjs/listeners/input-listener-managers.js +3 -3
  25. package/dist/cjs/listeners/touch-listener-manager.js +3 -3
  26. package/dist/cjs/listeners/unload-listener-manager.js +3 -3
  27. package/dist/cjs/listeners/visibility-listener-manager.js +3 -3
  28. package/dist/cjs/managers/event.manager.d.ts +5 -1
  29. package/dist/cjs/managers/event.manager.js +103 -40
  30. package/dist/cjs/managers/sender.manager.js +29 -36
  31. package/dist/cjs/managers/session.manager.js +5 -13
  32. package/dist/cjs/managers/state.manager.d.ts +0 -3
  33. package/dist/cjs/managers/state.manager.js +1 -43
  34. package/dist/cjs/managers/storage.manager.d.ts +21 -2
  35. package/dist/cjs/managers/storage.manager.js +164 -21
  36. package/dist/cjs/managers/user.manager.d.ts +1 -1
  37. package/dist/cjs/managers/user.manager.js +2 -2
  38. package/dist/cjs/public-api.d.ts +3 -3
  39. package/dist/cjs/public-api.js +1 -1
  40. package/dist/cjs/test-bridge.d.ts +1 -0
  41. package/dist/cjs/test-bridge.js +37 -2
  42. package/dist/cjs/types/config.types.d.ts +17 -20
  43. package/dist/cjs/types/config.types.js +6 -0
  44. package/dist/cjs/types/event.types.d.ts +1 -13
  45. package/dist/cjs/types/index.d.ts +0 -2
  46. package/dist/cjs/types/index.js +0 -2
  47. package/dist/cjs/types/mode.types.d.ts +1 -2
  48. package/dist/cjs/types/mode.types.js +0 -1
  49. package/dist/cjs/types/queue.types.d.ts +0 -6
  50. package/dist/cjs/types/state.types.d.ts +2 -0
  51. package/dist/cjs/types/test-bridge.types.d.ts +2 -2
  52. package/dist/cjs/types/validation-error.types.d.ts +0 -6
  53. package/dist/cjs/types/validation-error.types.js +1 -10
  54. package/dist/cjs/utils/browser/device-detector.utils.js +2 -24
  55. package/dist/cjs/utils/browser/index.d.ts +1 -0
  56. package/dist/cjs/utils/browser/index.js +1 -0
  57. package/dist/cjs/utils/browser/qa-mode.utils.d.ts +13 -0
  58. package/dist/cjs/utils/browser/qa-mode.utils.js +43 -0
  59. package/dist/cjs/utils/browser/utm-params.utils.js +0 -15
  60. package/dist/cjs/utils/data/uuid.utils.d.ts +13 -0
  61. package/dist/cjs/utils/data/uuid.utils.js +37 -1
  62. package/dist/cjs/utils/index.d.ts +1 -1
  63. package/dist/cjs/utils/index.js +1 -1
  64. package/dist/cjs/utils/logging.utils.d.ts +21 -0
  65. package/dist/cjs/utils/logging.utils.js +86 -0
  66. package/dist/cjs/utils/network/index.d.ts +0 -1
  67. package/dist/cjs/utils/network/index.js +0 -1
  68. package/dist/cjs/utils/network/url.utils.d.ts +2 -8
  69. package/dist/cjs/utils/network/url.utils.js +45 -90
  70. package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -13
  71. package/dist/cjs/utils/security/sanitize.utils.js +15 -178
  72. package/dist/cjs/utils/validations/config-validations.utils.d.ts +3 -9
  73. package/dist/cjs/utils/validations/config-validations.utils.js +56 -93
  74. package/dist/cjs/utils/validations/event-validations.utils.js +11 -5
  75. package/dist/cjs/utils/validations/index.d.ts +0 -1
  76. package/dist/cjs/utils/validations/index.js +0 -1
  77. package/dist/cjs/utils/validations/metadata-validations.utils.js +0 -1
  78. package/dist/cjs/utils/validations/type-guards.utils.d.ts +2 -2
  79. package/dist/cjs/utils/validations/type-guards.utils.js +50 -4
  80. package/dist/esm/api.d.ts +12 -2
  81. package/dist/esm/api.js +73 -29
  82. package/dist/esm/app.d.ts +2 -2
  83. package/dist/esm/app.js +28 -34
  84. package/dist/esm/constants/config.constants.d.ts +7 -2
  85. package/dist/esm/constants/config.constants.js +7 -16
  86. package/dist/esm/constants/index.d.ts +0 -1
  87. package/dist/esm/constants/index.js +0 -1
  88. package/dist/esm/constants/storage.constants.d.ts +3 -2
  89. package/dist/esm/constants/storage.constants.js +3 -2
  90. package/dist/esm/handlers/click.handler.js +3 -6
  91. package/dist/esm/handlers/error.handler.js +1 -11
  92. package/dist/esm/handlers/page-view.handler.js +0 -4
  93. package/dist/esm/handlers/performance.handler.js +14 -29
  94. package/dist/esm/handlers/scroll.handler.js +7 -6
  95. package/dist/esm/handlers/session.handler.js +7 -6
  96. package/dist/esm/integrations/google-analytics.integration.js +3 -7
  97. package/dist/esm/listeners/activity-listener-manager.js +3 -3
  98. package/dist/esm/listeners/input-listener-managers.js +3 -3
  99. package/dist/esm/listeners/touch-listener-manager.js +3 -3
  100. package/dist/esm/listeners/unload-listener-manager.js +3 -3
  101. package/dist/esm/listeners/visibility-listener-manager.js +3 -3
  102. package/dist/esm/managers/event.manager.d.ts +5 -1
  103. package/dist/esm/managers/event.manager.js +106 -43
  104. package/dist/esm/managers/sender.manager.js +31 -38
  105. package/dist/esm/managers/session.manager.js +5 -13
  106. package/dist/esm/managers/state.manager.d.ts +0 -3
  107. package/dist/esm/managers/state.manager.js +1 -43
  108. package/dist/esm/managers/storage.manager.d.ts +21 -2
  109. package/dist/esm/managers/storage.manager.js +164 -21
  110. package/dist/esm/managers/user.manager.d.ts +1 -1
  111. package/dist/esm/managers/user.manager.js +2 -2
  112. package/dist/esm/public-api.d.ts +3 -3
  113. package/dist/esm/public-api.js +1 -1
  114. package/dist/esm/test-bridge.d.ts +1 -0
  115. package/dist/esm/test-bridge.js +37 -2
  116. package/dist/esm/types/config.types.d.ts +17 -20
  117. package/dist/esm/types/config.types.js +5 -1
  118. package/dist/esm/types/event.types.d.ts +1 -13
  119. package/dist/esm/types/index.d.ts +0 -2
  120. package/dist/esm/types/index.js +0 -2
  121. package/dist/esm/types/mode.types.d.ts +1 -2
  122. package/dist/esm/types/mode.types.js +0 -1
  123. package/dist/esm/types/queue.types.d.ts +0 -6
  124. package/dist/esm/types/state.types.d.ts +2 -0
  125. package/dist/esm/types/test-bridge.types.d.ts +2 -2
  126. package/dist/esm/types/validation-error.types.d.ts +0 -6
  127. package/dist/esm/types/validation-error.types.js +0 -8
  128. package/dist/esm/utils/browser/device-detector.utils.js +2 -24
  129. package/dist/esm/utils/browser/index.d.ts +1 -0
  130. package/dist/esm/utils/browser/index.js +1 -0
  131. package/dist/esm/utils/browser/qa-mode.utils.d.ts +13 -0
  132. package/dist/esm/utils/browser/qa-mode.utils.js +39 -0
  133. package/dist/esm/utils/browser/utm-params.utils.js +0 -15
  134. package/dist/esm/utils/data/uuid.utils.d.ts +13 -0
  135. package/dist/esm/utils/data/uuid.utils.js +35 -0
  136. package/dist/esm/utils/index.d.ts +1 -1
  137. package/dist/esm/utils/index.js +1 -1
  138. package/dist/esm/utils/logging.utils.d.ts +21 -0
  139. package/dist/esm/utils/logging.utils.js +81 -0
  140. package/dist/esm/utils/network/index.d.ts +0 -1
  141. package/dist/esm/utils/network/index.js +0 -1
  142. package/dist/esm/utils/network/url.utils.d.ts +2 -8
  143. package/dist/esm/utils/network/url.utils.js +44 -88
  144. package/dist/esm/utils/security/sanitize.utils.d.ts +1 -13
  145. package/dist/esm/utils/security/sanitize.utils.js +15 -176
  146. package/dist/esm/utils/validations/config-validations.utils.d.ts +3 -9
  147. package/dist/esm/utils/validations/config-validations.utils.js +57 -93
  148. package/dist/esm/utils/validations/event-validations.utils.js +11 -5
  149. package/dist/esm/utils/validations/index.d.ts +0 -1
  150. package/dist/esm/utils/validations/index.js +0 -1
  151. package/dist/esm/utils/validations/metadata-validations.utils.js +0 -1
  152. package/dist/esm/utils/validations/type-guards.utils.d.ts +2 -2
  153. package/dist/esm/utils/validations/type-guards.utils.js +50 -4
  154. package/package.json +3 -2
  155. package/dist/cjs/app.types.d.ts +0 -2
  156. package/dist/cjs/app.types.js +0 -12
  157. package/dist/cjs/constants/api.constants.d.ts +0 -6
  158. package/dist/cjs/constants/api.constants.js +0 -14
  159. package/dist/cjs/managers/api.manager.d.ts +0 -13
  160. package/dist/cjs/managers/api.manager.js +0 -44
  161. package/dist/cjs/managers/config.builder.d.ts +0 -33
  162. package/dist/cjs/managers/config.builder.js +0 -116
  163. package/dist/cjs/managers/config.manager.d.ts +0 -56
  164. package/dist/cjs/managers/config.manager.js +0 -157
  165. package/dist/cjs/managers/tags.manager.d.ts +0 -36
  166. package/dist/cjs/managers/tags.manager.js +0 -171
  167. package/dist/cjs/types/api.types.d.ts +0 -52
  168. package/dist/cjs/types/api.types.js +0 -56
  169. package/dist/cjs/types/tag.types.d.ts +0 -43
  170. package/dist/cjs/types/tag.types.js +0 -31
  171. package/dist/cjs/utils/logging/debug-logger.utils.d.ts +0 -14
  172. package/dist/cjs/utils/logging/debug-logger.utils.js +0 -47
  173. package/dist/cjs/utils/logging/index.d.ts +0 -1
  174. package/dist/cjs/utils/logging/index.js +0 -5
  175. package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +0 -4
  176. package/dist/cjs/utils/network/fetch-with-timeout.utils.js +0 -25
  177. package/dist/cjs/utils/validations/url-validations.utils.d.ts +0 -15
  178. package/dist/cjs/utils/validations/url-validations.utils.js +0 -47
  179. package/dist/esm/app.types.d.ts +0 -2
  180. package/dist/esm/app.types.js +0 -1
  181. package/dist/esm/constants/api.constants.d.ts +0 -6
  182. package/dist/esm/constants/api.constants.js +0 -11
  183. package/dist/esm/managers/api.manager.d.ts +0 -13
  184. package/dist/esm/managers/api.manager.js +0 -41
  185. package/dist/esm/managers/config.builder.d.ts +0 -33
  186. package/dist/esm/managers/config.builder.js +0 -112
  187. package/dist/esm/managers/config.manager.d.ts +0 -56
  188. package/dist/esm/managers/config.manager.js +0 -153
  189. package/dist/esm/managers/tags.manager.d.ts +0 -36
  190. package/dist/esm/managers/tags.manager.js +0 -167
  191. package/dist/esm/types/api.types.d.ts +0 -52
  192. package/dist/esm/types/api.types.js +0 -53
  193. package/dist/esm/types/tag.types.d.ts +0 -43
  194. package/dist/esm/types/tag.types.js +0 -28
  195. package/dist/esm/utils/logging/debug-logger.utils.d.ts +0 -14
  196. package/dist/esm/utils/logging/debug-logger.utils.js +0 -44
  197. package/dist/esm/utils/logging/index.d.ts +0 -1
  198. package/dist/esm/utils/logging/index.js +0 -1
  199. package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +0 -4
  200. package/dist/esm/utils/network/fetch-with-timeout.utils.js +0 -22
  201. package/dist/esm/utils/validations/url-validations.utils.d.ts +0 -15
  202. package/dist/esm/utils/validations/url-validations.utils.js +0 -42
@@ -37,15 +37,14 @@ exports.PerformanceHandler = void 0;
37
37
  const state_manager_1 = require("../managers/state.manager");
38
38
  const types_1 = require("../types");
39
39
  const constants_1 = require("../constants");
40
- const performance_constants_1 = require("../constants/performance.constants");
41
- const logging_1 = require("../utils/logging");
40
+ const utils_1 = require("@/utils");
42
41
  class PerformanceHandler extends state_manager_1.StateManager {
43
42
  constructor(eventManager) {
44
43
  super();
45
44
  this.reportedByNav = new Map();
46
45
  this.observers = [];
47
46
  this.lastLongTaskSentAt = 0;
48
- this.vitalThresholds = performance_constants_1.WEB_VITALS_THRESHOLDS;
47
+ this.vitalThresholds = constants_1.WEB_VITALS_THRESHOLDS;
49
48
  this.eventManager = eventManager;
50
49
  }
51
50
  async startTracking() {
@@ -58,10 +57,7 @@ class PerformanceHandler extends state_manager_1.StateManager {
58
57
  obs.disconnect();
59
58
  }
60
59
  catch (error) {
61
- logging_1.debugLog.warn('PerformanceHandler', 'Failed to disconnect performance observer', {
62
- error: error instanceof Error ? error.message : 'Unknown error',
63
- observerIndex: index,
64
- });
60
+ (0, utils_1.log)('warn', 'Failed to disconnect performance observer', { error, data: { observerIndex: index } });
65
61
  }
66
62
  });
67
63
  this.observers.length = 0;
@@ -134,9 +130,7 @@ class PerformanceHandler extends state_manager_1.StateManager {
134
130
  onINP(report('INP'));
135
131
  }
136
132
  catch (error) {
137
- logging_1.debugLog.warn('PerformanceHandler', 'Failed to load web-vitals library, using fallback', {
138
- error: error instanceof Error ? error.message : 'Unknown error',
139
- });
133
+ (0, utils_1.log)('warn', 'Failed to load web-vitals library, using fallback', { error });
140
134
  this.observeWebVitalsFallback();
141
135
  }
142
136
  }
@@ -157,9 +151,7 @@ class PerformanceHandler extends state_manager_1.StateManager {
157
151
  }
158
152
  }
159
153
  catch (error) {
160
- logging_1.debugLog.warn('PerformanceHandler', 'Failed to report TTFB', {
161
- error: error instanceof Error ? error.message : 'Unknown error',
162
- });
154
+ (0, utils_1.log)('warn', 'Failed to report TTFB', { error });
163
155
  }
164
156
  }
165
157
  observeLongTasks() {
@@ -201,7 +193,7 @@ class PerformanceHandler extends state_manager_1.StateManager {
201
193
  }
202
194
  trackWebVital(type, value) {
203
195
  if (!Number.isFinite(value)) {
204
- logging_1.debugLog.warn('PerformanceHandler', 'Invalid web vital value', { type, value });
196
+ (0, utils_1.log)('warn', 'Invalid web vital value', { data: { type, value } });
205
197
  return;
206
198
  }
207
199
  this.eventManager.track({
@@ -224,9 +216,7 @@ class PerformanceHandler extends state_manager_1.StateManager {
224
216
  return `${timestamp.toFixed(2)}_${window.location.pathname}_${random}`;
225
217
  }
226
218
  catch (error) {
227
- logging_1.debugLog.warn('PerformanceHandler', 'Failed to get navigation ID', {
228
- error: error instanceof Error ? error.message : 'Unknown error',
229
- });
219
+ (0, utils_1.log)('warn', 'Failed to get navigation ID', { error });
230
220
  return null;
231
221
  }
232
222
  }
@@ -246,9 +236,9 @@ class PerformanceHandler extends state_manager_1.StateManager {
246
236
  cb(list, observer);
247
237
  }
248
238
  catch (callbackError) {
249
- logging_1.debugLog.warn('PerformanceHandler', 'Observer callback failed', {
250
- type,
251
- error: callbackError instanceof Error ? callbackError.message : 'Unknown error',
239
+ (0, utils_1.log)('warn', 'Observer callback failed', {
240
+ error: callbackError,
241
+ data: { type },
252
242
  });
253
243
  }
254
244
  if (once) {
@@ -267,25 +257,20 @@ class PerformanceHandler extends state_manager_1.StateManager {
267
257
  return true;
268
258
  }
269
259
  catch (error) {
270
- logging_1.debugLog.warn('PerformanceHandler', 'Failed to create performance observer', {
271
- type,
272
- error: error instanceof Error ? error.message : 'Unknown error',
260
+ (0, utils_1.log)('warn', 'Failed to create performance observer', {
261
+ error,
262
+ data: { type },
273
263
  });
274
264
  return false;
275
265
  }
276
266
  }
277
267
  shouldSendVital(type, value) {
278
268
  if (typeof value !== 'number' || !Number.isFinite(value)) {
279
- logging_1.debugLog.warn('PerformanceHandler', 'Invalid web vital value', { type, value });
269
+ (0, utils_1.log)('warn', 'Invalid web vital value', { data: { type, value } });
280
270
  return false;
281
271
  }
282
272
  const threshold = this.vitalThresholds[type];
283
273
  if (typeof threshold === 'number' && value <= threshold) {
284
- logging_1.debugLog.debug('PerformanceHandler', 'Web vital below threshold, skipping', {
285
- type,
286
- value,
287
- threshold,
288
- });
289
274
  return false;
290
275
  }
291
276
  return true;
@@ -4,7 +4,7 @@ exports.ScrollHandler = void 0;
4
4
  const constants_1 = require("../constants");
5
5
  const types_1 = require("../types");
6
6
  const state_manager_1 = require("../managers/state.manager");
7
- const logging_1 = require("../utils/logging");
7
+ const utils_1 = require("../utils");
8
8
  class ScrollHandler extends state_manager_1.StateManager {
9
9
  constructor(eventManager) {
10
10
  super();
@@ -144,8 +144,8 @@ class ScrollHandler extends state_manager_1.StateManager {
144
144
  return;
145
145
  }
146
146
  this.limitWarningLogged = true;
147
- logging_1.debugLog.warn('ScrollHandler', 'Max scroll events per session reached', {
148
- limit: this.maxEventsPerSession,
147
+ (0, utils_1.log)('warn', 'Max scroll events per session reached', {
148
+ data: { limit: this.maxEventsPerSession },
149
149
  });
150
150
  }
151
151
  applyConfigOverrides() {
@@ -214,9 +214,10 @@ class ScrollHandler extends state_manager_1.StateManager {
214
214
  return document.querySelector(selector);
215
215
  }
216
216
  catch (error) {
217
- logging_1.debugLog.clientWarn('ScrollHandler', 'Invalid CSS selector', {
218
- selector,
219
- error: error instanceof Error ? error.message : 'Unknown error',
217
+ (0, utils_1.log)('warn', 'Invalid CSS selector', {
218
+ error,
219
+ data: { selector },
220
+ showToClient: true,
220
221
  });
221
222
  return null;
222
223
  }
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SessionHandler = void 0;
4
4
  const session_manager_1 = require("../managers/session.manager");
5
5
  const state_manager_1 = require("../managers/state.manager");
6
- const logging_1 = require("../utils/logging");
6
+ const utils_1 = require("../utils");
7
7
  class SessionHandler extends state_manager_1.StateManager {
8
8
  constructor(storageManager, eventManager) {
9
9
  super();
@@ -17,16 +17,19 @@ class SessionHandler extends state_manager_1.StateManager {
17
17
  return;
18
18
  }
19
19
  if (this.destroyed) {
20
- logging_1.debugLog.warn('SessionHandler', 'Cannot start tracking on destroyed handler');
20
+ (0, utils_1.log)('warn', 'Cannot start tracking on destroyed handler');
21
21
  return;
22
22
  }
23
- const projectId = this.get('config')?.id;
23
+ const config = this.get('config');
24
+ const projectId = config?.integrations?.tracelog?.projectId ?? config?.integrations?.custom?.apiUrl ?? 'default';
24
25
  if (!projectId) {
25
26
  throw new Error('Cannot start session tracking: config not available');
26
27
  }
27
28
  try {
28
29
  this.sessionManager = new session_manager_1.SessionManager(this.storageManager, this.eventManager, projectId);
29
30
  await this.sessionManager.startTracking();
31
+ // Flush any events that were buffered during initialization
32
+ this.eventManager.flushPendingEvents();
30
33
  }
31
34
  catch (error) {
32
35
  if (this.sessionManager) {
@@ -38,9 +41,7 @@ class SessionHandler extends state_manager_1.StateManager {
38
41
  }
39
42
  this.sessionManager = null;
40
43
  }
41
- logging_1.debugLog.error('SessionHandler', 'Failed to start session tracking', {
42
- error: error instanceof Error ? error.message : 'Unknown error',
43
- });
44
+ (0, utils_1.log)('error', 'Failed to start session tracking', { error });
44
45
  throw error;
45
46
  }
46
47
  }
@@ -27,9 +27,7 @@ class GoogleAnalyticsIntegration extends state_manager_1.StateManager {
27
27
  this.isInitialized = true;
28
28
  }
29
29
  catch (error) {
30
- utils_1.debugLog.error('GoogleAnalyticsIntegration', 'Initialization failed', {
31
- error: error instanceof Error ? error.message : 'Unknown error',
32
- });
30
+ (0, utils_1.log)('error', 'Google Analytics initialization failed', { error });
33
31
  }
34
32
  }
35
33
  trackEvent(eventName, metadata) {
@@ -41,9 +39,7 @@ class GoogleAnalyticsIntegration extends state_manager_1.StateManager {
41
39
  window.gtag('event', eventName, normalizedMetadata);
42
40
  }
43
41
  catch (error) {
44
- utils_1.debugLog.error('GoogleAnalyticsIntegration', 'Event tracking failed', {
45
- error: error instanceof Error ? error.message : 'Unknown error',
46
- });
42
+ (0, utils_1.log)('error', 'Google Analytics event tracking failed', { error });
47
43
  }
48
44
  }
49
45
  cleanup() {
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ActivityListenerManager = void 0;
4
- const logging_1 = require("../utils/logging");
4
+ const utils_1 = require("../utils");
5
5
  class ActivityListenerManager {
6
6
  constructor(onActivity) {
7
7
  this.options = { passive: true };
@@ -14,7 +14,7 @@ class ActivityListenerManager {
14
14
  window.addEventListener('focus', this.onActivity, this.options);
15
15
  }
16
16
  catch (error) {
17
- logging_1.debugLog.error('ActivityListenerManager', 'Failed to setup activity listeners', { error });
17
+ (0, utils_1.log)('error', 'Failed to setup activity listeners', { error });
18
18
  throw error;
19
19
  }
20
20
  }
@@ -25,7 +25,7 @@ class ActivityListenerManager {
25
25
  window.removeEventListener('focus', this.onActivity);
26
26
  }
27
27
  catch (error) {
28
- logging_1.debugLog.warn('ActivityListenerManager', 'Error during activity listeners cleanup', { error });
28
+ (0, utils_1.log)('warn', 'Error during activity listeners cleanup', { error });
29
29
  }
30
30
  }
31
31
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KeyboardListenerManager = exports.MouseListenerManager = void 0;
4
- const logging_1 = require("../utils/logging");
4
+ const utils_1 = require("../utils");
5
5
  /**
6
6
  * Base class for input listener managers to reduce code duplication
7
7
  */
@@ -17,7 +17,7 @@ class BaseInputListenerManager {
17
17
  });
18
18
  }
19
19
  catch (error) {
20
- logging_1.debugLog.error(this.logPrefix, `Failed to setup ${this.logPrefix.toLowerCase()} listeners`, { error });
20
+ (0, utils_1.log)('error', `Failed to setup ${this.logPrefix.toLowerCase()} listeners`, { error });
21
21
  }
22
22
  }
23
23
  cleanup() {
@@ -27,7 +27,7 @@ class BaseInputListenerManager {
27
27
  });
28
28
  }
29
29
  catch (error) {
30
- logging_1.debugLog.warn(this.logPrefix, `Error during ${this.logPrefix.toLowerCase()} listeners cleanup`, { error });
30
+ (0, utils_1.log)('warn', `Error during ${this.logPrefix.toLowerCase()} listeners cleanup`, { error });
31
31
  }
32
32
  }
33
33
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.TouchListenerManager = void 0;
4
- const logging_1 = require("../utils/logging");
4
+ const utils_1 = require("../utils");
5
5
  class TouchListenerManager {
6
6
  constructor(onActivity) {
7
7
  this.options = { passive: true };
@@ -15,7 +15,7 @@ class TouchListenerManager {
15
15
  window.addEventListener('orientationchange', this.onActivity, this.options);
16
16
  }
17
17
  catch (error) {
18
- logging_1.debugLog.error('TouchListenerManager', 'Failed to setup touch listeners', { error });
18
+ (0, utils_1.log)('error', 'Failed to setup touch listeners', { error });
19
19
  throw error;
20
20
  }
21
21
  }
@@ -27,7 +27,7 @@ class TouchListenerManager {
27
27
  window.removeEventListener('orientationchange', this.onActivity);
28
28
  }
29
29
  catch (error) {
30
- logging_1.debugLog.warn('TouchListenerManager', 'Error during touch listeners cleanup', { error });
30
+ (0, utils_1.log)('warn', 'Error during touch listeners cleanup', { error });
31
31
  }
32
32
  }
33
33
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.UnloadListenerManager = void 0;
4
- const logging_1 = require("../utils/logging");
4
+ const utils_1 = require("../utils");
5
5
  class UnloadListenerManager {
6
6
  constructor(onInactivity) {
7
7
  this.options = { passive: true };
@@ -13,7 +13,7 @@ class UnloadListenerManager {
13
13
  window.addEventListener('pagehide', this.onInactivity, this.options);
14
14
  }
15
15
  catch (error) {
16
- logging_1.debugLog.error('UnloadListenerManager', 'Failed to setup unload listeners', { error });
16
+ (0, utils_1.log)('error', 'Failed to setup unload listeners', { error });
17
17
  throw error;
18
18
  }
19
19
  }
@@ -23,7 +23,7 @@ class UnloadListenerManager {
23
23
  window.removeEventListener('pagehide', this.onInactivity);
24
24
  }
25
25
  catch (error) {
26
- logging_1.debugLog.warn('UnloadListenerManager', 'Error during unload listeners cleanup', { error });
26
+ (0, utils_1.log)('warn', 'Error during unload listeners cleanup', { error });
27
27
  }
28
28
  }
29
29
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.VisibilityListenerManager = void 0;
4
- const logging_1 = require("../utils/logging");
4
+ const utils_1 = require("../utils");
5
5
  class VisibilityListenerManager {
6
6
  constructor(onActivity, onVisibilityChange) {
7
7
  this.options = { passive: true };
@@ -24,7 +24,7 @@ class VisibilityListenerManager {
24
24
  }
25
25
  }
26
26
  catch (error) {
27
- logging_1.debugLog.error('VisibilityListenerManager', 'Failed to setup visibility listeners', { error });
27
+ (0, utils_1.log)('error', 'Failed to setup visibility listeners', { error });
28
28
  }
29
29
  }
30
30
  cleanup() {
@@ -40,7 +40,7 @@ class VisibilityListenerManager {
40
40
  }
41
41
  }
42
42
  catch (error) {
43
- logging_1.debugLog.warn('VisibilityListenerManager', 'Error during visibility listeners cleanup', { error });
43
+ (0, utils_1.log)('warn', 'Error during visibility listeners cleanup', { error });
44
44
  }
45
45
  }
46
46
  }
@@ -8,9 +8,12 @@ export declare class EventManager extends StateManager {
8
8
  private readonly dataSender;
9
9
  private readonly emitter;
10
10
  private eventsQueue;
11
+ private pendingEventsBuffer;
11
12
  private lastEventFingerprint;
12
13
  private lastEventTime;
13
14
  private sendIntervalId;
15
+ private rateLimitCounter;
16
+ private rateLimitWindowStart;
14
17
  constructor(storeManager: StorageManager, googleAnalytics?: GoogleAnalyticsIntegration | null, emitter?: Emitter | null);
15
18
  recoverPersistedEvents(): Promise<void>;
16
19
  track({ type, page_url, from_page_url, scroll_data, click_data, custom_event, web_vitals, error_data, session_end_reason, }: Partial<EventData>): void;
@@ -18,12 +21,12 @@ export declare class EventManager extends StateManager {
18
21
  flushImmediately(): Promise<boolean>;
19
22
  flushImmediatelySync(): boolean;
20
23
  getQueueLength(): number;
24
+ flushPendingEvents(): void;
21
25
  private clearSendInterval;
22
26
  private flushEvents;
23
27
  private sendEventsQueue;
24
28
  private buildEventsPayload;
25
29
  private buildEventPayload;
26
- private isEventExcluded;
27
30
  private isDuplicateEvent;
28
31
  private createEventFingerprint;
29
32
  private createEventSignature;
@@ -31,6 +34,7 @@ export declare class EventManager extends StateManager {
31
34
  private startSendInterval;
32
35
  private handleGoogleAnalyticsIntegration;
33
36
  private shouldSample;
37
+ private checkRateLimit;
34
38
  private removeProcessedEvents;
35
39
  private emitEvent;
36
40
  private emitEventsQueue;
@@ -10,9 +10,12 @@ class EventManager extends state_manager_1.StateManager {
10
10
  constructor(storeManager, googleAnalytics = null, emitter = null) {
11
11
  super();
12
12
  this.eventsQueue = [];
13
+ this.pendingEventsBuffer = [];
13
14
  this.lastEventFingerprint = null;
14
15
  this.lastEventTime = 0;
15
16
  this.sendIntervalId = null;
17
+ this.rateLimitCounter = 0;
18
+ this.rateLimitWindowStart = 0;
16
19
  this.googleAnalytics = googleAnalytics;
17
20
  this.dataSender = new sender_manager_1.SenderManager(storeManager);
18
21
  this.emitter = emitter;
@@ -21,7 +24,7 @@ class EventManager extends state_manager_1.StateManager {
21
24
  await this.dataSender.recoverPersistedEvents({
22
25
  onSuccess: (_eventCount, recoveredEvents, body) => {
23
26
  if (recoveredEvents && recoveredEvents.length > 0) {
24
- const eventIds = recoveredEvents.map((e) => e.timestamp + '_' + e.type);
27
+ const eventIds = recoveredEvents.map((e) => e.id);
25
28
  this.removeProcessedEvents(eventIds);
26
29
  if (body) {
27
30
  this.emitEventsQueue(body);
@@ -29,19 +32,48 @@ class EventManager extends state_manager_1.StateManager {
29
32
  }
30
33
  },
31
34
  onFailure: async () => {
32
- utils_1.debugLog.warn('EventManager', 'Failed to recover persisted events');
35
+ (0, utils_1.log)('warn', 'Failed to recover persisted events');
33
36
  },
34
37
  });
35
38
  }
36
39
  track({ type, page_url, from_page_url, scroll_data, click_data, custom_event, web_vitals, error_data, session_end_reason, }) {
37
40
  if (!type) {
38
- utils_1.debugLog.warn('EventManager', 'Event type is required');
41
+ (0, utils_1.log)('error', 'Event type is required - event will be ignored');
42
+ return;
43
+ }
44
+ // Check session BEFORE rate limiting to avoid consuming quota for buffered events
45
+ if (!this.get('sessionId')) {
46
+ // Protect against unbounded buffer growth during initialization delays
47
+ if (this.pendingEventsBuffer.length >= config_constants_1.MAX_PENDING_EVENTS_BUFFER) {
48
+ // Drop oldest event (FIFO) to make room for new one
49
+ this.pendingEventsBuffer.shift();
50
+ (0, utils_1.log)('warn', 'Pending events buffer full - dropping oldest event', {
51
+ data: { maxBufferSize: config_constants_1.MAX_PENDING_EVENTS_BUFFER },
52
+ });
53
+ }
54
+ this.pendingEventsBuffer.push({
55
+ type,
56
+ page_url,
57
+ from_page_url,
58
+ scroll_data,
59
+ click_data,
60
+ custom_event,
61
+ web_vitals,
62
+ error_data,
63
+ session_end_reason,
64
+ });
65
+ return;
66
+ }
67
+ // Rate limiting check (except for critical events)
68
+ // Applied AFTER session check to only rate-limit processable events
69
+ const isCriticalEvent = type === types_1.EventType.SESSION_START || type === types_1.EventType.SESSION_END;
70
+ if (!isCriticalEvent && !this.checkRateLimit()) {
71
+ // Rate limit exceeded - drop event silently
72
+ // Logging would itself cause performance issues
39
73
  return;
40
74
  }
41
75
  const eventType = type;
42
76
  const isSessionStart = eventType === types_1.EventType.SESSION_START;
43
- const isSessionEnd = eventType === types_1.EventType.SESSION_END;
44
- const isCriticalEvent = isSessionStart || isSessionEnd;
45
77
  const currentPageUrl = page_url || this.get('pageUrl');
46
78
  const payload = this.buildEventPayload({
47
79
  type: eventType,
@@ -54,21 +86,18 @@ class EventManager extends state_manager_1.StateManager {
54
86
  error_data,
55
87
  session_end_reason,
56
88
  });
57
- if (this.isEventExcluded(payload)) {
58
- return;
59
- }
60
89
  if (!isCriticalEvent && !this.shouldSample()) {
61
90
  return;
62
91
  }
63
92
  if (isSessionStart) {
64
93
  const currentSessionId = this.get('sessionId');
65
94
  if (!currentSessionId) {
66
- utils_1.debugLog.warn('EventManager', 'Session start event ignored: missing sessionId');
95
+ (0, utils_1.log)('error', 'Session start event requires sessionId - event will be ignored');
67
96
  return;
68
97
  }
69
98
  if (this.get('hasStartSession')) {
70
- utils_1.debugLog.warn('EventManager', 'Duplicate session_start detected', {
71
- sessionId: currentSessionId,
99
+ (0, utils_1.log)('warn', 'Duplicate session_start detected', {
100
+ data: { sessionId: currentSessionId },
72
101
  });
73
102
  return;
74
103
  }
@@ -77,6 +106,14 @@ class EventManager extends state_manager_1.StateManager {
77
106
  if (this.isDuplicateEvent(payload)) {
78
107
  return;
79
108
  }
109
+ if (this.get('mode') === types_1.Mode.QA && eventType === types_1.EventType.CUSTOM && custom_event) {
110
+ console.log('[TraceLog] Event', {
111
+ name: custom_event.name,
112
+ ...(custom_event.metadata && { metadata: custom_event.metadata }),
113
+ });
114
+ this.emitEvent(payload);
115
+ return;
116
+ }
80
117
  this.addToQueue(payload);
81
118
  }
82
119
  stop() {
@@ -85,8 +122,11 @@ class EventManager extends state_manager_1.StateManager {
85
122
  this.sendIntervalId = null;
86
123
  }
87
124
  this.eventsQueue = [];
125
+ this.pendingEventsBuffer = [];
88
126
  this.lastEventFingerprint = null;
89
127
  this.lastEventTime = 0;
128
+ this.rateLimitCounter = 0;
129
+ this.rateLimitWindowStart = 0;
90
130
  this.dataSender.stop();
91
131
  }
92
132
  async flushImmediately() {
@@ -98,6 +138,27 @@ class EventManager extends state_manager_1.StateManager {
98
138
  getQueueLength() {
99
139
  return this.eventsQueue.length;
100
140
  }
141
+ flushPendingEvents() {
142
+ if (this.pendingEventsBuffer.length === 0) {
143
+ return;
144
+ }
145
+ const currentSessionId = this.get('sessionId');
146
+ if (!currentSessionId) {
147
+ // Keep events in buffer for future retry - do NOT discard
148
+ // This prevents data loss during legitimate race conditions
149
+ (0, utils_1.log)('warn', 'Cannot flush pending events: session not initialized - keeping in buffer', {
150
+ data: { bufferedEventCount: this.pendingEventsBuffer.length },
151
+ });
152
+ return;
153
+ }
154
+ // Create copy before clearing to avoid infinite recursion
155
+ const bufferedEvents = [...this.pendingEventsBuffer];
156
+ this.pendingEventsBuffer = [];
157
+ // Process all buffered events now that session exists
158
+ bufferedEvents.forEach((event) => {
159
+ this.track(event);
160
+ });
161
+ }
101
162
  clearSendInterval() {
102
163
  if (this.sendIntervalId) {
103
164
  clearInterval(this.sendIntervalId);
@@ -110,7 +171,7 @@ class EventManager extends state_manager_1.StateManager {
110
171
  }
111
172
  const body = this.buildEventsPayload();
112
173
  const eventsToSend = [...this.eventsQueue];
113
- const eventIds = eventsToSend.map((e) => `${e.timestamp}_${e.type}`);
174
+ const eventIds = eventsToSend.map((e) => e.id);
114
175
  if (isSync) {
115
176
  const success = this.dataSender.sendEventsQueueSync(body);
116
177
  if (success) {
@@ -128,8 +189,8 @@ class EventManager extends state_manager_1.StateManager {
128
189
  this.emitEventsQueue(body);
129
190
  },
130
191
  onFailure: () => {
131
- utils_1.debugLog.warn('EventManager', 'Async flush failed', {
132
- eventCount: eventsToSend.length,
192
+ (0, utils_1.log)('warn', 'Async flush failed', {
193
+ data: { eventCount: eventsToSend.length },
133
194
  });
134
195
  },
135
196
  });
@@ -141,15 +202,15 @@ class EventManager extends state_manager_1.StateManager {
141
202
  }
142
203
  const body = this.buildEventsPayload();
143
204
  const eventsToSend = [...this.eventsQueue];
144
- const eventIds = eventsToSend.map((e) => `${e.timestamp}_${e.type}`);
205
+ const eventIds = eventsToSend.map((e) => e.id);
145
206
  await this.dataSender.sendEventsQueue(body, {
146
207
  onSuccess: () => {
147
208
  this.removeProcessedEvents(eventIds);
148
209
  this.emitEventsQueue(body);
149
210
  },
150
211
  onFailure: async () => {
151
- utils_1.debugLog.warn('EventManager', 'Events send failed, keeping in queue', {
152
- eventCount: eventsToSend.length,
212
+ (0, utils_1.log)('warn', 'Events send failed, keeping in queue', {
213
+ data: { eventCount: eventsToSend.length },
153
214
  });
154
215
  },
155
216
  });
@@ -180,6 +241,7 @@ class EventManager extends state_manager_1.StateManager {
180
241
  const isSessionStart = data.type === types_1.EventType.SESSION_START;
181
242
  const currentPageUrl = data.page_url ?? this.get('pageUrl');
182
243
  const payload = {
244
+ id: (0, utils_1.generateEventId)(),
183
245
  type: data.type,
184
246
  page_url: currentPageUrl,
185
247
  timestamp: Date.now(),
@@ -193,23 +255,8 @@ class EventManager extends state_manager_1.StateManager {
193
255
  ...(data.session_end_reason && { session_end_reason: data.session_end_reason }),
194
256
  ...(isSessionStart && (0, utils_1.getUTMParameters)() && { utm: (0, utils_1.getUTMParameters)() }),
195
257
  };
196
- const projectTags = this.get('config')?.tags;
197
- if (projectTags?.length) {
198
- payload.tags = projectTags;
199
- }
200
258
  return payload;
201
259
  }
202
- isEventExcluded(event) {
203
- const config = this.get('config');
204
- const isRouteExcluded = (0, utils_1.isUrlPathExcluded)(event.page_url, config?.excludedUrlPaths ?? []);
205
- const hasStartSession = this.get('hasStartSession');
206
- const isSessionEndEvent = event.type === types_1.EventType.SESSION_END;
207
- const isSessionStartEvent = event.type === types_1.EventType.SESSION_START;
208
- if (isRouteExcluded && !isSessionStartEvent && !(isSessionEndEvent && hasStartSession)) {
209
- return true;
210
- }
211
- return config?.ipExcluded === true;
212
- }
213
260
  isDuplicateEvent(event) {
214
261
  const now = Date.now();
215
262
  const fingerprint = this.createEventFingerprint(event);
@@ -250,11 +297,13 @@ class EventManager extends state_manager_1.StateManager {
250
297
  if (this.eventsQueue.length > config_constants_1.MAX_EVENTS_QUEUE_LENGTH) {
251
298
  const nonCriticalIndex = this.eventsQueue.findIndex((e) => e.type !== types_1.EventType.SESSION_START && e.type !== types_1.EventType.SESSION_END);
252
299
  const removedEvent = nonCriticalIndex >= 0 ? this.eventsQueue.splice(nonCriticalIndex, 1)[0] : this.eventsQueue.shift();
253
- utils_1.debugLog.warn('EventManager', 'Event queue overflow, oldest non-critical event removed', {
254
- maxLength: config_constants_1.MAX_EVENTS_QUEUE_LENGTH,
255
- currentLength: this.eventsQueue.length,
256
- removedEventType: removedEvent?.type,
257
- wasCritical: removedEvent?.type === types_1.EventType.SESSION_START || removedEvent?.type === types_1.EventType.SESSION_END,
300
+ (0, utils_1.log)('warn', 'Event queue overflow, oldest non-critical event removed', {
301
+ data: {
302
+ maxLength: config_constants_1.MAX_EVENTS_QUEUE_LENGTH,
303
+ currentLength: this.eventsQueue.length,
304
+ removedEventType: removedEvent?.type,
305
+ wasCritical: removedEvent?.type === types_1.EventType.SESSION_START || removedEvent?.type === types_1.EventType.SESSION_END,
306
+ },
258
307
  });
259
308
  }
260
309
  if (!this.sendIntervalId) {
@@ -271,7 +320,7 @@ class EventManager extends state_manager_1.StateManager {
271
320
  }
272
321
  handleGoogleAnalyticsIntegration(event) {
273
322
  if (this.googleAnalytics && event.type === types_1.EventType.CUSTOM && event.custom_event) {
274
- if (this.get('config')?.mode === 'qa' || this.get('config')?.mode === 'debug') {
323
+ if (this.get('mode') === types_1.Mode.QA) {
275
324
  return;
276
325
  }
277
326
  this.googleAnalytics.trackEvent(event.custom_event.name, event.custom_event.metadata ?? {});
@@ -281,11 +330,25 @@ class EventManager extends state_manager_1.StateManager {
281
330
  const samplingRate = this.get('config')?.samplingRate ?? 1;
282
331
  return Math.random() < samplingRate;
283
332
  }
333
+ checkRateLimit() {
334
+ const now = Date.now();
335
+ // Reset counter if window has expired
336
+ if (now - this.rateLimitWindowStart > config_constants_1.RATE_LIMIT_WINDOW_MS) {
337
+ this.rateLimitCounter = 0;
338
+ this.rateLimitWindowStart = now;
339
+ }
340
+ // Check if limit exceeded
341
+ if (this.rateLimitCounter >= config_constants_1.MAX_EVENTS_PER_SECOND) {
342
+ return false;
343
+ }
344
+ // Increment counter
345
+ this.rateLimitCounter++;
346
+ return true;
347
+ }
284
348
  removeProcessedEvents(eventIds) {
285
349
  const eventIdSet = new Set(eventIds);
286
350
  this.eventsQueue = this.eventsQueue.filter((event) => {
287
- const eventId = `${event.timestamp}_${event.type}`;
288
- return !eventIdSet.has(eventId);
351
+ return !eventIdSet.has(event.id);
289
352
  });
290
353
  }
291
354
  emitEvent(eventData) {