@arms/rum-core 0.0.39 → 0.1.1

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.
Files changed (53) hide show
  1. package/es/index.d.ts +3 -0
  2. package/es/index.js +3 -0
  3. package/es/model/client.d.ts +2 -1
  4. package/es/model/client.js +2 -2
  5. package/es/model/configManager.d.ts +58 -0
  6. package/es/model/configManager.js +177 -0
  7. package/es/model/context.d.ts +3 -1
  8. package/es/model/context.js +13 -2
  9. package/es/model/reporter.d.ts +2 -4
  10. package/es/model/reporter.js +53 -11
  11. package/es/model/shell.d.ts +1 -15
  12. package/es/model/shell.js +62 -52
  13. package/es/types/client.d.ts +60 -8
  14. package/es/types/client.js +6 -1
  15. package/es/types/config.d.ts +49 -0
  16. package/es/types/config.js +1 -0
  17. package/es/types/rum-event.d.ts +2 -0
  18. package/es/utils/base.d.ts +4 -4
  19. package/es/utils/base.js +70 -42
  20. package/es/utils/combineConfig.js +89 -101
  21. package/es/utils/match.d.ts +6 -0
  22. package/es/utils/match.js +34 -0
  23. package/es/utils/trace.d.ts +5 -1
  24. package/es/utils/url.d.ts +2 -0
  25. package/es/utils/url.js +61 -0
  26. package/lib/index.d.ts +3 -0
  27. package/lib/index.js +21 -0
  28. package/lib/model/client.d.ts +2 -1
  29. package/lib/model/client.js +2 -2
  30. package/lib/model/configManager.d.ts +58 -0
  31. package/lib/model/configManager.js +182 -0
  32. package/lib/model/context.d.ts +3 -1
  33. package/lib/model/context.js +13 -2
  34. package/lib/model/reporter.d.ts +2 -4
  35. package/lib/model/reporter.js +54 -11
  36. package/lib/model/shell.d.ts +1 -15
  37. package/lib/model/shell.js +61 -53
  38. package/lib/types/client.d.ts +60 -8
  39. package/lib/types/client.js +5 -1
  40. package/lib/types/config.d.ts +49 -0
  41. package/lib/types/config.js +3 -0
  42. package/lib/types/rum-event.d.ts +2 -0
  43. package/lib/utils/base.d.ts +4 -4
  44. package/lib/utils/base.js +71 -43
  45. package/lib/utils/combineConfig.js +90 -107
  46. package/lib/utils/match.d.ts +6 -0
  47. package/lib/utils/match.js +35 -0
  48. package/lib/utils/trace.d.ts +5 -1
  49. package/lib/utils/url.d.ts +2 -0
  50. package/lib/utils/url.js +65 -0
  51. package/package.json +2 -2
  52. package/es/utils/combineConfig.d.ts +0 -15
  53. package/lib/utils/combineConfig.d.ts +0 -15
@@ -7,9 +7,7 @@ var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")
7
7
  var _rumEvent = require("../types/rum-event");
8
8
  var _client = _interopRequireDefault(require("../model/client"));
9
9
  var _is = require("../utils/is");
