@tracelog/lib 0.0.8 → 0.2.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 (228) hide show
  1. package/README.md +58 -24
  2. package/dist/browser/tracelog.js +1934 -3226
  3. package/dist/cjs/api.d.ts +33 -19
  4. package/dist/cjs/api.js +111 -156
  5. package/dist/cjs/app.constants.d.ts +80 -1
  6. package/dist/cjs/app.constants.js +90 -3
  7. package/dist/cjs/app.d.ts +29 -44
  8. package/dist/cjs/app.js +114 -212
  9. package/dist/cjs/app.types.d.ts +2 -7
  10. package/dist/cjs/app.types.js +10 -21
  11. package/dist/cjs/constants/api.constants.js +11 -5
  12. package/dist/cjs/constants/config.constants.d.ts +75 -0
  13. package/dist/cjs/constants/config.constants.js +178 -0
  14. package/dist/cjs/constants/error.constants.d.ts +29 -0
  15. package/dist/cjs/constants/error.constants.js +50 -0
  16. package/dist/cjs/constants/index.d.ts +3 -6
  17. package/dist/cjs/constants/index.js +3 -6
  18. package/dist/cjs/constants/performance.constants.d.ts +28 -0
  19. package/dist/cjs/constants/performance.constants.js +43 -0
  20. package/dist/cjs/handlers/click.handler.d.ts +1 -0
  21. package/dist/cjs/handlers/click.handler.js +30 -49
  22. package/dist/cjs/handlers/error.handler.d.ts +11 -6
  23. package/dist/cjs/handlers/error.handler.js +91 -51
  24. package/dist/cjs/handlers/page-view.handler.js +38 -29
  25. package/dist/cjs/handlers/performance.handler.d.ts +3 -0
  26. package/dist/cjs/handlers/performance.handler.js +76 -37
  27. package/dist/cjs/handlers/scroll.handler.d.ts +15 -0
  28. package/dist/cjs/handlers/scroll.handler.js +105 -31
  29. package/dist/cjs/handlers/session.handler.d.ts +6 -20
  30. package/dist/cjs/handlers/session.handler.js +38 -326
  31. package/dist/cjs/integrations/google-analytics.integration.d.ts +0 -1
  32. package/dist/cjs/integrations/google-analytics.integration.js +27 -98
  33. package/dist/cjs/listeners/input-listener-managers.d.ts +18 -9
  34. package/dist/cjs/listeners/input-listener-managers.js +24 -33
  35. package/dist/cjs/listeners/touch-listener-manager.d.ts +1 -3
  36. package/dist/cjs/listeners/touch-listener-manager.js +1 -23
  37. package/dist/cjs/listeners/visibility-listener-manager.d.ts +1 -4
  38. package/dist/cjs/listeners/visibility-listener-manager.js +6 -42
  39. package/dist/cjs/managers/api.manager.d.ts +13 -3
  40. package/dist/cjs/managers/api.manager.js +35 -5
  41. package/dist/cjs/managers/config.manager.d.ts +53 -3
  42. package/dist/cjs/managers/config.manager.js +131 -62
  43. package/dist/cjs/managers/event.manager.d.ts +57 -36
  44. package/dist/cjs/managers/event.manager.js +266 -417
  45. package/dist/cjs/managers/sender.manager.d.ts +40 -22
  46. package/dist/cjs/managers/sender.manager.js +200 -198
  47. package/dist/cjs/managers/session.manager.d.ts +80 -66
  48. package/dist/cjs/managers/session.manager.js +267 -522
  49. package/dist/cjs/managers/state.manager.d.ts +33 -0
  50. package/dist/cjs/managers/state.manager.js +79 -6
  51. package/dist/cjs/managers/storage.manager.d.ts +26 -2
  52. package/dist/cjs/managers/storage.manager.js +67 -34
  53. package/dist/cjs/managers/tags.manager.d.ts +31 -7
  54. package/dist/cjs/managers/tags.manager.js +123 -241
  55. package/dist/cjs/managers/user.manager.d.ts +14 -5
  56. package/dist/cjs/managers/user.manager.js +17 -9
  57. package/dist/cjs/public-api.d.ts +10 -1
  58. package/dist/cjs/public-api.js +18 -24
  59. package/dist/cjs/test-bridge.d.ts +48 -0
  60. package/dist/cjs/test-bridge.js +110 -0
  61. package/dist/cjs/types/api.types.d.ts +21 -6
  62. package/dist/cjs/types/api.types.js +21 -6
  63. package/dist/cjs/types/config.types.d.ts +22 -84
  64. package/dist/cjs/types/emitter.types.d.ts +11 -0
  65. package/dist/cjs/types/emitter.types.js +8 -0
  66. package/dist/cjs/types/event.types.d.ts +8 -11
  67. package/dist/cjs/types/index.d.ts +3 -1
  68. package/dist/cjs/types/index.js +3 -1
  69. package/dist/cjs/types/queue.types.d.ts +1 -0
  70. package/dist/cjs/types/session.types.d.ts +0 -64
  71. package/dist/cjs/types/state.types.d.ts +1 -0
  72. package/dist/cjs/types/test-bridge.types.d.ts +38 -0
  73. package/dist/cjs/types/validation-error.types.d.ts +7 -0
  74. package/dist/cjs/types/validation-error.types.js +11 -1
  75. package/dist/cjs/types/window.types.d.ts +1 -8
  76. package/dist/cjs/utils/data/uuid.utils.d.ts +1 -1
  77. package/dist/cjs/utils/data/uuid.utils.js +7 -5
  78. package/dist/cjs/utils/emitter.utils.d.ts +8 -0
  79. package/dist/cjs/utils/emitter.utils.js +33 -0
  80. package/dist/cjs/utils/index.d.ts +1 -0
  81. package/dist/cjs/utils/index.js +1 -0
  82. package/dist/cjs/utils/logging/debug-logger.utils.d.ts +10 -51
  83. package/dist/cjs/utils/logging/debug-logger.utils.js +36 -127
  84. package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +4 -0
  85. package/dist/cjs/utils/network/fetch-with-timeout.utils.js +25 -0
  86. package/dist/cjs/utils/network/index.d.ts +1 -0
  87. package/dist/cjs/utils/network/index.js +1 -0
  88. package/dist/cjs/utils/network/url.utils.js +2 -42
  89. package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -8
  90. package/dist/cjs/utils/security/sanitize.utils.js +7 -41
  91. package/dist/cjs/utils/validations/config-validations.utils.d.ts +7 -0
  92. package/dist/cjs/utils/validations/config-validations.utils.js +77 -22
  93. package/dist/esm/api.d.ts +33 -19
  94. package/dist/esm/api.js +105 -118
  95. package/dist/esm/app.constants.d.ts +80 -1
  96. package/dist/esm/app.constants.js +89 -1
  97. package/dist/esm/app.d.ts +29 -44
  98. package/dist/esm/app.js +115 -213
  99. package/dist/esm/app.types.d.ts +2 -7
  100. package/dist/esm/app.types.js +1 -7
  101. package/dist/esm/constants/api.constants.js +10 -4
  102. package/dist/esm/constants/config.constants.d.ts +75 -0
  103. package/dist/esm/constants/config.constants.js +174 -0
  104. package/dist/esm/constants/error.constants.d.ts +29 -0
  105. package/dist/esm/constants/error.constants.js +47 -0
  106. package/dist/esm/constants/index.d.ts +3 -6
  107. package/dist/esm/constants/index.js +3 -6
  108. package/dist/esm/constants/performance.constants.d.ts +28 -0
  109. package/dist/esm/constants/performance.constants.js +40 -0
  110. package/dist/esm/handlers/click.handler.d.ts +1 -0
  111. package/dist/esm/handlers/click.handler.js +30 -49
  112. package/dist/esm/handlers/error.handler.d.ts +11 -6
  113. package/dist/esm/handlers/error.handler.js +91 -51
  114. package/dist/esm/handlers/page-view.handler.js +38 -29
  115. package/dist/esm/handlers/performance.handler.d.ts +3 -0
  116. package/dist/esm/handlers/performance.handler.js +71 -32
  117. package/dist/esm/handlers/scroll.handler.d.ts +15 -0
  118. package/dist/esm/handlers/scroll.handler.js +106 -32
  119. package/dist/esm/handlers/session.handler.d.ts +6 -20
  120. package/dist/esm/handlers/session.handler.js +38 -326
  121. package/dist/esm/integrations/google-analytics.integration.d.ts +0 -1
  122. package/dist/esm/integrations/google-analytics.integration.js +27 -98
  123. package/dist/esm/listeners/input-listener-managers.d.ts +18 -9
  124. package/dist/esm/listeners/input-listener-managers.js +23 -32
  125. package/dist/esm/listeners/touch-listener-manager.d.ts +1 -3
  126. package/dist/esm/listeners/touch-listener-manager.js +1 -23
  127. package/dist/esm/listeners/visibility-listener-manager.d.ts +1 -4
  128. package/dist/esm/listeners/visibility-listener-manager.js +6 -42
  129. package/dist/esm/managers/api.manager.d.ts +13 -3
  130. package/dist/esm/managers/api.manager.js +34 -3
  131. package/dist/esm/managers/config.manager.d.ts +53 -3
  132. package/dist/esm/managers/config.manager.js +133 -64
  133. package/dist/esm/managers/event.manager.d.ts +57 -36
  134. package/dist/esm/managers/event.manager.js +268 -419
  135. package/dist/esm/managers/sender.manager.d.ts +40 -22
  136. package/dist/esm/managers/sender.manager.js +201 -199
  137. package/dist/esm/managers/session.manager.d.ts +80 -66
  138. package/dist/esm/managers/session.manager.js +269 -524
  139. package/dist/esm/managers/state.manager.d.ts +33 -0
  140. package/dist/esm/managers/state.manager.js +78 -6
  141. package/dist/esm/managers/storage.manager.d.ts +26 -2
  142. package/dist/esm/managers/storage.manager.js +66 -33
  143. package/dist/esm/managers/tags.manager.d.ts +31 -7
  144. package/dist/esm/managers/tags.manager.js +124 -242
  145. package/dist/esm/managers/user.manager.d.ts +14 -5
  146. package/dist/esm/managers/user.manager.js +17 -9
  147. package/dist/esm/public-api.d.ts +10 -1
  148. package/dist/esm/public-api.js +14 -1
  149. package/dist/esm/test-bridge.d.ts +48 -0
  150. package/dist/esm/test-bridge.js +106 -0
  151. package/dist/esm/types/api.types.d.ts +21 -6
  152. package/dist/esm/types/api.types.js +21 -6
  153. package/dist/esm/types/config.types.d.ts +22 -84
  154. package/dist/esm/types/emitter.types.d.ts +11 -0
  155. package/dist/esm/types/emitter.types.js +5 -0
  156. package/dist/esm/types/event.types.d.ts +8 -11
  157. package/dist/esm/types/index.d.ts +3 -1
  158. package/dist/esm/types/index.js +3 -1
  159. package/dist/esm/types/queue.types.d.ts +1 -0
  160. package/dist/esm/types/session.types.d.ts +0 -64
  161. package/dist/esm/types/state.types.d.ts +1 -0
  162. package/dist/esm/types/test-bridge.types.d.ts +38 -0
  163. package/dist/esm/types/validation-error.types.d.ts +7 -0
  164. package/dist/esm/types/validation-error.types.js +9 -0
  165. package/dist/esm/types/window.types.d.ts +1 -8
  166. package/dist/esm/utils/data/uuid.utils.d.ts +1 -1
  167. package/dist/esm/utils/data/uuid.utils.js +7 -5
  168. package/dist/esm/utils/emitter.utils.d.ts +8 -0
  169. package/dist/esm/utils/emitter.utils.js +29 -0
  170. package/dist/esm/utils/index.d.ts +1 -0
  171. package/dist/esm/utils/index.js +1 -0
  172. package/dist/esm/utils/logging/debug-logger.utils.d.ts +10 -51
  173. package/dist/esm/utils/logging/debug-logger.utils.js +36 -127
  174. package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +4 -0
  175. package/dist/esm/utils/network/fetch-with-timeout.utils.js +22 -0
  176. package/dist/esm/utils/network/index.d.ts +1 -0
  177. package/dist/esm/utils/network/index.js +1 -0
  178. package/dist/esm/utils/network/url.utils.js +2 -42
  179. package/dist/esm/utils/security/sanitize.utils.d.ts +1 -8
  180. package/dist/esm/utils/security/sanitize.utils.js +6 -39
  181. package/dist/esm/utils/validations/config-validations.utils.d.ts +7 -0
  182. package/dist/esm/utils/validations/config-validations.utils.js +76 -22
  183. package/package.json +23 -16
  184. package/dist/browser/web-vitals-CCnqwnC8.mjs +0 -198
  185. package/dist/cjs/constants/browser.constants.d.ts +0 -3
  186. package/dist/cjs/constants/browser.constants.js +0 -41
  187. package/dist/cjs/constants/initialization.constants.d.ts +0 -40
  188. package/dist/cjs/constants/initialization.constants.js +0 -48
  189. package/dist/cjs/constants/limits.constants.d.ts +0 -25
  190. package/dist/cjs/constants/limits.constants.js +0 -40
  191. package/dist/cjs/constants/security.constants.d.ts +0 -1
  192. package/dist/cjs/constants/security.constants.js +0 -12
  193. package/dist/cjs/constants/timing.constants.d.ts +0 -22
  194. package/dist/cjs/constants/timing.constants.js +0 -34
  195. package/dist/cjs/constants/validation.constants.d.ts +0 -13
  196. package/dist/cjs/constants/validation.constants.js +0 -31
  197. package/dist/cjs/handlers/network.handler.d.ts +0 -16
  198. package/dist/cjs/handlers/network.handler.js +0 -136
  199. package/dist/cjs/managers/cross-tab-session.manager.d.ts +0 -170
  200. package/dist/cjs/managers/cross-tab-session.manager.js +0 -730
  201. package/dist/cjs/managers/sampling.manager.d.ts +0 -8
  202. package/dist/cjs/managers/sampling.manager.js +0 -53
  203. package/dist/cjs/managers/session-recovery.manager.d.ts +0 -65
  204. package/dist/cjs/managers/session-recovery.manager.js +0 -237
  205. package/dist/cjs/types/web-vitals.types.d.ts +0 -6
  206. package/dist/esm/constants/browser.constants.d.ts +0 -3
  207. package/dist/esm/constants/browser.constants.js +0 -38
  208. package/dist/esm/constants/initialization.constants.d.ts +0 -40
  209. package/dist/esm/constants/initialization.constants.js +0 -45
  210. package/dist/esm/constants/limits.constants.d.ts +0 -25
  211. package/dist/esm/constants/limits.constants.js +0 -37
  212. package/dist/esm/constants/security.constants.d.ts +0 -1
  213. package/dist/esm/constants/security.constants.js +0 -9
  214. package/dist/esm/constants/timing.constants.d.ts +0 -22
  215. package/dist/esm/constants/timing.constants.js +0 -31
  216. package/dist/esm/constants/validation.constants.d.ts +0 -13
  217. package/dist/esm/constants/validation.constants.js +0 -28
  218. package/dist/esm/handlers/network.handler.d.ts +0 -16
  219. package/dist/esm/handlers/network.handler.js +0 -132
  220. package/dist/esm/managers/cross-tab-session.manager.d.ts +0 -170
  221. package/dist/esm/managers/cross-tab-session.manager.js +0 -726
  222. package/dist/esm/managers/sampling.manager.d.ts +0 -8
  223. package/dist/esm/managers/sampling.manager.js +0 -49
  224. package/dist/esm/managers/session-recovery.manager.d.ts +0 -65
  225. package/dist/esm/managers/session-recovery.manager.js +0 -233
  226. package/dist/esm/types/web-vitals.types.d.ts +0 -6
  227. /package/dist/cjs/types/{web-vitals.types.js → test-bridge.types.js} +0 -0
  228. /package/dist/esm/types/{web-vitals.types.js → test-bridge.types.js} +0 -0
