sobey-monitor-sdk 1.1.2 → 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 -111
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +27 -19
- package/dist/index.esm.js +196 -111
- package/dist/index.esm.js.map +1 -1
- package/dist/index.umd.js +196 -111
- 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,13 +1494,8 @@ function installBehaviorMonitor() {
|
|
|
1435
1494
|
* ```
|
|
1436
1495
|
*/
|
|
1437
1496
|
const VueMonitorPlugin = {
|
|
1438
|
-
install(app, options) {
|
|
1439
|
-
//
|
|
1440
|
-
if (!options || (!options.configUrl && (!options.appId || !options.dsn))) {
|
|
1441
|
-
console.warn('[Monitor] VueMonitorPlugin requires either configUrl or (appId and dsn) in options');
|
|
1442
|
-
return;
|
|
1443
|
-
}
|
|
1444
|
-
// 初始化 SDK(如果尚未初始化)
|
|
1497
|
+
install(app, options = {}) {
|
|
1498
|
+
// 初始化 SDK(支持空配置,后续通过 updateConfig 激活)
|
|
1445
1499
|
try {
|
|
1446
1500
|
monitor.init(options);
|
|
1447
1501
|
}
|
|
@@ -1537,18 +1591,8 @@ const VueMonitorPlugin = {
|
|
|
1537
1591
|
* );
|
|
1538
1592
|
* ```
|
|
1539
1593
|
*/
|
|
1540
|
-
function createReactErrorBoundary(React, config) {
|
|
1541
|
-
//
|
|
1542
|
-
if (!config || (!config.configUrl && (!config.appId || !config.dsn))) {
|
|
1543
|
-
console.warn('[Monitor] createReactErrorBoundary requires either configUrl or (appId and dsn) in config');
|
|
1544
|
-
// 返回一个空的组件
|
|
1545
|
-
return class EmptyBoundary extends React.Component {
|
|
1546
|
-
render() {
|
|
1547
|
-
return this.props.children;
|
|
1548
|
-
}
|
|
1549
|
-
};
|
|
1550
|
-
}
|
|
1551
|
-
// 初始化 SDK(如果尚未初始化)
|
|
1594
|
+
function createReactErrorBoundary(React, config = {}) {
|
|
1595
|
+
// 初始化 SDK(支持空配置,后续通过 updateConfig 激活)
|
|
1552
1596
|
try {
|
|
1553
1597
|
monitor.init(config);
|
|
1554
1598
|
}
|
|
@@ -1644,64 +1688,131 @@ const SDK_VERSION = '1.0.0';
|
|
|
1644
1688
|
*/
|
|
1645
1689
|
class MonitorSDK {
|
|
1646
1690
|
constructor() {
|
|
1691
|
+
/** SDK 是否已初始化(基础初始化,可能还没有完整配置) */
|
|
1647
1692
|
this.initialized = false;
|
|
1648
|
-
|
|
1693
|
+
/** SDK 是否已就绪(配置完整,可以上报数据) */
|
|
1694
|
+
this.ready = false;
|
|
1695
|
+
/** 是否正在加载远程配置 */
|
|
1696
|
+
this.loading = false;
|
|
1697
|
+
/** 监控模块是否已安装 */
|
|
1698
|
+
this.monitorsInstalled = false;
|
|
1649
1699
|
}
|
|
1650
1700
|
/**
|
|
1651
1701
|
* 初始化 SDK
|
|
1652
|
-
*
|
|
1653
|
-
* 无需 await,SDK 内部会自动处理异步逻辑
|
|
1702
|
+
* 支持空配置初始化,后续通过 updateConfig 传入 configUrl 完成配置
|
|
1654
1703
|
*/
|
|
1655
|
-
init(userConfig) {
|
|
1656
|
-
if (this.initialized
|
|
1657
|
-
|
|
1658
|
-
console.warn('[Monitor] SDK already initialized');
|
|
1659
|
-
}
|
|
1704
|
+
init(userConfig = {}) {
|
|
1705
|
+
if (this.initialized) {
|
|
1706
|
+
console.warn('[Monitor] SDK already initialized');
|
|
1660
1707
|
return;
|
|
1661
1708
|
}
|
|
1662
|
-
// 如果配置了 configUrl
|
|
1709
|
+
// 如果配置了 configUrl,异步获取远程配置
|
|
1663
1710
|
if (userConfig.configUrl) {
|
|
1664
|
-
this.
|
|
1711
|
+
this.loading = true;
|
|
1712
|
+
this.initBasic(userConfig);
|
|
1665
1713
|
this.fetchRemoteConfig(userConfig.configUrl)
|
|
1666
1714
|
.then((remoteConfig) => {
|
|
1667
|
-
// 远程配置作为基础,用户本地配置覆盖远程配置
|
|
1668
1715
|
const finalConfig = this.mergeUserConfig(remoteConfig, userConfig);
|
|
1669
1716
|
if (userConfig.debug) {
|
|
1670
1717
|
console.log('[Monitor] Remote config loaded:', remoteConfig);
|
|
1671
1718
|
}
|
|
1672
|
-
this.
|
|
1719
|
+
this.activate(finalConfig);
|
|
1673
1720
|
})
|
|
1674
1721
|
.catch((error) => {
|
|
1675
|
-
this.
|
|
1722
|
+
this.loading = false;
|
|
1676
1723
|
console.error('[Monitor] Failed to fetch remote config:', error);
|
|
1677
1724
|
});
|
|
1678
1725
|
}
|
|
1726
|
+
else if (userConfig.appId && userConfig.dsn) {
|
|
1727
|
+
// 有完整配置,直接激活
|
|
1728
|
+
this.initBasic(userConfig);
|
|
1729
|
+
this.activate(userConfig);
|
|
1730
|
+
}
|
|
1679
1731
|
else {
|
|
1680
|
-
//
|
|
1681
|
-
this.
|
|
1732
|
+
// 空配置或不完整配置,只做基础初始化,等待后续 updateConfig
|
|
1733
|
+
this.initBasic(userConfig);
|
|
1734
|
+
console.log('[Monitor] SDK initialized in pending mode. Call updateConfig({configUrl}) to activate.');
|
|
1682
1735
|
}
|
|
1683
1736
|
}
|
|
1684
1737
|
/**
|
|
1685
|
-
*
|
|
1738
|
+
* 基础初始化(安装监控模块,但不开始上报)
|
|
1686
1739
|
*/
|
|
1687
|
-
|
|
1688
|
-
// 初始化配置
|
|
1689
|
-
config.init({
|
|
1690
|
-
...finalConfig,
|
|
1691
|
-
version: finalConfig.version || SDK_VERSION,
|
|
1692
|
-
}, isRemoteConfig);
|
|
1740
|
+
initBasic(userConfig) {
|
|
1693
1741
|
// 初始化上下文
|
|
1694
|
-
const maxBreadcrumbs =
|
|
1742
|
+
const maxBreadcrumbs = userConfig.behavior?.maxBreadcrumbs || 20;
|
|
1695
1743
|
context.init(maxBreadcrumbs);
|
|
1744
|
+
// 安装监控模块(早期捕获的数据会被缓存)
|
|
1745
|
+
if (!this.monitorsInstalled) {
|
|
1746
|
+
installErrorHandlers();
|
|
1747
|
+
installPerformanceMonitor();
|
|
1748
|
+
installBehaviorMonitor();
|
|
1749
|
+
this.monitorsInstalled = true;
|
|
1750
|
+
}
|
|
1696
1751
|
this.initialized = true;
|
|
1697
|
-
|
|
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);
|
|
1698
1769
|
if (config.get().debug) {
|
|
1699
|
-
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
|
+
}
|
|
1700
1815
|
}
|
|
1701
|
-
// 安装监控模块
|
|
1702
|
-
installErrorHandlers();
|
|
1703
|
-
installPerformanceMonitor();
|
|
1704
|
-
installBehaviorMonitor();
|
|
1705
1816
|
}
|
|
1706
1817
|
/**
|
|
1707
1818
|
* 从远程获取配置
|
|
@@ -1727,7 +1838,7 @@ class MonitorSDK {
|
|
|
1727
1838
|
if (Object.prototype.hasOwnProperty.call(local, key)) {
|
|
1728
1839
|
const localValue = local[key];
|
|
1729
1840
|
const remoteValue = remote[key];
|
|
1730
|
-
// 跳过 configUrl
|
|
1841
|
+
// 跳过 configUrl
|
|
1731
1842
|
if (key === 'configUrl')
|
|
1732
1843
|
continue;
|
|
1733
1844
|
if (localValue !== null &&
|
|
@@ -1748,55 +1859,33 @@ class MonitorSDK {
|
|
|
1748
1859
|
return result;
|
|
1749
1860
|
}
|
|
1750
1861
|
/**
|
|
1751
|
-
*
|
|
1862
|
+
* 检查 SDK 是否就绪
|
|
1752
1863
|
*/
|
|
1753
|
-
|
|
1754
|
-
this.
|
|
1755
|
-
config.setUser(user);
|
|
1864
|
+
isReady() {
|
|
1865
|
+
return this.ready;
|
|
1756
1866
|
}
|
|
1757
1867
|
/**
|
|
1758
|
-
*
|
|
1759
|
-
* @description 可以在运行时更新 SDK 配置,如 debug、sampling、report 等
|
|
1760
|
-
* 如果传入 configUrl,会从远程获取配置并合并
|
|
1868
|
+
* 设置用户信息
|
|
1761
1869
|
*/
|
|
1762
|
-
|
|
1763
|
-
this.
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
this.fetchRemoteConfig(partialConfig.configUrl)
|
|
1767
|
-
.then((remoteConfig) => {
|
|
1768
|
-
// 远程配置作为基础,传入的其他本地配置覆盖远程配置
|
|
1769
|
-
const mergedConfig = this.mergeUserConfig(remoteConfig, partialConfig);
|
|
1770
|
-
// 移除 configUrl,不需要存到配置里
|
|
1771
|
-
delete mergedConfig.configUrl;
|
|
1772
|
-
config.update(mergedConfig);
|
|
1773
|
-
if (config.get().debug) {
|
|
1774
|
-
console.log('[Monitor] Config updated from remote:', mergedConfig);
|
|
1775
|
-
}
|
|
1776
|
-
})
|
|
1777
|
-
.catch((error) => {
|
|
1778
|
-
console.error('[Monitor] Failed to fetch remote config:', error);
|
|
1779
|
-
});
|
|
1780
|
-
}
|
|
1781
|
-
else {
|
|
1782
|
-
config.update(partialConfig);
|
|
1783
|
-
if (config.get().debug) {
|
|
1784
|
-
console.log('[Monitor] Config updated', partialConfig);
|
|
1785
|
-
}
|
|
1786
|
-
}
|
|
1870
|
+
setUser(user) {
|
|
1871
|
+
if (!this.ready)
|
|
1872
|
+
return;
|
|
1873
|
+
config.setUser(user);
|
|
1787
1874
|
}
|
|
1788
1875
|
/**
|
|
1789
1876
|
* 获取当前配置
|
|
1790
1877
|
*/
|
|
1791
1878
|
getConfig() {
|
|
1792
|
-
this.
|
|
1879
|
+
if (!this.ready)
|
|
1880
|
+
return null;
|
|
1793
1881
|
return config.get();
|
|
1794
1882
|
}
|
|
1795
1883
|
/**
|
|
1796
1884
|
* 手动上报错误
|
|
1797
1885
|
*/
|
|
1798
1886
|
captureError(error, extra) {
|
|
1799
|
-
this.
|
|
1887
|
+
if (!this.ready)
|
|
1888
|
+
return;
|
|
1800
1889
|
const errorData = {
|
|
1801
1890
|
type: 'js_error',
|
|
1802
1891
|
message: typeof error === 'string' ? error : error.message,
|
|
@@ -1809,7 +1898,8 @@ class MonitorSDK {
|
|
|
1809
1898
|
* 手动上报性能数据
|
|
1810
1899
|
*/
|
|
1811
1900
|
capturePerformance(metrics) {
|
|
1812
|
-
this.
|
|
1901
|
+
if (!this.ready)
|
|
1902
|
+
return;
|
|
1813
1903
|
reporter.reportPerformance({
|
|
1814
1904
|
type: 'performance',
|
|
1815
1905
|
metrics,
|
|
@@ -1819,7 +1909,8 @@ class MonitorSDK {
|
|
|
1819
1909
|
* 手动上报行为数据
|
|
1820
1910
|
*/
|
|
1821
1911
|
captureBehavior(action, data) {
|
|
1822
|
-
this.
|
|
1912
|
+
if (!this.ready)
|
|
1913
|
+
return;
|
|
1823
1914
|
reporter.reportBehavior({
|
|
1824
1915
|
type: 'behavior',
|
|
1825
1916
|
action,
|
|
@@ -1830,14 +1921,16 @@ class MonitorSDK {
|
|
|
1830
1921
|
* 添加面包屑
|
|
1831
1922
|
*/
|
|
1832
1923
|
addBreadcrumb(crumb) {
|
|
1833
|
-
this.
|
|
1924
|
+
if (!this.initialized)
|
|
1925
|
+
return;
|
|
1834
1926
|
context.addBreadcrumb(crumb);
|
|
1835
1927
|
}
|
|
1836
1928
|
/**
|
|
1837
1929
|
* 立即发送缓冲区数据
|
|
1838
1930
|
*/
|
|
1839
1931
|
flush() {
|
|
1840
|
-
this.
|
|
1932
|
+
if (!this.ready)
|
|
1933
|
+
return;
|
|
1841
1934
|
reporter.flush();
|
|
1842
1935
|
}
|
|
1843
1936
|
/**
|
|
@@ -1846,14 +1939,6 @@ class MonitorSDK {
|
|
|
1846
1939
|
getVersion() {
|
|
1847
1940
|
return SDK_VERSION;
|
|
1848
1941
|
}
|
|
1849
|
-
/**
|
|
1850
|
-
* 检查是否已初始化
|
|
1851
|
-
*/
|
|
1852
|
-
checkInit() {
|
|
1853
|
-
if (!this.initialized) {
|
|
1854
|
-
throw new Error('[Monitor] SDK not initialized. Please call init() first.');
|
|
1855
|
-
}
|
|
1856
|
-
}
|
|
1857
1942
|
}
|
|
1858
1943
|
// 导出单例
|
|
1859
1944
|
const monitor = new MonitorSDK();
|