@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.
- package/README.md +157 -180
- package/dist/browser/tracelog.esm.js +1007 -1357
- package/dist/browser/tracelog.js +2 -2
- package/dist/cjs/api.d.ts +12 -2
- package/dist/cjs/api.js +63 -27
- package/dist/cjs/app.d.ts +2 -2
- package/dist/cjs/app.js +26 -32
- package/dist/cjs/constants/config.constants.d.ts +4 -2
- package/dist/cjs/constants/config.constants.js +6 -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 +2 -1
- package/dist/cjs/managers/event.manager.js +60 -38
- 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 +16 -2
- package/dist/cjs/managers/storage.manager.js +73 -19
- 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 +15 -18
- 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 +6 -0
- package/dist/cjs/utils/logging.utils.js +25 -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 +46 -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 +48 -94
- 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 +62 -27
- package/dist/esm/app.d.ts +2 -2
- package/dist/esm/app.js +28 -34
- package/dist/esm/constants/config.constants.d.ts +4 -2
- package/dist/esm/constants/config.constants.js +4 -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 +2 -1
- package/dist/esm/managers/event.manager.js +62 -40
- 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 +16 -2
- package/dist/esm/managers/storage.manager.js +73 -19
- 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 +15 -18
- 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 +6 -0
- package/dist/esm/utils/logging.utils.js +20 -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 +45 -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 +49 -94
- 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 +1 -1
- 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
|
@@ -1,18 +1,5 @@
|
|
|
1
1
|
import { MetadataType } from './common.types';
|
|
2
|
-
|
|
3
|
-
import { Mode } from './mode.types';
|
|
4
|
-
export type Config = AppConfig & ExclusiveApiConfig;
|
|
5
|
-
export type ApiConfig = SharedConfig & ExclusiveApiConfig;
|
|
6
|
-
export type SharedConfig = Pick<AppConfig, 'mode' | 'samplingRate' | 'excludedUrlPaths'>;
|
|
7
|
-
export interface ExclusiveApiConfig {
|
|
8
|
-
/** Tag definitions used to categorize tracked events. */
|
|
9
|
-
tags?: TagConfig[];
|
|
10
|
-
/** Determines if IP address is excluded from tracking. */
|
|
11
|
-
ipExcluded?: boolean;
|
|
12
|
-
}
|
|
13
|
-
export interface AppConfig {
|
|
14
|
-
/** Project identifier used for tracing. */
|
|
15
|
-
id: string;
|
|
2
|
+
export interface Config {
|
|
16
3
|
/** Session inactivity timeout in milliseconds. @default 900000 */
|
|
17
4
|
sessionTimeout?: number;
|
|
18
5
|
/** Metadata appended to every tracked event. */
|
|
@@ -25,14 +12,20 @@ export interface AppConfig {
|
|
|
25
12
|
sensitiveQueryParams?: string[];
|
|
26
13
|
/** Error event sampling rate between 0 and 1. */
|
|
27
14
|
errorSampling?: number;
|
|
28
|
-
/** Logging mode controlling verbosity of client logs. */
|
|
29
|
-
mode?: Mode;
|
|
30
15
|
/** Event sampling rate between 0 and 1. */
|
|
31
16
|
samplingRate?: number;
|
|
32
|
-
/** URL path patterns that should be ignored by tracking. */
|
|
33
|
-
excludedUrlPaths?: string[];
|
|
34
17
|
/** Optional configuration for third-party integrations. */
|
|
35
18
|
integrations?: {
|
|
19
|
+
/** TraceLog integration options. */
|
|
20
|
+
tracelog?: {
|
|
21
|
+
/** Required project ID TraceLog SaaS integration. */
|
|
22
|
+
projectId: string;
|
|
23
|
+
};
|
|
24
|
+
/** Custom integration options. */
|
|
25
|
+
custom?: {
|
|
26
|
+
/** Required API URL for custom integration. */
|
|
27
|
+
apiUrl: string;
|
|
28
|
+
};
|
|
36
29
|
/** Google Analytics integration options. */
|
|
37
30
|
googleAnalytics?: {
|
|
38
31
|
/** Required measurement ID for Google Analytics. */
|
|
@@ -40,3 +33,7 @@ export interface AppConfig {
|
|
|
40
33
|
};
|
|
41
34
|
};
|
|
42
35
|
}
|
|
36
|
+
export declare enum SpecialApiUrl {
|
|
37
|
+
Localhost = "localhost:8080",
|
|
38
|
+
Fail = "localhost:9999"
|
|
39
|
+
}
|
|
@@ -74,15 +74,8 @@ export interface PageViewData {
|
|
|
74
74
|
search?: string;
|
|
75
75
|
hash?: string;
|
|
76
76
|
}
|
|
77
|
-
export interface EventLocation {
|
|
78
|
-
country: string;
|
|
79
|
-
country_code: string;
|
|
80
|
-
}
|
|
81
|
-
export interface VitalSample {
|
|
82
|
-
type: WebVitalType;
|
|
83
|
-
value: number;
|
|
84
|
-
}
|
|
85
77
|
export interface EventData {
|
|
78
|
+
id: string;
|
|
86
79
|
type: EventType;
|
|
87
80
|
page_url: string;
|
|
88
81
|
timestamp: number;
|
|
@@ -96,9 +89,4 @@ export interface EventData {
|
|
|
96
89
|
session_end_reason?: SessionEndReason;
|
|
97
90
|
error_data?: ErrorData;
|
|
98
91
|
utm?: UTM;
|
|
99
|
-
location?: EventLocation;
|
|
100
|
-
tags?: string[] | {
|
|
101
|
-
id: string;
|
|
102
|
-
key: string;
|
|
103
|
-
}[];
|
|
104
92
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from './api.types';
|
|
2
1
|
export * from './common.types';
|
|
3
2
|
export * from './config.types';
|
|
4
3
|
export * from './device.types';
|
|
@@ -9,7 +8,6 @@ export * from './mode.types';
|
|
|
9
8
|
export * from './queue.types';
|
|
10
9
|
export * from './session.types';
|
|
11
10
|
export * from './state.types';
|
|
12
|
-
export * from './tag.types';
|
|
13
11
|
export * from './test-bridge.types';
|
|
14
12
|
export * from './validation-error.types';
|
|
15
13
|
export * from './window.types';
|
package/dist/esm/types/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
export * from './api.types';
|
|
2
1
|
export * from './common.types';
|
|
3
2
|
export * from './config.types';
|
|
4
3
|
export * from './device.types';
|
|
@@ -9,7 +8,6 @@ export * from './mode.types';
|
|
|
9
8
|
export * from './queue.types';
|
|
10
9
|
export * from './session.types';
|
|
11
10
|
export * from './state.types';
|
|
12
|
-
export * from './tag.types';
|
|
13
11
|
export * from './test-bridge.types';
|
|
14
12
|
export * from './validation-error.types';
|
|
15
13
|
export * from './window.types';
|
|
@@ -8,11 +8,6 @@ export interface BaseEventsQueueDto {
|
|
|
8
8
|
events: EventData[];
|
|
9
9
|
global_metadata?: Record<string, MetadataType>;
|
|
10
10
|
}
|
|
11
|
-
export interface ExtendedEventsQueueDto extends BaseEventsQueueDto {
|
|
12
|
-
project: string;
|
|
13
|
-
source: string;
|
|
14
|
-
ip: string;
|
|
15
|
-
}
|
|
16
11
|
export interface PersistedQueueData {
|
|
17
12
|
userId: string;
|
|
18
13
|
sessionId: string;
|
|
@@ -20,5 +15,4 @@ export interface PersistedQueueData {
|
|
|
20
15
|
events: BaseEventsQueueDto['events'];
|
|
21
16
|
timestamp: number;
|
|
22
17
|
global_metadata?: BaseEventsQueueDto['global_metadata'];
|
|
23
|
-
fallbackMode?: boolean;
|
|
24
18
|
}
|
|
@@ -7,7 +7,7 @@ import { SessionHandler } from '@/handlers/session.handler';
|
|
|
7
7
|
import { GoogleAnalyticsIntegration } from '@/integrations/google-analytics.integration';
|
|
8
8
|
import { EventManager } from '@/managers/event.manager';
|
|
9
9
|
import { StorageManager as TraceLogStorageManager } from '@/managers/storage.manager';
|
|
10
|
-
import {
|
|
10
|
+
import { Config } from './config.types';
|
|
11
11
|
import { State } from './state.types';
|
|
12
12
|
/**
|
|
13
13
|
* Testing bridge interface for E2E tests
|
|
@@ -15,7 +15,7 @@ import { State } from './state.types';
|
|
|
15
15
|
*/
|
|
16
16
|
export interface TraceLogTestBridge {
|
|
17
17
|
readonly initialized: boolean;
|
|
18
|
-
init(config:
|
|
18
|
+
init(config: Config): Promise<void>;
|
|
19
19
|
destroy(): Promise<void>;
|
|
20
20
|
isInitializing(): boolean;
|
|
21
21
|
sendCustomEvent(name: string, data?: Record<string, unknown> | Record<string, unknown>[]): void;
|
|
@@ -10,12 +10,6 @@ export declare abstract class TraceLogValidationError extends Error {
|
|
|
10
10
|
readonly layer: 'config' | 'app' | 'runtime';
|
|
11
11
|
constructor(message: string, errorCode: string, layer: 'config' | 'app' | 'runtime');
|
|
12
12
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Thrown when project ID validation fails
|
|
15
|
-
*/
|
|
16
|
-
export declare class ProjectIdValidationError extends TraceLogValidationError {
|
|
17
|
-
constructor(message?: string, layer?: 'config' | 'app' | 'runtime');
|
|
18
|
-
}
|
|
19
13
|
/**
|
|
20
14
|
* Thrown when app configuration validation fails
|
|
21
15
|
*/
|
|
@@ -17,14 +17,6 @@ export class TraceLogValidationError extends Error {
|
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
/**
|
|
21
|
-
* Thrown when project ID validation fails
|
|
22
|
-
*/
|
|
23
|
-
export class ProjectIdValidationError extends TraceLogValidationError {
|
|
24
|
-
constructor(message = 'Project ID is required', layer = 'config') {
|
|
25
|
-
super(message, 'PROJECT_ID_INVALID', layer);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
20
|
/**
|
|
29
21
|
* Thrown when app configuration validation fails
|
|
30
22
|
*/
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DeviceType } from '../../types/device.types';
|
|
2
|
-
import {
|
|
2
|
+
import { log } from '../logging.utils';
|
|
3
3
|
let coarsePointerQuery;
|
|
4
4
|
let noHoverQuery;
|
|
5
5
|
const initMediaQueries = () => {
|
|
@@ -14,22 +14,14 @@ const initMediaQueries = () => {
|
|
|
14
14
|
*/
|
|
15
15
|
export const getDeviceType = () => {
|
|
16
16
|
try {
|
|
17
|
-
debugLog.debug('DeviceDetector', 'Starting device detection');
|
|
18
17
|
const nav = navigator;
|
|
19
18
|
if (nav.userAgentData && typeof nav.userAgentData.mobile === 'boolean') {
|
|
20
|
-
debugLog.debug('DeviceDetector', 'Using modern User-Agent Client Hints API', {
|
|
21
|
-
mobile: nav.userAgentData.mobile,
|
|
22
|
-
platform: nav.userAgentData.platform,
|
|
23
|
-
});
|
|
24
19
|
if (nav.userAgentData.platform && /ipad|tablet/i.test(nav.userAgentData.platform)) {
|
|
25
|
-
debugLog.debug('DeviceDetector', 'Device detected as tablet via platform hint');
|
|
26
20
|
return DeviceType.Tablet;
|
|
27
21
|
}
|
|
28
22
|
const result = nav.userAgentData.mobile ? DeviceType.Mobile : DeviceType.Desktop;
|
|
29
|
-
debugLog.debug('DeviceDetector', 'Device detected via User-Agent hints', { result });
|
|
30
23
|
return result;
|
|
31
24
|
}
|
|
32
|
-
debugLog.debug('DeviceDetector', 'Using fallback detection methods');
|
|
33
25
|
initMediaQueries();
|
|
34
26
|
const width = window.innerWidth;
|
|
35
27
|
const hasCoarsePointer = coarsePointerQuery?.matches ?? false;
|
|
@@ -38,30 +30,16 @@ export const getDeviceType = () => {
|
|
|
38
30
|
const ua = navigator.userAgent.toLowerCase();
|
|
39
31
|
const isMobileUA = /mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(ua);
|
|
40
32
|
const isTabletUA = /tablet|ipad|android(?!.*mobile)/.test(ua);
|
|
41
|
-
const detectionData = {
|
|
42
|
-
width,
|
|
43
|
-
hasCoarsePointer,
|
|
44
|
-
hasNoHover,
|
|
45
|
-
hasTouchSupport,
|
|
46
|
-
isMobileUA,
|
|
47
|
-
isTabletUA,
|
|
48
|
-
maxTouchPoints: navigator.maxTouchPoints,
|
|
49
|
-
};
|
|
50
33
|
if (width <= 767 || (isMobileUA && hasTouchSupport)) {
|
|
51
|
-
debugLog.debug('DeviceDetector', 'Device detected as mobile', detectionData);
|
|
52
34
|
return DeviceType.Mobile;
|
|
53
35
|
}
|
|
54
36
|
if ((width >= 768 && width <= 1024) || isTabletUA || (hasCoarsePointer && hasNoHover && hasTouchSupport)) {
|
|
55
|
-
debugLog.debug('DeviceDetector', 'Device detected as tablet', detectionData);
|
|
56
37
|
return DeviceType.Tablet;
|
|
57
38
|
}
|
|
58
|
-
debugLog.debug('DeviceDetector', 'Device detected as desktop', detectionData);
|
|
59
39
|
return DeviceType.Desktop;
|
|
60
40
|
}
|
|
61
41
|
catch (error) {
|
|
62
|
-
|
|
63
|
-
error: error instanceof Error ? error.message : error,
|
|
64
|
-
});
|
|
42
|
+
log('warn', 'Device detection failed, defaulting to desktop', { error });
|
|
65
43
|
return DeviceType.Desktop;
|
|
66
44
|
}
|
|
67
45
|
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detects if QA mode should be active based on URL query parameter or sessionStorage
|
|
3
|
+
*
|
|
4
|
+
* Detection flow:
|
|
5
|
+
* 1. Check if already active in sessionStorage
|
|
6
|
+
* 2. Check for ?tlog_mode=qa query parameter
|
|
7
|
+
* 3. If found in URL:
|
|
8
|
+
* - Persist to sessionStorage
|
|
9
|
+
* - Clean param from URL
|
|
10
|
+
*
|
|
11
|
+
* @returns True if QA mode is active, false otherwise
|
|
12
|
+
*/
|
|
13
|
+
export declare const detectQaMode: () => boolean;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { QA_MODE_KEY } from '@/constants';
|
|
2
|
+
import { log } from '../logging.utils';
|
|
3
|
+
const QA_MODE_PARAM = 'tlog_mode';
|
|
4
|
+
const QA_MODE_VALUE = 'qa';
|
|
5
|
+
/**
|
|
6
|
+
* Detects if QA mode should be active based on URL query parameter or sessionStorage
|
|
7
|
+
*
|
|
8
|
+
* Detection flow:
|
|
9
|
+
* 1. Check if already active in sessionStorage
|
|
10
|
+
* 2. Check for ?tlog_mode=qa query parameter
|
|
11
|
+
* 3. If found in URL:
|
|
12
|
+
* - Persist to sessionStorage
|
|
13
|
+
* - Clean param from URL
|
|
14
|
+
*
|
|
15
|
+
* @returns True if QA mode is active, false otherwise
|
|
16
|
+
*/
|
|
17
|
+
export const detectQaMode = () => {
|
|
18
|
+
const stored = sessionStorage.getItem(QA_MODE_KEY);
|
|
19
|
+
if (stored === 'true') {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
const params = new URLSearchParams(window.location.search);
|
|
23
|
+
const modeParam = params.get(QA_MODE_PARAM);
|
|
24
|
+
const isQaMode = modeParam === QA_MODE_VALUE;
|
|
25
|
+
if (isQaMode) {
|
|
26
|
+
sessionStorage.setItem(QA_MODE_KEY, 'true');
|
|
27
|
+
params.delete(QA_MODE_PARAM);
|
|
28
|
+
const newSearch = params.toString();
|
|
29
|
+
const newUrl = `${window.location.pathname}${newSearch ? '?' + newSearch : ''}${window.location.hash}`;
|
|
30
|
+
try {
|
|
31
|
+
window.history.replaceState({}, '', newUrl);
|
|
32
|
+
}
|
|
33
|
+
catch (error) {
|
|
34
|
+
log('warn', 'History API not available, cannot replace URL', { error });
|
|
35
|
+
}
|
|
36
|
+
console.log('%c[TraceLog] QA Mode ACTIVE', 'background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;');
|
|
37
|
+
}
|
|
38
|
+
return isQaMode;
|
|
39
|
+
};
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
import { UTM_PARAMS } from '../../constants';
|
|
2
|
-
import { debugLog } from '../logging';
|
|
3
2
|
/**
|
|
4
3
|
* Extracts UTM parameters from the current URL
|
|
5
4
|
* @returns UTM parameters object or undefined if none found
|
|
6
5
|
*/
|
|
7
6
|
export const getUTMParameters = () => {
|
|
8
|
-
debugLog.debug('UTMParams', 'Extracting UTM parameters from URL', {
|
|
9
|
-
url: window.location.href,
|
|
10
|
-
search: window.location.search,
|
|
11
|
-
});
|
|
12
7
|
const urlParams = new URLSearchParams(window.location.search);
|
|
13
8
|
const utmParams = {};
|
|
14
9
|
UTM_PARAMS.forEach((param) => {
|
|
@@ -16,18 +11,8 @@ export const getUTMParameters = () => {
|
|
|
16
11
|
if (value) {
|
|
17
12
|
const key = param.split('utm_')[1];
|
|
18
13
|
utmParams[key] = value;
|
|
19
|
-
debugLog.debug('UTMParams', 'Found UTM parameter', { param, key, value });
|
|
20
14
|
}
|
|
21
15
|
});
|
|
22
16
|
const result = Object.keys(utmParams).length ? utmParams : undefined;
|
|
23
|
-
if (result) {
|
|
24
|
-
debugLog.debug('UTMParams', 'UTM parameters extracted successfully', {
|
|
25
|
-
parameterCount: Object.keys(result).length,
|
|
26
|
-
parameters: Object.keys(result),
|
|
27
|
-
});
|
|
28
|
-
}
|
|
29
|
-
else {
|
|
30
|
-
debugLog.debug('UTMParams', 'No UTM parameters found in URL');
|
|
31
|
-
}
|
|
32
17
|
return result;
|
|
33
18
|
};
|
|
@@ -3,3 +3,16 @@
|
|
|
3
3
|
* @returns A UUID string
|
|
4
4
|
*/
|
|
5
5
|
export declare const generateUUID: () => string;
|
|
6
|
+
/**
|
|
7
|
+
* Generates a unique event ID optimized for high-frequency event tracking
|
|
8
|
+
*
|
|
9
|
+
* Uses a simple hybrid approach:
|
|
10
|
+
* - Timestamp for temporal ordering
|
|
11
|
+
* - Random component for uniqueness across tabs/processes
|
|
12
|
+
*
|
|
13
|
+
* Format: {timestamp}-{random}
|
|
14
|
+
* Example: "1704067200000-a3f9c2b1"
|
|
15
|
+
*
|
|
16
|
+
* @returns Unique event ID string
|
|
17
|
+
*/
|
|
18
|
+
export declare const generateEventId: () => string;
|
|
@@ -14,3 +14,38 @@ export const generateUUID = () => {
|
|
|
14
14
|
return v.toString(16);
|
|
15
15
|
});
|
|
16
16
|
};
|
|
17
|
+
/**
|
|
18
|
+
* Generates a unique event ID optimized for high-frequency event tracking
|
|
19
|
+
*
|
|
20
|
+
* Uses a simple hybrid approach:
|
|
21
|
+
* - Timestamp for temporal ordering
|
|
22
|
+
* - Random component for uniqueness across tabs/processes
|
|
23
|
+
*
|
|
24
|
+
* Format: {timestamp}-{random}
|
|
25
|
+
* Example: "1704067200000-a3f9c2b1"
|
|
26
|
+
*
|
|
27
|
+
* @returns Unique event ID string
|
|
28
|
+
*/
|
|
29
|
+
export const generateEventId = () => {
|
|
30
|
+
const timestamp = Date.now();
|
|
31
|
+
// Generate 8 random hex chars (32 bits entropy)
|
|
32
|
+
let random = '';
|
|
33
|
+
try {
|
|
34
|
+
if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
|
|
35
|
+
const bytes = crypto.getRandomValues(new Uint8Array(4));
|
|
36
|
+
if (bytes) {
|
|
37
|
+
random = Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch {
|
|
42
|
+
// crypto failed, use fallback
|
|
43
|
+
}
|
|
44
|
+
// Fallback to Math.random if crypto unavailable
|
|
45
|
+
if (!random) {
|
|
46
|
+
random = Math.floor(Math.random() * 0xffffffff)
|
|
47
|
+
.toString(16)
|
|
48
|
+
.padStart(8, '0');
|
|
49
|
+
}
|
|
50
|
+
return `${timestamp}-${random}`;
|
|
51
|
+
};
|
package/dist/esm/utils/index.js
CHANGED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const formatLogMsg = (msg, error) => {
|
|
2
|
+
if (error) {
|
|
3
|
+
return `[TraceLog] ${msg}: ${error instanceof Error ? error.message : 'Unknown error'}`;
|
|
4
|
+
}
|
|
5
|
+
return `[TraceLog] ${msg}`;
|
|
6
|
+
};
|
|
7
|
+
export const log = (type, msg, extra) => {
|
|
8
|
+
const { error, data, showToClient } = extra ?? {};
|
|
9
|
+
const formattedMsg = error ? formatLogMsg(msg, error) : `[TraceLog] ${msg}`;
|
|
10
|
+
const method = type === 'error' ? 'error' : type === 'warn' ? 'warn' : 'log';
|
|
11
|
+
if (process.env.NODE_ENV !== 'dev' && !showToClient) {
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
if (data !== undefined) {
|
|
15
|
+
console[method](formattedMsg, data);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console[method](formattedMsg);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
+
import { Config } from '@/types';
|
|
1
2
|
/**
|
|
2
3
|
* Generates an API URL based on project ID and current domain
|
|
3
4
|
* @param id - The project ID
|
|
4
5
|
* @returns The generated API URL
|
|
5
6
|
*/
|
|
6
|
-
export declare const getApiUrl: (
|
|
7
|
+
export declare const getApiUrl: (config: Config) => string;
|
|
7
8
|
/**
|
|
8
9
|
* Normalizes a URL by removing sensitive query parameters
|
|
9
10
|
* @param url - The URL to normalize
|
|
@@ -11,10 +12,3 @@ export declare const getApiUrl: (id: string, allowHttp?: boolean) => string;
|
|
|
11
12
|
* @returns The normalized URL
|
|
12
13
|
*/
|
|
13
14
|
export declare const normalizeUrl: (url: string, sensitiveQueryParams?: string[]) => string;
|
|
14
|
-
/**
|
|
15
|
-
* Checks if a URL path should be excluded from tracking
|
|
16
|
-
* @param url - The URL to check
|
|
17
|
-
* @param excludedPaths - Array of patterns to match against
|
|
18
|
-
* @returns True if the URL should be excluded
|
|
19
|
-
*/
|
|
20
|
-
export declare const isUrlPathExcluded: (url: string, excludedPaths?: string[]) => boolean;
|