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,543 @@
1
+ import {
2
+ DEFAULT_SETTINGS,
3
+ EXTRA_INFO_PARAMS,
4
+ IGNORE_PARAMS
5
+ } from '@@/constants/config';
6
+ import {
7
+ forEach,
8
+ has,
9
+ head,
10
+ isArray,
11
+ isBoolean,
12
+ isEmpty,
13
+ isFunction,
14
+ isNil,
15
+ isString,
16
+ keys,
17
+ toString,
18
+ typeOf,
19
+ unset
20
+ } from '@@/utils/glodash';
21
+ import {
22
+ batchSetStorageSync,
23
+ callError,
24
+ consoleText,
25
+ getAppInst,
26
+ getSubKeys,
27
+ guid,
28
+ niceTry
29
+ } from '@@/utils/tools';
30
+ import { DataStoreType, OriginOptions } from '@@/types/dataStore';
31
+ import { EventHooksType } from '@@/types/eventHooks';
32
+ import { GrowingIOType } from '@@/types/growingIO';
33
+ import EventContextBuilder from './eventContextBuilder';
34
+ import EventHooks from './eventHooks';
35
+
36
+ class DataStore implements DataStoreType {
37
+ readonly ALLOW_SETTING_KEYS = keys(DEFAULT_SETTINGS);
38
+ public gsidStorageName = '_growing_gsid_';
39
+ public originalSourceName = 'gdp_original_source';
40
+ public _gsid: number;
41
+ public _stid: number; // 用于判断每发送10个事件,往本地存储里同步一次gsid,减少存储的读写操作。
42
+ public eventHooks: EventHooksType;
43
+ // 来源场景值
44
+ public _scene: number | string;
45
+ // 上次来源场景值
46
+ public lastScene: number | string;
47
+ // 是否是分享弹窗导致的跳出页面
48
+ public shareOut: boolean;
49
+ // 上次小程序关闭时间
50
+ public lastCloseTime: number;
51
+ // 保活时间(两次打开小程序间隔算为一次访问的时间)
52
+ public keepAlive: number;
53
+ // 事件通用属性构建方法
54
+ public eventContextBuilder: (params?: any) => any;
55
+ // 上一个访问事件,保存最近的一次visit事件,存储一些设备系统信息,避免多次重新获取
56
+ public lastVisitEvent: any;
57
+ // 上一个页面事件,便于下一个Page事件获取数据
58
+ public lastPageEvent: any;
59
+ // 由客户设置的位置信息
60
+ public locationData: any;
61
+ // 埋点事件通用属性
62
+ public generalProps: any;
63
+ // 事件时长计时器
64
+ public trackTimers: any;
65
+ // 被拦截的事件
66
+ public interceptEvents: any;
67
+
68
+ constructor(public growingIO: GrowingIOType) {
69
+ this.initStorageInfo();
70
+ this.eventContextBuilder = new EventContextBuilder(this.growingIO).main;
71
+ this.shareOut = false;
72
+ this.lastVisitEvent = {};
73
+ this.lastPageEvent = {};
74
+ this.locationData = {};
75
+ this.generalProps = {};
76
+ this.trackTimers = {};
77
+ this.interceptEvents = [];
78
+ this.eventHooks = new EventHooks(this.growingIO);
79
+ // visit、page事件监听
80
+ this.growingIO.emitter.on('onComposeAfter', ({ composedEvent }) => {
81
+ if (composedEvent.eventType === 'VISIT' || composedEvent.t === 'vst') {
82
+ this.lastVisitEvent = composedEvent;
83
+ }
84
+ if (composedEvent.eventType === 'PAGE' || composedEvent.t === 'page') {
85
+ this.lastPageEvent = composedEvent;
86
+ }
87
+ });
88
+ // 小程序切后台把所有还在计时中的计时器记一次时长
89
+ if (isFunction(this.growingIO.minipInstance.minip?.onAppHide)) {
90
+ this.growingIO.minipInstance.minip.onAppHide(() => {
91
+ forEach(this.trackTimers, (tracker: any) => {
92
+ if (tracker.start) {
93
+ tracker.leng = tracker.leng + (+Date.now() - tracker.start);
94
+ }
95
+ });
96
+ });
97
+ }
98
+
99
+ // 小程序切前台把所有还在计时中的计时器重置开始时间
100
+ if (isFunction(this.growingIO.minipInstance.minip?.onAppShow)) {
101
+ this.growingIO.minipInstance.minip.onAppShow(() => {
102
+ forEach(this.trackTimers, (tracker: any) => {
103
+ if (tracker.start) {
104
+ tracker.start = +Date.now();
105
+ }
106
+ });
107
+ });
108
+ }
109
+ // 关闭数据采集时要移除所有的计时器
110
+ this.growingIO.emitter.on(
111
+ 'OPTION_CHANGE',
112
+ ({ optionName, optionValue }) => {
113
+ if (optionName === 'dataCollect' && optionValue === false) {
114
+ this.growingIO.clearTrackTimer();
115
+ }
116
+ }
117
+ );
118
+ }
119
+
120
+ // @ts-ignore
121
+ get gsid() {
122
+ const app = getAppInst();
123
+ const sKeys = getSubKeys(app);
124
+ return !isEmpty(sKeys) && app.gio_gsid ? app.gio_gsid : this._gsid;
125
+ }
126
+
127
+ // @ts-ignore
128
+ set gsid(v: any) {
129
+ const newV = Number.parseInt(v, 10);
130
+ if (Number.isNaN(newV) || v >= 1e9 || v < 1) {
131
+ this._gsid = 1;
132
+ } else {
133
+ this._gsid = v;
134
+ }
135
+ // 在全局app中存一份gsid给分包用
136
+ const app = getAppInst();
137
+ app.gio_gsid = this._gsid;
138
+ // _gsid每自增10次(即每发送10个事件)时,往本地存储里同步一次gsid
139
+ if (this._gsid - this._stid >= 10) {
140
+ this.saveStorageInfo();
141
+ }
142
+ }
143
+
144
+ get scene() {
145
+ return this._scene;
146
+ }
147
+
148
+ set scene(v: any) {
149
+ const prevScene = this._scene;
150
+ this._scene = v;
151
+ if (prevScene !== this._scene) {
152
+ this.growingIO.emitter.emit('SCENE_UPDATE', {
153
+ newScene: v,
154
+ oldScene: prevScene
155
+ });
156
+ }
157
+ }
158
+
159
+ // 初始化gsid
160
+ initStorageInfo = () => {
161
+ const { minipInstance } = this.growingIO;
162
+ const app = getAppInst();
163
+ // gsid
164
+ const gid = app.gio_gsid
165
+ ? app.gio_gsid
166
+ : Number.parseInt(minipInstance.getStorageSync(this.gsidStorageName), 10);
167
+ this._gsid = Number.isNaN(gid) || gid >= 1e9 || gid < 1 ? 1 : gid;
168
+ // 初始化时同步stid
169
+ this._stid = this._gsid;
170
+ if (gid !== this._gsid) {
171
+ minipInstance.setStorageSync(this.gsidStorageName, this._gsid);
172
+ }
173
+ };
174
+
175
+ // 退出小程序时在存储中同步gsid信息
176
+ saveStorageInfo = () => {
177
+ const { minipInstance } = this.growingIO;
178
+ this._stid = this._gsid;
179
+ batchSetStorageSync(minipInstance, [
180
+ { key: this.gsidStorageName, value: this._gsid }
181
+ ]);
182
+ };
183
+
184
+ // 保存初始来源信息
185
+ setOriginalSource = ({ path, query }) => {
186
+ const { minipInstance } = this.growingIO;
187
+ if (isNil(this.getOriginalSource())) {
188
+ const originalSource = { path, query, title: '' };
189
+ minipInstance.setStorageSync(
190
+ this.originalSourceName,
191
+ JSON.stringify(originalSource)
192
+ );
193
+ }
194
+ };
195
+
196
+ // 获取初始来源信息
197
+ getOriginalSource = () => {
198
+ const { minipInstance } = this.growingIO;
199
+ return niceTry(() =>
200
+ JSON.parse(minipInstance.getStorageSync(this.originalSourceName))
201
+ );
202
+ };
203
+
204
+ // 初始化全局配置
205
+ initOptions = (userOptions: OriginOptions) => {
206
+ const { projectId, dataSourceId, appId } = userOptions;
207
+ const vdsConfig: any = {};
208
+ // 只处理允许的配置项,之外用户的配置项无视
209
+ this.ALLOW_SETTING_KEYS.forEach((k) => {
210
+ // 配置项值不存在或类型不合法时置为默认值
211
+ const altp = DEFAULT_SETTINGS[k].type;
212
+ const invalid = isArray(altp)
213
+ ? !altp.includes(typeOf(userOptions[k]))
214
+ : typeOf(userOptions[k]) !== DEFAULT_SETTINGS[k].type;
215
+ if (invalid) {
216
+ vdsConfig[k] = DEFAULT_SETTINGS[k].default;
217
+ } else if (k === 'ignoreFields') {
218
+ vdsConfig.ignoreFields = userOptions.ignoreFields.filter((o) =>
219
+ IGNORE_PARAMS.includes(o)
220
+ );
221
+ } else if (k === 'extraParams') {
222
+ vdsConfig.extraParams = userOptions.extraParams.filter((o) =>
223
+ EXTRA_INFO_PARAMS.includes(o)
224
+ );
225
+ } else {
226
+ vdsConfig[k] = userOptions[k];
227
+ }
228
+ });
229
+ // 发送间隔不允许设置为小数,如果是小数则取整
230
+ vdsConfig.uploadInterval = Math.round(vdsConfig.uploadInterval);
231
+ // 设置发送间隔小于0或者大于2秒的都认为不合法,改回1秒
232
+ if (
233
+ Number.isNaN(vdsConfig.uploadInterval) ||
234
+ vdsConfig.uploadInterval < 0 ||
235
+ vdsConfig.uploadInterval > 2000
236
+ ) {
237
+ vdsConfig.uploadInterval = 1000;
238
+ }
239
+ // idMapping配置项兼容处理
240
+ if (vdsConfig.enableIdMapping && !vdsConfig.idMapping) {
241
+ vdsConfig.idMapping = true;
242
+ }
243
+ // 是否开启强制插件模式
244
+ if (vdsConfig.pluginMode) {
245
+ this.growingIO.inPlugin = true;
246
+ }
247
+ this.growingIO.vdsConfig = {
248
+ ...vdsConfig,
249
+ projectId,
250
+ dataSourceId,
251
+ appId,
252
+ // 补充性能默认值
253
+ performance: {
254
+ monitor: vdsConfig.performance?.monitor ?? true,
255
+ exception: vdsConfig.performance?.exception ?? true,
256
+ network: vdsConfig.performance?.network ?? false
257
+ }
258
+ };
259
+ this.keepAlive = vdsConfig.keepAlive;
260
+ // 初始化配置提示
261
+ if (!vdsConfig.dataCollect) {
262
+ consoleText('已关闭数据采集', 'info');
263
+ }
264
+ if (!vdsConfig.autotrack) {
265
+ consoleText('已关闭无埋点', 'info');
266
+ }
267
+ const { plugins, inPlugin, minipInstance } = this.growingIO;
268
+ const { uniVue, taro } = vdsConfig;
269
+ // 如果是使用全量版本时,当前小程序不是框架的,要允许原生的hook
270
+ if (!(uniVue || taro)) {
271
+ this.growingIO.platformConfig.canHook = true;
272
+ }
273
+ // 初始化核心钩子(重写全局)
274
+ if (!inPlugin || ['tbp', 'jdp'].includes(minipInstance.platform)) {
275
+ this.eventHooks.initEventHooks();
276
+ }
277
+ /** 第三方框架重写 */
278
+ // uniapp
279
+ if (uniVue) {
280
+ plugins?.gioUniAppAdapter?.main();
281
+ }
282
+ // taro
283
+ if (taro) {
284
+ plugins?.gioTaroAdapter?.main();
285
+ }
286
+ };
287
+
288
+ // 全局配置修改
289
+ setOption = (k: string, v: any) => {
290
+ const { vdsConfig, userStore, uploader, emitter } = this.growingIO;
291
+ // 检查 k
292
+ const validKey = isString(k) && this.ALLOW_SETTING_KEYS.includes(k);
293
+ const validValue = validKey && typeof v === DEFAULT_SETTINGS[k]?.type;
294
+ if (validKey && validValue) {
295
+ // 从关闭到打开dataCollect时补发visit和page
296
+ if (
297
+ k === 'dataCollect' &&
298
+ vdsConfig.dataCollect === false &&
299
+ v === true
300
+ ) {
301
+ let t = setTimeout(() => {
302
+ userStore.sessionId = '';
303
+ const { path, query, settedTitle } = this.eventHooks.currentPage;
304
+ // 重新获取页面title,防止切换配置前修改了title没取到
305
+ this.eventHooks.currentPage.title =
306
+ settedTitle[path] ||
307
+ this.growingIO.minipInstance.getPageTitle(
308
+ this.growingIO.minipInstance.getCurrentPage()
309
+ );
310
+ // visit取当前页面值
311
+ this.sendVisit({ path, query });
312
+ // 要重设一次页面时间,防止比visit早
313
+ this.eventHooks.currentPage.time = Date.now();
314
+ this.sendPage({ path, query });
315
+ clearTimeout(t);
316
+ t = null;
317
+ }, 0);
318
+ }
319
+ vdsConfig[k] = v;
320
+ // 修改serverUrl时要重新生成上报地址
321
+ if (k === 'serverUrl') {
322
+ uploader?.generateURL();
323
+ }
324
+ // 配置项有变更要全局广播
325
+ emitter.emit('OPTION_CHANGE', { optionName: k, optionValue: v });
326
+ return true;
327
+ } else {
328
+ callError(`setOption > ${k}`);
329
+ return false;
330
+ }
331
+ };
332
+
333
+ // 获取全局配置
334
+ getOption = (k?: string) => {
335
+ const { vdsConfig } = this.growingIO;
336
+ if (k && has(vdsConfig, toString(k))) {
337
+ return vdsConfig[toString(k)];
338
+ } else if (isNil(k)) {
339
+ return { ...vdsConfig };
340
+ } else {
341
+ callError(`getOption > ${k}`);
342
+ return undefined;
343
+ }
344
+ };
345
+
346
+ // 修改分享跳出判断值
347
+ toggleShareOut = (v?: boolean) => {
348
+ if (isBoolean(v)) {
349
+ this.shareOut = v;
350
+ } else {
351
+ this.shareOut = !this.shareOut;
352
+ }
353
+ };
354
+
355
+ // 手动调用visit事件的方法
356
+ sendVisit = (props?: any) => {
357
+ (this.eventHooks.appEffects as any).buildVisitEvent(
358
+ props ?? this.lastVisitEvent
359
+ );
360
+ // 等visit发完要重置页面时间,确保不会比visit早
361
+ this.eventHooks.currentPage.time = Date.now();
362
+ };
363
+
364
+ // 手动调用page事件的方法
365
+ sendPage = (props?: any) => {
366
+ (this.eventHooks.pageEffects as any).buildPageEvent(props);
367
+ };
368
+
369
+ // 事件的格式转换(同时移除无值的字段)
370
+ eventConverter = (event: any) => {
371
+ const { vdsConfig, dataStore, uploader } = this.growingIO;
372
+ // 开启数据采集时才会处理事件、累计全局计数并将合成的事件提交到请求队列
373
+ if (vdsConfig.dataCollect) {
374
+ //? 在4.0中用户属性事件和关闭事件不再带eventSequenceId字段
375
+ if (!['LOGIN_USER_ATTRIBUTES', 'APP_CLOSED'].includes(event.eventType)) {
376
+ //? 在4.0中event.eventSequenceId(esid)的值实际为全局的事件id,即值是globalSequenceId(gsid)为了保持向下兼容不做更名,会涉及存储
377
+ event.eventSequenceId = dataStore.gsid;
378
+ // 全局事件计数加1
379
+ this.growingIO.dataStore.gsid += 1;
380
+ }
381
+ const convertedEvent: any = {};
382
+ forEach(event, (v: any, k: string) => {
383
+ /**
384
+ * 字段的转换
385
+ */
386
+ // 无埋点element的转换
387
+ if (k === 'element') {
388
+ const target: object = head(v) ?? {};
389
+ forEach(target, (ev: any, ek: string) => {
390
+ // 判断属性是否存在,同时忽略无值属性(放入convertedEvent中)
391
+ if (!isEmpty(ev) || ev === 0) {
392
+ convertedEvent[ek] = ev;
393
+ }
394
+ });
395
+ } else if (!isEmpty(v) || v === 0) {
396
+ // 判断属性是否存在,同时忽略无值属性
397
+ convertedEvent[k] = v;
398
+ }
399
+ });
400
+ this.growingIO.emitter.emit('onComposeAfter', {
401
+ composedEvent: convertedEvent
402
+ });
403
+ // 提交请求队列
404
+ uploader.commitRequest({ ...convertedEvent, requestId: guid() });
405
+ }
406
+ };
407
+
408
+ // 事件拦截器(有的通用维度字段需要异步获取,为了防止事件在通用维度还没返回之前就发出去)一般只有最开始的个别事件会被拦住
409
+ eventInterceptor = (event: any) => {
410
+ const { systemInfo, network } = this.growingIO.minipInstance;
411
+ if (isEmpty(systemInfo) || isEmpty(network)) {
412
+ // 没有通用维度字段,直接拦截存下来
413
+ this.interceptEvents.push(event);
414
+ } else if (!isEmpty(this.interceptEvents)) {
415
+ // 有通用维度字段了,且有被拦截的事件,放一起重新添加通用维度字段再提交转换
416
+ [...this.interceptEvents, event].forEach((e: any) => {
417
+ // 有的事件的path和query不能再用页面的值,所以直接使用事件中已有的值
418
+ const ne = {
419
+ ...e,
420
+ ...this.eventContextBuilder({
421
+ path: e.path,
422
+ query: e.query,
423
+ // page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
424
+ timestamp: e.timestamp
425
+ })
426
+ };
427
+ this.eventConverter(ne);
428
+ });
429
+ this.interceptEvents = [];
430
+ } else {
431
+ // 有通用维度字段了,也没有有被拦截的事件,直接提交转换
432
+ this.eventConverter(event);
433
+ }
434
+ };
435
+
436
+ // 系统信息异步获取完后对拦截队列进行检查,防止事件被卡住
437
+ eventReleaseInspector = () => {
438
+ const {
439
+ minipInstance: { systemInfo, network }
440
+ } = this.growingIO;
441
+ if (systemInfo && network && !isEmpty(this.interceptEvents)) {
442
+ [...this.interceptEvents].forEach((e: any) => {
443
+ // 有的事件的path和query不能再用页面的值,所以直接使用事件中已有的值
444
+ const ne = {
445
+ ...e,
446
+ ...this.eventContextBuilder({
447
+ path: e.path,
448
+ query: e.query,
449
+ // page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
450
+ timestamp: e.timestamp
451
+ })
452
+ };
453
+ this.eventConverter(ne);
454
+ });
455
+ this.interceptEvents = [];
456
+ }
457
+ };
458
+
459
+ // 构建应用/页面转发分享事件
460
+ buildAppMessageEvent = (args: any) => {
461
+ const originResult = args[0];
462
+ let updateResult;
463
+ if (args.length >= 2) {
464
+ updateResult = args[1];
465
+ } else if (args.length === 1) {
466
+ updateResult = originResult;
467
+ }
468
+ const {
469
+ dataStore: { eventContextBuilder, eventInterceptor }
470
+ } = this.growingIO;
471
+ const uri = (updateResult?.path || '').split('?');
472
+ const event = {
473
+ eventType: 'CUSTOM',
474
+ eventName: '$mp_on_share',
475
+ attributes: {
476
+ $from: originResult.from,
477
+ $target: originResult?.target?.id,
478
+ $share_title: updateResult?.title,
479
+ $share_path: head(uri),
480
+ $share_query: uri[1],
481
+ ...updateResult?.attributes
482
+ },
483
+ ...eventContextBuilder()
484
+ };
485
+ eventInterceptor(event);
486
+ };
487
+
488
+ // 构建朋友圈分享事件
489
+ buildTimelineEvent = (args: any) => {
490
+ const originResult = args[0];
491
+ let updateResult;
492
+ if (args.length >= 2) {
493
+ updateResult = args[1];
494
+ } else if (args.length === 1) {
495
+ updateResult = originResult;
496
+ }
497
+ const {
498
+ dataStore: { eventContextBuilder, eventInterceptor }
499
+ } = this.growingIO;
500
+ const uri = (updateResult?.path || '').split('?');
501
+ const event = {
502
+ eventType: 'CUSTOM',
503
+ eventName: '$mp_share_timeline',
504
+ attributes: {
505
+ $target: originResult?.target?.id,
506
+ $share_title: updateResult?.title,
507
+ $share_path: head(uri),
508
+ $share_query: uri[1],
509
+ ...updateResult?.attributes
510
+ },
511
+ ...eventContextBuilder()
512
+ };
513
+ eventInterceptor(event);
514
+ };
515
+
516
+ // 构建添加收藏事件
517
+ buildAddFavorites = (args: any) => {
518
+ const originResult = args[0];
519
+ let updateResult;
520
+ if (args.length >= 2) {
521
+ updateResult = args[1];
522
+ } else if (args.length === 1) {
523
+ updateResult = originResult;
524
+ }
525
+ const {
526
+ dataStore: { eventContextBuilder, eventInterceptor }
527
+ } = this.growingIO;
528
+ const uri = (updateResult?.path || '').split('?');
529
+ const event = {
530
+ eventType: 'CUSTOM',
531
+ eventName: '$mp_add_favorites',
532
+ attributes: {
533
+ $share_title: updateResult?.title,
534
+ $share_path: head(uri),
535
+ $share_query: uri[1]
536
+ },
537
+ ...eventContextBuilder()
538
+ };
539
+ eventInterceptor(event);
540
+ };
541
+ }
542
+
543
+ export default DataStore;