sobey-monitor-sdk 1.1.1 → 1.1.3
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/core/config.d.ts +0 -1
- package/dist/frameworks/react.d.ts +1 -1
- package/dist/frameworks/vue.d.ts +1 -1
- package/dist/index.cjs.js +196 -109
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +27 -19
- package/dist/index.esm.js +196 -109
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +196 -109
- package/dist/index.umd.js.map +1 -1
- package/dist/reporter/index.d.ts +18 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -285,7 +285,7 @@ interface DeviceInfo {
|
|
|
285
285
|
* ```
|
|
286
286
|
*/
|
|
287
287
|
declare const VueMonitorPlugin: {
|
|
288
|
-
install(app: any, options
|
|
288
|
+
install(app: any, options?: MonitorConfig): void;
|
|
289
289
|
};
|
|
290
290
|
|
|
291
291
|
/**
|
|
@@ -332,7 +332,7 @@ interface ErrorBoundaryState {
|
|
|
332
332
|
* );
|
|
333
333
|
* ```
|
|
334
334
|
*/
|
|
335
|
-
declare function createReactErrorBoundary(React: any, config
|
|
335
|
+
declare function createReactErrorBoundary(React: any, config?: MonitorConfig): any;
|
|
336
336
|
/**
|
|
337
337
|
* React Hook: 用于手动上报错误
|
|
338
338
|
*
|
|
@@ -361,18 +361,32 @@ declare function createUseMonitorError(React: any): () => any;
|
|
|
361
361
|
* 监控 SDK 主类
|
|
362
362
|
*/
|
|
363
363
|
declare class MonitorSDK {
|
|
364
|
+
/** SDK 是否已初始化(基础初始化,可能还没有完整配置) */
|
|
364
365
|
private initialized;
|
|
365
|
-
|
|
366
|
+
/** SDK 是否已就绪(配置完整,可以上报数据) */
|
|
367
|
+
private ready;
|
|
368
|
+
/** 是否正在加载远程配置 */
|
|
369
|
+
private loading;
|
|
370
|
+
/** 监控模块是否已安装 */
|
|
371
|
+
private monitorsInstalled;
|
|
366
372
|
/**
|
|
367
373
|
* 初始化 SDK
|
|
368
|
-
*
|
|
369
|
-
* 无需 await,SDK 内部会自动处理异步逻辑
|
|
374
|
+
* 支持空配置初始化,后续通过 updateConfig 传入 configUrl 完成配置
|
|
370
375
|
*/
|
|
371
|
-
init(userConfig
|
|
376
|
+
init(userConfig?: MonitorConfig): void;
|
|
372
377
|
/**
|
|
373
|
-
*
|
|
378
|
+
* 基础初始化(安装监控模块,但不开始上报)
|
|
374
379
|
*/
|
|
375
|
-
private
|
|
380
|
+
private initBasic;
|
|
381
|
+
/**
|
|
382
|
+
* 激活 SDK(配置完整后调用)
|
|
383
|
+
*/
|
|
384
|
+
private activate;
|
|
385
|
+
/**
|
|
386
|
+
* 动态更新配置
|
|
387
|
+
* 如果传入 configUrl,会从远程获取配置并激活 SDK
|
|
388
|
+
*/
|
|
389
|
+
updateConfig(partialConfig: Partial<MonitorConfig>): void;
|
|
376
390
|
/**
|
|
377
391
|
* 从远程获取配置
|
|
378
392
|
*/
|
|
@@ -382,19 +396,17 @@ declare class MonitorSDK {
|
|
|
382
396
|
*/
|
|
383
397
|
private mergeUserConfig;
|
|
384
398
|
/**
|
|
385
|
-
*
|
|
399
|
+
* 检查 SDK 是否就绪
|
|
386
400
|
*/
|
|
387
|
-
|
|
401
|
+
isReady(): boolean;
|
|
388
402
|
/**
|
|
389
|
-
*
|
|
390
|
-
* @description 可以在运行时更新 SDK 配置,如 debug、sampling、report 等
|
|
391
|
-
* 如果传入 configUrl,会从远程获取配置并合并
|
|
403
|
+
* 设置用户信息
|
|
392
404
|
*/
|
|
393
|
-
|
|
405
|
+
setUser(user: UserInfo): void;
|
|
394
406
|
/**
|
|
395
407
|
* 获取当前配置
|
|
396
408
|
*/
|
|
397
|
-
getConfig(): MonitorConfig;
|
|
409
|
+
getConfig(): MonitorConfig | null;
|
|
398
410
|
/**
|
|
399
411
|
* 手动上报错误
|
|
400
412
|
*/
|
|
@@ -419,10 +431,6 @@ declare class MonitorSDK {
|
|
|
419
431
|
* 获取 SDK 版本
|
|
420
432
|
*/
|
|
421
433
|
getVersion(): string;
|
|
422
|
-
/**
|
|
423
|
-
* 检查是否已初始化
|
|
424
|
-
*/
|
|
425
|
-
private checkInit;
|
|
426
434
|
}
|
|
427
435
|
declare const monitor: MonitorSDK;
|
|
428
436
|
|
package/dist/index.esm.js
CHANGED
|
@@ -45,27 +45,14 @@ class ConfigManager {
|
|
|
45
45
|
}
|
|
46
46
|
/**
|
|
47
47
|
* 初始化配置
|
|
48
|
-
* @param skipValidation 是否跳过必填校验(用于远程配置已获取 appId/dsn 的场景)
|
|
49
48
|
*/
|
|
50
49
|
init(userConfig, skipValidation = false) {
|
|
51
50
|
if (!skipValidation) {
|
|
52
|
-
// 如果没有 configUrl,则 appId 和 dsn 是必填的
|
|
53
|
-
if (!userConfig.configUrl) {
|
|
54
|
-
if (!userConfig.appId) {
|
|
55
|
-
throw new Error('[Monitor] appId is required when configUrl is not provided');
|
|
56
|
-
}
|
|
57
|
-
if (!userConfig.dsn) {
|
|
58
|
-
throw new Error('[Monitor] dsn is required when configUrl is not provided');
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
// 远程配置模式下,校验合并后的配置
|
|
64
51
|
if (!userConfig.appId) {
|
|
65
|
-
throw new Error('[Monitor] appId is required
|
|
52
|
+
throw new Error('[Monitor] appId is required');
|
|
66
53
|
}
|
|
67
54
|
if (!userConfig.dsn) {
|
|
68
|
-
throw new Error('[Monitor] dsn is required
|
|
55
|
+
throw new Error('[Monitor] dsn is required');
|
|
69
56
|
}
|
|
70
57
|
}
|
|
71
58
|
this.config = this.mergeConfig(DEFAULT_CONFIG, userConfig);
|
|
@@ -289,6 +276,13 @@ class Sender {
|
|
|
289
276
|
doSend(data) {
|
|
290
277
|
const cfg = config.get();
|
|
291
278
|
const dsn = cfg.dsn;
|
|
279
|
+
// dsn 未配置,跳过发送
|
|
280
|
+
if (!dsn) {
|
|
281
|
+
if (cfg.debug) {
|
|
282
|
+
console.warn('[Monitor] dsn not configured, skip sending');
|
|
283
|
+
}
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
292
286
|
const payload = JSON.stringify(data);
|
|
293
287
|
// 优先使用 sendBeacon(更可靠、异步、不阻塞页面)
|
|
294
288
|
if (supportsSendBeacon()) {
|
|
@@ -387,13 +381,63 @@ const SDK_VERSION$1 = '1.0.0';
|
|
|
387
381
|
* 上报器类
|
|
388
382
|
*/
|
|
389
383
|
class Reporter {
|
|
384
|
+
constructor() {
|
|
385
|
+
/** SDK 是否就绪 */
|
|
386
|
+
this.ready = false;
|
|
387
|
+
/** 早期数据缓存队列(SDK 未就绪时缓存) */
|
|
388
|
+
this.earlyBuffer = [];
|
|
389
|
+
/** 最大缓存数量 */
|
|
390
|
+
this.maxEarlyBufferSize = 50;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* 设置 SDK 就绪状态
|
|
394
|
+
*/
|
|
395
|
+
setReady(ready) {
|
|
396
|
+
this.ready = ready;
|
|
397
|
+
// 就绪后发送缓存的早期数据
|
|
398
|
+
if (ready && this.earlyBuffer.length > 0) {
|
|
399
|
+
console.log(`[Monitor] Flushing ${this.earlyBuffer.length} early buffered items`);
|
|
400
|
+
this.flushEarlyBuffer();
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* 发送早期缓存的数据
|
|
405
|
+
*/
|
|
406
|
+
flushEarlyBuffer() {
|
|
407
|
+
while (this.earlyBuffer.length > 0) {
|
|
408
|
+
const item = this.earlyBuffer.shift();
|
|
409
|
+
if (!item)
|
|
410
|
+
continue;
|
|
411
|
+
switch (item.type) {
|
|
412
|
+
case 'error':
|
|
413
|
+
this.reportError(item.data);
|
|
414
|
+
break;
|
|
415
|
+
case 'performance':
|
|
416
|
+
this.reportPerformance(item.data);
|
|
417
|
+
break;
|
|
418
|
+
case 'behavior':
|
|
419
|
+
this.reportBehavior(item.data);
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* 缓存早期数据
|
|
426
|
+
*/
|
|
427
|
+
bufferEarly(type, data) {
|
|
428
|
+
if (this.earlyBuffer.length >= this.maxEarlyBufferSize) {
|
|
429
|
+
// 缓存已满,丢弃最早的数据
|
|
430
|
+
this.earlyBuffer.shift();
|
|
431
|
+
}
|
|
432
|
+
this.earlyBuffer.push({ type, data });
|
|
433
|
+
}
|
|
390
434
|
/**
|
|
391
435
|
* 构建基础数据
|
|
392
436
|
*/
|
|
393
437
|
buildBaseData() {
|
|
394
438
|
const cfg = config.get();
|
|
395
439
|
return {
|
|
396
|
-
appId: cfg.appId,
|
|
440
|
+
appId: cfg.appId || '',
|
|
397
441
|
userId: cfg.user?.userId,
|
|
398
442
|
sessionId: context.getSessionId(),
|
|
399
443
|
pageUrl: getPageUrl(),
|
|
@@ -414,6 +458,11 @@ class Reporter {
|
|
|
414
458
|
* 上报错误
|
|
415
459
|
*/
|
|
416
460
|
reportError(data) {
|
|
461
|
+
// SDK 未就绪时缓存数据
|
|
462
|
+
if (!this.ready) {
|
|
463
|
+
this.bufferEarly('error', data);
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
417
466
|
if (!this.shouldSample('error'))
|
|
418
467
|
return;
|
|
419
468
|
const cfg = config.get();
|
|
@@ -435,6 +484,11 @@ class Reporter {
|
|
|
435
484
|
* 上报性能
|
|
436
485
|
*/
|
|
437
486
|
reportPerformance(data) {
|
|
487
|
+
// SDK 未就绪时缓存数据
|
|
488
|
+
if (!this.ready) {
|
|
489
|
+
this.bufferEarly('performance', data);
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
438
492
|
if (!this.shouldSample('performance'))
|
|
439
493
|
return;
|
|
440
494
|
const reportData = {
|
|
@@ -447,6 +501,11 @@ class Reporter {
|
|
|
447
501
|
* 上报行为
|
|
448
502
|
*/
|
|
449
503
|
reportBehavior(data) {
|
|
504
|
+
// SDK 未就绪时缓存数据
|
|
505
|
+
if (!this.ready) {
|
|
506
|
+
this.bufferEarly('behavior', data);
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
450
509
|
if (!this.shouldSample('behavior'))
|
|
451
510
|
return;
|
|
452
511
|
const reportData = {
|
|
@@ -1435,12 +1494,8 @@ function installBehaviorMonitor() {
|
|
|
1435
1494
|
* ```
|
|
1436
1495
|
*/
|
|
1437
1496
|
const VueMonitorPlugin = {
|
|
1438
|
-
install(app, options) {
|
|
1439
|
-
|
|
1440
|
-
console.warn('[Monitor] VueMonitorPlugin requires appId and dsn in options');
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
// 初始化 SDK(如果尚未初始化)
|
|
1497
|
+
install(app, options = {}) {
|
|
1498
|
+
// 初始化 SDK(支持空配置,后续通过 updateConfig 激活)
|
|
1444
1499
|
try {
|
|
1445
1500
|
monitor.init(options);
|
|
1446
1501
|
}
|
|
@@ -1536,17 +1591,8 @@ const VueMonitorPlugin = {
|
|
|
1536
1591
|
* );
|
|
1537
1592
|
* ```
|
|
1538
1593
|
*/
|
|
1539
|
-
function createReactErrorBoundary(React, config) {
|
|
1540
|
-
|
|
1541
|
-
console.warn('[Monitor] createReactErrorBoundary requires appId and dsn in config');
|
|
1542
|
-
// 返回一个空的组件
|
|
1543
|
-
return class EmptyBoundary extends React.Component {
|
|
1544
|
-
render() {
|
|
1545
|
-
return this.props.children;
|
|
1546
|
-
}
|
|
1547
|
-
};
|
|
1548
|
-
}
|
|
1549
|
-
// 初始化 SDK(如果尚未初始化)
|
|
1594
|
+
function createReactErrorBoundary(React, config = {}) {
|
|
1595
|
+
// 初始化 SDK(支持空配置,后续通过 updateConfig 激活)
|
|
1550
1596
|
try {
|
|
1551
1597
|
monitor.init(config);
|
|
1552
1598
|
}
|
|
@@ -1642,64 +1688,131 @@ const SDK_VERSION = '1.0.0';
|
|
|
1642
1688
|
*/
|
|
1643
1689
|
class MonitorSDK {
|
|
1644
1690
|
constructor() {
|
|
1691
|
+
/** SDK 是否已初始化(基础初始化,可能还没有完整配置) */
|
|
1645
1692
|
this.initialized = false;
|
|
1646
|
-
|
|
1693
|
+
/** SDK 是否已就绪(配置完整,可以上报数据) */
|
|
1694
|
+
this.ready = false;
|
|
1695
|
+
/** 是否正在加载远程配置 */
|
|
1696
|
+
this.loading = false;
|
|
1697
|
+
/** 监控模块是否已安装 */
|
|
1698
|
+
this.monitorsInstalled = false;
|
|
1647
1699
|
}
|
|
1648
1700
|
/**
|
|
1649
1701
|
* 初始化 SDK
|
|
1650
|
-
*
|
|
1651
|
-
* 无需 await,SDK 内部会自动处理异步逻辑
|
|
1702
|
+
* 支持空配置初始化,后续通过 updateConfig 传入 configUrl 完成配置
|
|
1652
1703
|
*/
|
|
1653
|
-
init(userConfig) {
|
|
1654
|
-
if (this.initialized
|
|
1655
|
-
|
|
1656
|
-
console.warn('[Monitor] SDK already initialized');
|
|
1657
|
-
}
|
|
1704
|
+
init(userConfig = {}) {
|
|
1705
|
+
if (this.initialized) {
|
|
1706
|
+
console.warn('[Monitor] SDK already initialized');
|
|
1658
1707
|
return;
|
|
1659
1708
|
}
|
|
1660
|
-
// 如果配置了 configUrl
|
|
1709
|
+
// 如果配置了 configUrl,异步获取远程配置
|
|
1661
1710
|
if (userConfig.configUrl) {
|
|
1662
|
-
this.
|
|
1711
|
+
this.loading = true;
|
|
1712
|
+
this.initBasic(userConfig);
|
|
1663
1713
|
this.fetchRemoteConfig(userConfig.configUrl)
|
|
1664
1714
|
.then((remoteConfig) => {
|
|
1665
|
-
// 远程配置作为基础,用户本地配置覆盖远程配置
|
|
1666
1715
|
const finalConfig = this.mergeUserConfig(remoteConfig, userConfig);
|
|
1667
1716
|
if (userConfig.debug) {
|
|
1668
1717
|
console.log('[Monitor] Remote config loaded:', remoteConfig);
|
|
1669
1718
|
}
|
|
1670
|
-
this.
|
|
1719
|
+
this.activate(finalConfig);
|
|
1671
1720
|
})
|
|
1672
1721
|
.catch((error) => {
|
|
1673
|
-
this.
|
|
1722
|
+
this.loading = false;
|
|
1674
1723
|
console.error('[Monitor] Failed to fetch remote config:', error);
|
|
1675
1724
|
});
|
|
1676
1725
|
}
|
|
1726
|
+
else if (userConfig.appId && userConfig.dsn) {
|
|
1727
|
+
// 有完整配置,直接激活
|
|
1728
|
+
this.initBasic(userConfig);
|
|
1729
|
+
this.activate(userConfig);
|
|
1730
|
+
}
|
|
1677
1731
|
else {
|
|
1678
|
-
//
|
|
1679
|
-
this.
|
|
1732
|
+
// 空配置或不完整配置,只做基础初始化,等待后续 updateConfig
|
|
1733
|
+
this.initBasic(userConfig);
|
|
1734
|
+
console.log('[Monitor] SDK initialized in pending mode. Call updateConfig({configUrl}) to activate.');
|
|
1680
1735
|
}
|
|
1681
1736
|
}
|
|
1682
1737
|
/**
|
|
1683
|
-
*
|
|
1738
|
+
* 基础初始化(安装监控模块,但不开始上报)
|
|
1684
1739
|
*/
|
|
1685
|
-
|
|
1686
|
-
// 初始化配置
|
|
1687
|
-
config.init({
|
|
1688
|
-
...finalConfig,
|
|
1689
|
-
version: finalConfig.version || SDK_VERSION,
|
|
1690
|
-
}, isRemoteConfig);
|
|
1740
|
+
initBasic(userConfig) {
|
|
1691
1741
|
// 初始化上下文
|
|
1692
|
-
const maxBreadcrumbs =
|
|
1742
|
+
const maxBreadcrumbs = userConfig.behavior?.maxBreadcrumbs || 20;
|
|
1693
1743
|
context.init(maxBreadcrumbs);
|
|
1744
|
+
// 安装监控模块(早期捕获的数据会被缓存)
|
|
1745
|
+
if (!this.monitorsInstalled) {
|
|
1746
|
+
installErrorHandlers();
|
|
1747
|
+
installPerformanceMonitor();
|
|
1748
|
+
installBehaviorMonitor();
|
|
1749
|
+
this.monitorsInstalled = true;
|
|
1750
|
+
}
|
|
1694
1751
|
this.initialized = true;
|
|
1695
|
-
|
|
1752
|
+
if (userConfig.debug) {
|
|
1753
|
+
console.log('[Monitor] SDK basic initialized (monitors installed, waiting for config)');
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1756
|
+
/**
|
|
1757
|
+
* 激活 SDK(配置完整后调用)
|
|
1758
|
+
*/
|
|
1759
|
+
activate(finalConfig) {
|
|
1760
|
+
// 初始化配置管理器
|
|
1761
|
+
config.init({
|
|
1762
|
+
...finalConfig,
|
|
1763
|
+
version: finalConfig.version || SDK_VERSION,
|
|
1764
|
+
}, true);
|
|
1765
|
+
this.ready = true;
|
|
1766
|
+
this.loading = false;
|
|
1767
|
+
// 通知 reporter 可以开始上报(会自动发送缓存的早期数据)
|
|
1768
|
+
reporter.setReady(true);
|
|
1696
1769
|
if (config.get().debug) {
|
|
1697
|
-
console.log('[Monitor] SDK
|
|
1770
|
+
console.log('[Monitor] SDK activated with config:', config.get());
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
/**
|
|
1774
|
+
* 动态更新配置
|
|
1775
|
+
* 如果传入 configUrl,会从远程获取配置并激活 SDK
|
|
1776
|
+
*/
|
|
1777
|
+
updateConfig(partialConfig) {
|
|
1778
|
+
// 如果传入了 configUrl,从远程获取配置
|
|
1779
|
+
if (partialConfig.configUrl) {
|
|
1780
|
+
console.log('[Monitor] Fetching remote config from:', partialConfig.configUrl);
|
|
1781
|
+
this.loading = true;
|
|
1782
|
+
this.fetchRemoteConfig(partialConfig.configUrl)
|
|
1783
|
+
.then((remoteConfig) => {
|
|
1784
|
+
const mergedConfig = this.mergeUserConfig(remoteConfig, partialConfig);
|
|
1785
|
+
// 移除 configUrl
|
|
1786
|
+
delete mergedConfig.configUrl;
|
|
1787
|
+
if (this.ready) {
|
|
1788
|
+
// 已就绪,更新配置
|
|
1789
|
+
config.update(mergedConfig);
|
|
1790
|
+
this.loading = false;
|
|
1791
|
+
if (config.get().debug) {
|
|
1792
|
+
console.log('[Monitor] Config updated from remote:', mergedConfig);
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1795
|
+
else {
|
|
1796
|
+
// 未就绪,激活 SDK
|
|
1797
|
+
this.activate(mergedConfig);
|
|
1798
|
+
}
|
|
1799
|
+
})
|
|
1800
|
+
.catch((error) => {
|
|
1801
|
+
this.loading = false;
|
|
1802
|
+
console.error('[Monitor] Failed to fetch remote config:', error);
|
|
1803
|
+
});
|
|
1804
|
+
}
|
|
1805
|
+
else {
|
|
1806
|
+
// 普通配置更新
|
|
1807
|
+
if (!this.ready) {
|
|
1808
|
+
console.warn('[Monitor] SDK not ready. Please provide configUrl or (appId + dsn) first.');
|
|
1809
|
+
return;
|
|
1810
|
+
}
|
|
1811
|
+
config.update(partialConfig);
|
|
1812
|
+
if (config.get().debug) {
|
|
1813
|
+
console.log('[Monitor] Config updated', partialConfig);
|
|
1814
|
+
}
|
|
1698
1815
|
}
|
|
1699
|
-
// 安装监控模块
|
|
1700
|
-
installErrorHandlers();
|
|
1701
|
-
installPerformanceMonitor();
|
|
1702
|
-
installBehaviorMonitor();
|
|
1703
1816
|
}
|
|
1704
1817
|
/**
|
|
1705
1818
|
* 从远程获取配置
|
|
@@ -1725,7 +1838,7 @@ class MonitorSDK {
|
|
|
1725
1838
|
if (Object.prototype.hasOwnProperty.call(local, key)) {
|
|
1726
1839
|
const localValue = local[key];
|
|
1727
1840
|
const remoteValue = remote[key];
|
|
1728
|
-
// 跳过 configUrl
|
|
1841
|
+
// 跳过 configUrl
|
|
1729
1842
|
if (key === 'configUrl')
|
|
1730
1843
|
continue;
|
|
1731
1844
|
if (localValue !== null &&
|
|
@@ -1746,55 +1859,33 @@ class MonitorSDK {
|
|
|
1746
1859
|
return result;
|
|
1747
1860
|
}
|
|
1748
1861
|
/**
|
|
1749
|
-
*
|
|
1862
|
+
* 检查 SDK 是否就绪
|
|
1750
1863
|
*/
|
|
1751
|
-
|
|
1752
|
-
this.
|
|
1753
|
-
config.setUser(user);
|
|
1864
|
+
isReady() {
|
|
1865
|
+
return this.ready;
|
|
1754
1866
|
}
|
|
1755
1867
|
/**
|
|
1756
|
-
*
|
|
1757
|
-
* @description 可以在运行时更新 SDK 配置,如 debug、sampling、report 等
|
|
1758
|
-
* 如果传入 configUrl,会从远程获取配置并合并
|
|
1868
|
+
* 设置用户信息
|
|
1759
1869
|
*/
|
|
1760
|
-
|
|
1761
|
-
this.
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
this.fetchRemoteConfig(partialConfig.configUrl)
|
|
1765
|
-
.then((remoteConfig) => {
|
|
1766
|
-
// 远程配置作为基础,传入的其他本地配置覆盖远程配置
|
|
1767
|
-
const mergedConfig = this.mergeUserConfig(remoteConfig, partialConfig);
|
|
1768
|
-
// 移除 configUrl,不需要存到配置里
|
|
1769
|
-
delete mergedConfig.configUrl;
|
|
1770
|
-
config.update(mergedConfig);
|
|
1771
|
-
if (config.get().debug) {
|
|
1772
|
-
console.log('[Monitor] Config updated from remote:', mergedConfig);
|
|
1773
|
-
}
|
|
1774
|
-
})
|
|
1775
|
-
.catch((error) => {
|
|
1776
|
-
console.error('[Monitor] Failed to fetch remote config:', error);
|
|
1777
|
-
});
|
|
1778
|
-
}
|
|
1779
|
-
else {
|
|
1780
|
-
config.update(partialConfig);
|
|
1781
|
-
if (config.get().debug) {
|
|
1782
|
-
console.log('[Monitor] Config updated', partialConfig);
|
|
1783
|
-
}
|
|
1784
|
-
}
|
|
1870
|
+
setUser(user) {
|
|
1871
|
+
if (!this.ready)
|
|
1872
|
+
return;
|
|
1873
|
+
config.setUser(user);
|
|
1785
1874
|
}
|
|
1786
1875
|
/**
|
|
1787
1876
|
* 获取当前配置
|
|
1788
1877
|
*/
|
|
1789
1878
|
getConfig() {
|
|
1790
|
-
this.
|
|
1879
|
+
if (!this.ready)
|
|
1880
|
+
return null;
|
|
1791
1881
|
return config.get();
|
|
1792
1882
|
}
|
|
1793
1883
|
/**
|
|
1794
1884
|
* 手动上报错误
|
|
1795
1885
|
*/
|
|
1796
1886
|
captureError(error, extra) {
|
|
1797
|
-
this.
|
|
1887
|
+
if (!this.ready)
|
|
1888
|
+
return;
|
|
1798
1889
|
const errorData = {
|
|
1799
1890
|
type: 'js_error',
|
|
1800
1891
|
message: typeof error === 'string' ? error : error.message,
|
|
@@ -1807,7 +1898,8 @@ class MonitorSDK {
|
|
|
1807
1898
|
* 手动上报性能数据
|
|
1808
1899
|
*/
|
|
1809
1900
|
capturePerformance(metrics) {
|
|
1810
|
-
this.
|
|
1901
|
+
if (!this.ready)
|
|
1902
|
+
return;
|
|
1811
1903
|
reporter.reportPerformance({
|
|
1812
1904
|
type: 'performance',
|
|
1813
1905
|
metrics,
|
|
@@ -1817,7 +1909,8 @@ class MonitorSDK {
|
|
|
1817
1909
|
* 手动上报行为数据
|
|
1818
1910
|
*/
|
|
1819
1911
|
captureBehavior(action, data) {
|
|
1820
|
-
this.
|
|
1912
|
+
if (!this.ready)
|
|
1913
|
+
return;
|
|
1821
1914
|
reporter.reportBehavior({
|
|
1822
1915
|
type: 'behavior',
|
|
1823
1916
|
action,
|
|
@@ -1828,14 +1921,16 @@ class MonitorSDK {
|
|
|
1828
1921
|
* 添加面包屑
|
|
1829
1922
|
*/
|
|
1830
1923
|
addBreadcrumb(crumb) {
|
|
1831
|
-
this.
|
|
1924
|
+
if (!this.initialized)
|
|
1925
|
+
return;
|
|
1832
1926
|
context.addBreadcrumb(crumb);
|
|
1833
1927
|
}
|
|
1834
1928
|
/**
|
|
1835
1929
|
* 立即发送缓冲区数据
|
|
1836
1930
|
*/
|
|
1837
1931
|
flush() {
|
|
1838
|
-
this.
|
|
1932
|
+
if (!this.ready)
|
|
1933
|
+
return;
|
|
1839
1934
|
reporter.flush();
|
|
1840
1935
|
}
|
|
1841
1936
|
/**
|
|
@@ -1844,14 +1939,6 @@ class MonitorSDK {
|
|
|
1844
1939
|
getVersion() {
|
|
1845
1940
|
return SDK_VERSION;
|
|
1846
1941
|
}
|
|
1847
|
-
/**
|
|
1848
|
-
* 检查是否已初始化
|
|
1849
|
-
*/
|
|
1850
|
-
checkInit() {
|
|
1851
|
-
if (!this.initialized) {
|
|
1852
|
-
throw new Error('[Monitor] SDK not initialized. Please call init() first.');
|
|
1853
|
-
}
|
|
1854
|
-
}
|
|
1855
1942
|
}
|
|
1856
1943
|
// 导出单例
|
|
1857
1944
|
const monitor = new MonitorSDK();
|