@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.

@@ -267,12 +267,6 @@ var init_event_types = __esm({
267
267
  }
268
268
  });
269
269
 
270
- // src/types/log.types.ts
271
- var init_log_types = __esm({
272
- "src/types/log.types.ts"() {
273
- }
274
- });
275
-
276
270
  // src/types/mode.types.ts
277
271
  exports.Mode = void 0;
278
272
  var init_mode_types = __esm({
@@ -387,7 +381,6 @@ var init_types = __esm({
387
381
  init_emitter_types();
388
382
  init_error_types();
389
383
  init_event_types();
390
- init_log_types();
391
384
  init_mode_types();
392
385
  init_queue_types();
393
386
  init_scroll_types();
@@ -400,10 +393,22 @@ var init_types = __esm({
400
393
  }
401
394
  });
402
395
 
396
+ // src/constants/app.constants.ts
397
+ var LOG_STYLE_ACTIVE, LOG_STYLE_DISABLED, LOG_STYLE_CRITICAL;
398
+ var init_app_constants = __esm({
399
+ "src/constants/app.constants.ts"() {
400
+ LOG_STYLE_ACTIVE = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
401
+ LOG_STYLE_DISABLED = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
402
+ LOG_STYLE_CRITICAL = "background: #d32f2f; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
403
+ }
404
+ });
405
+
403
406
  // src/utils/logging.utils.ts
404
- var formatLogMsg, log, sanitizeLogData;
407
+ var formatLogMsg, isQaModeActive, log, shouldShowLog, getEffectiveStyle, outputLog, sanitizeLogData;
405
408
  var init_logging_utils = __esm({
406
409
  "src/utils/logging.utils.ts"() {
410
+ init_storage_constants();
411
+ init_app_constants();
407
412
  formatLogMsg = (msg, error) => {
408
413
  if (error) {
409
414
  if (process.env.NODE_ENV !== "development" && error instanceof Error) {
@@ -427,27 +432,59 @@ var init_logging_utils = __esm({
427
432
  }
428
433
  return `[TraceLog] ${msg}`;
429
434
  };
435
+ isQaModeActive = () => {
436
+ if (typeof window === "undefined" || typeof sessionStorage === "undefined") {
437
+ return false;
438
+ }
439
+ try {
440
+ return sessionStorage.getItem(QA_MODE_KEY) === "true";
441
+ } catch {
442
+ return false;
443
+ }
444
+ };
430
445
  log = (type, msg, extra) => {
431
- const { error, data, showToClient = false, style } = extra ?? {};
446
+ const { error, data, showToClient = false, style, visibility } = extra ?? {};
432
447
  const formattedMsg = error ? formatLogMsg(msg, error) : `[TraceLog] ${msg}`;
433
448
  const method = type === "error" ? "error" : type === "warn" ? "warn" : "log";
434
449
  const isProduction = process.env.NODE_ENV !== "development";
435
- if (isProduction) {
436
- if (type === "debug") {
437
- return;
438
- }
439
- if (type === "info" && !showToClient) {
440
- return;
441
- }
450
+ if (!isProduction) {
451
+ outputLog(method, formattedMsg, style, data);
452
+ return;
453
+ }
454
+ const shouldShow = shouldShowLog(visibility, showToClient);
455
+ if (!shouldShow) {
456
+ return;
457
+ }
458
+ const effectiveStyle = getEffectiveStyle(visibility, style);
459
+ const sanitizedData = data !== void 0 ? sanitizeLogData(data) : void 0;
460
+ outputLog(method, formattedMsg, effectiveStyle, sanitizedData);
461
+ };
462
+ shouldShowLog = (visibility, showToClient) => {
463
+ if (visibility === "critical") {
464
+ return true;
442
465
  }
466
+ if (visibility === "qa" || showToClient) {
467
+ return isQaModeActive();
468
+ }
469
+ return false;
470
+ };
471
+ getEffectiveStyle = (visibility, providedStyle) => {
472
+ if (providedStyle !== void 0 && providedStyle !== "") {
473
+ return providedStyle;
474
+ }
475
+ if (visibility === "critical") {
476
+ return LOG_STYLE_CRITICAL;
477
+ }
478
+ return "";
479
+ };
480
+ outputLog = (method, formattedMsg, style, data) => {
443
481
  const hasStyle = style !== void 0 && style !== "";
444
482
  const styledMsg = hasStyle ? `%c${formattedMsg}` : formattedMsg;
445
483
  if (data !== void 0) {
446
- const sanitizedData = isProduction ? sanitizeLogData(data) : data;
447
484
  if (hasStyle) {
448
- console[method](styledMsg, style, sanitizedData);
485
+ console[method](styledMsg, style, data);
449
486
  } else {
450
- console[method](styledMsg, sanitizedData);
487
+ console[method](styledMsg, data);
451
488
  }
452
489
  } else {
453
490
  if (hasStyle) {
@@ -482,7 +519,7 @@ var init_logging_utils = __esm({
482
519
  });
483
520
 
484
521
  // src/utils/browser/device-detector.utils.ts
485
- var coarsePointerQuery, noHoverQuery, initMediaQueries, getDeviceType;
522
+ var coarsePointerQuery, noHoverQuery, initMediaQueries, UNKNOWN, detectOS, detectBrowser, getDeviceType, getDeviceInfo;
486
523
  var init_device_detector_utils = __esm({
487
524
  "src/utils/browser/device-detector.utils.ts"() {
488
525
  init_device_types();
@@ -493,11 +530,53 @@ var init_device_detector_utils = __esm({
493
530
  noHoverQuery = window.matchMedia("(hover: none)");
494
531
  }
495
532
  };
533
+ UNKNOWN = "Unknown";
534
+ detectOS = (nav) => {
535
+ const platform = nav.userAgentData?.platform;
536
+ if (platform != null && platform !== "") {
537
+ if (/windows/i.test(platform)) return "Windows";
538
+ if (/macos/i.test(platform)) return "macOS";
539
+ if (/android/i.test(platform)) return "Android";
540
+ if (/linux/i.test(platform)) return "Linux";
541
+ if (/chromeos/i.test(platform)) return "ChromeOS";
542
+ if (/ios/i.test(platform)) return "iOS";
543
+ }
544
+ const ua = navigator.userAgent;
545
+ if (/Windows/i.test(ua)) return "Windows";
546
+ if (/iPhone|iPad|iPod/i.test(ua)) return "iOS";
547
+ if (/Mac OS X|Macintosh/i.test(ua)) return "macOS";
548
+ if (/Android/i.test(ua)) return "Android";
549
+ if (/CrOS/i.test(ua)) return "ChromeOS";
550
+ if (/Linux/i.test(ua)) return "Linux";
551
+ return UNKNOWN;
552
+ };
553
+ detectBrowser = (nav) => {
554
+ const brands = nav.userAgentData?.brands;
555
+ if (brands != null && brands.length > 0) {
556
+ const validBrands = brands.filter((b) => !/not.?a.?brand|chromium/i.test(b.brand));
557
+ const firstBrand = validBrands[0];
558
+ if (firstBrand != null) {
559
+ const brand = firstBrand.brand;
560
+ if (/google chrome/i.test(brand)) return "Chrome";
561
+ if (/microsoft edge/i.test(brand)) return "Edge";
562
+ if (/opera/i.test(brand)) return "Opera";
563
+ return brand;
564
+ }
565
+ }
566
+ const ua = navigator.userAgent;
567
+ if (/Edg\//i.test(ua)) return "Edge";
568
+ if (/OPR\//i.test(ua)) return "Opera";
569
+ if (/Chrome/i.test(ua)) return "Chrome";
570
+ if (/Firefox/i.test(ua)) return "Firefox";
571
+ if (/Safari/i.test(ua) && !/Chrome/i.test(ua)) return "Safari";
572
+ return UNKNOWN;
573
+ };
496
574
  getDeviceType = () => {
497
575
  try {
498
576
  const nav = navigator;
499
- if (nav.userAgentData && typeof nav.userAgentData.mobile === "boolean") {
500
- if (nav.userAgentData.platform && /ipad|tablet/i.test(nav.userAgentData.platform)) {
577
+ if (nav.userAgentData != null && typeof nav.userAgentData.mobile === "boolean") {
578
+ const uaPlatform = nav.userAgentData.platform;
579
+ if (uaPlatform != null && uaPlatform !== "" && /ipad|tablet/i.test(uaPlatform)) {
501
580
  return "tablet" /* Tablet */;
502
581
  }
503
582
  const result = nav.userAgentData.mobile ? "mobile" /* Mobile */ : "desktop" /* Desktop */;
@@ -519,27 +598,27 @@ var init_device_detector_utils = __esm({
519
598
  }
520
599
  return "desktop" /* Desktop */;
521
600
  } catch (error) {
522
- log("warn", "Device detection failed, defaulting to desktop", { error });
601
+ log("debug", "Device detection failed, defaulting to desktop", { error });
523
602
  return "desktop" /* Desktop */;
524
603
  }
525
604
  };
526
- }
527
- });
528
-
529
- // src/constants/app.constants.ts
530
- var LOG_STYLE_ACTIVE, LOG_STYLE_DISABLED;
531
- var init_app_constants = __esm({
532
- "src/constants/app.constants.ts"() {
533
- LOG_STYLE_ACTIVE = "background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
534
- LOG_STYLE_DISABLED = "background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;";
535
- }
536
- });
537
-
538
- // src/constants/disabled-events.constants.ts
539
- var DISABLEABLE_EVENT_TYPES;
540
- var init_disabled_events_constants = __esm({
541
- "src/constants/disabled-events.constants.ts"() {
542
- DISABLEABLE_EVENT_TYPES = ["scroll", "web_vitals", "error"];
605
+ getDeviceInfo = () => {
606
+ try {
607
+ const nav = navigator;
608
+ return {
609
+ type: getDeviceType(),
610
+ os: detectOS(nav),
611
+ browser: detectBrowser(nav)
612
+ };
613
+ } catch (error) {
614
+ log("debug", "Device info detection failed, using defaults", { error });
615
+ return {
616
+ type: "desktop" /* Desktop */,
617
+ os: UNKNOWN,
618
+ browser: UNKNOWN
619
+ };
620
+ }
621
+ };
543
622
  }
544
623
  });
545
624
 
@@ -641,7 +720,7 @@ var init_performance_constants = __esm({
641
720
  var version;
642
721
  var init_package = __esm({
643
722
  "package.json"() {
644
- version = "2.0.1";
723
+ version = "2.0.3";
645
724
  }
646
725
  });
647
726
 
@@ -659,7 +738,6 @@ var init_constants = __esm({
659
738
  "src/constants/index.ts"() {
660
739
  init_app_constants();
661
740
  init_config_constants();
662
- init_disabled_events_constants();
663
741
  init_error_constants();
664
742
  init_storage_constants();
665
743
  init_performance_constants();
@@ -667,19 +745,33 @@ var init_constants = __esm({
667
745
  }
668
746
  });
669
747
 
670
- // src/utils/browser/qa-mode.utils.ts
671
- var qa_mode_utils_exports = {};
672
- __export(qa_mode_utils_exports, {
748
+ // src/utils/browser/mode.utils.ts
749
+ var mode_utils_exports = {};
750
+ __export(mode_utils_exports, {
673
751
  detectQaMode: () => detectQaMode,
752
+ isQaModeActive: () => isQaModeActive2,
674
753
  setQaMode: () => setQaMode
675
754
  });
676
- var detectQaMode, setQaMode;
677
- var init_qa_mode_utils = __esm({
678
- "src/utils/browser/qa-mode.utils.ts"() {
755
+ var isBrowserEnvironment, cleanUrlParameter, detectQaMode, setQaMode, isQaModeActive2;
756
+ var init_mode_utils = __esm({
757
+ "src/utils/browser/mode.utils.ts"() {
679
758
  init_constants();
680
759
  init_logging_utils();
760
+ isBrowserEnvironment = () => {
761
+ return typeof window !== "undefined" && typeof sessionStorage !== "undefined";
762
+ };
763
+ cleanUrlParameter = () => {
764
+ try {
765
+ const params = new URLSearchParams(window.location.search);
766
+ params.delete(QA_MODE_URL_PARAM);
767
+ const search = params.toString();
768
+ const url = window.location.pathname + (search ? "?" + search : "") + window.location.hash;
769
+ window.history.replaceState({}, "", url);
770
+ } catch {
771
+ }
772
+ };
681
773
  detectQaMode = () => {
682
- if (typeof window === "undefined" || typeof document === "undefined") {
774
+ if (!isBrowserEnvironment()) {
683
775
  return false;
684
776
  }
685
777
  try {
@@ -691,25 +783,19 @@ var init_qa_mode_utils = __esm({
691
783
  newState = true;
692
784
  sessionStorage.setItem(QA_MODE_KEY, "true");
693
785
  log("info", "QA Mode ACTIVE", {
694
- showToClient: true,
786
+ visibility: "qa",
695
787
  style: LOG_STYLE_ACTIVE
696
788
  });
697
789
  } else if (urlParam === QA_MODE_DISABLE_VALUE) {
698
790
  newState = false;
699
791
  sessionStorage.setItem(QA_MODE_KEY, "false");
700
792
  log("info", "QA Mode DISABLED", {
701
- showToClient: true,
793
+ visibility: "qa",
702
794
  style: LOG_STYLE_DISABLED
703
795
  });
704
796
  }
705
797
  if (urlParam === QA_MODE_ENABLE_VALUE || urlParam === QA_MODE_DISABLE_VALUE) {
706
- try {
707
- params.delete(QA_MODE_URL_PARAM);
708
- const search = params.toString();
709
- const url = window.location.pathname + (search ? "?" + search : "") + window.location.hash;
710
- window.history.replaceState({}, "", url);
711
- } catch {
712
- }
798
+ cleanUrlParameter();
713
799
  }
714
800
  return newState ?? storedState === "true";
715
801
  } catch {
@@ -717,25 +803,27 @@ var init_qa_mode_utils = __esm({
717
803
  }
718
804
  };
719
805
  setQaMode = (enabled) => {
720
- if (typeof window === "undefined" || typeof document === "undefined") {
806
+ if (!isBrowserEnvironment()) {
721
807
  return;
722
808
  }
723
809
  try {
724
- if (enabled) {
725
- sessionStorage.setItem(QA_MODE_KEY, "true");
726
- log("info", "QA Mode ENABLED", {
727
- showToClient: true,
728
- style: LOG_STYLE_ACTIVE
729
- });
730
- } else {
731
- sessionStorage.setItem(QA_MODE_KEY, "false");
732
- log("info", "QA Mode DISABLED", {
733
- showToClient: true,
734
- style: LOG_STYLE_DISABLED
735
- });
736
- }
810
+ sessionStorage.setItem(QA_MODE_KEY, enabled ? "true" : "false");
811
+ log("info", enabled ? "QA Mode ACTIVE" : "QA Mode DISABLED", {
812
+ visibility: "qa",
813
+ style: enabled ? LOG_STYLE_ACTIVE : LOG_STYLE_DISABLED
814
+ });
737
815
  } catch {
738
- log("warn", "Cannot set QA mode: sessionStorage unavailable");
816
+ log("debug", "Cannot set QA mode: sessionStorage unavailable");
817
+ }
818
+ };
819
+ isQaModeActive2 = () => {
820
+ if (!isBrowserEnvironment()) {
821
+ return false;
822
+ }
823
+ try {
824
+ return sessionStorage.getItem(QA_MODE_KEY) === "true";
825
+ } catch {
826
+ return false;
739
827
  }
740
828
  };
741
829
  }
@@ -766,7 +854,7 @@ var init_utm_params_utils = __esm({
766
854
  var init_browser = __esm({
767
855
  "src/utils/browser/index.ts"() {
768
856
  init_device_detector_utils();
769
- init_qa_mode_utils();
857
+ init_mode_utils();
770
858
  init_utm_params_utils();
771
859
  }
772
860
  });
@@ -896,7 +984,7 @@ var init_url_utils = __esm({
896
984
  };
897
985
  normalizeUrl = (url, sensitiveQueryParams = []) => {
898
986
  if (!url || typeof url !== "string") {
899
- log("warn", "Invalid URL provided to normalizeUrl", { data: { url: String(url) } });
987
+ log("warn", "Invalid URL provided to normalizeUrl", { data: { type: typeof url } });
900
988
  return url || "";
901
989
  }
902
990
  try {
@@ -919,8 +1007,7 @@ var init_url_utils = __esm({
919
1007
  const result = urlObject.toString();
920
1008
  return result;
921
1009
  } catch (error) {
922
- const urlPreview = url && typeof url === "string" ? url.slice(0, 100) : String(url);
923
- log("warn", "URL normalization failed, returning original", { error, data: { url: urlPreview } });
1010
+ log("warn", "URL normalization failed, returning original", { error, data: { urlLength: url?.length } });
924
1011
  return url;
925
1012
  }
926
1013
  };
@@ -960,7 +1047,7 @@ var init_sanitize_utils = __esm({
960
1047
  log("warn", "XSS patterns detected and removed", {
961
1048
  data: {
962
1049
  patternMatches: xssPatternMatches,
963
- originalValue: value.slice(0, 100)
1050
+ valueLength: value.length
964
1051
  }
965
1052
  });
966
1053
  }
@@ -1111,30 +1198,6 @@ var init_config_validations_utils = __esm({
1111
1198
  if (config.viewport !== void 0) {
1112
1199
  validateViewportConfig(config.viewport);
1113
1200
  }
1114
- if (config.disabledEvents !== void 0) {
1115
- if (!Array.isArray(config.disabledEvents)) {
1116
- throw new exports.AppConfigValidationError("disabledEvents must be an array", "config");
1117
- }
1118
- const uniqueEvents = /* @__PURE__ */ new Set();
1119
- for (const eventType of config.disabledEvents) {
1120
- if (typeof eventType !== "string") {
1121
- throw new exports.AppConfigValidationError("All disabled event types must be strings", "config");
1122
- }
1123
- if (!DISABLEABLE_EVENT_TYPES.includes(eventType)) {
1124
- throw new exports.AppConfigValidationError(
1125
- `Invalid disabled event type: "${eventType}". Must be one of: ${DISABLEABLE_EVENT_TYPES.join(", ")}`,
1126
- "config"
1127
- );
1128
- }
1129
- if (uniqueEvents.has(eventType)) {
1130
- throw new exports.AppConfigValidationError(
1131
- `Duplicate disabled event type found: "${eventType}". Each event type should appear only once.`,
1132
- "config"
1133
- );
1134
- }
1135
- uniqueEvents.add(eventType);
1136
- }
1137
- }
1138
1201
  if (config.webVitalsMode !== void 0) {
1139
1202
  if (typeof config.webVitalsMode !== "string") {
1140
1203
  throw new exports.AppConfigValidationError(
@@ -1262,8 +1325,7 @@ var init_config_validations_utils = __esm({
1262
1325
  samplingRate: config?.samplingRate ?? DEFAULT_SAMPLING_RATE,
1263
1326
  pageViewThrottleMs: config?.pageViewThrottleMs ?? DEFAULT_PAGE_VIEW_THROTTLE_MS,
1264
1327
  clickThrottleMs: config?.clickThrottleMs ?? DEFAULT_CLICK_THROTTLE_MS,
1265
- maxSameEventPerMinute: config?.maxSameEventPerMinute ?? MAX_SAME_EVENT_PER_MINUTE,
1266
- disabledEvents: config?.disabledEvents ?? []
1328
+ maxSameEventPerMinute: config?.maxSameEventPerMinute ?? MAX_SAME_EVENT_PER_MINUTE
1267
1329
  };
1268
1330
  if (normalizedConfig.integrations?.custom) {
1269
1331
  normalizedConfig.integrations.custom = {
@@ -1501,7 +1563,6 @@ var init_event_validations_utils = __esm({
1501
1563
  const nameValidation = isValidEventName(eventName);
1502
1564
  if (!nameValidation.valid) {
1503
1565
  log("error", "Event name validation failed", {
1504
- showToClient: true,
1505
1566
  data: { eventName, error: nameValidation.error }
1506
1567
  });
1507
1568
  return nameValidation;
@@ -1512,7 +1573,6 @@ var init_event_validations_utils = __esm({
1512
1573
  const metadataValidation = isValidMetadata(eventName, metadata, "customEvent");
1513
1574
  if (!metadataValidation.valid) {
1514
1575
  log("error", "Event metadata validation failed", {
1515
- showToClient: true,
1516
1576
  data: {
1517
1577
  eventName,
1518
1578
  error: metadataValidation.error
@@ -1678,7 +1738,10 @@ function transformEvent(event2, transformer, context) {
1678
1738
  log("warn", `beforeSend transformer returned invalid data, using original [${context}]`);
1679
1739
  return event2;
1680
1740
  } catch (error) {
1681
- log("error", `beforeSend transformer threw error, using original event [${context}]`, { error });
1741
+ log("error", `beforeSend transformer threw error, using original event [${context}]`, {
1742
+ error,
1743
+ visibility: "critical"
1744
+ });
1682
1745
  return event2;
1683
1746
  }
1684
1747
  }
@@ -1704,7 +1767,8 @@ function transformBatch(batch, transformer, context) {
1704
1767
  } catch (error) {
1705
1768
  log("error", `beforeBatch transformer threw error, using original batch [${context}]`, {
1706
1769
  error,
1707
- data: { eventCount: batch.events.length }
1770
+ data: { eventCount: batch.events.length },
1771
+ visibility: "critical"
1708
1772
  });
1709
1773
  return batch;
1710
1774
  }
@@ -2207,7 +2271,7 @@ var init_sender_manager = __esm({
2207
2271
  return true;
2208
2272
  }
2209
2273
  if (this.apiUrl?.includes("localhost:9999" /* Fail */)) {
2210
- log("warn", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
2274
+ log("debug", `Fail mode: simulating network failure${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
2211
2275
  data: { events: transformedBody.events.length }
2212
2276
  });
2213
2277
  return false;
@@ -2434,7 +2498,7 @@ var init_sender_manager = __esm({
2434
2498
  return JSON.parse(persistedDataString);
2435
2499
  }
2436
2500
  } catch (error) {
2437
- log("warn", `Failed to parse persisted data${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2501
+ log("debug", `Failed to parse persisted data${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2438
2502
  this.clearPersistedEvents();
2439
2503
  }
2440
2504
  return null;
@@ -2513,7 +2577,7 @@ var init_sender_manager = __esm({
2513
2577
  this.storeManager.setItem(storageKey, JSON.stringify(persistedData));
2514
2578
  return !!this.storeManager.getItem(storageKey);
2515
2579
  } catch (error) {
2516
- log("warn", `Failed to persist events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2580
+ log("debug", `Failed to persist events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2517
2581
  return false;
2518
2582
  }
2519
2583
  }
@@ -2522,7 +2586,9 @@ var init_sender_manager = __esm({
2522
2586
  const key = this.getQueueStorageKey();
2523
2587
  this.storeManager.removeItem(key);
2524
2588
  } catch (error) {
2525
- log("warn", `Failed to clear persisted events${this.integrationId ? ` [${this.integrationId}]` : ""}`, { error });
2589
+ log("debug", `Failed to clear persisted events${this.integrationId ? ` [${this.integrationId}]` : ""}`, {
2590
+ error
2591
+ });
2526
2592
  }
2527
2593
  }
2528
2594
  shouldSkipSend() {
@@ -2597,7 +2663,7 @@ var init_time_manager = __esm({
2597
2663
  } else {
2598
2664
  this.bootTime = 0;
2599
2665
  this.bootTimestamp = Date.now();
2600
- log("warn", "performance.now() not available, falling back to Date.now()");
2666
+ log("debug", "performance.now() not available, falling back to Date.now()");
2601
2667
  }
2602
2668
  }
2603
2669
  /**
@@ -2832,7 +2898,7 @@ var init_event_manager = __esm({
2832
2898
  }
2833
2899
  },
2834
2900
  onFailure: () => {
2835
- log("warn", "Failed to recover persisted events");
2901
+ log("debug", "Failed to recover persisted events");
2836
2902
  }
2837
2903
  })
2838
2904
  );
@@ -2916,7 +2982,7 @@ var init_event_manager = __esm({
2916
2982
  if (!currentSessionId) {
2917
2983
  if (this.pendingEventsBuffer.length >= MAX_PENDING_EVENTS_BUFFER) {
2918
2984
  this.pendingEventsBuffer.shift();
2919
- log("warn", "Pending events buffer full - dropping oldest event", {
2985
+ log("debug", "Pending events buffer full - dropping oldest event", {
2920
2986
  data: { maxBufferSize: MAX_PENDING_EVENTS_BUFFER }
2921
2987
  });
2922
2988
  }
@@ -3005,7 +3071,7 @@ var init_event_manager = __esm({
3005
3071
  return;
3006
3072
  }
3007
3073
  if (this.get("hasStartSession")) {
3008
- log("warn", "Duplicate session_start detected", {
3074
+ log("debug", "Duplicate session_start detected", {
3009
3075
  data: { sessionId: currentSessionId2 }
3010
3076
  });
3011
3077
  return;
@@ -3015,16 +3081,33 @@ var init_event_manager = __esm({
3015
3081
  if (this.isDuplicateEvent(payload)) {
3016
3082
  return;
3017
3083
  }
3018
- if (this.get("mode") === "qa" /* QA */ && eventType === "custom" /* CUSTOM */ && custom_event) {
3019
- log("info", `Custom Event: ${custom_event.name}`, {
3020
- showToClient: true,
3021
- data: {
3022
- name: custom_event.name,
3023
- ...custom_event.metadata && { metadata: custom_event.metadata }
3024
- }
3025
- });
3026
- this.emitEvent(payload);
3027
- return;
3084
+ if (this.get("mode") === "qa" /* QA */) {
3085
+ if (eventType === "custom" /* CUSTOM */ && custom_event) {
3086
+ log("info", `Custom Event: ${custom_event.name}`, {
3087
+ visibility: "qa",
3088
+ data: {
3089
+ name: custom_event.name,
3090
+ ...custom_event.metadata && { metadata: custom_event.metadata }
3091
+ }
3092
+ });
3093
+ this.emitEvent(payload);
3094
+ return;
3095
+ }
3096
+ if (eventType === "viewport_visible" /* VIEWPORT_VISIBLE */ && viewport_data) {
3097
+ const displayName = viewport_data.name || viewport_data.id || viewport_data.selector;
3098
+ log("info", `Viewport Visible: ${displayName}`, {
3099
+ visibility: "qa",
3100
+ data: {
3101
+ selector: viewport_data.selector,
3102
+ ...viewport_data.name && { name: viewport_data.name },
3103
+ ...viewport_data.id && { id: viewport_data.id },
3104
+ visibilityRatio: viewport_data.visibilityRatio,
3105
+ dwellTime: viewport_data.dwellTime
3106
+ }
3107
+ });
3108
+ this.emitEvent(payload);
3109
+ return;
3110
+ }
3028
3111
  }
3029
3112
  this.addToQueue(payload);
3030
3113
  if (!isCriticalEvent) {
@@ -3276,7 +3359,7 @@ var init_event_manager = __esm({
3276
3359
  }
3277
3360
  const currentSessionId = this.get("sessionId");
3278
3361
  if (!currentSessionId) {
3279
- log("warn", "Cannot flush pending events: session not initialized - keeping in buffer", {
3362
+ log("debug", "Cannot flush pending events: session not initialized - keeping in buffer", {
3280
3363
  data: { bufferedEventCount: this.pendingEventsBuffer.length }
3281
3364
  });
3282
3365
  return;
@@ -3318,7 +3401,7 @@ var init_event_manager = __esm({
3318
3401
  this.emitEventsQueue(body);
3319
3402
  } else {
3320
3403
  this.clearSendInterval();
3321
- log("warn", "Sync flush complete failure, events kept in queue for retry", {
3404
+ log("debug", "Sync flush complete failure, events kept in queue for retry", {
3322
3405
  data: { eventCount: eventIds.length }
3323
3406
  });
3324
3407
  }
@@ -3339,7 +3422,7 @@ var init_event_manager = __esm({
3339
3422
  this.clearSendInterval();
3340
3423
  this.emitEventsQueue(body);
3341
3424
  } else {
3342
- log("warn", "Async flush complete failure, events kept in queue for retry", {
3425
+ log("debug", "Async flush complete failure, events kept in queue for retry", {
3343
3426
  data: { eventCount: eventsToSend.length }
3344
3427
  });
3345
3428
  }
@@ -3373,12 +3456,12 @@ var init_event_manager = __esm({
3373
3456
  this.emitEventsQueue(body);
3374
3457
  const failedCount = results.filter((result) => !this.isSuccessfulResult(result)).length;
3375
3458
  if (failedCount > 0) {
3376
- log("warn", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
3459
+ log("debug", "Periodic send completed with some failures, removed from queue and persisted per-integration", {
3377
3460
  data: { eventCount: eventsToSend.length, failedCount }
3378
3461
  });
3379
3462
  }
3380
3463
  } else {
3381
- log("warn", "Periodic send complete failure, events kept in queue for retry", {
3464
+ log("debug", "Periodic send complete failure, events kept in queue for retry", {
3382
3465
  data: { eventCount: eventsToSend.length }
3383
3466
  });
3384
3467
  }
@@ -3475,7 +3558,7 @@ var init_event_manager = __esm({
3475
3558
  if (this.recentEventFingerprints.size > MAX_FINGERPRINTS_HARD_LIMIT) {
3476
3559
  this.recentEventFingerprints.clear();
3477
3560
  this.recentEventFingerprints.set(fingerprint, now);
3478
- log("warn", "Event fingerprint cache exceeded hard limit, cleared", {
3561
+ log("debug", "Event fingerprint cache exceeded hard limit, cleared", {
3479
3562
  data: { hardLimit: MAX_FINGERPRINTS_HARD_LIMIT }
3480
3563
  });
3481
3564
  }
@@ -3913,7 +3996,7 @@ var init_session_manager = __esm({
3913
3996
  }
3914
3997
  initCrossTabSync() {
3915
3998
  if (typeof BroadcastChannel === "undefined") {
3916
- log("warn", "BroadcastChannel not supported");
3999
+ log("debug", "BroadcastChannel not supported");
3917
4000
  return;
3918
4001
  }
3919
4002
  const projectId = this.getProjectId();
@@ -4061,7 +4144,7 @@ var init_session_manager = __esm({
4061
4144
  */
4062
4145
  startTracking() {
4063
4146
  if (this.isTracking) {
4064
- log("warn", "Session tracking already active");
4147
+ log("debug", "Session tracking already active");
4065
4148
  return;
4066
4149
  }
4067
4150
  const recoveredSessionId = this.recoverSession();
@@ -4284,7 +4367,7 @@ var init_session_handler = __esm({
4284
4367
  return;
4285
4368
  }
4286
4369
  if (this.destroyed) {
4287
- log("warn", "Cannot start tracking on destroyed handler");
4370
+ log("debug", "Cannot start tracking on destroyed handler");
4288
4371
  return;
4289
4372
  }
4290
4373
  const config = this.get("config");
@@ -4520,7 +4603,7 @@ var init_click_handler = __esm({
4520
4603
  const target = mouseEvent.target;
4521
4604
  const clickedElement = typeof HTMLElement !== "undefined" && target instanceof HTMLElement ? target : typeof HTMLElement !== "undefined" && target instanceof Node && target.parentElement instanceof HTMLElement ? target.parentElement : null;
4522
4605
  if (!clickedElement) {
4523
- log("warn", "Click target not found or not an element");
4606
+ log("debug", "Click target not found or not an element");
4524
4607
  return;
4525
4608
  }
4526
4609
  if (this.shouldIgnoreElement(clickedElement)) {
@@ -4682,7 +4765,7 @@ var init_click_handler = __esm({
4682
4765
  return parent;
4683
4766
  }
4684
4767
  } catch (error) {
4685
- log("warn", "Invalid selector in element search", { error, data: { selector } });
4768
+ log("debug", "Invalid selector in element search", { error, data: { selector } });
4686
4769
  continue;
4687
4770
  }
4688
4771
  }
@@ -5064,7 +5147,7 @@ var init_scroll_handler = __esm({
5064
5147
  return;
5065
5148
  }
5066
5149
  this.limitWarningLogged = true;
5067
- log("warn", "Max scroll events per session reached", {
5150
+ log("debug", "Max scroll events per session reached", {
5068
5151
  data: { limit: this.maxEventsPerSession }
5069
5152
  });
5070
5153
  }
@@ -5149,7 +5232,7 @@ var init_scroll_handler = __esm({
5149
5232
  } else {
5150
5233
  const element = document.querySelector(selector);
5151
5234
  if (!(element instanceof HTMLElement)) {
5152
- log("warn", `Selector "${selector}" did not match an HTMLElement`);
5235
+ log("debug", `Selector "${selector}" did not match an HTMLElement`);
5153
5236
  return;
5154
5237
  }
5155
5238
  targetElement = element;
@@ -5202,15 +5285,15 @@ var init_viewport_handler = __esm({
5202
5285
  const threshold = this.config.threshold ?? 0.5;
5203
5286
  const minDwellTime = this.config.minDwellTime ?? 1e3;
5204
5287
  if (threshold < 0 || threshold > 1) {
5205
- log("warn", "ViewportHandler: Invalid threshold, must be between 0 and 1");
5288
+ log("debug", "ViewportHandler: Invalid threshold, must be between 0 and 1");
5206
5289
  return;
5207
5290
  }
5208
5291
  if (minDwellTime < 0) {
5209
- log("warn", "ViewportHandler: Invalid minDwellTime, must be non-negative");
5292
+ log("debug", "ViewportHandler: Invalid minDwellTime, must be non-negative");
5210
5293
  return;
5211
5294
  }
5212
5295
  if (typeof IntersectionObserver === "undefined") {
5213
- log("warn", "ViewportHandler: IntersectionObserver not supported in this browser");
5296
+ log("debug", "ViewportHandler: IntersectionObserver not supported in this browser");
5214
5297
  return;
5215
5298
  }
5216
5299
  this.observer = new IntersectionObserver(this.handleIntersection, {
@@ -5254,7 +5337,7 @@ var init_viewport_handler = __esm({
5254
5337
  const elements = document.querySelectorAll(elementConfig.selector);
5255
5338
  for (const element of Array.from(elements)) {
5256
5339
  if (totalTracked >= maxTrackedElements) {
5257
- log("warn", "ViewportHandler: Maximum tracked elements reached", {
5340
+ log("debug", "ViewportHandler: Maximum tracked elements reached", {
5258
5341
  data: {
5259
5342
  limit: maxTrackedElements,
5260
5343
  selector: elementConfig.selector,
@@ -5282,7 +5365,7 @@ var init_viewport_handler = __esm({
5282
5365
  totalTracked++;
5283
5366
  }
5284
5367
  } catch (error) {
5285
- log("warn", `ViewportHandler: Invalid selector "${elementConfig.selector}"`, { error });
5368
+ log("debug", `ViewportHandler: Invalid selector "${elementConfig.selector}"`, { error });
5286
5369
  }
5287
5370
  }
5288
5371
  log("debug", "ViewportHandler: Elements tracked", {
@@ -5362,7 +5445,7 @@ var init_viewport_handler = __esm({
5362
5445
  return;
5363
5446
  }
5364
5447
  if (!document.body) {
5365
- log("warn", "ViewportHandler: document.body not available, skipping MutationObserver setup");
5448
+ log("debug", "ViewportHandler: document.body not available, skipping MutationObserver setup");
5366
5449
  return;
5367
5450
  }
5368
5451
  this.mutationObserver = new MutationObserver((mutations) => {
@@ -5437,10 +5520,10 @@ var init_storage_manager = __esm({
5437
5520
  this.storage = this.initializeStorage("localStorage");
5438
5521
  this.sessionStorageRef = this.initializeStorage("sessionStorage");
5439
5522
  if (!this.storage) {
5440
- log("warn", "localStorage not available, using memory fallback");
5523
+ log("debug", "localStorage not available, using memory fallback");
5441
5524
  }
5442
5525
  if (!this.sessionStorageRef) {
5443
- log("warn", "sessionStorage not available, using memory fallback");
5526
+ log("debug", "sessionStorage not available, using memory fallback");
5444
5527
  }
5445
5528
  }
5446
5529
  /**
@@ -5826,7 +5909,7 @@ var init_performance_handler = __esm({
5826
5909
  try {
5827
5910
  obs.disconnect();
5828
5911
  } catch (error) {
5829
- log("warn", "Failed to disconnect performance observer", { error, data: { observerIndex: index } });
5912
+ log("debug", "Failed to disconnect performance observer", { error, data: { observerIndex: index } });
5830
5913
  }
5831
5914
  });
5832
5915
  this.observers.length = 0;
@@ -5911,7 +5994,7 @@ var init_performance_handler = __esm({
5911
5994
  onTTFB(report("TTFB"), { reportAllChanges: false });
5912
5995
  onINP(report("INP"), { reportAllChanges: false });
5913
5996
  } catch (error) {
5914
- log("warn", "Failed to load web-vitals library, using fallback", { error });
5997
+ log("debug", "Failed to load web-vitals library, using fallback", { error });
5915
5998
  this.observeWebVitalsFallback();
5916
5999
  }
5917
6000
  }
@@ -5926,7 +6009,7 @@ var init_performance_handler = __esm({
5926
6009
  this.sendVital({ type: "TTFB", value: Number(ttfb.toFixed(PRECISION_TWO_DECIMALS)) });
5927
6010
  }
5928
6011
  } catch (error) {
5929
- log("warn", "Failed to report TTFB", { error });
6012
+ log("debug", "Failed to report TTFB", { error });
5930
6013
  }
5931
6014
  }
5932
6015
  observeLongTasks() {
@@ -5976,7 +6059,7 @@ var init_performance_handler = __esm({
5976
6059
  }
5977
6060
  trackWebVital(type, value) {
5978
6061
  if (!Number.isFinite(value)) {
5979
- log("warn", "Invalid web vital value", { data: { type, value } });
6062
+ log("debug", "Invalid web vital value", { data: { type, value } });
5980
6063
  return;
5981
6064
  }
5982
6065
  this.eventManager.track({
@@ -6019,7 +6102,7 @@ var init_performance_handler = __esm({
6019
6102
  const baseId = `${timestamp.toFixed(2)}_${window.location.pathname}`;
6020
6103
  return counter > 1 ? `${baseId}_${counter}` : baseId;
6021
6104
  } catch (error) {
6022
- log("warn", "Failed to get navigation ID", { error });
6105
+ log("debug", "Failed to get navigation ID", { error });
6023
6106
  return null;
6024
6107
  }
6025
6108
  }
@@ -6037,7 +6120,7 @@ var init_performance_handler = __esm({
6037
6120
  try {
6038
6121
  cb(list, observer);
6039
6122
  } catch (callbackError) {
6040
- log("warn", "Observer callback failed", {
6123
+ log("debug", "Observer callback failed", {
6041
6124
  error: callbackError,
6042
6125
  data: { type }
6043
6126
  });
@@ -6055,7 +6138,7 @@ var init_performance_handler = __esm({
6055
6138
  }
6056
6139
  return true;
6057
6140
  } catch (error) {
6058
- log("warn", "Failed to create performance observer", {
6141
+ log("debug", "Failed to create performance observer", {
6059
6142
  error,
6060
6143
  data: { type }
6061
6144
  });
@@ -6064,7 +6147,7 @@ var init_performance_handler = __esm({
6064
6147
  }
6065
6148
  shouldSendVital(type, value) {
6066
6149
  if (typeof value !== "number" || !Number.isFinite(value)) {
6067
- log("warn", "Invalid web vital value", { data: { type, value } });
6150
+ log("debug", "Invalid web vital value", { data: { type, value } });
6068
6151
  return false;
6069
6152
  }
6070
6153
  const threshold = this.vitalThresholds[type];
@@ -6136,7 +6219,7 @@ var init_error_handler = __esm({
6136
6219
  this.errorBurstCounter++;
6137
6220
  if (this.errorBurstCounter > ERROR_BURST_THRESHOLD) {
6138
6221
  this.burstBackoffUntil = now + ERROR_BURST_BACKOFF_MS;
6139
- log("warn", "Error burst detected - entering cooldown", {
6222
+ log("debug", "Error burst detected - entering cooldown", {
6140
6223
  data: {
6141
6224
  errorsInWindow: this.errorBurstCounter,
6142
6225
  cooldownMs: ERROR_BURST_BACKOFF_MS
@@ -6391,13 +6474,13 @@ var init_app = __esm({
6391
6474
  this.set("userId", userId);
6392
6475
  const collectApiUrls = getCollectApiUrls(config);
6393
6476
  this.set("collectApiUrls", collectApiUrls);
6394
- const device = getDeviceType();
6477
+ const device = getDeviceInfo();
6395
6478
  this.set("device", device);
6396
6479
  const pageUrl = normalizeUrl(window.location.href, config.sensitiveQueryParams);
6397
6480
  this.set("pageUrl", pageUrl);
6398
- const mode = detectQaMode() ? "qa" /* QA */ : void 0;
6399
- if (mode) {
6400
- this.set("mode", mode);
6481
+ const isQaMode = detectQaMode();
6482
+ if (isQaMode) {
6483
+ this.set("mode", "qa" /* QA */);
6401
6484
  }
6402
6485
  }
6403
6486
  /**
@@ -6497,7 +6580,6 @@ var init_app = __esm({
6497
6580
  }
6498
6581
  initializeHandlers() {
6499
6582
  const config = this.get("config");
6500
- const disabledEvents = config.disabledEvents ?? [];
6501
6583
  this.handlers.session = new SessionHandler(
6502
6584
  this.managers.storage,
6503
6585
  this.managers.event
@@ -6516,20 +6598,14 @@ var init_app = __esm({
6516
6598
  this.handlers.pageView.startTracking();
6517
6599
  this.handlers.click = new ClickHandler(this.managers.event);
6518
6600
  this.handlers.click.startTracking();
6519
- if (!disabledEvents.includes("scroll")) {
6520
- this.handlers.scroll = new ScrollHandler(this.managers.event);
6521
- this.handlers.scroll.startTracking();
6522
- }
6523
- if (!disabledEvents.includes("web_vitals")) {
6524
- this.handlers.performance = new PerformanceHandler(this.managers.event);
6525
- this.handlers.performance.startTracking().catch((error) => {
6526
- log("warn", "Failed to start performance tracking", { error });
6527
- });
6528
- }
6529
- if (!disabledEvents.includes("error")) {
6530
- this.handlers.error = new ErrorHandler(this.managers.event);
6531
- this.handlers.error.startTracking();
6532
- }
6601
+ this.handlers.scroll = new ScrollHandler(this.managers.event);
6602
+ this.handlers.scroll.startTracking();
6603
+ this.handlers.performance = new PerformanceHandler(this.managers.event);
6604
+ this.handlers.performance.startTracking().catch((error) => {
6605
+ log("warn", "Failed to start performance tracking", { error });
6606
+ });
6607
+ this.handlers.error = new ErrorHandler(this.managers.event);
6608
+ this.handlers.error.startTracking();
6533
6609
  if (config.viewport) {
6534
6610
  this.handlers.viewport = new ViewportHandler(this.managers.event);
6535
6611
  this.handlers.viewport.startTracking();
@@ -6550,7 +6626,7 @@ var init_test_bridge = __esm({
6550
6626
  "src/test-bridge.ts"() {
6551
6627
  init_app();
6552
6628
  init_api();
6553
- init_qa_mode_utils();
6629
+ init_mode_utils();
6554
6630
  TestBridge = class extends App {
6555
6631
  constructor() {
6556
6632
  super();
@@ -7027,7 +7103,7 @@ var init_api = __esm({
7027
7103
  }
7028
7104
  }).catch(() => {
7029
7105
  });
7030
- void Promise.resolve().then(() => (init_qa_mode_utils(), qa_mode_utils_exports)).then((module) => {
7106
+ void Promise.resolve().then(() => (init_mode_utils(), mode_utils_exports)).then((module) => {
7031
7107
  if (typeof module.detectQaMode === "function") {
7032
7108
  module.detectQaMode();
7033
7109
  }