gio-miniprogram-sdk 4.0.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.
Files changed (103) hide show
  1. package/.babelrc +4 -0
  2. package/.eslintignore +11 -0
  3. package/.eslintrc.js +120 -0
  4. package/.github/workflows/greetings.yml +13 -0
  5. package/.github/workflows/publish.yml +43 -0
  6. package/.prettierignore +19 -0
  7. package/.prettierrc.js +9 -0
  8. package/LICENSE +674 -0
  9. package/README.md +103 -0
  10. package/babel.config.js +6 -0
  11. package/bin/build/all.sh +38 -0
  12. package/bin/build/full.sh +32 -0
  13. package/bin/build/jd.sh +14 -0
  14. package/bin/build/ks.sh +14 -0
  15. package/bin/build/my.sh +14 -0
  16. package/bin/build/plugins.sh +5 -0
  17. package/bin/build/qq.sh +14 -0
  18. package/bin/build/quickapp.sh +14 -0
  19. package/bin/build/swan.sh +14 -0
  20. package/bin/build/taro.sh +18 -0
  21. package/bin/build/tb.sh +18 -0
  22. package/bin/build/tt.sh +14 -0
  23. package/bin/build/uniapp.sh +18 -0
  24. package/bin/build/wx.sh +14 -0
  25. package/dist/alipay.js +1 -0
  26. package/dist/baidu.js +1 -0
  27. package/dist/bytedance.js +1 -0
  28. package/dist/jingdong.js +1 -0
  29. package/dist/kuaishou.js +1 -0
  30. package/dist/plugins/gioABTest.js +1 -0
  31. package/dist/plugins/gioCompress.js +1 -0
  32. package/dist/plugins/gioEventAutoTracking.js +1 -0
  33. package/dist/plugins/gioImpressionTracking.js +1 -0
  34. package/dist/qq.js +1 -0
  35. package/dist/quickapp.js +1 -0
  36. package/dist/taobao.js +1 -0
  37. package/dist/taro.js +1 -0
  38. package/dist/uniapp.js +1 -0
  39. package/dist/wechat.js +1 -0
  40. package/package.json +144 -0
  41. package/rollup.config.js +92 -0
  42. package/rollup.plugins.config.js +76 -0
  43. package/src/constants/config.ts +136 -0
  44. package/src/constants/regex.ts +4 -0
  45. package/src/core/dataStore/eventContextBuilder.ts +70 -0
  46. package/src/core/dataStore/eventHooks/appEffects.ts +220 -0
  47. package/src/core/dataStore/eventHooks/index.ts +403 -0
  48. package/src/core/dataStore/eventHooks/minipPage.ts +132 -0
  49. package/src/core/dataStore/eventHooks/pageEffects.ts +168 -0
  50. package/src/core/dataStore/index.ts +543 -0
  51. package/src/core/growingIO.ts +433 -0
  52. package/src/core/plugins.ts +152 -0
  53. package/src/core/uploader.ts +219 -0
  54. package/src/core/userStore.ts +203 -0
  55. package/src/index.ts +68 -0
  56. package/src/minipInstance/base.ts +287 -0
  57. package/src/minipInstance/framework.ts +22 -0
  58. package/src/minipInstance/jd.ts +11 -0
  59. package/src/minipInstance/ks.ts +12 -0
  60. package/src/minipInstance/my.ts +53 -0
  61. package/src/minipInstance/qq.ts +12 -0
  62. package/src/minipInstance/quickapp.ts +230 -0
  63. package/src/minipInstance/swan.ts +20 -0
  64. package/src/minipInstance/tb.ts +53 -0
  65. package/src/minipInstance/tt.ts +12 -0
  66. package/src/minipInstance/wx.ts +12 -0
  67. package/src/platformConfig/base.ts +86 -0
  68. package/src/platformConfig/framework.ts +29 -0
  69. package/src/platformConfig/jd.ts +11 -0
  70. package/src/platformConfig/ks.ts +11 -0
  71. package/src/platformConfig/my.ts +15 -0
  72. package/src/platformConfig/qq.ts +13 -0
  73. package/src/platformConfig/quickapp.ts +48 -0
  74. package/src/platformConfig/swan.ts +11 -0
  75. package/src/platformConfig/tb.ts +29 -0
  76. package/src/platformConfig/tt.ts +11 -0
  77. package/src/platformConfig/wx.ts +20 -0
  78. package/src/pluginsOut/README.md +50 -0
  79. package/src/pluginsOut/frameworks/gioTaobaoAdapter.ts +195 -0
  80. package/src/pluginsOut/frameworks/gioTaroAdapter.ts +358 -0
  81. package/src/pluginsOut/frameworks/gioUniAppAdapter.ts +220 -0
  82. package/src/pluginsOut/ordinary/gioABTest.ts +254 -0
  83. package/src/pluginsOut/ordinary/gioCompress.ts +251 -0
  84. package/src/pluginsOut/ordinary/gioCustomTracking.ts +71 -0
  85. package/src/pluginsOut/ordinary/gioEventAutoTracking.ts +164 -0
  86. package/src/pluginsOut/ordinary/gioImpressionTracking.ts +298 -0
  87. package/src/types/base.ts +150 -0
  88. package/src/types/dataStore.ts +43 -0
  89. package/src/types/eventHooks.ts +141 -0
  90. package/src/types/gioCustomTracking.ts +9 -0
  91. package/src/types/gioEventTracking.ts +10 -0
  92. package/src/types/gioPerformance.ts +8 -0
  93. package/src/types/growingIO.ts +102 -0
  94. package/src/types/minipInstance.ts +126 -0
  95. package/src/types/platforms.ts +65 -0
  96. package/src/types/plugins.ts +24 -0
  97. package/src/types/uploader.ts +26 -0
  98. package/src/types/userStore.ts +22 -0
  99. package/src/utils/glodash.ts +423 -0
  100. package/src/utils/tools.ts +384 -0
  101. package/src/utils/verifiers.ts +76 -0
  102. package/tsconfig.json +32 -0
  103. package/typings/global.d.ts +92 -0
