@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.
- package/README.md +157 -180
- package/dist/browser/tracelog.esm.js +1124 -1377
- package/dist/browser/tracelog.esm.js.map +1 -0
- package/dist/browser/tracelog.js +2 -2
- package/dist/browser/tracelog.js.map +1 -0
- package/dist/cjs/api.d.ts +12 -2
- package/dist/cjs/api.js +74 -29
- package/dist/cjs/app.d.ts +2 -2
- package/dist/cjs/app.js +26 -32
- package/dist/cjs/constants/config.constants.d.ts +7 -2
- package/dist/cjs/constants/config.constants.js +9 -18
- package/dist/cjs/constants/index.d.ts +0 -1
- package/dist/cjs/constants/index.js +0 -1
- package/dist/cjs/constants/storage.constants.d.ts +3 -2
- package/dist/cjs/constants/storage.constants.js +4 -4
- package/dist/cjs/handlers/click.handler.js +3 -6
- package/dist/cjs/handlers/error.handler.js +1 -11
- package/dist/cjs/handlers/page-view.handler.js +0 -4
- package/dist/cjs/handlers/performance.handler.js +14 -29
- package/dist/cjs/handlers/scroll.handler.js +7 -6
- package/dist/cjs/handlers/session.handler.js +7 -6
- package/dist/cjs/integrations/google-analytics.integration.js +2 -6
- package/dist/cjs/listeners/activity-listener-manager.js +3 -3
- package/dist/cjs/listeners/input-listener-managers.js +3 -3
- package/dist/cjs/listeners/touch-listener-manager.js +3 -3
- package/dist/cjs/listeners/unload-listener-manager.js +3 -3
- package/dist/cjs/listeners/visibility-listener-manager.js +3 -3
- package/dist/cjs/managers/event.manager.d.ts +5 -1
- package/dist/cjs/managers/event.manager.js +103 -40
- package/dist/cjs/managers/sender.manager.js +29 -36
- package/dist/cjs/managers/session.manager.js +5 -13
- package/dist/cjs/managers/state.manager.d.ts +0 -3
- package/dist/cjs/managers/state.manager.js +1 -43
- package/dist/cjs/managers/storage.manager.d.ts +21 -2
- package/dist/cjs/managers/storage.manager.js +164 -21
- package/dist/cjs/managers/user.manager.d.ts +1 -1
- package/dist/cjs/managers/user.manager.js +2 -2
- package/dist/cjs/public-api.d.ts +3 -3
- package/dist/cjs/public-api.js +1 -1
- package/dist/cjs/test-bridge.d.ts +1 -0
- package/dist/cjs/test-bridge.js +37 -2
- package/dist/cjs/types/config.types.d.ts +17 -20
- package/dist/cjs/types/config.types.js +6 -0
- package/dist/cjs/types/event.types.d.ts +1 -13
- package/dist/cjs/types/index.d.ts +0 -2
- package/dist/cjs/types/index.js +0 -2
- package/dist/cjs/types/mode.types.d.ts +1 -2
- package/dist/cjs/types/mode.types.js +0 -1
- package/dist/cjs/types/queue.types.d.ts +0 -6
- package/dist/cjs/types/state.types.d.ts +2 -0
- package/dist/cjs/types/test-bridge.types.d.ts +2 -2
- package/dist/cjs/types/validation-error.types.d.ts +0 -6
- package/dist/cjs/types/validation-error.types.js +1 -10
- package/dist/cjs/utils/browser/device-detector.utils.js +2 -24
- package/dist/cjs/utils/browser/index.d.ts +1 -0
- package/dist/cjs/utils/browser/index.js +1 -0
- package/dist/cjs/utils/browser/qa-mode.utils.d.ts +13 -0
- package/dist/cjs/utils/browser/qa-mode.utils.js +43 -0
- package/dist/cjs/utils/browser/utm-params.utils.js +0 -15
- package/dist/cjs/utils/data/uuid.utils.d.ts +13 -0
- package/dist/cjs/utils/data/uuid.utils.js +37 -1
- package/dist/cjs/utils/index.d.ts +1 -1
- package/dist/cjs/utils/index.js +1 -1
- package/dist/cjs/utils/logging.utils.d.ts +21 -0
- package/dist/cjs/utils/logging.utils.js +86 -0
- package/dist/cjs/utils/network/index.d.ts +0 -1
- package/dist/cjs/utils/network/index.js +0 -1
- package/dist/cjs/utils/network/url.utils.d.ts +2 -8
- package/dist/cjs/utils/network/url.utils.js +45 -90
- package/dist/cjs/utils/security/sanitize.utils.d.ts +1 -13
- package/dist/cjs/utils/security/sanitize.utils.js +15 -178
- package/dist/cjs/utils/validations/config-validations.utils.d.ts +3 -9
- package/dist/cjs/utils/validations/config-validations.utils.js +56 -93
- package/dist/cjs/utils/validations/event-validations.utils.js +11 -5
- package/dist/cjs/utils/validations/index.d.ts +0 -1
- package/dist/cjs/utils/validations/index.js +0 -1
- package/dist/cjs/utils/validations/metadata-validations.utils.js +0 -1
- package/dist/cjs/utils/validations/type-guards.utils.d.ts +2 -2
- package/dist/cjs/utils/validations/type-guards.utils.js +50 -4
- package/dist/esm/api.d.ts +12 -2
- package/dist/esm/api.js +73 -29
- package/dist/esm/app.d.ts +2 -2
- package/dist/esm/app.js +28 -34
- package/dist/esm/constants/config.constants.d.ts +7 -2
- package/dist/esm/constants/config.constants.js +7 -16
- package/dist/esm/constants/index.d.ts +0 -1
- package/dist/esm/constants/index.js +0 -1
- package/dist/esm/constants/storage.constants.d.ts +3 -2
- package/dist/esm/constants/storage.constants.js +3 -2
- package/dist/esm/handlers/click.handler.js +3 -6
- package/dist/esm/handlers/error.handler.js +1 -11
- package/dist/esm/handlers/page-view.handler.js +0 -4
- package/dist/esm/handlers/performance.handler.js +14 -29
- package/dist/esm/handlers/scroll.handler.js +7 -6
- package/dist/esm/handlers/session.handler.js +7 -6
- package/dist/esm/integrations/google-analytics.integration.js +3 -7
- package/dist/esm/listeners/activity-listener-manager.js +3 -3
- package/dist/esm/listeners/input-listener-managers.js +3 -3
- package/dist/esm/listeners/touch-listener-manager.js +3 -3
- package/dist/esm/listeners/unload-listener-manager.js +3 -3
- package/dist/esm/listeners/visibility-listener-manager.js +3 -3
- package/dist/esm/managers/event.manager.d.ts +5 -1
- package/dist/esm/managers/event.manager.js +106 -43
- package/dist/esm/managers/sender.manager.js +31 -38
- package/dist/esm/managers/session.manager.js +5 -13
- package/dist/esm/managers/state.manager.d.ts +0 -3
- package/dist/esm/managers/state.manager.js +1 -43
- package/dist/esm/managers/storage.manager.d.ts +21 -2
- package/dist/esm/managers/storage.manager.js +164 -21
- package/dist/esm/managers/user.manager.d.ts +1 -1
- package/dist/esm/managers/user.manager.js +2 -2
- package/dist/esm/public-api.d.ts +3 -3
- package/dist/esm/public-api.js +1 -1
- package/dist/esm/test-bridge.d.ts +1 -0
- package/dist/esm/test-bridge.js +37 -2
- package/dist/esm/types/config.types.d.ts +17 -20
- package/dist/esm/types/config.types.js +5 -1
- package/dist/esm/types/event.types.d.ts +1 -13
- package/dist/esm/types/index.d.ts +0 -2
- package/dist/esm/types/index.js +0 -2
- package/dist/esm/types/mode.types.d.ts +1 -2
- package/dist/esm/types/mode.types.js +0 -1
- package/dist/esm/types/queue.types.d.ts +0 -6
- package/dist/esm/types/state.types.d.ts +2 -0
- package/dist/esm/types/test-bridge.types.d.ts +2 -2
- package/dist/esm/types/validation-error.types.d.ts +0 -6
- package/dist/esm/types/validation-error.types.js +0 -8
- package/dist/esm/utils/browser/device-detector.utils.js +2 -24
- package/dist/esm/utils/browser/index.d.ts +1 -0
- package/dist/esm/utils/browser/index.js +1 -0
- package/dist/esm/utils/browser/qa-mode.utils.d.ts +13 -0
- package/dist/esm/utils/browser/qa-mode.utils.js +39 -0
- package/dist/esm/utils/browser/utm-params.utils.js +0 -15
- package/dist/esm/utils/data/uuid.utils.d.ts +13 -0
- package/dist/esm/utils/data/uuid.utils.js +35 -0
- package/dist/esm/utils/index.d.ts +1 -1
- package/dist/esm/utils/index.js +1 -1
- package/dist/esm/utils/logging.utils.d.ts +21 -0
- package/dist/esm/utils/logging.utils.js +81 -0
- package/dist/esm/utils/network/index.d.ts +0 -1
- package/dist/esm/utils/network/index.js +0 -1
- package/dist/esm/utils/network/url.utils.d.ts +2 -8
- package/dist/esm/utils/network/url.utils.js +44 -88
- package/dist/esm/utils/security/sanitize.utils.d.ts +1 -13
- package/dist/esm/utils/security/sanitize.utils.js +15 -176
- package/dist/esm/utils/validations/config-validations.utils.d.ts +3 -9
- package/dist/esm/utils/validations/config-validations.utils.js +57 -93
- package/dist/esm/utils/validations/event-validations.utils.js +11 -5
- package/dist/esm/utils/validations/index.d.ts +0 -1
- package/dist/esm/utils/validations/index.js +0 -1
- package/dist/esm/utils/validations/metadata-validations.utils.js +0 -1
- package/dist/esm/utils/validations/type-guards.utils.d.ts +2 -2
- package/dist/esm/utils/validations/type-guards.utils.js +50 -4
- package/package.json +3 -2
- package/dist/cjs/app.types.d.ts +0 -2
- package/dist/cjs/app.types.js +0 -12
- package/dist/cjs/constants/api.constants.d.ts +0 -6
- package/dist/cjs/constants/api.constants.js +0 -14
- package/dist/cjs/managers/api.manager.d.ts +0 -13
- package/dist/cjs/managers/api.manager.js +0 -44
- package/dist/cjs/managers/config.builder.d.ts +0 -33
- package/dist/cjs/managers/config.builder.js +0 -116
- package/dist/cjs/managers/config.manager.d.ts +0 -56
- package/dist/cjs/managers/config.manager.js +0 -157
- package/dist/cjs/managers/tags.manager.d.ts +0 -36
- package/dist/cjs/managers/tags.manager.js +0 -171
- package/dist/cjs/types/api.types.d.ts +0 -52
- package/dist/cjs/types/api.types.js +0 -56
- package/dist/cjs/types/tag.types.d.ts +0 -43
- package/dist/cjs/types/tag.types.js +0 -31
- package/dist/cjs/utils/logging/debug-logger.utils.d.ts +0 -14
- package/dist/cjs/utils/logging/debug-logger.utils.js +0 -47
- package/dist/cjs/utils/logging/index.d.ts +0 -1
- package/dist/cjs/utils/logging/index.js +0 -5
- package/dist/cjs/utils/network/fetch-with-timeout.utils.d.ts +0 -4
- package/dist/cjs/utils/network/fetch-with-timeout.utils.js +0 -25
- package/dist/cjs/utils/validations/url-validations.utils.d.ts +0 -15
- package/dist/cjs/utils/validations/url-validations.utils.js +0 -47
- package/dist/esm/app.types.d.ts +0 -2
- package/dist/esm/app.types.js +0 -1
- package/dist/esm/constants/api.constants.d.ts +0 -6
- package/dist/esm/constants/api.constants.js +0 -11
- package/dist/esm/managers/api.manager.d.ts +0 -13
- package/dist/esm/managers/api.manager.js +0 -41
- package/dist/esm/managers/config.builder.d.ts +0 -33
- package/dist/esm/managers/config.builder.js +0 -112
- package/dist/esm/managers/config.manager.d.ts +0 -56
- package/dist/esm/managers/config.manager.js +0 -153
- package/dist/esm/managers/tags.manager.d.ts +0 -36
- package/dist/esm/managers/tags.manager.js +0 -167
- package/dist/esm/types/api.types.d.ts +0 -52
- package/dist/esm/types/api.types.js +0 -53
- package/dist/esm/types/tag.types.d.ts +0 -43
- package/dist/esm/types/tag.types.js +0 -28
- package/dist/esm/utils/logging/debug-logger.utils.d.ts +0 -14
- package/dist/esm/utils/logging/debug-logger.utils.js +0 -44
- package/dist/esm/utils/logging/index.d.ts +0 -1
- package/dist/esm/utils/logging/index.js +0 -1
- package/dist/esm/utils/network/fetch-with-timeout.utils.d.ts +0 -4
- package/dist/esm/utils/network/fetch-with-timeout.utils.js +0 -22
- package/dist/esm/utils/validations/url-validations.utils.d.ts +0 -15
- package/dist/esm/utils/validations/url-validations.utils.js +0 -42
package/dist/cjs/api.d.ts
CHANGED
|
@@ -1,8 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { App } from './app';
|
|
2
|
+
import { MetadataType, Config, EmitterCallback, EmitterMap } from './types';
|
|
2
3
|
import './types/window.types';
|
|
3
|
-
export declare const init: (
|
|
4
|
+
export declare const init: (config: Config) => Promise<void>;
|
|
4
5
|
export declare const event: (name: string, metadata?: Record<string, MetadataType> | Record<string, MetadataType>[]) => void;
|
|
5
6
|
export declare const on: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
|
|
6
7
|
export declare const off: <K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>) => void;
|
|
7
8
|
export declare const isInitialized: () => boolean;
|
|
8
9
|
export declare const destroy: () => Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Internal sync function - ONLY for TestBridge in development
|
|
12
|
+
*
|
|
13
|
+
* WARNING: This function is internal and should NEVER be called directly.
|
|
14
|
+
* It's only exported for TestBridge synchronization in dev mode.
|
|
15
|
+
*
|
|
16
|
+
* @internal
|
|
17
|
+
*/
|
|
18
|
+
export declare const __setAppInstance: (instance: App | null) => void;
|
package/dist/cjs/api.js
CHANGED
|
@@ -1,51 +1,61 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.destroy = exports.isInitialized = exports.off = exports.on = exports.event = exports.init = void 0;
|
|
3
|
+
exports.__setAppInstance = exports.destroy = exports.isInitialized = exports.off = exports.on = exports.event = exports.init = void 0;
|
|
4
4
|
const app_1 = require("./app");
|
|
5
5
|
const utils_1 = require("./utils");
|
|
6
6
|
const test_bridge_1 = require("./test-bridge");
|
|
7
|
+
const constants_1 = require("./constants");
|
|
7
8
|
require("./types/window.types");
|
|
9
|
+
// Buffer for listeners registered before init()
|
|
10
|
+
const pendingListeners = [];
|
|
8
11
|
let app = null;
|
|
9
12
|
let isInitializing = false;
|
|
10
13
|
let isDestroying = false;
|
|
11
|
-
const init = async (
|
|
14
|
+
const init = async (config) => {
|
|
12
15
|
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
13
|
-
throw new Error('This library can only be used in a browser environment');
|
|
16
|
+
throw new Error('[TraceLog] This library can only be used in a browser environment');
|
|
14
17
|
}
|
|
15
18
|
if (window.__traceLogDisabled) {
|
|
16
19
|
return;
|
|
17
20
|
}
|
|
18
21
|
if (app) {
|
|
19
|
-
utils_1.debugLog.debug('API', 'Library already initialized, skipping duplicate initialization');
|
|
20
22
|
return;
|
|
21
23
|
}
|
|
22
24
|
if (isInitializing) {
|
|
23
|
-
|
|
24
|
-
throw new Error('Initialization already in progress');
|
|
25
|
+
return;
|
|
25
26
|
}
|
|
26
27
|
isInitializing = true;
|
|
27
28
|
try {
|
|
28
|
-
|
|
29
|
-
const validatedConfig = (0, utils_1.validateAndNormalizeConfig)(appConfig);
|
|
29
|
+
const validatedConfig = (0, utils_1.validateAndNormalizeConfig)(config);
|
|
30
30
|
const instance = new app_1.App();
|
|
31
31
|
try {
|
|
32
|
-
|
|
32
|
+
// Attach buffered listeners BEFORE init() so they capture initial events
|
|
33
|
+
pendingListeners.forEach(({ event, callback }) => {
|
|
34
|
+
instance.on(event, callback);
|
|
35
|
+
});
|
|
36
|
+
pendingListeners.length = 0;
|
|
37
|
+
// Wrap initialization with timeout using Promise.race
|
|
38
|
+
const initPromise = instance.init(validatedConfig);
|
|
39
|
+
const timeoutPromise = new Promise((_, reject) => {
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
reject(new Error(`[TraceLog] Initialization timeout after ${constants_1.INITIALIZATION_TIMEOUT_MS}ms`));
|
|
42
|
+
}, constants_1.INITIALIZATION_TIMEOUT_MS);
|
|
43
|
+
});
|
|
44
|
+
await Promise.race([initPromise, timeoutPromise]);
|
|
33
45
|
app = instance;
|
|
34
|
-
utils_1.debugLog.info('API', 'TraceLog initialized successfully', { projectId: validatedConfig.id });
|
|
35
46
|
}
|
|
36
47
|
catch (error) {
|
|
37
48
|
try {
|
|
38
49
|
await instance.destroy(true);
|
|
39
50
|
}
|
|
40
51
|
catch (cleanupError) {
|
|
41
|
-
utils_1.
|
|
52
|
+
(0, utils_1.log)('error', 'Failed to cleanup partially initialized app', { error: cleanupError });
|
|
42
53
|
}
|
|
43
54
|
throw error;
|
|
44
55
|
}
|
|
45
56
|
}
|
|
46
57
|
catch (error) {
|
|
47
58
|
app = null;
|
|
48
|
-
utils_1.debugLog.error('API', 'Initialization failed', { error });
|
|
49
59
|
throw error;
|
|
50
60
|
}
|
|
51
61
|
finally {
|
|
@@ -55,27 +65,31 @@ const init = async (appConfig) => {
|
|
|
55
65
|
exports.init = init;
|
|
56
66
|
const event = (name, metadata) => {
|
|
57
67
|
if (!app) {
|
|
58
|
-
throw new Error('TraceLog not initialized. Please call init() first.');
|
|
59
|
-
}
|
|
60
|
-
try {
|
|
61
|
-
app.sendCustomEvent(name, metadata);
|
|
68
|
+
throw new Error('[TraceLog] TraceLog not initialized. Please call init() first.');
|
|
62
69
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
throw error;
|
|
70
|
+
if (isDestroying) {
|
|
71
|
+
throw new Error('[TraceLog] Cannot send events while TraceLog is being destroyed');
|
|
66
72
|
}
|
|
73
|
+
app.sendCustomEvent(name, metadata);
|
|
67
74
|
};
|
|
68
75
|
exports.event = event;
|
|
69
76
|
const on = (event, callback) => {
|
|
70
|
-
if (!app) {
|
|
71
|
-
|
|
77
|
+
if (!app || isInitializing) {
|
|
78
|
+
// Buffer listeners registered before or during init()
|
|
79
|
+
pendingListeners.push({ event, callback });
|
|
80
|
+
return;
|
|
72
81
|
}
|
|
73
82
|
app.on(event, callback);
|
|
74
83
|
};
|
|
75
84
|
exports.on = on;
|
|
76
85
|
const off = (event, callback) => {
|
|
77
86
|
if (!app) {
|
|
78
|
-
|
|
87
|
+
// Remove from pending listeners if not yet initialized
|
|
88
|
+
const index = pendingListeners.findIndex((l) => l.event === event && l.callback === callback);
|
|
89
|
+
if (index !== -1) {
|
|
90
|
+
pendingListeners.splice(index, 1);
|
|
91
|
+
}
|
|
92
|
+
return;
|
|
79
93
|
}
|
|
80
94
|
app.off(event, callback);
|
|
81
95
|
};
|
|
@@ -86,25 +100,30 @@ const isInitialized = () => {
|
|
|
86
100
|
exports.isInitialized = isInitialized;
|
|
87
101
|
const destroy = async () => {
|
|
88
102
|
if (!app) {
|
|
89
|
-
throw new Error('App not initialized');
|
|
103
|
+
throw new Error('[TraceLog] App not initialized');
|
|
90
104
|
}
|
|
91
105
|
if (isDestroying) {
|
|
92
|
-
throw new Error('Destroy operation already in progress');
|
|
106
|
+
throw new Error('[TraceLog] Destroy operation already in progress');
|
|
93
107
|
}
|
|
94
108
|
isDestroying = true;
|
|
95
109
|
try {
|
|
96
|
-
utils_1.debugLog.info('API', 'Destroying TraceLog instance');
|
|
97
110
|
await app.destroy();
|
|
98
111
|
app = null;
|
|
99
112
|
isInitializing = false;
|
|
100
|
-
|
|
113
|
+
pendingListeners.length = 0;
|
|
114
|
+
// Clear TestBridge reference in dev mode to prevent stale references
|
|
115
|
+
if (process.env.NODE_ENV === 'dev' && typeof window !== 'undefined' && window.__traceLogBridge) {
|
|
116
|
+
// Don't call destroy on bridge (would cause recursion), just clear reference
|
|
117
|
+
window.__traceLogBridge = undefined;
|
|
118
|
+
}
|
|
101
119
|
}
|
|
102
120
|
catch (error) {
|
|
103
|
-
// Force cleanup even if destroy fails
|
|
104
121
|
app = null;
|
|
105
122
|
isInitializing = false;
|
|
106
|
-
|
|
107
|
-
throw
|
|
123
|
+
pendingListeners.length = 0;
|
|
124
|
+
// Log error but don't re-throw - destroy should always complete successfully
|
|
125
|
+
// Applications should be able to tear down TraceLog even if internal cleanup fails
|
|
126
|
+
(0, utils_1.log)('warn', 'Error during destroy, forced cleanup completed', { error });
|
|
108
127
|
}
|
|
109
128
|
finally {
|
|
110
129
|
isDestroying = false;
|
|
@@ -122,3 +141,29 @@ if (process.env.NODE_ENV === 'dev' && typeof window !== 'undefined') {
|
|
|
122
141
|
injectTestingBridge();
|
|
123
142
|
}
|
|
124
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Internal sync function - ONLY for TestBridge in development
|
|
146
|
+
*
|
|
147
|
+
* WARNING: This function is internal and should NEVER be called directly.
|
|
148
|
+
* It's only exported for TestBridge synchronization in dev mode.
|
|
149
|
+
*
|
|
150
|
+
* @internal
|
|
151
|
+
*/
|
|
152
|
+
const __setAppInstance = (instance) => {
|
|
153
|
+
if (instance !== null) {
|
|
154
|
+
const hasRequiredMethods = typeof instance === 'object' &&
|
|
155
|
+
'init' in instance &&
|
|
156
|
+
'destroy' in instance &&
|
|
157
|
+
'on' in instance &&
|
|
158
|
+
'off' in instance;
|
|
159
|
+
if (!hasRequiredMethods) {
|
|
160
|
+
throw new Error('[TraceLog] Invalid app instance type');
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
// Prevent overwriting an already initialized app (except when clearing)
|
|
164
|
+
if (app !== null && instance !== null && app !== instance) {
|
|
165
|
+
throw new Error('[TraceLog] Cannot overwrite existing app instance. Call destroy() first.');
|
|
166
|
+
}
|
|
167
|
+
app = instance;
|
|
168
|
+
};
|
|
169
|
+
exports.__setAppInstance = __setAppInstance;
|
package/dist/cjs/app.d.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { SessionHandler } from './handlers/session.handler';
|
|
|
4
4
|
import { PageViewHandler } from './handlers/page-view.handler';
|
|
5
5
|
import { ClickHandler } from './handlers/click.handler';
|
|
6
6
|
import { ScrollHandler } from './handlers/scroll.handler';
|
|
7
|
-
import {
|
|
7
|
+
import { Config, 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';
|
|
@@ -29,7 +29,7 @@ export declare class App extends StateManager {
|
|
|
29
29
|
googleAnalytics?: GoogleAnalyticsIntegration;
|
|
30
30
|
};
|
|
31
31
|
get initialized(): boolean;
|
|
32
|
-
init(
|
|
32
|
+
init(config: Config): Promise<void>;
|
|
33
33
|
sendCustomEvent(name: string, metadata?: Record<string, unknown> | Record<string, unknown>[]): void;
|
|
34
34
|
on<K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>): void;
|
|
35
35
|
off<K extends keyof EmitterMap>(event: K, callback: EmitterCallback<EmitterMap[K]>): void;
|
package/dist/cjs/app.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.App = void 0;
|
|
4
|
-
const api_manager_1 = require("./managers/api.manager");
|
|
5
|
-
const config_manager_1 = require("./managers/config.manager");
|
|
6
4
|
const event_manager_1 = require("./managers/event.manager");
|
|
7
5
|
const user_manager_1 = require("./managers/user.manager");
|
|
8
6
|
const state_manager_1 = require("./managers/state.manager");
|
|
@@ -30,27 +28,25 @@ class App extends state_manager_1.StateManager {
|
|
|
30
28
|
get initialized() {
|
|
31
29
|
return this.isInitialized;
|
|
32
30
|
}
|
|
33
|
-
async init(
|
|
31
|
+
async init(config) {
|
|
34
32
|
if (this.isInitialized) {
|
|
35
33
|
return;
|
|
36
34
|
}
|
|
37
|
-
if (!appConfig.id?.trim()) {
|
|
38
|
-
throw new Error('Project ID is required');
|
|
39
|
-
}
|
|
40
35
|
this.managers.storage = new storage_manager_1.StorageManager();
|
|
41
36
|
try {
|
|
42
|
-
|
|
37
|
+
this.setupState(config);
|
|
43
38
|
await this.setupIntegrations();
|
|
44
39
|
this.managers.event = new event_manager_1.EventManager(this.managers.storage, this.integrations.googleAnalytics, this.emitter);
|
|
45
|
-
this.initializeHandlers();
|
|
46
|
-
await this.managers.event.recoverPersistedEvents().catch(() => {
|
|
47
|
-
utils_1.
|
|
40
|
+
await this.initializeHandlers();
|
|
41
|
+
await this.managers.event.recoverPersistedEvents().catch((error) => {
|
|
42
|
+
(0, utils_1.log)('warn', 'Failed to recover persisted events', { error });
|
|
48
43
|
});
|
|
49
44
|
this.isInitialized = true;
|
|
50
45
|
}
|
|
51
46
|
catch (error) {
|
|
52
47
|
await this.destroy(true);
|
|
53
|
-
|
|
48
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
49
|
+
throw new Error(`[TraceLog] TraceLog initialization failed: ${errorMessage}`);
|
|
54
50
|
}
|
|
55
51
|
}
|
|
56
52
|
sendCustomEvent(name, metadata) {
|
|
@@ -59,9 +55,8 @@ class App extends state_manager_1.StateManager {
|
|
|
59
55
|
}
|
|
60
56
|
const { valid, error, sanitizedMetadata } = (0, utils_1.isEventValid)(name, metadata);
|
|
61
57
|
if (!valid) {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
throw new Error(`Custom event "${name}" validation failed: ${error}`);
|
|
58
|
+
if (this.get('mode') === types_1.Mode.QA) {
|
|
59
|
+
throw new Error(`[TraceLog] Custom event "${name}" validation failed: ${error}`);
|
|
65
60
|
}
|
|
66
61
|
return;
|
|
67
62
|
}
|
|
@@ -90,8 +85,8 @@ class App extends state_manager_1.StateManager {
|
|
|
90
85
|
try {
|
|
91
86
|
await handler.stopTracking();
|
|
92
87
|
}
|
|
93
|
-
catch {
|
|
94
|
-
utils_1.
|
|
88
|
+
catch (error) {
|
|
89
|
+
(0, utils_1.log)('warn', 'Failed to stop tracking', { error });
|
|
95
90
|
}
|
|
96
91
|
});
|
|
97
92
|
await Promise.allSettled(handlerCleanups);
|
|
@@ -108,22 +103,25 @@ class App extends state_manager_1.StateManager {
|
|
|
108
103
|
this.isInitialized = false;
|
|
109
104
|
this.handlers = {};
|
|
110
105
|
}
|
|
111
|
-
|
|
112
|
-
const apiUrl = (0, api_manager_1.getApiUrlForProject)(appConfig.id, appConfig.allowHttp);
|
|
113
|
-
this.set('apiUrl', apiUrl);
|
|
114
|
-
const configManager = new config_manager_1.ConfigManager();
|
|
115
|
-
const config = await configManager.get(apiUrl, appConfig);
|
|
106
|
+
setupState(config) {
|
|
116
107
|
this.set('config', config);
|
|
117
|
-
const userId = user_manager_1.UserManager.getId(this.managers.storage
|
|
108
|
+
const userId = user_manager_1.UserManager.getId(this.managers.storage);
|
|
118
109
|
this.set('userId', userId);
|
|
119
|
-
|
|
110
|
+
const apiUrl = (0, utils_1.getApiUrl)(config);
|
|
111
|
+
this.set('apiUrl', apiUrl);
|
|
112
|
+
const device = (0, utils_1.getDeviceType)();
|
|
113
|
+
this.set('device', device);
|
|
120
114
|
const pageUrl = (0, utils_1.normalizeUrl)(window.location.href, config.sensitiveQueryParams);
|
|
121
115
|
this.set('pageUrl', pageUrl);
|
|
116
|
+
const mode = (0, utils_1.detectQaMode)() ? types_1.Mode.QA : undefined;
|
|
117
|
+
if (mode) {
|
|
118
|
+
this.set('mode', mode);
|
|
119
|
+
}
|
|
122
120
|
}
|
|
123
121
|
async setupIntegrations() {
|
|
124
122
|
const config = this.get('config');
|
|
125
123
|
const measurementId = config.integrations?.googleAnalytics?.measurementId;
|
|
126
|
-
if (
|
|
124
|
+
if (measurementId?.trim()) {
|
|
127
125
|
try {
|
|
128
126
|
this.integrations.googleAnalytics = new google_analytics_integration_1.GoogleAnalyticsIntegration();
|
|
129
127
|
await this.integrations.googleAnalytics.initialize();
|
|
@@ -133,13 +131,9 @@ class App extends state_manager_1.StateManager {
|
|
|
133
131
|
}
|
|
134
132
|
}
|
|
135
133
|
}
|
|
136
|
-
initializeHandlers() {
|
|
134
|
+
async initializeHandlers() {
|
|
137
135
|
this.handlers.session = new session_handler_1.SessionHandler(this.managers.storage, this.managers.event);
|
|
138
|
-
this.handlers.session.startTracking()
|
|
139
|
-
utils_1.debugLog.error('App', 'Session handler failed to start', {
|
|
140
|
-
message: error instanceof Error ? error.message : 'Unknown error',
|
|
141
|
-
});
|
|
142
|
-
});
|
|
136
|
+
await this.handlers.session.startTracking();
|
|
143
137
|
const onPageView = () => {
|
|
144
138
|
this.set('suppressNextScroll', true);
|
|
145
139
|
if (this.suppressNextScrollTimer) {
|
|
@@ -156,8 +150,8 @@ class App extends state_manager_1.StateManager {
|
|
|
156
150
|
this.handlers.scroll = new scroll_handler_1.ScrollHandler(this.managers.event);
|
|
157
151
|
this.handlers.scroll.startTracking();
|
|
158
152
|
this.handlers.performance = new performance_handler_1.PerformanceHandler(this.managers.event);
|
|
159
|
-
this.handlers.performance.startTracking().catch(() => {
|
|
160
|
-
utils_1.
|
|
153
|
+
this.handlers.performance.startTracking().catch((error) => {
|
|
154
|
+
(0, utils_1.log)('warn', 'Failed to start performance tracking', { error });
|
|
161
155
|
});
|
|
162
156
|
this.handlers.error = new error_handler_1.ErrorHandler(this.managers.event);
|
|
163
157
|
this.handlers.error.startTracking();
|
|
@@ -22,13 +22,17 @@ export declare const MAX_SCROLL_EVENTS_PER_SESSION = 120;
|
|
|
22
22
|
export declare const DEFAULT_SAMPLING_RATE = 1;
|
|
23
23
|
export declare const MIN_SAMPLING_RATE = 0;
|
|
24
24
|
export declare const MAX_SAMPLING_RATE = 1;
|
|
25
|
+
export declare const RATE_LIMIT_WINDOW_MS = 1000;
|
|
26
|
+
export declare const MAX_EVENTS_PER_SECOND = 200;
|
|
25
27
|
export declare const BATCH_SIZE_THRESHOLD = 50;
|
|
28
|
+
export declare const MAX_PENDING_EVENTS_BUFFER = 100;
|
|
26
29
|
export declare const MIN_SESSION_TIMEOUT_MS = 30000;
|
|
27
30
|
export declare const MAX_SESSION_TIMEOUT_MS = 86400000;
|
|
28
31
|
export declare const MAX_CUSTOM_EVENT_NAME_LENGTH = 120;
|
|
29
32
|
export declare const MAX_CUSTOM_EVENT_STRING_SIZE: number;
|
|
30
33
|
export declare const MAX_CUSTOM_EVENT_KEYS = 10;
|
|
31
34
|
export declare const MAX_CUSTOM_EVENT_ARRAY_SIZE = 10;
|
|
35
|
+
export declare const MAX_NESTED_OBJECT_KEYS = 20;
|
|
32
36
|
export declare const MAX_TEXT_LENGTH = 255;
|
|
33
37
|
export declare const MAX_STRING_LENGTH = 1000;
|
|
34
38
|
export declare const MAX_ARRAY_LENGTH = 100;
|
|
@@ -38,7 +42,7 @@ export declare const SYNC_XHR_TIMEOUT_MS = 2000;
|
|
|
38
42
|
export declare const MAX_FINGERPRINTS = 1000;
|
|
39
43
|
export declare const FINGERPRINT_CLEANUP_MULTIPLIER = 10;
|
|
40
44
|
export declare const MAX_FINGERPRINTS_HARD_LIMIT = 2000;
|
|
41
|
-
export declare const HTML_DATA_ATTR_PREFIX = "data-
|
|
45
|
+
export declare const HTML_DATA_ATTR_PREFIX = "data-tlog";
|
|
42
46
|
export declare const INTERACTIVE_SELECTORS: readonly ["button", "a", "input[type=\"button\"]", "input[type=\"submit\"]", "input[type=\"reset\"]", "input[type=\"checkbox\"]", "input[type=\"radio\"]", "select", "textarea", "[role=\"button\"]", "[role=\"link\"]", "[role=\"tab\"]", "[role=\"menuitem\"]", "[role=\"option\"]", "[role=\"checkbox\"]", "[role=\"radio\"]", "[role=\"switch\"]", "[routerLink]", "[ng-click]", "[data-action]", "[data-click]", "[data-navigate]", "[data-toggle]", "[onclick]", ".btn", ".button", ".clickable", ".nav-link", ".menu-item", "[data-testid]", "[tabindex=\"0\"]"];
|
|
43
47
|
export declare const UTM_PARAMS: string[];
|
|
44
48
|
export declare const INITIALIZATION_MAX_CONCURRENT_RETRIES = 20;
|
|
@@ -60,13 +64,14 @@ export declare const RETRY_BACKOFF_INITIAL = 1000;
|
|
|
60
64
|
export declare const RETRY_BACKOFF_MAX = 30000;
|
|
61
65
|
export declare const RATE_LIMIT_INTERVAL = 1000;
|
|
62
66
|
export declare const MAX_RETRY_ATTEMPTS = 10;
|
|
63
|
-
export declare const ALLOWED_API_CONFIG_KEYS: Set<"mode" | "samplingRate" | "excludedUrlPaths" | keyof import("../types").ExclusiveApiConfig>;
|
|
64
67
|
export declare const VALIDATION_MESSAGES: {
|
|
65
68
|
readonly MISSING_PROJECT_ID: "Project ID is required";
|
|
66
69
|
readonly PROJECT_ID_EMPTY_AFTER_TRIM: "Project ID is required";
|
|
67
70
|
readonly INVALID_SESSION_TIMEOUT: "Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)";
|
|
68
71
|
readonly INVALID_SAMPLING_RATE: "Sampling rate must be between 0 and 1";
|
|
69
72
|
readonly INVALID_ERROR_SAMPLING_RATE: "Error sampling must be between 0 and 1";
|
|
73
|
+
readonly INVALID_TRACELOG_PROJECT_ID: "TraceLog project ID is required when integration is enabled";
|
|
74
|
+
readonly INVALID_CUSTOM_API_URL: "Custom API URL is required when integration is enabled";
|
|
70
75
|
readonly INVALID_GOOGLE_ANALYTICS_ID: "Google Analytics measurement ID is required when integration is enabled";
|
|
71
76
|
readonly INVALID_SCROLL_CONTAINER_SELECTORS: "Scroll container selectors must be valid CSS selectors";
|
|
72
77
|
readonly INVALID_GLOBAL_METADATA: "Global metadata must be an object";
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* This file centralizes all timing, limits, browser, and initialization constants
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.
|
|
8
|
-
exports.XSS_PATTERNS = exports.VALIDATION_MESSAGES = exports.
|
|
7
|
+
exports.CROSS_TAB_INITIALIZATION_LOCK_TIMEOUT_MS = exports.SESSION_CLEANUP_DELAY_MS = exports.SESSION_MAX_RETRY_ATTEMPTS = exports.SESSION_SYNC_TIMEOUT_MS = exports.INITIALIZATION_TIMEOUT_MS = exports.INITIALIZATION_CONCURRENT_RETRY_DELAY_MS = exports.INITIALIZATION_MAX_CONCURRENT_RETRIES = exports.UTM_PARAMS = exports.INTERACTIVE_SELECTORS = exports.HTML_DATA_ATTR_PREFIX = exports.MAX_FINGERPRINTS_HARD_LIMIT = exports.FINGERPRINT_CLEANUP_MULTIPLIER = exports.MAX_FINGERPRINTS = exports.SYNC_XHR_TIMEOUT_MS = exports.PRECISION_TWO_DECIMALS = exports.MAX_OBJECT_DEPTH = exports.MAX_ARRAY_LENGTH = exports.MAX_STRING_LENGTH = exports.MAX_TEXT_LENGTH = exports.MAX_NESTED_OBJECT_KEYS = exports.MAX_CUSTOM_EVENT_ARRAY_SIZE = exports.MAX_CUSTOM_EVENT_KEYS = exports.MAX_CUSTOM_EVENT_STRING_SIZE = exports.MAX_CUSTOM_EVENT_NAME_LENGTH = exports.MAX_SESSION_TIMEOUT_MS = exports.MIN_SESSION_TIMEOUT_MS = exports.MAX_PENDING_EVENTS_BUFFER = exports.BATCH_SIZE_THRESHOLD = exports.MAX_EVENTS_PER_SECOND = exports.RATE_LIMIT_WINDOW_MS = exports.MAX_SAMPLING_RATE = exports.MIN_SAMPLING_RATE = exports.DEFAULT_SAMPLING_RATE = exports.MAX_SCROLL_EVENTS_PER_SESSION = exports.SCROLL_MIN_EVENT_INTERVAL_MS = exports.MIN_SCROLL_DEPTH_CHANGE = exports.SIGNIFICANT_SCROLL_DELTA = exports.DEFAULT_MOTION_THRESHOLD = exports.MAX_METADATA_SIZE = exports.REQUEST_TIMEOUT_MS = exports.RETRY_DELAY_MS = exports.MAX_RETRIES = exports.MAX_EVENTS_QUEUE_LENGTH = exports.EVENT_PERSISTENCE_MAX_AGE_MS = exports.EVENT_EXPIRY_HOURS = exports.DEFAULT_VISIBILITY_TIMEOUT_MS = exports.SCROLL_DEBOUNCE_TIME_MS = exports.EVENT_SENT_INTERVAL_MS = exports.DUPLICATE_EVENT_THRESHOLD_MS = exports.DEFAULT_SESSION_TIMEOUT = void 0;
|
|
8
|
+
exports.XSS_PATTERNS = exports.VALIDATION_MESSAGES = exports.MAX_RETRY_ATTEMPTS = exports.RATE_LIMIT_INTERVAL = exports.RETRY_BACKOFF_MAX = exports.RETRY_BACKOFF_INITIAL = exports.SCROLL_SUPPRESS_MULTIPLIER = exports.MIN_SESSION_RECOVERY_WINDOW_MS = exports.MAX_SESSION_RECOVERY_WINDOW_MS = exports.MAX_SESSION_RECOVERY_ATTEMPTS = exports.SESSION_RECOVERY_WINDOW_MULTIPLIER = exports.TAB_CLEANUP_DELAY_MS = exports.TAB_ELECTION_TIMEOUT_MS = exports.TAB_HEARTBEAT_INTERVAL_MS = void 0;
|
|
9
9
|
// ============================================================================
|
|
10
10
|
// SESSION & TIMING
|
|
11
11
|
// ============================================================================
|
|
@@ -36,8 +36,11 @@ exports.MAX_SCROLL_EVENTS_PER_SESSION = 120;
|
|
|
36
36
|
exports.DEFAULT_SAMPLING_RATE = 1;
|
|
37
37
|
exports.MIN_SAMPLING_RATE = 0;
|
|
38
38
|
exports.MAX_SAMPLING_RATE = 1;
|
|
39
|
+
exports.RATE_LIMIT_WINDOW_MS = 1000; // 1 second window
|
|
40
|
+
exports.MAX_EVENTS_PER_SECOND = 200; // Maximum 200 events per second
|
|
39
41
|
// Queue and batch limits
|
|
40
42
|
exports.BATCH_SIZE_THRESHOLD = 50;
|
|
43
|
+
exports.MAX_PENDING_EVENTS_BUFFER = 100; // Maximum events to buffer before session init
|
|
41
44
|
// Session timeout validation limits
|
|
42
45
|
exports.MIN_SESSION_TIMEOUT_MS = 30000; // 30 seconds minimum
|
|
43
46
|
exports.MAX_SESSION_TIMEOUT_MS = 86400000; // 24 hours maximum
|
|
@@ -46,6 +49,7 @@ exports.MAX_CUSTOM_EVENT_NAME_LENGTH = 120;
|
|
|
46
49
|
exports.MAX_CUSTOM_EVENT_STRING_SIZE = 8 * 1024; // 8KB
|
|
47
50
|
exports.MAX_CUSTOM_EVENT_KEYS = 10;
|
|
48
51
|
exports.MAX_CUSTOM_EVENT_ARRAY_SIZE = 10;
|
|
52
|
+
exports.MAX_NESTED_OBJECT_KEYS = 20; // Maximum keys in nested objects within arrays
|
|
49
53
|
// Text content limits
|
|
50
54
|
exports.MAX_TEXT_LENGTH = 255; // For click tracking text content
|
|
51
55
|
// Data sanitization limits
|
|
@@ -63,7 +67,7 @@ exports.MAX_FINGERPRINTS_HARD_LIMIT = 2000; // Hard limit for aggressive cleanup
|
|
|
63
67
|
// ============================================================================
|
|
64
68
|
// BROWSER & HTML
|
|
65
69
|
// ============================================================================
|
|
66
|
-
exports.HTML_DATA_ATTR_PREFIX = 'data-
|
|
70
|
+
exports.HTML_DATA_ATTR_PREFIX = 'data-tlog';
|
|
67
71
|
// Interactive element selectors for click tracking
|
|
68
72
|
exports.INTERACTIVE_SELECTORS = [
|
|
69
73
|
'button',
|
|
@@ -137,31 +141,18 @@ exports.MAX_RETRY_ATTEMPTS = 10;
|
|
|
137
141
|
// ============================================================================
|
|
138
142
|
// VALIDATION
|
|
139
143
|
// ============================================================================
|
|
140
|
-
// Allowed API config keys for runtime validation
|
|
141
|
-
exports.ALLOWED_API_CONFIG_KEYS = new Set([
|
|
142
|
-
'mode',
|
|
143
|
-
'tags',
|
|
144
|
-
'samplingRate',
|
|
145
|
-
'excludedUrlPaths',
|
|
146
|
-
'ipExcluded',
|
|
147
|
-
]);
|
|
148
144
|
// Validation error messages - standardized across all layers
|
|
149
145
|
exports.VALIDATION_MESSAGES = {
|
|
150
|
-
// Project ID validation - consistent message across all layers
|
|
151
146
|
MISSING_PROJECT_ID: 'Project ID is required',
|
|
152
147
|
PROJECT_ID_EMPTY_AFTER_TRIM: 'Project ID is required',
|
|
153
|
-
// Session timeout validation
|
|
154
148
|
INVALID_SESSION_TIMEOUT: `Session timeout must be between ${exports.MIN_SESSION_TIMEOUT_MS}ms (30 seconds) and ${exports.MAX_SESSION_TIMEOUT_MS}ms (24 hours)`,
|
|
155
|
-
// Sampling rate validation
|
|
156
149
|
INVALID_SAMPLING_RATE: 'Sampling rate must be between 0 and 1',
|
|
157
150
|
INVALID_ERROR_SAMPLING_RATE: 'Error sampling must be between 0 and 1',
|
|
158
|
-
|
|
151
|
+
INVALID_TRACELOG_PROJECT_ID: 'TraceLog project ID is required when integration is enabled',
|
|
152
|
+
INVALID_CUSTOM_API_URL: 'Custom API URL is required when integration is enabled',
|
|
159
153
|
INVALID_GOOGLE_ANALYTICS_ID: 'Google Analytics measurement ID is required when integration is enabled',
|
|
160
|
-
// UI validation
|
|
161
154
|
INVALID_SCROLL_CONTAINER_SELECTORS: 'Scroll container selectors must be valid CSS selectors',
|
|
162
|
-
// Global metadata validation
|
|
163
155
|
INVALID_GLOBAL_METADATA: 'Global metadata must be an object',
|
|
164
|
-
// Array validation
|
|
165
156
|
INVALID_SENSITIVE_QUERY_PARAMS: 'Sensitive query params must be an array of strings',
|
|
166
157
|
};
|
|
167
158
|
// ============================================================================
|
|
@@ -14,7 +14,6 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./api.constants"), exports);
|
|
18
17
|
__exportStar(require("./config.constants"), exports);
|
|
19
18
|
__exportStar(require("./storage.constants"), exports);
|
|
20
19
|
__exportStar(require("./performance.constants"), exports);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
export declare const STORAGE_BASE_KEY = "
|
|
2
|
-
export declare const
|
|
1
|
+
export declare const STORAGE_BASE_KEY = "tlog";
|
|
2
|
+
export declare const QA_MODE_KEY = "tlog:qa_mode";
|
|
3
|
+
export declare const USER_ID_KEY = "tlog:uid";
|
|
3
4
|
export declare const QUEUE_KEY: (id: string) => string;
|
|
4
5
|
export declare const SESSION_STORAGE_KEY: (id: string) => string;
|
|
5
6
|
export declare const CROSS_TAB_SESSION_KEY: (id: string) => string;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.BROADCAST_CHANNEL_NAME = exports.SESSION_RECOVERY_KEY = exports.TAB_SPECIFIC_INFO_KEY = exports.TAB_INFO_KEY = exports.CROSS_TAB_SESSION_KEY = exports.SESSION_STORAGE_KEY = exports.QUEUE_KEY = exports.USER_ID_KEY = exports.STORAGE_BASE_KEY = void 0;
|
|
4
|
-
exports.STORAGE_BASE_KEY = '
|
|
5
|
-
|
|
6
|
-
exports.USER_ID_KEY =
|
|
3
|
+
exports.BROADCAST_CHANNEL_NAME = exports.SESSION_RECOVERY_KEY = exports.TAB_SPECIFIC_INFO_KEY = exports.TAB_INFO_KEY = exports.CROSS_TAB_SESSION_KEY = exports.SESSION_STORAGE_KEY = exports.QUEUE_KEY = exports.USER_ID_KEY = exports.QA_MODE_KEY = exports.STORAGE_BASE_KEY = void 0;
|
|
4
|
+
exports.STORAGE_BASE_KEY = 'tlog';
|
|
5
|
+
exports.QA_MODE_KEY = `${exports.STORAGE_BASE_KEY}:qa_mode`;
|
|
6
|
+
exports.USER_ID_KEY = `${exports.STORAGE_BASE_KEY}:uid`;
|
|
7
7
|
const QUEUE_KEY = (id) => (id ? `${exports.STORAGE_BASE_KEY}:${id}:queue` : `${exports.STORAGE_BASE_KEY}:queue`);
|
|
8
8
|
exports.QUEUE_KEY = QUEUE_KEY;
|
|
9
9
|
const SESSION_STORAGE_KEY = (id) => id ? `${exports.STORAGE_BASE_KEY}:${id}:session` : `${exports.STORAGE_BASE_KEY}:session`;
|
|
@@ -4,7 +4,7 @@ exports.ClickHandler = 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
|
|
7
|
+
const utils_1 = require("@/utils");
|
|
8
8
|
class ClickHandler extends state_manager_1.StateManager {
|
|
9
9
|
constructor(eventManager) {
|
|
10
10
|
super();
|
|
@@ -23,7 +23,7 @@ class ClickHandler extends state_manager_1.StateManager {
|
|
|
23
23
|
? target.parentElement
|
|
24
24
|
: null;
|
|
25
25
|
if (!clickedElement) {
|
|
26
|
-
|
|
26
|
+
(0, utils_1.log)('warn', 'Click target not found or not an element');
|
|
27
27
|
return;
|
|
28
28
|
}
|
|
29
29
|
const trackingElement = this.findTrackingElement(clickedElement);
|
|
@@ -75,10 +75,7 @@ class ClickHandler extends state_manager_1.StateManager {
|
|
|
75
75
|
}
|
|
76
76
|
}
|
|
77
77
|
catch (error) {
|
|
78
|
-
|
|
79
|
-
selector,
|
|
80
|
-
error: error instanceof Error ? error.message : 'Unknown error',
|
|
81
|
-
});
|
|
78
|
+
(0, utils_1.log)('warn', 'Invalid selector in element search', { error, data: { selector } });
|
|
82
79
|
continue;
|
|
83
80
|
}
|
|
84
81
|
}
|
|
@@ -4,7 +4,6 @@ exports.ErrorHandler = void 0;
|
|
|
4
4
|
const state_manager_1 = require("../managers/state.manager");
|
|
5
5
|
const types_1 = require("../types");
|
|
6
6
|
const error_constants_1 = require("../constants/error.constants");
|
|
7
|
-
const logging_1 = require("../utils/logging");
|
|
8
7
|
/**
|
|
9
8
|
* Simplified error handler for tracking JavaScript errors and unhandled promise rejections
|
|
10
9
|
* Includes PII sanitization and sampling support
|
|
@@ -21,11 +20,6 @@ class ErrorHandler extends state_manager_1.StateManager {
|
|
|
21
20
|
if (this.shouldSuppressError(types_1.ErrorType.JS_ERROR, sanitizedMessage)) {
|
|
22
21
|
return;
|
|
23
22
|
}
|
|
24
|
-
logging_1.debugLog.warn('ErrorHandler', 'JS error captured', {
|
|
25
|
-
message: sanitizedMessage,
|
|
26
|
-
filename: event.filename,
|
|
27
|
-
line: event.lineno,
|
|
28
|
-
});
|
|
29
23
|
this.eventManager.track({
|
|
30
24
|
type: types_1.EventType.ERROR,
|
|
31
25
|
error_data: {
|
|
@@ -46,7 +40,6 @@ class ErrorHandler extends state_manager_1.StateManager {
|
|
|
46
40
|
if (this.shouldSuppressError(types_1.ErrorType.PROMISE_REJECTION, sanitizedMessage)) {
|
|
47
41
|
return;
|
|
48
42
|
}
|
|
49
|
-
logging_1.debugLog.warn('ErrorHandler', 'Promise rejection captured', { message: sanitizedMessage });
|
|
50
43
|
this.eventManager.track({
|
|
51
44
|
type: types_1.EventType.ERROR,
|
|
52
45
|
error_data: {
|
|
@@ -110,10 +103,7 @@ class ErrorHandler extends state_manager_1.StateManager {
|
|
|
110
103
|
}
|
|
111
104
|
this.recentErrors.set(key, now);
|
|
112
105
|
if (this.recentErrors.size > error_constants_1.MAX_TRACKED_ERRORS_HARD_LIMIT) {
|
|
113
|
-
|
|
114
|
-
size: this.recentErrors.size,
|
|
115
|
-
limit: error_constants_1.MAX_TRACKED_ERRORS_HARD_LIMIT,
|
|
116
|
-
});
|
|
106
|
+
// Hard limit exceeded, clearing all tracked errors
|
|
117
107
|
this.recentErrors.clear();
|
|
118
108
|
this.recentErrors.set(key, now);
|
|
119
109
|
return false;
|
|
@@ -4,7 +4,6 @@ exports.PageViewHandler = void 0;
|
|
|
4
4
|
const types_1 = require("../types");
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
const state_manager_1 = require("../managers/state.manager");
|
|
7
|
-
const logging_1 = require("../utils/logging");
|
|
8
7
|
class PageViewHandler extends state_manager_1.StateManager {
|
|
9
8
|
constructor(eventManager, onTrack) {
|
|
10
9
|
super();
|
|
@@ -16,7 +15,6 @@ class PageViewHandler extends state_manager_1.StateManager {
|
|
|
16
15
|
}
|
|
17
16
|
this.onTrack();
|
|
18
17
|
const fromUrl = this.get('pageUrl');
|
|
19
|
-
logging_1.debugLog.debug('PageViewHandler', 'Page navigation detected', { from: fromUrl, to: normalizedUrl });
|
|
20
18
|
this.set('pageUrl', normalizedUrl);
|
|
21
19
|
const pageViewData = this.extractPageViewData();
|
|
22
20
|
this.eventManager.track({
|
|
@@ -30,7 +28,6 @@ class PageViewHandler extends state_manager_1.StateManager {
|
|
|
30
28
|
this.onTrack = onTrack;
|
|
31
29
|
}
|
|
32
30
|
startTracking() {
|
|
33
|
-
logging_1.debugLog.debug('PageViewHandler', 'Starting page view tracking');
|
|
34
31
|
this.trackInitialPageView();
|
|
35
32
|
window.addEventListener('popstate', this.trackCurrentPage, true);
|
|
36
33
|
window.addEventListener('hashchange', this.trackCurrentPage, true);
|
|
@@ -38,7 +35,6 @@ class PageViewHandler extends state_manager_1.StateManager {
|
|
|
38
35
|
this.patchHistory('replaceState');
|
|
39
36
|
}
|
|
40
37
|
stopTracking() {
|
|
41
|
-
logging_1.debugLog.debug('PageViewHandler', 'Stopping page view tracking');
|
|
42
38
|
window.removeEventListener('popstate', this.trackCurrentPage, true);
|
|
43
39
|
window.removeEventListener('hashchange', this.trackCurrentPage, true);
|
|
44
40
|
if (this.originalPushState) {
|