gio-miniprogram-sdk 4.3.2 → 4.4.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.
Files changed (58) hide show
  1. package/.github/workflows/publish.yml +3 -3
  2. package/dist/alipay.js +1 -1
  3. package/dist/baidu.js +1 -1
  4. package/dist/bytedance.js +1 -1
  5. package/dist/jingdong.js +1 -1
  6. package/dist/kuaishou.js +1 -1
  7. package/dist/plugins/gioABTest.js +1 -1
  8. package/dist/plugins/gioCompress.js +1 -1
  9. package/dist/plugins/gioEventAutoTracking.js +1 -1
  10. package/dist/plugins/gioImpressionTracking.js +1 -1
  11. package/dist/plugins/gioMultipleInstances.js +1 -1
  12. package/dist/plugins/gioPerformance.js +1 -0
  13. package/dist/qq.js +1 -1
  14. package/dist/quickapp.js +1 -1
  15. package/dist/taobao.js +1 -1
  16. package/dist/taro.js +1 -1
  17. package/dist/uniapp.js +1 -1
  18. package/dist/wechat.js +1 -1
  19. package/dist/xiaohongshu.js +1 -0
  20. package/package.json +12 -6
  21. package/rollup.config.js +9 -6
  22. package/rollup.plugins.config.js +1 -1
  23. package/src/adapters/gioUniAppAdapter.ts +324 -113
  24. package/src/constants/emitMsg.ts +1 -0
  25. package/src/core/dataStore/eventHooks/appEffects.ts +6 -1
  26. package/src/core/dataStore/eventHooks/index.ts +122 -80
  27. package/src/core/dataStore/eventHooks/minipPage.ts +78 -68
  28. package/src/core/dataStore/eventHooks/pageEffects.ts +9 -2
  29. package/src/core/dataStore/index.ts +1 -1
  30. package/src/core/growingIO.ts +27 -3
  31. package/src/core/uploader.ts +12 -3
  32. package/src/core/userStore.ts +1 -2
  33. package/src/minipInstance/base.ts +62 -23
  34. package/src/minipInstance/framework.ts +3 -1
  35. package/src/minipInstance/my.ts +34 -1
  36. package/src/minipInstance/quickapp.ts +11 -0
  37. package/src/minipInstance/wx.ts +15 -0
  38. package/src/minipInstance/xhs.ts +20 -0
  39. package/src/platformConfig/base.ts +1 -0
  40. package/src/platformConfig/framework.ts +2 -0
  41. package/src/platformConfig/my.ts +1 -0
  42. package/src/platformConfig/xhs.ts +27 -0
  43. package/src/plugins/gioABTest.ts +32 -3
  44. package/src/plugins/gioEventAutoTracking.ts +101 -1
  45. package/src/plugins/gioImpressionTracking.ts +8 -3
  46. package/src/plugins/gioPerformance/exception.ts +152 -0
  47. package/src/plugins/gioPerformance/monitor.ts +284 -0
  48. package/src/plugins/gioPerformance/network.ts +197 -0
  49. package/src/plugins/gioPerformance.ts +131 -0
  50. package/src/types/base.ts +5 -1
  51. package/src/types/eventHooks.ts +5 -4
  52. package/src/types/minipInstance.ts +8 -1
  53. package/src/types/platforms.ts +3 -0
  54. package/src/utils/tools.ts +47 -3
  55. package/src/utils/verifiers.ts +4 -3
  56. package/tsconfig.json +1 -1
  57. package/typings/global.d.ts +8 -0
  58. package/bin/build.sh +0 -38
@@ -1,6 +1,6 @@
1
1
  import { EventHooksType, MinipPageType } from '@@/types/eventHooks';
2
2
  import { GrowingIOType } from '@@/types/growingIO';
3
- import { has, isArray, isFunction, typeOf, unset } from '@@/utils/glodash';
3
+ import { has, isArray, isEmpty, isFunction, typeOf } from '@@/utils/glodash';
4
4
  import { consoleText, getGlobal, niceTry } from '@@/utils/tools';
5
5
 
6
6
  import AppEffects from './appEffects';