package/dist/esm/api.d.ts CHANGED
@@ -1,15 +1,12 @@
1
- import { MetadataType } from './types/common.types';
2
- import { AppConfig } from './types/config.types';
1
+ import { MetadataType, AppConfig, EmitterCallback, EmitterMap } from './types';
3
2
  import './types/window.types';
4
- export * as Types from './app.types';
5
- export * as Constants from './app.constants';
6
3
  /**
7
4
  * Initializes the tracelog app with the provided configuration.
8
5
  * If already initialized, this function returns early without error.
9
6
  * @param appConfig - The configuration object for the app
10
- * @throws {Error} If initialization is currently in progress
7
+ * @throws {Error} If initialization fails or environment is invalid
11
8
  * @example
12
- * await init({ id: 'my-project-id' });
9
+ * await tracelog.init({ id: 'my-project-id' });
13
10
  */
14
11
  export declare const init: (appConfig: AppConfig) => Promise<void>;
15
12
  /**
@@ -18,29 +15,46 @@ export declare const init: (appConfig: AppConfig) => Promise<void>;
18
15
  * @param metadata - Optional metadata to attach to the event.
19
16
  * @example
20
17
  * // Send a custom event with metadata
21
- * event('user_signup', { method: 'email', plan: 'premium' });
18
+ * tracelog.event('user_signup', { method: 'email', plan: 'premium' });
22
19
  * @example
23
20
  * // Send a custom event without metadata
24
- * event('user_login');
21
+ * tracelog.event('user_login');
25
22
  * @remarks
26
- * This function should be called after the app has been initialized using the `init` function.
23
+ * This function should be called after the app has been initialized using the `tracelog.init` function.
27
24
  */