@@ -0,0 +1,254 @@
1
+ /**
2
+ * 名称:ABTest插件
3
+ * 用途:用于提供自动获取AB实验数据和上报实验命中的插件。
4
+ */
5
+ import { GrowingIOType } from '@@/types/growingIO';
6
+ import {
7
+ isEmpty,
8
+ isNaN,
9
+ isNumber,
10
+ startsWith,
11
+ toString
12
+ } from '@@/utils/glodash';
13
+ import { consoleText, hashCode, niceCallback } from '@@/utils/tools';
14
+
15
+ class GioABTest {
16
+ // 请求间隔时长
17
+ public requestInterval: number;
18
+ // 请求超时时长
19
+ public requestTimeout: number;
20
+ // 分流服务请求地址
21
+ public url: string;
22
+ // 接口重试计数
23
+ public retryCount: number;
24
+ constructor(public growingIO: GrowingIOType, options: any) {
25
+ const { abServerUrl, requestInterval, requestTimeout } = options ?? {};
26
+ this.timeoutCheck(requestInterval, requestTimeout);
27
+ const { emitter } = this.growingIO;
28
+ this.growingIO.getABTest = this.getABTest;
29
+ emitter.on('OPTION_INITIALIZED', () => {
30
+ if (abServerUrl) {
31
+ this.abtStorageCheck();
32
+ this.generateUrl(abServerUrl);
33
+ } else {
34
+ consoleText(
35
+ '如果您需要使用ABTest功能,请配置服务地址 abServerUrl!',
36
+ 'warn'
37
+ );
38
+ }
39
+ });
40
+ this.retryCount = 0;
41
+ }
42
+
43
+ // 两个时长的初始化处理
44
+ timeoutCheck = (
45
+ requestInterval: number | string,
46
+ requestTimeout: number | string
47
+ ) => {
48
+ this.requestInterval =
49
+ isNumber(Number(requestInterval)) &&
50
+ !isNaN(Number.parseInt(requestInterval as string, 10))
51
+ ? Number.parseInt(requestInterval as string, 10)
52
+ : 5;
53
+ if (this.requestInterval > 60 * 24 || this.requestInterval < 0) {
54
+ this.requestInterval = 5;
55
+ }
56
+ this.requestTimeout =
57
+ isNumber(Number(requestTimeout)) &&
58
+ !isNaN(Number.parseInt(requestTimeout as string, 10))
59
+ ? Number.parseInt(requestTimeout as string, 10)
60
+ : 1000;
61
+ if (this.requestTimeout > 5000 || this.requestTimeout < 100) {
62
+ this.requestTimeout = 1000;
63
+ }
64
+ };
65
+
66
+ // 检查存储中的实验数据是否已过期
67
+ abtStorageCheck = () => {
68
+ const { minipInstance }: any = this.growingIO;
69
+ const storageKeys = minipInstance.minip?.getStorageInfoSync().keys || [];
70
+ // 请求标记
71
+ const abtsKeys = storageKeys.filter((k) => /^\d+_gdp_abt_sign$/.test(k));
72
+ abtsKeys.forEach((k) => {
73
+ // 移除过期的数据,防止存储超限
74
+ const sign = minipInstance.getStorageSync(k);
75
+ if (!sign || sign < Date.now()) {
76
+ minipInstance.removeStorageSync(k);
77
+ }
78
+ });
79
+ // abtest数据
80
+ const abtdKeys = storageKeys.filter((k) => /^\d+_gdp_abtd$/.test(k));
81
+ abtdKeys.forEach((k) => {
82
+ // 移除过期的数据,防止存储超限
83
+ if (isEmpty(minipInstance.getStorageSync(k))) {
84
+ minipInstance.removeStorageSync(k);
85
+ }
86
+ });
87
+ };
88
+
89
+ // 生成存储的hash key
90
+ getHashKey = (layerId: string | number) => {
91
+ const {
92
+ userStore: { uid },
93
+ vdsConfig: { projectId }
94
+ } = this.growingIO;
95
+ return Math.abs(hashCode(`${projectId}#${uid}#${layerId}`));
96
+ };
97
+
98
+ // 生成数据接口地址
99
+ generateUrl = (abServerUrl: string) => {
100
+ if (!startsWith(abServerUrl, 'http')) {
101
+ this.url = `https://${abServerUrl}/diversion/specified-layer-variables`;
102
+ } else {
103
+ this.url = `${abServerUrl}/diversion/specified-layer-variables`;
104
+ }
105
+ };
106
+
107
+ // 获取实验调用
108
+ getABTest = (layerId: string | number, callback: any) => {
109
+ if (!this.url) {
110
+ niceCallback(callback, {});
111
+ return;
112
+ }
113
+ if (!layerId) {
114
+ consoleText('获取ABTest数据失败! 实验层Id不合法!', 'error');
115
+ niceCallback(callback, {});
116
+ return;
117
+ }
118
+ const { minipInstance } = this.growingIO;
119
+ // 接口调用的超时时间
120
+ const abtSign =
121
+ minipInstance.getStorageSync(
122
+ `${this.getHashKey(layerId)}_gdp_abt_sign`
123
+ ) || 0;
124
+ // 没有超时尝试取数据
125
+ const abtData =
126
+ minipInstance.getStorageSync(`${this.getHashKey(layerId)}_gdp_abtd`) ||
127
+ {};
128
+ // 没有有效数据或者接口请求标记超时则从调用分流服务获取数据
129
+ if (!abtSign || abtSign < Date.now()) {
130
+ this.initiateRequest(layerId, abtData, callback);
131
+ } else {
132
+ niceCallback(callback, abtData);
133
+ }
134
+ };
135
+
136
+ // 发起请求
137
+ initiateRequest = (
138
+ layerId: string | number,
139
+ originData: any,
140
+ callback: any
141
+ ) => {
142
+ const {
143
+ userStore: { uid },
144
+ vdsConfig: { projectId, dataSourceId },
145
+ minipInstance
146
+ } = this.growingIO;
147
+
148
+ minipInstance.request({
149
+ url: this.url,
150
+ header: { 'Content-Type': 'application/x-www-form-urlencoded' },
151
+ method: 'POST',
152
+ data: {
153
+ accountId: projectId,
154
+ datasourceId: dataSourceId,
155
+ distinctId: uid,
156
+ layerId
157
+ },
158
+ timeout: this.requestTimeout,
159
+ success: ({ data }: any) => {
160
+ if (data.code === 0) {
161
+ this.experimentVerify({ ...data, layerId }, originData, callback);
162
+ } else {
163
+ consoleText(`获取ABTest数据失败! ${data.errorMsg}!`, 'error');
164
+ // 接口业务失败返回false信息
165
+ niceCallback(callback, {});
166
+ }
167
+ // 接口调用返回后刷新接口调用标记
168
+ minipInstance.setStorageSync(
169
+ `${this.getHashKey(layerId)}_gdp_abt_sign`,
170
+ Date.now() + 1000 * 60 * this.requestInterval
171
+ );
172
+ },
173
+ fail: ({ errMsg }: any) => {
174
+ // 请求超时(这里没用微信提供的errno,因为它没有值,其他小程序也不一定能兼容)
175
+ if (errMsg.indexOf('timeout') > -1) {
176
+ consoleText('获取ABTest数据失败! 请求超时!', 'error');
177
+ // 接口超时返回false信息
178
+ niceCallback(callback, {});
179
+ } else {
180
+ // 其他失败情况重试
181
+ if (this.retryCount < 2) {
182
+ this.initiateRequest(layerId, originData, callback);
183
+ this.retryCount += 1;
184
+ } else {
185
+ consoleText(
186
+ `获取ABTest数据失败! ${JSON.stringify(errMsg).slice(0, 30)}!`,
187
+ 'error'
188
+ );
189
+ // 重试结束后返回false信息
190
+ niceCallback(callback, {});
191
+ }
192
+ }
193
+ }
194
+ });
195
+ };
196
+
197
+ // 实验校验(决定是否上报命中事件)
198
+ experimentVerify = (responseData: any, originData: any, callback: any) => {
199
+ const { layerId, strategyId, experimentId, variables } = responseData;
200
+ const abtDataKey = `${this.getHashKey(layerId)}_gdp_abtd`;
201
+ const abtData = {
202
+ layerId: toString(layerId),
203
+ strategyId: toString(strategyId),
204
+ experimentId: toString(experimentId),
205
+ variables
206
+ };
207
+ const comparisonValue = hashCode(JSON.stringify(abtData));
208
+ const controlValue = hashCode(JSON.stringify(originData));
209
+ // 本地实验和请求回来的实验直接做整体hash数据对比
210
+ if (comparisonValue !== controlValue) {
211
+ // 存储实验数据
212
+ this.growingIO.minipInstance.setStorageSync(
213
+ abtDataKey,
214
+ abtData,
215
+ new Date(
216
+ new Date().getFullYear(),
217
+ new Date().getMonth(),
218
+ new Date().getDate() + 1
219
+ ).getTime()
220
+ );
221
+ // 数据不一致重新发命中埋点
222
+ if (strategyId && experimentId) {
223
+ this.buildExperimentHitEvent(
224
+ toString(layerId),
225
+ toString(experimentId),
226
+ toString(strategyId)
227
+ );
228
+ }
229
+ }
230
+ // 回调调用
231
+ niceCallback(callback, abtData);
232
+ };
233
+
234
+ // 构建实验命中事件
235
+ buildExperimentHitEvent = (layerId, experimentId, strategyId) => {
236
+ const {
237
+ dataStore: { eventContextBuilder, eventConverter }
238
+ } = this.growingIO;
239
+ let event = {
240
+ eventType: 'CUSTOM',
241
+ eventName: '$exp_hit',
242
+ attributes: {
243
+ $exp_layer_id: layerId,
244
+ $exp_id: experimentId,
245
+ $exp_strategy_id: strategyId
246
+ },
247
+ ...eventContextBuilder(),
248
+ customEventType: 0
249
+ };
250
+ eventConverter(event);
251
+ };
252
+ }
253
+
254
+ export default { name: 'gioABTest', method: GioABTest };
@@ -0,0 +1,251 @@
1
+ /**
2
+ * 名称:数据加密插件
3
+ * 用途:用于提供上报数据加密。
4
+ */
5
+ import { GrowingIOType } from '@@/types/growingIO';
6
+
7
+ class GioCompress {
8
+ private f;
9
+ private _compress;
10
+ constructor(public growingIO: GrowingIOType) {
11
+ this.f = String.fromCharCode;
12
+ this._compress = function (uncompressed, bitsPerChar, getCharFromInt) {
13
+ if (uncompressed === null) return '';
14
+ let i,
15
+ value,
16
+ context_dictionary = {},
17
+ context_dictionaryToCreate = {},
18
+ context_c = '',
19
+ context_wc = '',
20
+ context_w = '',
21
+ context_enlargeIn = 2, // Compensate for the first entry which should not count
22
+ context_dictSize = 3,
23
+ context_numBits = 2,
24
+ context_data = [],
25
+ context_data_val = 0,
26
+ context_data_position = 0,
27
+ ii;
28
+
29
+ for (ii = 0; ii < uncompressed.length; ii += 1) {
30
+ context_c = uncompressed.charAt(ii);
31
+ if (
32
+ !Object.prototype.hasOwnProperty.call(context_dictionary, context_c)
33
+ ) {
34
+ context_dictionary[context_c] = context_dictSize++;
35
+ context_dictionaryToCreate[context_c] = true;
36
+ }
37
+
38
+ context_wc = context_w + context_c;
39
+ if (
40
+ Object.prototype.hasOwnProperty.call(context_dictionary, context_wc)
41
+ ) {
42
+ context_w = context_wc;
43
+ } else {
44
+ if (
45
+ Object.prototype.hasOwnProperty.call(
46
+ context_dictionaryToCreate,
47
+ context_w
48
+ )
49
+ ) {
50
+ if (context_w.charCodeAt(0) < 256) {
51
+ for (i = 0; i < context_numBits; i++) {
52
+ context_data_val = context_data_val << 1;
53
+ if (context_data_position === bitsPerChar - 1) {
54
+ context_data_position = 0;
55
+ context_data.push(getCharFromInt(context_data_val));
56
+ context_data_val = 0;
57
+ } else {
58
+ context_data_position++;
59
+ }
60
+ }
61
+ value = context_w.charCodeAt(0);
62
+ for (i = 0; i < 8; i++) {
63
+ context_data_val = (context_data_val << 1) | (value & 1);
64
+ if (context_data_position === bitsPerChar - 1) {
65
+ context_data_position = 0;
66
+ context_data.push(getCharFromInt(context_data_val));
67
+ context_data_val = 0;
68
+ } else {
69
+ context_data_position++;
70
+ }
71
+ value = value >> 1;
72
+ }
73
+ } else {
74
+ value = 1;
75
+ for (i = 0; i < context_numBits; i++) {
76
+ context_data_val = (context_data_val << 1) | value;
77
+ if (context_data_position === bitsPerChar - 1) {
78
+ context_data_position = 0;
79
+ context_data.push(getCharFromInt(context_data_val));
80
+ context_data_val = 0;
81
+ } else {
82
+ context_data_position++;
83
+ }
84
+ value = 0;
85
+ }
86
+ value = context_w.charCodeAt(0);
87
+ for (i = 0; i < 16; i++) {
88
+ context_data_val = (context_data_val << 1) | (value & 1);
89
+ if (context_data_position === bitsPerChar - 1) {
90
+ context_data_position = 0;
91
+ context_data.push(getCharFromInt(context_data_val));
92
+ context_data_val = 0;
93
+ } else {
94
+ context_data_position++;
95
+ }
96
+ value = value >> 1;
97
+ }
98
+ }
99
+ context_enlargeIn--;
100
+ if (context_enlargeIn === 0) {
101
+ context_enlargeIn = Math.pow(2, context_numBits);
102
+ context_numBits++;
103
+ }
104
+ delete context_dictionaryToCreate[context_w];
105
+ } else {
106
+ value = context_dictionary[context_w];
107
+ for (i = 0; i < context_numBits; i++) {
108
+ context_data_val = (context_data_val << 1) | (value & 1);
109
+ if (context_data_position === bitsPerChar - 1) {
110
+ context_data_position = 0;
111
+ context_data.push(getCharFromInt(context_data_val));
112
+ context_data_val = 0;
113
+ } else {
114
+ context_data_position++;
115
+ }
116
+ value = value >> 1;
117
+ }
118
+ }
119
+ context_enlargeIn--;
120
+ if (context_enlargeIn === 0) {
121
+ context_enlargeIn = Math.pow(2, context_numBits);
122
+ context_numBits++;
123
+ }
124
+ // Add wc to the dictionary.
125
+ context_dictionary[context_wc] = context_dictSize++;
126
+ context_w = String(context_c);
127
+ }
128
+ }
129
+
130
+ // Output the code for w.
131
+ if (context_w !== '') {
132
+ if (
133
+ Object.prototype.hasOwnProperty.call(
134
+ context_dictionaryToCreate,
135
+ context_w
136
+ )
137
+ ) {
138
+ if (context_w.charCodeAt(0) < 256) {
139
+ for (i = 0; i < context_numBits; i++) {
140
+ context_data_val = context_data_val << 1;
141
+ if (context_data_position === bitsPerChar - 1) {
142
+ context_data_position = 0;
143
+ context_data.push(getCharFromInt(context_data_val));
144
+ context_data_val = 0;
145
+ } else {
146
+ context_data_position++;
147
+ }
148
+ }
149
+ value = context_w.charCodeAt(0);
150
+ for (i = 0; i < 8; i++) {
151
+ context_data_val = (context_data_val << 1) | (value & 1);
152
+ if (context_data_position === bitsPerChar - 1) {
153
+ context_data_position = 0;
154
+ context_data.push(getCharFromInt(context_data_val));
155
+ context_data_val = 0;
156
+ } else {
157
+ context_data_position++;
158
+ }
159
+ value = value >> 1;
160
+ }
161
+ } else {
162
+ value = 1;
163
+ for (i = 0; i < context_numBits; i++) {
164
+ context_data_val = (context_data_val << 1) | value;
165
+ if (context_data_position === bitsPerChar - 1) {
166
+ context_data_position = 0;
167
+ context_data.push(getCharFromInt(context_data_val));
168
+ context_data_val = 0;
169
+ } else {
170
+ context_data_position++;
171
+ }
172
+ value = 0;
173
+ }
174
+ value = context_w.charCodeAt(0);
175
+ for (i = 0; i < 16; i++) {
176
+ context_data_val = (context_data_val << 1) | (value & 1);
177
+ if (context_data_position === bitsPerChar - 1) {
178
+ context_data_position = 0;
179
+ context_data.push(getCharFromInt(context_data_val));
180
+ context_data_val = 0;
181
+ } else {
182
+ context_data_position++;
183
+ }
184
+ value = value >> 1;
185
+ }
186
+ }
187
+ context_enlargeIn--;
188
+ if (context_enlargeIn === 0) {
189
+ context_enlargeIn = Math.pow(2, context_numBits);
190
+ context_numBits++;
191
+ }
192
+ delete context_dictionaryToCreate[context_w];
193
+ } else {
194
+ value = context_dictionary[context_w];
195
+ for (i = 0; i < context_numBits; i++) {
196
+ context_data_val = (context_data_val << 1) | (value & 1);
197
+ if (context_data_position === bitsPerChar - 1) {
198
+ context_data_position = 0;
199
+ context_data.push(getCharFromInt(context_data_val));
200
+ context_data_val = 0;
201
+ } else {
202
+ context_data_position++;
203
+ }
204
+ value = value >> 1;
205
+ }
206
+ }
207
+ context_enlargeIn--;
208
+ if (context_enlargeIn === 0) {
209
+ context_enlargeIn = Math.pow(2, context_numBits);
210
+ context_numBits++;
211
+ }
212
+ }
213
+
214
+ // Mark the end of the stream
215
+ value = 2;
216
+ for (i = 0; i < context_numBits; i++) {
217
+ context_data_val = (context_data_val << 1) | (value & 1);
218
+ if (context_data_position === bitsPerChar - 1) {
219
+ context_data_position = 0;
220
+ context_data.push(getCharFromInt(context_data_val));
221
+ context_data_val = 0;
222
+ } else {
223
+ context_data_position++;
224
+ }
225
+ value = value >> 1;
226
+ }
227
+
228
+ // Flush the last char
229
+ while (true) {
230
+ context_data_val = context_data_val << 1;
231
+ if (context_data_position === bitsPerChar - 1) {
232
+ context_data.push(getCharFromInt(context_data_val));
233
+ break;
234
+ } else context_data_position++;
235
+ }
236
+ return context_data.join('');
237
+ };
238
+ }
239
+
240
+ compressToUTF16 = (input) => {
241
+ const self = this;
242
+ if (input === null) return '';
243
+ return (
244
+ this._compress(input, 15, function (a) {
245
+ return self.f(a + 32);
246
+ }) + ' '
247
+ );
248
+ };
249
+ }
250
+
251
+ export default { name: 'gioCompress', method: GioCompress };
@@ -0,0 +1,71 @@
1
+ /**
2
+ * 名称:自定义埋点插件
3
+ * 用途:用于提供自定义埋点的事件构建方法。
4
+ */
5
+ import { GioCustomTrackingType } from '@@/types/gioCustomTracking';
6
+ import { GrowingIOType } from '@@/types/growingIO';
7
+
8
+ let ut;
9
+ class GioCustomTracking implements GioCustomTrackingType {
10
+ constructor(public growingIO: GrowingIOType) {
11
+ ut = this.growingIO.utils;
12
+ }
13
+
14
+ // 获取动态属性的值
15
+ getDynamicAttributes = (properties: any) => {
16
+ if (!ut.isNil(properties)) {
17
+ ut.keys(properties).forEach((k: string) => {
18
+ if (ut.isFunction(properties[k])) {
19
+ properties[k] = properties[k]();
20
+ } else if (!ut.isArray(properties[k])) {
21
+ properties[k] = ut.toString(properties[k]);
22
+ }
23
+ });
24
+ }
25
+ return properties;
26
+ };
27
+
28
+ // 构建自定义埋点事件
29
+ buildCustomEvent = (name: string, properties: { [key: string]: string }) => {
30
+ ut.eventNameValidate(name, () => {
31
+ const {
32
+ dataStore: { eventContextBuilder, eventInterceptor }
33
+ } = this.growingIO;
34
+ const event = {
35
+ eventType: 'CUSTOM',
36
+ eventName: name,
37
+ attributes: ut.limitObject(
38
+ this.getDynamicAttributes(
39
+ ut.isObject(properties) && !ut.isEmpty(properties)
40
+ ? properties
41
+ : undefined
42
+ )
43
+ ),
44
+ ...eventContextBuilder()
45
+ };
46
+ eventInterceptor(event);
47
+ });
48
+ };
49
+
50
+ // 构建用户变量事件
51
+ buildUserAttributesEvent = (attributes: { [key: string]: string }) => {
52
+ const {
53
+ dataStore: { eventContextBuilder, eventInterceptor, lastVisitEvent }
54
+ } = this.growingIO;
55
+ const event = {
56
+ eventType: 'LOGIN_USER_ATTRIBUTES',
57
+ attributes: ut.limitObject(attributes),
58
+ ...eventContextBuilder()
59
+ };
60
+ // 该方法很可能被放在在app的onShow中的wx.login异步回调中,
61
+ // 此时页面的path和query可能还没取到,就拿visit事件的path和query补上
62
+ if (!event.path) {
63
+ event.path = lastVisitEvent.path;
64
+ event.query = lastVisitEvent.query;
65
+ event.title = lastVisitEvent.title;
66
+ }
67
+ eventInterceptor(event);
68
+ };
69
+ }
70
+
71
+ export default { name: 'gioCustomTracking', method: GioCustomTracking };