@arms/rum-core 0.1.7 → 0.1.9

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.
@@ -68,14 +68,16 @@ var Client = /*#__PURE__*/function () {
68
68
  }
69
69
  if (processor.match(ctx)) {
70
70
  var res = processor.process(ctx);
71
- if (res) {
72
- ctx.setRumEvent(res);
73
- }
71
+ // 无论返回值是否为 falsy 都写回 context,
72
+ // 确保 processor 返回 null/undefined(丢弃事件)时能正确生效
73
+ ctx.setRumEvent(res);
74
74
  }
75
75
  }
76
76
  reporter.report(ctx, options);
77
77
  });
78
- collectors.forEach(function (collector) {
78
+
79
+ // 采集器可全部经 Shell 扩展通道注册,此处允许为空
80
+ (collectors || []).forEach(function (collector) {
79
81
  collector.setup(ctx, _this2.sendEvent);
80
82
  });
81
83
  };
@@ -21,7 +21,7 @@ export declare abstract class ConfigManager implements IConfigManager {
21
21
  * 更新配置
22
22
  * @param config 新配置
23
23
  */
24
- setConfig(config: Partial<IConfiguration>): Promise<void>;
24
+ setConfig(config: Partial<IConfiguration>): void;
25
25
  /**
26
26
  * 检查缓存是否有效
27
27
  * @param cachedData 缓存数据
@@ -1,6 +1,3 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
3
- import _regeneratorRuntime from "@babel/runtime/regenerator";
4
1
  function parseRemoteConfig(config) {
5
2
  var remoteConfig = config.remoteConfig || {};
6
3
  var enable = false;
@@ -33,75 +30,46 @@ export var ConfigManager = /*#__PURE__*/function () {
33
30
  * 初始化配置管理器
34
31
  * @param config 初始配置
35
32
  */
36
- _proto.init =
37
- /*#__PURE__*/
38
- function () {
39
- var _init = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(config) {
40
- var _this = this;
41
- var remoteConfig, cacheConfig, asyncConfigPromise;
42
- return _regeneratorRuntime.wrap(function (_context) {
43
- while (1) switch (_context.prev = _context.next) {
44
- case 0:
45
- if (!this.initialized) {
46
- _context.next = 1;
47
- break;
48
- }
49
- return _context.abrupt("return");
50
- case 1:
51
- this.currentConfig = _extends({}, config);
52
- this.initialized = true;
53
- remoteConfig = parseRemoteConfig(config);
54
- this.currentConfig.remoteConfig = remoteConfig;
55
- if (remoteConfig.enable) {
56
- _context.next = 2;
57
- break;
58
- }
59
- return _context.abrupt("return");
60
- case 2:
61
- _context.next = 3;
62
- return this.getCacheConfig();
63
- case 3:
64
- cacheConfig = _context.sent;
65
- if (cacheConfig && cacheConfig.content) {
66
- this.currentConfig = this.mergeRemoteCfg(cacheConfig.content);
67
- }
68
- if (!this.isCacheValid(cacheConfig, remoteConfig.cacheTimeout)) {
69
- _context.next = 4;
70
- break;
71
- }
72
- return _context.abrupt("return");
73
- case 4:
74
- asyncConfigPromise = this.fetchRemoteCfg(this.currentConfig).then(function (resp) {
75
- if (!resp) return;
76
- var asyncRemoteConfig = _this.parseConfig(resp);
77
- _this.currentConfig = _this.mergeRemoteCfg(asyncRemoteConfig);
78
- _this.setCacheConfig({
79
- timestamp: Date.now(),
80
- content: resp
81
- });
82
- });
83
- if (!(remoteConfig.mode === 'remote-first')) {
84
- _context.next = 5;
85
- break;
86
- }
87
- _context.next = 5;
88
- return asyncConfigPromise;
89
- case 5:
90
- case "end":
91
- return _context.stop();
92
- }
93
- }, _callee, this);
94
- }));
95
- function init(_x) {
96
- return _init.apply(this, arguments);
33
+ _proto.init = function init(config) {
34
+ var _this = this;
35
+ if (this.initialized) {
36
+ return Promise.resolve();
97
37
  }
98
- return init;
99
- }()
38
+ this.currentConfig = Object.assign({}, config);
39
+ this.initialized = true;
40
+ var remoteConfig = parseRemoteConfig(config);
41
+ this.currentConfig.remoteConfig = remoteConfig;
42
+ if (!remoteConfig.enable) {
43
+ return Promise.resolve();
44
+ }
45
+ return Promise.resolve(this.getCacheConfig()).then(function (cacheConfig) {
46
+ if (cacheConfig && cacheConfig.content) {
47
+ _this.currentConfig = _this.mergeRemoteCfg(cacheConfig.content);
48
+ }
49
+ if (_this.isCacheValid(cacheConfig, remoteConfig.cacheTimeout)) {
50
+ // 配置有效期内直接返回,不抓取远端配置
51
+ return;
52
+ }
53
+ var asyncConfigPromise = _this.fetchRemoteCfg(_this.currentConfig).then(function (resp) {
54
+ if (!resp) return;
55
+ var asyncRemoteConfig = _this.parseConfig(resp);
56
+ _this.currentConfig = _this.mergeRemoteCfg(asyncRemoteConfig);
57
+ _this.setCacheConfig({
58
+ timestamp: Date.now(),
59
+ content: resp
60
+ });
61
+ });
62
+ if (remoteConfig.mode === 'remote-first') {
63
+ // 远端配置优先情况下,要等待获取完成后返回
64
+ return asyncConfigPromise;
65
+ }
66
+ });
67
+ }
68
+
100
69
  /**
101
70
  * 获取配置
102
71
  * @returns 配置数据
103
- */
104
- ;
72
+ */;
105
73
  _proto.getConfig = function getConfig() {
106
74
  if (!this.currentConfig) {
107
75
  throw new Error('Config not initialized');
@@ -113,37 +81,16 @@ export var ConfigManager = /*#__PURE__*/function () {
113
81
  * 更新配置
114
82
  * @param config 新配置
115
83
  */;
116
- _proto.setConfig =
117
- /*#__PURE__*/
118
- function () {
119
- var _setConfig = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(config) {
120
- return _regeneratorRuntime.wrap(function (_context2) {
121
- while (1) switch (_context2.prev = _context2.next) {
122
- case 0:
123
- if (this.currentConfig) {
124
- _context2.next = 1;
125
- break;
126
- }
127
- return _context2.abrupt("return");
128
- case 1:
129
- this.currentConfig = _extends({}, this.currentConfig, config);
130
- case 2:
131
- case "end":
132
- return _context2.stop();
133
- }
134
- }, _callee2, this);
135
- }));
136
- function setConfig(_x2) {
137
- return _setConfig.apply(this, arguments);
138
- }
139
- return setConfig;
140
- }()
84
+ _proto.setConfig = function setConfig(config) {
85
+ if (!this.currentConfig) return;
86
+ this.currentConfig = Object.assign({}, this.currentConfig, config);
87
+ }
88
+
141
89
  /**
142
90
  * 检查缓存是否有效
143
91
  * @param cachedData 缓存数据
144
92
  * @param cacheTimeout 缓存超时时间
145
- */
146
- ;
93
+ */;
147
94
  _proto.isCacheValid = function isCacheValid(cachedData, cacheTimeout) {
148
95
  if (!cachedData || !cachedData.timestamp) {
149
96
  return false;
@@ -165,7 +112,7 @@ export var ConfigManager = /*#__PURE__*/function () {
165
112
  remoteConfig = _this$currentConfig.remoteConfig,
166
113
  beforeReport = _this$currentConfig.beforeReport,
167
114
  properties = _this$currentConfig.properties;
168
- return _extends({}, this.currentConfig, remoteCfg, {
115
+ return Object.assign({}, this.currentConfig, remoteCfg, {
169
116
  pid: pid,
170
117
  app: app,
171
118
  endpoint: endpoint,
@@ -1,6 +1,3 @@
1
- import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
2
- import _extends from "@babel/runtime/helpers/extends";
3
- import _regeneratorRuntime from "@babel/runtime/regenerator";
4
1
  import { logger } from '../monitor/logger';
5
2
  import { RumEventType } from '../types/rum-event';
6
3
  import { getErrorID } from '../utils/exception';
@@ -82,6 +79,7 @@ var Reporter = /*#__PURE__*/function () {
82
79
  var sampled = session ? session.getSampled() : true;
83
80
  if (!sampled) return;
84
81
  var event = ctx.getRumEvent();
82
+ if (!event) return;
85
83
  var views = ctx.getViews();
86
84
  var curView = views[views.length - 1];
87
85
  if (((_event$view = event.view) === null || _event$view === void 0 ? void 0 : _event$view.id) === curView.id) {
@@ -93,6 +91,8 @@ var Reporter = /*#__PURE__*/function () {
93
91
  var ctx = this.ctx,
94
92
  eventQueue = this.eventQueue;
95
93
  var event = ctx.getRumEvent();
94
+ // processor 返回 null/undefined 表示丢弃事件,直接跳过
95
+ if (!event) return;
96
96
 
97
97
  // 针对相同 event,做 times 合并
98
98
  // todo,支持其他类型 event 合并
@@ -204,7 +204,7 @@ var Reporter = /*#__PURE__*/function () {
204
204
  */;
205
205
  _proto.buildAndSend = function buildAndSend(ctx, config, session, sessionId, events, view) {
206
206
  var extend = getUrlParams(config.endpoint);
207
- var bundle = _extends({
207
+ var bundle = Object.assign({
208
208
  app: {
209
209
  id: config.pid,
210
210
  env: config.env || 'prod',
@@ -243,54 +243,32 @@ var Reporter = /*#__PURE__*/function () {
243
243
  }
244
244
  this.tryRequest(bundle);
245
245
  };
246
- _proto.tryRequest = /*#__PURE__*/function () {
247
- var _tryRequest = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee(bundle, retry) {
248
- var _this$ctx$getConfig,
249
- _reportConfig$maxRetr,
250
- _reportConfig$retryDe,
251
- _this2 = this;
252
- var reportConfig, maxRetryCount, retryDelay, _t;
253
- return _regeneratorRuntime.wrap(function (_context) {
254
- while (1) switch (_context.prev = _context.next) {
255
- case 0:
256
- if (retry === void 0) {
257
- retry = 0;
258
- }
259
- reportConfig = (_this$ctx$getConfig = this.ctx.getConfig()) === null || _this$ctx$getConfig === void 0 ? void 0 : _this$ctx$getConfig.reportConfig;
260
- maxRetryCount = (_reportConfig$maxRetr = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.maxRetryCount) !== null && _reportConfig$maxRetr !== void 0 ? _reportConfig$maxRetr : 0;
261
- retryDelay = (_reportConfig$retryDe = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.retryDelay) !== null && _reportConfig$retryDe !== void 0 ? _reportConfig$retryDe : 3000;
262
- _context.prev = 1;
263
- bundle._retry = retry;
264
- _context.next = 2;
265
- return this.request(this.ctx, bundle);
266
- case 2:
267
- _context.next = 4;
268
- break;
269
- case 3:
270
- _context.prev = 3;
271
- _t = _context["catch"](1);
272
- if (retry < maxRetryCount - 1) {
273
- setTimeout(function () {
274
- return _this2.tryRequest(bundle, retry + 1);
275
- }, retryDelay);
276
- } else {
277
- logger.error('reporter', "Request failed after " + (retry + 1) + " attempts", _t);
278
- }
279
- case 4:
280
- case "end":
281
- return _context.stop();
282
- }
283
- }, _callee, this, [[1, 3]]);
284
- }));
285
- function tryRequest(_x, _x2) {
286
- return _tryRequest.apply(this, arguments);
246
+ _proto.tryRequest = function tryRequest(bundle, retry) {
247
+ var _this$ctx$getConfig,
248
+ _reportConfig$maxRetr,
249
+ _reportConfig$retryDe,
250
+ _this2 = this;
251
+ if (retry === void 0) {
252
+ retry = 0;
287
253
  }
288
- return tryRequest;
289
- }()
254
+ var reportConfig = (_this$ctx$getConfig = this.ctx.getConfig()) === null || _this$ctx$getConfig === void 0 ? void 0 : _this$ctx$getConfig.reportConfig;
255
+ var maxRetryCount = (_reportConfig$maxRetr = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.maxRetryCount) !== null && _reportConfig$maxRetr !== void 0 ? _reportConfig$maxRetr : 0;
256
+ var retryDelay = (_reportConfig$retryDe = reportConfig === null || reportConfig === void 0 ? void 0 : reportConfig.retryDelay) !== null && _reportConfig$retryDe !== void 0 ? _reportConfig$retryDe : 3000;
257
+ bundle._retry = retry;
258
+ Promise.resolve(this.request(this.ctx, bundle))["catch"](function (e) {
259
+ if (retry < maxRetryCount - 1) {
260
+ setTimeout(function () {
261
+ return _this2.tryRequest(bundle, retry + 1);
262
+ }, retryDelay);
263
+ } else {
264
+ logger.error('reporter', "Request failed after " + (retry + 1) + " attempts", e);
265
+ }
266
+ });
267
+ }
268
+
290
269
  /**
291
270
  * 接口请求由各平台 sdk reporter 实现
292
- */
293
- ;
271
+ */;
294
272
  /**
295
273
  * 初始化时
296
274
  */
@@ -1,9 +1,31 @@
1
1
  import { IClient, IConfiguration } from '../types/client';
2
+ import { ICollector } from '../types/collector';
2
3
  import { RumCustomEvent, RumEvent, RumExceptionEvent, RumResourceEvent, RumViewEvent, SendEventOptions } from '../types/rum-event';
3
4
  import { IShell } from '../types/shell';
4
5
  export default abstract class Shell implements IShell {
5
6
  client: IClient;
7
+ protected initialized: boolean;
8
+ private extensionCollectors;
9
+ private static instances;
6
10
  constructor(config?: IConfiguration);
11
+ /**
12
+ * 注册扩展采集器(实例方法,支持 per-instance 隔离)
13
+ * 支持在 init 之前或之后调用;若已初始化则立即 setup
14
+ */
15
+ useCollectors(...collectors: ICollector[]): void;
16
+ /**
17
+ * 返回当前实例装载的全部采集器(client 内置通道 + 实例扩展通道)
18
+ */
19
+ getCollectors(): ICollector[];
20
+ /**
21
+ * 向所有已初始化的实例广播事件
22
+ */
23
+ static broadcastEvent(event: RumEvent, options?: SendEventOptions): void;
24
+ /**
25
+ * 统一初始化 Client,并在 init 完成后自动挂载扩展采集器。
26
+ * 由 client.init 拦截器自动调用,子包无需手动调用。
27
+ */
28
+ protected initClient(): void;
7
29
  /**
8
30
  * 初始化
9
31
  */
package/es/model/shell.js CHANGED
@@ -1,40 +1,89 @@
1
- import _extends from "@babel/runtime/helpers/extends";
1
+ var _Shell;
2
2
  import { RumEventType } from '../types/rum-event';
3
3
  import Client from '../model/client';
4
4
  import { isNumber, isObject } from '../utils/is';
5
5
  var Shell = /*#__PURE__*/function () {
6
6
  function Shell(config) {
7
- // private callbacks: Function[] = [];
8
- // private initialized = false;
7
+ var _this = this;
9
8
  this.client = void 0;
9
+ this.initialized = false;
10
+ this.extensionCollectors = [];
10
11
  this.client = new Client();
12
+
13
+ // 拦截 client.init,自动在其后挂载扩展采集器
14
+ var originalInit = this.client.init.bind(this.client);
15
+ this.client.init = function () {
16
+ originalInit.apply(void 0, arguments);
17
+ _this.initClient();
18
+ };
11
19
  if (config && this.init) {
12
20
  this.init(config);
13
- // const p = this.init(config) as Promise<Shell>;
14
- // if(isFunction(p?.then)){
15
- // p.then(this.shellReady);
16
- // } else {
17
- // this.shellReady()
18
- // }
19
21
  }
20
22
  }
21
23
 
22
- // private shellReady = () => {
23
- // this.initialized = true;
24
- // this.callbacks.forEach(cb => cb());
25
- // }
26
- //
27
- // onReady(callback: Function) {
28
- // if (this.initialized) {
29
- // callback();
30
- // }
31
- // this.callbacks.push(callback);
32
- // }
33
-
34
24
  /**
35
- * 初始化
25
+ * 注册扩展采集器(实例方法,支持 per-instance 隔离)
26
+ * 支持在 init 之前或之后调用;若已初始化则立即 setup
36
27
  */
37
28
  var _proto = Shell.prototype;
29
+ _proto.useCollectors = function useCollectors() {
30
+ var _this$extensionCollec,
31
+ _this2 = this;
32
+ for (var _len = arguments.length, collectors = new Array(_len), _key = 0; _key < _len; _key++) {
33
+ collectors[_key] = arguments[_key];
34
+ }
35
+ (_this$extensionCollec = this.extensionCollectors).push.apply(_this$extensionCollec, collectors);
36
+ if (this.initialized && this.client) {
37
+ var ctx = this.client.getContext();
38
+ if (ctx) {
39
+ collectors.forEach(function (collector) {
40
+ collector.setup(ctx, _this2.client.sendEvent);
41
+ });
42
+ }
43
+ }
44
+ }
45
+
46
+ /**
47
+ * 返回当前实例装载的全部采集器(client 内置通道 + 实例扩展通道)
48
+ */;
49
+ _proto.getCollectors = function getCollectors() {
50
+ var clientCollectors = this.client && this.client.getCollectors() || [];
51
+ // 用 concat 替代数组 spread,避免依赖 babel 降级注入 helper(项目去 @babel/runtime 规范)
52
+ return clientCollectors.concat(this.extensionCollectors);
53
+ }
54
+
55
+ /**
56
+ * 向所有已初始化的实例广播事件
57
+ */;
58
+ Shell.broadcastEvent = function broadcastEvent(event, options) {
59
+ Shell.instances.forEach(function (instance) {
60
+ if (instance.initialized && instance.client) {
61
+ instance.client.sendEvent(event, options);
62
+ }
63
+ });
64
+ }
65
+
66
+ /**
67
+ * 统一初始化 Client,并在 init 完成后自动挂载扩展采集器。
68
+ * 由 client.init 拦截器自动调用,子包无需手动调用。
69
+ */;
70
+ _proto.initClient = function initClient() {
71
+ var _this3 = this;
72
+ if (this.extensionCollectors.length > 0) {
73
+ var ctx = this.client.getContext();
74
+ if (ctx) {
75
+ this.extensionCollectors.forEach(function (collector) {
76
+ collector.setup(ctx, _this3.client.sendEvent);
77
+ });
78
+ }
79
+ }
80
+ this.initialized = true;
81
+ Shell.instances.push(this);
82
+ }
83
+
84
+ /**
85
+ * 初始化
86
+ */;
38
87
  _proto.sendEvent = function sendEvent(payload, options) {
39
88
  if (this.client) {
40
89
  this.client.sendEvent(payload, options);
@@ -60,7 +109,7 @@ var Shell = /*#__PURE__*/function () {
60
109
  if (!payload.name || !payload.type) {
61
110
  return;
62
111
  }
63
- var data = _extends({}, payload, {
112
+ var data = Object.assign({}, payload, {
64
113
  event_type: RumEventType.CUSTOM
65
114
  });
66
115
  this.sendEvent(data);
@@ -86,7 +135,7 @@ var Shell = /*#__PURE__*/function () {
86
135
  });
87
136
  if (n === 0) return;
88
137
  }
89
- var data = _extends({}, payload, {
138
+ var data = Object.assign({}, payload, {
90
139
  event_type: RumEventType.VIEW
91
140
  });
92
141
  this.sendEvent(data);
@@ -102,7 +151,7 @@ var Shell = /*#__PURE__*/function () {
102
151
  var name = payload.name,
103
152
  message = payload.message,
104
153
  stack = payload.stack;
105
- var data = _extends({
154
+ var data = Object.assign({
106
155
  times: 1,
107
156
  name: name,
108
157
  message: message,
@@ -122,7 +171,7 @@ var Shell = /*#__PURE__*/function () {
122
171
  if (!payload.name || !payload.type || !isNumber(payload.duration)) {
123
172
  return;
124
173
  }
125
- var data = _extends({
174
+ var data = Object.assign({
126
175
  times: 1
127
176
  }, payload, {
128
177
  event_type: RumEventType.RESOURCE
@@ -131,4 +180,6 @@ var Shell = /*#__PURE__*/function () {
131
180
  };
132
181
  return Shell;
133
182
  }();
183
+ _Shell = Shell;
184
+ Shell.instances = [];
134
185
  export { Shell as default };
@@ -1,5 +1,10 @@
1
1
  import { MonitorLogEvent, MonitorLogLevel } from './types';
2
- type LogArgs = [module: string, message: string, error?: unknown, context?: Record<string, unknown>];
2
+ type LogArgs = [
3
+ module: string,
4
+ message: string,
5
+ error?: unknown,
6
+ context?: Record<string, unknown>
7
+ ];
3
8
  export interface ILogger {
4
9
  debug(...args: LogArgs): void;
5
10
  info(...args: LogArgs): void;
@@ -57,7 +57,7 @@ var Logger = /*#__PURE__*/function () {
57
57
  }
58
58
 
59
59
  // 仅上报配置中指定的级别
60
- if (!this.reportLevels.includes(level)) return;
60
+ if (this.reportLevels.indexOf(level) === -1) return;
61
61
  var stack;
62
62
  if (error instanceof Error) {
63
63
  stack = error.stack;
@@ -1,4 +1,3 @@
1
- import _extends from "@babel/runtime/helpers/extends";
2
1
  var _Telemetry;
3
2
  import { logger } from './logger';
4
3
  import { getUrlParams } from '../utils/url';
@@ -75,12 +74,12 @@ export var Telemetry = /*#__PURE__*/function () {
75
74
  var _this$context$getSess, _this$context, _this$context$getView, _this$context2;
76
75
  if (!this.enabled || !event) return;
77
76
  if (event.content && event.content.length > LOG_CONTENT_MAX_SIZE) {
78
- event = _extends({}, event, {
77
+ event = Object.assign({}, event, {
79
78
  content: event.content.slice(0, LOG_CONTENT_MAX_SIZE)
80
79
  });
81
80
  }
82
81
  if (event.stack && event.stack.length > LOG_CONTENT_MAX_SIZE) {
83
- event = _extends({}, event, {
82
+ event = Object.assign({}, event, {
84
83
  stack: event.stack.slice(0, LOG_CONTENT_MAX_SIZE)
85
84
  });
86
85
  }
@@ -149,7 +148,7 @@ export var Telemetry = /*#__PURE__*/function () {
149
148
  appType = _this$context3.appType,
150
149
  sdkVersion = _this$context3.sdkVersion,
151
150
  endpoint = _this$context3.endpoint;
152
- return _extends({
151
+ return Object.assign({
153
152
  'app.type': appType,
154
153
  _v: sdkVersion,
155
154
  endpoint: endpoint,
@@ -189,11 +188,11 @@ export function convertBundlesToLogGroup(data) {
189
188
  var contents = [];
190
189
 
191
190
  // 遍历 bundle 顶层字段,跳过 timestamp(映射到 time),对象类型整体序列化
192
- for (var _i = 0, _Object$entries = Object.entries(bundle); _i < _Object$entries.length; _i++) {
193
- var _Object$entries$_i = _Object$entries[_i],
194
- _key = _Object$entries$_i[0],
195
- val = _Object$entries$_i[1];
191
+ var bundleKeys = Object.keys(bundle);
192
+ for (var i = 0; i < bundleKeys.length; i++) {
193
+ var _key = bundleKeys[i];
196
194
  if (_key === 'timestamp') continue;
195
+ var val = bundle[_key];
197
196
  if (val !== undefined && val !== null) {
198
197
  contents.push({
199
198
  key: _key,
@@ -1,4 +1,5 @@
1
1
  import { IConfiguration } from './client';
2
+ import { ICollector } from './collector';
2
3
  import { RumEvent, SendEventOptions } from './rum-event';
3
4
  /**
4
5
  * 每个 sdk shell 导出固定需要实现的基础 api
@@ -8,6 +9,14 @@ import { RumEvent, SendEventOptions } from './rum-event';
8
9
  * 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
9
10
  */
10
11
  export interface IShell {
12
+ /**
13
+ * 注册扩展采集器(per-instance 隔离)
14
+ */
15
+ useCollectors(...collectors: ICollector[]): void;
16
+ /**
17
+ * 返回当前实例装载的全部采集器
18
+ */
19
+ getCollectors(): ICollector[];
11
20
  /**
12
21
  * 初始化
13
22
  */