28
25
  export declare const event: (name: string, metadata?: Record<string, MetadataType>) => void;
26
+ /**
27
+ * Subscribe to events emitted by TraceLog
28
+ * @param event - Event name to listen to
29
+ * @param callback - Function to call when event is emitted
30
+ * @example
31
+ * // Listen for real-time events
32
+ * tracelog.on('realtime', (data) => {
33
+ * console.log('Event tracked:', data.type, data.data);
34
+ * });
35
+ *
36
+ * // Listen for sent events
37
+ * tracelog.on('sent', (data) => {
38
+ * console.log('Events sent:', data.eventCount);
39
+ * });
40
+ */
41
+ export declare const on: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
42
+ /**
43
+ * Unsubscribe from events emitted by TraceLog
44
+ * @param event - Event name to stop listening to
45
+ * @param callback - The same function reference that was used in on()
46
+ * @example
47
+ * // Remove a specific listener
48
+ * tracelog.off('realtime', myCallback);
49
+ */
50
+ export declare const off: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
29
51
  /**
30
52
  * Checks if the app has been initialized.
31
53
  * @returns true if the app is initialized, false otherwise
32
54
  */
33
55
  export declare const isInitialized: () => boolean;
34
- /**
35
- * Gets the current initialization status for debugging purposes.
36
- * @returns Object with detailed initialization state
37
- */
38
- export declare const getInitializationStatus: () => {
39
- isInitialized: boolean;
40
- isInitializing: boolean;
41
- hasInstance: boolean;
42
- };
43
56
  /**
44
57
  * Destroys the current app instance and cleans up resources.
58
+ * @throws {Error} If not initialized or already destroying
45
59
  */
