@arms/rum-core 0.0.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.
- package/README.md +3 -0
- package/lib/index.d.ts +12 -0
- package/lib/index.js +71 -0
- package/lib/model/client.d.ts +20 -0
- package/lib/model/client.js +73 -0
- package/lib/model/context.d.ts +17 -0
- package/lib/model/context.js +37 -0
- package/lib/model/reporter.d.ts +28 -0
- package/lib/model/reporter.js +118 -0
- package/lib/style.js +1 -0
- package/lib/types/client.d.ts +99 -0
- package/lib/types/client.js +8 -0
- package/lib/types/collector.d.ts +7 -0
- package/lib/types/collector.js +3 -0
- package/lib/types/processor.d.ts +7 -0
- package/lib/types/processor.js +3 -0
- package/lib/types/reporter.d.ts +8 -0
- package/lib/types/reporter.js +3 -0
- package/lib/types/rum-event.d.ts +120 -0
- package/lib/types/rum-event.js +18 -0
- package/lib/types/shell.d.ts +28 -0
- package/lib/types/shell.js +3 -0
- package/lib/utils/base.d.ts +15 -0
- package/lib/utils/base.js +54 -0
- package/lib/utils/exception.d.ts +7 -0
- package/lib/utils/exception.js +14 -0
- package/lib/utils/is.d.ts +2 -0
- package/lib/utils/is.js +10 -0
- package/package.json +30 -0
package/README.md
ADDED
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import Client from './model/client';
|
|
2
|
+
import Context from './model/context';
|
|
3
|
+
import Reporter from './model/reporter';
|
|
4
|
+
export * from './types/client';
|
|
5
|
+
export * from './types/collector';
|
|
6
|
+
export * from './types/processor';
|
|
7
|
+
export * from './types/reporter';
|
|
8
|
+
export * from './types/rum-event';
|
|
9
|
+
export * from './types/shell';
|
|
10
|
+
export * from './utils/base';
|
|
11
|
+
export * from './utils/is';
|
|
12
|
+
export { Client, Context, Reporter };
|
package/lib/index.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
exports.__esModule = true;
|
|
5
|
+
var _exportNames = {
|
|
6
|
+
Client: true,
|
|
7
|
+
Context: true,
|
|
8
|
+
Reporter: true
|
|
9
|
+
};
|
|
10
|
+
var _client = _interopRequireDefault(require("./model/client"));
|
|
11
|
+
exports.Client = _client["default"];
|
|
12
|
+
var _context = _interopRequireDefault(require("./model/context"));
|
|
13
|
+
exports.Context = _context["default"];
|
|
14
|
+
var _reporter = _interopRequireDefault(require("./model/reporter"));
|
|
15
|
+
exports.Reporter = _reporter["default"];
|
|
16
|
+
var _client2 = require("./types/client");
|
|
17
|
+
Object.keys(_client2).forEach(function (key) {
|
|
18
|
+
if (key === "default" || key === "__esModule") return;
|
|
19
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
20
|
+
if (key in exports && exports[key] === _client2[key]) return;
|
|
21
|
+
exports[key] = _client2[key];
|
|
22
|
+
});
|
|
23
|
+
var _collector = require("./types/collector");
|
|
24
|
+
Object.keys(_collector).forEach(function (key) {
|
|
25
|
+
if (key === "default" || key === "__esModule") return;
|
|
26
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
27
|
+
if (key in exports && exports[key] === _collector[key]) return;
|
|
28
|
+
exports[key] = _collector[key];
|
|
29
|
+
});
|
|
30
|
+
var _processor = require("./types/processor");
|
|
31
|
+
Object.keys(_processor).forEach(function (key) {
|
|
32
|
+
if (key === "default" || key === "__esModule") return;
|
|
33
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
34
|
+
if (key in exports && exports[key] === _processor[key]) return;
|
|
35
|
+
exports[key] = _processor[key];
|
|
36
|
+
});
|
|
37
|
+
var _reporter2 = require("./types/reporter");
|
|
38
|
+
Object.keys(_reporter2).forEach(function (key) {
|
|
39
|
+
if (key === "default" || key === "__esModule") return;
|
|
40
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
41
|
+
if (key in exports && exports[key] === _reporter2[key]) return;
|
|
42
|
+
exports[key] = _reporter2[key];
|
|
43
|
+
});
|
|
44
|
+
var _rumEvent = require("./types/rum-event");
|
|
45
|
+
Object.keys(_rumEvent).forEach(function (key) {
|
|
46
|
+
if (key === "default" || key === "__esModule") return;
|
|
47
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
48
|
+
if (key in exports && exports[key] === _rumEvent[key]) return;
|
|
49
|
+
exports[key] = _rumEvent[key];
|
|
50
|
+
});
|
|
51
|
+
var _shell = require("./types/shell");
|
|
52
|
+
Object.keys(_shell).forEach(function (key) {
|
|
53
|
+
if (key === "default" || key === "__esModule") return;
|
|
54
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
55
|
+
if (key in exports && exports[key] === _shell[key]) return;
|
|
56
|
+
exports[key] = _shell[key];
|
|
57
|
+
});
|
|
58
|
+
var _base = require("./utils/base");
|
|
59
|
+
Object.keys(_base).forEach(function (key) {
|
|
60
|
+
if (key === "default" || key === "__esModule") return;
|
|
61
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
62
|
+
if (key in exports && exports[key] === _base[key]) return;
|
|
63
|
+
exports[key] = _base[key];
|
|
64
|
+
});
|
|
65
|
+
var _is = require("./utils/is");
|
|
66
|
+
Object.keys(_is).forEach(function (key) {
|
|
67
|
+
if (key === "default" || key === "__esModule") return;
|
|
68
|
+
if (Object.prototype.hasOwnProperty.call(_exportNames, key)) return;
|
|
69
|
+
if (key in exports && exports[key] === _is[key]) return;
|
|
70
|
+
exports[key] = _is[key];
|
|
71
|
+
});
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IClient, IConfiguration, IContext } from '../types/client';
|
|
2
|
+
import { RumEvent } from '../types/rum-event';
|
|
3
|
+
import { IProcessor } from '../types/processor';
|
|
4
|
+
import { ICollector } from '../types/collector';
|
|
5
|
+
import { IReporter } from '../types/reporter';
|
|
6
|
+
declare class Client implements IClient {
|
|
7
|
+
private emitter;
|
|
8
|
+
private collectors;
|
|
9
|
+
private processors;
|
|
10
|
+
private reporter;
|
|
11
|
+
private ctx;
|
|
12
|
+
init(config: IConfiguration): void;
|
|
13
|
+
sendEvent: (payload: RumEvent) => void;
|
|
14
|
+
setContext(ctx: IContext): void;
|
|
15
|
+
getContext(): IContext;
|
|
16
|
+
useCollectors(collectors: ICollector[]): void;
|
|
17
|
+
useProcessors(processors: IProcessor[]): void;
|
|
18
|
+
useReporter(reporter: IReporter): void;
|
|
19
|
+
}
|
|
20
|
+
export default Client;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
exports.__esModule = true;
|
|
5
|
+
exports["default"] = void 0;
|
|
6
|
+
var _client = require("../types/client");
|
|
7
|
+
var _events = require("events");
|
|
8
|
+
var _context = _interopRequireDefault(require("./context"));
|
|
9
|
+
function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
|
|
10
|
+
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
|
|
11
|
+
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
|
|
12
|
+
var Client = /*#__PURE__*/function () {
|
|
13
|
+
function Client() {
|
|
14
|
+
var _this = this;
|
|
15
|
+
this.emitter = new _events.EventEmitter();
|
|
16
|
+
this.collectors = void 0;
|
|
17
|
+
this.processors = void 0;
|
|
18
|
+
this.reporter = void 0;
|
|
19
|
+
this.ctx = void 0;
|
|
20
|
+
this.sendEvent = function (payload) {
|
|
21
|
+
_this.emitter.emit(_client.EventType.collect, payload);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
var _proto = Client.prototype;
|
|
25
|
+
_proto.init = function init(config) {
|
|
26
|
+
var _this2 = this;
|
|
27
|
+
this.ctx = new _context["default"](config);
|
|
28
|
+
var ctx = this.ctx,
|
|
29
|
+
collectors = this.collectors,
|
|
30
|
+
processors = this.processors,
|
|
31
|
+
reporter = this.reporter;
|
|
32
|
+
|
|
33
|
+
// collector 收集数据统一 push 到各匹配 processor
|
|
34
|
+
this.emitter.on(_client.EventType.collect, function (payload) {
|
|
35
|
+
ctx.setRumEvent(payload);
|
|
36
|
+
for (var _iterator = _createForOfIteratorHelperLoose(processors), _step; !(_step = _iterator()).done;) {
|
|
37
|
+
var processor = _step.value;
|
|
38
|
+
// default match return true
|
|
39
|
+
if (!processor.match) {
|
|
40
|
+
processor.match = function () {
|
|
41
|
+
return true;
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
;
|
|
45
|
+
if (processor.match(ctx)) {
|
|
46
|
+
var res = processor.process(ctx);
|
|
47
|
+
ctx.setRumEvent(res);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
reporter.report(ctx);
|
|
51
|
+
});
|
|
52
|
+
collectors.forEach(function (collector) {
|
|
53
|
+
collector.setup(ctx, _this2.sendEvent);
|
|
54
|
+
});
|
|
55
|
+
};
|
|
56
|
+
_proto.setContext = function setContext(ctx) {
|
|
57
|
+
this.ctx = ctx;
|
|
58
|
+
};
|
|
59
|
+
_proto.getContext = function getContext() {
|
|
60
|
+
return this.ctx;
|
|
61
|
+
};
|
|
62
|
+
_proto.useCollectors = function useCollectors(collectors) {
|
|
63
|
+
this.collectors = collectors;
|
|
64
|
+
};
|
|
65
|
+
_proto.useProcessors = function useProcessors(processors) {
|
|
66
|
+
this.processors = processors;
|
|
67
|
+
};
|
|
68
|
+
_proto.useReporter = function useReporter(reporter) {
|
|
69
|
+
this.reporter = reporter;
|
|
70
|
+
};
|
|
71
|
+
return Client;
|
|
72
|
+
}();
|
|
73
|
+
var _default = exports["default"] = Client;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { IConfiguration, IContext, IViewData } from "../types/client";
|
|
2
|
+
import { RumEvent } from "../types/rum-event";
|
|
3
|
+
declare class Context implements IContext {
|
|
4
|
+
private config;
|
|
5
|
+
private rumEvent;
|
|
6
|
+
private views;
|
|
7
|
+
constructor(config: IConfiguration);
|
|
8
|
+
getConfig(): IConfiguration;
|
|
9
|
+
setConfig(config: IConfiguration): void;
|
|
10
|
+
getViews(): IViewData[];
|
|
11
|
+
addView(view: IViewData): void;
|
|
12
|
+
removeView(viewId: string): void;
|
|
13
|
+
getRumEvent(): RumEvent;
|
|
14
|
+
setRumEvent(rumEvent: RumEvent): void;
|
|
15
|
+
[key: string]: any;
|
|
16
|
+
}
|
|
17
|
+
export default Context;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports["default"] = void 0;
|
|
5
|
+
var Context = /*#__PURE__*/function () {
|
|
6
|
+
function Context(config) {
|
|
7
|
+
this.config = config;
|
|
8
|
+
this.rumEvent = void 0;
|
|
9
|
+
this.views = [];
|
|
10
|
+
}
|
|
11
|
+
var _proto = Context.prototype;
|
|
12
|
+
_proto.getConfig = function getConfig() {
|
|
13
|
+
return this.config;
|
|
14
|
+
};
|
|
15
|
+
_proto.setConfig = function setConfig(config) {
|
|
16
|
+
this.config = config;
|
|
17
|
+
};
|
|
18
|
+
_proto.getViews = function getViews() {
|
|
19
|
+
return this.views;
|
|
20
|
+
};
|
|
21
|
+
_proto.addView = function addView(view) {
|
|
22
|
+
this.views.push(view);
|
|
23
|
+
};
|
|
24
|
+
_proto.removeView = function removeView(viewId) {
|
|
25
|
+
this.views = this.views.filter(function (view) {
|
|
26
|
+
return view.id !== viewId;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
29
|
+
_proto.getRumEvent = function getRumEvent() {
|
|
30
|
+
return this.rumEvent;
|
|
31
|
+
};
|
|
32
|
+
_proto.setRumEvent = function setRumEvent(rumEvent) {
|
|
33
|
+
this.rumEvent = rumEvent;
|
|
34
|
+
};
|
|
35
|
+
return Context;
|
|
36
|
+
}();
|
|
37
|
+
var _default = exports["default"] = Context;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IContext, IViewData } from '../types/client';
|
|
2
|
+
import { RumEvent } from '../types/rum-event';
|
|
3
|
+
export default abstract class Reporter {
|
|
4
|
+
name: string;
|
|
5
|
+
/**
|
|
6
|
+
* 新上报事件优先检测队列是否超过 50 条,如果超过立即 report。
|
|
7
|
+
* 如果没超过则检测 FlushTime 内有无新上报事件,如果有新事件,重置 timer,无则 report
|
|
8
|
+
*/
|
|
9
|
+
protected eventQueue: RumEvent[];
|
|
10
|
+
protected ctx: IContext;
|
|
11
|
+
private timer;
|
|
12
|
+
private FLUSH_TIME;
|
|
13
|
+
private MAX_EVENT_COUNT;
|
|
14
|
+
report(ctx: IContext): void;
|
|
15
|
+
private pushToQueue;
|
|
16
|
+
/**
|
|
17
|
+
* eventQueue 提取最新 View 作为公共 View,event 中不同 View Event 保留 View id
|
|
18
|
+
*/
|
|
19
|
+
protected flushEventQueue(): void;
|
|
20
|
+
/**
|
|
21
|
+
* 接口请求由各平台 sdk reporter 实现
|
|
22
|
+
*/
|
|
23
|
+
abstract request(ctx: IContext, events: RumEvent[], view: IViewData): void;
|
|
24
|
+
/**
|
|
25
|
+
* 初始化时
|
|
26
|
+
*/
|
|
27
|
+
protected init(ctx: IContext): void;
|
|
28
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports["default"] = void 0;
|
|
5
|
+
var _rumEvent = require("../types/rum-event");
|
|
6
|
+
var _exception = require("../utils/exception");
|
|
7
|
+
var Reporter = exports["default"] = /*#__PURE__*/function () {
|
|
8
|
+
function Reporter() {
|
|
9
|
+
this.name = 'reporter';
|
|
10
|
+
/**
|
|
11
|
+
* 新上报事件优先检测队列是否超过 50 条,如果超过立即 report。
|
|
12
|
+
* 如果没超过则检测 FlushTime 内有无新上报事件,如果有新事件,重置 timer,无则 report
|
|
13
|
+
*/
|
|
14
|
+
this.eventQueue = [];
|
|
15
|
+
this.ctx = void 0;
|
|
16
|
+
this.timer = void 0;
|
|
17
|
+
this.FLUSH_TIME = 3000;
|
|
18
|
+
this.MAX_EVENT_COUNT = 50;
|
|
19
|
+
}
|
|
20
|
+
var _proto = Reporter.prototype;
|
|
21
|
+
_proto.report = function report(ctx) {
|
|
22
|
+
var _this = this;
|
|
23
|
+
this.ctx = ctx;
|
|
24
|
+
this.init(ctx);
|
|
25
|
+
clearTimeout(this.timer);
|
|
26
|
+
this.pushToQueue();
|
|
27
|
+
|
|
28
|
+
// 超过 MaxCount 直接 flush,否则延迟发送
|
|
29
|
+
if (this.eventQueue.length >= this.MAX_EVENT_COUNT) {
|
|
30
|
+
this.flushEventQueue();
|
|
31
|
+
} else {
|
|
32
|
+
this.timer = setTimeout(function () {
|
|
33
|
+
_this.flushEventQueue();
|
|
34
|
+
}, this.FLUSH_TIME);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
_proto.pushToQueue = function pushToQueue() {
|
|
38
|
+
var ctx = this.ctx,
|
|
39
|
+
eventQueue = this.eventQueue;
|
|
40
|
+
var event = ctx.getRumEvent();
|
|
41
|
+
|
|
42
|
+
// 针对相同 event,做 times 合并
|
|
43
|
+
// todo,支持其他类型 event 合并
|
|
44
|
+
if (event.event_type === _rumEvent.RumEventType.EXCEPTION) {
|
|
45
|
+
var _ref = event,
|
|
46
|
+
message = _ref.message,
|
|
47
|
+
stack = _ref.stack;
|
|
48
|
+
var curErrorId = (0, _exception.getErrorID)({
|
|
49
|
+
message: message,
|
|
50
|
+
stack: stack
|
|
51
|
+
});
|
|
52
|
+
var targetEvent = this.eventQueue.find(function (cacheEvent) {
|
|
53
|
+
if (cacheEvent.event_type === _rumEvent.RumEventType.EXCEPTION) {
|
|
54
|
+
var _ref2 = cacheEvent,
|
|
55
|
+
_message = _ref2.message,
|
|
56
|
+
_stack = _ref2.stack;
|
|
57
|
+
return (0, _exception.getErrorID)({
|
|
58
|
+
message: _message,
|
|
59
|
+
stack: _stack
|
|
60
|
+
}) === curErrorId;
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
if (targetEvent) {
|
|
64
|
+
targetEvent.times++;
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (event.event_type === _rumEvent.RumEventType.ACTION) {
|
|
69
|
+
var _ref3 = event,
|
|
70
|
+
target_name = _ref3.target_name;
|
|
71
|
+
var _targetEvent = this.eventQueue.find(function (cacheEvent) {
|
|
72
|
+
if (cacheEvent.event_type === _rumEvent.RumEventType.ACTION) {
|
|
73
|
+
return target_name === cacheEvent.target_name;
|
|
74
|
+
}
|
|
75
|
+
});
|
|
76
|
+
if (_targetEvent) {
|
|
77
|
+
_targetEvent.times++;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
eventQueue.push(event);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* eventQueue 提取最新 View 作为公共 View,event 中不同 View Event 保留 View id
|
|
86
|
+
*/;
|
|
87
|
+
_proto.flushEventQueue = function flushEventQueue() {
|
|
88
|
+
var ctx = this.ctx,
|
|
89
|
+
eventQueue = this.eventQueue;
|
|
90
|
+
if (!eventQueue.length) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
var views = ctx.getViews();
|
|
94
|
+
var curView = views[views.length - 1];
|
|
95
|
+
views.forEach(function (view) {
|
|
96
|
+
if (view.id === curView.id) {
|
|
97
|
+
var _events = eventQueue.filter(function (event) {
|
|
98
|
+
var _event$view;
|
|
99
|
+
return ((_event$view = event.view) === null || _event$view === void 0 ? void 0 : _event$view.id) === view.id;
|
|
100
|
+
});
|
|
101
|
+
_events.forEach(function (event) {
|
|
102
|
+
delete event.view;
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
this.request(ctx, eventQueue, curView);
|
|
107
|
+
this.eventQueue = [];
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* 接口请求由各平台 sdk reporter 实现
|
|
112
|
+
*/;
|
|
113
|
+
/**
|
|
114
|
+
* 初始化时
|
|
115
|
+
*/
|
|
116
|
+
_proto.init = function init(ctx) {};
|
|
117
|
+
return Reporter;
|
|
118
|
+
}();
|
package/lib/style.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//empty file
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { ICollector } from './collector';
|
|
2
|
+
import { IProcessor } from './processor';
|
|
3
|
+
import { IReporter } from './reporter';
|
|
4
|
+
import { RumEvent, RumEventBundle } from './rum-event';
|
|
5
|
+
export declare enum EventType {
|
|
6
|
+
/**
|
|
7
|
+
* 收集数据
|
|
8
|
+
*/
|
|
9
|
+
collect = "collect"
|
|
10
|
+
}
|
|
11
|
+
export interface IViewData {
|
|
12
|
+
id: string;
|
|
13
|
+
name: string;
|
|
14
|
+
}
|
|
15
|
+
export interface IContext {
|
|
16
|
+
/**
|
|
17
|
+
* user config
|
|
18
|
+
*/
|
|
19
|
+
getConfig(): IConfiguration;
|
|
20
|
+
setConfig(config: IConfiguration): void;
|
|
21
|
+
/**
|
|
22
|
+
* view
|
|
23
|
+
*/
|
|
24
|
+
getViews(): IViewData[];
|
|
25
|
+
addView(view: IViewData): void;
|
|
26
|
+
removeView(viewId: string): void;
|
|
27
|
+
/**
|
|
28
|
+
* event
|
|
29
|
+
*/
|
|
30
|
+
getRumEvent(): RumEvent;
|
|
31
|
+
setRumEvent(rumEvent: RumEvent): void;
|
|
32
|
+
[key: string]: any;
|
|
33
|
+
}
|
|
34
|
+
export interface IClient {
|
|
35
|
+
/**
|
|
36
|
+
* 初始化
|
|
37
|
+
*/
|
|
38
|
+
init: (configuration: IConfiguration) => void;
|
|
39
|
+
/**
|
|
40
|
+
* 业务自定义上传数据
|
|
41
|
+
*/
|
|
42
|
+
sendEvent(payload: RumEvent): void;
|
|
43
|
+
/**
|
|
44
|
+
* 修改运行时上下文
|
|
45
|
+
*/
|
|
46
|
+
setContext(ctx: IContext): void;
|
|
47
|
+
/**
|
|
48
|
+
* 获取运行时上下文
|
|
49
|
+
*/
|
|
50
|
+
getContext(): IContext;
|
|
51
|
+
/**
|
|
52
|
+
* 装载 client 需要的 Collector
|
|
53
|
+
*/
|
|
54
|
+
useCollectors(collectors: ICollector[]): void;
|
|
55
|
+
/**
|
|
56
|
+
* 装载 client 需要的 processor
|
|
57
|
+
*/
|
|
58
|
+
useProcessors(processors: IProcessor[]): void;
|
|
59
|
+
/**
|
|
60
|
+
* 装载 client 需要的 report
|
|
61
|
+
*/
|
|
62
|
+
useReporter(reporter: IReporter): void;
|
|
63
|
+
}
|
|
64
|
+
export interface IConfiguration {
|
|
65
|
+
/**
|
|
66
|
+
* 项目 id
|
|
67
|
+
*/
|
|
68
|
+
pid: string;
|
|
69
|
+
/**
|
|
70
|
+
* 应用环境
|
|
71
|
+
*/
|
|
72
|
+
env?: 'prod' | 'gray' | 'pre' | 'daily' | 'local';
|
|
73
|
+
/**
|
|
74
|
+
* 应用版本
|
|
75
|
+
*/
|
|
76
|
+
version?: string;
|
|
77
|
+
/**
|
|
78
|
+
* 用户配置
|
|
79
|
+
*/
|
|
80
|
+
user?: {
|
|
81
|
+
id?: string;
|
|
82
|
+
tags?: string;
|
|
83
|
+
name?: string;
|
|
84
|
+
[key: string]: any;
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* 上报地址
|
|
88
|
+
*/
|
|
89
|
+
endpoint: string;
|
|
90
|
+
/**
|
|
91
|
+
* repoter 发送事件之前
|
|
92
|
+
*/
|
|
93
|
+
beforeReport?(bundle: RumEventBundle): any;
|
|
94
|
+
/**
|
|
95
|
+
* 各个 collector config
|
|
96
|
+
*/
|
|
97
|
+
collectors?: any;
|
|
98
|
+
[key: string]: any;
|
|
99
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { IContext, IViewData } from './client';
|
|
2
|
+
import { RumEvent } from './rum-event';
|
|
3
|
+
export interface IReporter {
|
|
4
|
+
name: string;
|
|
5
|
+
init(ctx: IContext): void;
|
|
6
|
+
request(ctx: IContext, events: RumEvent[], view: IViewData): void;
|
|
7
|
+
report(ctx: IContext): void;
|
|
8
|
+
}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
export declare enum RumEventType {
|
|
2
|
+
VIEW = "view",
|
|
3
|
+
RESOURCE = "resource",
|
|
4
|
+
EXCEPTION = "exception",
|
|
5
|
+
LONG_TASK = "longtask",
|
|
6
|
+
ACTION = "action",
|
|
7
|
+
CUSTOM = "custom"
|
|
8
|
+
}
|
|
9
|
+
export type BaseObjectKey = string | number;
|
|
10
|
+
export type BaseObjectPrimitiveValue = string | number | boolean | null | undefined;
|
|
11
|
+
export type BaseObjectValue = BaseObjectPrimitiveValue | BaseObject | BaseObjectPrimitiveValue[];
|
|
12
|
+
export interface BaseObject {
|
|
13
|
+
[key: BaseObjectKey]: BaseObjectValue;
|
|
14
|
+
}
|
|
15
|
+
export interface RumBaseEvent {
|
|
16
|
+
event_type: RumEventType;
|
|
17
|
+
event_id?: string;
|
|
18
|
+
timestamp?: number;
|
|
19
|
+
times?: number;
|
|
20
|
+
view?: {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
24
|
+
[key: `$attr.${string}`]: BaseObjectValue;
|
|
25
|
+
}
|
|
26
|
+
export interface RumViewEvent extends RumBaseEvent {
|
|
27
|
+
loading_type?: 'initial_load' | 'route_change';
|
|
28
|
+
type: 'pv' | 'perf' | 'webvitals';
|
|
29
|
+
largest_contentful_paint?: number;
|
|
30
|
+
first_input_delay?: number;
|
|
31
|
+
cumulative_layout_shift?: number;
|
|
32
|
+
loading_time?: number;
|
|
33
|
+
first_contentful_paint?: number;
|
|
34
|
+
dom_interactive?: number;
|
|
35
|
+
dom_content_loaded?: number;
|
|
36
|
+
dom_complete?: number;
|
|
37
|
+
referrer?: string;
|
|
38
|
+
url?: string;
|
|
39
|
+
timing_data?: string;
|
|
40
|
+
}
|
|
41
|
+
export interface RumResourceEvent extends RumBaseEvent {
|
|
42
|
+
name?: string;
|
|
43
|
+
type: string;
|
|
44
|
+
method?: string;
|
|
45
|
+
status_code?: number;
|
|
46
|
+
message?: string;
|
|
47
|
+
success: 0 | 1;
|
|
48
|
+
provider_type?: string;
|
|
49
|
+
trace_id?: string;
|
|
50
|
+
duration: number;
|
|
51
|
+
size?: number;
|
|
52
|
+
connect_duration?: number;
|
|
53
|
+
ssl_duration?: number;
|
|
54
|
+
dns_duration?: number;
|
|
55
|
+
redirect_duration?: number;
|
|
56
|
+
first_byte_duration?: number;
|
|
57
|
+
download_duration?: number;
|
|
58
|
+
url: string;
|
|
59
|
+
timing_data?: PerformanceResourceTiming;
|
|
60
|
+
}
|
|
61
|
+
export interface RumExceptionEvent extends RumBaseEvent {
|
|
62
|
+
source?: string;
|
|
63
|
+
type?: 'crash' | 'cutsom' | 'error';
|
|
64
|
+
name?: string;
|
|
65
|
+
message?: string;
|
|
66
|
+
file?: string;
|
|
67
|
+
stack?: string;
|
|
68
|
+
line?: number;
|
|
69
|
+
column?: number;
|
|
70
|
+
}
|
|
71
|
+
export interface RumLongTaskEvent extends RumBaseEvent {
|
|
72
|
+
view_name: string;
|
|
73
|
+
source?: string;
|
|
74
|
+
type?: string;
|
|
75
|
+
message?: string;
|
|
76
|
+
count: number;
|
|
77
|
+
stack?: string;
|
|
78
|
+
caused_by?: string;
|
|
79
|
+
}
|
|
80
|
+
export interface RumActionEvent extends RumBaseEvent {
|
|
81
|
+
type?: string;
|
|
82
|
+
name?: string;
|
|
83
|
+
target_name?: string;
|
|
84
|
+
duration?: number;
|
|
85
|
+
snapshots?: string;
|
|
86
|
+
}
|
|
87
|
+
export interface RumCustomEvent extends RumBaseEvent {
|
|
88
|
+
id: string;
|
|
89
|
+
type: string;
|
|
90
|
+
[key: BaseObjectKey]: BaseObjectValue;
|
|
91
|
+
}
|
|
92
|
+
export type RumEvent = RumViewEvent | RumResourceEvent | RumExceptionEvent | RumActionEvent | RumCustomEvent;
|
|
93
|
+
export declare enum AppType {
|
|
94
|
+
broswer = "browser",
|
|
95
|
+
miniapp = "miniapp"
|
|
96
|
+
}
|
|
97
|
+
export interface RumEventBundle {
|
|
98
|
+
app: {
|
|
99
|
+
id: string;
|
|
100
|
+
env?: string;
|
|
101
|
+
version?: string;
|
|
102
|
+
type: AppType;
|
|
103
|
+
};
|
|
104
|
+
user: {
|
|
105
|
+
id: string;
|
|
106
|
+
name?: string;
|
|
107
|
+
tags?: string;
|
|
108
|
+
};
|
|
109
|
+
session: {
|
|
110
|
+
id: string;
|
|
111
|
+
};
|
|
112
|
+
view: {
|
|
113
|
+
id: string;
|
|
114
|
+
name: string;
|
|
115
|
+
};
|
|
116
|
+
net?: {
|
|
117
|
+
model: string;
|
|
118
|
+
};
|
|
119
|
+
events: Array<RumEvent>;
|
|
120
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.RumEventType = exports.AppType = void 0;
|
|
5
|
+
var RumEventType = exports.RumEventType = /*#__PURE__*/function (RumEventType) {
|
|
6
|
+
RumEventType["VIEW"] = "view";
|
|
7
|
+
RumEventType["RESOURCE"] = "resource";
|
|
8
|
+
RumEventType["EXCEPTION"] = "exception";
|
|
9
|
+
RumEventType["LONG_TASK"] = "longtask";
|
|
10
|
+
RumEventType["ACTION"] = "action";
|
|
11
|
+
RumEventType["CUSTOM"] = "custom";
|
|
12
|
+
return RumEventType;
|
|
13
|
+
}({});
|
|
14
|
+
var AppType = exports.AppType = /*#__PURE__*/function (AppType) {
|
|
15
|
+
AppType["broswer"] = "browser";
|
|
16
|
+
AppType["miniapp"] = "miniapp";
|
|
17
|
+
return AppType;
|
|
18
|
+
}({});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IConfiguration } from "./client";
|
|
2
|
+
import { RumEvent } from "./rum-event";
|
|
3
|
+
/**
|
|
4
|
+
* 每个 sdk shell 导出固定需要实现的基础 api
|
|
5
|
+
* 对外导出 shell 层, 所有 shell 层模型的 API 设计约定:
|
|
6
|
+
* 1. API 命名空间按照 variables / functions / events 来组织
|
|
7
|
+
* 2. 事件(events)的命名格式为:on[Will|Did]VerbNoun?,参考 https://code.visualstudio.com/api/references/vscode-api#events
|
|
8
|
+
* 3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
|
|
9
|
+
*/
|
|
10
|
+
export interface IShell {
|
|
11
|
+
/**
|
|
12
|
+
* 初始化
|
|
13
|
+
*/
|
|
14
|
+
init(configuration: IConfiguration): void;
|
|
15
|
+
/**
|
|
16
|
+
* 自定义上传数据
|
|
17
|
+
*/
|
|
18
|
+
sendEvent(payload: RumEvent): void;
|
|
19
|
+
/**
|
|
20
|
+
* get config
|
|
21
|
+
*/
|
|
22
|
+
getConfig(): IConfiguration;
|
|
23
|
+
/**
|
|
24
|
+
* set config
|
|
25
|
+
*/
|
|
26
|
+
setConfig<T extends keyof IConfiguration>(key: T, value: IConfiguration[T]): void;
|
|
27
|
+
setConfig(value: IConfiguration): void;
|
|
28
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 劫持函数
|
|
3
|
+
*/
|
|
4
|
+
export declare function interceptFunction(options: any, name: string, callback: Function): void;
|
|
5
|
+
/**
|
|
6
|
+
* GUID v4
|
|
7
|
+
* from https://gist.github.com/jed/982883
|
|
8
|
+
*/
|
|
9
|
+
export declare function generateGUID(placeholder?: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* 唯一的字符串 universe unique id
|
|
12
|
+
* @param len {String}
|
|
13
|
+
* @return {String}
|
|
14
|
+
*/
|
|
15
|
+
export declare function generateUUID(len?: number): string;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.generateGUID = generateGUID;
|
|
5
|
+
exports.generateUUID = generateUUID;
|
|
6
|
+
exports.interceptFunction = interceptFunction;
|
|
7
|
+
/**
|
|
8
|
+
* 劫持函数
|
|
9
|
+
*/
|
|
10
|
+
function interceptFunction(options, name, callback) {
|
|
11
|
+
var registeredMethod = options[name];
|
|
12
|
+
options[name] = function () {
|
|
13
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
14
|
+
args[_key] = arguments[_key];
|
|
15
|
+
}
|
|
16
|
+
callback.apply(this, args);
|
|
17
|
+
if (registeredMethod) {
|
|
18
|
+
return registeredMethod.apply(this, args);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* GUID v4
|
|
25
|
+
* from https://gist.github.com/jed/982883
|
|
26
|
+
*/
|
|
27
|
+
function generateGUID(placeholder) {
|
|
28
|
+
return placeholder ?
|
|
29
|
+
// eslint-disable-next-line no-bitwise
|
|
30
|
+
(parseInt(placeholder, 10) ^ Math.random() * 16 >> parseInt(placeholder, 10) / 4).toString(16) : (1e7 + "-" + 1e3 + "-" + 4e3 + "-" + 8e3 + "-" + 1e11).replace(/[018]/g, generateGUID);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* 唯一的字符串 universe unique id
|
|
35
|
+
* @param len {String}
|
|
36
|
+
* @return {String}
|
|
37
|
+
*/
|
|
38
|
+
function generateUUID(len) {
|
|
39
|
+
if (len === void 0) {
|
|
40
|
+
len = 8;
|
|
41
|
+
}
|
|
42
|
+
var str = new Array(len);
|
|
43
|
+
var d = Date.now().toString(36).split('');
|
|
44
|
+
var r, c;
|
|
45
|
+
while (len-- > 0) {
|
|
46
|
+
r = Math.random() * 36 | 0;
|
|
47
|
+
c = r.toString(36);
|
|
48
|
+
str[len] = r % 3 ? c : c.toUpperCase();
|
|
49
|
+
}
|
|
50
|
+
for (var i = 0; i < 8; i++) {
|
|
51
|
+
str.splice(i * 3 + 2, 0, d[i]);
|
|
52
|
+
}
|
|
53
|
+
return str.join('');
|
|
54
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.getErrorID = void 0;
|
|
5
|
+
/**
|
|
6
|
+
* 获取错误对象唯一标识
|
|
7
|
+
*/
|
|
8
|
+
var getErrorID = exports.getErrorID = function getErrorID(error) {
|
|
9
|
+
var _error$message = error.message,
|
|
10
|
+
message = _error$message === void 0 ? '' : _error$message,
|
|
11
|
+
_error$stack = error.stack,
|
|
12
|
+
stack = _error$stack === void 0 ? '' : _error$stack;
|
|
13
|
+
return message + stack;
|
|
14
|
+
};
|
package/lib/utils/is.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
exports.__esModule = true;
|
|
4
|
+
exports.isFunction = exports.isArray = void 0;
|
|
5
|
+
var isFunction = exports.isFunction = function isFunction(func) {
|
|
6
|
+
return typeof func === 'function';
|
|
7
|
+
};
|
|
8
|
+
var isArray = exports.isArray = function isArray(arr) {
|
|
9
|
+
return Array.isArray(arr);
|
|
10
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@arms/rum-core",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"description": "arms rum javascript sdk core",
|
|
5
|
+
"author": "guangli.fj <guangli.fj@alibaba-inc.com>",
|
|
6
|
+
"homepage": "https://unpkg.com/@arms/rum-core@0.0.1/build/index.html",
|
|
7
|
+
"license": "ISC",
|
|
8
|
+
"main": "lib/index.js",
|
|
9
|
+
"directories": {
|
|
10
|
+
"lib": "lib",
|
|
11
|
+
"test": "__tests__"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"lib"
|
|
15
|
+
],
|
|
16
|
+
"publishConfig": {
|
|
17
|
+
"access": "public"
|
|
18
|
+
},
|
|
19
|
+
"scripts": {
|
|
20
|
+
"start": "build-scripts build --watch",
|
|
21
|
+
"build": "build-scripts build --skip-demo",
|
|
22
|
+
"test": "node ./__tests__/@arms/core.test.js"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"events": "^3.3.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"typescript": "^4.9.4"
|
|
29
|
+
}
|
|
30
|
+
}
|