gio-miniprogram-sdk 4.1.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/publish.yml +2 -0
- package/dist/alipay.js +1 -1
- package/dist/baidu.js +1 -1
- package/dist/bytedance.js +1 -1
- package/dist/jingdong.js +1 -1
- package/dist/kuaishou.js +1 -1
- package/dist/plugins/gioABTest.js +1 -1
- package/dist/plugins/gioCompress.js +1 -1
- package/dist/plugins/gioEventAutoTracking.js +1 -1
- package/dist/plugins/gioImpressionTracking.js +1 -1
- package/dist/plugins/gioMultipleInstances.js +1 -1
- package/dist/qq.js +1 -1
- package/dist/quickapp.js +1 -1
- package/dist/taobao.js +1 -1
- package/dist/taro.js +1 -1
- package/dist/uniapp.js +1 -1
- package/dist/wechat.js +1 -1
- package/package.json +1 -1
- package/rollup.config.js +1 -1
- package/rollup.plugins.config.js +6 -1
- package/src/adapters/gioTaobaoAdapter.ts +7 -3
- package/src/adapters/gioTaroAdapter.ts +18 -10
- package/src/adapters/gioUniAppAdapter.ts +3 -32
- package/src/constants/config.ts +1 -0
- package/src/core/dataStore/eventContextBuilder.ts +27 -13
- package/src/core/dataStore/eventHooks/appEffects.ts +62 -76
- package/src/core/dataStore/eventHooks/index.ts +45 -24
- package/src/core/dataStore/eventHooks/minipPage.ts +129 -30
- package/src/core/dataStore/eventHooks/pageEffects.ts +25 -53
- package/src/core/dataStore/index.ts +67 -74
- package/src/core/growingIO.ts +93 -45
- package/src/index.ts +12 -12
- package/src/minipInstance/base.ts +53 -26
- package/src/minipInstance/my.ts +5 -0
- package/src/minipInstance/tb.ts +5 -0
- package/src/platformConfig/base.ts +0 -1
- package/src/plugins/gioABTest.ts +15 -8
- package/src/plugins/gioCompress.ts +2 -0
- package/src/plugins/gioEventAutoTracking.ts +20 -3
- package/src/plugins/gioImpressionTracking.ts +13 -2
- package/src/plugins/gioMultipleInstances.ts +14 -3
- package/src/types/dataStore.ts +5 -1
- package/src/types/eventHooks.ts +13 -8
- package/src/types/growingIO.ts +52 -33
- package/src/utils/tools.ts +26 -3
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import { get, isEmpty, isFunction, unset } from '@@/utils/glodash';
|
|
2
2
|
import { GrowingIOType } from '@@/types/growingIO';
|
|
3
|
-
import { niceTry } from '@@/utils/tools';
|
|
4
3
|
import { PageHookLifeCircle } from '@@/types/eventHooks';
|
|
5
4
|
import EMIT_MSG from '@@/constants/emitMsg';
|
|
6
5
|
|
|
7
6
|
class PageEffects {
|
|
8
7
|
public buildTabClickEvent: (tabItem: any) => void;
|
|
9
8
|
private prevEvent: any;
|
|
10
|
-
private argQuery: any;
|
|
11
9
|
constructor(public growingIO: GrowingIOType) {
|
|
12
10
|
this.prevEvent = {};
|
|
13
|
-
this.argQuery = {};
|
|
14
11
|
}
|
|
15
12
|
|
|
16
13
|
main = (page: any, event: PageHookLifeCircle, args: any) => {
|
|
@@ -23,15 +20,15 @@ class PageEffects {
|
|
|
23
20
|
platformConfig,
|
|
24
21
|
dataStore: {
|
|
25
22
|
getTrackerVds,
|
|
23
|
+
getOriginalSource,
|
|
24
|
+
setOriginalSource,
|
|
26
25
|
trackersExecute,
|
|
27
|
-
shareOut,
|
|
28
26
|
eventHooks,
|
|
29
27
|
toggleShareOut,
|
|
30
28
|
buildAppMessageEvent,
|
|
31
29
|
buildTimelineEvent,
|
|
32
30
|
buildAddFavorites
|
|
33
|
-
}
|
|
34
|
-
inPlugin
|
|
31
|
+
}
|
|
35
32
|
}: GrowingIOType = this.growingIO;
|
|
36
33
|
const { currentPage } = eventHooks;
|
|
37
34
|
if (
|
|
@@ -69,43 +66,34 @@ class PageEffects {
|
|
|
69
66
|
currentPage.currentLifecycle = event;
|
|
70
67
|
switch (event) {
|
|
71
68
|
case pageListeners.pageLoad: {
|
|
72
|
-
|
|
69
|
+
// 获取一次页面参数存起来,防止类似支付宝小程序只能通过生命周期获取页面参数或页面堆栈拿不到页面参数,做兜底
|
|
70
|
+
currentPage.queryOption[path] =
|
|
73
71
|
get(page, 'options') ||
|
|
74
72
|
get(page, '__displayReporter.query') ||
|
|
75
73
|
get(page, '$page.query') ||
|
|
76
74
|
get(page, '$wx.__displayReporter.query') ||
|
|
75
|
+
get(page, '$taroParams') ||
|
|
77
76
|
args[0] ||
|
|
78
77
|
{};
|
|
79
|
-
unset(
|
|
80
|
-
currentPage.parsePage(page, this.argQuery[path]);
|
|
78
|
+
unset(currentPage.queryOption[path], '$taroTimestamp');
|
|
81
79
|
break;
|
|
82
80
|
}
|
|
83
81
|
case pageListeners.pageShow: {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
82
|
+
trackersExecute((trackingId: string) => {
|
|
83
|
+
// 检查originalSource内容是否已经被消费,如果没有被消费是同一个页面,说明visit还没被发出去,要更新title
|
|
84
|
+
const originalSource = getOriginalSource(trackingId);
|
|
85
|
+
if (!isEmpty(originalSource) && originalSource.path === path) {
|
|
86
|
+
setOriginalSource(trackingId, {
|
|
87
|
+
...originalSource,
|
|
88
|
+
title: currentPage.getPageTitle()
|
|
89
|
+
});
|
|
90
90
|
}
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
} else if (!shareOut || !eventHooks.currentPage.time) {
|
|
98
|
-
// 不是因为分享切出再返回的onshow(视为第一次进入改页面)和切出去以后因为超时或者进入的场景值不一致时(会在appshow清掉页面时间),发page
|
|
99
|
-
currentPage.parsePage(page, this.argQuery[path]);
|
|
100
|
-
// 超时进入页面时前后path一致parsePage方法不会重置页面时间,可能会没有值,所以要补充重设一次
|
|
101
|
-
eventHooks.currentPage.time = Date.now();
|
|
102
|
-
trackersExecute((trackingId: string) => {
|
|
103
|
-
const { trackPage } = getTrackerVds(trackingId);
|
|
104
|
-
if (trackPage) {
|
|
105
|
-
this.buildPageEvent(trackingId);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
}
|
|
91
|
+
// 发page事件
|
|
92
|
+
const { trackPage } = getTrackerVds(trackingId);
|
|
93
|
+
if (trackPage) {
|
|
94
|
+
this.buildPageEvent(trackingId);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
109
97
|
// 分享标记置为false
|
|
110
98
|
toggleShareOut(false);
|
|
111
99
|
break;
|
|
@@ -157,12 +145,6 @@ class PageEffects {
|
|
|
157
145
|
default:
|
|
158
146
|
break;
|
|
159
147
|
}
|
|
160
|
-
// 页面销毁移除当前页面的属性
|
|
161
|
-
if (event === pageListeners.pageUnload) {
|
|
162
|
-
trackersExecute((trackingId: string) => {
|
|
163
|
-
currentPage.pageProps[trackingId] = undefined;
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
148
|
};
|
|
167
149
|
|
|
168
150
|
// 构建页面访问事件
|
|
@@ -172,29 +154,19 @@ class PageEffects {
|
|
|
172
154
|
eventContextBuilder,
|
|
173
155
|
eventInterceptor,
|
|
174
156
|
eventHooks: { currentPage }
|
|
175
|
-
}
|
|
176
|
-
minipInstance
|
|
157
|
+
}
|
|
177
158
|
} = this.growingIO;
|
|
178
159
|
const event = {
|
|
179
160
|
eventType: 'PAGE',
|
|
180
161
|
referralPage: currentPage.getReferralPage(trackingId),
|
|
181
|
-
...eventContextBuilder(trackingId)
|
|
182
|
-
// page事件要单独设一个title以覆盖eventContextBuilder中的lastPage的title错误值
|
|
183
|
-
title:
|
|
184
|
-
currentPage?.title ||
|
|
185
|
-
minipInstance.getPageTitle(minipInstance.getCurrentPage()),
|
|
186
|
-
timestamp: currentPage.time
|
|
162
|
+
...eventContextBuilder(trackingId)
|
|
187
163
|
};
|
|
164
|
+
// 合并页面属性
|
|
165
|
+
event.attributes = currentPage.eventSetPageProps(trackingId, event);
|
|
188
166
|
// 传入参数生成的page事件取值为传入参数
|
|
189
167
|
if (!isEmpty(props) && props.title) {
|
|
190
168
|
event.title = props.title;
|
|
191
169
|
}
|
|
192
|
-
// 添加页面属性
|
|
193
|
-
const pageProps = niceTry(() => currentPage.pageProps[trackingId]);
|
|
194
|
-
if (!isEmpty(pageProps)) {
|
|
195
|
-
event.attributes = pageProps;
|
|
196
|
-
currentPage.pageProps[trackingId] = undefined;
|
|
197
|
-
}
|
|
198
170
|
eventInterceptor(event);
|
|
199
171
|
};
|
|
200
172
|
}
|
|
@@ -13,7 +13,6 @@ import {
|
|
|
13
13
|
isBoolean,
|
|
14
14
|
isEmpty,
|
|
15
15
|
isFunction,
|
|
16
|
-
isNil,
|
|
17
16
|
isString,
|
|
18
17
|
keys,
|
|
19
18
|
typeOf,
|
|
@@ -25,6 +24,7 @@ import {
|
|
|
25
24
|
consoleText,
|
|
26
25
|
getGlobal,
|
|
27
26
|
guid,
|
|
27
|
+
limitObject,
|
|
28
28
|
niceTry
|
|
29
29
|
} from '@@/utils/tools';
|
|
30
30
|
import {
|
|
@@ -93,7 +93,7 @@ class DataStore implements DataStoreType {
|
|
|
93
93
|
EMIT_MSG.ON_COMMIT_REQUEST,
|
|
94
94
|
({ eventData: event, trackingId }) => {
|
|
95
95
|
if (event.eventType === 'VISIT') {
|
|
96
|
-
this.lastVisitEvent = event;
|
|
96
|
+
this.lastVisitEvent[trackingId] = event;
|
|
97
97
|
}
|
|
98
98
|
if (event.eventType === 'PAGE') {
|
|
99
99
|
this.lastPageEvent[trackingId] = event;
|
|
@@ -218,26 +218,25 @@ class DataStore implements DataStoreType {
|
|
|
218
218
|
};
|
|
219
219
|
|
|
220
220
|
// 保存初始来源信息
|
|
221
|
-
setOriginalSource = (trackingId: string,
|
|
221
|
+
setOriginalSource = (trackingId: string, origins: any) => {
|
|
222
222
|
const { minipInstance } = this.growingIO;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
JSON.stringify(originalSource)
|
|
228
|
-
);
|
|
229
|
-
}
|
|
223
|
+
minipInstance.setStorageSync(
|
|
224
|
+
this.getStorageKey(trackingId, 'originalSource'),
|
|
225
|
+
JSON.stringify(origins)
|
|
226
|
+
);
|
|
230
227
|
};
|
|
231
228
|
|
|
232
229
|
// 获取初始来源信息
|
|
233
230
|
getOriginalSource = (trackingId: string) => {
|
|
234
231
|
const { minipInstance } = this.growingIO;
|
|
235
|
-
return
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
232
|
+
return (
|
|
233
|
+
niceTry(() =>
|
|
234
|
+
JSON.parse(
|
|
235
|
+
minipInstance.getStorageSync(
|
|
236
|
+
this.getStorageKey(trackingId, 'originalSource')
|
|
237
|
+
)
|
|
239
238
|
)
|
|
240
|
-
)
|
|
239
|
+
) ?? {}
|
|
241
240
|
);
|
|
242
241
|
};
|
|
243
242
|
|
|
@@ -262,12 +261,14 @@ class DataStore implements DataStoreType {
|
|
|
262
261
|
const { platformConfig, inPlugin, minipInstance, plugins } = this.growingIO;
|
|
263
262
|
const { uniVue, taro } = vdsConfig;
|
|
264
263
|
// 如果是使用全量版本时,当前小程序不是框架的,要允许原生的hook
|
|
265
|
-
if (!(uniVue || taro)) {
|
|
264
|
+
if (!(uniVue || taro || minipInstance.platform === 'quickapp')) {
|
|
266
265
|
platformConfig.canHook = true;
|
|
267
266
|
}
|
|
268
267
|
// 初始化核心钩子(重写全局)
|
|
269
268
|
if (!inPlugin || ['tbp', 'jdp'].includes(minipInstance.platform)) {
|
|
270
269
|
this.eventHooks.initEventHooks();
|
|
270
|
+
} else {
|
|
271
|
+
this.eventHooks.initOriginalValue();
|
|
271
272
|
}
|
|
272
273
|
/** 第三方框架重写 */
|
|
273
274
|
// uniapp
|
|
@@ -364,19 +365,11 @@ class DataStore implements DataStoreType {
|
|
|
364
365
|
this.updateVdsConfig(trackingId, { ...trakerVds, [k]: v });
|
|
365
366
|
// 从关闭到打开dataCollect时补发visit和page
|
|
366
367
|
if (k === 'dataCollect' && prevConfig.dataCollect !== v && v) {
|
|
368
|
+
// 更新session
|
|
367
369
|
userStore.setSessionId(trackingId);
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
this.
|
|
371
|
-
settedTitle[path] ||
|
|
372
|
-
this.growingIO.minipInstance.getPageTitle(
|
|
373
|
-
this.growingIO.minipInstance.getCurrentPage()
|
|
374
|
-
);
|
|
375
|
-
// visit取当前页面值
|
|
376
|
-
this.sendVisit(trackingId, { path, query });
|
|
377
|
-
// 要重设一次页面时间,防止比visit早
|
|
378
|
-
this.eventHooks.currentPage.time = Date.now();
|
|
379
|
-
this.sendPage(trackingId, { path, query });
|
|
370
|
+
// 重发visit/page
|
|
371
|
+
this.sendVisit(trackingId);
|
|
372
|
+
this.sendPage(trackingId);
|
|
380
373
|
}
|
|
381
374
|
// 配置项有变更要全局广播
|
|
382
375
|
emitter.emit(EMIT_MSG.OPTION_CHANGE, { optionName: k, optionValue: v });
|
|
@@ -430,10 +423,7 @@ class DataStore implements DataStoreType {
|
|
|
430
423
|
|
|
431
424
|
// 手动调用visit事件的方法
|
|
432
425
|
sendVisit = (trackingId: string, props?: any) => {
|
|
433
|
-
(this.eventHooks.appEffects as any).buildVisitEvent(
|
|
434
|
-
trackingId,
|
|
435
|
-
props ?? this.lastVisitEvent
|
|
436
|
-
);
|
|
426
|
+
(this.eventHooks.appEffects as any).buildVisitEvent(trackingId, props);
|
|
437
427
|
};
|
|
438
428
|
|
|
439
429
|
// 手动调用page事件的方法
|
|
@@ -481,6 +471,26 @@ class DataStore implements DataStoreType {
|
|
|
481
471
|
}
|
|
482
472
|
};
|
|
483
473
|
|
|
474
|
+
// 事件重组
|
|
475
|
+
eventRefactor = (e: any) => {
|
|
476
|
+
// 有的事件的path和query不能再用页面的值,所以直接使用事件中已有的值
|
|
477
|
+
const ne = {
|
|
478
|
+
...e,
|
|
479
|
+
...this.eventContextBuilder(e.trackingId, {
|
|
480
|
+
path: e.path,
|
|
481
|
+
query: e.query,
|
|
482
|
+
// page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
|
|
483
|
+
timestamp: e.timestamp
|
|
484
|
+
})
|
|
485
|
+
};
|
|
486
|
+
// 防止事件原有的属性被通用属性直接覆盖
|
|
487
|
+
ne.attributes = {
|
|
488
|
+
...(ne.attributes ?? {}),
|
|
489
|
+
...(e.attributes ?? {})
|
|
490
|
+
};
|
|
491
|
+
return ne;
|
|
492
|
+
};
|
|
493
|
+
|
|
484
494
|
// 事件拦截器(有的通用维度字段需要异步获取,为了防止事件在通用维度还没返回之前就发出去)一般只有最开始的个别事件会被拦住
|
|
485
495
|
eventInterceptor = (event: any) => {
|
|
486
496
|
const { systemInfo, network } = this.growingIO.minipInstance;
|
|
@@ -490,17 +500,7 @@ class DataStore implements DataStoreType {
|
|
|
490
500
|
} else if (!isEmpty(this.interceptEvents)) {
|
|
491
501
|
// 有通用维度字段了,且有被拦截的事件,放一起重新添加通用维度字段再提交转换
|
|
492
502
|
[...this.interceptEvents, event].forEach((e: any) => {
|
|
493
|
-
|
|
494
|
-
const ne = {
|
|
495
|
-
...e,
|
|
496
|
-
...this.eventContextBuilder(event.trackingId, {
|
|
497
|
-
path: e.path,
|
|
498
|
-
query: e.query,
|
|
499
|
-
// page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
|
|
500
|
-
timestamp: e.timestamp
|
|
501
|
-
})
|
|
502
|
-
};
|
|
503
|
-
this.eventConverter(ne);
|
|
503
|
+
this.eventConverter(this.eventRefactor(e));
|
|
504
504
|
});
|
|
505
505
|
this.interceptEvents = [];
|
|
506
506
|
} else {
|
|
@@ -516,17 +516,7 @@ class DataStore implements DataStoreType {
|
|
|
516
516
|
} = this.growingIO;
|
|
517
517
|
if (systemInfo && network && !isEmpty(this.interceptEvents)) {
|
|
518
518
|
[...this.interceptEvents].forEach((e: any) => {
|
|
519
|
-
|
|
520
|
-
const ne = {
|
|
521
|
-
...e,
|
|
522
|
-
...this.eventContextBuilder(e.trackingId, {
|
|
523
|
-
path: e.path,
|
|
524
|
-
query: e.query,
|
|
525
|
-
// page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
|
|
526
|
-
timestamp: e.timestamp
|
|
527
|
-
})
|
|
528
|
-
};
|
|
529
|
-
this.eventConverter(ne);
|
|
519
|
+
this.eventConverter(this.eventRefactor(e));
|
|
530
520
|
});
|
|
531
521
|
this.interceptEvents = [];
|
|
532
522
|
}
|
|
@@ -548,16 +538,17 @@ class DataStore implements DataStoreType {
|
|
|
548
538
|
const event = {
|
|
549
539
|
eventType: 'CUSTOM',
|
|
550
540
|
eventName: '$mp_on_share',
|
|
551
|
-
attributes: {
|
|
552
|
-
$from: originResult.from,
|
|
553
|
-
$target: originResult?.target?.id,
|
|
554
|
-
$share_title: updateResult?.title,
|
|
555
|
-
$share_path: head(uri),
|
|
556
|
-
$share_query: uri[1],
|
|
557
|
-
...updateResult?.attributes
|
|
558
|
-
},
|
|
559
541
|
...eventContextBuilder(trackingId)
|
|
560
542
|
};
|
|
543
|
+
event.attributes = limitObject({
|
|
544
|
+
...(event.attributes ?? {}),
|
|
545
|
+
$from: originResult.from,
|
|
546
|
+
$target: originResult?.target?.id,
|
|
547
|
+
$share_title: updateResult?.title,
|
|
548
|
+
$share_path: head(uri),
|
|
549
|
+
$share_query: uri[1],
|
|
550
|
+
...updateResult?.attributes
|
|
551
|
+
});
|
|
561
552
|
eventInterceptor(event);
|
|
562
553
|
};
|
|
563
554
|
|
|
@@ -577,15 +568,16 @@ class DataStore implements DataStoreType {
|
|
|
577
568
|
const event = {
|
|
578
569
|
eventType: 'CUSTOM',
|
|
579
570
|
eventName: '$mp_share_timeline',
|
|
580
|
-
attributes: {
|
|
581
|
-
$target: originResult?.target?.id,
|
|
582
|
-
$share_title: updateResult?.title,
|
|
583
|
-
$share_path: head(uri),
|
|
584
|
-
$share_query: uri[1],
|
|
585
|
-
...updateResult?.attributes
|
|
586
|
-
},
|
|
587
571
|
...eventContextBuilder(trackingId)
|
|
588
572
|
};
|
|
573
|
+
event.attributes = limitObject({
|
|
574
|
+
...(event.attributes ?? {}),
|
|
575
|
+
$target: originResult?.target?.id,
|
|
576
|
+
$share_title: updateResult?.title,
|
|
577
|
+
$share_path: head(uri),
|
|
578
|
+
$share_query: uri[1],
|
|
579
|
+
...updateResult?.attributes
|
|
580
|
+
});
|
|
589
581
|
eventInterceptor(event);
|
|
590
582
|
};
|
|
591
583
|
|
|
@@ -605,13 +597,14 @@ class DataStore implements DataStoreType {
|
|
|
605
597
|
const event = {
|
|
606
598
|
eventType: 'CUSTOM',
|
|
607
599
|
eventName: '$mp_add_favorites',
|
|
608
|
-
attributes: {
|
|
609
|
-
$share_title: updateResult?.title,
|
|
610
|
-
$share_path: head(uri),
|
|
611
|
-
$share_query: uri[1]
|
|
612
|
-
},
|
|
613
600
|
...eventContextBuilder(trackingId)
|
|
614
601
|
};
|
|
602
|
+
event.attributes = limitObject({
|
|
603
|
+
...(event.attributes ?? {}),
|
|
604
|
+
$share_title: updateResult?.title,
|
|
605
|
+
$share_path: head(uri),
|
|
606
|
+
$share_query: uri[1]
|
|
607
|
+
});
|
|
615
608
|
eventInterceptor(event);
|
|
616
609
|
};
|
|
617
610
|
|
package/src/core/growingIO.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
forEach,
|
|
2
3
|
isArray,
|
|
3
4
|
isEmpty,
|
|
4
5
|
isFunction,
|
|
@@ -205,15 +206,55 @@ class GrowingIO implements GrowingIOType {
|
|
|
205
206
|
|
|
206
207
|
// 设置页面属性
|
|
207
208
|
setPageAttributes = (trackingId: string, properties: any) => {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
209
|
+
if (isObject(properties) && !isEmpty(properties)) {
|
|
210
|
+
const { currentPage } = this.dataStore.eventHooks;
|
|
211
|
+
const path = currentPage.getPagePath();
|
|
212
|
+
if (isEmpty(currentPage.pageProps[trackingId])) {
|
|
213
|
+
currentPage.pageProps[trackingId] = {};
|
|
214
|
+
}
|
|
215
|
+
if (isEmpty(currentPage.pageProps[trackingId][path])) {
|
|
216
|
+
currentPage.pageProps[trackingId][path] = {};
|
|
217
|
+
}
|
|
218
|
+
// 结果合并,动态属性不作处理
|
|
219
|
+
if (!isEmpty(properties)) {
|
|
220
|
+
forEach(properties, (v, k) => {
|
|
221
|
+
if (
|
|
222
|
+
!isFunction(currentPage.pageProps[trackingId][path][k]) ||
|
|
223
|
+
isFunction(v)
|
|
224
|
+
) {
|
|
225
|
+
currentPage.pageProps[trackingId][path][k] = v;
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
return true;
|
|
230
|
+
} else {
|
|
231
|
+
callError('setPageAttributes');
|
|
232
|
+
return false;
|
|
211
233
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
// 清空已设置的页面属性
|
|
237
|
+
clearPageAttributes = (
|
|
238
|
+
trackingId: string,
|
|
239
|
+
properties: string[] | undefined
|
|
240
|
+
) => {
|
|
241
|
+
try {
|
|
242
|
+
if (
|
|
243
|
+
!isEmpty(this.dataStore.eventHooks.currentPage.pageProps[trackingId])
|
|
244
|
+
) {
|
|
245
|
+
const { currentPage } = this.dataStore.eventHooks;
|
|
246
|
+
const path = currentPage.getPagePath();
|
|
247
|
+
if (isArray(properties) && !isEmpty(properties)) {
|
|
248
|
+
properties.forEach((propName: string) => {
|
|
249
|
+
unset(currentPage.pageProps[trackingId][path], propName);
|
|
250
|
+
});
|
|
251
|
+
} else {
|
|
252
|
+
currentPage.pageProps[trackingId][path] = {};
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
} catch (error) {
|
|
256
|
+
callError('clearPageAttributes');
|
|
257
|
+
return false;
|
|
217
258
|
}
|
|
218
259
|
};
|
|
219
260
|
|
|
@@ -261,20 +302,23 @@ class GrowingIO implements GrowingIOType {
|
|
|
261
302
|
|
|
262
303
|
// 发送用户属性
|
|
263
304
|
setUserAttributes = (trackingId: string, userAttributes: any) => {
|
|
264
|
-
if (
|
|
305
|
+
if (isObject(userAttributes) && !isEmpty(userAttributes)) {
|
|
265
306
|
const { eventContextBuilder, eventInterceptor, lastVisitEvent } =
|
|
266
307
|
this.dataStore;
|
|
267
308
|
const event = {
|
|
268
309
|
eventType: 'LOGIN_USER_ATTRIBUTES',
|
|
269
|
-
attributes: limitObject(userAttributes),
|
|
270
310
|
...eventContextBuilder(trackingId)
|
|
271
311
|
};
|
|
312
|
+
event.attributes = limitObject({
|
|
313
|
+
...(event.attributes ?? {}),
|
|
314
|
+
...getDynamicAttributes(userAttributes)
|
|
315
|
+
});
|
|
272
316
|
// 该方法很可能被放在在app的onShow中的wx.login异步回调中,
|
|
273
317
|
// 此时页面的path和query可能还没取到,就拿visit事件的path和query补上
|
|
274
318
|
if (!event.path) {
|
|
275
|
-
event.path = lastVisitEvent
|
|
276
|
-
event.query = lastVisitEvent
|
|
277
|
-
event.title = lastVisitEvent
|
|
319
|
+
event.path = lastVisitEvent[trackingId]?.path;
|
|
320
|
+
event.query = lastVisitEvent[trackingId]?.query;
|
|
321
|
+
event.title = lastVisitEvent[trackingId]?.title;
|
|
278
322
|
}
|
|
279
323
|
eventInterceptor(event);
|
|
280
324
|
} else {
|
|
@@ -301,14 +345,7 @@ class GrowingIO implements GrowingIOType {
|
|
|
301
345
|
// 切换userId时重置session并补发visit
|
|
302
346
|
if (prevId && prevId !== userId) {
|
|
303
347
|
this.userStore.setSessionId(trackingId);
|
|
304
|
-
|
|
305
|
-
this.dataStore.eventHooks.currentPage;
|
|
306
|
-
// 重新获取页面title,防止切换配置前修改了title没取到
|
|
307
|
-
this.dataStore.eventHooks.currentPage.title =
|
|
308
|
-
settedTitle[path] ||
|
|
309
|
-
this.minipInstance.getPageTitle(this.minipInstance.getCurrentPage());
|
|
310
|
-
// visit取当前页面值
|
|
311
|
-
this.dataStore.sendVisit(trackingId, { path, query });
|
|
348
|
+
this.dataStore.sendVisit(trackingId);
|
|
312
349
|
}
|
|
313
350
|
} else {
|
|
314
351
|
callError('setUserId');
|
|
@@ -321,13 +358,20 @@ class GrowingIO implements GrowingIOType {
|
|
|
321
358
|
this.userStore.setUserKey(trackingId, undefined);
|
|
322
359
|
};
|
|
323
360
|
|
|
324
|
-
//
|
|
361
|
+
// 设置全局通用属性(即每个事件都会带上的属性值)
|
|
325
362
|
setGeneralProps = (trackingId: string, properties: any) => {
|
|
326
|
-
if (!isEmpty(properties)) {
|
|
327
|
-
this.dataStore.generalProps[trackingId]
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
363
|
+
if (isObject(properties) && !isEmpty(properties)) {
|
|
364
|
+
if (isEmpty(this.dataStore.generalProps[trackingId])) {
|
|
365
|
+
this.dataStore.generalProps[trackingId] = {};
|
|
366
|
+
}
|
|
367
|
+
forEach(properties, (v, k) => {
|
|
368
|
+
if (
|
|
369
|
+
!isFunction(this.dataStore.generalProps[trackingId][k]) ||
|
|
370
|
+
isFunction(v)
|
|
371
|
+
) {
|
|
372
|
+
this.dataStore.generalProps[trackingId][k] = v;
|
|
373
|
+
}
|
|
374
|
+
});
|
|
331
375
|
return true;
|
|
332
376
|
} else {
|
|
333
377
|
callError('setGeneralProps');
|
|
@@ -335,14 +379,13 @@ class GrowingIO implements GrowingIOType {
|
|
|
335
379
|
}
|
|
336
380
|
};
|
|
337
381
|
|
|
338
|
-
//
|
|
382
|
+
// 清空已设置的全局通用属性
|
|
339
383
|
clearGeneralProps = (
|
|
340
384
|
trackingId: string,
|
|
341
385
|
properties: string[] | undefined
|
|
342
386
|
) => {
|
|
343
387
|
try {
|
|
344
388
|
if (!isEmpty(this.dataStore.generalProps[trackingId])) {
|
|
345
|
-
// 获取目标tracker的引用
|
|
346
389
|
if (isArray(properties) && !isEmpty(properties)) {
|
|
347
390
|
properties.forEach((propName: string) => {
|
|
348
391
|
unset(this.dataStore.generalProps[trackingId], propName);
|
|
@@ -352,7 +395,7 @@ class GrowingIO implements GrowingIOType {
|
|
|
352
395
|
}
|
|
353
396
|
}
|
|
354
397
|
} catch (error) {
|
|
355
|
-
callError('
|
|
398
|
+
callError('clearGeneralProps');
|
|
356
399
|
return false;
|
|
357
400
|
}
|
|
358
401
|
};
|
|
@@ -360,22 +403,22 @@ class GrowingIO implements GrowingIOType {
|
|
|
360
403
|
// 自定义埋点事件
|
|
361
404
|
track = (
|
|
362
405
|
trackingId: string,
|
|
363
|
-
|
|
406
|
+
eventName: string,
|
|
364
407
|
properties: { [key: string]: string | string[] }
|
|
365
408
|
) => {
|
|
366
|
-
eventNameValidate(
|
|
367
|
-
const { eventContextBuilder, eventInterceptor
|
|
368
|
-
this.dataStore;
|
|
369
|
-
const mergedProperties = {
|
|
370
|
-
...(generalProps[trackingId] ?? {}),
|
|
371
|
-
...(isObject(properties) && !isEmpty(properties) ? properties : {})
|
|
372
|
-
};
|
|
409
|
+
eventNameValidate(eventName, () => {
|
|
410
|
+
const { eventContextBuilder, eventInterceptor } = this.dataStore;
|
|
373
411
|
const event = {
|
|
374
412
|
eventType: 'CUSTOM',
|
|
375
|
-
eventName
|
|
376
|
-
attributes: limitObject(getDynamicAttributes(mergedProperties)),
|
|
413
|
+
eventName,
|
|
377
414
|
...eventContextBuilder(trackingId)
|
|
378
415
|
};
|
|
416
|
+
event.attributes = limitObject({
|
|
417
|
+
...(event.attributes ?? {}),
|
|
418
|
+
...getDynamicAttributes({
|
|
419
|
+
...(isObject(properties) && !isEmpty(properties) ? properties : {})
|
|
420
|
+
})
|
|
421
|
+
});
|
|
379
422
|
// 埋点事件要保留'&&sendTo'字段用于多实例复制发送
|
|
380
423
|
if (
|
|
381
424
|
this.plugins.gioMultipleInstances &&
|
|
@@ -453,12 +496,15 @@ class GrowingIO implements GrowingIOType {
|
|
|
453
496
|
const event = {
|
|
454
497
|
eventType: 'CUSTOM',
|
|
455
498
|
eventName: timer.eventName,
|
|
456
|
-
attributes: limitObject({
|
|
457
|
-
...properties,
|
|
458
|
-
event_duration: timer.leng > maxEnd ? 0 : timer.leng / 1000
|
|
459
|
-
}),
|
|
460
499
|
...eventContextBuilder(trackingId)
|
|
461
500
|
};
|
|
501
|
+
event.attributes = limitObject({
|
|
502
|
+
...(event.attributes ?? {}),
|
|
503
|
+
...getDynamicAttributes({
|
|
504
|
+
...(isObject(properties) && !isEmpty(properties) ? properties : {}),
|
|
505
|
+
event_duration: timer.leng > maxEnd ? 0 : timer.leng / 1000
|
|
506
|
+
})
|
|
507
|
+
});
|
|
462
508
|
// 埋点事件要保留'&&sendTo'字段用于多实例复制发送
|
|
463
509
|
if (
|
|
464
510
|
this.plugins.gioMultipleInstances &&
|
|
@@ -555,7 +601,9 @@ class GrowingIO implements GrowingIOType {
|
|
|
555
601
|
if (!isEmpty(extraParams)) {
|
|
556
602
|
extraParams.forEach((o) => {
|
|
557
603
|
if (!ignoreFields.includes(o)) {
|
|
558
|
-
infos[`gio${o}`] = this.dataStore.lastVisitEvent[
|
|
604
|
+
infos[`gio${o}`] = (this.dataStore.lastVisitEvent[trackingId] ?? {})[
|
|
605
|
+
o
|
|
606
|
+
];
|
|
559
607
|
}
|
|
560
608
|
});
|
|
561
609
|
}
|
package/src/index.ts
CHANGED
|
@@ -62,16 +62,16 @@ const gdp = function () {
|
|
|
62
62
|
getGlobal().gdp = gdp;
|
|
63
63
|
getGlobal().gioSDKVersion = gioInstance.sdkVersion;
|
|
64
64
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
);
|
|
74
|
-
export const
|
|
75
|
-
|
|
76
|
-
);
|
|
65
|
+
const {
|
|
66
|
+
growingApp,
|
|
67
|
+
growingPage,
|
|
68
|
+
growingComponent,
|
|
69
|
+
growingBehavior,
|
|
70
|
+
initOriginalValue
|
|
71
|
+
} = gioInstance.dataStore.eventHooks;
|
|
72
|
+
initOriginalValue();
|
|
73
|
+
export const GioApp = niceTry(() => growingApp ?? App);
|
|
74
|
+
export const GioPage = niceTry(() => growingPage ?? Page);
|
|
75
|
+
export const GioComponent = niceTry(() => growingComponent ?? Component);
|
|
76
|
+
export const GioBehavior = niceTry(() => growingBehavior ?? Behavior);
|
|
77
77
|
export default gdp;
|