sobey-monitor-sdk 1.1.4 → 1.1.5
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/dist/index.cjs.js +137 -117
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +137 -117
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +137 -117
- package/dist/index.umd.js.map +1 -1
- package/dist/reporter/index.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs.js
CHANGED
|
@@ -278,13 +278,22 @@ class Sender {
|
|
|
278
278
|
* 策略:优先使用 sendBeacon(更可靠),不支持或失败时降级为 fetch
|
|
279
279
|
*/
|
|
280
280
|
doSend(data) {
|
|
281
|
+
// 检查配置是否已初始化
|
|
282
|
+
if (!config.isInitialized()) {
|
|
283
|
+
// 配置未初始化,数据放回缓冲区等待下次发送
|
|
284
|
+
this.buffer.unshift(...data);
|
|
285
|
+
this.scheduleFlush();
|
|
286
|
+
return;
|
|
287
|
+
}
|
|
281
288
|
const cfg = config.get();
|
|
282
289
|
const dsn = cfg.dsn;
|
|
283
|
-
// dsn
|
|
290
|
+
// dsn 未配置,将数据放回缓冲区等待下次发送
|
|
284
291
|
if (!dsn) {
|
|
285
292
|
if (cfg.debug) {
|
|
286
|
-
console.warn('[Monitor] dsn not configured,
|
|
293
|
+
console.warn('[Monitor] dsn not configured, buffering data for later');
|
|
287
294
|
}
|
|
295
|
+
this.buffer.unshift(...data);
|
|
296
|
+
this.scheduleFlush();
|
|
288
297
|
return;
|
|
289
298
|
}
|
|
290
299
|
const payload = JSON.stringify(data);
|
|
@@ -405,25 +414,83 @@ class Reporter {
|
|
|
405
414
|
}
|
|
406
415
|
}
|
|
407
416
|
/**
|
|
408
|
-
*
|
|
417
|
+
* 发送早期缓存的数据(根据最新配置过滤)
|
|
409
418
|
*/
|
|
410
419
|
flushEarlyBuffer() {
|
|
420
|
+
const cfg = config.get();
|
|
421
|
+
let skippedCount = 0;
|
|
422
|
+
// 全局开关检查:如果 enabled 为 false,清空缓存不上报
|
|
423
|
+
if (cfg.enabled === false) {
|
|
424
|
+
const totalCount = this.earlyBuffer.length;
|
|
425
|
+
this.earlyBuffer = [];
|
|
426
|
+
if (cfg.debug) {
|
|
427
|
+
console.log(`[Monitor] SDK disabled, discarded ${totalCount} early buffered items`);
|
|
428
|
+
}
|
|
429
|
+
return;
|
|
430
|
+
}
|
|
411
431
|
while (this.earlyBuffer.length > 0) {
|
|
412
432
|
const item = this.earlyBuffer.shift();
|
|
413
433
|
if (!item)
|
|
414
434
|
continue;
|
|
435
|
+
// 根据最新配置过滤数据
|
|
415
436
|
switch (item.type) {
|
|
416
437
|
case 'error':
|
|
438
|
+
// 检查错误监控是否启用
|
|
439
|
+
if (cfg.error?.enabled === false) {
|
|
440
|
+
skippedCount++;
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
// 根据错误类型检查具体开关
|
|
444
|
+
const errorType = item.data?.type;
|
|
445
|
+
if (errorType === 'js_error' && cfg.error?.jsError === false) {
|
|
446
|
+
skippedCount++;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (errorType === 'promise_error' && cfg.error?.promiseError === false) {
|
|
450
|
+
skippedCount++;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (errorType === 'resource_error' && cfg.error?.resourceError === false) {
|
|
454
|
+
skippedCount++;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
457
|
+
if (errorType === 'http_error' && cfg.error?.httpError === false) {
|
|
458
|
+
skippedCount++;
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
417
461
|
this.reportError(item.data);
|
|
418
462
|
break;
|
|
419
463
|
case 'performance':
|
|
464
|
+
// 检查性能监控是否启用
|
|
465
|
+
if (cfg.performance?.enabled === false) {
|
|
466
|
+
skippedCount++;
|
|
467
|
+
continue;
|
|
468
|
+
}
|
|
420
469
|
this.reportPerformance(item.data);
|
|
421
470
|
break;
|
|
422
471
|
case 'behavior':
|
|
472
|
+
// 检查行为监控是否启用
|
|
473
|
+
if (cfg.behavior?.enabled === false) {
|
|
474
|
+
skippedCount++;
|
|
475
|
+
continue;
|
|
476
|
+
}
|
|
477
|
+
// 根据行为类型检查具体开关
|
|
478
|
+
const action = item.data?.action;
|
|
479
|
+
if (action === 'pv' && cfg.behavior?.pv === false) {
|
|
480
|
+
skippedCount++;
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
483
|
+
if (action === 'route' && cfg.behavior?.route === false) {
|
|
484
|
+
skippedCount++;
|
|
485
|
+
continue;
|
|
486
|
+
}
|
|
423
487
|
this.reportBehavior(item.data);
|
|
424
488
|
break;
|
|
425
489
|
}
|
|
426
490
|
}
|
|
491
|
+
if (skippedCount > 0 && cfg.debug) {
|
|
492
|
+
console.log(`[Monitor] Filtered out ${skippedCount} early buffered items based on config`);
|
|
493
|
+
}
|
|
427
494
|
}
|
|
428
495
|
/**
|
|
429
496
|
* 缓存早期数据
|
|
@@ -552,17 +619,15 @@ const reporter = new Reporter();
|
|
|
552
619
|
*/
|
|
553
620
|
function installJsErrorHandler() {
|
|
554
621
|
window.addEventListener('error', (event) => {
|
|
555
|
-
// 延迟检查配置(SDK 可能还在加载配置)
|
|
556
|
-
if (config.isInitialized()) {
|
|
557
|
-
const cfg = config.get();
|
|
558
|
-
if (!cfg.error?.enabled || !cfg.error?.jsError) {
|
|
559
|
-
return;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
622
|
// 过滤资源加载错误(由 resourceError 处理)
|
|
563
623
|
if (event.target !== window) {
|
|
564
624
|
return;
|
|
565
625
|
}
|
|
626
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
627
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
628
|
+
if (cfg?.error?.enabled === false || cfg?.error?.jsError === false) {
|
|
629
|
+
return;
|
|
630
|
+
}
|
|
566
631
|
const errorData = {
|
|
567
632
|
type: 'js_error',
|
|
568
633
|
message: event.message || 'Unknown error',
|
|
@@ -583,6 +648,7 @@ function installJsErrorHandler() {
|
|
|
583
648
|
});
|
|
584
649
|
reporter.reportError(errorData);
|
|
585
650
|
}, true);
|
|
651
|
+
console.log('[Monitor] JS error handler installed');
|
|
586
652
|
}
|
|
587
653
|
|
|
588
654
|
/**
|
|
@@ -593,12 +659,10 @@ function installJsErrorHandler() {
|
|
|
593
659
|
*/
|
|
594
660
|
function installPromiseErrorHandler() {
|
|
595
661
|
window.addEventListener('unhandledrejection', (event) => {
|
|
596
|
-
//
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
return;
|
|
601
|
-
}
|
|
662
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
663
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
664
|
+
if (cfg?.error?.enabled === false || cfg?.error?.promiseError === false) {
|
|
665
|
+
return;
|
|
602
666
|
}
|
|
603
667
|
let message = 'Unhandled Promise rejection';
|
|
604
668
|
let stack;
|
|
@@ -628,6 +692,7 @@ function installPromiseErrorHandler() {
|
|
|
628
692
|
});
|
|
629
693
|
reporter.reportError(errorData);
|
|
630
694
|
});
|
|
695
|
+
console.log('[Monitor] Promise error handler installed');
|
|
631
696
|
}
|
|
632
697
|
|
|
633
698
|
/**
|
|
@@ -638,18 +703,16 @@ function installPromiseErrorHandler() {
|
|
|
638
703
|
*/
|
|
639
704
|
function installResourceErrorHandler() {
|
|
640
705
|
window.addEventListener('error', (event) => {
|
|
641
|
-
// 延迟检查配置(SDK 可能还在加载配置)
|
|
642
|
-
if (config.isInitialized()) {
|
|
643
|
-
const cfg = config.get();
|
|
644
|
-
if (!cfg.error?.enabled || !cfg.error?.resourceError) {
|
|
645
|
-
return;
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
706
|
const target = event.target;
|
|
649
707
|
// 只处理资源加载错误(target 不是 window)
|
|
650
708
|
if (!target || target === window || !(target instanceof HTMLElement)) {
|
|
651
709
|
return;
|
|
652
710
|
}
|
|
711
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
712
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
713
|
+
if (cfg?.error?.enabled === false || cfg?.error?.resourceError === false) {
|
|
714
|
+
return;
|
|
715
|
+
}
|
|
653
716
|
const tagName = target.tagName.toLowerCase();
|
|
654
717
|
// 只监控特定标签的资源
|
|
655
718
|
if (!['img', 'script', 'link', 'video', 'audio', 'source'].includes(tagName)) {
|
|
@@ -678,6 +741,7 @@ function installResourceErrorHandler() {
|
|
|
678
741
|
});
|
|
679
742
|
reporter.reportError(errorData);
|
|
680
743
|
}, true); // 使用捕获阶段
|
|
744
|
+
console.log('[Monitor] Resource error handler installed');
|
|
681
745
|
}
|
|
682
746
|
|
|
683
747
|
/**
|
|
@@ -694,6 +758,7 @@ const originalFetch = window.fetch;
|
|
|
694
758
|
function installHttpErrorHandler() {
|
|
695
759
|
interceptXHR();
|
|
696
760
|
interceptFetch();
|
|
761
|
+
console.log('[Monitor] HTTP error handler installed');
|
|
697
762
|
}
|
|
698
763
|
/**
|
|
699
764
|
* 检查是否是 SDK 自身的请求
|
|
@@ -706,18 +771,6 @@ function isSdkRequest(url) {
|
|
|
706
771
|
return false;
|
|
707
772
|
return url.includes(cfg.dsn);
|
|
708
773
|
}
|
|
709
|
-
/**
|
|
710
|
-
* 检查 HTTP 错误监控是否启用
|
|
711
|
-
*/
|
|
712
|
-
function isHttpErrorEnabled() {
|
|
713
|
-
if (!config.isInitialized())
|
|
714
|
-
return true; // 配置未就绪时默认启用,数据会被缓存
|
|
715
|
-
const cfg = config.get();
|
|
716
|
-
return cfg.error?.enabled !== false && cfg.error?.httpError !== false;
|
|
717
|
-
}
|
|
718
|
-
/**
|
|
719
|
-
* 拦截 XMLHttpRequest
|
|
720
|
-
*/
|
|
721
774
|
function interceptXHR() {
|
|
722
775
|
XMLHttpRequest.prototype.open = function (method, url, async = true, username, password) {
|
|
723
776
|
const urlStr = url.toString();
|
|
@@ -747,16 +800,11 @@ function interceptXHR() {
|
|
|
747
800
|
this.addEventListener('loadend', function () {
|
|
748
801
|
if (!monitorData)
|
|
749
802
|
return;
|
|
750
|
-
if (!isHttpErrorEnabled())
|
|
751
|
-
return;
|
|
752
803
|
const duration = Date.now() - monitorData.startTime;
|
|
753
804
|
const status = this.status;
|
|
754
805
|
// 根据配置决定是否添加到面包屑
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
const cfg = config.get();
|
|
758
|
-
recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
759
|
-
}
|
|
806
|
+
const cfg = config.get();
|
|
807
|
+
const recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
760
808
|
// 重定向(3xx)始终记录,不受配置控制
|
|
761
809
|
const isRedirect = status >= 300 && status < 400;
|
|
762
810
|
// 其他异常情况(0-网络错误、4xx-客户端错误、5xx-服务端错误)根据配置控制
|
|
@@ -803,17 +851,11 @@ function interceptFetch() {
|
|
|
803
851
|
const requestBody = typeof init?.body === 'string' ? init.body : undefined;
|
|
804
852
|
try {
|
|
805
853
|
const response = await originalFetch.call(window, input, init);
|
|
806
|
-
if (!isHttpErrorEnabled()) {
|
|
807
|
-
return response;
|
|
808
|
-
}
|
|
809
854
|
const duration = Date.now() - startTime;
|
|
810
855
|
const status = response.status;
|
|
811
856
|
// 根据配置决定是否添加到面包屑
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
const cfg = config.get();
|
|
815
|
-
recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
816
|
-
}
|
|
857
|
+
const cfg = config.get();
|
|
858
|
+
const recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
817
859
|
// 重定向(3xx)始终记录,不受配置控制
|
|
818
860
|
const isRedirect = status >= 300 && status < 400;
|
|
819
861
|
// 其他异常情况根据配置控制
|
|
@@ -852,16 +894,10 @@ function interceptFetch() {
|
|
|
852
894
|
return response;
|
|
853
895
|
}
|
|
854
896
|
catch (error) {
|
|
855
|
-
if (!isHttpErrorEnabled()) {
|
|
856
|
-
throw error;
|
|
857
|
-
}
|
|
858
897
|
const duration = Date.now() - startTime;
|
|
859
898
|
// 网络错误时根据配置决定是否添加到面包屑
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
const cfg = config.get();
|
|
863
|
-
recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
864
|
-
}
|
|
899
|
+
const cfg = config.get();
|
|
900
|
+
const recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
865
901
|
// 网络错误属于 error,当模式为 'all' 或 'error' 时都记录
|
|
866
902
|
if (recordMode !== 'none') {
|
|
867
903
|
context.addBreadcrumb({
|
|
@@ -899,10 +935,6 @@ function reportHttpError(httpInfo) {
|
|
|
899
935
|
reporter.reportError(errorData);
|
|
900
936
|
}
|
|
901
937
|
|
|
902
|
-
/**
|
|
903
|
-
* 白屏检测插件
|
|
904
|
-
* 使用 DOM 采样检测页面是否白屏
|
|
905
|
-
*/
|
|
906
938
|
// 采样点 - 页面关键区域
|
|
907
939
|
const SAMPLE_POINTS = [
|
|
908
940
|
{ x: 0.5, y: 0.1 }, // 顶部中间
|
|
@@ -926,6 +958,7 @@ function installWhiteScreenDetector() {
|
|
|
926
958
|
scheduleDetection();
|
|
927
959
|
});
|
|
928
960
|
}
|
|
961
|
+
console.log('[Monitor] White screen detector installed');
|
|
929
962
|
}
|
|
930
963
|
/**
|
|
931
964
|
* 调度检测(延迟执行,给页面渲染时间)
|
|
@@ -933,13 +966,6 @@ function installWhiteScreenDetector() {
|
|
|
933
966
|
function scheduleDetection() {
|
|
934
967
|
// 延迟 1 秒检测
|
|
935
968
|
setTimeout(() => {
|
|
936
|
-
// 检测时才检查配置
|
|
937
|
-
if (config.isInitialized()) {
|
|
938
|
-
const cfg = config.get();
|
|
939
|
-
if (!cfg.error?.enabled) {
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
942
|
-
}
|
|
943
969
|
const isWhiteScreen = detectWhiteScreen();
|
|
944
970
|
if (isWhiteScreen) {
|
|
945
971
|
reportWhiteScreen();
|
|
@@ -1004,10 +1030,6 @@ function installErrorHandlers() {
|
|
|
1004
1030
|
* 安装 Web Vitals 采集
|
|
1005
1031
|
*/
|
|
1006
1032
|
function installWebVitals() {
|
|
1007
|
-
const cfg = config.get();
|
|
1008
|
-
if (!cfg.performance?.enabled || !cfg.performance?.webVitals) {
|
|
1009
|
-
return;
|
|
1010
|
-
}
|
|
1011
1033
|
// 页面加载完成后采集
|
|
1012
1034
|
if (document.readyState === 'complete') {
|
|
1013
1035
|
collectMetrics();
|
|
@@ -1018,14 +1040,17 @@ function installWebVitals() {
|
|
|
1018
1040
|
setTimeout(collectMetrics, 3000);
|
|
1019
1041
|
});
|
|
1020
1042
|
}
|
|
1021
|
-
|
|
1022
|
-
console.log('[Monitor] Web Vitals collector installed');
|
|
1023
|
-
}
|
|
1043
|
+
console.log('[Monitor] Web Vitals collector installed');
|
|
1024
1044
|
}
|
|
1025
1045
|
/**
|
|
1026
1046
|
* 采集性能指标
|
|
1027
1047
|
*/
|
|
1028
1048
|
function collectMetrics() {
|
|
1049
|
+
// 检查配置(在采集时检查,而不是安装时)
|
|
1050
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1051
|
+
if (cfg?.performance?.enabled === false || cfg?.performance?.webVitals === false) {
|
|
1052
|
+
return;
|
|
1053
|
+
}
|
|
1029
1054
|
const metrics = {};
|
|
1030
1055
|
// 使用 Performance API
|
|
1031
1056
|
if (!window.performance) {
|
|
@@ -1134,22 +1159,13 @@ function installPerformanceMonitor() {
|
|
|
1134
1159
|
installWebVitals();
|
|
1135
1160
|
}
|
|
1136
1161
|
|
|
1137
|
-
/**
|
|
1138
|
-
* PV (Page View) 统计插件
|
|
1139
|
-
*/
|
|
1140
1162
|
/**
|
|
1141
1163
|
* 安装 PV 统计
|
|
1142
1164
|
*/
|
|
1143
1165
|
function installPVTracker() {
|
|
1144
|
-
|
|
1145
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.pv) {
|
|
1146
|
-
return;
|
|
1147
|
-
}
|
|
1148
|
-
// 页面加载时上报
|
|
1166
|
+
// 页面加载时上报(reporter 会缓存直到 SDK 就绪)
|
|
1149
1167
|
reportPV();
|
|
1150
|
-
|
|
1151
|
-
console.log('[Monitor] PV tracker installed');
|
|
1152
|
-
}
|
|
1168
|
+
console.log('[Monitor] PV tracker installed');
|
|
1153
1169
|
}
|
|
1154
1170
|
/**
|
|
1155
1171
|
* 上报 PV
|
|
@@ -1172,11 +1188,12 @@ function reportPV() {
|
|
|
1172
1188
|
* 安装点击追踪
|
|
1173
1189
|
*/
|
|
1174
1190
|
function installClickTracker() {
|
|
1175
|
-
const cfg = config.get();
|
|
1176
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.click) {
|
|
1177
|
-
return;
|
|
1178
|
-
}
|
|
1179
1191
|
document.addEventListener('click', (event) => {
|
|
1192
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1193
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1194
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.click === false) {
|
|
1195
|
+
return;
|
|
1196
|
+
}
|
|
1180
1197
|
const target = event.target;
|
|
1181
1198
|
if (!target)
|
|
1182
1199
|
return;
|
|
@@ -1194,9 +1211,7 @@ function installClickTracker() {
|
|
|
1194
1211
|
// data: clickData,
|
|
1195
1212
|
// });
|
|
1196
1213
|
}, true);
|
|
1197
|
-
|
|
1198
|
-
console.log('[Monitor] Click tracker installed');
|
|
1199
|
-
}
|
|
1214
|
+
console.log('[Monitor] Click tracker installed');
|
|
1200
1215
|
}
|
|
1201
1216
|
/**
|
|
1202
1217
|
* 提取点击数据
|
|
@@ -1275,10 +1290,6 @@ const originalReplaceState = history.replaceState;
|
|
|
1275
1290
|
* 安装路由监控
|
|
1276
1291
|
*/
|
|
1277
1292
|
function installRouteTracker() {
|
|
1278
|
-
const cfg = config.get();
|
|
1279
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.route) {
|
|
1280
|
-
return;
|
|
1281
|
-
}
|
|
1282
1293
|
// 拦截 pushState
|
|
1283
1294
|
history.pushState = function (...args) {
|
|
1284
1295
|
const result = originalPushState.apply(this, args);
|
|
@@ -1299,14 +1310,17 @@ function installRouteTracker() {
|
|
|
1299
1310
|
window.addEventListener('hashchange', () => {
|
|
1300
1311
|
handleRouteChange('hashchange');
|
|
1301
1312
|
});
|
|
1302
|
-
|
|
1303
|
-
console.log('[Monitor] Route tracker installed');
|
|
1304
|
-
}
|
|
1313
|
+
console.log('[Monitor] Route tracker installed');
|
|
1305
1314
|
}
|
|
1306
1315
|
/**
|
|
1307
1316
|
* 处理路由变化
|
|
1308
1317
|
*/
|
|
1309
1318
|
function handleRouteChange(trigger) {
|
|
1319
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1320
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1321
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.route === false) {
|
|
1322
|
+
return;
|
|
1323
|
+
}
|
|
1310
1324
|
const routeData = {
|
|
1311
1325
|
url: getPageUrl(),
|
|
1312
1326
|
title: getPageTitle(),
|
|
@@ -1341,16 +1355,16 @@ const originalConsole = {
|
|
|
1341
1355
|
* 安装控制台追踪
|
|
1342
1356
|
*/
|
|
1343
1357
|
function installConsoleTracker() {
|
|
1344
|
-
const cfg = config.get();
|
|
1345
|
-
// 默认启用控制台追踪(跟随 behavior.enabled)
|
|
1346
|
-
if (!cfg.behavior?.enabled) {
|
|
1347
|
-
return;
|
|
1348
|
-
}
|
|
1349
1358
|
const levels = ['log', 'info', 'warn', 'error'];
|
|
1350
1359
|
levels.forEach((level) => {
|
|
1351
1360
|
console[level] = function (...args) {
|
|
1352
1361
|
// 调用原始方法
|
|
1353
1362
|
originalConsole[level].apply(console, args);
|
|
1363
|
+
// 检查配置(在调用时检查,而不是安装时)
|
|
1364
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1365
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1366
|
+
return;
|
|
1367
|
+
}
|
|
1354
1368
|
// 添加到面包屑(只记录 warn 和 error)
|
|
1355
1369
|
if (level === 'warn' || level === 'error') {
|
|
1356
1370
|
const message = formatConsoleArgs(args);
|
|
@@ -1365,9 +1379,7 @@ function installConsoleTracker() {
|
|
|
1365
1379
|
}
|
|
1366
1380
|
};
|
|
1367
1381
|
});
|
|
1368
|
-
|
|
1369
|
-
originalConsole.log('[Monitor] Console tracker installed');
|
|
1370
|
-
}
|
|
1382
|
+
originalConsole.log('[Monitor] Console tracker installed');
|
|
1371
1383
|
}
|
|
1372
1384
|
/**
|
|
1373
1385
|
* 格式化控制台参数
|
|
@@ -1399,24 +1411,22 @@ function formatConsoleArgs(args) {
|
|
|
1399
1411
|
* 安装输入追踪
|
|
1400
1412
|
*/
|
|
1401
1413
|
function installInputTracker() {
|
|
1402
|
-
const cfg = config.get();
|
|
1403
|
-
// 默认启用输入追踪(跟随 behavior.enabled)
|
|
1404
|
-
if (!cfg.behavior?.enabled) {
|
|
1405
|
-
return;
|
|
1406
|
-
}
|
|
1407
1414
|
// 监听 input 事件(使用 change 事件减少数据量)
|
|
1408
1415
|
document.addEventListener('change', handleInputChange, true);
|
|
1409
1416
|
// 监听焦点事件
|
|
1410
1417
|
document.addEventListener('focus', handleFocus, true);
|
|
1411
1418
|
document.addEventListener('blur', handleBlur, true);
|
|
1412
|
-
|
|
1413
|
-
console.log('[Monitor] Input tracker installed');
|
|
1414
|
-
}
|
|
1419
|
+
console.log('[Monitor] Input tracker installed');
|
|
1415
1420
|
}
|
|
1416
1421
|
/**
|
|
1417
1422
|
* 处理输入变化
|
|
1418
1423
|
*/
|
|
1419
1424
|
function handleInputChange(event) {
|
|
1425
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1426
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1427
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1428
|
+
return;
|
|
1429
|
+
}
|
|
1420
1430
|
const target = event.target;
|
|
1421
1431
|
if (!target || !isFormElement(target))
|
|
1422
1432
|
return;
|
|
@@ -1431,6 +1441,11 @@ function handleInputChange(event) {
|
|
|
1431
1441
|
* 处理焦点获取
|
|
1432
1442
|
*/
|
|
1433
1443
|
function handleFocus(event) {
|
|
1444
|
+
// 检查配置
|
|
1445
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1446
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1447
|
+
return;
|
|
1448
|
+
}
|
|
1434
1449
|
const target = event.target;
|
|
1435
1450
|
if (!target || !isFormElement(target))
|
|
1436
1451
|
return;
|
|
@@ -1444,6 +1459,11 @@ function handleFocus(event) {
|
|
|
1444
1459
|
* 处理焦点失去
|
|
1445
1460
|
*/
|
|
1446
1461
|
function handleBlur(event) {
|
|
1462
|
+
// 检查配置
|
|
1463
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1464
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1465
|
+
return;
|
|
1466
|
+
}
|
|
1447
1467
|
const target = event.target;
|
|
1448
1468
|
if (!target || !isFormElement(target))
|
|
1449
1469
|
return;
|