@@ -17,6 +17,7 @@ class EventHooks implements EventHooksType {
17
17
  public defPageCbs: any;
18
18
  public appHandlers: string[];
19
19
  public pageHandlers: string[];
20
+ public shareEventTypes: string[];
20
21
  public actionEventTypes: string[];
21
22
  public originalApp: (any: any) => any;
22
23
  public originalPage: (any: any) => any;
@@ -33,6 +34,7 @@ class EventHooks implements EventHooksType {
33
34
  this.defPageCbs = {};
34
35
  this.appHandlers = config.appHandlers;
35
36
  this.pageHandlers = config.pageHandlers;
37
+ this.shareEventTypes = config.shareEventTypes;
36
38
  this.actionEventTypes = config.actionEventTypes;
37
39
  this.appEffects = new AppEffects(this.growingIO);
38
40
  this.pageEffects = new PageEffects(this.growingIO);
@@ -85,95 +87,135 @@ class EventHooks implements EventHooksType {
85
87
  }
86
88
  };
87
89
 
88
- // 生命周期方法effects
90
+ /**
91
+ * 执行生命周期回调并广播事件
92
+ */
93
+ lifeFcEffectsFn = (instance, args, cType, eventName, result = undefined) => {
94
+ // 创建参数数组副本
95
+ const argsArray =
96
+ typeOf(args) === 'array' ? Array.prototype.slice.call(args) : [];
97
+ // 如果有结果,添加到参数列表
98
+ if (!isEmpty(result)) {
99
+ argsArray.push(result);
100
+ }
101
+
102
+ // 执行effects
103
+ this[`def${cType}Cbs`][eventName].apply(instance, argsArray);
104
+
105
+ // 广播生命周期
106
+ this.growingIO.emitter.emit(EMIT_MSG.MINIP_LIFECYCLE, {
107
+ event: `${cType} ${eventName}End`,
108
+ timestamp: Date.now(),
109
+ params: { instance, arguments: Array.from(argsArray) }
110
+ });
111
+
112
+ return result;
113
+ };
114
+
115
+ /**
116
+ * 生命周期方法effects
117
+ */
89
118
  lifeFcEffects = (eventName: string, method: any, cType: 'App' | 'Page') => {
90
119
  const self = this;
91
- if (['onShareTimeline', 'onAddToFavorites'].includes(eventName)) {
92
- // onShareTimeline和onAddToFavorites不能异步执行,单独处理
93
- return function (...args) {
94
- let result = method.apply(this, args);
95
- if (
96
- eventName === 'onShareTimeline' &&
97
- self.growingIO.vdsConfig.followShare
98
- ) {
99
- result = self.currentPage.updateTimelineResult(result ?? {});
100
- }
101
- if (eventName === 'onAddToFavorites') {
102
- result = self.currentPage.updateAddFavoritesResult(result ?? {});
103
- }
104
- const argsArray = Array.prototype.slice.call(args);
105
- if (result) {
106
- argsArray.push(result);
120
+
121
+ return function (...args) {
122
+ let result;
123
+
124
+ // 分享事件单独处理
125
+ if (self.shareEventTypes.includes(eventName)) {
126
+ // 先执行分享的生命周期拿到分享数据
127
+ const originResult = method.apply(this, args) ?? {};
128
+
129
+ // sdk跟踪分享事件时才处理,否则直接返回原结果
130
+ if (!self.growingIO.vdsConfig.followShare) {
131
+ return originResult;
107
132
  }
108
- // 执行effects
109
- self[`def${cType}Cbs`][eventName].apply(this, argsArray);
110
- return result;
111
- };
112
- } else {
113
- // 其他生命周期可以异步执行
114
- return async function (...args) {
115
- let result;
116
- try {
117
- // 分享处理
118
- if (eventName === 'onShareAppMessage') {
119
- // 先执行分享的生命周期拿到分享数据
120
- // 与基础库保持一致,没有返回值时默认使用{}
121
- result = method.apply(this, args) ?? {};
122
- // 如果分享事件是个promise函数,需要等待异步结果
123
- if (typeOf(result) === 'promise') {
124
- result = await result.then((r) => r);
125
- }
126
- // 如果返回的对象中包含promise,要等待异步结果
127
- if (typeOf(result.promise) === 'promise') {
128
- const f = async function () {
129
- let sRes = result;
130
- return new Promise((resolve) => {
131
- // 如果3秒后result.promise没有返回结果,则返回的是默认的result值
132
- // https://developers.weixin.qq.com/miniprogram/dev/reference/api/Page.html#onShareAppMessage-Object-object
133
- let t = setTimeout(() => {
134
- resolve({ ...sRes });
135
- clearTimeout(t);
136
- t = undefined;
137
- }, 3000);
138
- result.promise.then((res) => {
139
- sRes = res;
140
- resolve({ ...sRes });
141
- clearTimeout(t);
142
- t = undefined;
143
- });
144
- });
133
+ const isPromiseResult = typeOf(originResult) === 'promise';
134
+ const hasPromiseProperty = typeOf(originResult.promise) === 'promise';
135
+ // 支付宝的promise会被提前处理过,通过以下两个字段判断是否需要自定义promise
136
+ const isSpecialPromise =
137
+ has(originResult, '_result') && has(originResult, '_state');
138
+
139
+ // 处理异步分享结果
140
+ if (isPromiseResult || hasPromiseProperty || isSpecialPromise) {
141
+ // 创建处理Promise结果的通用函数
142
+ const handlePromiseResult = (promiseResult = {}) => {
143
+ try {
144
+ // 合并原始结果和Promise结果
145
+ const mergedResult = {
146
+ ...originResult,
147
+ ...promiseResult
145
148
  };
146
- result = { ...result, ...((await f()) as any) };
147
- unset(result, 'promise');
148
- }
149
- if (self.growingIO.vdsConfig.followShare) {
150
- result = self.currentPage.updateAppMessageResult(result ?? {});
149
+
150
+ // 更新分享内容
151
+ const updatedResult =
152
+ self.currentPage.updateShareResult(mergedResult);
153
+
154
+ // 执行回调
155
+ self.lifeFcEffectsFn(this, args, cType, eventName, updatedResult);
156
+ } catch (error) {
157
+ consoleText(error, 'error');
151
158
  }
159
+ };
160
+
161
+ // 处理整个返回值是Promise的情况
162
+ if (isPromiseResult) {
163
+ // 如果三秒内不resolve结果,分享会使用原默认参数
164
+ Promise.race([
165
+ originResult,
166
+ new Promise((resolve) => {
167
+ setTimeout(() => {
168
+ resolve({});
169
+ }, 3000);
170
+ })
171
+ ])
172
+ .then(handlePromiseResult)
173
+ .catch((error) => consoleText(error, 'error'));
152
174
  }
153
- const argsArray = Array.prototype.slice.call(args);
154
- if (result) {
155
- argsArray.push(result);
175
+
176
+ // 处理返回值中包含promise属性的情况
177
+ if (hasPromiseProperty) {
178
+ // 如果三秒内不resolve结果,分享会使用原默认参数
179
+ Promise.race([
180
+ originResult.promise,
181
+ new Promise((resolve) => {
182
+ setTimeout(() => {
183
+ resolve({});
184
+ }, 3000);
185
+ })
186
+ ])
187
+ .then(handlePromiseResult)
188
+ .catch((error) => consoleText(error, 'error'));
156
189
  }
157
- // 执行effects
158
- self[`def${cType}Cbs`][eventName].apply(this, argsArray);
159
- } catch (error) {
160
- consoleText(error, 'error');
161
- }
162
- // 执行分享之外的生命周期函数
163
- if (eventName !== 'onShareAppMessage') {
164
- result = method.apply(this, args);
190
+
191
+ // 处理支付宝特有的promise
192
+ if (isSpecialPromise) {
193
+ self.growingIO.minipInstance?.handleSharePromise(
194
+ originResult,
195
+ handlePromiseResult
196
+ );
197
+ }
198
+
199
+ // 直接返回原分享结果继续执行原逻辑
200
+ result = self.currentPage.updateShareResult(originResult, false);
201
+ } else {
202
+ // 没有异步逻辑,直接更新分享内容执行回调
203
+ result = self.currentPage.updateShareResult(originResult);
204
+ self.lifeFcEffectsFn(this, args, cType, eventName, result);
165
205
  }
166
- self.growingIO.emitter.emit(EMIT_MSG.MINIP_LIFECYCLE, {
167
- event: `${cType} ${eventName}End`,
168
- timestamp: Date.now(),
169
- params: { instance: this, arguments: Array.from(args) }
170
- });
171
- return result;
172
- };
173
- }
206
+ } else {
207
+ // 其他生命周期事件:先执行回调,再执行原方法
208
+ self.lifeFcEffectsFn(this, args, cType, eventName);
209
+ result = method.apply(this, args);
210
+ }
211
+
212
+ return result;
213
+ };
174
214
  };
175
215
 
176
- // 自定义方法effects
216
+ /*
217
+ * 自定义方法effects
218
+ */
177
219
  customFcEffects = (eventName: string, method: any) => {
178
220
  const self = this;
179
221
  return function (...args) {
@@ -1,12 +1,4 @@
1
- import {
2
- compact,
3
- has,
4
- head,
5
- isEmpty,
6
- keys,
7
- last,
8
- unset
9
- } from '@@/utils/glodash';
1
+ import { compact, has, isEmpty, keys, last, unset } from '@@/utils/glodash';
10
2
  import { GrowingIOType } from '@@/types/growingIO';
11
3
  import { MinipPageType, PageShareResult } from '@@/types/eventHooks';
12
4
  import {
@@ -23,7 +15,7 @@ import { EVENT } from '@@/types/base';
23
15
 
24
16
  class MinipPage implements MinipPageType {
25
17
  // 根据页面存储的页面参数
26
- public queryOption: any;
18
+ public queryOptions: any;
27
19
  // 通过调用wx.setNavigationBarTitle设置的title
28
20
  public configuredTitle: any;
29
21
  // 页面级属性
@@ -36,12 +28,16 @@ class MinipPage implements MinipPageType {
36
28
  public lifeBeforeShow = true;
37
29
 
38
30
  constructor(public growingIO: GrowingIOType) {
39
- this.queryOption = {};
31
+ this.queryOptions = {};
40
32
  this.configuredTitle = {};
41
33
  this.pageProps = {};
42
34
  }
43
35
 
44
- // 获取页面地址
36
+ /**
37
+ * 获取当前页面路径
38
+ * 优先级:页面堆栈路径 > 启动参数路径 > 最近 page 事件路径 > 最近 visit 事件路径
39
+ * 插件环境下无页面时返回插件 appId
40
+ */
45
41
  getPagePath = () => {
46
42
  const { minipInstance, inPlugin, dataStore, trackingId } = this.growingIO;
47
43
  const path = minipInstance.getCurrentPath();
@@ -61,7 +57,10 @@ class MinipPage implements MinipPageType {
61
57
  }
62
58
  };
63
59
 
64
- // 获取页面参数
60
+ /**
61
+ * 获取当前页面参数(query)
62
+ * 优先级:页面堆栈参数 > 生命周期参数 > 启动参数 > 最近 page 事件参数 > 最近 visit 事件参数
63
+ */
65
64
  getPageQuery = () => {
66
65
  const { minipInstance, dataStore, trackingId } = this.growingIO;
67
66
  const stackPage = minipInstance.getCurrentPage();
@@ -71,13 +70,13 @@ class MinipPage implements MinipPageType {
71
70
  const pageParams = stackPage.options ?? stackPage.$taroParams;
72
71
  // 堆栈中有页面信息,则使用堆栈中的页面参数
73
72
  if (!isEmpty(pageParams)) {
74
- // 删掉taro框架中自带的字段
75
- unset(pageParams, '$taroTimestamp');
76
- // 有页面解析的option直接取
73
+ // 删掉 taro 框架中自带的字段,删除圈选可能带进来的参数
74
+ unset(pageParams, ['$taroTimestamp', 'gdpCircleRoomCollectUrl']);
75
+ // 有页面解析的 option 直接取
77
76
  return this.qsQuery(pageParams);
78
- } else if (!isEmpty(this.queryOption[stackPath])) {
79
- // 没有option从hook获取的生命周期参数中取
80
- return this.qsQuery(this.queryOption[stackPath]);
77
+ } else if (!isEmpty(this.queryOptions[stackPath])) {
78
+ // 没有 option 从 hook 获取的生命周期参数中取
79
+ return this.qsQuery(this.queryOptions[stackPath]);
81
80
  } else if (stackPath === enterParams.path) {
82
81
  // 某些小程序虽然有页面堆栈,但是页面还没加载完,兜底取启动参数
83
82
  return this.qsQuery(
@@ -93,16 +92,20 @@ class MinipPage implements MinipPageType {
93
92
  getLaunchQuery(enterParams?.query, enterParams?.referrerInfo?.extraData)
94
93
  );
95
94
  } else {
96
- // 作为页面组件时component created生命周期中的埋点会取不到页面堆栈,所以拿最近的一个page事件中的页面信息做兜底
95
+ // 作为页面组件时 component created 生命周期中的埋点会取不到页面堆栈,所以拿最近的一个 page 事件中的页面信息做兜底
97
96
  return dataStore.lastPageEvent[trackingId]?.path
98
97
  ? dataStore.lastPageEvent[trackingId]?.query
99
- : // 没有最近的一个page事件说明在app初始化的生命周期中,有些框架可能会有异步处理逻辑导致事件触发比visit晚,则使用visit事件中的页面信息兜底
98
+ : // 没有最近的一个 page 事件说明在 app 初始化的生命周期中,有些框架可能会有异步处理逻辑导致事件触发比 visit 晚,则使用 visit 事件中的页面信息兜底
100
99
  dataStore.lastVisitEvent[trackingId]?.query;
101
100
  }
102
101
  };
103
102
 
104
- // 获取页面标题
105
- // 页面title (优先级:setNavigationBarTitle > data.gioPageTitle[不保证能取到] > config.js中设置的值 > tabBar配置)
103
+ /**
104
+ * 获取页面标题
105
+ * 优先级:setNavigationBarTitle > data.gioPageTitle > config.js 中设置的值 > tabBar 配置
106
+ * 插件环境下无页面时返回插件 appId
107
+ * @param trackingId 可选,追踪 id
108
+ */
106
109
  getPageTitle = (trackingId?: string) => {
107
110
  const { minipInstance, inPlugin, dataStore } = this.growingIO;
108
111
  const path = minipInstance.getCurrentPath();
@@ -122,14 +125,22 @@ class MinipPage implements MinipPageType {
122
125
  }
123
126
  };
124
127
 
125
- // 格式化页面参数
128
+ /**
129
+ * 格式化页面参数为 query string
130
+ * 会去除 wxShoppingListScene 字段
131
+ * @param query 页面参数对象
132
+ */
126
133
  qsQuery = (query = {}) => {
127
134
  const slimQuery = { ...query };
128
135
  unset(slimQuery, 'wxShoppingListScene');
129
136
  return qsStringify(slimQuery);
130
137
  };
131
138
 
132
- // 获取页面来源
139
+ /**
140
+ * 获取页面来源(referrer)
141
+ * 优先级:最近 page 事件路径 > 启动参数 referrerInfo.appId > scene 场景值
142
+ * @param trackingId 追踪 id
143
+ */
133
144
  getReferralPage = (trackingId: string) => {
134
145
  const {
135
146
  minipInstance,
@@ -142,69 +153,68 @@ class MinipPage implements MinipPageType {
142
153
  );
143
154
  };
144
155
 
145
- // 处理分享参数
146
- buildShareQuery(
147
- result: PageShareResult // 客户自定义的参数
148
- ): [string, string] {
149
- // 自定义path的地址参数截取(onShareAppMessage中的页面参数是拼在地址中的)
156
+ /**
157
+ * 处理分享参数,生成分享用的 path 和 query
158
+ * 优先级:result.query > result.path > 当前页面参数(去除 utm_ 开头参数)
159
+ * @param result PageShareResult 客户自定义的参数
160
+ * @returns [path, queryString]
161
+ */
162
+ buildShareQuery(result: PageShareResult): [string, string] {
163
+ // 自定义 path 的地址参数截取(onShareAppMessage 中的页面参数是拼在地址中的)
150
164
  const customSplit = splitPath(result.path ?? '');
151
165
 
152
- let path = this.getPagePath();
166
+ let path = result.path || this.getPagePath();
153
167
  let parsedQuery: any = {};
154
168
  let resultHasPath = has(result, 'path');
155
- // 优先使用自定义的地址
156
- if (resultHasPath) {
157
- path = head(customSplit);
169
+ let resultHasQuery = has(result, 'query');
170
+ // 如果定义了 query 字段则优先取 query 参数
171
+ if (resultHasQuery) {
172
+ parsedQuery = qsParse(result.query ?? '') || {};
173
+ } else if (resultHasPath) {
174
+ // 没有定义 query 字段则尝试取 path 中的参数
158
175
  parsedQuery = qsParse(last(customSplit)) || {};
159
- }
176
+ } else {
177
+ // 只有在没有自定义 path 和 query 的情况下,才使用页面堆栈中的默认参数并删除 utm 参数
178
+ const stackPage = this.growingIO.minipInstance.getCurrentPage();
179
+ // 这里不要直接用对象赋值,下面的 unset 会修改原对象,导致触发一次分享以后当前页面事件中的 utm 参数就会被删除掉
180
+ parsedQuery = {
181
+ ...(stackPage.options || this.queryOptions[stackPage.route] || {})
182
+ };
160
183
 
161
- // 自定义path中没有截取到query说明是在onShareAppMessage中没有参数,或是在onShareTimeline中需要取自定义query
162
- if (isEmpty(parsedQuery)) {
163
- parsedQuery = qsParse(result.query ?? '') || {};
184
+ // 删除 utm_ 参数
164
185
  compact(keys(parsedQuery)).forEach((key) => {
165
- // 删除从默认页面的query中原有的utm参数,防止带入到下一次分享导致渠道统计错误(如果客户质疑参数被删,让他们自己拼回去或者关followShare)
166
186
  if (key.toLowerCase().startsWith('utm_')) {
167
187
  unset(parsedQuery, key);
168
188
  }
169
189
  });
170
190
  }
171
191
 
172
- // 以上两种都是自定义的地址和参数,不做处理直接用,防止出现encode/decode的问题。
173
-
174
- // 自定义query没有值则使用当前页面默认参数
175
- // 如果path存在,但是不携带参数,此时不使用当前页面的默认参数
176
- if (!resultHasPath && isEmpty(parsedQuery)) {
177
- const stackPage = this.growingIO.minipInstance.getCurrentPage();
178
- parsedQuery =
179
- stackPage.options || this.queryOption[stackPage.route] || {};
180
- }
181
-
182
192
  return [path, qsStringify(parsedQuery)];
183
193
  }
184
194
 
185
- // 更新分享结果
186
- updateShareResult = (result: PageShareResult) => {
195
+ /**
196
+ * 更新分享结果,补全参数
197
+ * @param result PageShareResult 分享参数对象
198
+ * @param fillParams 是否补全参数,默认 true
199
+ * @returns 更新后的 result
200
+ */
201
+ updateShareResult = (result: PageShareResult, fillParams = true) => {
187
202
  const [path, queryString] = this.buildShareQuery(result);
188
- result.path = normalPath(path + (queryString ? `?${queryString}` : ''));
189
- result.query = queryString;
190
- return result;
191
- };
192
-
193
- // 更新分享转发事件的结果
194
- updateAppMessageResult = this.updateShareResult;
195
-
196
- // 更新分享朋友圈结果
197
- updateTimelineResult = this.updateShareResult;
198
-
199
- // 更新收藏结果
200
- updateAddFavoritesResult = (result: PageShareResult) => {
201
- const [path, queryString] = this.buildShareQuery(result);
202
- result.path = normalPath(path + (queryString ? `?${queryString}` : ''));
203
- result.query = queryString;
203
+ if (fillParams || has(result, 'path')) {
204
+ result.path = normalPath(path + (queryString ? `?${queryString}` : ''));
205
+ }
206
+ if (fillParams || has(result, 'query')) {
207
+ result.query = queryString;
208
+ }
204
209
  return result;
205
210
  };
206
211
 
207
- // 给事件合并页面属性
212
+ /**
213
+ * 给事件合并页面属性
214
+ * @param trackingId 追踪 id
215
+ * @param event 事件对象
216
+ * @returns 合并后的属性对象
217
+ */
208
218
  eventSetPageProps = (trackingId: string, event: EVENT) => {
209
219
  const pageProps = niceTry(
210
220
  () => this.pageProps[trackingId][this.getPagePath()]
@@ -67,7 +67,7 @@ class PageEffects {
67
67
  switch (event) {
68
68
  case pageListeners.pageLoad: {
69
69
  // 获取一次页面参数存起来,防止类似支付宝小程序只能通过生命周期获取页面参数或页面堆栈拿不到页面参数,做兜底
70
- currentPage.queryOption[path] =
70
+ currentPage.queryOptions[path] =
71
71
  get(page, 'options') ||
72
72
  get(page, '__displayReporter.query') ||
73
73
  get(page, '$page.query') ||
@@ -75,7 +75,10 @@ class PageEffects {
75
75
  get(page, '$taroParams') ||
76
76
  args[0] ||
77
77
  {};
78
- unset(currentPage.queryOption[path], '$taroTimestamp');
78
+ unset(currentPage.queryOptions[path], [
79
+ '$taroTimestamp',
80
+ 'gdpCircleRoomCollectUrl'
81
+ ]);
79
82
  break;
80
83
  }
81
84
  case pageListeners.pageShow: {
@@ -102,6 +105,7 @@ class PageEffects {
102
105
  case pageListeners.pageUnload: {
103
106
  break;
104
107
  }
108
+ case pageListeners.shareChat: // 小红书特有事件
105
109
  case pageListeners.shareApp: {
106
110
  toggleShareOut(true);
107
111
  trackersExecute((trackingId: string) => {
@@ -113,6 +117,9 @@ class PageEffects {
113
117
  break;
114
118
  }
115
119
  case pageListeners.shareTime: {
120
+ if (minipInstance.platform === 'xhsp') {
121
+ toggleShareOut(true);
122
+ }
116
123
  trackersExecute((trackingId: string) => {
117
124
  const { followShare } = getTrackerVds(trackingId);
118
125
  if (followShare) {
@@ -582,7 +582,7 @@ class DataStore implements DataStoreType {
582
582
  };
583
583
  event.attributes = limitObject({
584
584
  ...(event.attributes ?? {}),
585
- $from: originResult.from,
585
+ $from: originResult?.from,
586
586
  $target: originResult?.target?.id,
587
587
  $share_title: updateResult?.title,
588
588
  $share_path: head(uri),
@@ -18,7 +18,8 @@ import {
18
18
  getPlainPlatform,
19
19
  guid,
20
20
  limitObject,
21
- niceCallback
21
+ niceCallback,
22
+ qsParse
22
23
  } from '@@/utils/tools';
23
24
  import { ALLOW_SET_OPTIONS, DEFAULT_SETTINGS } from '@@/constants/config';
24
25
  import { DataStoreType, OriginOptions } from '@@/types/dataStore';
@@ -65,6 +66,7 @@ class GrowingIO implements GrowingIOType {
65
66
  // 当前主SDK的trackingId,用于区分事件归属。
66
67
  public trackingId: string;
67
68
  public subInstance: any;
69
+ private _identified: boolean;
68
70
  constructor() {
69
71
  this.utils = { ...glodash, ...tools, qs };
70
72
  this.emitter = mitt();
@@ -288,6 +290,8 @@ class GrowingIO implements GrowingIOType {
288
290
  this.userStore.setUid(asId);
289
291
  // 修改forceLogin配置项
290
292
  this.dataStore.setOption(this.trackingId, 'forceLogin', false);
293
+ // 标记当前已被identify过
294
+ this._identified = true;
291
295
  // 为已积压的请求使用assignmentId全部赋值deviceId
292
296
  this.dataStore.trackersExecute((tid: string) => {
293
297
  const hq = this.uploader.getHoardingQueue(tid);
@@ -295,6 +299,8 @@ class GrowingIO implements GrowingIOType {
295
299
  // 发送积压队列中的请求
296
300
  this.uploader.initiateRequest(tid, true);
297
301
  });
302
+ } else if (this._identified) {
303
+ callError('identify', !1, '请勿重复调用');
298
304
  } else {
299
305
  callError('identify', !1, 'forceLogin未开启');
300
306
  }
@@ -338,9 +344,14 @@ class GrowingIO implements GrowingIOType {
338
344
  userId = toString(userId).slice(0, 1000);
339
345
  userKey = toString(userKey).slice(0, 1000);
340
346
  this.userStore.setUserId(trackingId, userId);
347
+ const processedUserKey =
348
+ !isNil(userKey) && toString(userKey).length > 0
349
+ ? toString(userKey).slice(0, 1000)
350
+ : '';
351
+ this.userStore.setUserKey(trackingId, processedUserKey);
341
352
  const { idMapping } = this.dataStore.getTrackerVds(trackingId);
342
- if (idMapping) {
343
- this.userStore.setUserKey(trackingId, isNil(userKey) ? '' : userKey);
353
+ if (!idMapping && processedUserKey) {
354
+ consoleText('您设置了 userKey ,请初始化开启 idMapping!', 'warn');
344
355
  }
345
356
  // 切换userId时重置session
346
357
  if (prevId && prevId !== userId) {
@@ -606,6 +617,19 @@ class GrowingIO implements GrowingIOType {
606
617
  }
607
618
  });
608
619
  }
620
+ // 只有主实例有可能会带圈选的字段
621
+ if (trackingId === this.trackingId) {
622
+ // 小程序处于圈选状态时,把圈选上报地址带给web
623
+ const { circleServerUrl, circleOpen } =
624
+ this.plugins?.gioEventAutoTracking ?? {};
625
+ if (circleServerUrl && circleOpen) {
626
+ // infos.giocircleserverurl = encodeURIComponent(circleServerUrl);
627
+ const circleParam: any = qsParse(circleServerUrl.split('?')[1]);
628
+ if (circleParam.roomId) {
629
+ infos.giocircleroomid = circleParam.roomId;
630
+ }
631
+ }
632
+ }
609
633
  return qs.stringify(infos);
610
634
  };
611
635
  }
@@ -33,10 +33,10 @@ class Uploader implements UploaderType {
33
33
  this.retryLimit = 2;
34
34
  this.retryIds = {};
35
35
  this.requestingNum = 0;
36
- const { emitter, vdsConfig, plugins } = this.growingIO;
37
- emitter.on(
36
+ this.growingIO.emitter.on(
38
37
  EMIT_MSG.ON_SEND_BEFORE,
39
38
  ({ eventsQueue, requestData, trackingId }) => {
39
+ const { vdsConfig, plugins } = this.growingIO;
40
40
  // 核心逻辑中只发送主实例的事件
41
41
  if (trackingId === this.growingIO.trackingId) {
42
42
  if (vdsConfig?.tbConfig?.cloudAppId) {
@@ -223,11 +223,20 @@ class Uploader implements UploaderType {
223
223
  this.requestFailFn(o);
224
224
  });
225
225
  consoleText(`请求失败!${JSON.stringify(result)}`, 'error');
226
+ emitter.emit(EMIT_MSG.ON_SEND_ERROR, {
227
+ eventsQueue,
228
+ requestData,
229
+ trackingId
230
+ });
226
231
  }
227
232
  },
228
233
  complete: (args: any) => {
229
234
  this.requestingNum -= 1;
230
- emitter.emit(EMIT_MSG.ON_SEND_AFTER, { result: args, requestData });
235
+ emitter.emit(EMIT_MSG.ON_SEND_AFTER, {
236
+ result: args,
237
+ requestData,
238
+ trackingId
239
+ });
231
240
  this.initiateRequest(trackingId);
232
241
  }
233
242
  });
@@ -50,8 +50,7 @@ class UserStore implements UserStoreType {
50
50
  }
51
51
  // 存储中拿不到尝试设新值
52
52
  if (!this._uid) {
53
- this._uid = guid();
54
- minipInstance.setStorage(this._getUidKey(), this._uid);
53
+ this.setUid(guid());
55
54
  }
56
55
  return this._uid;
57
56
  };