@tracelog/lib 2.0.2 → 2.0.3-rc.73.6

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.

Potentially problematic release.


This version of @tracelog/lib might be problematic. Click here for more details.

@@ -265,12 +265,6 @@ var init_event_types = __esm({
265
265
  }
266
266
  });
267
267
 
268
- // src/types/log.types.ts
269
- var init_log_types = __esm({
270
- "src/types/log.types.ts"() {
271
- }
272
- });
273
-
274
268
  // src/types/mode.types.ts
275
269
  var Mode;
276
270
  var init_mode_types = __esm({
@@ -385,7 +379,6 @@ var init_types = __esm({
385
379
  init_emitter_types();
386
380
  init_error_types();
387
381
  init_event_types();
388
- init_log_types();
389
382
  init_mode_types();
390
383
  init_queue_types();
391
384
  init_scroll_types();
@@ -398,10 +391,22 @@ var init_types = __esm({
398
391
  }
399
392
  });
400
393
 
394
+ // src/constants/app.constants.ts
395
+ var LOG_STYLE_ACTIVE, LOG_STYLE_DISABLED, LOG_STYLE_CRITICAL;
396
+ var init_app_constants = __esm({
397
+ "src/constants/app.constants.ts"() {
398
+ LOG_STYLE_ACTIVE = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
399
+ LOG_STYLE_DISABLED = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
400
+ LOG_STYLE_CRITICAL = "background: #d32f2f; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
401
+ }
402
+ });
403
+
401
404
  // src/utils/logging.utils.ts
402
- var formatLogMsg, log, sanitizeLogData;
405
+ var formatLogMsg, isQaModeActive, log, shouldShowLog, getEffectiveStyle, outputLog, sanitizeLogData;
403
406
  var init_logging_utils = __esm({
404
407
  "src/utils/logging.utils.ts"() {
408
+ init_storage_constants();
409
+ init_app_constants();
405
410
  formatLogMsg = (msg, error) => {
406
411
  if (error) {
407
412
  if (process.env.NODE_ENV !== "development" && error instanceof Error) {
@@ -425,27 +430,59 @@ var init_logging_utils = __esm({
425
430
  }
426
431
  return `[TraceLog] ${msg}`;
427
432
  };
433
+ isQaModeActive = () => {
434
+ if (typeof window === "undefined" || typeof sessionStorage === "undefined") {
435
+ return false;
436
+ }
437
+ try {
438
+ return sessionStorage.getItem(QA_MODE_KEY) === "true";
439
+ } catch {
440
+ return false;
441
+ }
442
+ };
428
443
  log = (type, msg, extra) => {
429
- const { error, data, showToClient = false, style } = extra ?? {};
444
+ const { error, data, showToClient = false, style, visibility } = extra ?? {};
430
445
  const formattedMsg = error ? formatLogMsg(msg, error) : `[TraceLog] ${msg}`;
431
446
  const method = type === "error" ? "error" : type === "warn" ? "warn" : "log";
432
447
  const isProduction = process.env.NODE_ENV !== "development";
433
- if (isProduction) {
434
- if (type === "debug") {
435
- return;
436
- }
437
- if (type === "info" && !showToClient) {
438
- return;
439
- }
448
+ if (!isProduction) {
449
+ outputLog(method, formattedMsg, style, data);
450
+ return;
451
+ }
452
+ const shouldShow = shouldShowLog(visibility, showToClient);
453
+ if (!shouldShow) {
454
+ return;
455
+ }
456
+ const effectiveStyle = getEffectiveStyle(visibility, style);
457
+ const sanitizedData = data !== void 0 ? sanitizeLogData(data) : void 0;
458
+ outputLog(method, formattedMsg, effectiveStyle, sanitizedData);
459
+ };
460
+ shouldShowLog = (visibility, showToClient) => {
461
+ if (visibility === "critical") {
462
+ return true;
440
463
  }
464
+ if (visibility === "qa" || showToClient) {
465
+ return isQaModeActive();
466
+ }
467
+ return false;
468
+ };
469
+ getEffectiveStyle = (visibility, providedStyle) => {
470
+ if (providedStyle !== void 0 && providedStyle !== "") {
471
+ return providedStyle;
472
+ }
473
+ if (visibility === "critical") {
474
+ return LOG_STYLE_CRITICAL;
475
+ }
476
+ return "";
477
+ };
478
+ outputLog = (method, formattedMsg, style, data) => {
441
479
  const hasStyle = style !== void 0 && style !== "";
442
480
  const styledMsg = hasStyle ? `%c${formattedMsg}` : formattedMsg;
443
481
  if (data !== void 0) {
444
- const sanitizedData = isProduction ? sanitizeLogData(data) : data;
445
482
  if (hasStyle) {
446
- console[method](styledMsg, style, sanitizedData);
483
+ console[method](styledMsg, style, data);
447
484
  } else {
448
- console[method](styledMsg, sanitizedData);
485
+ console[method](styledMsg, data);
449
486
  }
450
487
  } else {
451
488
  if (hasStyle) {
@@ -480,7 +517,7 @@ var init_logging_utils = __esm({
480
517
  });
481
518
 
482
519
  // src/utils/browser/device-detector.utils.ts
483
- var coarsePointerQuery, noHoverQuery, initMediaQueries, getDeviceType;
520
+ var coarsePointerQuery, noHoverQuery, initMediaQueries, UNKNOWN, detectOS, detectBrowser, getDeviceType, getDeviceInfo;
484
521
  var init_device_detector_utils = __esm({
485
522
  "src/utils/browser/device-detector.utils.ts"() {
486
523
  init_device_types();
@@ -491,11 +528,53 @@ var init_device_detector_utils = __esm({
491
528
  noHoverQuery = window.matchMedia("(hover: none)");
492
529
  }
493
530
  };
531
+ UNKNOWN = "Unknown";
532
+ detectOS = (nav) => {
533
+ const platform = nav.userAgentData?.platform;
534
+ if (platform != null && platform !== "") {
535
+ if (/windows/i.test(platform)) return "Windows";
536
+ if (/macos/i.test(platform)) return "macOS";
537
+ if (/android/i.test(platform)) return "Android";
538
+ if (/linux/i.test(platform)) return "Linux";
539
+ if (/chromeos/i.test(platform)) return "ChromeOS";
540
+ if (/ios/i.test(platform)) return "iOS";
541
+ }
542
+ const ua = navigator.userAgent;
543
+ if (/Windows/i.test(ua)) return "Windows";
544
+ if (/iPhone|iPad|iPod/i.test(ua)) return "iOS";
545
+ if (/Mac OS X|Macintosh/i.test(ua)) return "macOS";
546
+ if (/Android/i.test(ua)) return "Android";
547
+ if (/CrOS/i.test(ua)) return "ChromeOS";
548
+ if (/Linux/i.test(ua)) return "Linux";
549
+ return UNKNOWN;
550
+ };
551
+ detectBrowser = (nav) => {
552
+ const brands = nav.userAgentData?.brands;
553
+ if (brands != null && brands.length > 0) {
554
+ const validBrands = brands.filter((b) => !/not.?a.?brand|chromium/i.test(b.brand));
555
+ const firstBrand = validBrands[0];
556
+ if (firstBrand != null) {
557
+ const brand = firstBrand.brand;
558
+ if (/google chrome/i.test(brand)) return "Chrome";
559
+ if (/microsoft edge/i.test(brand)) return "Edge";
560
+ if (/opera/i.test(brand)) return "Opera";
561
+ return brand;
562
+ }
563
+ }
564
+ const ua = navigator.userAgent;
565
+ if (/Edg\//i.test(ua)) return "Edge";
566
+ if (/OPR\//i.test(ua)) return "Opera";
567
+ if (/Chrome/i.test(ua)) return "Chrome";
568
+ if (/Firefox/i.test(ua)) return "Firefox";
569
+ if (/Safari/i.test(ua) && !/Chrome/i.test(ua)) return "Safari";
570
+ return UNKNOWN;
571
+ };
494
572
  getDeviceType = () => {
495
573
  try {
496
574
  const nav = navigator;
497
- if (nav.userAgentData && typeof nav.userAgentData.mobile === "boolean") {
498
- if (nav.userAgentData.platform && /ipad|tablet/i.test(nav.userAgentData.platform)) {
575
+ if (nav.userAgentData != null && typeof nav.userAgentData.mobile === "boolean") {
576
+ const uaPlatform = nav.userAgentData.platform;
577
+ if (uaPlatform != null && uaPlatform !== "" && /ipad|tablet/i.test(uaPlatform)) {
499
578
  return "tablet" /* Tablet */;
500
579
  }
501
580
  const result = nav.userAgentData.mobile ? "mobile" /* Mobile */ : "desktop" /* Desktop */;
@@ -517,27 +596,27 @@ var init_device_detector_utils = __esm({
517
596
  }
518
597
  return "desktop" /* Desktop */;
519
598
  } catch (error) {
520
- log("warn", "Device detection failed, defaulting to desktop", { error });
599
+ log("debug", "Device detection failed, defaulting to desktop", { error });
521
600
  return "desktop" /* Desktop */;
522
601
  }
523
602
  };
524
- }
525
- });
526
-
527
- // src/constants/app.constants.ts
528
- var LOG_STYLE_ACTIVE, LOG_STYLE_DISABLED;
529
- var init_app_constants = __esm({
530
- "src/constants/app.constants.ts"() {
531
- LOG_STYLE_ACTIVE = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
532
- LOG_STYLE_DISABLED = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
533
- }
534
- });
535
-
536
- // src/constants/disabled-events.constants.ts
537
- var DISABLEABLE_EVENT_TYPES;
538
- var init_disabled_events_constants = __esm({
539
- "src/constants/disabled-events.constants.ts"() {
540
- DISABLEABLE_EVENT_TYPES = ["scroll", "web_vitals", "error"];
603
+ getDeviceInfo = () => {
604
+ try {
605
+ const nav = navigator;
606
+ return {
607
+ type: getDeviceType(),
608
+ os: detectOS(nav),
609
+ browser: detectBrowser(nav)
610
+ };
611
+ } catch (error) {
612
+ log("debug", "Device info detection failed, using defaults", { error });
613
+ return {
614
+ type: "desktop" /* Desktop */,
615
+ os: UNKNOWN,
616
+ browser: UNKNOWN
617
+ };
618
+ }
619
+ };
541
620
  }
542
621
  });
543
622
 
@@ -639,7 +718,7 @@ var init_performance_constants = __esm({
639
718
  var version;
640
719
  var init_package = __esm({
641
720
  "package.json"() {
642
- version = "2.0.1";
721
+ version = "2.0.3";
643
722
  }
644
723
  });
645
724
 
@@ -657,7 +736,6 @@ var init_constants = __esm({
657
736
  "src/constants/index.ts"() {
658
737
  init_app_constants();
659
738
  init_config_constants();
660
- init_disabled_events_constants();
661
739
  init_error_constants();
662
740
  init_storage_constants();
663
741
  init_performance_constants();
@@ -665,19 +743,33 @@ var init_constants = __esm({
665
743
  }
666
744
  });
667
745
 
668
- // src/utils/browser/qa-mode.utils.ts
669
- var qa_mode_utils_exports = {};
670
- __export(qa_mode_utils_exports, {
746
+ // src/utils/browser/mode.utils.ts
747
+ var mode_utils_exports = {};
748
+ __export(mode_utils_exports, {
671
749
  detectQaMode: () => detectQaMode,
750
+ isQaModeActive: () => isQaModeActive2,
672
751
  setQaMode: () => setQaMode
673
752
  });
674
- var detectQaMode, setQaMode;
675
- var init_qa_mode_utils = __esm({
676
- "src/utils/browser/qa-mode.utils.ts"() {
753
+ var isBrowserEnvironment, cleanUrlParameter, detectQaMode, setQaMode, isQaModeActive2;
754
+ var init_mode_utils = __esm({
755
+ "src/utils/browser/mode.utils.ts"() {
677
756
  init_constants();
678
757
  init_logging_utils();
758
+ isBrowserEnvironment = () => {
759
+ return typeof window !== "undefined" && typeof sessionStorage !== "undefined";
760
+ };
761
+ cleanUrlParameter = () => {
762
+ try {
763
+ const params = new URLSearchParams(window.location.search);
764
+ params.delete(QA_MODE_URL_PARAM);
765
+ const search = params.toString();
766
+ const url = window.location.pathname + (search ? "?" + search : "") + window.location.hash;
767
+ window.history.replaceState({}, "", url);
768
+ } catch {
769
+ }
770
+ };
679
771
  detectQaMode = () => {
680
- if (typeof window === "undefined" || typeof document === "undefined") {
772
+ if (!isBrowserEnvironment()) {
681
773
  return false;
682
774
  }
683
775
  try {
@@ -689,25 +781,19 @@ var init_qa_mode_utils = __esm({
689
781
  newState = true;
690
782
  sessionStorage.setItem(QA_MODE_KEY, "true");
691
783
  log("info", "QA Mode ACTIVE", {
692
- showToClient: true,
784
+ visibility: "qa",
693
785
  style: LOG_STYLE_ACTIVE
694
786
  });
695
787
  } else if (urlParam === QA_MODE_DISABLE_VALUE) {
696
788
  newState = false;
697
789
  sessionStorage.setItem(QA_MODE_KEY, "false");
698
790
  log("info", "QA Mode DISABLED", {
699
- showToClient: true,
791
+ visibility: "qa",
700
792
  style: LOG_STYLE_DISABLED
701
793
  });
702
794
  }
703
795
  if (urlParam === QA_MODE_ENABLE_VALUE || urlParam === QA_MODE_DISABLE_VALUE) {
704
- try {
705
- params.delete(QA_MODE_URL_PARAM);
706
- const search = params.toString();
707
- const url = window.location.pathname + (search ? "?" + search : "") + window.location.hash;
708
- window.history.replaceState({}, "", url);
709
- } catch {
710
- }
796
+ cleanUrlParameter();
711
797
  }
712
798
  return newState ?? storedState === "true";
713
799
  } catch {
@@ -715,25 +801,27 @@ var init_qa_mode_utils = __esm({
715
801
  }
716
802
  };
717
803
  setQaMode = (enabled) => {
718
- if (typeof window === "undefined" || typeof document === "undefined") {
804
+ if (!isBrowserEnvironment()) {
719
805
  return;
720
806
  }
721
807
  try {
722
- if (enabled) {
723
- sessionStorage.setItem(QA_MODE_KEY, "true");
724
- log("info", "QA Mode ENABLED", {
725
- showToClient: true,
726
- style: LOG_STYLE_ACTIVE
727
- });
728
- } else {
729
- sessionStorage.setItem(QA_MODE_KEY, "false");
730
- log("info", "QA Mode DISABLED", {
731
- showToClient: true,
732
- style: LOG_STYLE_DISABLED
733
- });
734
- }
808
+ sessionStorage.setItem(QA_MODE_KEY, enabled ? "true" : "false");
809
+ log("info", enabled ? "QA Mode ACTIVE" : "QA Mode DISABLED", {
810
+ visibility: "qa",
811
+ style: enabled ? LOG_STYLE_ACTIVE : LOG_STYLE_DISABLED
812
+ });
735
813
  } catch {
736
- log("warn", "Cannot set QA mode: sessionStorage unavailable");
814
+ log("debug", "Cannot set QA mode: sessionStorage unavailable");
815
+ }
816
+ };
817
+ isQaModeActive2 = () => {
818
+ if (!isBrowserEnvironment()) {
819
+ return false;
820
+ }
821
+ try {
822
+ return sessionStorage.getItem(QA_MODE_KEY) === "true";
823
+ } catch {
824
+ return false;
737
825
  }
738
826
  };
739
827
  }
@@ -764,7 +852,7 @@ var init_utm_params_utils = __esm({
764
852
  var init_browser = __esm({
765
853
  "src/utils/browser/index.ts"() {
766
854
  init_device_detector_utils();
767
- init_qa_mode_utils();
855
+ init_mode_utils();
768
856
  init_utm_params_utils();
769
857
  }
770
858
  });
@@ -894,7 +982,7 @@ var init_url_utils = __esm({
894
982
  };
895
983
  normalizeUrl = (url, sensitiveQueryParams = []) => {
896
984
  if (!url || typeof url !== "string") {
897
- log("warn", "Invalid URL provided to normalizeUrl", { data: { url: String(url) } });
985
+ log("warn", "Invalid URL provided to normalizeUrl", { data: { type: typeof url } });
898
986
  return url || "";
899
987
  }
900
988
  try {
@@ -917,8 +1005,7 @@ var init_url_utils = __esm({
917
1005
  const result = urlObject.toString();
918
1006
  return result;
919
1007
  } catch (error) {
920
- const urlPreview = url && typeof url === "string" ? url.slice(0, 100) : String(url);
921
- log("warn", "URL normalization failed, returning original", { error, data: { url: urlPreview } });
1008
+ log("warn", "URL normalization failed, returning original", { error, data: { urlLength: url?.length } });
922
1009
  return url;
923
1010
  }
924
1011
  };
@@ -958,7 +1045,7 @@ var init_sanitize_utils = __esm({
958
1045
  log("warn", "XSS patterns detected and removed", {
959
1046
  data: {
960
1047
  patternMatches: xssPatternMatches,
961
- originalValue: value.slice(0, 100)
1048
+ valueLength: value.length
962
1049
  }
963
1050
  });
964
1051
  }
@@ -1109,30 +1196,6 @@ var init_config_validations_utils = __esm({
1109
1196
  if (config.viewport !== void 0) {
1110
1197
  validateViewportConfig(config.viewport);
1111
1198
  }
1112
- if (config.disabledEvents !== void 0) {
1113
- if (!Array.isArray(config.disabledEvents)) {
1114
- throw new AppConfigValidationError("disabledEvents must be an array", "config");
1115
- }
1116
- const uniqueEvents = /* @__PURE__ */ new Set();
1117
- for (const eventType of config.disabledEvents) {
1118
- if (typeof eventType !== "string") {
1119
- throw new AppConfigValidationError("All disabled event types must be strings", "config");
1120
- }
1121
- if (!DISABLEABLE_EVENT_TYPES.includes(eventType)) {
1122
- throw new AppConfigValidationError(
1123
- `Invalid disabled event type: "${eventType}". Must be one of: ${DISABLEABLE_EVENT_TYPES.join(", ")}`,
1124
- "config"
1125
- );
1126
- }
1127
- if (uniqueEvents.has(eventType)) {
1128
- throw new AppConfigValidationError(
1129
- `Duplicate disabled event type found: "${eventType}". Each event type should appear only once.`,
1130
- "config"
1131
- );
1132
- }
1133
- uniqueEvents.add(eventType);
1134
- }
1135
- }
1136
1199
  if (config.webVitalsMode !== void 0) {
1137
1200
  if (typeof config.webVitalsMode !== "string") {
1138
1201
  throw new AppConfigValidationError(
@@ -1260,8 +1323,7 @@ var init_config_validations_utils = __esm({
1260
1323
  samplingRate: config?.samplingRate ?? DEFAULT_SAMPLING_RATE,
1261
1324
  pageViewThrottleMs: config?.pageViewThrottleMs ?? DEFAULT_PAGE_VIEW_THROTTLE_MS,
1262
1325
  clickThrottleMs: config?.clickThrottleMs ?? DEFAULT_CLICK_THROTTLE_MS,
1263
- maxSameEventPerMinute: config?.maxSameEventPerMinute ?? MAX_SAME_EVENT_PER_MINUTE,
1264
- disabledEvents: config?.disabledEvents ?? []
1326
+ maxSameEventPerMinute: config?.maxSameEventPerMinute ?? MAX_SAME_EVENT_PER_MINUTE
1265
1327
  };
1266
1328
  if (normalizedConfig.integrations?.custom) {
1267
1329
  normalizedConfig.integrations.custom = {
@@ -1499,7 +1561,6 @@ var init_event_validations_utils = __esm({
1499
1561
  const nameValidation = isValidEventName(eventName);
1500
1562
  if (!nameValidation.valid) {
1501
1563
  log("error", "Event name validation failed", {
1502
- showToClient: true,
1503
1564
  data: { eventName, error: nameValidation.error }
1504
1565
  });
1505
1566
  return nameValidation;
@@ -1510,7 +1571,6 @@ var init_event_validations_utils = __esm({
1510
1571
  const metadataValidation = isValidMetadata(eventName, metadata, "customEvent");
1511
1572
  if (!metadataValidation.valid) {
1512
1573
  log("error", "Event metadata validation failed", {
1513
- showToClient: true,
1514
1574
  data: {
1515
1575
  eventName,
1516
1576
  error: metadataValidation.error
@@ -1676,7 +1736,10 @@ function transformEvent(event2, transformer, context) {
1676
1736
  log("warn", `beforeSend transformer returned invalid data, using original [${context}]`);
1677
1737
  return event2;
1678
1738
  } catch (error) {
1679
- log("error", `beforeSend transformer threw error, using original event [${context}]`, { error });
1739
+ log("error", `beforeSend transformer threw error, using original event [${context}]`, {
1740
+ error,
1741
+ visibility: "critical"
1742
+ });
1680
1743
  return event2;
1681
1744
  }
1682
1745
  }
@@ -1702,7 +1765,8 @@ function transformBatch(batch, transformer, context) {
1702
1765
  } catch (error) {
1703
1766
  log("error", `beforeBatch transformer threw error, using original batch [${context}]`, {
1704
1767
  error,
1705
- data: { eventCount: batch.events.length }
1768
+ data: { eventCount: batch.events.length },
1769
+ visibility: "critical"
1706
1770
  });
1707
1771
  return batch;
1708
1772
  }
@@ -2205,7 +2269,7 @@ var init_sender_manager = __esm({
2205
2269
  return true;
2206
2270
  }
2207
2271
  if (this.apiUrl?.includes("localhost:9999" /* Fail */)) {
2208
- log("warn", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
2272
+ log("debug", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
2209
2273
  data: { events: transformedBody.events.length }
2210
2274
  });
2211
2275
  return false;
@@ -2432,7 +2496,7 @@ var init_sender_manager = __esm({
2432
2496
  return JSON.parse(persistedDataString);
2433
2497
  }
2434
2498
  } catch (error) {
2435
- log("warn", `Failed to parse persisted data${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2499
+ log("debug", `Failed to parse persisted data${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2436
2500
  this.clearPersistedEvents();
2437
2501
  }
2438
2502
  return null;
@@ -2511,7 +2575,7 @@ var init_sender_manager = __esm({
2511
2575
  this.storeManager.setItem(storageKey, JSON.stringify(persistedData));
2512
2576
  return !!this.storeManager.getItem(storageKey);
2513
2577
  } catch (error) {
2514
- log("warn", `Failed to persist events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2578
+ log("debug", `Failed to persist events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2515
2579
  return false;
2516
2580
  }
2517
2581
  }
@@ -2520,7 +2584,9 @@ var init_sender_manager = __esm({
2520
2584
  const key = this.getQueueStorageKey();
2521
2585
  this.storeManager.removeItem(key);
2522
2586
  } catch (error) {
2523
- log("warn", `Failed to clear persisted events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2587
+ log("debug", `Failed to clear persisted events${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
2588
+ error
2589
+ });
2524
2590
  }
2525
2591
  }
2526
2592
  shouldSkipSend() {
@@ -2595,7 +2661,7 @@ var init_time_manager = __esm({
2595
2661
  } else {
2596
2662
  this.bootTime = 0;
2597
2663
  this.bootTimestamp = Date.now();
2598
- log("warn", "performance.now() not available, falling back to Date.now()");
2664
+ log("debug", "performance.now() not available, falling back to Date.now()");
2599
2665
  }
2600
2666
  }
2601
2667
  /**
@@ -2830,7 +2896,7 @@ var init_event_manager = __esm({
2830
2896
  }
2831
2897
  },
2832
2898
  onFailure: () => {
2833
- log("warn", "Failed to recover persisted events");
2899
+ log("debug", "Failed to recover persisted events");
2834
2900
  }
2835
2901
  })
2836
2902
  );
@@ -2914,7 +2980,7 @@ var init_event_manager = __esm({
2914
2980
  if (!currentSessionId) {
2915
2981
  if (this.pendingEventsBuffer.length >= MAX_PENDING_EVENTS_BUFFER) {
2916
2982
  this.pendingEventsBuffer.shift();
2917
- log("warn", "Pending events buffer full - dropping oldest event", {
2983
+ log("debug", "Pending events buffer full - dropping oldest event", {
2918
2984
  data: { maxBufferSize: MAX_PENDING_EVENTS_BUFFER }
2919
2985
  });
2920
2986
  }
@@ -3003,7 +3069,7 @@ var init_event_manager = __esm({
3003
3069
  return;
3004
3070
  }
3005
3071
  if (this.get("hasStartSession")) {
3006
- log("warn", "Duplicate session_start detected", {
3072
+ log("debug", "Duplicate session_start detected", {
3007
3073
  data: { sessionId: currentSessionId2 }
3008
3074
  });
3009
3075
  return;
@@ -3013,16 +3079,33 @@ var init_event_manager = __esm({
3013
3079
  if (this.isDuplicateEvent(payload)) {
3014
3080
  return;
3015
3081
  }
3016
- if (this.get("mode") === "qa" /* QA */ && eventType === "custom" /* CUSTOM */ && custom_event) {
3017
- log("info", `Custom Event: ${custom_event.name}`, {
3018
- showToClient: true,
3019
- data: {
3020
- name: custom_event.name,
3021
- ...custom_event.metadata && { metadata: custom_event.metadata }
3022
- }
3023
- });
3024
- this.emitEvent(payload);
3025
- return;
3082
+ if (this.get("mode") === "qa" /* QA */) {
3083
+ if (eventType === "custom" /* CUSTOM */ && custom_event) {
3084
+ log("info", `Custom Event: ${custom_event.name}`, {
3085
+ visibility: "qa",
3086
+ data: {
3087
+ name: custom_event.name,
3088
+ ...custom_event.metadata && { metadata: custom_event.metadata }
3089
+ }
3090
+ });
3091
+ this.emitEvent(payload);
3092
+ return;
3093
+ }
3094
+ if (eventType === "viewport_visible" /* VIEWPORT_VISIBLE */ && viewport_data) {
3095
+ const displayName = viewport_data.name || viewport_data.id || viewport_data.selector;
3096
+ log("info", `Viewport Visible: ${displayName}`, {
3097
+ visibility: "qa",
3098
+ data: {
3099
+ selector: viewport_data.selector,
3100
+ ...viewport_data.name && { name: viewport_data.name },
3101
+ ...viewport_data.id && { id: viewport_data.id },
3102
+ visibilityRatio: viewport_data.visibilityRatio,
3103
+ dwellTime: viewport_data.dwellTime
3104
+ }
3105
+ });
3106
+ this.emitEvent(payload);
3107
+ return;
3108
+ }
3026
3109
  }
3027
3110
  this.addToQueue(payload);
3028
3111
  if (!isCriticalEvent) {
@@ -3274,7 +3357,7 @@ var init_event_manager = __esm({
3274
3357
  }
3275
3358
  const currentSessionId = this.get("sessionId");
3276
3359
  if (!currentSessionId) {
3277
- log("warn", "Cannot flush pending events: session not initialized - keeping in buffer", {
3360
+ log("debug", "Cannot flush pending events: session not initialized - keeping in buffer", {
3278
3361
  data: { bufferedEventCount: this.pendingEventsBuffer.length }
3279
3362
  });
3280
3363
  return;
@@ -3316,7 +3399,7 @@ var init_event_manager = __esm({
3316
3399
  this.emitEventsQueue(body);
3317
3400
  } else {
3318
3401
  this.clearSendInterval();
3319
- log("warn", "Sync flush complete failure, events kept in queue for retry", {
3402
+ log("debug", "Sync flush complete failure, events kept in queue for retry", {
3320
3403
  data: { eventCount: eventIds.length }
3321
3404
  });
3322
3405
  }
@@ -3337,7 +3420,7 @@ var init_event_manager = __esm({
3337
3420
  this.clearSendInterval();
3338
3421
  this.emitEventsQueue(body);
3339
3422
  } else {
3340
- log("warn", "Async flush complete failure, events kept in queue for retry", {
3423
+ log("debug", "Async flush complete failure, events kept in queue for retry", {
3341
3424
  data: { eventCount: eventsToSend.length }
3342
3425
  });
3343
3426
  }
@@ -3371,12 +3454,12 @@ var init_event_manager = __esm({
3371
3454
  this.emitEventsQueue(body);
3372
3455
  const failedCount = results.filter((result) => !this.isSuccessfulResult(result)).length;
3373
3456
  if (failedCount > 0) {
3374
- log("warn", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
3457
+ log("debug", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
3375
3458
  data: { eventCount: eventsToSend.length, failedCount }
3376
3459
  });
3377
3460
  }
3378
3461
  } else {
3379
- log("warn", "Periodic send complete failure, events kept in queue for retry", {
3462
+ log("debug", "Periodic send complete failure, events kept in queue for retry", {
3380
3463
  data: { eventCount: eventsToSend.length }
3381
3464
  });
3382
3465
  }
@@ -3473,7 +3556,7 @@ var init_event_manager = __esm({
3473
3556
  if (this.recentEventFingerprints.size > MAX_FINGERPRINTS_HARD_LIMIT) {
3474
3557
  this.recentEventFingerprints.clear();
3475
3558
  this.recentEventFingerprints.set(fingerprint, now);
3476
- log("warn", "Event fingerprint cache exceeded hard limit, cleared", {
3559
+ log("debug", "Event fingerprint cache exceeded hard limit, cleared", {
3477
3560
  data: { hardLimit: MAX_FINGERPRINTS_HARD_LIMIT }
3478
3561
  });
3479
3562
  }
@@ -3911,7 +3994,7 @@ var init_session_manager = __esm({
3911
3994
  }
3912
3995
  initCrossTabSync() {
3913
3996
  if (typeof BroadcastChannel === "undefined") {
3914
- log("warn", "BroadcastChannel not supported");
3997
+ log("debug", "BroadcastChannel not supported");
3915
3998
  return;
3916
3999
  }
3917
4000
  const projectId = this.getProjectId();
@@ -4059,7 +4142,7 @@ var init_session_manager = __esm({
4059
4142
  */
4060
4143
  startTracking() {
4061
4144
  if (this.isTracking) {
4062
- log("warn", "Session tracking already active");
4145
+ log("debug", "Session tracking already active");
4063
4146
  return;
4064
4147
  }
4065
4148
  const recoveredSessionId = this.recoverSession();
@@ -4282,7 +4365,7 @@ var init_session_handler = __esm({
4282
4365
  return;
4283
4366
  }
4284
4367
  if (this.destroyed) {
4285
- log("warn", "Cannot start tracking on destroyed handler");
4368
+ log("debug", "Cannot start tracking on destroyed handler");
4286
4369
  return;
4287
4370
  }
4288
4371
  const config = this.get("config");
@@ -4518,7 +4601,7 @@ var init_click_handler = __esm({
4518
4601
  const target = mouseEvent.target;
4519
4602
  const clickedElement = typeof HTMLElement !== "undefined" && target instanceof HTMLElement ? target : typeof HTMLElement !== "undefined" && target instanceof Node && target.parentElement instanceof HTMLElement ? target.parentElement : null;
4520
4603
  if (!clickedElement) {
4521
- log("warn", "Click target not found or not an element");
4604
+ log("debug", "Click target not found or not an element");
4522
4605
  return;
4523
4606
  }
4524
4607
  if (this.shouldIgnoreElement(clickedElement)) {
@@ -4680,7 +4763,7 @@ var init_click_handler = __esm({
4680
4763
  return parent;
4681
4764
  }
4682
4765
  } catch (error) {
4683
- log("warn", "Invalid selector in element search", { error, data: { selector } });
4766
+ log("debug", "Invalid selector in element search", { error, data: { selector } });
4684
4767
  continue;
4685
4768
  }
4686
4769
  }
@@ -5062,7 +5145,7 @@ var init_scroll_handler = __esm({
5062
5145
  return;
5063
5146
  }
5064
5147
  this.limitWarningLogged = true;
5065
- log("warn", "Max scroll events per session reached", {
5148
+ log("debug", "Max scroll events per session reached", {
5066
5149
  data: { limit: this.maxEventsPerSession }
5067
5150
  });
5068
5151
  }
@@ -5147,7 +5230,7 @@ var init_scroll_handler = __esm({
5147
5230
  } else {
5148
5231
  const element = document.querySelector(selector);
5149
5232
  if (!(element instanceof HTMLElement)) {
5150
- log("warn", `Selector "${selector}" did not match an HTMLElement`);
5233
+ log("debug", `Selector "${selector}" did not match an HTMLElement`);
5151
5234
  return;
5152
5235
  }
5153
5236
  targetElement = element;
@@ -5200,15 +5283,15 @@ var init_viewport_handler = __esm({
5200
5283
  const threshold = this.config.threshold ?? 0.5;
5201
5284
  const minDwellTime = this.config.minDwellTime ?? 1e3;
5202
5285
  if (threshold < 0 || threshold > 1) {
5203
- log("warn", "ViewportHandler: Invalid threshold, must be between 0 and 1");
5286
+ log("debug", "ViewportHandler: Invalid threshold, must be between 0 and 1");
5204
5287
  return;
5205
5288
  }
5206
5289
  if (minDwellTime < 0) {
5207
- log("warn", "ViewportHandler: Invalid minDwellTime, must be non-negative");
5290
+ log("debug", "ViewportHandler: Invalid minDwellTime, must be non-negative");
5208
5291
  return;
5209
5292
  }
5210
5293
  if (typeof IntersectionObserver === "undefined") {
5211
- log("warn", "ViewportHandler: IntersectionObserver not supported in this browser");
5294
+ log("debug", "ViewportHandler: IntersectionObserver not supported in this browser");
5212
5295
  return;
5213
5296
  }
5214
5297
  this.observer = new IntersectionObserver(this.handleIntersection, {
@@ -5252,7 +5335,7 @@ var init_viewport_handler = __esm({
5252
5335
  const elements = document.querySelectorAll(elementConfig.selector);
5253
5336
  for (const element of Array.from(elements)) {
5254
5337
  if (totalTracked >= maxTrackedElements) {
5255
- log("warn", "ViewportHandler: Maximum tracked elements reached", {
5338
+ log("debug", "ViewportHandler: Maximum tracked elements reached", {
5256
5339
  data: {
5257
5340
  limit: maxTrackedElements,
5258
5341
  selector: elementConfig.selector,
@@ -5280,7 +5363,7 @@ var init_viewport_handler = __esm({
5280
5363
  totalTracked++;
5281
5364
  }
5282
5365
  } catch (error) {
5283
- log("warn", `ViewportHandler: Invalid selector "${elementConfig.selector}"`, { error });
5366
+ log("debug", `ViewportHandler: Invalid selector "${elementConfig.selector}"`, { error });
5284
5367
  }
5285
5368
  }
5286
5369
  log("debug", "ViewportHandler: Elements tracked", {
@@ -5360,7 +5443,7 @@ var init_viewport_handler = __esm({
5360
5443
  return;
5361
5444
  }
5362
5445
  if (!document.body) {
5363
- log("warn", "ViewportHandler: document.body not available, skipping MutationObserver setup");
5446
+ log("debug", "ViewportHandler: document.body not available, skipping MutationObserver setup");
5364
5447
  return;
5365
5448
  }
5366
5449
  this.mutationObserver = new MutationObserver((mutations) => {
@@ -5435,10 +5518,10 @@ var init_storage_manager = __esm({
5435
5518
  this.storage = this.initializeStorage("localStorage");
5436
5519
  this.sessionStorageRef = this.initializeStorage("sessionStorage");
5437
5520
  if (!this.storage) {
5438
- log("warn", "localStorage not available, using memory fallback");
5521
+ log("debug", "localStorage not available, using memory fallback");
5439
5522
  }
5440
5523
  if (!this.sessionStorageRef) {
5441
- log("warn", "sessionStorage not available, using memory fallback");
5524
+ log("debug", "sessionStorage not available, using memory fallback");
5442
5525
  }
5443
5526
  }
5444
5527
  /**
@@ -5824,7 +5907,7 @@ var init_performance_handler = __esm({
5824
5907
  try {
5825
5908
  obs.disconnect();
5826
5909
  } catch (error) {
5827
- log("warn", "Failed to disconnect performance observer", { error, data: { observerIndex: index } });
5910
+ log("debug", "Failed to disconnect performance observer", { error, data: { observerIndex: index } });
5828
5911
  }
5829
5912
  });
5830
5913
  this.observers.length = 0;
@@ -5909,7 +5992,7 @@ var init_performance_handler = __esm({
5909
5992
  onTTFB(report("TTFB"), { reportAllChanges: false });
5910
5993
  onINP(report("INP"), { reportAllChanges: false });
5911
5994
  } catch (error) {
5912
- log("warn", "Failed to load web-vitals library, using fallback", { error });
5995
+ log("debug", "Failed to load web-vitals library, using fallback", { error });
5913
5996
  this.observeWebVitalsFallback();
5914
5997
  }
5915
5998
  }
@@ -5924,7 +6007,7 @@ var init_performance_handler = __esm({
5924
6007
  this.sendVital({ type: "TTFB", value: Number(ttfb.toFixed(PRECISION_TWO_DECIMALS)) });
5925
6008
  }
5926
6009
  } catch (error) {
5927
- log("warn", "Failed to report TTFB", { error });
6010
+ log("debug", "Failed to report TTFB", { error });
5928
6011
  }
5929
6012
  }
5930
6013
  observeLongTasks() {
@@ -5974,7 +6057,7 @@ var init_performance_handler = __esm({
5974
6057
  }
5975
6058
  trackWebVital(type, value) {
5976
6059
  if (!Number.isFinite(value)) {
5977
- log("warn", "Invalid web vital value", { data: { type, value } });
6060
+ log("debug", "Invalid web vital value", { data: { type, value } });
5978
6061
  return;
5979
6062
  }
5980
6063
  this.eventManager.track({
@@ -6017,7 +6100,7 @@ var init_performance_handler = __esm({
6017
6100
  const baseId = `${timestamp.toFixed(2)}_${window.location.pathname}`;
6018
6101
  return counter > 1 ? `${baseId}_${counter}` : baseId;
6019
6102
  } catch (error) {
6020
- log("warn", "Failed to get navigation ID", { error });
6103
+ log("debug", "Failed to get navigation ID", { error });
6021
6104
  return null;
6022
6105
  }
6023
6106
  }
@@ -6035,7 +6118,7 @@ var init_performance_handler = __esm({
6035
6118
  try {
6036
6119
  cb(list, observer);
6037
6120
  } catch (callbackError) {
6038
- log("warn", "Observer callback failed", {
6121
+ log("debug", "Observer callback failed", {
6039
6122
  error: callbackError,
6040
6123
  data: { type }
6041
6124
  });
@@ -6053,7 +6136,7 @@ var init_performance_handler = __esm({
6053
6136
  }
6054
6137
  return true;
6055
6138
  } catch (error) {
6056
- log("warn", "Failed to create performance observer", {
6139
+ log("debug", "Failed to create performance observer", {
6057
6140
  error,
6058
6141
  data: { type }
6059
6142
  });
@@ -6062,7 +6145,7 @@ var init_performance_handler = __esm({
6062
6145
  }
6063
6146
  shouldSendVital(type, value) {
6064
6147
  if (typeof value !== "number" || !Number.isFinite(value)) {
6065
- log("warn", "Invalid web vital value", { data: { type, value } });
6148
+ log("debug", "Invalid web vital value", { data: { type, value } });
6066
6149
  return false;
6067
6150
  }
6068
6151
  const threshold = this.vitalThresholds[type];
@@ -6134,7 +6217,7 @@ var init_error_handler = __esm({
6134
6217
  this.errorBurstCounter++;
6135
6218
  if (this.errorBurstCounter > ERROR_BURST_THRESHOLD) {
6136
6219
  this.burstBackoffUntil = now + ERROR_BURST_BACKOFF_MS;
6137
- log("warn", "Error burst detected - entering cooldown", {
6220
+ log("debug", "Error burst detected - entering cooldown", {
6138
6221
  data: {
6139
6222
  errorsInWindow: this.errorBurstCounter,
6140
6223
  cooldownMs: ERROR_BURST_BACKOFF_MS
@@ -6389,13 +6472,13 @@ var init_app = __esm({
6389
6472
  this.set("userId", userId);
6390
6473
  const collectApiUrls = getCollectApiUrls(config);
6391
6474
  this.set("collectApiUrls", collectApiUrls);
6392
- const device = getDeviceType();
6475
+ const device = getDeviceInfo();
6393
6476
  this.set("device", device);
6394
6477
  const pageUrl = normalizeUrl(window.location.href, config.sensitiveQueryParams);
6395
6478
  this.set("pageUrl", pageUrl);
6396
- const mode = detectQaMode() ? "qa" /* QA */ : void 0;
6397
- if (mode) {
6398
- this.set("mode", mode);
6479
+ const isQaMode = detectQaMode();
6480
+ if (isQaMode) {
6481
+ this.set("mode", "qa" /* QA */);
6399
6482
  }
6400
6483
  }
6401
6484
  /**
@@ -6495,7 +6578,6 @@ var init_app = __esm({
6495
6578
  }
6496
6579
  initializeHandlers() {
6497
6580
  const config = this.get("config");
6498
- const disabledEvents = config.disabledEvents ?? [];
6499
6581
  this.handlers.session = new SessionHandler(
6500
6582
  this.managers.storage,
6501
6583
  this.managers.event
@@ -6514,20 +6596,14 @@ var init_app = __esm({
6514
6596
  this.handlers.pageView.startTracking();
6515
6597
  this.handlers.click = new ClickHandler(this.managers.event);
6516
6598
  this.handlers.click.startTracking();
6517
- if (!disabledEvents.includes("scroll")) {
6518
- this.handlers.scroll = new ScrollHandler(this.managers.event);
6519
- this.handlers.scroll.startTracking();
6520
- }
6521
- if (!disabledEvents.includes("web_vitals")) {
6522
- this.handlers.performance = new PerformanceHandler(this.managers.event);
6523
- this.handlers.performance.startTracking().catch((error) => {
6524
- log("warn", "Failed to start performance tracking", { error });
6525
- });
6526
- }
6527
- if (!disabledEvents.includes("error")) {
6528
- this.handlers.error = new ErrorHandler(this.managers.event);
6529
- this.handlers.error.startTracking();
6530
- }
6599
+ this.handlers.scroll = new ScrollHandler(this.managers.event);
6600
+ this.handlers.scroll.startTracking();
6601
+ this.handlers.performance = new PerformanceHandler(this.managers.event);
6602
+ this.handlers.performance.startTracking().catch((error) => {
6603
+ log("warn", "Failed to start performance tracking", { error });
6604
+ });
6605
+ this.handlers.error = new ErrorHandler(this.managers.event);
6606
+ this.handlers.error.startTracking();
6531
6607
  if (config.viewport) {
6532
6608
  this.handlers.viewport = new ViewportHandler(this.managers.event);
6533
6609
  this.handlers.viewport.startTracking();
@@ -6548,7 +6624,7 @@ var init_test_bridge = __esm({
6548
6624
  "src/test-bridge.ts"() {
6549
6625
  init_app();
6550
6626
  init_api();
6551
- init_qa_mode_utils();
6627
+ init_mode_utils();
6552
6628
  TestBridge = class extends App {
6553
6629
  constructor() {
6554
6630
  super();
@@ -7025,7 +7101,7 @@ var init_api = __esm({
7025
7101
  }
7026
7102
  }).catch(() => {
7027
7103
  });
7028
- void Promise.resolve().then(() => (init_qa_mode_utils(), qa_mode_utils_exports)).then((module) => {
7104
+ void Promise.resolve().then(() => (init_mode_utils(), mode_utils_exports)).then((module) => {
7029
7105
  if (typeof module.detectQaMode === "function") {
7030
7106
  module.detectQaMode();
7031
7107
  }