46
- export declare const destroy: () => void;
60
+ export declare const destroy: () => Promise<void>;
package/dist/esm/api.js CHANGED
@@ -1,83 +1,54 @@
1
1
  import { App } from './app';
2
- import { debugLog } from './utils/logging';
3
- import { validateAndNormalizeConfig } from './utils/validations';
4
- import { INITIALIZATION_CONSTANTS } from './constants';
2
+ import { debugLog, validateAndNormalizeConfig } from './utils';
3
+ import { TestBridge } from './test-bridge';
5
4
  import './types/window.types';
6
- export * as Types from './app.types';
7
- export * as Constants from './app.constants';
8
5
  let app = null;
9
6
  let isInitializing = false;
7
+ let isDestroying = false;
10
8
  /**
11
9
  * Initializes the tracelog app with the provided configuration.
12
10
  * If already initialized, this function returns early without error.
13
11
  * @param appConfig - The configuration object for the app
14
- * @throws {Error} If initialization is currently in progress
12
+ * @throws {Error} If initialization fails or environment is invalid
15
13
  * @example
16
- * await init({ id: 'my-project-id' });
14
+ * await tracelog.init({ id: 'my-project-id' });
17
15
  */
18
16
  export const init = async (appConfig) => {
17
+ // Browser environment check
18
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
19
+ throw new Error('This library can only be used in a browser environment');
20
+ }
21
+ // Already initialized - safe to return
22
+ if (app) {
23
+ debugLog.debug('API', 'Library already initialized, skipping duplicate initialization');
24
+ return;
25
+ }
26
+ // Prevent concurrent initialization
27
+ if (isInitializing) {
28
+ debugLog.warn('API', 'Initialization already in progress');
29
+ throw new Error('Initialization already in progress');
30
+ }
31
+ isInitializing = true;
19
32
  try {
20
- debugLog.info('API', 'Library initialization started', { id: appConfig.id });
21
- if (typeof window === 'undefined' || typeof document === 'undefined') {
22
- debugLog.clientError('API', 'Browser environment required - this library can only be used in a browser environment', {
23
- hasWindow: typeof window !== 'undefined',
24
- hasDocument: typeof document !== 'undefined',
25
- });
26
- throw new Error('This library can only be used in a browser environment');
27
- }
28
- if (app) {
29
- debugLog.debug('API', 'Library already initialized, skipping duplicate initialization', {
30
- projectId: appConfig.id,
31
- });
32
- return;
33
- }
34
- if (isInitializing) {
35
- debugLog.debug('API', 'Concurrent initialization detected, waiting for completion', { projectId: appConfig.id });
36
- let retries = 0;
37
- const maxRetries = INITIALIZATION_CONSTANTS.MAX_CONCURRENT_RETRIES;
38
- const retryDelay = INITIALIZATION_CONSTANTS.CONCURRENT_RETRY_DELAY_MS;
39
- while (isInitializing && retries < maxRetries) {
40
- await new Promise((resolve) => setTimeout(resolve, retryDelay));
41
- retries++;
42
- }
43
- if (app) {
44
- debugLog.debug('API', 'Concurrent initialization completed successfully', {
45
- projectId: appConfig.id,
46
- retriesUsed: retries,
47
- });
48
- return;
49
- }
50
- if (isInitializing) {
51
- debugLog.error('API', 'Initialization timeout - concurrent initialization took too long', {
52
- projectId: appConfig.id,
53
- retriesUsed: retries,
54
- maxRetries,
55
- });
56
- throw new Error('App initialization timeout - concurrent initialization took too long');
57
- }
58
- }
59
- isInitializing = true;
60
- debugLog.debug('API', 'Validating and normalizing configuration', { projectId: appConfig.id });
33
+ debugLog.info('API', 'Initializing TraceLog', { projectId: appConfig.id });
61
34
  const validatedConfig = validateAndNormalizeConfig(appConfig);
62
- debugLog.debug('API', 'Creating App instance', { projectId: validatedConfig.id });
63
35
  const instance = new App();
64
- await instance.init(validatedConfig);
65
- app = instance;
66
- debugLog.info('API', 'Library initialization completed successfully', {
67
- projectId: validatedConfig.id,
68
- });
69
- }
70
- catch (error) {
71
- // Ensure complete cleanup on initialization failure
72
- if (app && !app.initialized) {
73
- // Clean up partially initialized app instance
36
+ try {
37
+ await instance.init(validatedConfig);
38
+ app = instance;
39
+ debugLog.info('API', 'TraceLog initialized successfully', { projectId: validatedConfig.id });
40
+ }
41
+ catch (error) {
74
42
  try {
75
- app.destroy();
43
+ await instance.destroy(true);
76
44
  }
77
45
  catch (cleanupError) {
78
46
  debugLog.warn('API', 'Failed to cleanup partially initialized app', { cleanupError });
79
47
  }
48
+ throw error;
80
49
  }
50
+ }
51
+ catch (error) {
81
52
  app = null;
82
53
  debugLog.error('API', 'Initialization failed', { error });
83
54
  throw error;
@@ -92,36 +63,59 @@ export const init = async (appConfig) => {
92
63
  * @param metadata - Optional metadata to attach to the event.
93
64
  * @example
94
65
  * // Send a custom event with metadata
95
- * event('user_signup', { method: 'email', plan: 'premium' });
66
+ * tracelog.event('user_signup', { method: 'email', plan: 'premium' });
96
67
  * @example
97
68
  * // Send a custom event without metadata
98
- * event('user_login');
69
+ * tracelog.event('user_login');
99
70
  * @remarks
100
- * This function should be called after the app has been initialized using the `init` function.
71
+ * This function should be called after the app has been initialized using the `tracelog.init` function.
101
72
  */
102
73
  export const event = (name, metadata) => {
74
+ if (!app) {
75
+ throw new Error('TraceLog not initialized. Please call init() first.');
76
+ }
103
77
  try {
104
- if (!app) {
105
- debugLog.clientError('API', 'Custom event failed - Library not initialized. Please call TraceLog.init() first', {
106
- eventName: name,
107
- hasMetadata: !!metadata,
108
- });
109
- throw new Error('App not initialized');
110
- }
111
- debugLog.debug('API', 'Sending custom event', {
112
- eventName: name,
113
- hasMetadata: !!metadata,
114
- metadataKeys: metadata ? Object.keys(metadata) : [],
115
- });
116
78
  app.sendCustomEvent(name, metadata);
117
79
  }
118
80
  catch (error) {
119
- debugLog.error('API', 'Event tracking failed', { eventName: name, error, hasMetadata: !!metadata });
120
- if (error instanceof Error &&
121
- (error.message === 'App not initialized' || error.message.includes('validation failed'))) {
122
- throw error;
123
- }
81
+ debugLog.error('API', 'Failed to send custom event', { eventName: name, error });
82
+ throw error;
83
+ }
84
+ };
85
+ /**
86
+ * Subscribe to events emitted by TraceLog
87
+ * @param event - Event name to listen to
88
+ * @param callback - Function to call when event is emitted
89
+ * @example
90
+ * // Listen for real-time events
91
+ * tracelog.on('realtime', (data) => {
92
+ * console.log('Event tracked:', data.type, data.data);
93
+ * });
94
+ *
95
+ * // Listen for sent events
96
+ * tracelog.on('sent', (data) => {
97
+ * console.log('Events sent:', data.eventCount);
98
+ * });
99
+ */
100
+ export const on = (event, callback) => {
101
+ if (!app) {
102
+ throw new Error('TraceLog not initialized. Please call init() first.');
103
+ }
104
+ app.on(event, callback);
105
+ };
106
+ /**
107
+ * Unsubscribe from events emitted by TraceLog
108
+ * @param event - Event name to stop listening to
109
+ * @param callback - The same function reference that was used in on()
110
+ * @example
111
+ * // Remove a specific listener
112
+ * tracelog.off('realtime', myCallback);
113
+ */
114
+ export const off = (event, callback) => {
115
+ if (!app) {
116
+ throw new Error('TraceLog not initialized. Please call init() first.');
124
117
  }
118
+ app.off(event, callback);
125
119
  };
126
120
  /**
127
121
  * Checks if the app has been initialized.
@@ -130,54 +124,47 @@ export const event = (name, metadata) => {
130
124
  export const isInitialized = () => {
131
125
  return app !== null;
132
126
  };
133
- /**
134
- * Gets the current initialization status for debugging purposes.
135
- * @returns Object with detailed initialization state
136
- */
137
- export const getInitializationStatus = () => {
138
- return {
139
- isInitialized: app !== null,
140
- isInitializing: isInitializing,
141
- hasInstance: app !== null,
142
- };
143
- };
144
127
  /**
145
128
  * Destroys the current app instance and cleans up resources.
129
+ * @throws {Error} If not initialized or already destroying
146
130
  */
147
- export const destroy = () => {
131
+ export const destroy = async () => {
132
+ // Check if app was never initialized
133
+ if (!app) {
134
+ throw new Error('App not initialized');
135
+ }
136
+ // Prevent concurrent destroy operations
137
+ if (isDestroying) {
138
+ throw new Error('Destroy operation already in progress');
139
+ }
140
+ isDestroying = true;
148
141
  try {
149
- debugLog.info('API', 'Library cleanup initiated');
150
- if (!app) {
151
- debugLog.warn('API', 'Cleanup called but Library was not initialized');
152
- throw new Error('App not initialized');
153
- }
154
- app.destroy();
142
+ debugLog.info('API', 'Destroying TraceLog instance');
143
+ await app.destroy();
155
144
  app = null;
156
145
  isInitializing = false;
157
- debugLog.info('API', 'Library cleanup completed successfully');
146
+ debugLog.info('API', 'TraceLog destroyed successfully');
158
147
  }
159
148
  catch (error) {
160
- debugLog.error('API', 'Cleanup failed', { error, hadApp: !!app, wasInitializing: isInitializing });
149
+ // Force cleanup even if destroy fails
150
+ app = null;
151
+ isInitializing = false;
152
+ debugLog.error('API', 'Error during destroy, forced cleanup', { error });
153
+ throw error;
154
+ }
155
+ finally {
156
+ isDestroying = false;
161
157
  }
162
158
  };
163
- class TestBridge extends App {
164
- isInitializing() {
165
- return isInitializing;
159
+ // Auto-inject testing bridge in development environments
160
+ if (process.env.NODE_ENV === 'dev' && typeof window !== 'undefined') {
161
+ const injectTestingBridge = () => {
162
+ window.__traceLogBridge = new TestBridge(isInitializing, isDestroying);
163
+ };
164
+ if (document.readyState === 'loading') {
165
+ document.addEventListener('DOMContentLoaded', injectTestingBridge);
166
166
  }
167
- }
168
- // Auto-inject testing bridge only in development/testing environments
169
- if (process.env.NODE_ENV === 'dev') {
170
- if (typeof window !== 'undefined') {
171
- // Wait for DOM to be ready before injecting
172
- const injectTestingBridge = () => {
173
- window.__traceLogBridge = new TestBridge();
174
- };
175
- // Inject immediately if DOM is ready, otherwise wait
176
- if (document.readyState === 'loading') {
177
- document.addEventListener('DOMContentLoaded', injectTestingBridge);
178
- }
179
- else {
180
- injectTestingBridge();
181
- }
167
+ else {
168
+ injectTestingBridge();
182
169
  }
183
170
  }
@@ -1 +1,80 @@
1
- export { DEFAULT_SESSION_TIMEOUT_MS } from './constants';
1
+ export declare const PERFORMANCE_CONFIG: {
2
+ readonly WEB_VITALS_THRESHOLDS: Record<import("./types").WebVitalType, number>;
3
+ };
4
+ export declare const DATA_PROTECTION: {
5
+ readonly PII_PATTERNS: readonly [RegExp, RegExp, RegExp, RegExp];
6
+ };
7
+ export declare const ENGAGEMENT_THRESHOLDS: {
8
+ readonly LOW_ACTIVITY_EVENT_COUNT: 50;
9
+ readonly HIGH_ACTIVITY_EVENT_COUNT: 1000;
10
+ readonly MIN_EVENTS_FOR_DYNAMIC_CALCULATION: 100;
11
+ readonly MIN_EVENTS_FOR_TREND_ANALYSIS: 30;
12
+ readonly BOUNCE_RATE_SESSION_THRESHOLD: 1;
13
+ readonly MIN_ENGAGED_SESSION_DURATION_MS: number;
14
+ readonly MIN_SCROLL_DEPTH_ENGAGEMENT: 25;
15
+ };
16
+ export declare const SESSION_ANALYTICS: {
17
+ readonly INACTIVITY_TIMEOUT_MS: number;
18
+ readonly SHORT_SESSION_THRESHOLD_MS: number;
19
+ readonly MEDIUM_SESSION_THRESHOLD_MS: number;
20
+ readonly LONG_SESSION_THRESHOLD_MS: number;
21
+ readonly MAX_REALISTIC_SESSION_DURATION_MS: number;
22
+ };
23
+ export declare const DEVICE_ANALYTICS: {
24
+ readonly MOBILE_MAX_WIDTH: 768;
25
+ readonly TABLET_MAX_WIDTH: 1024;
26
+ readonly MOBILE_PERFORMANCE_FACTOR: 1.5;
27
+ readonly TABLET_PERFORMANCE_FACTOR: 1.2;
28
+ };
29
+ export declare const CONTENT_ANALYTICS: {
30
+ readonly MIN_TEXT_LENGTH_FOR_ANALYSIS: 10;
31
+ readonly MIN_CLICKS_FOR_HOT_ELEMENT: 10;
32
+ readonly MIN_SCROLL_COMPLETION_PERCENT: 80;
33
+ readonly MIN_TIME_ON_PAGE_FOR_READ_MS: number;
34
+ };
35
+ export declare const INSIGHT_THRESHOLDS: {
36
+ readonly SIGNIFICANT_CHANGE_PERCENT: 20;
37
+ readonly MAJOR_CHANGE_PERCENT: 50;
38
+ readonly MIN_EVENTS_FOR_INSIGHT: 100;
39
+ readonly MIN_SESSIONS_FOR_INSIGHT: 10;
40
+ readonly MIN_CORRELATION_STRENGTH: 0.7;
41
+ readonly LOW_ERROR_RATE_PERCENT: 1;
42
+ readonly HIGH_ERROR_RATE_PERCENT: 5;
43
+ readonly CRITICAL_ERROR_RATE_PERCENT: 10;
44
+ };
45
+ export declare const TEMPORAL_ANALYSIS: {
46
+ readonly SHORT_TERM_TREND_HOURS: 24;
47
+ readonly MEDIUM_TERM_TREND_DAYS: 7;
48
+ readonly LONG_TERM_TREND_DAYS: 30;
49
+ readonly MIN_DATA_POINTS_FOR_TREND: 5;
50
+ readonly WEEKLY_PATTERN_MIN_WEEKS: 4;
51
+ readonly DAILY_PATTERN_MIN_DAYS: 14;
52
+ };
53
+ export declare const SEGMENTATION_ANALYTICS: {
54
+ readonly MIN_SEGMENT_SIZE: 10;
55
+ readonly MIN_COHORT_SIZE: 5;
56
+ readonly COHORT_ANALYSIS_DAYS: readonly [1, 3, 7, 14, 30];
57
+ readonly MIN_FUNNEL_EVENTS: 20;
58
+ };
59
+ export declare const ANALYTICS_QUERY_LIMITS: {
60
+ readonly DEFAULT_EVENTS_LIMIT: 5;
61
+ readonly DEFAULT_SESSIONS_LIMIT: 5;
62
+ readonly DEFAULT_PAGES_LIMIT: 5;
63
+ readonly MAX_EVENTS_FOR_DEEP_ANALYSIS: 10000;
64
+ readonly MAX_TIME_RANGE_DAYS: 365;
65
+ readonly ANALYTICS_BATCH_SIZE: 1000;
66
+ };
67
+ export declare const ANOMALY_DETECTION: {
68
+ readonly ANOMALY_THRESHOLD_SIGMA: 2.5;
69
+ readonly STRONG_ANOMALY_THRESHOLD_SIGMA: 3;
70
+ readonly TRAFFIC_DROP_ALERT_PERCENT: -30;
71
+ readonly TRAFFIC_SPIKE_ALERT_PERCENT: 200;
72
+ readonly MIN_BASELINE_DAYS: 7;
73
+ readonly MIN_EVENTS_FOR_ANOMALY_DETECTION: 50;
74
+ };
75
+ export declare const SPECIAL_VALUES: {
76
+ readonly PAGE_URL_EXCLUDED: "excluded";
77
+ readonly PAGE_URL_UNKNOWN: "unknown";
78
+ readonly IPV6_IPV4_PREFIX: "::ffff:";
79
+ };
80
+ export declare const LOCAL_IP_ADDRESSES: readonly ["localhost", "127.0.0.1", "::1"];
@@ -1 +1,89 @@
1
- export { DEFAULT_SESSION_TIMEOUT_MS } from './constants';
1
+ // Solo importamos constantes con valor analítico real
2
+ import { WEB_VITALS_THRESHOLDS } from './constants/performance.constants';
3
+ import { PII_PATTERNS } from './constants/error.constants';
4
+ // ============================================================================
5
+ // PERFORMANCE ANALYTICS CONSTANTS
6
+ // ============================================================================
7
+ export const PERFORMANCE_CONFIG = {
8
+ WEB_VITALS_THRESHOLDS, // Umbrales de negocio para análisis de rendimiento
9
+ };
10
+ // ============================================================================
11
+ // DATA PROTECTION CONSTANTS
12
+ // ============================================================================
13
+ export const DATA_PROTECTION = {
14
+ PII_PATTERNS, // Patrones para protección de datos sensibles
15
+ };
16
+ export const ENGAGEMENT_THRESHOLDS = {
17
+ LOW_ACTIVITY_EVENT_COUNT: 50,
18
+ HIGH_ACTIVITY_EVENT_COUNT: 1000,
19
+ MIN_EVENTS_FOR_DYNAMIC_CALCULATION: 100,
20
+ MIN_EVENTS_FOR_TREND_ANALYSIS: 30,
21
+ BOUNCE_RATE_SESSION_THRESHOLD: 1, // Sessions with 1 page view = bounce
22
+ MIN_ENGAGED_SESSION_DURATION_MS: 30 * 1000,
23
+ MIN_SCROLL_DEPTH_ENGAGEMENT: 25, // 25% scroll depth for engagement
24
+ };
25
+ export const SESSION_ANALYTICS = {
26
+ INACTIVITY_TIMEOUT_MS: 30 * 60 * 1000, // 30min for analytics (vs 15min client)
27
+ SHORT_SESSION_THRESHOLD_MS: 30 * 1000,
28
+ MEDIUM_SESSION_THRESHOLD_MS: 5 * 60 * 1000,
29
+ LONG_SESSION_THRESHOLD_MS: 30 * 60 * 1000,
30
+ MAX_REALISTIC_SESSION_DURATION_MS: 8 * 60 * 60 * 1000, // Filter outliers
31
+ };
32
+ export const DEVICE_ANALYTICS = {
33
+ MOBILE_MAX_WIDTH: 768,
34
+ TABLET_MAX_WIDTH: 1024,
35
+ MOBILE_PERFORMANCE_FACTOR: 1.5, // Mobile typically 1.5x slower
36
+ TABLET_PERFORMANCE_FACTOR: 1.2,
37
+ };
38
+ export const CONTENT_ANALYTICS = {
39
+ MIN_TEXT_LENGTH_FOR_ANALYSIS: 10,
40
+ MIN_CLICKS_FOR_HOT_ELEMENT: 10, // Popular element threshold
41
+ MIN_SCROLL_COMPLETION_PERCENT: 80, // Page consumption threshold
42
+ MIN_TIME_ON_PAGE_FOR_READ_MS: 15 * 1000,
43
+ };
44
+ export const INSIGHT_THRESHOLDS = {
45
+ SIGNIFICANT_CHANGE_PERCENT: 20,
46
+ MAJOR_CHANGE_PERCENT: 50,
47
+ MIN_EVENTS_FOR_INSIGHT: 100,
48
+ MIN_SESSIONS_FOR_INSIGHT: 10,
49
+ MIN_CORRELATION_STRENGTH: 0.7, // Strong correlation threshold
50
+ LOW_ERROR_RATE_PERCENT: 1,
51
+ HIGH_ERROR_RATE_PERCENT: 5,
52
+ CRITICAL_ERROR_RATE_PERCENT: 10,
53
+ };
54
+ export const TEMPORAL_ANALYSIS = {
55
+ SHORT_TERM_TREND_HOURS: 24,
56
+ MEDIUM_TERM_TREND_DAYS: 7,
57
+ LONG_TERM_TREND_DAYS: 30,
58
+ MIN_DATA_POINTS_FOR_TREND: 5,
59
+ WEEKLY_PATTERN_MIN_WEEKS: 4,
60
+ DAILY_PATTERN_MIN_DAYS: 14,
61
+ };
62
+ export const SEGMENTATION_ANALYTICS = {
63
+ MIN_SEGMENT_SIZE: 10,
64
+ MIN_COHORT_SIZE: 5,
65
+ COHORT_ANALYSIS_DAYS: [1, 3, 7, 14, 30],
66
+ MIN_FUNNEL_EVENTS: 20,
67
+ };
68
+ export const ANALYTICS_QUERY_LIMITS = {
69
+ DEFAULT_EVENTS_LIMIT: 5,
70
+ DEFAULT_SESSIONS_LIMIT: 5,
71
+ DEFAULT_PAGES_LIMIT: 5,
72
+ MAX_EVENTS_FOR_DEEP_ANALYSIS: 10000,
73
+ MAX_TIME_RANGE_DAYS: 365,
74
+ ANALYTICS_BATCH_SIZE: 1000, // For historical analysis
75
+ };
76
+ export const ANOMALY_DETECTION = {
77
+ ANOMALY_THRESHOLD_SIGMA: 2.5,
78
+ STRONG_ANOMALY_THRESHOLD_SIGMA: 3.0,
79
+ TRAFFIC_DROP_ALERT_PERCENT: -30,
80
+ TRAFFIC_SPIKE_ALERT_PERCENT: 200,
81
+ MIN_BASELINE_DAYS: 7,
82
+ MIN_EVENTS_FOR_ANOMALY_DETECTION: 50,
83
+ };
84
+ export const SPECIAL_VALUES = {
85
+ PAGE_URL_EXCLUDED: 'excluded',
86
+ PAGE_URL_UNKNOWN: 'unknown',
87
+ IPV6_IPV4_PREFIX: '::ffff:',
88
+ };
89
+ export const LOCAL_IP_ADDRESSES = ['localhost', '127.0.0.1', '::1'];
package/dist/esm/app.d.ts CHANGED
@@ -1,59 +1,44 @@
1
1
  import { EventManager } from './managers/event.manager';
2
- import { AppConfig } from './types/config.types';
3
2
  import { StateManager } from './managers/state.manager';
4
3
  import { SessionHandler } from './handlers/session.handler';
5
4
  import { PageViewHandler } from './handlers/page-view.handler';
6
5
  import { ClickHandler } from './handlers/click.handler';
7
6
  import { ScrollHandler } from './handlers/scroll.handler';
7
+ import { AppConfig, EmitterCallback, EmitterMap } from './types';
8
8
  import { GoogleAnalyticsIntegration } from './integrations/google-analytics.integration';
9
9
  import { StorageManager } from './managers/storage.manager';
10
10
  import { PerformanceHandler } from './handlers/performance.handler';
11
11
  import { ErrorHandler } from './handlers/error.handler';
12
- import { NetworkHandler } from './handlers/network.handler';
12
+ /**
13
+ * Main application class for TraceLog analytics
14
+ * Orchestrates event tracking, session management, and integrations
15
+ */
13
16
  export declare class App extends StateManager {
14
- protected isInitialized: boolean;
15
- protected googleAnalytics: GoogleAnalyticsIntegration | null;
16
- protected storageManager: StorageManager;
17
- protected eventManager: EventManager;
18
- protected sessionHandler: SessionHandler;
19
- protected pageViewHandler: PageViewHandler;
20
- protected clickHandler: ClickHandler;
21
- protected scrollHandler: ScrollHandler;
22
- protected performanceHandler: PerformanceHandler;
23
- protected errorHandler: ErrorHandler;
24
- protected networkHandler: NetworkHandler;
25
- protected suppressNextScrollTimer: number | null;
26
- /**
27
- * Returns the initialization status of the app
28
- * @returns true if the app is fully initialized, false otherwise
29
- */
17
+ private isInitialized;
18
+ private suppressNextScrollTimer;
19
+ private readonly emitter;
20
+ protected managers: {
21
+ storage?: StorageManager;
22
+ event?: EventManager;
23
+ };
24
+ protected handlers: {
25
+ session?: SessionHandler;
26
+ pageView?: PageViewHandler;
27
+ click?: ClickHandler;
28
+ scroll?: ScrollHandler;
29
+ performance?: PerformanceHandler;
30
+ error?: ErrorHandler;
31
+ };
32
+ protected integrations: {
33
+ googleAnalytics?: GoogleAnalyticsIntegration;
34
+ };
30
35
  get initialized(): boolean;
31
36
  init(appConfig: AppConfig): Promise<void>;
32
- /**
33
- * Validates that the app is ready to initialize with the provided config
34
- * This is a lightweight runtime validation layer that ensures the app receives proper config
35
- * @param appConfig - The validated and normalized configuration
36
- * @throws {ProjectIdValidationError} If project ID is invalid at runtime
37
- */
38
- private validateAppReadiness;
39
37
  sendCustomEvent(name: string, metadata?: Record<string, unknown>): void;
40
- destroy(): void;
41
- private setState;
42
- private setApiUrl;
43
- private setConfig;
44
- private setUserId;
45
- private setDevice;
46
- private setPageUrl;
47
- private setIntegrations;
48
- private initHandlers;
49
- private initStorage;
50
- private setEventManager;
51
- private initSessionHandler;
52
- private initPageViewHandler;
53
- private onPageViewTrack;
54
- private initClickHandler;
55
- private initScrollHandler;
56
- private initPerformanceHandler;
57
- private initErrorHandler;
58
- private initNetworkHandler;
38
+ on<K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>): void;
39
+ off<K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>): void;
40
+ destroy(force?: boolean): Promise<void>;
41
+ private setupState;
42
+ private setupIntegrations;
43
+ private initializeHandlers;
59
44
  }