sobey-monitor-sdk 1.1.4 → 1.1.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.
- 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.esm.js
CHANGED
|
@@ -274,13 +274,22 @@ class Sender {
|
|
|
274
274
|
* 策略:优先使用 sendBeacon(更可靠),不支持或失败时降级为 fetch
|
|
275
275
|
*/
|
|
276
276
|
doSend(data) {
|
|
277
|
+
// 检查配置是否已初始化
|
|
278
|
+
if (!config.isInitialized()) {
|
|
279
|
+
// 配置未初始化,数据放回缓冲区等待下次发送
|
|
280
|
+
this.buffer.unshift(...data);
|
|
281
|
+
this.scheduleFlush();
|
|
282
|
+
return;
|
|
283
|
+
}
|
|
277
284
|
const cfg = config.get();
|
|
278
285
|
const dsn = cfg.dsn;
|
|
279
|
-
// dsn
|
|
286
|
+
// dsn 未配置,将数据放回缓冲区等待下次发送
|
|
280
287
|
if (!dsn) {
|
|
281
288
|
if (cfg.debug) {
|
|
282
|
-
console.warn('[Monitor] dsn not configured,
|
|
289
|
+
console.warn('[Monitor] dsn not configured, buffering data for later');
|
|
283
290
|
}
|
|
291
|
+
this.buffer.unshift(...data);
|
|
292
|
+
this.scheduleFlush();
|
|
284
293
|
return;
|
|
285
294
|
}
|
|
286
295
|
const payload = JSON.stringify(data);
|
|
@@ -401,25 +410,83 @@ class Reporter {
|
|
|
401
410
|
}
|
|
402
411
|
}
|
|
403
412
|
/**
|
|
404
|
-
*
|
|
413
|
+
* 发送早期缓存的数据(根据最新配置过滤)
|
|
405
414
|
*/
|
|
406
415
|
flushEarlyBuffer() {
|
|
416
|
+
const cfg = config.get();
|
|
417
|
+
let skippedCount = 0;
|
|
418
|
+
// 全局开关检查:如果 enabled 为 false,清空缓存不上报
|
|
419
|
+
if (cfg.enabled === false) {
|
|
420
|
+
const totalCount = this.earlyBuffer.length;
|
|
421
|
+
this.earlyBuffer = [];
|
|
422
|
+
if (cfg.debug) {
|
|
423
|
+
console.log(`[Monitor] SDK disabled, discarded ${totalCount} early buffered items`);
|
|
424
|
+
}
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
407
427
|
while (this.earlyBuffer.length > 0) {
|
|
408
428
|
const item = this.earlyBuffer.shift();
|
|
409
429
|
if (!item)
|
|
410
430
|
continue;
|
|
431
|
+
// 根据最新配置过滤数据
|
|
411
432
|
switch (item.type) {
|
|
412
433
|
case 'error':
|
|
434
|
+
// 检查错误监控是否启用
|
|
435
|
+
if (cfg.error?.enabled === false) {
|
|
436
|
+
skippedCount++;
|
|
437
|
+
continue;
|
|
438
|
+
}
|
|
439
|
+
// 根据错误类型检查具体开关
|
|
440
|
+
const errorType = item.data?.type;
|
|
441
|
+
if (errorType === 'js_error' && cfg.error?.jsError === false) {
|
|
442
|
+
skippedCount++;
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
445
|
+
if (errorType === 'promise_error' && cfg.error?.promiseError === false) {
|
|
446
|
+
skippedCount++;
|
|
447
|
+
continue;
|
|
448
|
+
}
|
|
449
|
+
if (errorType === 'resource_error' && cfg.error?.resourceError === false) {
|
|
450
|
+
skippedCount++;
|
|
451
|
+
continue;
|
|
452
|
+
}
|
|
453
|
+
if (errorType === 'http_error' && cfg.error?.httpError === false) {
|
|
454
|
+
skippedCount++;
|
|
455
|
+
continue;
|
|
456
|
+
}
|
|
413
457
|
this.reportError(item.data);
|
|
414
458
|
break;
|
|
415
459
|
case 'performance':
|
|
460
|
+
// 检查性能监控是否启用
|
|
461
|
+
if (cfg.performance?.enabled === false) {
|
|
462
|
+
skippedCount++;
|
|
463
|
+
continue;
|
|
464
|
+
}
|
|
416
465
|
this.reportPerformance(item.data);
|
|
417
466
|
break;
|
|
418
467
|
case 'behavior':
|
|
468
|
+
// 检查行为监控是否启用
|
|
469
|
+
if (cfg.behavior?.enabled === false) {
|
|
470
|
+
skippedCount++;
|
|
471
|
+
continue;
|
|
472
|
+
}
|
|
473
|
+
// 根据行为类型检查具体开关
|
|
474
|
+
const action = item.data?.action;
|
|
475
|
+
if (action === 'pv' && cfg.behavior?.pv === false) {
|
|
476
|
+
skippedCount++;
|
|
477
|
+
continue;
|
|
478
|
+
}
|
|
479
|
+
if (action === 'route' && cfg.behavior?.route === false) {
|
|
480
|
+
skippedCount++;
|
|
481
|
+
continue;
|
|
482
|
+
}
|
|
419
483
|
this.reportBehavior(item.data);
|
|
420
484
|
break;
|
|
421
485
|
}
|
|
422
486
|
}
|
|
487
|
+
if (skippedCount > 0 && cfg.debug) {
|
|
488
|
+
console.log(`[Monitor] Filtered out ${skippedCount} early buffered items based on config`);
|
|
489
|
+
}
|
|
423
490
|
}
|
|
424
491
|
/**
|
|
425
492
|
* 缓存早期数据
|
|
@@ -548,17 +615,15 @@ const reporter = new Reporter();
|
|
|
548
615
|
*/
|
|
549
616
|
function installJsErrorHandler() {
|
|
550
617
|
window.addEventListener('error', (event) => {
|
|
551
|
-
// 延迟检查配置(SDK 可能还在加载配置)
|
|
552
|
-
if (config.isInitialized()) {
|
|
553
|
-
const cfg = config.get();
|
|
554
|
-
if (!cfg.error?.enabled || !cfg.error?.jsError) {
|
|
555
|
-
return;
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
618
|
// 过滤资源加载错误(由 resourceError 处理)
|
|
559
619
|
if (event.target !== window) {
|
|
560
620
|
return;
|
|
561
621
|
}
|
|
622
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
623
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
624
|
+
if (cfg?.error?.enabled === false || cfg?.error?.jsError === false) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
562
627
|
const errorData = {
|
|
563
628
|
type: 'js_error',
|
|
564
629
|
message: event.message || 'Unknown error',
|
|
@@ -579,6 +644,7 @@ function installJsErrorHandler() {
|
|
|
579
644
|
});
|
|
580
645
|
reporter.reportError(errorData);
|
|
581
646
|
}, true);
|
|
647
|
+
console.log('[Monitor] JS error handler installed');
|
|
582
648
|
}
|
|
583
649
|
|
|
584
650
|
/**
|
|
@@ -589,12 +655,10 @@ function installJsErrorHandler() {
|
|
|
589
655
|
*/
|
|
590
656
|
function installPromiseErrorHandler() {
|
|
591
657
|
window.addEventListener('unhandledrejection', (event) => {
|
|
592
|
-
//
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
return;
|
|
597
|
-
}
|
|
658
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
659
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
660
|
+
if (cfg?.error?.enabled === false || cfg?.error?.promiseError === false) {
|
|
661
|
+
return;
|
|
598
662
|
}
|
|
599
663
|
let message = 'Unhandled Promise rejection';
|
|
600
664
|
let stack;
|
|
@@ -624,6 +688,7 @@ function installPromiseErrorHandler() {
|
|
|
624
688
|
});
|
|
625
689
|
reporter.reportError(errorData);
|
|
626
690
|
});
|
|
691
|
+
console.log('[Monitor] Promise error handler installed');
|
|
627
692
|
}
|
|
628
693
|
|
|
629
694
|
/**
|
|
@@ -634,18 +699,16 @@ function installPromiseErrorHandler() {
|
|
|
634
699
|
*/
|
|
635
700
|
function installResourceErrorHandler() {
|
|
636
701
|
window.addEventListener('error', (event) => {
|
|
637
|
-
// 延迟检查配置(SDK 可能还在加载配置)
|
|
638
|
-
if (config.isInitialized()) {
|
|
639
|
-
const cfg = config.get();
|
|
640
|
-
if (!cfg.error?.enabled || !cfg.error?.resourceError) {
|
|
641
|
-
return;
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
702
|
const target = event.target;
|
|
645
703
|
// 只处理资源加载错误(target 不是 window)
|
|
646
704
|
if (!target || target === window || !(target instanceof HTMLElement)) {
|
|
647
705
|
return;
|
|
648
706
|
}
|
|
707
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
708
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
709
|
+
if (cfg?.error?.enabled === false || cfg?.error?.resourceError === false) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
649
712
|
const tagName = target.tagName.toLowerCase();
|
|
650
713
|
// 只监控特定标签的资源
|
|
651
714
|
if (!['img', 'script', 'link', 'video', 'audio', 'source'].includes(tagName)) {
|
|
@@ -674,6 +737,7 @@ function installResourceErrorHandler() {
|
|
|
674
737
|
});
|
|
675
738
|
reporter.reportError(errorData);
|
|
676
739
|
}, true); // 使用捕获阶段
|
|
740
|
+
console.log('[Monitor] Resource error handler installed');
|
|
677
741
|
}
|
|
678
742
|
|
|
679
743
|
/**
|
|
@@ -690,6 +754,7 @@ const originalFetch = window.fetch;
|
|
|
690
754
|
function installHttpErrorHandler() {
|
|
691
755
|
interceptXHR();
|
|
692
756
|
interceptFetch();
|
|
757
|
+
console.log('[Monitor] HTTP error handler installed');
|
|
693
758
|
}
|
|
694
759
|
/**
|
|
695
760
|
* 检查是否是 SDK 自身的请求
|
|
@@ -702,18 +767,6 @@ function isSdkRequest(url) {
|
|
|
702
767
|
return false;
|
|
703
768
|
return url.includes(cfg.dsn);
|
|
704
769
|
}
|
|
705
|
-
/**
|
|
706
|
-
* 检查 HTTP 错误监控是否启用
|
|
707
|
-
*/
|
|
708
|
-
function isHttpErrorEnabled() {
|
|
709
|
-
if (!config.isInitialized())
|
|
710
|
-
return true; // 配置未就绪时默认启用,数据会被缓存
|
|
711
|
-
const cfg = config.get();
|
|
712
|
-
return cfg.error?.enabled !== false && cfg.error?.httpError !== false;
|
|
713
|
-
}
|
|
714
|
-
/**
|
|
715
|
-
* 拦截 XMLHttpRequest
|
|
716
|
-
*/
|
|
717
770
|
function interceptXHR() {
|
|
718
771
|
XMLHttpRequest.prototype.open = function (method, url, async = true, username, password) {
|
|
719
772
|
const urlStr = url.toString();
|
|
@@ -743,16 +796,11 @@ function interceptXHR() {
|
|
|
743
796
|
this.addEventListener('loadend', function () {
|
|
744
797
|
if (!monitorData)
|
|
745
798
|
return;
|
|
746
|
-
if (!isHttpErrorEnabled())
|
|
747
|
-
return;
|
|
748
799
|
const duration = Date.now() - monitorData.startTime;
|
|
749
800
|
const status = this.status;
|
|
750
801
|
// 根据配置决定是否添加到面包屑
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
const cfg = config.get();
|
|
754
|
-
recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
755
|
-
}
|
|
802
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
803
|
+
const recordMode = cfg?.behavior?.recordRequestBreadcrumb || 'error';
|
|
756
804
|
// 重定向(3xx)始终记录,不受配置控制
|
|
757
805
|
const isRedirect = status >= 300 && status < 400;
|
|
758
806
|
// 其他异常情况(0-网络错误、4xx-客户端错误、5xx-服务端错误)根据配置控制
|
|
@@ -799,17 +847,11 @@ function interceptFetch() {
|
|
|
799
847
|
const requestBody = typeof init?.body === 'string' ? init.body : undefined;
|
|
800
848
|
try {
|
|
801
849
|
const response = await originalFetch.call(window, input, init);
|
|
802
|
-
if (!isHttpErrorEnabled()) {
|
|
803
|
-
return response;
|
|
804
|
-
}
|
|
805
850
|
const duration = Date.now() - startTime;
|
|
806
851
|
const status = response.status;
|
|
807
852
|
// 根据配置决定是否添加到面包屑
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
const cfg = config.get();
|
|
811
|
-
recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
812
|
-
}
|
|
853
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
854
|
+
const recordMode = cfg?.behavior?.recordRequestBreadcrumb || 'error';
|
|
813
855
|
// 重定向(3xx)始终记录,不受配置控制
|
|
814
856
|
const isRedirect = status >= 300 && status < 400;
|
|
815
857
|
// 其他异常情况根据配置控制
|
|
@@ -848,16 +890,10 @@ function interceptFetch() {
|
|
|
848
890
|
return response;
|
|
849
891
|
}
|
|
850
892
|
catch (error) {
|
|
851
|
-
if (!isHttpErrorEnabled()) {
|
|
852
|
-
throw error;
|
|
853
|
-
}
|
|
854
893
|
const duration = Date.now() - startTime;
|
|
855
894
|
// 网络错误时根据配置决定是否添加到面包屑
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
const cfg = config.get();
|
|
859
|
-
recordMode = cfg.behavior?.recordRequestBreadcrumb || 'error';
|
|
860
|
-
}
|
|
895
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
896
|
+
const recordMode = cfg?.behavior?.recordRequestBreadcrumb || 'error';
|
|
861
897
|
// 网络错误属于 error,当模式为 'all' 或 'error' 时都记录
|
|
862
898
|
if (recordMode !== 'none') {
|
|
863
899
|
context.addBreadcrumb({
|
|
@@ -895,10 +931,6 @@ function reportHttpError(httpInfo) {
|
|
|
895
931
|
reporter.reportError(errorData);
|
|
896
932
|
}
|
|
897
933
|
|
|
898
|
-
/**
|
|
899
|
-
* 白屏检测插件
|
|
900
|
-
* 使用 DOM 采样检测页面是否白屏
|
|
901
|
-
*/
|
|
902
934
|
// 采样点 - 页面关键区域
|
|
903
935
|
const SAMPLE_POINTS = [
|
|
904
936
|
{ x: 0.5, y: 0.1 }, // 顶部中间
|
|
@@ -922,6 +954,7 @@ function installWhiteScreenDetector() {
|
|
|
922
954
|
scheduleDetection();
|
|
923
955
|
});
|
|
924
956
|
}
|
|
957
|
+
console.log('[Monitor] White screen detector installed');
|
|
925
958
|
}
|
|
926
959
|
/**
|
|
927
960
|
* 调度检测(延迟执行,给页面渲染时间)
|
|
@@ -929,13 +962,6 @@ function installWhiteScreenDetector() {
|
|
|
929
962
|
function scheduleDetection() {
|
|
930
963
|
// 延迟 1 秒检测
|
|
931
964
|
setTimeout(() => {
|
|
932
|
-
// 检测时才检查配置
|
|
933
|
-
if (config.isInitialized()) {
|
|
934
|
-
const cfg = config.get();
|
|
935
|
-
if (!cfg.error?.enabled) {
|
|
936
|
-
return;
|
|
937
|
-
}
|
|
938
|
-
}
|
|
939
965
|
const isWhiteScreen = detectWhiteScreen();
|
|
940
966
|
if (isWhiteScreen) {
|
|
941
967
|
reportWhiteScreen();
|
|
@@ -1000,10 +1026,6 @@ function installErrorHandlers() {
|
|
|
1000
1026
|
* 安装 Web Vitals 采集
|
|
1001
1027
|
*/
|
|
1002
1028
|
function installWebVitals() {
|
|
1003
|
-
const cfg = config.get();
|
|
1004
|
-
if (!cfg.performance?.enabled || !cfg.performance?.webVitals) {
|
|
1005
|
-
return;
|
|
1006
|
-
}
|
|
1007
1029
|
// 页面加载完成后采集
|
|
1008
1030
|
if (document.readyState === 'complete') {
|
|
1009
1031
|
collectMetrics();
|
|
@@ -1014,14 +1036,17 @@ function installWebVitals() {
|
|
|
1014
1036
|
setTimeout(collectMetrics, 3000);
|
|
1015
1037
|
});
|
|
1016
1038
|
}
|
|
1017
|
-
|
|
1018
|
-
console.log('[Monitor] Web Vitals collector installed');
|
|
1019
|
-
}
|
|
1039
|
+
console.log('[Monitor] Web Vitals collector installed');
|
|
1020
1040
|
}
|
|
1021
1041
|
/**
|
|
1022
1042
|
* 采集性能指标
|
|
1023
1043
|
*/
|
|
1024
1044
|
function collectMetrics() {
|
|
1045
|
+
// 检查配置(在采集时检查,而不是安装时)
|
|
1046
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1047
|
+
if (cfg?.performance?.enabled === false || cfg?.performance?.webVitals === false) {
|
|
1048
|
+
return;
|
|
1049
|
+
}
|
|
1025
1050
|
const metrics = {};
|
|
1026
1051
|
// 使用 Performance API
|
|
1027
1052
|
if (!window.performance) {
|
|
@@ -1130,22 +1155,13 @@ function installPerformanceMonitor() {
|
|
|
1130
1155
|
installWebVitals();
|
|
1131
1156
|
}
|
|
1132
1157
|
|
|
1133
|
-
/**
|
|
1134
|
-
* PV (Page View) 统计插件
|
|
1135
|
-
*/
|
|
1136
1158
|
/**
|
|
1137
1159
|
* 安装 PV 统计
|
|
1138
1160
|
*/
|
|
1139
1161
|
function installPVTracker() {
|
|
1140
|
-
|
|
1141
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.pv) {
|
|
1142
|
-
return;
|
|
1143
|
-
}
|
|
1144
|
-
// 页面加载时上报
|
|
1162
|
+
// 页面加载时上报(reporter 会缓存直到 SDK 就绪)
|
|
1145
1163
|
reportPV();
|
|
1146
|
-
|
|
1147
|
-
console.log('[Monitor] PV tracker installed');
|
|
1148
|
-
}
|
|
1164
|
+
console.log('[Monitor] PV tracker installed');
|
|
1149
1165
|
}
|
|
1150
1166
|
/**
|
|
1151
1167
|
* 上报 PV
|
|
@@ -1168,11 +1184,12 @@ function reportPV() {
|
|
|
1168
1184
|
* 安装点击追踪
|
|
1169
1185
|
*/
|
|
1170
1186
|
function installClickTracker() {
|
|
1171
|
-
const cfg = config.get();
|
|
1172
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.click) {
|
|
1173
|
-
return;
|
|
1174
|
-
}
|
|
1175
1187
|
document.addEventListener('click', (event) => {
|
|
1188
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1189
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1190
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.click === false) {
|
|
1191
|
+
return;
|
|
1192
|
+
}
|
|
1176
1193
|
const target = event.target;
|
|
1177
1194
|
if (!target)
|
|
1178
1195
|
return;
|
|
@@ -1190,9 +1207,7 @@ function installClickTracker() {
|
|
|
1190
1207
|
// data: clickData,
|
|
1191
1208
|
// });
|
|
1192
1209
|
}, true);
|
|
1193
|
-
|
|
1194
|
-
console.log('[Monitor] Click tracker installed');
|
|
1195
|
-
}
|
|
1210
|
+
console.log('[Monitor] Click tracker installed');
|
|
1196
1211
|
}
|
|
1197
1212
|
/**
|
|
1198
1213
|
* 提取点击数据
|
|
@@ -1271,10 +1286,6 @@ const originalReplaceState = history.replaceState;
|
|
|
1271
1286
|
* 安装路由监控
|
|
1272
1287
|
*/
|
|
1273
1288
|
function installRouteTracker() {
|
|
1274
|
-
const cfg = config.get();
|
|
1275
|
-
if (!cfg.behavior?.enabled || !cfg.behavior?.route) {
|
|
1276
|
-
return;
|
|
1277
|
-
}
|
|
1278
1289
|
// 拦截 pushState
|
|
1279
1290
|
history.pushState = function (...args) {
|
|
1280
1291
|
const result = originalPushState.apply(this, args);
|
|
@@ -1295,14 +1306,17 @@ function installRouteTracker() {
|
|
|
1295
1306
|
window.addEventListener('hashchange', () => {
|
|
1296
1307
|
handleRouteChange('hashchange');
|
|
1297
1308
|
});
|
|
1298
|
-
|
|
1299
|
-
console.log('[Monitor] Route tracker installed');
|
|
1300
|
-
}
|
|
1309
|
+
console.log('[Monitor] Route tracker installed');
|
|
1301
1310
|
}
|
|
1302
1311
|
/**
|
|
1303
1312
|
* 处理路由变化
|
|
1304
1313
|
*/
|
|
1305
1314
|
function handleRouteChange(trigger) {
|
|
1315
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1316
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1317
|
+
if (cfg?.behavior?.enabled === false || cfg?.behavior?.route === false) {
|
|
1318
|
+
return;
|
|
1319
|
+
}
|
|
1306
1320
|
const routeData = {
|
|
1307
1321
|
url: getPageUrl(),
|
|
1308
1322
|
title: getPageTitle(),
|
|
@@ -1337,16 +1351,16 @@ const originalConsole = {
|
|
|
1337
1351
|
* 安装控制台追踪
|
|
1338
1352
|
*/
|
|
1339
1353
|
function installConsoleTracker() {
|
|
1340
|
-
const cfg = config.get();
|
|
1341
|
-
// 默认启用控制台追踪(跟随 behavior.enabled)
|
|
1342
|
-
if (!cfg.behavior?.enabled) {
|
|
1343
|
-
return;
|
|
1344
|
-
}
|
|
1345
1354
|
const levels = ['log', 'info', 'warn', 'error'];
|
|
1346
1355
|
levels.forEach((level) => {
|
|
1347
1356
|
console[level] = function (...args) {
|
|
1348
1357
|
// 调用原始方法
|
|
1349
1358
|
originalConsole[level].apply(console, args);
|
|
1359
|
+
// 检查配置(在调用时检查,而不是安装时)
|
|
1360
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1361
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1362
|
+
return;
|
|
1363
|
+
}
|
|
1350
1364
|
// 添加到面包屑(只记录 warn 和 error)
|
|
1351
1365
|
if (level === 'warn' || level === 'error') {
|
|
1352
1366
|
const message = formatConsoleArgs(args);
|
|
@@ -1361,9 +1375,7 @@ function installConsoleTracker() {
|
|
|
1361
1375
|
}
|
|
1362
1376
|
};
|
|
1363
1377
|
});
|
|
1364
|
-
|
|
1365
|
-
originalConsole.log('[Monitor] Console tracker installed');
|
|
1366
|
-
}
|
|
1378
|
+
originalConsole.log('[Monitor] Console tracker installed');
|
|
1367
1379
|
}
|
|
1368
1380
|
/**
|
|
1369
1381
|
* 格式化控制台参数
|
|
@@ -1395,24 +1407,22 @@ function formatConsoleArgs(args) {
|
|
|
1395
1407
|
* 安装输入追踪
|
|
1396
1408
|
*/
|
|
1397
1409
|
function installInputTracker() {
|
|
1398
|
-
const cfg = config.get();
|
|
1399
|
-
// 默认启用输入追踪(跟随 behavior.enabled)
|
|
1400
|
-
if (!cfg.behavior?.enabled) {
|
|
1401
|
-
return;
|
|
1402
|
-
}
|
|
1403
1410
|
// 监听 input 事件(使用 change 事件减少数据量)
|
|
1404
1411
|
document.addEventListener('change', handleInputChange, true);
|
|
1405
1412
|
// 监听焦点事件
|
|
1406
1413
|
document.addEventListener('focus', handleFocus, true);
|
|
1407
1414
|
document.addEventListener('blur', handleBlur, true);
|
|
1408
|
-
|
|
1409
|
-
console.log('[Monitor] Input tracker installed');
|
|
1410
|
-
}
|
|
1415
|
+
console.log('[Monitor] Input tracker installed');
|
|
1411
1416
|
}
|
|
1412
1417
|
/**
|
|
1413
1418
|
* 处理输入变化
|
|
1414
1419
|
*/
|
|
1415
1420
|
function handleInputChange(event) {
|
|
1421
|
+
// 检查配置(在事件触发时检查,而不是安装时)
|
|
1422
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1423
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1424
|
+
return;
|
|
1425
|
+
}
|
|
1416
1426
|
const target = event.target;
|
|
1417
1427
|
if (!target || !isFormElement(target))
|
|
1418
1428
|
return;
|
|
@@ -1427,6 +1437,11 @@ function handleInputChange(event) {
|
|
|
1427
1437
|
* 处理焦点获取
|
|
1428
1438
|
*/
|
|
1429
1439
|
function handleFocus(event) {
|
|
1440
|
+
// 检查配置
|
|
1441
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1442
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1443
|
+
return;
|
|
1444
|
+
}
|
|
1430
1445
|
const target = event.target;
|
|
1431
1446
|
if (!target || !isFormElement(target))
|
|
1432
1447
|
return;
|
|
@@ -1440,6 +1455,11 @@ function handleFocus(event) {
|
|
|
1440
1455
|
* 处理焦点失去
|
|
1441
1456
|
*/
|
|
1442
1457
|
function handleBlur(event) {
|
|
1458
|
+
// 检查配置
|
|
1459
|
+
const cfg = config.isInitialized() ? config.get() : null;
|
|
1460
|
+
if (cfg?.behavior?.enabled === false) {
|
|
1461
|
+
return;
|
|
1462
|
+
}
|
|
1443
1463
|
const target = event.target;
|
|
1444
1464
|
if (!target || !isFormElement(target))
|
|
1445
1465
|
return;
|