gio-miniprogram-sdk 4.0.0 → 4.1.0
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/alipay.js +1 -1
- package/dist/baidu.js +1 -1
- package/dist/bytedance.js +1 -1
- package/dist/jingdong.js +1 -1
- package/dist/kuaishou.js +1 -1
- package/dist/plugins/gioABTest.js +1 -1
- package/dist/plugins/gioCompress.js +1 -1
- package/dist/plugins/gioEventAutoTracking.js +1 -1
- package/dist/plugins/gioImpressionTracking.js +1 -1
- package/dist/plugins/gioMultipleInstances.js +1 -0
- package/dist/qq.js +1 -1
- package/dist/quickapp.js +1 -1
- package/dist/taobao.js +1 -1
- package/dist/taro.js +1 -1
- package/dist/uniapp.js +1 -1
- package/dist/wechat.js +1 -1
- package/package.json +39 -42
- package/rollup.config.js +11 -6
- package/rollup.plugins.config.js +13 -10
- package/src/{pluginsOut/frameworks → adapters}/gioTaobaoAdapter.ts +47 -44
- package/src/adapters/gioTaroAdapter.ts +459 -0
- package/src/{pluginsOut/frameworks → adapters}/gioUniAppAdapter.ts +35 -6
- package/src/constants/config.ts +49 -20
- package/src/constants/emitMsg.ts +23 -0
- package/src/constants/regex.ts +14 -0
- package/src/core/dataStore/eventContextBuilder.ts +28 -17
- package/src/core/dataStore/eventHooks/appEffects.ts +50 -31
- package/src/core/dataStore/eventHooks/index.ts +7 -5
- package/src/core/dataStore/eventHooks/minipPage.ts +2 -11
- package/src/core/dataStore/eventHooks/pageEffects.ts +61 -27
- package/src/core/dataStore/index.ts +266 -181
- package/src/core/growingIO.ts +312 -179
- package/src/core/pluginsInstance/base.ts +157 -0
- package/src/core/pluginsInstance/taro.ts +15 -0
- package/src/core/pluginsInstance/tb.ts +15 -0
- package/src/core/pluginsInstance/uniapp.ts +15 -0
- package/src/core/uploader.ts +131 -87
- package/src/core/userStore.ts +160 -121
- package/src/index.ts +37 -28
- package/src/minipInstance/base.ts +2 -1
- package/src/minipInstance/quickapp.ts +5 -19
- package/src/platformConfig/base.ts +0 -4
- package/src/{pluginsOut/ordinary → plugins}/gioABTest.ts +74 -37
- package/src/{pluginsOut/ordinary → plugins}/gioEventAutoTracking.ts +25 -18
- package/src/{pluginsOut/ordinary → plugins}/gioImpressionTracking.ts +109 -41
- package/src/plugins/gioMultipleInstances.ts +176 -0
- package/src/types/base.ts +12 -3
- package/src/types/dataStore.ts +31 -16
- package/src/types/eventHooks.ts +8 -9
- package/src/types/growingIO.ts +30 -14
- package/src/types/platforms.ts +0 -4
- package/src/types/plugins.ts +1 -1
- package/src/types/uploader.ts +16 -12
- package/src/types/userStore.ts +21 -17
- package/src/utils/glodash.ts +10 -3
- package/src/utils/tools.ts +27 -6
- package/src/utils/verifiers.ts +25 -50
- package/typings/global.d.ts +5 -0
- package/.babelrc +0 -4
- package/bin/build/full.sh +0 -32
- package/bin/build/jd.sh +0 -14
- package/bin/build/ks.sh +0 -14
- package/bin/build/my.sh +0 -14
- package/bin/build/plugins.sh +0 -5
- package/bin/build/qq.sh +0 -14
- package/bin/build/quickapp.sh +0 -14
- package/bin/build/swan.sh +0 -14
- package/bin/build/taro.sh +0 -18
- package/bin/build/tb.sh +0 -18
- package/bin/build/tt.sh +0 -14
- package/bin/build/uniapp.sh +0 -18
- package/bin/build/wx.sh +0 -14
- package/src/core/plugins.ts +0 -152
- package/src/pluginsOut/README.md +0 -50
- package/src/pluginsOut/frameworks/gioTaroAdapter.ts +0 -358
- package/src/pluginsOut/ordinary/gioCustomTracking.ts +0 -71
- package/bin/{build/all.sh → build.sh} +3 -3
- /package/src/{pluginsOut/ordinary → plugins}/gioCompress.ts +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// 原生环境下的plugin实例,无任何内置插件
|
|
2
|
+
import { GrowingIOType } from '@@/types/growingIO';
|
|
3
|
+
import { PluginItem, PluginsType } from '@@/types/plugins';
|
|
4
|
+
import {
|
|
5
|
+
find,
|
|
6
|
+
isEmpty,
|
|
7
|
+
isFunction,
|
|
8
|
+
keys,
|
|
9
|
+
lowerFirst,
|
|
10
|
+
unset
|
|
11
|
+
} from '@@/utils/glodash';
|
|
12
|
+
import { consoleText } from '@@/utils/tools';
|
|
13
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
14
|
+
|
|
15
|
+
// 会被强制剔除出内置的插件(即必须通过手动注册的方式加载的内置插件)
|
|
16
|
+
const EXTRA_PLUGINS = ['gioPerformance'];
|
|
17
|
+
// @ts-nocheck
|
|
18
|
+
class BasePlugins implements PluginsType {
|
|
19
|
+
public pluginItems: PluginItem[];
|
|
20
|
+
public pluginsContext: any;
|
|
21
|
+
constructor(public growingIO: GrowingIOType) {
|
|
22
|
+
this.pluginsContext = { plugins: {} };
|
|
23
|
+
this.pluginItems = [];
|
|
24
|
+
this.growingIO.emitter?.on(EMIT_MSG.ON_INSTALL, (args) =>
|
|
25
|
+
this.callLifeCycle('onInstall', args)
|
|
26
|
+
);
|
|
27
|
+
this.growingIO.emitter?.on(EMIT_MSG.ON_ERROR, (args) =>
|
|
28
|
+
this.callLifeCycle('onError', args)
|
|
29
|
+
);
|
|
30
|
+
this.growingIO.emitter?.on(EMIT_MSG.ON_COMPOSE_BEFORE, (args) =>
|
|
31
|
+
this.callLifeCycle('onComposeBefore', args)
|
|
32
|
+
);
|
|
33
|
+
this.growingIO.emitter?.on(EMIT_MSG.ON_COMPOSE_AFTER, (args) =>
|
|
34
|
+
this.callLifeCycle('onComposeAfter', args)
|
|
35
|
+
);
|
|
36
|
+
this.growingIO.emitter?.on(EMIT_MSG.ON_SEND_BEFORE, (args) =>
|
|
37
|
+
this.callLifeCycle('onSendBefore', args)
|
|
38
|
+
);
|
|
39
|
+
this.growingIO.emitter?.on(EMIT_MSG.ON_SEND_AFTER, (args) =>
|
|
40
|
+
this.callLifeCycle('onSendAfter', args)
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// 初始化内置插件,不允许客户自己热插拔的插件,内置打包完成
|
|
45
|
+
innerPluginInit = () => {
|
|
46
|
+
EXTRA_PLUGINS.forEach((o) => unset(this.pluginsContext?.plugins, o));
|
|
47
|
+
keys(this.pluginsContext?.plugins).forEach((key) => {
|
|
48
|
+
const { name, method }: PluginItem =
|
|
49
|
+
this.pluginsContext?.plugins[key] ?? {};
|
|
50
|
+
// 若列表中出现同名插件,以第一个扫描出来的插件为准
|
|
51
|
+
const isExist = find(this.pluginItems, (o) => o.name === name);
|
|
52
|
+
if (!isExist) {
|
|
53
|
+
this.pluginItems.push({
|
|
54
|
+
// 优先使用指定插件名
|
|
55
|
+
name: lowerFirst(name || key),
|
|
56
|
+
method: method ? method : (growingIO) => {} // eslint-disable-line
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
if (!isEmpty(this.pluginItems)) {
|
|
61
|
+
this.installAll();
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
// 挂载插件
|
|
66
|
+
install = (pluginName: string, pluginItem?: any, options?: any) => {
|
|
67
|
+
const { emitter } = this.growingIO;
|
|
68
|
+
const pluginTarget: PluginItem =
|
|
69
|
+
pluginItem ||
|
|
70
|
+
find(this.pluginItems, (o: PluginItem) => o.name === pluginName);
|
|
71
|
+
// 插件已加载或与已加载的插件重名
|
|
72
|
+
if ((this.growingIO?.plugins as any)[pluginName]) {
|
|
73
|
+
consoleText(`重复加载插件 ${pluginName} 或插件重名,已跳过加载!`, 'warn');
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
// 插件列表中不存在要加载的插件
|
|
77
|
+
if (!pluginTarget) {
|
|
78
|
+
consoleText(`插件加载失败!不存在名为 ${pluginName} 的插件!`, 'error');
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
// 将插件实例挂载到growingIO实例上使得其他模块可以调用
|
|
82
|
+
try {
|
|
83
|
+
(this.growingIO?.plugins as any)[pluginName] = new (
|
|
84
|
+
pluginTarget as any
|
|
85
|
+
).method(this.growingIO, options);
|
|
86
|
+
if (pluginItem) {
|
|
87
|
+
emitter.emit(EMIT_MSG.ON_INSTALL, pluginName);
|
|
88
|
+
consoleText(`加载插件 ${pluginName}`, 'info');
|
|
89
|
+
}
|
|
90
|
+
return true;
|
|
91
|
+
} catch (error) {
|
|
92
|
+
this.lifeError(pluginItem, error);
|
|
93
|
+
consoleText(`插件【${pluginName}】加载异常 ${error}`, 'error');
|
|
94
|
+
return false;
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
// 挂载所有插件
|
|
99
|
+
installAll = (plugins?: PluginItem[]) => {
|
|
100
|
+
(plugins || this.pluginItems).forEach((o: PluginItem) => {
|
|
101
|
+
const suc = this.install(
|
|
102
|
+
o.name,
|
|
103
|
+
plugins ? o : undefined,
|
|
104
|
+
plugins ? o?.options : undefined
|
|
105
|
+
);
|
|
106
|
+
if (suc && !find(this.pluginItems, (p) => p.name === o.name)) {
|
|
107
|
+
this.pluginItems.push({
|
|
108
|
+
// 优先使用指定插件名
|
|
109
|
+
name: lowerFirst(o.name),
|
|
110
|
+
// @ts-ignore
|
|
111
|
+
method: o.method ? o.method : () => {}
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// 移除插件
|
|
118
|
+
uninstall = (pluginName: string) => {
|
|
119
|
+
unset(this.pluginItems, pluginName);
|
|
120
|
+
const u = unset(this.growingIO?.plugins, pluginName);
|
|
121
|
+
if (!u) {
|
|
122
|
+
consoleText(`卸载插件 ${pluginName} 失败!`, 'error');
|
|
123
|
+
}
|
|
124
|
+
return u as boolean;
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// 移除所有插件
|
|
128
|
+
uninstallAll = () => {
|
|
129
|
+
this.pluginItems.forEach((o: PluginItem) => this.uninstall(o.name));
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
lifeError = (p: PluginItem, e: any) => {
|
|
133
|
+
this.growingIO.emitter.emit(EMIT_MSG.ON_ERROR, {
|
|
134
|
+
plugin: p,
|
|
135
|
+
error: e
|
|
136
|
+
});
|
|
137
|
+
consoleText(`插件执行错误 ${p.name} ${e}`, 'error');
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
// 触发插件的生命周期事件
|
|
141
|
+
callLifeCycle = (lifetime: string, args: any) => {
|
|
142
|
+
this.pluginItems.forEach((o: PluginItem) => {
|
|
143
|
+
const method = (this.growingIO.plugins as any)[o.name]
|
|
144
|
+
? (this.growingIO.plugins as any)[o.name][lifetime]
|
|
145
|
+
: undefined;
|
|
146
|
+
if (method && isFunction(method)) {
|
|
147
|
+
try {
|
|
148
|
+
method(args);
|
|
149
|
+
} catch (e) {
|
|
150
|
+
this.lifeError(o, e);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export default BasePlugins;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// taro环境下的plugins实例,添加taro适配插件
|
|
2
|
+
import { GrowingIOType } from '@@/types/growingIO';
|
|
3
|
+
import BasePlugins from './base';
|
|
4
|
+
import gioTaroAdapter from '@@/adapters/gioTaroAdapter';
|
|
5
|
+
|
|
6
|
+
class Plugins extends BasePlugins {
|
|
7
|
+
constructor(public growingIO: GrowingIOType) {
|
|
8
|
+
super(growingIO);
|
|
9
|
+
this.pluginsContext = {
|
|
10
|
+
plugins: { gioTaroAdapter }
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default Plugins;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// taobao环境下的plugins实例,添加taobao适配插件
|
|
2
|
+
import { GrowingIOType } from '@@/types/growingIO';
|
|
3
|
+
import BasePlugins from './base';
|
|
4
|
+
import gioTaobaoAdapter from '@@/adapters/gioTaobaoAdapter';
|
|
5
|
+
|
|
6
|
+
class Plugins extends BasePlugins {
|
|
7
|
+
constructor(public growingIO: GrowingIOType) {
|
|
8
|
+
super(growingIO);
|
|
9
|
+
this.pluginsContext = {
|
|
10
|
+
plugins: { gioTaobaoAdapter }
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default Plugins;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// uniapp环境下的plugins实例,添加uniapp适配插件
|
|
2
|
+
import { GrowingIOType } from '@@/types/growingIO';
|
|
3
|
+
import BasePlugins from './base';
|
|
4
|
+
import gioUniAppAdapter from '@@/adapters/gioUniAppAdapter';
|
|
5
|
+
|
|
6
|
+
class Plugins extends BasePlugins {
|
|
7
|
+
constructor(public growingIO: GrowingIOType) {
|
|
8
|
+
super(growingIO);
|
|
9
|
+
this.pluginsContext = {
|
|
10
|
+
plugins: { gioUniAppAdapter }
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export default Plugins;
|
package/src/core/uploader.ts
CHANGED
|
@@ -1,49 +1,62 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
isArray,
|
|
2
|
+
head,
|
|
4
3
|
isEmpty,
|
|
4
|
+
isNil,
|
|
5
5
|
startsWith,
|
|
6
6
|
throttle,
|
|
7
|
-
toString,
|
|
8
7
|
unset
|
|
9
8
|
} from '@@/utils/glodash';
|
|
10
|
-
import {
|
|
9
|
+
import { EVENT, EXTEND_EVENT } from '@@/types/base';
|
|
11
10
|
import { consoleText } from '@@/utils/tools';
|
|
12
11
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
13
12
|
import { UploaderType } from '@@/types/uploader';
|
|
13
|
+
import EMIT_MSG from '@@/constants/emitMsg';
|
|
14
14
|
|
|
15
15
|
class Uploader implements UploaderType {
|
|
16
16
|
// 因forceLogin配置积压的事件请求队列
|
|
17
|
-
public hoardingQueue: any
|
|
17
|
+
public hoardingQueue: any;
|
|
18
18
|
// 请求队列
|
|
19
|
-
public requestQueue: any
|
|
19
|
+
public requestQueue: any;
|
|
20
20
|
// 请求限制最大数
|
|
21
21
|
public requestLimit: number;
|
|
22
|
-
// 请求超时时间(ms)
|
|
23
|
-
public requestTimeout: number;
|
|
24
22
|
// 请求重试限制最大数
|
|
25
23
|
public retryLimit: number;
|
|
26
24
|
// 请求重试的原请求id
|
|
27
25
|
public retryIds: any;
|
|
28
26
|
// 请求中的请求数
|
|
29
27
|
public requestingNum: number;
|
|
30
|
-
// 请求地址
|
|
31
|
-
public requestURL: string;
|
|
32
28
|
|
|
33
29
|
constructor(public growingIO: GrowingIOType) {
|
|
34
|
-
this.hoardingQueue =
|
|
35
|
-
this.requestQueue =
|
|
30
|
+
this.hoardingQueue = {};
|
|
31
|
+
this.requestQueue = {};
|
|
36
32
|
this.requestLimit = 3;
|
|
37
|
-
this.requestTimeout = 5000;
|
|
38
33
|
this.retryLimit = 2;
|
|
39
34
|
this.retryIds = {};
|
|
40
35
|
this.requestingNum = 0;
|
|
41
|
-
|
|
36
|
+
const { emitter, vdsConfig, plugins } = this.growingIO;
|
|
37
|
+
emitter.on(
|
|
38
|
+
EMIT_MSG.ON_SEND_BEFORE,
|
|
39
|
+
({ eventsQueue, requestData, trackingId }) => {
|
|
40
|
+
// 核心逻辑中只发送主实例的事件
|
|
41
|
+
if (trackingId === this.growingIO.trackingId) {
|
|
42
|
+
if (vdsConfig?.tbConfig?.cloudAppId) {
|
|
43
|
+
// 通过淘宝云应用转发
|
|
44
|
+
plugins?.gioTaobaoAdapter?.tbCloudAppInvoke(
|
|
45
|
+
eventsQueue,
|
|
46
|
+
requestData
|
|
47
|
+
);
|
|
48
|
+
} else {
|
|
49
|
+
this.sendEvent(eventsQueue, requestData);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
);
|
|
42
54
|
}
|
|
43
55
|
|
|
44
56
|
// 生成上报地址
|
|
45
|
-
generateURL = () => {
|
|
46
|
-
const { serverUrl, projectId } =
|
|
57
|
+
generateURL = (trackingId: string) => {
|
|
58
|
+
const { serverUrl, projectId } =
|
|
59
|
+
this.growingIO.dataStore.getTrackerVds(trackingId);
|
|
47
60
|
if (!startsWith(serverUrl, 'http')) {
|
|
48
61
|
return `https://${serverUrl}/v3/projects/${projectId}/collect`;
|
|
49
62
|
} else {
|
|
@@ -51,70 +64,114 @@ class Uploader implements UploaderType {
|
|
|
51
64
|
}
|
|
52
65
|
};
|
|
53
66
|
|
|
67
|
+
// 获取积压队列
|
|
68
|
+
getHoardingQueue = (trackingId: string) =>
|
|
69
|
+
this.hoardingQueue[trackingId] ?? [];
|
|
70
|
+
|
|
71
|
+
// 获取请求队列
|
|
72
|
+
getRequestQueue = (trackingId: string) => this.requestQueue[trackingId] ?? [];
|
|
73
|
+
|
|
54
74
|
// 提交请求(将请求按队列进行管理)
|
|
55
|
-
commitRequest = (
|
|
56
|
-
const data:
|
|
57
|
-
const { vdsConfig } = this.growingIO;
|
|
75
|
+
commitRequest = (commitData: EXTEND_EVENT) => {
|
|
76
|
+
const data: EXTEND_EVENT = { ...commitData };
|
|
77
|
+
const { vdsConfig, emitter } = this.growingIO;
|
|
78
|
+
emitter.emit(EMIT_MSG.ON_COMMIT_REQUEST, {
|
|
79
|
+
eventData: commitData,
|
|
80
|
+
trackingId: commitData.trackingId
|
|
81
|
+
});
|
|
58
82
|
// 如果开启forceLogin 则将请求推入积压队列,反之则进入请求队列
|
|
59
83
|
if (vdsConfig.forceLogin) {
|
|
60
|
-
this.hoardingQueue.
|
|
84
|
+
if (isNil(this.hoardingQueue[commitData.trackingId])) {
|
|
85
|
+
this.hoardingQueue[commitData.trackingId] = [];
|
|
86
|
+
}
|
|
87
|
+
this.hoardingQueue[commitData.trackingId]?.push(data);
|
|
61
88
|
} else {
|
|
62
|
-
this.requestQueue.
|
|
63
|
-
|
|
89
|
+
if (isNil(this.requestQueue[commitData.trackingId])) {
|
|
90
|
+
this.requestQueue[commitData.trackingId] = [];
|
|
91
|
+
}
|
|
92
|
+
this.requestQueue[commitData.trackingId]?.push(data);
|
|
93
|
+
this.initiateRequest(commitData.trackingId);
|
|
64
94
|
}
|
|
65
95
|
};
|
|
66
96
|
|
|
67
97
|
// 发起请求
|
|
68
|
-
initiateRequest = (forceSend?: boolean) => {
|
|
69
|
-
const { plugins, vdsConfig } = this.growingIO;
|
|
98
|
+
initiateRequest = (trackingId: string, forceSend?: boolean) => {
|
|
99
|
+
const { plugins, vdsConfig, minipInstance, dataStore } = this.growingIO;
|
|
100
|
+
const hoardingQueue = this.getHoardingQueue(trackingId);
|
|
101
|
+
const requestQueue = this.getRequestQueue(trackingId);
|
|
70
102
|
// 同时请求数的限制,防止挤占小程序本身的业务请求
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
) {
|
|
75
|
-
// 淘宝云函数单发判断
|
|
103
|
+
const queues = [...hoardingQueue, ...requestQueue];
|
|
104
|
+
const requestProcess = (tid: string) => {
|
|
105
|
+
// 淘宝云函数直接发送要单发
|
|
76
106
|
if (vdsConfig?.tbConfig?.cloudFuncSend) {
|
|
77
|
-
plugins?.gioTaobaoAdapter?.singleInvoke();
|
|
107
|
+
plugins?.gioTaobaoAdapter?.singleInvoke(tid);
|
|
78
108
|
} else if (forceSend) {
|
|
79
|
-
|
|
109
|
+
// 强制即时发送
|
|
110
|
+
this.batchInvoke(tid);
|
|
111
|
+
} else {
|
|
112
|
+
// 有节流的批量发送(1秒钟之内产生的请求只会组团发送一次)
|
|
113
|
+
const { uploadInterval } = this.growingIO.dataStore.getTrackerVds(tid);
|
|
114
|
+
throttle(this.batchInvoke, uploadInterval, false, false)(tid);
|
|
115
|
+
}
|
|
116
|
+
// 发起visit请求时把存储里的originalSource删掉
|
|
117
|
+
const hasVisit = queues.some((e) => e.eventType === 'VISIT');
|
|
118
|
+
if (hasVisit) {
|
|
119
|
+
minipInstance.removeStorageSync(
|
|
120
|
+
dataStore.getStorageKey(tid, 'originalSource')
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
if (queues.length > 0) {
|
|
125
|
+
// 同时请求数在3个以下直接发起请求
|
|
126
|
+
if (this.requestingNum < this.requestLimit) {
|
|
127
|
+
requestProcess(trackingId);
|
|
80
128
|
} else {
|
|
81
|
-
|
|
129
|
+
// 同时有3个请求在发送时,设轮询延时直到请求数在3个以下
|
|
130
|
+
let t = setInterval(() => {
|
|
131
|
+
if (this.requestingNum < this.requestLimit) {
|
|
132
|
+
requestProcess(trackingId);
|
|
133
|
+
clearInterval(t);
|
|
134
|
+
t = undefined;
|
|
135
|
+
}
|
|
136
|
+
}, 500);
|
|
82
137
|
}
|
|
83
138
|
}
|
|
84
139
|
};
|
|
85
140
|
|
|
86
141
|
// 批量发送无延时(强制发送)
|
|
87
|
-
batchInvoke = () => {
|
|
88
|
-
const { vdsConfig,
|
|
89
|
-
|
|
142
|
+
batchInvoke = (trackingId: string) => {
|
|
143
|
+
const { vdsConfig, emitter } = this.growingIO;
|
|
144
|
+
const hoardingQueue = this.getHoardingQueue(trackingId);
|
|
145
|
+
const requestQueue = this.getRequestQueue(trackingId);
|
|
146
|
+
let queues = [...hoardingQueue, ...requestQueue];
|
|
90
147
|
// 如果事件数大于50,剩下的切断放到下次请求
|
|
91
148
|
if (queues.length > 50) {
|
|
92
149
|
queues = queues.slice(0, 50);
|
|
93
150
|
// 如果积压队列超过50,只截取积压队列,剩下的下一次发
|
|
94
|
-
if (
|
|
95
|
-
this.hoardingQueue =
|
|
151
|
+
if (hoardingQueue.length > 50) {
|
|
152
|
+
this.hoardingQueue[trackingId] = hoardingQueue.slice(50);
|
|
96
153
|
} else {
|
|
97
154
|
// 如果积压队列小于50,正常的请求队列就只截取补满50后剩下的事件
|
|
98
|
-
this.
|
|
99
|
-
|
|
100
|
-
50 - this.hoardingQueue.length
|
|
155
|
+
this.requestQueue[trackingId] = requestQueue.slice(
|
|
156
|
+
50 - hoardingQueue.length
|
|
101
157
|
);
|
|
158
|
+
this.hoardingQueue[trackingId] = [];
|
|
102
159
|
}
|
|
103
160
|
} else {
|
|
104
|
-
this.hoardingQueue = [];
|
|
105
|
-
this.requestQueue = [];
|
|
161
|
+
this.hoardingQueue[trackingId] = [];
|
|
162
|
+
this.requestQueue[trackingId] = [];
|
|
106
163
|
}
|
|
107
164
|
// 过滤掉重试超过3次的请求(直接丢弃)
|
|
108
|
-
let eventsQueue:
|
|
165
|
+
let eventsQueue: EXTEND_EVENT[] = queues.filter(
|
|
109
166
|
(o) => (this.retryIds[o.requestId] || 0) <= this.retryLimit
|
|
110
167
|
);
|
|
111
168
|
if (isEmpty(eventsQueue)) {
|
|
112
169
|
return;
|
|
113
170
|
}
|
|
114
171
|
// 生成新的请求事件(过滤事件中不能被上报的字段)
|
|
115
|
-
const requestData = eventsQueue.map((eData) => {
|
|
172
|
+
const requestData: EVENT[] = eventsQueue.map((eData) => {
|
|
116
173
|
const rdata = { ...eData };
|
|
117
|
-
unset(rdata, 'requestId');
|
|
174
|
+
unset(rdata, ['requestId', 'trackingId']);
|
|
118
175
|
return rdata;
|
|
119
176
|
});
|
|
120
177
|
// 开启debug模式时,打印事件日志
|
|
@@ -122,25 +179,18 @@ class Uploader implements UploaderType {
|
|
|
122
179
|
console.log('[GrowingIO Debug]:', JSON.stringify(requestData, null, 2));
|
|
123
180
|
}
|
|
124
181
|
// 广播事件
|
|
125
|
-
emitter.emit(
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
}
|
|
182
|
+
emitter.emit(EMIT_MSG.ON_SEND_BEFORE, {
|
|
183
|
+
eventsQueue,
|
|
184
|
+
requestData,
|
|
185
|
+
trackingId
|
|
186
|
+
});
|
|
131
187
|
};
|
|
132
188
|
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
this.growingIO
|
|
137
|
-
|
|
138
|
-
false
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
// 基础请求逻辑
|
|
142
|
-
normalBatchInvoke = (eventsQueue: any, requestData: any) => {
|
|
143
|
-
const { minipInstance, vdsConfig, emitter, plugins } = this.growingIO;
|
|
189
|
+
// 发送事件
|
|
190
|
+
sendEvent = (eventsQueue: EXTEND_EVENT[], requestData: EVENT[]) => {
|
|
191
|
+
const trackingId = head(eventsQueue).trackingId;
|
|
192
|
+
const { minipInstance, dataStore, emitter, plugins } = this.growingIO;
|
|
193
|
+
const { compress, requestTimeout } = dataStore.getTrackerVds(trackingId);
|
|
144
194
|
this.requestingNum += 1;
|
|
145
195
|
// 根据设置拼装最后请求数据
|
|
146
196
|
const header: any = {
|
|
@@ -153,61 +203,55 @@ class Uploader implements UploaderType {
|
|
|
153
203
|
};
|
|
154
204
|
let compressData = [...requestData];
|
|
155
205
|
// 数据加密
|
|
156
|
-
const isCompress =
|
|
157
|
-
vdsConfig.compress && plugins?.gioCompress?.compressToUTF16;
|
|
206
|
+
const isCompress = !!compress && plugins?.gioCompress?.compressToUTF16;
|
|
158
207
|
if (isCompress) {
|
|
159
208
|
compressData = plugins.gioCompress.compressToUTF16(
|
|
160
209
|
JSON.stringify(requestData)
|
|
161
210
|
);
|
|
162
211
|
header['X-Compress-Codec'] = '1';
|
|
163
212
|
}
|
|
213
|
+
const sendURL = this.generateURL(trackingId);
|
|
164
214
|
minipInstance.request({
|
|
165
|
-
url: `${
|
|
166
|
-
isCompress ? '1' : '0'
|
|
167
|
-
}`,
|
|
215
|
+
url: `${sendURL}?stm=${Date.now()}&compress=${isCompress ? '1' : '0'}`,
|
|
168
216
|
header,
|
|
169
217
|
method: 'POST',
|
|
170
218
|
data: compressData,
|
|
171
|
-
timeout:
|
|
219
|
+
timeout: requestTimeout,
|
|
172
220
|
fail: (result: any) => {
|
|
173
221
|
if (![200, 204].includes(result.code)) {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
});
|
|
178
|
-
} else {
|
|
179
|
-
this.requestFailFn(eventsQueue);
|
|
180
|
-
}
|
|
222
|
+
eventsQueue.forEach((o: any) => {
|
|
223
|
+
this.requestFailFn(o);
|
|
224
|
+
});
|
|
181
225
|
consoleText(`请求失败!${JSON.stringify(result)}`, 'error');
|
|
182
226
|
}
|
|
183
227
|
},
|
|
184
228
|
complete: (args: any) => {
|
|
185
229
|
this.requestingNum -= 1;
|
|
186
|
-
emitter.emit(
|
|
187
|
-
this.initiateRequest();
|
|
230
|
+
emitter.emit(EMIT_MSG.ON_SEND_AFTER, { result: args, requestData });
|
|
231
|
+
this.initiateRequest(trackingId);
|
|
188
232
|
}
|
|
189
233
|
});
|
|
190
234
|
};
|
|
191
235
|
|
|
192
236
|
// 请求失败的回调
|
|
193
|
-
requestFailFn = (
|
|
237
|
+
requestFailFn = (event: EXTEND_EVENT) => {
|
|
194
238
|
// 把重试的请求进行计数,超过重试上限的会被丢弃
|
|
195
|
-
if (!this.retryIds[
|
|
196
|
-
this.retryIds[
|
|
239
|
+
if (!this.retryIds[event.requestId]) {
|
|
240
|
+
this.retryIds[event.requestId] = 0;
|
|
197
241
|
}
|
|
198
|
-
this.retryIds[
|
|
242
|
+
this.retryIds[event.requestId] += 1;
|
|
199
243
|
// 发送失败的事件会重新推入请求队列
|
|
200
|
-
const eventExist = this.requestQueue.some(
|
|
201
|
-
(o) => o.requestId ===
|
|
244
|
+
const eventExist = this.requestQueue[event.trackingId].some(
|
|
245
|
+
(o) => o.requestId === event.requestId
|
|
202
246
|
);
|
|
203
247
|
if (!eventExist) {
|
|
204
248
|
// 延迟半秒后再推入请求队列,给网络一点恢复时间
|
|
205
249
|
let t = setTimeout(() => {
|
|
206
|
-
if (!isEmpty(this.requestQueue)) {
|
|
207
|
-
this.requestQueue.push(
|
|
250
|
+
if (!isEmpty(this.requestQueue[event.trackingId])) {
|
|
251
|
+
this.requestQueue[event.trackingId].push(event);
|
|
208
252
|
} else {
|
|
209
|
-
this.requestQueue.push(
|
|
210
|
-
this.initiateRequest();
|
|
253
|
+
this.requestQueue[event.trackingId].push(event);
|
|
254
|
+
this.initiateRequest(event.trackingId);
|
|
211
255
|
}
|
|
212
256
|
clearTimeout(t);
|
|
213
257
|
t = null;
|