@tracelog/lib 0.5.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/README.md +157 -180
  2. package/dist/browser/tracelog.esm.js +1007 -1357
  3. package/dist/browser/tracelog.js +2 -2
  4. package/dist/cjs/api.d.ts +12 -2
  5. package/dist/cjs/api.js +63 -27
  6. package/dist/cjs/app.d.ts +2 -2
  7. package/dist/cjs/app.js +26 -32
  8. package/dist/cjs/constants/config.constants.d.ts +4 -2
  9. package/dist/cjs/constants/config.constants.js +6 -18
  10. package/dist/cjs/constants/index.d.ts +0 -1
  11. package/dist/cjs/constants/index.js +0 -1
  12. package/dist/cjs/constants/storage.constants.d.ts +3 -2
  13. package/dist/cjs/constants/storage.constants.js +4 -4
  14. package/dist/cjs/handlers/click.handler.js +3 -6
  15. package/dist/cjs/handlers/error.handler.js +1 -11
  16. package/dist/cjs/handlers/page-view.handler.js +0 -4
  17. package/dist/cjs/handlers/performance.handler.js +14 -29
  18. package/dist/cjs/handlers/scroll.handler.js +7 -6
  19. package/dist/cjs/handlers/session.handler.js +7 -6
  20. package/dist/cjs/integrations/google-analytics.integration.js +2 -6
  21. package/dist/cjs/listeners/activity-listener-manager.js +3 -3
  22. package/dist/cjs/listeners/input-listener-managers.js +3 -3
  23. package/dist/cjs/listeners/touch-listener-manager.js +3 -3
  24. package/dist/cjs/listeners/unload-listener-manager.js +3 -3
  25. package/dist/cjs/listeners/visibility-listener-manager.js +3 -3
  26. package/dist/cjs/managers/event.manager.d.ts +2 -1
  27. package/dist/cjs/managers/event.manager.js +60 -38
  28. package/dist/cjs/managers/sender.manager.js +29 -36
  29. package/dist/cjs/managers/session.manager.js +5 -13
  30. package/dist/cjs/managers/state.manager.d.ts +0 -3
  31. package/dist/cjs/managers/state.manager.js +1 -43
  32. package/dist/cjs/managers/storage.manager.d.ts +16 -2
  33. package/dist/cjs/managers/storage.manager.js +73 -19
  34. package/dist/cjs/managers/user.manager.d.ts +1 -1
  35. package/dist/cjs/managers/user.manager.js +2 -2
  36. package/dist/cjs/public-api.d.ts +3 -3
  37. package/dist/cjs/public-api.js +1 -1
  38. package/dist/cjs/test-bridge.d.ts +1 -0
  39. package/dist/cjs/test-bridge.js +37 -2
  40. package/dist/cjs/types/config.types.d.ts +15 -18
  41. package/dist/cjs/types/config.types.js +6 -0
  42. package/dist/cjs/types/event.types.d.ts +1 -13
  43. package/dist/cjs/types/index.d.ts +0 -2
  44. package/dist/cjs/types/index.js +0 -2
  45. package/dist/cjs/types/mode.types.d.ts +1 -2
  46. package/dist/cjs/types/mode.types.js +0 -1
  47. package/dist/cjs/types/queue.types.d.ts +0 -6
  48. package/dist/cjs/types/state.types.d.ts +2 -0
  49. package/dist/cjs/types/test-bridge.types.d.ts +2 -2
  50. package/dist/cjs/types/validation-error.types.d.ts +0 -6
  51. package/dist/cjs/types/validation-error.types.js +1 -10
  52. package/dist/cjs/utils/browser/device-detector.utils.js +2 -24
  53. package/dist/cjs/utils/browser/index.d.ts +1 -0
  54. package/dist/cjs/utils/browser/index.js +1 -0
  55. package/dist/cjs/utils/browser/qa-mode.utils.d.ts +13 -0
  56. package/dist/cjs/utils/browser/qa-mode.utils.js +43 -0
  57. package/dist/cjs/utils/browser/utm-params.utils.js +0 -15
  58. package/dist/cjs/utils/data/uuid.utils.d.ts +13 -0
  59. package/dist/cjs/utils/data/uuid.utils.js +37 -1
  60. package/dist/cjs/utils/index.d.ts +1 -1
  61. package/dist/cjs/utils/index.js +1 -1
  62. package/dist/cjs/utils/logging.utils.d.ts +6 -0
  63. package/dist/cjs/utils/logging.utils.js +25 -0
  64. package/dist/cjs/utils/network/index.d.ts +0 -1
  65. package/dist/cjs/utils/network/index.js +0 -1
  66. package/dist/cjs/utils/network/url.utils.d.ts +2 -8
  67. package/dist/cjs/utils/network/url.utils.js +46 -90
  68. package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -13
  69. package/dist/cjs/utils/security/sanitize.utils.js +15 -178
  70. package/dist/cjs/utils/validations/config-validations.utils.d.ts +3 -9
  71. package/dist/cjs/utils/validations/config-validations.utils.js +48 -94
  72. package/dist/cjs/utils/validations/event-validations.utils.js +11 -5
  73. package/dist/cjs/utils/validations/index.d.ts +0 -1
  74. package/dist/cjs/utils/validations/index.js +0 -1
  75. package/dist/cjs/utils/validations/metadata-validations.utils.js +0 -1
  76. package/dist/cjs/utils/validations/type-guards.utils.d.ts +2 -2
  77. package/dist/cjs/utils/validations/type-guards.utils.js +50 -4
  78. package/dist/esm/api.d.ts +12 -2
  79. package/dist/esm/api.js +62 -27
  80. package/dist/esm/app.d.ts +2 -2
  81. package/dist/esm/app.js +28 -34
  82. package/dist/esm/constants/config.constants.d.ts +4 -2
  83. package/dist/esm/constants/config.constants.js +4 -16
  84. package/dist/esm/constants/index.d.ts +0 -1
  85. package/dist/esm/constants/index.js +0 -1
  86. package/dist/esm/constants/storage.constants.d.ts +3 -2
  87. package/dist/esm/constants/storage.constants.js +3 -2
  88. package/dist/esm/handlers/click.handler.js +3 -6
  89. package/dist/esm/handlers/error.handler.js +1 -11
  90. package/dist/esm/handlers/page-view.handler.js +0 -4
  91. package/dist/esm/handlers/performance.handler.js +14 -29
  92. package/dist/esm/handlers/scroll.handler.js +7 -6
  93. package/dist/esm/handlers/session.handler.js +7 -6
  94. package/dist/esm/integrations/google-analytics.integration.js +3 -7
  95. package/dist/esm/listeners/activity-listener-manager.js +3 -3
  96. package/dist/esm/listeners/input-listener-managers.js +3 -3
  97. package/dist/esm/listeners/touch-listener-manager.js +3 -3
  98. package/dist/esm/listeners/unload-listener-manager.js +3 -3
  99. package/dist/esm/listeners/visibility-listener-manager.js +3 -3
  100. package/dist/esm/managers/event.manager.d.ts +2 -1
  101. package/dist/esm/managers/event.manager.js +62 -40
  102. package/dist/esm/managers/sender.manager.js +31 -38
  103. package/dist/esm/managers/session.manager.js +5 -13
  104. package/dist/esm/managers/state.manager.d.ts +0 -3
  105. package/dist/esm/managers/state.manager.js +1 -43
  106. package/dist/esm/managers/storage.manager.d.ts +16 -2
  107. package/dist/esm/managers/storage.manager.js +73 -19
  108. package/dist/esm/managers/user.manager.d.ts +1 -1
  109. package/dist/esm/managers/user.manager.js +2 -2
  110. package/dist/esm/public-api.d.ts +3 -3
  111. package/dist/esm/public-api.js +1 -1
  112. package/dist/esm/test-bridge.d.ts +1 -0
  113. package/dist/esm/test-bridge.js +37 -2
  114. package/dist/esm/types/config.types.d.ts +15 -18
  115. package/dist/esm/types/config.types.js +5 -1
  116. package/dist/esm/types/event.types.d.ts +1 -13
  117. package/dist/esm/types/index.d.ts +0 -2
  118. package/dist/esm/types/index.js +0 -2
  119. package/dist/esm/types/mode.types.d.ts +1 -2
  120. package/dist/esm/types/mode.types.js +0 -1
  121. package/dist/esm/types/queue.types.d.ts +0 -6
  122. package/dist/esm/types/state.types.d.ts +2 -0
  123. package/dist/esm/types/test-bridge.types.d.ts +2 -2
  124. package/dist/esm/types/validation-error.types.d.ts +0 -6
  125. package/dist/esm/types/validation-error.types.js +0 -8
  126. package/dist/esm/utils/browser/device-detector.utils.js +2 -24
  127. package/dist/esm/utils/browser/index.d.ts +1 -0
  128. package/dist/esm/utils/browser/index.js +1 -0
  129. package/dist/esm/utils/browser/qa-mode.utils.d.ts +13 -0
  130. package/dist/esm/utils/browser/qa-mode.utils.js +39 -0
  131. package/dist/esm/utils/browser/utm-params.utils.js +0 -15
  132. package/dist/esm/utils/data/uuid.utils.d.ts +13 -0
  133. package/dist/esm/utils/data/uuid.utils.js +35 -0
  134. package/dist/esm/utils/index.d.ts +1 -1
  135. package/dist/esm/utils/index.js +1 -1
  136. package/dist/esm/utils/logging.utils.d.ts +6 -0
  137. package/dist/esm/utils/logging.utils.js +20 -0
  138. package/dist/esm/utils/network/index.d.ts +0 -1
  139. package/dist/esm/utils/network/index.js +0 -1
  140. package/dist/esm/utils/network/url.utils.d.ts +2 -8
  141. package/dist/esm/utils/network/url.utils.js +45 -88
  142. package/dist/esm/utils/security/sanitize.utils.d.ts +1 -13
  143. package/dist/esm/utils/security/sanitize.utils.js +15 -176
  144. package/dist/esm/utils/validations/config-validations.utils.d.ts +3 -9
  145. package/dist/esm/utils/validations/config-validations.utils.js +49 -94
  146. package/dist/esm/utils/validations/event-validations.utils.js +11 -5
  147. package/dist/esm/utils/validations/index.d.ts +0 -1
  148. package/dist/esm/utils/validations/index.js +0 -1
  149. package/dist/esm/utils/validations/metadata-validations.utils.js +0 -1
  150. package/dist/esm/utils/validations/type-guards.utils.d.ts +2 -2
  151. package/dist/esm/utils/validations/type-guards.utils.js +50 -4
  152. package/package.json +1 -1
  153. package/dist/cjs/app.types.d.ts +0 -2
  154. package/dist/cjs/app.types.js +0 -12
  155. package/dist/cjs/constants/api.constants.d.ts +0 -6
  156. package/dist/cjs/constants/api.constants.js +0 -14
  157. package/dist/cjs/managers/api.manager.d.ts +0 -13
  158. package/dist/cjs/managers/api.manager.js +0 -44
  159. package/dist/cjs/managers/config.builder.d.ts +0 -33
  160. package/dist/cjs/managers/config.builder.js +0 -116
  161. package/dist/cjs/managers/config.manager.d.ts +0 -56
  162. package/dist/cjs/managers/config.manager.js +0 -157
  163. package/dist/cjs/managers/tags.manager.d.ts +0 -36
  164. package/dist/cjs/managers/tags.manager.js +0 -171
  165. package/dist/cjs/types/api.types.d.ts +0 -52
  166. package/dist/cjs/types/api.types.js +0 -56
  167. package/dist/cjs/types/tag.types.d.ts +0 -43
  168. package/dist/cjs/types/tag.types.js +0 -31
  169. package/dist/cjs/utils/logging/debug-logger.utils.d.ts +0 -14
  170. package/dist/cjs/utils/logging/debug-logger.utils.js +0 -47
  171. package/dist/cjs/utils/logging/index.d.ts +0 -1
  172. package/dist/cjs/utils/logging/index.js +0 -5
  173. package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +0 -4
  174. package/dist/cjs/utils/network/fetch-with-timeout.utils.js +0 -25
  175. package/dist/cjs/utils/validations/url-validations.utils.d.ts +0 -15
  176. package/dist/cjs/utils/validations/url-validations.utils.js +0 -47
  177. package/dist/esm/app.types.d.ts +0 -2
  178. package/dist/esm/app.types.js +0 -1
  179. package/dist/esm/constants/api.constants.d.ts +0 -6
  180. package/dist/esm/constants/api.constants.js +0 -11
  181. package/dist/esm/managers/api.manager.d.ts +0 -13
  182. package/dist/esm/managers/api.manager.js +0 -41
  183. package/dist/esm/managers/config.builder.d.ts +0 -33
  184. package/dist/esm/managers/config.builder.js +0 -112
  185. package/dist/esm/managers/config.manager.d.ts +0 -56
  186. package/dist/esm/managers/config.manager.js +0 -153
  187. package/dist/esm/managers/tags.manager.d.ts +0 -36
  188. package/dist/esm/managers/tags.manager.js +0 -167
  189. package/dist/esm/types/api.types.d.ts +0 -52
  190. package/dist/esm/types/api.types.js +0 -53
  191. package/dist/esm/types/tag.types.d.ts +0 -43
  192. package/dist/esm/types/tag.types.js +0 -28
  193. package/dist/esm/utils/logging/debug-logger.utils.d.ts +0 -14
  194. package/dist/esm/utils/logging/debug-logger.utils.js +0 -44
  195. package/dist/esm/utils/logging/index.d.ts +0 -1
  196. package/dist/esm/utils/logging/index.js +0 -1
  197. package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +0 -4
  198. package/dist/esm/utils/network/fetch-with-timeout.utils.js +0 -22
  199. package/dist/esm/utils/validations/url-validations.utils.d.ts +0 -15
  200. package/dist/esm/utils/validations/url-validations.utils.js +0 -42