10
- var _combineConfig = _interopRequireWildcard(require("../utils/combineConfig"));
11
- function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
12
- function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
10
+ // import combineConfig, { isRemoteConfigEnable, getRemoteConfigUrl } from "../utils/combineConfig";
13
11
  var Shell = exports["default"] = /*#__PURE__*/function () {
14
12
  function Shell(config) {
15
13
  this.client = void 0;
@@ -17,60 +15,55 @@ var Shell = exports["default"] = /*#__PURE__*/function () {
17
15
  if (config && this.init) {
18
16
  this.init(config);
19
17
  }
20
- // if (config && this.init) {
21
- // this.init(this.getCombinedConfig(config));
22
-
23
- // // 拉取远程配置进行更新
24
- // this.updateFromRemoteConfig(config);
25
- // }
26
18
  }
27
- var _proto = Shell.prototype;
28
- _proto.getCombinedConfig = function getCombinedConfig(config) {
29
- var combinedConf;
30
- if ((0, _combineConfig.isRemoteConfigEnable)(config) && (0, _is.isFunction)(this.getLocalConfig)) {
31
- var localConfig = this.getLocalConfig(0, config.pid);
32
- combinedConf = (0, _combineConfig["default"])(config, localConfig);
33
- }
34
- return combinedConf || config;
35
- };
36
- _proto.updateFromRemoteConfig = function updateFromRemoteConfig(config, reSetup) {
37
- if (reSetup === void 0) {
38
- reSetup = true;
39
- }
40
- // 请求动态配置
41
- if (config.pid && (0, _combineConfig.isRemoteConfigEnable)(config) && (0, _is.isFunction)(this.getRemoteConfig)) {
42
- var that = this;
43
- var proms = this.getRemoteConfig((0, _combineConfig.getRemoteConfigUrl)(config), config);
44
- proms === null || proms === void 0 ? void 0 : proms.then(function (remoteConfig) {
45
- if (!remoteConfig || remoteConfig.errorStatus !== undefined) return;
46
- var combinedConf = (0, _combineConfig["default"])(config, remoteConfig);
47
-
48
- // 无有效的新配置,无需更新
49
- if (!combinedConf) return;
50
19
 
51
- // 存储到本地
52
- if ((0, _is.isFunction)(that.storeRemoteConfig)) {
53
- that.storeRemoteConfig(remoteConfig, config.pid);
54
- }
55
- if (reSetup === false || config.remoteConfig.reSetup === false) return;
56
- var context = that.client.getContext();
57
- // 更新配置
58
- context.setConfig(combinedConf);
59
- // 逐个更新collector
60
- var collectors = that.client.getCollectors();
61
- collectors.forEach(function (collector) {
62
- if ((0, _is.isFunction)(collector.destroy)) {
63
- collector.destroy();
64
- collector.setup(context, that.client.sendEvent);
65
- }
66
- });
67
- });
68
- }
69
- }
20
+ // getCombinedConfig(config?: IConfiguration) {
21
+ // let combinedConf;
22
+ // if(isRemoteConfigEnable(config) && isFunction(this.getLocalConfig)) {
23
+ // const localConfig = this.getLocalConfig(0, config.pid);
24
+ // combinedConf = combineConfig(config, localConfig);
25
+ // }
26
+ // return combinedConf || config;
27
+ // }
28
+ //
29
+ // updateFromRemoteConfig(config: any, reSetup: boolean = true) {
30
+ // // 请求动态配置
31
+ // if( config.pid && isRemoteConfigEnable(config) && isFunction(this.getRemoteConfig) ){
32
+ // const that = this;
33
+ // const proms = this.getRemoteConfig(getRemoteConfigUrl(config), config);
34
+ // proms?.then(remoteConfig => {
35
+ // if(!remoteConfig || remoteConfig.errorStatus !== undefined) return;
36
+ // const combinedConf = combineConfig(config, remoteConfig);
37
+ //
38
+ // // 无有效的新配置,无需更新
39
+ // if(!combinedConf) return;
40
+ //
41
+ // // 存储到本地
42
+ // if(isFunction(that.storeRemoteConfig)) {
43
+ // that.storeRemoteConfig(remoteConfig, config.pid);
44
+ // }
45
+ //
46
+ // if(reSetup === false || config.remoteConfig.reSetup === false) return;
47
+ //
48
+ // const context = that.client.getContext();
49
+ // // 更新配置
50
+ // context.setConfig(combinedConf);
51
+ // // 逐个更新collector
52
+ // const collectors = that.client.getCollectors();
53
+ // collectors.forEach(collector => {
54
+ // if(isFunction(collector.destroy)) {
55
+ // collector.destroy();
56
+ // collector.setup(context, that.client.sendEvent);
57
+ // }
58
+ // });
59
+ // });
60
+ // }
61
+ // }
70
62
 
71
63
  /**
72
64
  * 初始化
73
- */;
65
+ */
66
+ var _proto = Shell.prototype;
74
67
  _proto.sendEvent = function sendEvent(payload) {
75
68
  if (this.client) {
76
69
  this.client.sendEvent(payload);
@@ -86,8 +79,23 @@ var Shell = exports["default"] = /*#__PURE__*/function () {
86
79
  }
87
80
  }
88
81
 
82
+ // /**
83
+ // * 获取远程配置
84
+ // */
85
+ // abstract getRemoteConfig(url: string, config: any): object;
86
+ //
87
+ // /**
88
+ // * 存储远程配置到本地
89
+ // */
90
+ // abstract storeRemoteConfig(config: any, pid: string): boolean;
91
+ //
92
+ // /**
93
+ // * 提取本地存储的配置
94
+ // */
95
+ // abstract getLocalConfig(duration: number, pid: string): any;
96
+
89
97
  /**
90
- * 获取远程配置
98
+ * set config
91
99
  */;
92
100
  /**
93
101
  * 自定义事件上报
@@ -3,6 +3,7 @@ import { IProcessor } from './processor';
3
3
  import { IReporter } from './reporter';
4
4
  import { RumEvent, RumEventBundle, IViewData } from './rum-event';
5
5
  import { MatchOption } from "../utils/match";
6
+ import { IConfigManager } from "./config";
6
7
  export declare enum EventType {
7
8
  /**
8
9
  * 收集数据
@@ -35,6 +36,12 @@ export interface SessionConfig {
35
36
  overtime?: number;
36
37
  storage?: string;
37
38
  }
39
+ export interface IReportConfig {
40
+ flushTime?: number;
41
+ maxEventCount?: number;
42
+ maxRetryCount?: number;
43
+ retryDelay?: number;
44
+ }
38
45
  export interface IRumSession {
39
46
  init(ctx: IContext): void;
40
47
  sessionConfig: SessionConfig;
@@ -46,11 +53,54 @@ export interface IRumSession {
46
53
  getUserId: () => string;
47
54
  getBaseEvent: () => any;
48
55
  }
56
+ /**
57
+ * 远端监控配置接口
58
+ * @remarks 用于控制RUM数据采集的远程配置策略
59
+ */
60
+ export interface IRemoteConfig {
61
+ /**
62
+ * 是否启用远端配置 (default: false)
63
+ * @example true - 开启云端配置动态管控
64
+ */
65
+ enable?: boolean;
66
+ /**
67
+ * 配置服务器URL (required when enable=true)
68
+ * @format URL
69
+ */
70
+ url?: string;
71
+ /**
72
+ * 配置获取策略模式 (default: 'launch-first')
73
+ * @enum
74
+ * - 'launch-first': 启动优先模式,先使用本地配置快速启动,异步获取最新配置
75
+ * - 'remote-first': 云端优先模式,阻塞等待云端配置,超时后降级到本地
76
+ */
77
+ mode?: 'launch-first' | 'remote-first';
78
+ /**
79
+ * 配置缓存有效期(单位:毫秒,默认:3600000/1小时)
80
+ * @remarks 控制本地配置缓存刷新频率,超时后重新请求云端配置
81
+ * @example 1800000 - 30分钟更新一次配置
82
+ */
83
+ cacheTimeout?: number;
84
+ /**
85
+ * 配置远程配置拉取Region,兼容 0.0.x 版本远端配置
86
+ * @remarks 拉取远端配置地域
87
+ * @example cn-hangzhou 国内主要地区
88
+ */
89
+ region?: string;
90
+ [key: string]: unknown;
91
+ }
92
+ export interface ICollectorConfig {
93
+ name: string;
94
+ enable?: boolean;
95
+ sampling?: number;
96
+ filters?: MatchOption[];
97
+ [key: string]: unknown;
98
+ }
49
99
  export interface IClient {
50
100
  /**
51
101
  * 初始化
52
102
  */
53
- init: (configuration: IConfiguration, rumSession?: IRumSession) => void;
103
+ init: (configuration: IConfiguration, rumSession?: IRumSession, configManager?: IConfigManager) => void;
54
104
  /**
55
105
  * 业务自定义上传数据
56
106
  */
@@ -81,10 +131,15 @@ export interface IClient {
81
131
  useReporter(reporter: IReporter): void;
82
132
  }
83
133
  export interface IConfiguration {
134
+ /**
135
+ * 是否开启SDK
136
+ */
137
+ enable?: boolean;
84
138
  /**
85
139
  * 项目 id
140
+ * v0.0.40开始,不强依赖该参数,通过Endpoint获取 service_id 确定应用
86
141
  */
87
- pid: string;
142
+ pid?: string;
88
143
  /**
89
144
  * 应用环境
90
145
  */
@@ -125,15 +180,12 @@ export interface IConfiguration {
125
180
  /**
126
181
  * reporter 发送节奏配置
127
182
  */
128
- reportConfig?: {
129
- flushTime?: number;
130
- maxEventCount?: number;
131
- };
183
+ reportConfig?: IReportConfig;
132
184
  /**
133
185
  * 配置下发
134
186
  * - 运行时动态配置更新,根据端侧特点来做定制化配置
135
187
  */
136
- remoteConfig?: Boolean;
188
+ remoteConfig?: IRemoteConfig | Boolean;
137
189
  /**
138
190
  * session config
139
191
  */
@@ -142,7 +194,7 @@ export interface IConfiguration {
142
194
  * 各个 collector config
143
195
  */
144
196
  collectors?: {
145
- [key: string]: boolean;
197
+ [key: string]: boolean | ICollectorConfig;
146
198
  };
147
199
  /**
148
200
  * 事件过滤器配置
@@ -8,4 +8,8 @@ var EventType = exports.EventType = /*#__PURE__*/function (EventType) {
8
8
  */
9
9
  EventType["collect"] = "collect";
10
10
  return EventType;
11
- }({});
11
+ }({});
12
+ /**
13
+ * 远端监控配置接口
14
+ * @remarks 用于控制RUM数据采集的远程配置策略
15
+ */
@@ -0,0 +1,49 @@
1
+ import { IConfiguration } from './client';
2
+ export interface ICacheConfiguration {
3
+ /**
4
+ * 时间戳
5
+ */
6
+ timestamp: number;
7
+ /**
8
+ * 内容
9
+ */
10
+ content: any;
11
+ }
12
+ /**
13
+ * 配置管理器接口
14
+ * 统一管理配置的获取、存储、合并等操作
15
+ */
16
+ export interface IConfigManager {
17
+ /**
18
+ * 初始化配置管理器
19
+ * @param config 初始配置
20
+ */
21
+ init(config: IConfiguration): Promise<void> | void;
22
+ /**
23
+ * 获取配置
24
+ * @returns 配置数据
25
+ */
26
+ getConfig(): Promise<IConfiguration> | any;
27
+ /**
28
+ * 更新配置
29
+ * @param config 新配置
30
+ */
31
+ setConfig(config: Partial<IConfiguration>): Promise<void> | void;
32
+ /**
33
+ * 抽象方法:获取远程配置
34
+ * 各平台需要实现此方法来适配不同的网络请求方式
35
+ * @param config 当前配置
36
+ */
37
+ fetchRemoteCfg(config: IConfiguration): Promise<any>;
38
+ /**
39
+ * 合并配置
40
+ * @param baseConfig 基础配置
41
+ * @param remoteConfig 远程配置
42
+ * @returns 合并后的配置
43
+ */
44
+ mergeRemoteCfg(baseConfig: IConfiguration, remoteConfig: any): IConfiguration | null;
45
+ /**
46
+ * 销毁配置管理器
47
+ */
48
+ destroy(): void;
49
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+
3
+ exports.__esModule = true;
@@ -176,4 +176,6 @@ export interface RumEventBundle {
176
176
  events: Array<RumEvent>;
177
177
  properties?: BaseObject;
178
178
  _v?: string;
179
+ _retry?: number;
180
+ [key: string]: unknown;
179
181
  }
@@ -53,8 +53,8 @@ export declare function getType(obj: any): any;
53
53
  */
54
54
  export declare function transStrToReg(str: string): string | RegExp;
55
55
  /**
56
- *
57
- * @param config 配置
58
- * @param keys 需要转换的字段
56
+ * 解析正则表达式字符串,支持 /pattern/flags 格式
57
+ * @param str 正则表达式字符串,如 "/a/ig" 或 "a"
58
+ * @returns RegExp 对象
59
59
  */
60
- export declare function toRegFormat(config: any, keys: any[]): void;
60
+ export declare function parseRegExpString(str: string): RegExp;
package/lib/utils/base.js CHANGED
@@ -9,12 +9,10 @@ exports.generateSpanId = generateSpanId;
9
9
  exports.generateTraceId = generateTraceId;
10
10
  exports.getType = getType;
11
11
  exports.interceptFunction = interceptFunction;
12
+ exports.parseRegExpString = parseRegExpString;
12
13
  exports.restoreFunction = restoreFunction;
13
- exports.toRegFormat = toRegFormat;
14
14
  exports.transStrToReg = transStrToReg;
15
15
  var _is = require("./is");
16
- // 插值前缀
17
- var PRE_SUF_FIX = '__';
18
16
  // 类型匹配正则
19
17
  var TYPE_REG = /^\[object ([a-z]*)\]$/;
20
18
 
@@ -26,8 +24,7 @@ function interceptFunction(target, name, callback, isPrototype) {
26
24
  isPrototype = false;
27
25
  }
28
26
  var registeredMethod = target[name];
29
- target["" + PRE_SUF_FIX + name + PRE_SUF_FIX] = registeredMethod;
30
- target[name] = function () {
27
+ var proxyMethod = function proxyMethod() {
31
28
  var ctx = isPrototype ? this : target;
32
29
  for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
33
30
  args[_key] = arguments[_key];
@@ -37,17 +34,19 @@ function interceptFunction(target, name, callback, isPrototype) {
37
34
  return registeredMethod.apply(ctx, args);
38
35
  }
39
36
  };
37
+ proxyMethod._rum_intercepted = registeredMethod;
38
+ target[name] = proxyMethod;
40
39
  }
41
40
 
42
41
  /**
43
42
  * 还原函数
44
43
  */
45
44
  function restoreFunction(target, name) {
46
- var key = "" + PRE_SUF_FIX + name + PRE_SUF_FIX;
47
- if (typeof target[key] == 'function') {
48
- target[name] = target[key];
49
- delete target[key];
50
- }
45
+ var proxyMethod = target[name];
46
+ if ((0, _is.isFunction)(proxyMethod)) return;
47
+ var originalMethod = proxyMethod._rum_intercepted;
48
+ if ((0, _is.isFunction)(originalMethod)) return;
49
+ target[name] = originalMethod;
51
50
  }
52
51
 
53
52
  /**
@@ -188,42 +187,71 @@ function transStrToReg(str) {
188
187
  return str;
189
188
  }
190
189
 
190
+ // /**
191
+ // *
192
+ // * @param config 配置
193
+ // * @param keys 需要转换的字段
194
+ // */
195
+ // export function toRegFormat(config: any, keys: any[]) {
196
+ // if (getType(keys) === 'string') {
197
+ // keys = [keys];
198
+ // }
199
+ // for (let i = 0, len = keys.length; i < len; i++) {
200
+ // const paths = keys[i].split('.');
201
+ // const lastIndex = paths.length - 1;
202
+ // if (!config) break;
203
+ // let tmp = config;
204
+ // for (let j = 0, jlen = paths.length; j < jlen; j++) {
205
+ // if (paths[j] === '[]') {
206
+ // if (getType(tmp) === 'array') {
207
+ // let lastPath = paths.splice(j + 1);
208
+ // lastPath = lastPath.join('.');
209
+ // for (let x = 0, xlen = tmp.length; x < xlen; x++) {
210
+ // toRegFormat(tmp[x], lastPath);
211
+ // }
212
+ // }
213
+ // break;
214
+ // }
215
+ // // 最后一层了,需要往前一层才能修改对象
216
+ // if (lastIndex === j && getType(tmp[paths[j]]) === 'string') {
217
+ // tmp[paths[j]] = transStrToReg(tmp[paths[j]]);
218
+ // break;
219
+ // }
220
+ // tmp = tmp[paths[j]];
221
+ // if (!tmp) break;
222
+ // }
223
+ // if (!tmp || getType(tmp) !== 'array') continue;
224
+ // for (let j = 0, jlen = tmp.length; j < jlen; j++) {
225
+ // tmp[j] = transStrToReg(tmp[j]);
226
+ // }
227
+ // }
228
+ // }
229
+
191
230
  /**
192
- *
193
- * @param config 配置
194
- * @param keys 需要转换的字段
231
+ * 解析正则表达式字符串,支持 /pattern/flags 格式
232
+ * @param str 正则表达式字符串,如 "/a/ig" 或 "a"
233
+ * @returns RegExp 对象
195
234
  */
196
- function toRegFormat(config, keys) {
197
- if (getType(keys) === 'string') {
198
- keys = [keys];
235
+ function parseRegExpString(str) {
236
+ if (typeof str !== 'string') {
237
+ throw new TypeError('input must be a string');
199
238
  }
200
- for (var i = 0, len = keys.length; i < len; i++) {
201
- var paths = keys[i].split('.');
202
- var lastIndex = paths.length - 1;
203
- if (!config) break;
204
- var tmp = config;
205
- for (var j = 0, jlen = paths.length; j < jlen; j++) {
206
- if (paths[j] === '[]') {
207
- if (getType(tmp) === 'array') {
208
- var lastPath = paths.splice(j + 1);
209
- lastPath = lastPath.join('.');
210
- for (var x = 0, xlen = tmp.length; x < xlen; x++) {
211
- toRegFormat(tmp[x], lastPath);
212
- }
213
- }
214
- break;
215
- }
216
- // 最后一层了,需要往前一层才能修改对象
217
- if (lastIndex === j && getType(tmp[paths[j]]) === 'string') {
218
- tmp[paths[j]] = transStrToReg(tmp[paths[j]]);
219
- break;
220
- }
221
- tmp = tmp[paths[j]];
222
- if (!tmp) break;
223
- }
224
- if (!tmp || getType(tmp) !== 'array') continue;
225
- for (var _j = 0, _jlen = tmp.length; _j < _jlen; _j++) {
226
- tmp[_j] = transStrToReg(tmp[_j]);
239
+
240
+ // 检查是否是 /pattern/flags 格式
241
+ if (str.length > 2 && str[0] === '/') {
242
+ // 从后往前找最后一个 /,作为分隔符
243
+ var lastSlashIndex = str.lastIndexOf('/');
244
+ if (lastSlashIndex > 0) {
245
+ // 提取 pattern(第一个 / 和最后一个 / 之间的内容)
246
+ var pattern = str.substring(1, lastSlashIndex);
247
+ // 提取 flags(最后一个 / 之后的内容)
248
+ var flags = str.substring(lastSlashIndex + 1);
249
+ return new RegExp(pattern, flags);
227
250
  }
251
+ // 如果只有一个 /,当作 /pattern/ 格式处理(无 flags)
252
+ return new RegExp(str.substring(1, str.length - 1));
228
253
  }
254
+
255
+ // 如果不是 /pattern/flags 格式,直接作为 pattern 使用
256
+ return new RegExp(str);
229
257
  }