gio-miniprogram-sdk 4.0.1 → 4.2.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 (76) hide show
  1. package/dist/alipay.js +1 -1
  2. package/dist/baidu.js +1 -1
  3. package/dist/bytedance.js +1 -1
  4. package/dist/jingdong.js +1 -1
  5. package/dist/kuaishou.js +1 -1
  6. package/dist/plugins/gioABTest.js +1 -1
  7. package/dist/plugins/gioCompress.js +1 -1
  8. package/dist/plugins/gioEventAutoTracking.js +1 -1
  9. package/dist/plugins/gioImpressionTracking.js +1 -1
  10. package/dist/plugins/gioMultipleInstances.js +1 -0
  11. package/dist/qq.js +1 -1
  12. package/dist/quickapp.js +1 -1
  13. package/dist/taobao.js +1 -1
  14. package/dist/taro.js +1 -1
  15. package/dist/uniapp.js +1 -1
  16. package/dist/wechat.js +1 -1
  17. package/package.json +39 -42
  18. package/rollup.config.js +11 -6
  19. package/rollup.plugins.config.js +18 -10
  20. package/src/{pluginsOut/frameworks → adapters}/gioTaobaoAdapter.ts +49 -43
  21. package/src/{pluginsOut/frameworks → adapters}/gioTaroAdapter.ts +6 -4
  22. package/src/{pluginsOut/frameworks → adapters}/gioUniAppAdapter.ts +37 -6
  23. package/src/constants/config.ts +48 -18
  24. package/src/constants/emitMsg.ts +23 -0
  25. package/src/constants/regex.ts +0 -1
  26. package/src/core/dataStore/eventContextBuilder.ts +54 -25
  27. package/src/core/dataStore/eventHooks/appEffects.ts +50 -31
  28. package/src/core/dataStore/eventHooks/index.ts +13 -6
  29. package/src/core/dataStore/eventHooks/minipPage.ts +41 -13
  30. package/src/core/dataStore/eventHooks/pageEffects.ts +54 -31
  31. package/src/core/dataStore/index.ts +287 -205
  32. package/src/core/growingIO.ts +370 -180
  33. package/src/core/pluginsInstance/base.ts +157 -0
  34. package/src/core/pluginsInstance/taro.ts +15 -0
  35. package/src/core/pluginsInstance/tb.ts +15 -0
  36. package/src/core/pluginsInstance/uniapp.ts +15 -0
  37. package/src/core/uploader.ts +131 -82
  38. package/src/core/userStore.ts +160 -121
  39. package/src/index.ts +37 -28
  40. package/src/minipInstance/base.ts +2 -1
  41. package/src/minipInstance/quickapp.ts +5 -19
  42. package/src/platformConfig/base.ts +0 -5
  43. package/src/{pluginsOut/ordinary → plugins}/gioABTest.ts +88 -44
  44. package/src/{pluginsOut/ordinary → plugins}/gioCompress.ts +2 -0
  45. package/src/{pluginsOut/ordinary → plugins}/gioEventAutoTracking.ts +45 -21
  46. package/src/{pluginsOut/ordinary → plugins}/gioImpressionTracking.ts +67 -23
  47. package/src/plugins/gioMultipleInstances.ts +187 -0
  48. package/src/types/base.ts +10 -3
  49. package/src/types/dataStore.ts +35 -16
  50. package/src/types/eventHooks.ts +8 -6
  51. package/src/types/growingIO.ts +74 -39
  52. package/src/types/platforms.ts +0 -4
  53. package/src/types/plugins.ts +1 -1
  54. package/src/types/uploader.ts +16 -10
  55. package/src/types/userStore.ts +21 -17
  56. package/src/utils/glodash.ts +10 -3
  57. package/src/utils/tools.ts +31 -6
  58. package/src/utils/verifiers.ts +25 -50
  59. package/typings/global.d.ts +5 -0
  60. package/.babelrc +0 -4
  61. package/bin/build/full.sh +0 -32
  62. package/bin/build/jd.sh +0 -14
  63. package/bin/build/ks.sh +0 -14
  64. package/bin/build/my.sh +0 -14
  65. package/bin/build/plugins.sh +0 -5
  66. package/bin/build/qq.sh +0 -14
  67. package/bin/build/quickapp.sh +0 -14
  68. package/bin/build/swan.sh +0 -14
  69. package/bin/build/taro.sh +0 -18
  70. package/bin/build/tb.sh +0 -18
  71. package/bin/build/tt.sh +0 -14
  72. package/bin/build/uniapp.sh +0 -18
  73. package/bin/build/wx.sh +0 -14
  74. package/src/core/plugins.ts +0 -152
  75. package/src/pluginsOut/ordinary/gioCustomTracking.ts +0 -71
  76. package/bin/{build/all.sh → build.sh} +3 -3