@@ -1,6 +1,6 @@
1
1
  import { QUEUE_KEY, EVENT_EXPIRY_HOURS, MAX_RETRIES, RETRY_DELAY_MS, REQUEST_TIMEOUT_MS } from '../constants';
2
- import { SpecialProjectId } from '../types';
3
- import { debugLog } from '../utils';
2
+ import { SpecialApiUrl } from '../types';
3
+ import { log } from '../utils';
4
4
  import { StateManager } from './state.manager';
5
5
  export class SenderManager extends StateManager {
6
6
  constructor(storeManager) {
@@ -11,9 +11,8 @@ export class SenderManager extends StateManager {
11
11
  this.storeManager = storeManager;
12
12
  }
13
13
  getQueueStorageKey() {
14
- const projectId = this.get('config')?.id || 'default';
15
14
  const userId = this.get('userId') || 'anonymous';
16
- return `${QUEUE_KEY(projectId)}:${userId}`;
15
+ return QUEUE_KEY(userId);
17
16
  }
18
17
  sendEventsQueueSync(body) {
19
18
  if (this.shouldSkipSend()) {
@@ -21,9 +20,9 @@ export class SenderManager extends StateManager {
21
20
  return true;
22
21
  }
23
22
  const config = this.get('config');
24
- if (config?.id === SpecialProjectId.Fail) {
25
- debugLog.warn('SenderManager', 'Fail mode: simulating network failure (sync)', {
26
- events: body.events.length,
23
+ if (config?.integrations?.custom?.apiUrl === SpecialApiUrl.Fail) {
24
+ log('warn', 'Fail mode: simulating network failure (sync)', {
25
+ data: { events: body.events.length },
27
26
  });
28
27
  return false;
29
28
  }
@@ -34,9 +33,11 @@ export class SenderManager extends StateManager {
34
33
  return success;
35
34
  }
36
35
  async sendEventsQueue(body, callbacks) {
37
- const persisted = this.persistEvents(body);
38
- if (!persisted && !this.shouldSkipSend()) {
39
- debugLog.warn('SenderManager', 'Failed to persist events, attempting immediate send');
36
+ if (!this.shouldSkipSend()) {
37
+ const persisted = this.persistEvents(body);
38
+ if (!persisted) {
39
+ log('warn', 'Failed to persist events, attempting immediate send');
40
+ }
40
41
  }
41
42
  const success = await this.send(body);
42
43
  if (success) {
@@ -70,7 +71,7 @@ export class SenderManager extends StateManager {
70
71
  }
71
72
  }
72
73
  catch (error) {
73
- debugLog.error('SenderManager', 'Failed to recover persisted events', { error });
74
+ log('error', 'Failed to recover persisted events', { error });
74
75
  this.clearPersistedEvents();
75
76
  }
76
77
  }
@@ -89,9 +90,9 @@ export class SenderManager extends StateManager {
89
90
  return this.simulateSuccessfulSend();
90
91
  }
91
92
  const config = this.get('config');
92
- if (config?.id === SpecialProjectId.Fail) {
93
- debugLog.warn('SenderManager', 'Fail mode: simulating network failure', {
94
- events: body.events.length,
93
+ if (config?.integrations?.custom?.apiUrl === SpecialApiUrl.Fail) {
94
+ log('warn', 'Fail mode: simulating network failure', {
95
+ data: { events: body.events.length },
95
96
  });
96
97
  return false;
97
98
  }
@@ -101,11 +102,12 @@ export class SenderManager extends StateManager {
101
102
  return response.ok;
102
103
  }
103
104
  catch (error) {
104
- const errorMessage = error instanceof Error ? error.message : String(error);
105
- debugLog.error('SenderManager', 'Send request failed', {
106
- error: errorMessage,
107
- events: body.events.length,
108
- url: url.replace(/\/\/[^/]+/, '//[DOMAIN]'),
105
+ log('error', 'Send request failed', {
106
+ error,
107
+ data: {
108
+ events: body.events.length,
109
+ url: url.replace(/\/\/[^/]+/, '//[DOMAIN]'),
110
+ },
109
111
  });
110
112
  return false;
111
113
  }
@@ -113,18 +115,16 @@ export class SenderManager extends StateManager {
113
115
  async sendWithTimeout(url, payload) {
114
116
  const controller = new AbortController();
115
117
  const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
116
- const config = this.get('config');
117
118
  try {
118
119
  const response = await fetch(url, {
119
120
  method: 'POST',
120
- headers: {
121
- 'Content-Type': 'application/json',
122
- 'X-TraceLog-Project': config?.id || 'unknown',
123
- },
124
121
  body: payload,
125
122
  keepalive: true,
126
123
  credentials: 'include',
127
124
  signal: controller.signal,
125
+ headers: {
126
+ 'Content-Type': 'application/json',
127
+ },
128
128
  });
129
129
  if (!response.ok) {
130
130
  throw new Error(`HTTP ${response.status}: ${response.statusText}`);
@@ -143,10 +143,10 @@ export class SenderManager extends StateManager {
143
143
  if (success) {
144
144
  return true;
145
145
  }
146
- debugLog.warn('SenderManager', 'sendBeacon failed, persisting events for recovery');
146
+ log('warn', 'sendBeacon failed, persisting events for recovery');
147
147
  }
148
148
  else {
149
- debugLog.warn('SenderManager', 'sendBeacon not available, persisting events for recovery');
149
+ log('warn', 'sendBeacon not available, persisting events for recovery');
150
150
  }
151
151
  this.persistEventsForRecovery(body);
152
152
  return false;
@@ -176,7 +176,7 @@ export class SenderManager extends StateManager {
176
176
  }
177
177
  }
178
178
  catch (error) {
179
- debugLog.warn('SenderManager', 'Failed to parse persisted data', { error });
179
+ log('warn', 'Failed to parse persisted data', { error });
180
180
  this.clearPersistedEvents();
181
181
  }
182
182
  return null;
@@ -213,7 +213,7 @@ export class SenderManager extends StateManager {
213
213
  return !!this.storeManager.getItem(storageKey);
214
214
  }
215
215
  catch (error) {
216
- debugLog.warn('SenderManager', 'Failed to persist events', { error });
216
+ log('warn', 'Failed to persist events', { error });
217
217
  return false;
218
218
  }
219
219
  }
@@ -223,7 +223,7 @@ export class SenderManager extends StateManager {
223
223
  this.storeManager.removeItem(key);
224
224
  }
225
225
  catch (error) {
226
- debugLog.warn('SenderManager', 'Failed to clear persisted events', { error });
226
+ log('warn', 'Failed to clear persisted events', { error });
227
227
  }
228
228
  }
229
229
  resetRetryState() {
@@ -236,7 +236,7 @@ export class SenderManager extends StateManager {
236
236
  return;
237
237
  }
238
238
  if (this.retryCount >= MAX_RETRIES) {
239
- debugLog.warn('SenderManager', 'Max retries reached, giving up', { retryCount: this.retryCount });
239
+ log('warn', 'Max retries reached, giving up', { data: { retryCount: this.retryCount } });
240
240
  this.clearPersistedEvents();
241
241
  this.resetRetryState();
242
242
  originalCallbacks?.onFailure?.();
@@ -267,16 +267,9 @@ export class SenderManager extends StateManager {
267
267
  this.isRetrying = false;
268
268
  }
269
269
  }, retryDelay);
270
- debugLog.debug('SenderManager', 'Retry scheduled', {
271
- attempt: this.retryCount + 1,
272
- delay: retryDelay,
273
- events: body.events.length,
274
- });
275
270
  }
276
271
  shouldSkipSend() {
277
- const config = this.get('config');
278
- const { id } = config || {};
279
- return id === SpecialProjectId.Skip;
272
+ return !this.get('apiUrl');
280
273
  }
281
274
  async simulateSuccessfulSend() {
282
275
  const delay = Math.random() * 400 + 100;
@@ -1,6 +1,6 @@
1
1
  import { BROADCAST_CHANNEL_NAME, DEFAULT_SESSION_TIMEOUT, SESSION_STORAGE_KEY } from '../constants';
2
2
  import { EventType } from '../types';
3
- import { debugLog } from '../utils/logging';
3
+ import { log } from '../utils';
4
4
  import { StateManager } from './state.manager';
5
5
  export class SessionManager extends StateManager {
6
6
  constructor(storageManager, eventManager, projectId) {
@@ -17,7 +17,7 @@ export class SessionManager extends StateManager {
17
17
  }
18
18
  initCrossTabSync() {
19
19
  if (typeof BroadcastChannel === 'undefined') {
20
- debugLog.warn('SessionManager', 'BroadcastChannel not supported');
20
+ log('warn', 'BroadcastChannel not supported');
21
21
  return;
22
22
  }
23
23
  const projectId = this.getProjectId();
@@ -28,7 +28,6 @@ export class SessionManager extends StateManager {
28
28
  return;
29
29
  }
30
30
  if (action === 'session_end') {
31
- debugLog.debug('SessionManager', 'Session end synced from another tab');
32
31
  this.resetSessionState();
33
32
  return;
34
33
  }
@@ -39,7 +38,6 @@ export class SessionManager extends StateManager {
39
38
  if (this.isTracking) {
40
39
  this.setupSessionTimeout();
41
40
  }
42
- debugLog.debug('SessionManager', 'Session synced from another tab', { sessionId });
43
41
  }
44
42
  };
45
43
  }
@@ -82,11 +80,9 @@ export class SessionManager extends StateManager {
82
80
  }
83
81
  const sessionTimeout = this.get('config')?.sessionTimeout ?? DEFAULT_SESSION_TIMEOUT;
84
82
  if (Date.now() - storedSession.lastActivity > sessionTimeout) {
85
- debugLog.debug('SessionManager', 'Stored session expired');
86
83
  this.clearStoredSession();
87
84
  return null;
88
85
  }
89
- debugLog.info('SessionManager', 'Session recovered from storage', { sessionId: storedSession.id });
90
86
  return storedSession.id;
91
87
  }
92
88
  persistSession(sessionId, lastActivity = Date.now()) {
@@ -129,7 +125,7 @@ export class SessionManager extends StateManager {
129
125
  }
130
126
  async startTracking() {
131
127
  if (this.isTracking) {
132
- debugLog.warn('SessionManager', 'Session tracking already active');
128
+ log('warn', 'Session tracking already active');
133
129
  return;
134
130
  }
135
131
  const recoveredSessionId = this.recoverSession();
@@ -149,7 +145,6 @@ export class SessionManager extends StateManager {
149
145
  this.setupSessionTimeout();
150
146
  this.setupActivityListeners();
151
147
  this.setupLifecycleListeners();
152
- debugLog.info('SessionManager', 'Session tracking started', { sessionId, recovered: isRecovered });
153
148
  }
154
149
  catch (error) {
155
150
  this.isTracking = false;
@@ -232,11 +227,10 @@ export class SessionManager extends StateManager {
232
227
  async endSession(reason) {
233
228
  const sessionId = this.get('sessionId');
234
229
  if (!sessionId) {
235
- debugLog.warn('SessionManager', 'endSession called without active session', { reason });
230
+ log('warn', 'endSession called without active session', { data: { reason } });
236
231
  this.resetSessionState(reason);
237
232
  return;
238
233
  }
239
- debugLog.info('SessionManager', 'Ending session', { sessionId, reason });
240
234
  this.eventManager.track({
241
235
  type: EventType.SESSION_END,
242
236
  session_end_reason: reason,
@@ -255,9 +249,7 @@ export class SessionManager extends StateManager {
255
249
  finalize();
256
250
  }
257
251
  catch (error) {
258
- debugLog.warn('SessionManager', 'Async flush failed during session end', {
259
- error: error instanceof Error ? error.message : 'Unknown error',
260
- });
252
+ log('warn', 'Async flush failed during session end', { error });
261
253
  finalize();
262
254
  }
263
255
  }
@@ -5,7 +5,4 @@ export declare abstract class StateManager {
5
5
  protected get<T extends keyof State>(key: T): State[T];
6
6
  protected set<T extends keyof State>(key: T, value: State[T]): void;
7
7
  protected getState(): Readonly<State>;
8
- private isCriticalStateKey;
9
- private shouldLog;
10
- private formatLogValue;
11
8
  }
@@ -1,5 +1,3 @@
1
- import { debugLog } from '../utils/logging';
2
- import { DEFAULT_SAMPLING_RATE } from '../constants';
3
1
  const globalState = {};
4
2
  export function getGlobalState() {
5
3
  return globalState;
@@ -14,49 +12,9 @@ export class StateManager {
14
12
  return globalState[key];
15
13
  }
16
14
  set(key, value) {
17
- const oldValue = globalState[key];
18
- if (key === 'config' && value) {
19
- const configValue = value;
20
- if (configValue) {
21
- const samplingRate = configValue.samplingRate ?? DEFAULT_SAMPLING_RATE;
22
- const normalizedSamplingRate = samplingRate < 0 || samplingRate > 1 ? DEFAULT_SAMPLING_RATE : samplingRate;
23
- const hasNormalizedSampling = normalizedSamplingRate !== samplingRate;
24
- if (hasNormalizedSampling) {
25
- const normalizedConfig = { ...configValue, samplingRate: normalizedSamplingRate };
26
- globalState[key] = normalizedConfig;
27
- }
28
- else {
29
- globalState[key] = configValue;
30
- }
31
- }
32
- else {
33
- globalState[key] = value;
34
- }
35
- }
36
- else {
37
- globalState[key] = value;
38
- }
39
- if (this.isCriticalStateKey(key) && this.shouldLog(oldValue, globalState[key])) {
40
- debugLog.debug('StateManager', 'State updated', {
41
- key,
42
- oldValue: this.formatLogValue(key, oldValue),
43
- newValue: this.formatLogValue(key, globalState[key]),
44
- });
45
- }
15
+ globalState[key] = value;
46
16
  }
47
17
  getState() {
48
18
  return { ...globalState };
49
19
  }
50
- isCriticalStateKey(key) {
51
- return key === 'sessionId' || key === 'config' || key === 'hasStartSession';
52
- }
53
- shouldLog(oldValue, newValue) {
54
- return oldValue !== newValue;
55
- }
56
- formatLogValue(key, value) {
57
- if (key === 'config') {
58
- return value ? '(configured)' : '(not configured)';
59
- }
60
- return value;
61
- }
62
20
  }
@@ -1,11 +1,13 @@
1
1
  /**
2
- * Manages localStorage with automatic fallback to in-memory storage.
2
+ * Manages localStorage and sessionStorage with automatic fallback to in-memory storage.
3
3
  * Provides a consistent interface for storing session data, configuration,
4
4
  * and analytics metadata across browser environments.
5
5
  */
6
6
  export declare class StorageManager {
7
7
  private readonly storage;
8
+ private readonly sessionStorageRef;
8
9
  private readonly fallbackStorage;
10
+ private readonly fallbackSessionStorage;
9
11
  private hasQuotaExceededError;
10
12
  constructor();
11
13
  /**
@@ -34,7 +36,19 @@ export declare class StorageManager {
34
36
  */
35
37
  hasQuotaError(): boolean;
36
38
  /**
37
- * Initialize localStorage with feature detection
39
+ * Initialize storage (localStorage or sessionStorage) with feature detection
38
40
  */
39
41
  private initializeStorage;
42
+ /**
43
+ * Retrieves an item from sessionStorage
44
+ */
45
+ getSessionItem(key: string): string | null;
46
+ /**
47
+ * Stores an item in sessionStorage
48
+ */
49
+ setSessionItem(key: string, value: string): void;
50
+ /**
51
+ * Removes an item from sessionStorage
52
+ */
53
+ removeSessionItem(key: string): void;
40
54
  }
@@ -1,16 +1,21 @@
1
- import { debugLog } from '../utils/logging/debug-logger.utils';
1
+ import { log } from '../utils';
2
2
  /**
3
- * Manages localStorage with automatic fallback to in-memory storage.
3
+ * Manages localStorage and sessionStorage with automatic fallback to in-memory storage.
4
4
  * Provides a consistent interface for storing session data, configuration,
5
5
  * and analytics metadata across browser environments.
6
6
  */
7
7
  export class StorageManager {
8
8
  constructor() {
9
9
  this.fallbackStorage = new Map();
10
+ this.fallbackSessionStorage = new Map();
10
11
  this.hasQuotaExceededError = false;
11
- this.storage = this.initializeStorage();
12
+ this.storage = this.initializeStorage('localStorage');
13
+ this.sessionStorageRef = this.initializeStorage('sessionStorage');
12
14
  if (!this.storage) {
13
- debugLog.warn('StorageManager', 'localStorage not available, using memory fallback');
15
+ log('warn', 'localStorage not available, using memory fallback');
16
+ }
17
+ if (!this.sessionStorageRef) {
18
+ log('warn', 'sessionStorage not available, using memory fallback');
14
19
  }
15
20
  }
16
21
  /**
@@ -23,8 +28,8 @@ export class StorageManager {
23
28
  }
24
29
  return this.fallbackStorage.get(key) ?? null;
25
30
  }
26
- catch (error) {
27
- debugLog.warn('StorageManager', 'Failed to get item, using fallback', { key, error });
31
+ catch {
32
+ // Silent fallback - user already warned in constructor
28
33
  return this.fallbackStorage.get(key) ?? null;
29
34
  }
30
35
  }
@@ -41,14 +46,12 @@ export class StorageManager {
41
46
  catch (error) {
42
47
  if (error instanceof DOMException && error.name === 'QuotaExceededError') {
43
48
  this.hasQuotaExceededError = true;
44
- debugLog.error('StorageManager', 'localStorage quota exceeded - data will not persist after reload', {
45
- key,
46
- valueSize: value.length,
49
+ log('error', 'localStorage quota exceeded - data will not persist after reload', {
50
+ error,
51
+ data: { key, valueSize: value.length },
47
52
  });
48
53
  }
49
- else {
50
- debugLog.warn('StorageManager', 'Failed to set item, using fallback', { key, error });
51
- }
54
+ // Else: Silent fallback - user already warned in constructor
52
55
  }
53
56
  // Always update fallback for consistency
54
57
  this.fallbackStorage.set(key, value);
@@ -62,8 +65,8 @@ export class StorageManager {
62
65
  this.storage.removeItem(key);
63
66
  }
64
67
  }
65
- catch (error) {
66
- debugLog.warn('StorageManager', 'Failed to remove item', { key, error });
68
+ catch {
69
+ // Silent - not critical
67
70
  }
68
71
  // Always clean fallback
69
72
  this.fallbackStorage.delete(key);
@@ -86,10 +89,9 @@ export class StorageManager {
86
89
  }
87
90
  keysToRemove.forEach((key) => this.storage.removeItem(key));
88
91
  this.fallbackStorage.clear();
89
- debugLog.debug('StorageManager', 'Cleared storage', { itemsRemoved: keysToRemove.length });
90
92
  }
91
93
  catch (error) {
92
- debugLog.error('StorageManager', 'Failed to clear storage', { error });
94
+ log('error', 'Failed to clear storage', { error });
93
95
  this.fallbackStorage.clear();
94
96
  }
95
97
  }
@@ -107,14 +109,14 @@ export class StorageManager {
107
109
  return this.hasQuotaExceededError;
108
110
  }
109
111
  /**
110
- * Initialize localStorage with feature detection
112
+ * Initialize storage (localStorage or sessionStorage) with feature detection
111
113
  */
112
- initializeStorage() {
114
+ initializeStorage(type) {
113
115
  if (typeof window === 'undefined') {
114
116
  return null;
115
117
  }
116
118
  try {
117
- const storage = window.localStorage;
119
+ const storage = type === 'localStorage' ? window.localStorage : window.sessionStorage;
118
120
  const testKey = '__tracelog_test__';
119
121
  storage.setItem(testKey, 'test');
120
122
  storage.removeItem(testKey);
@@ -124,4 +126,56 @@ export class StorageManager {
124
126
  return null;
125
127
  }
126
128
  }
129
+ /**
130
+ * Retrieves an item from sessionStorage
131
+ */
132
+ getSessionItem(key) {
133
+ try {
134
+ if (this.sessionStorageRef) {
135
+ return this.sessionStorageRef.getItem(key);
136
+ }
137
+ return this.fallbackSessionStorage.get(key) ?? null;
138
+ }
139
+ catch {
140
+ // Silent fallback - user already warned in constructor
141
+ return this.fallbackSessionStorage.get(key) ?? null;
142
+ }
143
+ }
144
+ /**
145
+ * Stores an item in sessionStorage
146
+ */
147
+ setSessionItem(key, value) {
148
+ try {
149
+ if (this.sessionStorageRef) {
150
+ this.sessionStorageRef.setItem(key, value);
151
+ return;
152
+ }
153
+ }
154
+ catch (error) {
155
+ if (error instanceof DOMException && error.name === 'QuotaExceededError') {
156
+ log('error', 'sessionStorage quota exceeded - data will not persist', {
157
+ error,
158
+ data: { key, valueSize: value.length },
159
+ });
160
+ }
161
+ // Else: Silent fallback - user already warned in constructor
162
+ }
163
+ // Always update fallback for consistency
164
+ this.fallbackSessionStorage.set(key, value);
165
+ }
166
+ /**
167
+ * Removes an item from sessionStorage
168
+ */
169
+ removeSessionItem(key) {
170
+ try {
171
+ if (this.sessionStorageRef) {
172
+ this.sessionStorageRef.removeItem(key);
173
+ }
174
+ }
175
+ catch {
176
+ // Silent - not critical
177
+ }
178
+ // Always clean fallback
179
+ this.fallbackSessionStorage.delete(key);
180
+ }
127
181
  }
@@ -12,5 +12,5 @@ export declare class UserManager {
12
12
  * @param projectId - Project identifier for namespacing
13
13
  * @returns Persistent unique user ID
14
14
  */
15
- static getId(storageManager: StorageManager, projectId?: string): string;
15
+ static getId(storageManager: StorageManager): string;
16
16
  }
@@ -13,8 +13,8 @@ export class UserManager {
13
13
  * @param projectId - Project identifier for namespacing
14
14
  * @returns Persistent unique user ID
15
15
  */
16
- static getId(storageManager, projectId) {
17
- const storageKey = USER_ID_KEY(projectId ?? '');
16
+ static getId(storageManager) {
17
+ const storageKey = USER_ID_KEY;
18
18
  const storedUserId = storageManager.getItem(storageKey);
19
19
  if (storedUserId) {
20
20
  return storedUserId;
@@ -1,8 +1,8 @@
1
1
  export * from './app.constants';
2
- export * from './app.types';
2
+ export * from './types';
3
3
  export declare const tracelog: {
4
- init: (appConfig: import("./app.types").AppConfig) => Promise<void>;
5
- event: (name: string, metadata?: Record<string, import("./app.types").MetadataType> | Record<string, import("./app.types").MetadataType>[]) => void;
4
+ init: (config: import("./types").Config) => Promise<void>;
5
+ event: (name: string, metadata?: Record<string, import("./types").MetadataType> | Record<string, import("./types").MetadataType>[]) => void;
6
6
  on: <K extends keyof import("./types").EmitterMap>(event: K, callback: import("./types").EmitterCallback<import("./types").EmitterMap[K]>) => void;
7
7
  off: <K extends keyof import("./types").EmitterMap>(event: K, callback: import("./types").EmitterCallback<import("./types").EmitterMap[K]>) => void;
8
8
  isInitialized: () => boolean;
@@ -2,7 +2,7 @@ import { init, event, on, off, isInitialized, destroy } from './api';
2
2
  // Constants
3
3
  export * from './app.constants';
4
4
  // Types
5
- export * from './app.types';
5
+ export * from './types';
6
6
  // TraceLog namespace containing all API methods
7
7
  export const tracelog = {
8
8
  init,
@@ -16,6 +16,7 @@ export declare class TestBridge extends App implements TraceLogTestBridge {
16
16
  private _isInitializing;
17
17
  private _isDestroying;
18
18
  constructor(isInitializing: boolean, isDestroying: boolean);
19
+ init(config: any): Promise<void>;
19
20
  isInitializing(): boolean;
20
21
  sendCustomEvent(name: string, data?: Record<string, unknown> | Record<string, unknown>[]): void;
21
22
  getSessionData(): Record<string, unknown> | null;
@@ -1,4 +1,6 @@
1
1
  import { App } from './app';
2
+ import { __setAppInstance } from './api';
3
+ import { STORAGE_BASE_KEY } from './constants';
2
4
  /**
3
5
  * Test bridge for E2E testing
4
6
  */
@@ -9,6 +11,34 @@ export class TestBridge extends App {
9
11
  this._isInitializing = isInitializing;
10
12
  this._isDestroying = isDestroying;
11
13
  }
14
+ async init(config) {
15
+ // Guard: TestBridge should only be used in development
16
+ if (process.env.NODE_ENV !== 'dev') {
17
+ throw new Error('[TraceLog] TestBridge is only available in development mode');
18
+ }
19
+ // First sync with window.tracelog BEFORE initializing
20
+ // This ensures both APIs point to the same instance from the start
21
+ if (!__setAppInstance) {
22
+ throw new Error('[TraceLog] __setAppInstance is not available (production build?)');
23
+ }
24
+ try {
25
+ __setAppInstance(this);
26
+ }
27
+ catch {
28
+ // If __setAppInstance fails (e.g., already initialized), throw clear error
29
+ throw new Error('[TraceLog] TestBridge cannot sync with existing tracelog instance. Call destroy() first.');
30
+ }
31
+ try {
32
+ await super.init(config);
33
+ }
34
+ catch (error) {
35
+ // If init fails, clear the sync
36
+ if (__setAppInstance) {
37
+ __setAppInstance(null);
38
+ }
39
+ throw error;
40
+ }
41
+ }
12
42
  isInitializing() {
13
43
  return this._isInitializing;
14
44
  }
@@ -43,7 +73,8 @@ export class TestBridge extends App {
43
73
  if (!storageManager) {
44
74
  throw new Error('Storage manager not available');
45
75
  }
46
- const projectId = this.get('config')?.id;
76
+ const config = this.get('config');
77
+ const projectId = config?.integrations?.tracelog?.projectId ?? config?.integrations?.custom?.apiUrl ?? 'test';
47
78
  const userId = this.get('userId');
48
79
  const sessionId = this.get('sessionId');
49
80
  if (!projectId || !userId) {
@@ -58,7 +89,7 @@ export class TestBridge extends App {
58
89
  timestamp: Date.now(),
59
90
  };
60
91
  // Store in the same format as SenderManager.persistEvents()
61
- const storageKey = `tl:${projectId}:queue:${userId}`;
92
+ const storageKey = `${STORAGE_BASE_KEY}:${projectId}:queue:${userId}`;
62
93
  storageManager.setItem(storageKey, JSON.stringify(persistedData));
63
94
  }
64
95
  get(key) {
@@ -103,6 +134,10 @@ export class TestBridge extends App {
103
134
  this._isDestroying = true;
104
135
  try {
105
136
  await super.destroy(force);
137
+ // Clear window.tracelog API reference (only in dev mode)
138
+ if (__setAppInstance) {
139
+ __setAppInstance(null);
140
+ }
106
141
  }
107
142
  finally {
108
143
  this._isDestroying = false;