@omega-tracker/omg-abstract-strategy-plugin 0.0.1-security → 0.736.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of @omega-tracker/omg-abstract-strategy-plugin might be problematic. Click here for more details.

@@ -0,0 +1,261 @@
1
+ /**
2
+ * Copyright (c) 2018-present, Didi, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * @author Cory(kuanghongrui@didichuxing.com)
6
+ *
7
+ * @file The class of AEvent
8
+ */
9
+
10
+ import { IPlanObject } from 'com/didichuxing/IPlanObject';
11
+ import { IObjectMap } from 'com/didichuxing/IObjectMap';
12
+ import { IContext } from 'com/didichuxing/context/IContext';
13
+ import { ITrackerContext } from 'com/didichuxing/tracker/context/ITrackerContext';
14
+ import { IContextContainer } from 'com/didichuxing/context/IContextContainer';
15
+ import { ITrackedEvent } from 'com/didichuxing/tracker/event/ITrackedEvent';
16
+ import { ITrackedEventData } from 'com/didichuxing/tracker/event/ITrackedEventData';
17
+ import { IAttrs } from 'com/didichuxing/tracker/IAttrs';
18
+ import { EventStatus } from 'com/didichuxing/tracker/plugin/events/EventStatus';
19
+ import GlobalUtil from 'com/didichuxing/tracker/plugin/utils/GlobalUtil';
20
+
21
+ export default abstract class AEvent implements ITrackedEvent, IContextContainer {
22
+
23
+ /**
24
+ * 上报的上下文环境
25
+ */
26
+ private readonly context: IContext;
27
+
28
+ /**
29
+ * 事件的额外参数。
30
+ */
31
+ private readonly attrs: IAttrs;
32
+
33
+ /**
34
+ * @constructor
35
+ * @param {IAttrs} attrs
36
+ * @param {IContext} context
37
+ */
38
+ constructor(attrs: IAttrs, context: IContext) {
39
+ this.attrs = attrs;
40
+ this.context = context;
41
+ }
42
+
43
+ /**
44
+ * 获取版本号
45
+ */
46
+ private getVersion() {
47
+ return {
48
+ trackerVersion: this.getContext().version
49
+ };
50
+ }
51
+
52
+ /**
53
+ * @abstract
54
+ * @returns {string}
55
+ */
56
+ public abstract getType(): string;
57
+
58
+ /**
59
+ * @override
60
+ * @inheritDoc
61
+ * @returns {ITrackedEventData}
62
+ */
63
+ public getData(): ITrackedEventData {
64
+ const context: ITrackerContext = this.getContext() as ITrackerContext;
65
+ return {
66
+ eventId: this.getType(),
67
+ timestamp: new Date().getTime(),
68
+ viewportId: context.viewportId,
69
+ appName: context.appName,
70
+ appVersion: context.appVersion,
71
+ omgId: context.omgId,
72
+ url: context.url || location.href,
73
+ latitude: context.latitude,
74
+ longitude: context.longitude,
75
+ userAgent: context.userAgent,
76
+ osType: context.osType,
77
+ osVersion: context.osVersion,
78
+ appKey: context.appKey || context.productName,
79
+ userName: context.userName,
80
+ userId: context.userId,
81
+ cityId: context.cityId,
82
+ telephone: context.telephone,
83
+ bizId: context.bizId,
84
+ locale: context.locale,
85
+ countyId: context.countyId,
86
+ countryCallingCode: context.countryCallingCode,
87
+ utcOffset: context.utcOffset,
88
+ attrs: this.getAttrs(),
89
+ from: this.getFrom()
90
+ };
91
+ }
92
+
93
+ /**
94
+ * 将事件数据属性映射成上报的字段。
95
+ * @returns {IObjectMap<string>}
96
+ */
97
+ protected getDataKeyMap(): IObjectMap<string> {
98
+ return {
99
+ eventId: 'e',
100
+ timestamp: 'ts',
101
+ viewportId: 'uwid',
102
+ version: 'jv',
103
+ appName: 'an',
104
+ appVersion: 'av',
105
+ omgId: 'oid',
106
+ url: 'v',
107
+ latitude: 'lat',
108
+ longitude: 'lng',
109
+ userAgent: 'ua',
110
+ osType: 'ot',
111
+ osVersion: 'ov',
112
+ appKey: 'ak',
113
+ userName: 'un',
114
+ userId: 'uid',
115
+ cityId: 'cityid',
116
+ telephone: 'tel',
117
+ bizId: 'bizId',
118
+ locale: 'le',
119
+ countyId: 'coi',
120
+ countryCallingCode: 'dcc',
121
+ utcOffset: 'uo',
122
+ from: 'fr'
123
+ };
124
+ }
125
+
126
+ /**
127
+ * 将attrs属性映射成上报的字段。
128
+ * @returns {IObjectMap<string>}
129
+ */
130
+ protected getAttrsKeyMap(): IObjectMap<string> {
131
+ return {
132
+ _label: 'l',
133
+ trackerVersion: 'jv'
134
+ };
135
+ }
136
+
137
+ /**
138
+ * 把event data(去除attrs)序列化成json字符串。
139
+ * @returns {string}
140
+ */
141
+ public serialize2JsonStrWithoutAttrs(): string {
142
+ try {
143
+ const eventData: ITrackedEventData = this.getData();
144
+ const obj: IPlanObject = {};
145
+ const dataKeyMap: IObjectMap<string> = this.getDataKeyMap();
146
+ for (const prop in eventData) {
147
+ if (prop !== 'attrs' && !/Null|Undefined/.test(Object.prototype.toString.call(eventData[prop]))) {
148
+ obj[dataKeyMap[prop] || prop] = eventData[prop];
149
+ }
150
+ }
151
+ return JSON.stringify(obj);
152
+ } catch (e) {
153
+ GlobalUtil.dispatchOmgLog('serialize2JsonStrWithoutAttrs Error');
154
+ return '';
155
+ }
156
+ }
157
+
158
+ /**
159
+ * @override
160
+ * @inheritDoc
161
+ * @returns {string}
162
+ */
163
+ public serialize(): string {
164
+ try {
165
+ const eventData: ITrackedEventData = this.getData();
166
+ // 先用Object内置类的keys方法获取要排序对象的属性名,再利用Array原型上的sort方法对获取的属性名进行排序,newkey是一个数组
167
+ const newkeys = Object.keys(eventData).sort();
168
+ const kvs: string[] = [];
169
+ const dataKeyMap: IObjectMap<string> = this.getDataKeyMap();
170
+ // 要保证顺序 所以attrs也放进了循环
171
+ newkeys.forEach((prop) => {
172
+ if (prop !== 'attrs' && !/Null|Undefined/.test(Object.prototype.toString.call(eventData[prop]))) {
173
+ kvs.push(`${ dataKeyMap[prop] || prop }=${ encodeURIComponent(eventData[prop]) }`);
174
+ } else if (prop === 'attrs') {
175
+ const attrsJsonStr: string = this.serializeAttrs2JsonStr(eventData.attrs || {});
176
+ if (attrsJsonStr !== '{}') {
177
+ kvs.push(`attrs=${ encodeURIComponent(attrsJsonStr) }`);
178
+ }
179
+ }
180
+ });
181
+ return kvs.join('&');
182
+ } catch (e) {
183
+ GlobalUtil.dispatchOmgLog('serialize Error');
184
+ return '';
185
+ }
186
+ }
187
+
188
+ /**
189
+ * 格式化attrs
190
+ * @param {IAttrs} attrs
191
+ * @returns {string}
192
+ */
193
+ public serializeAttrs2JsonStr(attrs: IAttrs): string {
194
+ try {
195
+ const serializedAttrs: IPlanObject = {};
196
+ const attrsKeyMap: IObjectMap<string> = this.getAttrsKeyMap();
197
+ for (const prop in attrs) {
198
+ if (attrs.hasOwnProperty(prop)) {
199
+ const key: string = attrsKeyMap[prop] || prop;
200
+ if (/Object|Array/.test(Object.prototype.toString.call(attrs[prop]))) {
201
+ serializedAttrs[key] = JSON.stringify(attrs[prop]);
202
+ } else if (/String/.test(Object.prototype.toString.call(attrs[prop])) && attrs[prop]) {
203
+ serializedAttrs[key] = attrs[prop];
204
+ } else if (/Number/.test(Object.prototype.toString.call(attrs[prop]))) {
205
+ serializedAttrs[key] = attrs[prop];
206
+ } else if (/Boolean/.test(Object.prototype.toString.call(attrs[prop]))) {
207
+ serializedAttrs[key] = attrs[prop] | 0;
208
+ }
209
+ }
210
+ }
211
+ return JSON.stringify(serializedAttrs);
212
+ } catch (e) {
213
+ GlobalUtil.dispatchOmgLog('serializeAttrs2JsonStr Error');
214
+ return '';
215
+ }
216
+
217
+ }
218
+
219
+ /**
220
+ * @override
221
+ * @inheritDoc
222
+ * @returns {IContext}
223
+ */
224
+ public getContext(): IContext {
225
+ return this.context;
226
+ }
227
+
228
+ /**
229
+ * 该事件的额外参数。
230
+ * @returns {IAttrs}
231
+ */
232
+ protected getAttrs(): IAttrs {
233
+ const thisAttrs: any = {};
234
+ const context = this.getContext() as ITrackerContext;
235
+ if (context.openId) {
236
+ thisAttrs['_OMGPUID'] = context.openId;
237
+ }
238
+
239
+ return Object.assign(thisAttrs, context.attrs || {}, this.attrs, this.getVersion());
240
+ }
241
+
242
+ /**
243
+ * 获取框架来源
244
+ * 由业务方指定
245
+ */
246
+ protected getFrom(): string {
247
+ const context: ITrackerContext = this.getContext() as ITrackerContext;
248
+ if (GlobalUtil.isEmptyString(context.from)) {
249
+ return `h5-${ context.from }`;
250
+ } else {
251
+ return 'h5';
252
+ }
253
+ }
254
+
255
+ /**
256
+ * 事件的状态。
257
+ * {@link com/didichuxing/tracker/h5/plugins/events/EventStatus}
258
+ * @returns {EventStatus}
259
+ */
260
+ public abstract get status(): EventStatus;
261
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Copyright (c) 2018-present, Didi, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * @author Cory(kuanghongrui@didichuxing.com)
6
+ *
7
+ * @file The class of BlockedEvent
8
+ */
9
+
10
+ import { IContext } from 'com/didichuxing/context/IContext';
11
+ import { IAttrs } from 'com/didichuxing/tracker/IAttrs';
12
+ import { EventStatus } from 'com/didichuxing/tracker/plugin/events/EventStatus';
13
+ import AEvent from 'com/didichuxing/tracker/plugin/events/AEvent';
14
+
15
+ export default class BlockedEvent extends AEvent {
16
+
17
+ /**
18
+ * custom event id
19
+ */
20
+ private readonly eventId: string;
21
+
22
+ /**
23
+ * @constructor
24
+ * @param {IAttrs} attrs
25
+ * @param {IContext} context
26
+ */
27
+ constructor(eventId: string, attrs: IAttrs, context: IContext) {
28
+ super(attrs, context);
29
+ this.eventId = eventId;
30
+ }
31
+
32
+ /**
33
+ * @override
34
+ * @inheritDoc
35
+ */
36
+ protected initSequence(): void {
37
+ /* stop sequence */
38
+ }
39
+
40
+ /**
41
+ * @override
42
+ * @inheritDoc
43
+ * @returns {string}
44
+ */
45
+ public getType(): string {
46
+ return this.eventId;
47
+ }
48
+
49
+ /**
50
+ * @override
51
+ * @inheritDoc
52
+ * @returns {EventStatus}
53
+ */
54
+ public get status(): EventStatus {
55
+ return EventStatus.BLOCKED;
56
+ }
57
+ }
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Copyright (c) 2018-present, Didi, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * @author Cory(kuanghongrui@didichuxing.com)
6
+ *
7
+ * @file The enum class of EventStatus
8
+ */
9
+
10
+ export enum EventStatus {
11
+
12
+ /**
13
+ * 正常状态的事件。
14
+ */
15
+ NORMAL = 'normal',
16
+
17
+ /**
18
+ * 被阻止上报的事件
19
+ * @type {string}
20
+ */
21
+ BLOCKED = 'blocked',
22
+
23
+ /**
24
+ * 上报失败的事件。
25
+ * @type {string}
26
+ */
27
+ FAILED = 'failed',
28
+
29
+ /**
30
+ * 上报超时的事件。
31
+ * @type {string}
32
+ */
33
+ TIMEOUT = 'timeout'
34
+ }
@@ -0,0 +1,65 @@
1
+ /**
2
+ * Copyright (c) 2018-present, Didi, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * @author Cory(kuanghongrui@didichuxing.com)
6
+ *
7
+ * @file The class of FailedEvent
8
+ */
9
+
10
+ import { IContext } from 'com/didichuxing/context/IContext';
11
+ import { IAttrs } from 'com/didichuxing/tracker/IAttrs';
12
+ import { EventStatus } from 'com/didichuxing/tracker/plugin/events/EventStatus';
13
+ import AEvent from 'com/didichuxing/tracker/plugin/events/AEvent';
14
+
15
+ export default class FailedEvent extends AEvent {
16
+
17
+ /**
18
+ * custom event id
19
+ */
20
+ private readonly eventId: string;
21
+
22
+ /**
23
+ * error event
24
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error}
25
+ */
26
+ private readonly error: Error;
27
+
28
+ /**
29
+ * @constructor
30
+ * @param {IAttrs} attrs
31
+ * @param {IContext} context
32
+ */
33
+ constructor(error: Error, eventId: string, attrs: IAttrs, context: IContext) {
34
+ super(attrs, context);
35
+ this.error = error;
36
+ this.eventId = eventId;
37
+ }
38
+
39
+ /**
40
+ * @override
41
+ * @inheritDoc
42
+ * @returns {string}
43
+ */
44
+ public getType(): string {
45
+ return this.eventId;
46
+ }
47
+
48
+ /**
49
+ * @override
50
+ * @inheritDoc
51
+ * @returns {EventStatus}
52
+ */
53
+ public get status(): EventStatus {
54
+ return EventStatus.FAILED;
55
+ }
56
+
57
+ /**
58
+ * 获取出错信息事件。
59
+ * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error}
60
+ * @returns {ErrorEvent}
61
+ */
62
+ public getError(): Error {
63
+ return this.error;
64
+ }
65
+ }
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Copyright (c) 2018-present, Didi, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * @author Cory(kuanghongrui@didichuxing.com)
6
+ *
7
+ * @file The class of SequencedEvent
8
+ */
9
+
10
+ import { IContext } from 'com/didichuxing/context/IContext';
11
+ import { IObjectMap } from 'com/didichuxing/IObjectMap';
12
+ import { IAttrs } from 'com/didichuxing/tracker/IAttrs';
13
+ import { ITrackerContext } from 'com/didichuxing/tracker/context/ITrackerContext';
14
+ import { ITrackedEventData } from 'com/didichuxing/tracker/event/ITrackedEventData';
15
+ import { EventStatus } from 'com/didichuxing/tracker/plugin/events/EventStatus';
16
+ import AEvent from 'com/didichuxing/tracker/plugin/events/AEvent';
17
+
18
+ export default abstract class SequencedEvent extends AEvent {
19
+
20
+ /**
21
+ * Omega事件全局序列名称前缀。
22
+ * @type {string}
23
+ */
24
+ public static readonly OMG_SEQUENCE_NAME_PREFIX: string = '__OMG_SEQUENCE_';
25
+
26
+ /**
27
+ * Omega事件全局序列名称后缀。
28
+ * @type {string}
29
+ */
30
+ public static readonly OMG_SEQUENCE_NAME_SUFFIX: string = '__';
31
+
32
+ /**
33
+ * 事件的序列号。
34
+ * 默认为-1,表示没有序列号。
35
+ */
36
+ private readonly sequence: number;
37
+
38
+ /**
39
+ * @constructor
40
+ * @param {IAttrs} attrs
41
+ * @param {IContext} context
42
+ */
43
+ constructor(attrs: IAttrs, context: IContext) {
44
+ super(attrs, context);
45
+ const prefix: string = SequencedEvent.OMG_SEQUENCE_NAME_PREFIX;
46
+ const suffix: string = SequencedEvent.OMG_SEQUENCE_NAME_SUFFIX;
47
+ if (!(window as any)[`${ prefix }${ (context as ITrackerContext).viewportId }${ suffix }`]) {
48
+ (window as any)[`${ prefix }${ (context as ITrackerContext).viewportId }${ suffix }`] = 0;
49
+ }
50
+ this.sequence = (window as any)[`${ prefix }${ (context as ITrackerContext).viewportId }${ suffix }`]++;
51
+ }
52
+
53
+ /**
54
+ * @override
55
+ * @inheritDoc
56
+ * @returns {ITrackedEventData}
57
+ */
58
+ public getData(): ITrackedEventData {
59
+ return {
60
+ ...super.getData(),
61
+ sequence: this.sequence
62
+ };
63
+ }
64
+
65
+ /**
66
+ * @override
67
+ * @inheritDoc
68
+ * @returns {IObjectMap<string>}
69
+ */
70
+ protected getDataKeyMap(): IObjectMap<string> {
71
+ return {
72
+ ...super.getDataKeyMap(),
73
+ sequence: 'seq'
74
+ };
75
+ }
76
+
77
+ /**
78
+ * @override
79
+ * @inheritDoc
80
+ * @returns {EventStatus}
81
+ */
82
+ public get status(): EventStatus {
83
+ return EventStatus.NORMAL;
84
+ }
85
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Copyright (c) 2018-present, Didi, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * @author Cory(kuanghongrui@didichuxing.com)
6
+ *
7
+ * @file The class of TimeoutEvent
8
+ */
9
+
10
+ import { IContext } from 'com/didichuxing/context/IContext';
11
+ import { IAttrs } from 'com/didichuxing/tracker/IAttrs';
12
+ import { EventStatus } from 'com/didichuxing/tracker/plugin/events/EventStatus';
13
+ import AEvent from 'com/didichuxing/tracker/plugin/events/AEvent';
14
+
15
+ export default class TimeoutEvent extends AEvent {
16
+
17
+ /**
18
+ * custom event id
19
+ */
20
+ private readonly eventId: string;
21
+
22
+ /**
23
+ * @constructor
24
+ * @param {IAttrs} attrs
25
+ * @param {IContext} context
26
+ */
27
+ constructor(eventId: string, attrs: IAttrs, context: IContext) {
28
+ super(attrs, context);
29
+ this.eventId = eventId;
30
+ }
31
+
32
+ /**
33
+ * @override
34
+ * @inheritDoc
35
+ * @returns {string}
36
+ */
37
+ public getType(): string {
38
+ return this.eventId;
39
+ }
40
+
41
+ /**
42
+ * @override
43
+ * @inheritDoc
44
+ * @returns {EventStatus}
45
+ */
46
+ public get status(): EventStatus {
47
+ return EventStatus.TIMEOUT;
48
+ }
49
+ }
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Copyright (c) 2018-present, Didi, Inc.
3
+ * All rights reserved.
4
+ *
5
+ * @author Cory(kuanghongrui@didichuxing.com)
6
+ *
7
+ * @file The class of AH5EventReportor
8
+ */
9
+
10
+ import { ITrackerContext } from 'com/didichuxing/tracker/context/ITrackerContext';
11
+ import { IEventReportor } from 'com/didichuxing/tracker/plugin/reportor/IEventReportor';
12
+ import { ITrackedEvent } from 'com/didichuxing/tracker/event/ITrackedEvent';
13
+ import PluginUtils from 'com/didichuxing/tracker/plugin/utils/PluginUtils';
14
+ import GlobalUtil from 'com/didichuxing/tracker/plugin/utils/GlobalUtil';
15
+ import DataQueueSet from 'com/didichuxing/tracker/plugin/reportor/DataQueueSet';
16
+
17
+ interface IUnreportedItem {
18
+
19
+ /**
20
+ * 未上报事件
21
+ */
22
+ event: ITrackedEvent;
23
+
24
+ /**
25
+ * 该事件上报成功后执行的方法。
26
+ * @param {ITrackedEvent} evt
27
+ */
28
+ resolve(evt: ITrackedEvent): void;
29
+
30
+ /**
31
+ * 该事件上报失败后执行的方法。
32
+ * @param {ITrackedEvent} evt
33
+ */
34
+ reject(evt: ITrackedEvent): void;
35
+ }
36
+
37
+ export default abstract class AH5EventReportor implements IEventReportor {
38
+
39
+ private context: ITrackerContext;
40
+ private event: ITrackedEvent;
41
+
42
+ /**
43
+ * 待上报事件。
44
+ */
45
+ private unreportedEvents: IUnreportedItem[];
46
+ /**
47
+ * 上报失败事件
48
+ */
49
+ protected readonly errorreportedEvents = DataQueueSet.getInstance();
50
+
51
+ /**
52
+ * @constructor
53
+ * @param {ITrackerContext} context
54
+ * @param {ITrackedEvent} event
55
+ */
56
+ constructor(context: ITrackerContext, event: ITrackedEvent) {
57
+ this.event = event;
58
+ this.context = context;
59
+ this.unreportedEvents = [];
60
+ this.reportEventsAfterLoad = this.reportEventsAfterLoad.bind(this);
61
+ window.addEventListener('load', this.reportEventsAfterLoad);
62
+ }
63
+
64
+ /**
65
+ * load之后,将未上报事件集中依次上报。
66
+ */
67
+ private reportEventsAfterLoad(): void {
68
+ window.removeEventListener('load', this.reportEventsAfterLoad);
69
+ while (this.unreportedEvents.length) {
70
+ const unreportedItem: IUnreportedItem | undefined = this.unreportedEvents.shift();
71
+ if (unreportedItem) {
72
+ this.reportEventImmediately(unreportedItem.event).then(unreportedItem.resolve, unreportedItem.reject);
73
+ }
74
+ }
75
+ }
76
+
77
+ /**
78
+ * 得到context信息
79
+ * @returns {ITrackerContext}
80
+ */
81
+ protected getContext(): ITrackerContext {
82
+ return this.context;
83
+ }
84
+
85
+ /**
86
+ * 上报路径path
87
+ * @returns {string}
88
+ */
89
+ protected get reportPath(): string {
90
+ return '/api/web/stat';
91
+ }
92
+
93
+ /**
94
+ * @override
95
+ * @inheritDoc
96
+ * @returns {Promise<ITrackedEvent>}
97
+ */
98
+ public reportEvent(): Promise<ITrackedEvent> {
99
+ if (!GlobalUtil.isEmptyString(this.event.getData().appKey)) {
100
+ GlobalUtil.dispatchOmgLog('[Omega] H5 appKey 参数 不可为空');
101
+ throw new Error('[Omega] H5 appKey 参数 不可为空');
102
+ return Promise.reject();
103
+ }
104
+
105
+ if (GlobalUtil.isLoaded() || this.event.getType() === PluginUtils.EVENT_ID_PAGE_INIT ||
106
+ this.event.getType() === PluginUtils.EVENT_ID_OMG_LOG) {
107
+ // onload已经执行完或者当前事件为页面初始化事件
108
+ // 如果有上报错误的数据也去上报
109
+ if (!this.errorreportedEvents.empty()) {
110
+ this.errorreportedEvents.getData().forEach((value) => {
111
+ this.reportEventImmediately(value);
112
+ });
113
+ }
114
+ this.errorreportedEvents.removeAll();
115
+ return this.reportEventImmediately(this.event);
116
+ } else {
117
+ // load未完成,将事件聚集,等待集中上报。
118
+ return new Promise<ITrackedEvent>((resolve: (evt: ITrackedEvent) => void,
119
+ reject: (evt: ITrackedEvent) => void): void => {
120
+ this.unreportedEvents.push({
121
+ event: this.event,
122
+ resolve: resolve,
123
+ reject: reject
124
+ });
125
+ });
126
+ }
127
+ }
128
+
129
+ /**
130
+ * 马上直接上报事件。
131
+ * @param {ITrackedEvent} event
132
+ * @returns {Promise<ITrackedEvent>}
133
+ */
134
+ protected abstract reportEventImmediately(event: ITrackedEvent): Promise<ITrackedEvent>;
135
+ }