@@ -7,29 +7,52 @@ import {
7
7
  isEmpty,
8
8
  isNaN,
9
9
  isNumber,
10
+ isObject,
11
+ isString,
12
+ keys,
10
13
  startsWith,
11
14
  toString
12
15
  } from '@@/utils/glodash';
13
- import { consoleText, hashCode, niceCallback } from '@@/utils/tools';
16
+ import {
17
+ consoleText,
18
+ hashCode,
19
+ limitObject,
20
+ niceCallback
21
+ } from '@@/utils/tools';
22
+ import EMIT_MSG from '@@/constants/emitMsg';
23
+ import { ABTEST_DATA_REG, ABTEST_SIGN_REG } from '@@/constants/regex';
14
24
 
15
25
  class GioABTest {
26
+ public pluginVersion: string;
16
27
  // 请求间隔时长
17
28
  public requestInterval: number;
18
29
  // 请求超时时长
19
30
  public requestTimeout: number;
20
31
  // 分流服务请求地址
21
- public url: string;
32
+ public url: any;
22
33
  // 接口重试计数
23
34
  public retryCount: number;
24
35
  constructor(public growingIO: GrowingIOType, options: any) {
25
- const { abServerUrl, requestInterval, requestTimeout } = options ?? {};
36
+ this.pluginVersion = '__PLUGIN_VERSION__';
37
+ const {
38
+ abServerUrl = 'https://ab.growingio.com',
39
+ requestInterval,
40
+ requestTimeout
41
+ } = options ?? {};
26
42
  this.timeoutCheck(requestInterval, requestTimeout);
27
43
  const { emitter } = this.growingIO;
28
44
  this.growingIO.getABTest = this.getABTest;
29
- emitter.on('OPTION_INITIALIZED', () => {
30
- if (abServerUrl) {
45
+ emitter.on(EMIT_MSG.OPTION_INITIALIZED, () => {
46
+ if (!isEmpty(abServerUrl)) {
31
47
  this.abtStorageCheck();
32
- this.generateUrl(abServerUrl);
48
+ this.url = {};
49
+ if (isString(abServerUrl)) {
50
+ this.generateUrl(this.growingIO.trackingId, abServerUrl);
51
+ } else if (isObject(abServerUrl)) {
52
+ keys(abServerUrl).forEach((trackingId: string) => {
53
+ this.generateUrl(trackingId, abServerUrl[trackingId]);
54
+ });
55
+ }
33
56
  } else {
34
57
  consoleText(
35
58
  '如果您需要使用ABTest功能,请配置服务地址 abServerUrl!',
@@ -47,16 +70,16 @@ class GioABTest {
47
70
  ) => {
48
71
  this.requestInterval =
49
72
  isNumber(Number(requestInterval)) &&
50
- !isNaN(Number.parseInt(requestInterval as string, 10))
51
- ? Number.parseInt(requestInterval as string, 10)
73
+ !isNaN(Number(requestInterval as string))
74
+ ? Number(requestInterval as string)
52
75
  : 5;
53
76
  if (this.requestInterval > 60 * 24 || this.requestInterval < 0) {
54
77
  this.requestInterval = 5;
55
78
  }
56
79
  this.requestTimeout =
57
80
  isNumber(Number(requestTimeout)) &&
58
- !isNaN(Number.parseInt(requestTimeout as string, 10))
59
- ? Number.parseInt(requestTimeout as string, 10)
81
+ !isNaN(Number(requestTimeout as string))
82
+ ? Number(requestTimeout as string)
60
83
  : 1000;
61
84
  if (this.requestTimeout > 5000 || this.requestTimeout < 100) {
62
85
  this.requestTimeout = 1000;
@@ -68,7 +91,7 @@ class GioABTest {
68
91
  const { minipInstance }: any = this.growingIO;
69
92
  const storageKeys = minipInstance.minip?.getStorageInfoSync().keys || [];
70
93
  // 请求标记
71
- const abtsKeys = storageKeys.filter((k) => /^\d+_gdp_abt_sign$/.test(k));
94
+ const abtsKeys = storageKeys.filter((k) => ABTEST_SIGN_REG.test(k));
72
95
  abtsKeys.forEach((k) => {
73
96
  // 移除过期的数据,防止存储超限
74
97
  const sign = minipInstance.getStorageSync(k);
@@ -77,7 +100,7 @@ class GioABTest {
77
100
  }
78
101
  });
79
102
  // abtest数据
80
- const abtdKeys = storageKeys.filter((k) => /^\d+_gdp_abtd$/.test(k));
103
+ const abtdKeys = storageKeys.filter((k) => ABTEST_DATA_REG.test(k));
81
104
  abtdKeys.forEach((k) => {
82
105
  // 移除过期的数据,防止存储超限
83
106
  if (isEmpty(minipInstance.getStorageSync(k))) {
@@ -87,28 +110,31 @@ class GioABTest {
87
110
  };
88
111
 
89
112
  // 生成存储的hash key
90
- getHashKey = (layerId: string | number) => {
113
+ getHashKey = (trackingId: string, layerId: string | number) => {
91
114
  const {
92
- userStore: { uid },
115
+ userStore: { getUid },
93
116
  vdsConfig: { projectId }
94
117
  } = this.growingIO;
95
- return Math.abs(hashCode(`${projectId}#${uid}#${layerId}`));
118
+ return hashCode(`${trackingId}#${projectId}#${getUid()}#${layerId}`, true);
96
119
  };
97
120
 
98
121
  // 生成数据接口地址
99
- generateUrl = (abServerUrl: string) => {
122
+ generateUrl = (trackingId: string, abServerUrl: string) => {
100
123
  if (!startsWith(abServerUrl, 'http')) {
101
- this.url = `https://${abServerUrl}/diversion/specified-layer-variables`;
124
+ this.url[
125
+ trackingId
126
+ ] = `https://${abServerUrl}/diversion/specified-layer-variables`;
102
127
  } else {
103
- this.url = `${abServerUrl}/diversion/specified-layer-variables`;
128
+ this.url[
129
+ trackingId
130
+ ] = `${abServerUrl}/diversion/specified-layer-variables`;
104
131
  }
105
132
  };
106
133
 
107
134
  // 获取实验调用
108
- getABTest = (layerId: string | number, callback: any) => {
109
- if (!this.url) {
110
- niceCallback(callback, {});
111
- return;
135
+ getABTest = (trackingId: string, layerId: string | number, callback: any) => {
136
+ if (isEmpty(this.url[trackingId])) {
137
+ this.generateUrl(trackingId, 'https://ab.growingio.com');
112
138
  }
113
139
  if (!layerId) {
114
140
  consoleText('获取ABTest数据失败! 实验层Id不合法!', 'error');
@@ -119,15 +145,16 @@ class GioABTest {
119
145
  // 接口调用的超时时间
120
146
  const abtSign =
121
147
  minipInstance.getStorageSync(
122
- `${this.getHashKey(layerId)}_gdp_abt_sign`
148
+ `${this.getHashKey(trackingId, layerId)}_gdp_abt_sign`
123
149
  ) || 0;
124
150
  // 没有超时尝试取数据
125
151
  const abtData =
126
- minipInstance.getStorageSync(`${this.getHashKey(layerId)}_gdp_abtd`) ||
127
- {};
152
+ minipInstance.getStorageSync(
153
+ `${this.getHashKey(trackingId, layerId)}_gdp_abtd`
154
+ ) || {};
128
155
  // 没有有效数据或者接口请求标记超时则从调用分流服务获取数据
129
156
  if (!abtSign || abtSign < Date.now()) {
130
- this.initiateRequest(layerId, abtData, callback);
157
+ this.initiateRequest(trackingId, layerId, abtData, callback);
131
158
  } else {
132
159
  niceCallback(callback, abtData);
133
160
  }
@@ -135,30 +162,36 @@ class GioABTest {
135
162
 
136
163
  // 发起请求
137
164
  initiateRequest = (
165
+ trackingId: string,
138
166
  layerId: string | number,
139
167
  originData: any,
140
168
  callback: any
141
169
  ) => {
142
170
  const {
143
- userStore: { uid },
144
- vdsConfig: { projectId, dataSourceId },
171
+ userStore: { getUid },
172
+ dataStore,
145
173
  minipInstance
146
174
  } = this.growingIO;
147
-
175
+ const { projectId, dataSourceId } = dataStore.getTrackerVds(trackingId);
148
176
  minipInstance.request({
149
- url: this.url,
177
+ url: this.url[trackingId],
150
178
  header: { 'Content-Type': 'application/x-www-form-urlencoded' },
151
179
  method: 'POST',
152
180
  data: {
153
181
  accountId: projectId,
154
182
  datasourceId: dataSourceId,
155
- distinctId: uid,
183
+ distinctId: getUid(),
156
184
  layerId
157
185
  },
158
186
  timeout: this.requestTimeout,
159
187
  success: ({ data }: any) => {
160
188
  if (data.code === 0) {
161
- this.experimentVerify({ ...data, layerId }, originData, callback);
189
+ this.experimentVerify(
190
+ trackingId,
191
+ { ...data, layerId },
192
+ originData,
193
+ callback
194
+ );
162
195
  } else {
163
196
  consoleText(`获取ABTest数据失败! ${data.errorMsg}!`, 'error');
164
197
  // 接口业务失败返回false信息
@@ -166,7 +199,7 @@ class GioABTest {
166
199
  }
167
200
  // 接口调用返回后刷新接口调用标记
168
201
  minipInstance.setStorageSync(
169
- `${this.getHashKey(layerId)}_gdp_abt_sign`,
202
+ `${this.getHashKey(trackingId, layerId)}_gdp_abt_sign`,
170
203
  Date.now() + 1000 * 60 * this.requestInterval
171
204
  );
172
205
  },
@@ -179,7 +212,7 @@ class GioABTest {
179
212
  } else {
180
213
  // 其他失败情况重试
181
214
  if (this.retryCount < 2) {
182
- this.initiateRequest(layerId, originData, callback);
215
+ this.initiateRequest(trackingId, layerId, originData, callback);
183
216
  this.retryCount += 1;
184
217
  } else {
185
218
  consoleText(
@@ -195,9 +228,14 @@ class GioABTest {
195
228
  };
196
229
 
197
230
  // 实验校验(决定是否上报命中事件)
198
- experimentVerify = (responseData: any, originData: any, callback: any) => {
231
+ experimentVerify = (
232
+ trackingId: string,
233
+ responseData: any,
234
+ originData: any,
235
+ callback: any
236
+ ) => {
199
237
  const { layerId, strategyId, experimentId, variables } = responseData;
200
- const abtDataKey = `${this.getHashKey(layerId)}_gdp_abtd`;
238
+ const abtDataKey = `${this.getHashKey(trackingId, layerId)}_gdp_abtd`;
201
239
  const abtData = {
202
240
  layerId: toString(layerId),
203
241
  strategyId: toString(strategyId),
@@ -221,6 +259,7 @@ class GioABTest {
221
259
  // 数据不一致重新发命中埋点
222
260
  if (strategyId && experimentId) {
223
261
  this.buildExperimentHitEvent(
262
+ trackingId,
224
263
  toString(layerId),
225
264
  toString(experimentId),
226
265
  toString(strategyId)
@@ -232,21 +271,26 @@ class GioABTest {
232
271
  };
233
272
 
234
273
  // 构建实验命中事件
235
- buildExperimentHitEvent = (layerId, experimentId, strategyId) => {
274
+ buildExperimentHitEvent = (
275
+ trackingId: string,
276
+ layerId: string,
277
+ experimentId: string,
278
+ strategyId: string
279
+ ) => {
236
280
  const {
237
281
  dataStore: { eventContextBuilder, eventConverter }
238
282
  } = this.growingIO;
239
283
  let event = {
240
284
  eventType: 'CUSTOM',
241
285
  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
286
+ ...eventContextBuilder(trackingId)
249
287
  };
288
+ event.attributes = limitObject({
289
+ ...(event.attributes ?? {}),
290
+ $exp_layer_id: layerId,
291
+ $exp_id: experimentId,
292
+ $exp_strategy_id: strategyId
293
+ });
250
294
  eventConverter(event);
251
295
  };
252
296
  }
@@ -5,9 +5,11 @@
5
5
  import { GrowingIOType } from '@@/types/growingIO';
6
6
 
7
7
  class GioCompress {
8
+ public pluginVersion: string;
8
9
  private f;
9
10
  private _compress;
10
11
  constructor(public growingIO: GrowingIOType) {
12
+ this.pluginVersion = '__PLUGIN_VERSION__';
11
13
  this.f = String.fromCharCode;
12
14
  this._compress = function (uncompressed, bitsPerChar, getCharFromInt) {
13
15
  if (uncompressed === null) return '';
@@ -2,21 +2,30 @@
2
2
  * 名称:无埋点插件
3
3
  * 用途:用于提供无埋点的事件构建方法。
4
4
  */
5
+ import { ID_REG, SWAN_XID_REG, TARO_XID_REG } from '@@/constants/regex';
5
6
  import { EventTarget } from '@@/types/eventHooks';
6
7
  import { GrowingIOType } from '@@/types/growingIO';
7
8
  import { consoleText, isTaro3 } from '@@/utils/tools';
9
+ import EMIT_MSG from '@@/constants/emitMsg';
8
10
 
9
11
  let ut;
10
12
  class GioEventAutoTracking {
13
+ public pluginVersion: string;
11
14
  private prevEvent: any;
12
15
  constructor(public growingIO: GrowingIOType) {
16
+ this.pluginVersion = '__PLUGIN_VERSION__';
13
17
  ut = this.growingIO.utils;
14
18
  this.prevEvent = {};
15
19
  }
16
20
 
17
21
  main = (e: EventTarget, eventName: string) => {
18
- const { vdsConfig, platformConfig, plugins, emitter }: GrowingIOType =
19
- this.growingIO;
22
+ const {
23
+ vdsConfig,
24
+ platformConfig,
25
+ plugins,
26
+ emitter,
27
+ trackingId
28
+ }: GrowingIOType = this.growingIO;
20
29
  if (
21
30
  // 无埋点事件拦截
22
31
  !vdsConfig.autotrack ||
@@ -49,15 +58,15 @@ class GioEventAutoTracking {
49
58
  console.log('Action:', e.type, Date.now());
50
59
  }
51
60
  // 向其他插件广播事件
52
- emitter.emit('onComposeBefore', {
61
+ emitter.emit(EMIT_MSG.ON_COMPOSE_BEFORE, {
53
62
  event: eventName,
54
63
  params: e ?? {}
55
64
  });
56
65
  const actionListeners = platformConfig.listeners.actions;
57
66
  if (actionListeners.click.includes(e.type)) {
58
- this.buildClickEvent(e, eventName);
67
+ this.buildClickEvent(trackingId, e, eventName);
59
68
  } else if (actionListeners.change.includes(e.type)) {
60
- this.buildChangeEvent(e, eventName);
69
+ this.buildChangeEvent(trackingId, e, eventName);
61
70
  }
62
71
  };
63
72
 
@@ -68,8 +77,8 @@ class GioEventAutoTracking {
68
77
  let id = target.id;
69
78
  if (
70
79
  !id ||
71
- (gioPlatform === 'swan' && /^_[0-9a-f]+/.test(id)) ||
72
- (isTaro3(vdsConfig.taro) && /^_n_[0-9]+$/.test(id))
80
+ (gioPlatform === 'swan' && SWAN_XID_REG.test(id)) ||
81
+ (isTaro3(vdsConfig.taro) && TARO_XID_REG.test(id))
73
82
  ) {
74
83
  id = '';
75
84
  }
@@ -77,21 +86,17 @@ class GioEventAutoTracking {
77
86
  };
78
87
 
79
88
  // 构建点击事件
80
- buildClickEvent = (e: EventTarget, eventName: string) => {
89
+ buildClickEvent = (trackingId: string, e: EventTarget, eventName: string) => {
81
90
  const xpath = this.getNodeXpath(e, eventName);
82
91
  if (xpath) {
83
92
  const {
84
- dataStore: { eventContextBuilder, eventInterceptor }
93
+ dataStore: { eventContextBuilder, eventInterceptor, eventHooks }
85
94
  } = this.growingIO;
86
95
  const target = e.currentTarget || e.target;
87
96
  let idx;
88
97
  if (ut.has(target?.dataset, 'index') && target?.dataset?.index !== '') {
89
98
  const index: any = ut.toString(target.dataset.index);
90
- if (
91
- /^\d{1,10}$/.test(index) &&
92
- index - 0 > 0 &&
93
- index - 0 < 2147483647
94
- ) {
99
+ if (ID_REG.test(index) && index - 0 > 0 && index - 0 < 2147483647) {
95
100
  idx = +index;
96
101
  } else {
97
102
  consoleText(
@@ -110,16 +115,21 @@ class GioEventAutoTracking {
110
115
  hyperlink: target?.dataset?.src
111
116
  }
112
117
  ],
113
- ...eventContextBuilder()
118
+ ...eventContextBuilder(trackingId)
114
119
  };
120
+ // 合并页面属性
121
+ event.attributes = eventHooks.currentPage.eventSetPageProps(
122
+ trackingId,
123
+ event
124
+ );
115
125
  eventInterceptor(event);
116
126
  }
117
127
  };
118
128
 
119
129
  // 构建tab菜单点击事件
120
- buildTabClickEvent = (tabItem: any) => {
130
+ buildTabClickEvent = (trackingId: string, tabItem: any) => {
121
131
  const {
122
- dataStore: { eventContextBuilder, eventInterceptor }
132
+ dataStore: { eventContextBuilder, eventInterceptor, eventHooks }
123
133
  } = this.growingIO;
124
134
  const event = {
125
135
  eventType: 'VIEW_CLICK',
@@ -131,23 +141,32 @@ class GioEventAutoTracking {
131
141
  hyperlink: ut.toString(tabItem.pagePath)
132
142
  }
133
143
  ],
134
- ...eventContextBuilder()
144
+ ...eventContextBuilder(trackingId)
135
145
  };
146
+ // 合并页面属性
147
+ event.attributes = eventHooks.currentPage.eventSetPageProps(
148
+ trackingId,
149
+ event
150
+ );
136
151
  eventInterceptor(event);
137
152
  };
138
153
 
139
154
  // 构建表单变化事件
140
- buildChangeEvent = (e: EventTarget, eventName: string) => {
155
+ buildChangeEvent = (
156
+ trackingId: string,
157
+ e: EventTarget,
158
+ eventName: string
159
+ ) => {
141
160
  const xpath = this.getNodeXpath(e, eventName);
142
161
  if (xpath) {
143
162
  const {
144
- dataStore: { eventContextBuilder, eventInterceptor }
163
+ dataStore: { eventContextBuilder, eventInterceptor, eventHooks }
145
164
  } = this.growingIO;
146
165
  const target = e.currentTarget || e.target;
147
166
  const event = {
148
167
  eventType: 'VIEW_CHANGE',
149
168
  element: { xpath },
150
- ...eventContextBuilder()
169
+ ...eventContextBuilder(trackingId)
151
170
  };
152
171
  const ev = ut.get(e, 'detail.value') || ut.get(e, 'target.attr.value');
153
172
  if (target?.dataset?.growingTrack || target?.dataset?.growingtrack) {
@@ -156,6 +175,11 @@ class GioEventAutoTracking {
156
175
  }
157
176
  }
158
177
  event.element = [event.element];
178
+ // 合并页面属性
179
+ event.attributes = eventHooks.currentPage.eventSetPageProps(
180
+ trackingId,
181
+ event
182
+ );
159
183
  eventInterceptor(event);
160
184
  }
161
185
  };
@@ -2,12 +2,28 @@
2
2
  * 名称:半自动浏览埋点插件
3
3
  * 用途:用于提供半自动浏览埋点事件的自动注册、参数检验构建和创建事件方法。
4
4
  */
5
+ import { IMP_DATA_REG } from '@@/constants/regex';
5
6
  import { GrowingIOType } from '@@/types/growingIO';
6
- import { hashCode } from '@@/utils/tools';
7
- import { isEmpty, isEqualArray, toString } from '@@/utils/glodash';
7
+ import {
8
+ compact,
9
+ isArray,
10
+ isEmpty,
11
+ isEqualArray,
12
+ isObject,
13
+ isString,
14
+ toString
15
+ } from '@@/utils/glodash';
16
+ import {
17
+ eventNameValidate,
18
+ hashCode,
19
+ limitObject,
20
+ niceTry
21
+ } from '@@/utils/tools';
22
+ import EMIT_MSG from '@@/constants/emitMsg';
8
23
 
9
24
  let ut;
10
25
  class GioImpressionTracking {
26
+ public pluginVersion: string;
11
27
  public observerIds: any;
12
28
  public rects: any;
13
29
  public pageImpObserver: any;
@@ -16,6 +32,7 @@ class GioImpressionTracking {
16
32
  public componentQueryTarget: any;
17
33
  public sentImps: any;
18
34
  constructor(public growingIO: GrowingIOType) {
35
+ this.pluginVersion = '__PLUGIN_VERSION__';
19
36
  ut = this.growingIO.utils;
20
37
  this.observerIds = {};
21
38
  this.rects = {};
@@ -27,7 +44,7 @@ class GioImpressionTracking {
27
44
  }
28
45
  minipInstance.initImpression(collect);
29
46
  };
30
- emitter.on('minipLifecycle', ({ event, params }) => {
47
+ emitter.on(EMIT_MSG.MINIP_LIFECYCLE, ({ event, params }) => {
31
48
  const { minipInstance } = this.growingIO;
32
49
  if (event === 'Page onShowEnd') {
33
50
  const page = minipInstance.getCurrentPage();
@@ -78,6 +95,7 @@ class GioImpressionTracking {
78
95
  case 'jd':
79
96
  return collectTarget.__wxExparserNodeId__; // wx page/component
80
97
  case 'my':
98
+ case 'tb':
81
99
  return collectTarget.$page
82
100
  ? `${collectTarget.$page.$id}-${collectTarget.$id}` //my component
83
101
  : collectTarget.$id; // my page
@@ -229,8 +247,28 @@ class GioImpressionTracking {
229
247
  this.sentImps[sentId] = dataProperties;
230
248
  }
231
249
  }
232
- if (dataProperties.eventId) {
233
- this.buildImpEvent(dataProperties);
250
+ if (dataProperties.eventName) {
251
+ let sendTargets = [];
252
+ if (dataset.gioImpSendto) {
253
+ // 先尝试处理成数组
254
+ sendTargets = compact(
255
+ isArray(dataset.gioImpSendto)
256
+ ? dataset.gioImpSendto
257
+ : niceTry(() => JSON.parse(dataset.gioImpSendto)) || []
258
+ );
259
+ // 在尝试处理字符串
260
+ if (isEmpty(sendTargets)) {
261
+ niceTry(() =>
262
+ dataset.gioImpSendto.split(',').forEach((s: string) => {
263
+ s = isString(s) && s.trim().replace('[', '').replace(']', '');
264
+ if (s) {
265
+ sendTargets.push(s);
266
+ }
267
+ })
268
+ );
269
+ }
270
+ }
271
+ this.buildImpEvent(dataProperties, sendTargets);
234
272
  } else {
235
273
  ut.consoleText(
236
274
  '曝光事件格式不正确,事件名只能包含数字、字母和下划线,且不以数字开头!',
@@ -244,13 +282,13 @@ class GioImpressionTracking {
244
282
  // 曝光参数获取
245
283
  getImpressionProperties = (dataSet: any) => {
246
284
  let data: any = {
247
- eventId: undefined,
285
+ eventName: undefined,
248
286
  properties: {}
249
287
  };
250
288
  if (!dataSet?.gioImpTrack) {
251
289
  return data;
252
290
  } else {
253
- data.eventId = dataSet.gioImpTrack;
291
+ data.eventName = dataSet.gioImpTrack;
254
292
  }
255
293
  if (ut.has(dataSet, 'gioImpAttrs')) {
256
294
  // imp写法二
@@ -261,10 +299,9 @@ class GioImpressionTracking {
261
299
  );
262
300
  } else {
263
301
  // imp写法一
264
- const propReg = /^gioTrack(.+)/;
265
302
  for (const key in dataSet) {
266
303
  let normKey;
267
- const matchArr = key.match(propReg);
304
+ const matchArr = key.match(IMP_DATA_REG);
268
305
  if (matchArr) {
269
306
  normKey = ut.lowerFirst(matchArr[1]);
270
307
  if (normKey !== 'track') {
@@ -275,13 +312,12 @@ class GioImpressionTracking {
275
312
  }
276
313
  // 对参数对象进行限制
277
314
  data.properties = ut.limitObject(data.properties);
278
- // 校验eventId
279
- const eventIdReg = /^\w+$/;
280
- if (
281
- !eventIdReg.test(data.eventId) ||
282
- Number.isInteger(Number.parseInt(ut.head(data.eventId.split('')), 10))
283
- ) {
284
- data.eventId = null;
315
+ // 校验eventName
316
+ const validate = eventNameValidate(data.eventName, () => {
317
+ return data;
318
+ });
319
+ if (!validate) {
320
+ data.eventName = null;
285
321
  data = {};
286
322
  }
287
323
  return data;
@@ -315,18 +351,26 @@ class GioImpressionTracking {
315
351
  };
316
352
 
317
353
  // 创建半自动曝光事件
318
- buildImpEvent = (dataProperties: any) => {
319
- const { eventId, properties } = dataProperties;
354
+ buildImpEvent = (dataProperties: any, sendTargets: string[]) => {
355
+ const { eventName, properties } = dataProperties;
320
356
  const {
321
- dataStore: { eventContextBuilder, eventInterceptor }
357
+ trackingId,
358
+ dataStore: { eventContextBuilder, eventConverter },
359
+ plugins
322
360
  } = this.growingIO;
323
361
  const event = {
324
362
  eventType: 'CUSTOM',
325
- eventName: eventId,
326
- attributes: properties,
327
- ...eventContextBuilder()
363
+ eventName,
364
+ ...eventContextBuilder(trackingId)
328
365
  };
329
- eventInterceptor(event);
366
+ event.attributes = limitObject({
367
+ ...(event.attributes ?? {}),
368
+ ...(isObject(properties) && !isEmpty(properties) ? properties : {})
369
+ });
370
+ if (plugins.gioMultipleInstances && !isEmpty(sendTargets)) {
371
+ event['&&sendTo'] = sendTargets;
372
+ }
373
+ eventConverter(event);
330
374
  };
331
375
  }
332
376