gio-miniprogram-sdk 4.2.0 → 4.3.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.
- 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 +1 -1
- package/src/adapters/gioTaobaoAdapter.ts +5 -3
- package/src/adapters/gioTaroAdapter.ts +16 -10
- package/src/adapters/gioUniAppAdapter.ts +1 -32
- package/src/constants/config.ts +5 -1
- package/src/core/dataStore/eventContextBuilder.ts +4 -8
- package/src/core/dataStore/eventHooks/appEffects.ts +53 -79
- package/src/core/dataStore/eventHooks/index.ts +39 -23
- package/src/core/dataStore/eventHooks/minipPage.ts +108 -44
- package/src/core/dataStore/eventHooks/pageEffects.ts +31 -40
- package/src/core/dataStore/index.ts +90 -61
- package/src/core/growingIO.ts +17 -26
- package/src/core/userStore.ts +26 -0
- package/src/index.ts +12 -12
- package/src/minipInstance/base.ts +54 -27
- package/src/minipInstance/my.ts +6 -1
- package/src/minipInstance/tb.ts +6 -1
- package/src/plugins/gioABTest.ts +54 -33
- package/src/plugins/gioImpressionTracking.ts +14 -10
- package/src/plugins/gioMultipleInstances.ts +2 -0
- package/src/types/base.ts +4 -0
- package/src/types/eventHooks.ts +12 -9
- package/src/types/userStore.ts +2 -0
- package/src/utils/tools.ts +22 -3
|
@@ -6,10 +6,8 @@ import EMIT_MSG from '@@/constants/emitMsg';
|
|
|
6
6
|
class PageEffects {
|
|
7
7
|
public buildTabClickEvent: (tabItem: any) => void;
|
|
8
8
|
private prevEvent: any;
|
|
9
|
-
private argQuery: any;
|
|
10
9
|
constructor(public growingIO: GrowingIOType) {
|
|
11
10
|
this.prevEvent = {};
|
|
12
|
-
this.argQuery = {};
|
|
13
11
|
}
|
|
14
12
|
|
|
15
13
|
main = (page: any, event: PageHookLifeCircle, args: any) => {
|
|
@@ -22,15 +20,15 @@ class PageEffects {
|
|
|
22
20
|
platformConfig,
|
|
23
21
|
dataStore: {
|
|
24
22
|
getTrackerVds,
|
|
23
|
+
getOriginalSource,
|
|
24
|
+
setOriginalSource,
|
|
25
25
|
trackersExecute,
|
|
26
|
-
shareOut,
|
|
27
26
|
eventHooks,
|
|
28
27
|
toggleShareOut,
|
|
29
28
|
buildAppMessageEvent,
|
|
30
29
|
buildTimelineEvent,
|
|
31
30
|
buildAddFavorites
|
|
32
|
-
}
|
|
33
|
-
inPlugin
|
|
31
|
+
}
|
|
34
32
|
}: GrowingIOType = this.growingIO;
|
|
35
33
|
const { currentPage } = eventHooks;
|
|
36
34
|
if (
|
|
@@ -68,43 +66,34 @@ class PageEffects {
|
|
|
68
66
|
currentPage.currentLifecycle = event;
|
|
69
67
|
switch (event) {
|
|
70
68
|
case pageListeners.pageLoad: {
|
|
71
|
-
|
|
69
|
+
// 获取一次页面参数存起来,防止类似支付宝小程序只能通过生命周期获取页面参数或页面堆栈拿不到页面参数,做兜底
|
|
70
|
+
currentPage.queryOption[path] =
|
|
72
71
|
get(page, 'options') ||
|
|
73
72
|
get(page, '__displayReporter.query') ||
|
|
74
73
|
get(page, '$page.query') ||
|
|
75
74
|
get(page, '$wx.__displayReporter.query') ||
|
|
75
|
+
get(page, '$taroParams') ||
|
|
76
76
|
args[0] ||
|
|
77
77
|
{};
|
|
78
|
-
unset(
|
|
79
|
-
currentPage.parsePage(page, this.argQuery[path]);
|
|
78
|
+
unset(currentPage.queryOption[path], '$taroTimestamp');
|
|
80
79
|
break;
|
|
81
80
|
}
|
|
82
81
|
case pageListeners.pageShow: {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
+
});
|
|
89
90
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
} else if (!shareOut || !eventHooks.currentPage.time) {
|
|
97
|
-
// 不是因为分享切出再返回的onshow(视为第一次进入改页面)和切出去以后因为超时或者进入的场景值不一致时(会在appshow清掉页面时间),发page
|
|
98
|
-
currentPage.parsePage(page, this.argQuery[path]);
|
|
99
|
-
// 超时进入页面时前后path一致parsePage方法不会重置页面时间,可能会没有值,所以要补充重设一次
|
|
100
|
-
eventHooks.currentPage.time = Date.now();
|
|
101
|
-
trackersExecute((trackingId: string) => {
|
|
102
|
-
const { trackPage } = getTrackerVds(trackingId);
|
|
103
|
-
if (trackPage) {
|
|
104
|
-
this.buildPageEvent(trackingId);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
}
|
|
91
|
+
// 发page事件
|
|
92
|
+
const { trackPage } = getTrackerVds(trackingId);
|
|
93
|
+
if (trackPage) {
|
|
94
|
+
this.buildPageEvent(trackingId);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
108
97
|
// 分享标记置为false
|
|
109
98
|
toggleShareOut(false);
|
|
110
99
|
break;
|
|
@@ -156,6 +145,14 @@ class PageEffects {
|
|
|
156
145
|
default:
|
|
157
146
|
break;
|
|
158
147
|
}
|
|
148
|
+
currentPage.lastLifecycle = currentPage.currentLifecycle;
|
|
149
|
+
currentPage.currentLifecycle = `${event}End`;
|
|
150
|
+
if (['onHideEnd', 'onUnloadEnd'].includes(currentPage.currentLifecycle)) {
|
|
151
|
+
currentPage.lifeBeforeShow = true;
|
|
152
|
+
}
|
|
153
|
+
if (currentPage.currentLifecycle === 'onShowEnd') {
|
|
154
|
+
currentPage.lifeBeforeShow = false;
|
|
155
|
+
}
|
|
159
156
|
};
|
|
160
157
|
|
|
161
158
|
// 构建页面访问事件
|
|
@@ -165,18 +162,12 @@ class PageEffects {
|
|
|
165
162
|
eventContextBuilder,
|
|
166
163
|
eventInterceptor,
|
|
167
164
|
eventHooks: { currentPage }
|
|
168
|
-
}
|
|
169
|
-
minipInstance
|
|
165
|
+
}
|
|
170
166
|
} = this.growingIO;
|
|
171
167
|
const event = {
|
|
172
168
|
eventType: 'PAGE',
|
|
173
169
|
referralPage: currentPage.getReferralPage(trackingId),
|
|
174
|
-
...eventContextBuilder(trackingId)
|
|
175
|
-
// page事件要单独设一个title以覆盖eventContextBuilder中的lastPage的title错误值
|
|
176
|
-
title:
|
|
177
|
-
currentPage?.title ||
|
|
178
|
-
minipInstance.getPageTitle(minipInstance.getCurrentPage()),
|
|
179
|
-
timestamp: currentPage.time
|
|
170
|
+
...eventContextBuilder(trackingId)
|
|
180
171
|
};
|
|
181
172
|
// 合并页面属性
|
|
182
173
|
event.attributes = currentPage.eventSetPageProps(trackingId, event);
|
|
@@ -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,
|
|
@@ -94,7 +93,7 @@ class DataStore implements DataStoreType {
|
|
|
94
93
|
EMIT_MSG.ON_COMMIT_REQUEST,
|
|
95
94
|
({ eventData: event, trackingId }) => {
|
|
96
95
|
if (event.eventType === 'VISIT') {
|
|
97
|
-
this.lastVisitEvent = event;
|
|
96
|
+
this.lastVisitEvent[trackingId] = event;
|
|
98
97
|
}
|
|
99
98
|
if (event.eventType === 'PAGE') {
|
|
100
99
|
this.lastPageEvent[trackingId] = event;
|
|
@@ -135,6 +134,33 @@ class DataStore implements DataStoreType {
|
|
|
135
134
|
});
|
|
136
135
|
}
|
|
137
136
|
});
|
|
137
|
+
// session更新要补发当前页面的visit和page
|
|
138
|
+
this.growingIO.emitter.on(
|
|
139
|
+
EMIT_MSG.SESSIONID_UPDATE,
|
|
140
|
+
({ oldSessionId, trackingId }) => {
|
|
141
|
+
if (oldSessionId) {
|
|
142
|
+
// 补发visit
|
|
143
|
+
const { getPagePath, getPageQuery: getPageQuery } =
|
|
144
|
+
this.eventHooks.currentPage;
|
|
145
|
+
const path = getPagePath();
|
|
146
|
+
const query = getPageQuery();
|
|
147
|
+
if (!path) {
|
|
148
|
+
// 个别(说的就是你:淘宝)小程序场景值不一样后台拉起时可能args中会没有path和query,直接取上一个最后发送的page中的值
|
|
149
|
+
const lastPage = this.lastPageEvent[trackingId];
|
|
150
|
+
this.sendVisit(trackingId, {
|
|
151
|
+
path: lastPage.path,
|
|
152
|
+
query: lastPage.query
|
|
153
|
+
});
|
|
154
|
+
} else {
|
|
155
|
+
this.sendVisit(trackingId, { path, query });
|
|
156
|
+
}
|
|
157
|
+
// 页面显示以后触发切session要补发page,离开页面到页面加载显示完成前的切session不补发,由onshow生命周期触发
|
|
158
|
+
if (!this.eventHooks.currentPage.lifeBeforeShow) {
|
|
159
|
+
this.sendPage(trackingId);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
);
|
|
138
164
|
}
|
|
139
165
|
|
|
140
166
|
// 获取存储key
|
|
@@ -219,26 +245,25 @@ class DataStore implements DataStoreType {
|
|
|
219
245
|
};
|
|
220
246
|
|
|
221
247
|
// 保存初始来源信息
|
|
222
|
-
setOriginalSource = (trackingId: string,
|
|
248
|
+
setOriginalSource = (trackingId: string, origins: any) => {
|
|
223
249
|
const { minipInstance } = this.growingIO;
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
JSON.stringify(originalSource)
|
|
229
|
-
);
|
|
230
|
-
}
|
|
250
|
+
minipInstance.setStorageSync(
|
|
251
|
+
this.getStorageKey(trackingId, 'originalSource'),
|
|
252
|
+
JSON.stringify(origins)
|
|
253
|
+
);
|
|
231
254
|
};
|
|
232
255
|
|
|
233
256
|
// 获取初始来源信息
|
|
234
257
|
getOriginalSource = (trackingId: string) => {
|
|
235
258
|
const { minipInstance } = this.growingIO;
|
|
236
|
-
return
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
259
|
+
return (
|
|
260
|
+
niceTry(() =>
|
|
261
|
+
JSON.parse(
|
|
262
|
+
minipInstance.getStorageSync(
|
|
263
|
+
this.getStorageKey(trackingId, 'originalSource')
|
|
264
|
+
)
|
|
240
265
|
)
|
|
241
|
-
)
|
|
266
|
+
) ?? {}
|
|
242
267
|
);
|
|
243
268
|
};
|
|
244
269
|
|
|
@@ -263,12 +288,14 @@ class DataStore implements DataStoreType {
|
|
|
263
288
|
const { platformConfig, inPlugin, minipInstance, plugins } = this.growingIO;
|
|
264
289
|
const { uniVue, taro } = vdsConfig;
|
|
265
290
|
// 如果是使用全量版本时,当前小程序不是框架的,要允许原生的hook
|
|
266
|
-
if (!(uniVue || taro)) {
|
|
291
|
+
if (!(uniVue || taro || minipInstance.platform === 'quickapp')) {
|
|
267
292
|
platformConfig.canHook = true;
|
|
268
293
|
}
|
|
269
294
|
// 初始化核心钩子(重写全局)
|
|
270
295
|
if (!inPlugin || ['tbp', 'jdp'].includes(minipInstance.platform)) {
|
|
271
296
|
this.eventHooks.initEventHooks();
|
|
297
|
+
} else {
|
|
298
|
+
this.eventHooks.initOriginalValue();
|
|
272
299
|
}
|
|
273
300
|
/** 第三方框架重写 */
|
|
274
301
|
// uniapp
|
|
@@ -338,6 +365,22 @@ class DataStore implements DataStoreType {
|
|
|
338
365
|
configs.requestTimeout = 5000;
|
|
339
366
|
}
|
|
340
367
|
|
|
368
|
+
// 曝光比例不在合法范围内改回默认值
|
|
369
|
+
if (configs.impressionScale < 0 || configs.impressionScale > 1) {
|
|
370
|
+
configs.impressionScale = 0;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
// keepAlive有效时长不在合法范围内改回默认值
|
|
374
|
+
if (configs.keepAlive < 0 || configs.keepAlive > 60 * 24) {
|
|
375
|
+
configs.keepAlive = 5;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
// session有效时长不在合法范围内改回默认值
|
|
379
|
+
if (configs.sessionExpires < 1 || configs.sessionExpires > 60 * 24) {
|
|
380
|
+
// -1为默认不超时切session
|
|
381
|
+
configs.sessionExpires = -1;
|
|
382
|
+
}
|
|
383
|
+
|
|
341
384
|
return {
|
|
342
385
|
...configs,
|
|
343
386
|
projectId,
|
|
@@ -356,28 +399,17 @@ class DataStore implements DataStoreType {
|
|
|
356
399
|
// 全局配置修改
|
|
357
400
|
setOption = (trackingId: string, k: string, v: any) => {
|
|
358
401
|
const { userStore, emitter } = this.growingIO;
|
|
359
|
-
const
|
|
402
|
+
const trackerVds = this.getTrackerVds(trackingId);
|
|
360
403
|
// 检查 k
|
|
361
404
|
const validKey = isString(k) && this.ALLOW_SETTING_KEYS.includes(k);
|
|
362
405
|
const validValue = validKey && typeof v === DEFAULT_SETTINGS[k]?.type;
|
|
363
406
|
if (validKey && validValue) {
|
|
364
|
-
const prevConfig = { ...
|
|
365
|
-
this.updateVdsConfig(trackingId, { ...
|
|
407
|
+
const prevConfig = { ...trackerVds };
|
|
408
|
+
this.updateVdsConfig(trackingId, { ...trackerVds, [k]: v });
|
|
366
409
|
// 从关闭到打开dataCollect时补发visit和page
|
|
367
410
|
if (k === 'dataCollect' && prevConfig.dataCollect !== v && v) {
|
|
411
|
+
// 更新session
|
|
368
412
|
userStore.setSessionId(trackingId);
|
|
369
|
-
const { path, query, settedTitle } = this.eventHooks.currentPage;
|
|
370
|
-
// 重新获取页面title,防止切换配置前修改了title没取到
|
|
371
|
-
this.eventHooks.currentPage.title =
|
|
372
|
-
settedTitle[path] ||
|
|
373
|
-
this.growingIO.minipInstance.getPageTitle(
|
|
374
|
-
this.growingIO.minipInstance.getCurrentPage()
|
|
375
|
-
);
|
|
376
|
-
// visit取当前页面值
|
|
377
|
-
this.sendVisit(trackingId, { path, query });
|
|
378
|
-
// 要重设一次页面时间,防止比visit早
|
|
379
|
-
this.eventHooks.currentPage.time = Date.now();
|
|
380
|
-
this.sendPage(trackingId, { path, query });
|
|
381
413
|
}
|
|
382
414
|
// 配置项有变更要全局广播
|
|
383
415
|
emitter.emit(EMIT_MSG.OPTION_CHANGE, { optionName: k, optionValue: v });
|
|
@@ -390,15 +422,15 @@ class DataStore implements DataStoreType {
|
|
|
390
422
|
|
|
391
423
|
// 获取全局配置
|
|
392
424
|
getOption = (trackingId: string, k?: string) => {
|
|
393
|
-
const
|
|
425
|
+
const trackerVds = this.getTrackerVds(trackingId);
|
|
394
426
|
if (k && has(this.growingIO.vdsConfig, k)) {
|
|
395
|
-
if (has(
|
|
396
|
-
return
|
|
427
|
+
if (has(trackerVds, k)) {
|
|
428
|
+
return trackerVds[k];
|
|
397
429
|
} else {
|
|
398
430
|
return this.growingIO.vdsConfig[k];
|
|
399
431
|
}
|
|
400
432
|
} else if (isEmpty(k)) {
|
|
401
|
-
return
|
|
433
|
+
return trackerVds;
|
|
402
434
|
} else {
|
|
403
435
|
callError(`getOption > ${k}`);
|
|
404
436
|
return undefined;
|
|
@@ -431,10 +463,7 @@ class DataStore implements DataStoreType {
|
|
|
431
463
|
|
|
432
464
|
// 手动调用visit事件的方法
|
|
433
465
|
sendVisit = (trackingId: string, props?: any) => {
|
|
434
|
-
(this.eventHooks.appEffects as any).buildVisitEvent(
|
|
435
|
-
trackingId,
|
|
436
|
-
props ?? this.lastVisitEvent
|
|
437
|
-
);
|
|
466
|
+
(this.eventHooks.appEffects as any).buildVisitEvent(trackingId, props);
|
|
438
467
|
};
|
|
439
468
|
|
|
440
469
|
// 手动调用page事件的方法
|
|
@@ -482,6 +511,26 @@ class DataStore implements DataStoreType {
|
|
|
482
511
|
}
|
|
483
512
|
};
|
|
484
513
|
|
|
514
|
+
// 事件重组
|
|
515
|
+
eventRefactor = (e: any) => {
|
|
516
|
+
// 有的事件的path和query不能再用页面的值,所以直接使用事件中已有的值
|
|
517
|
+
const ne = {
|
|
518
|
+
...e,
|
|
519
|
+
...this.eventContextBuilder(e.trackingId, {
|
|
520
|
+
path: e.path,
|
|
521
|
+
query: e.query,
|
|
522
|
+
// page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
|
|
523
|
+
timestamp: e.timestamp
|
|
524
|
+
})
|
|
525
|
+
};
|
|
526
|
+
// 防止事件原有的属性被通用属性直接覆盖
|
|
527
|
+
ne.attributes = {
|
|
528
|
+
...(ne.attributes ?? {}),
|
|
529
|
+
...(e.attributes ?? {})
|
|
530
|
+
};
|
|
531
|
+
return ne;
|
|
532
|
+
};
|
|
533
|
+
|
|
485
534
|
// 事件拦截器(有的通用维度字段需要异步获取,为了防止事件在通用维度还没返回之前就发出去)一般只有最开始的个别事件会被拦住
|
|
486
535
|
eventInterceptor = (event: any) => {
|
|
487
536
|
const { systemInfo, network } = this.growingIO.minipInstance;
|
|
@@ -491,17 +540,7 @@ class DataStore implements DataStoreType {
|
|
|
491
540
|
} else if (!isEmpty(this.interceptEvents)) {
|
|
492
541
|
// 有通用维度字段了,且有被拦截的事件,放一起重新添加通用维度字段再提交转换
|
|
493
542
|
[...this.interceptEvents, event].forEach((e: any) => {
|
|
494
|
-
|
|
495
|
-
const ne = {
|
|
496
|
-
...e,
|
|
497
|
-
...this.eventContextBuilder(event.trackingId, {
|
|
498
|
-
path: e.path,
|
|
499
|
-
query: e.query,
|
|
500
|
-
// page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
|
|
501
|
-
timestamp: e.timestamp
|
|
502
|
-
})
|
|
503
|
-
};
|
|
504
|
-
this.eventConverter(ne);
|
|
543
|
+
this.eventConverter(this.eventRefactor(e));
|
|
505
544
|
});
|
|
506
545
|
this.interceptEvents = [];
|
|
507
546
|
} else {
|
|
@@ -517,17 +556,7 @@ class DataStore implements DataStoreType {
|
|
|
517
556
|
} = this.growingIO;
|
|
518
557
|
if (systemInfo && network && !isEmpty(this.interceptEvents)) {
|
|
519
558
|
[...this.interceptEvents].forEach((e: any) => {
|
|
520
|
-
|
|
521
|
-
const ne = {
|
|
522
|
-
...e,
|
|
523
|
-
...this.eventContextBuilder(e.trackingId, {
|
|
524
|
-
path: e.path,
|
|
525
|
-
query: e.query,
|
|
526
|
-
// page事件需要使用事件中原有的时间戳,其他事件也要用原来的时间戳保证事件的准确性
|
|
527
|
-
timestamp: e.timestamp
|
|
528
|
-
})
|
|
529
|
-
};
|
|
530
|
-
this.eventConverter(ne);
|
|
559
|
+
this.eventConverter(this.eventRefactor(e));
|
|
531
560
|
});
|
|
532
561
|
this.interceptEvents = [];
|
|
533
562
|
}
|
package/src/core/growingIO.ts
CHANGED
|
@@ -163,8 +163,8 @@ class GrowingIO implements GrowingIOType {
|
|
|
163
163
|
// 需要校验实例的方法执行
|
|
164
164
|
handlerDistribute = (trackingId: string, handler: string, args: any) => {
|
|
165
165
|
const { initializedTrackingIds, getTrackerVds } = this.dataStore;
|
|
166
|
-
const
|
|
167
|
-
if (
|
|
166
|
+
const trackerVds = getTrackerVds(trackingId);
|
|
167
|
+
if (trackerVds && initializedTrackingIds.includes(trackingId)) {
|
|
168
168
|
return this[handler](trackingId, ...args);
|
|
169
169
|
} else {
|
|
170
170
|
consoleText(`不存在实例:${trackingId},请检查!`, 'warn');
|
|
@@ -208,22 +208,21 @@ class GrowingIO implements GrowingIOType {
|
|
|
208
208
|
setPageAttributes = (trackingId: string, properties: any) => {
|
|
209
209
|
if (isObject(properties) && !isEmpty(properties)) {
|
|
210
210
|
const { currentPage } = this.dataStore.eventHooks;
|
|
211
|
+
const path = currentPage.getPagePath();
|
|
211
212
|
if (isEmpty(currentPage.pageProps[trackingId])) {
|
|
212
213
|
currentPage.pageProps[trackingId] = {};
|
|
213
214
|
}
|
|
214
|
-
if (isEmpty(currentPage.pageProps[trackingId][
|
|
215
|
-
currentPage.pageProps[trackingId][
|
|
215
|
+
if (isEmpty(currentPage.pageProps[trackingId][path])) {
|
|
216
|
+
currentPage.pageProps[trackingId][path] = {};
|
|
216
217
|
}
|
|
217
218
|
// 结果合并,动态属性不作处理
|
|
218
219
|
if (!isEmpty(properties)) {
|
|
219
220
|
forEach(properties, (v, k) => {
|
|
220
221
|
if (
|
|
221
|
-
!isFunction(
|
|
222
|
-
currentPage.pageProps[trackingId][currentPage.path][k]
|
|
223
|
-
) ||
|
|
222
|
+
!isFunction(currentPage.pageProps[trackingId][path][k]) ||
|
|
224
223
|
isFunction(v)
|
|
225
224
|
) {
|
|
226
|
-
currentPage.pageProps[trackingId][
|
|
225
|
+
currentPage.pageProps[trackingId][path][k] = v;
|
|
227
226
|
}
|
|
228
227
|
});
|
|
229
228
|
}
|
|
@@ -244,15 +243,13 @@ class GrowingIO implements GrowingIOType {
|
|
|
244
243
|
!isEmpty(this.dataStore.eventHooks.currentPage.pageProps[trackingId])
|
|
245
244
|
) {
|
|
246
245
|
const { currentPage } = this.dataStore.eventHooks;
|
|
246
|
+
const path = currentPage.getPagePath();
|
|
247
247
|
if (isArray(properties) && !isEmpty(properties)) {
|
|
248
248
|
properties.forEach((propName: string) => {
|
|
249
|
-
unset(
|
|
250
|
-
currentPage.pageProps[trackingId][currentPage.path],
|
|
251
|
-
propName
|
|
252
|
-
);
|
|
249
|
+
unset(currentPage.pageProps[trackingId][path], propName);
|
|
253
250
|
});
|
|
254
251
|
} else {
|
|
255
|
-
currentPage.pageProps[trackingId][
|
|
252
|
+
currentPage.pageProps[trackingId][path] = {};
|
|
256
253
|
}
|
|
257
254
|
}
|
|
258
255
|
} catch (error) {
|
|
@@ -319,9 +316,9 @@ class GrowingIO implements GrowingIOType {
|
|
|
319
316
|
// 该方法很可能被放在在app的onShow中的wx.login异步回调中,
|
|
320
317
|
// 此时页面的path和query可能还没取到,就拿visit事件的path和query补上
|
|
321
318
|
if (!event.path) {
|
|
322
|
-
event.path = lastVisitEvent
|
|
323
|
-
event.query = lastVisitEvent
|
|
324
|
-
event.title = lastVisitEvent
|
|
319
|
+
event.path = lastVisitEvent[trackingId]?.path;
|
|
320
|
+
event.query = lastVisitEvent[trackingId]?.query;
|
|
321
|
+
event.title = lastVisitEvent[trackingId]?.title;
|
|
325
322
|
}
|
|
326
323
|
eventInterceptor(event);
|
|
327
324
|
} else {
|
|
@@ -345,17 +342,9 @@ class GrowingIO implements GrowingIOType {
|
|
|
345
342
|
if (idMapping) {
|
|
346
343
|
this.userStore.setUserKey(trackingId, isNil(userKey) ? '' : userKey);
|
|
347
344
|
}
|
|
348
|
-
// 切换userId时重置session
|
|
345
|
+
// 切换userId时重置session
|
|
349
346
|
if (prevId && prevId !== userId) {
|
|
350
347
|
this.userStore.setSessionId(trackingId);
|
|
351
|
-
const { path, query, settedTitle } =
|
|
352
|
-
this.dataStore.eventHooks.currentPage;
|
|
353
|
-
// 重新获取页面title,防止切换配置前修改了title没取到
|
|
354
|
-
this.dataStore.eventHooks.currentPage.title =
|
|
355
|
-
settedTitle[path] ||
|
|
356
|
-
this.minipInstance.getPageTitle(this.minipInstance.getCurrentPage());
|
|
357
|
-
// visit取当前页面值
|
|
358
|
-
this.dataStore.sendVisit(trackingId, { path, query });
|
|
359
348
|
}
|
|
360
349
|
} else {
|
|
361
350
|
callError('setUserId');
|
|
@@ -611,7 +600,9 @@ class GrowingIO implements GrowingIOType {
|
|
|
611
600
|
if (!isEmpty(extraParams)) {
|
|
612
601
|
extraParams.forEach((o) => {
|
|
613
602
|
if (!ignoreFields.includes(o)) {
|
|
614
|
-
infos[`gio${o}`] = this.dataStore.lastVisitEvent[
|
|
603
|
+
infos[`gio${o}`] = (this.dataStore.lastVisitEvent[trackingId] ?? {})[
|
|
604
|
+
o
|
|
605
|
+
];
|
|
615
606
|
}
|
|
616
607
|
});
|
|
617
608
|
}
|
package/src/core/userStore.ts
CHANGED
|
@@ -26,12 +26,15 @@ class UserStore implements UserStoreType {
|
|
|
26
26
|
public _userKey: StringObject;
|
|
27
27
|
// 最后一次登录用户id(持久性存储)
|
|
28
28
|
public _gioId: StringObject;
|
|
29
|
+
// 设置了session有效期以后判断用的session失效时间
|
|
30
|
+
public _sessionExpires: number;
|
|
29
31
|
constructor(public growingIO: GrowingIOType) {
|
|
30
32
|
this._uid = undefined;
|
|
31
33
|
this._sessionId = {};
|
|
32
34
|
this._userId = {};
|
|
33
35
|
this._userKey = {};
|
|
34
36
|
this._gioId = {};
|
|
37
|
+
this._sessionExpires = -1;
|
|
35
38
|
}
|
|
36
39
|
|
|
37
40
|
// 获取sessionId存储key
|
|
@@ -69,9 +72,26 @@ class UserStore implements UserStoreType {
|
|
|
69
72
|
|
|
70
73
|
// 获取sessionId
|
|
71
74
|
getSessionId = (trackingId: string) => {
|
|
75
|
+
// 设置了session时长,就需要检查session是否过期
|
|
76
|
+
const {
|
|
77
|
+
vdsConfig: { sessionExpires },
|
|
78
|
+
dataStore: { trackersExecute }
|
|
79
|
+
} = this.growingIO;
|
|
80
|
+
// 不存在sessionId(即新进)要设一个新的sessionId
|
|
72
81
|
if (!this._sessionId[trackingId]) {
|
|
73
82
|
this.setSessionId(trackingId);
|
|
74
83
|
}
|
|
84
|
+
// 设置了session时长且过期
|
|
85
|
+
if (sessionExpires > -1) {
|
|
86
|
+
// 只要有一个session超时,所有实例都要重设sessionId
|
|
87
|
+
if (Date.now() > this._sessionExpires) {
|
|
88
|
+
trackersExecute((id: string) => {
|
|
89
|
+
this.setSessionId(id);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// 每次获取session后要更新过期时间
|
|
93
|
+
this._sessionExpires = Date.now() + 1000 * 60 * sessionExpires;
|
|
94
|
+
}
|
|
75
95
|
return this._sessionId[trackingId];
|
|
76
96
|
};
|
|
77
97
|
|
|
@@ -83,9 +103,15 @@ class UserStore implements UserStoreType {
|
|
|
83
103
|
}
|
|
84
104
|
// 小程序中sessionId只需要在内存中存储就可以,不需要持久化存储
|
|
85
105
|
this._sessionId[trackingId] = id;
|
|
106
|
+
// 设置了session时长,就需要更新过期时间
|
|
107
|
+
const { sessionExpires } = this.growingIO.vdsConfig;
|
|
108
|
+
if (sessionExpires > -1) {
|
|
109
|
+
this._sessionExpires = Date.now() + 1000 * 60 * sessionExpires;
|
|
110
|
+
}
|
|
86
111
|
// 广播通知登录sessionId变更
|
|
87
112
|
if (prevId !== id) {
|
|
88
113
|
this.growingIO.emitter.emit(EMIT_MSG.SESSIONID_UPDATE, {
|
|
114
|
+
trackingId,
|
|
89
115
|
newSessionId: id,
|
|
90
116
|
oldSessionId: prevId
|
|
91
117
|
});
|
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;
|
|
@@ -7,7 +7,14 @@ import {
|
|
|
7
7
|
SystemInfo
|
|
8
8
|
} from '@@/types/minipInstance';
|
|
9
9
|
import { PLATFORMS } from '@@/types/platforms';
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
isFunction,
|
|
12
|
+
isObject,
|
|
13
|
+
isString,
|
|
14
|
+
last,
|
|
15
|
+
typeOf,
|
|
16
|
+
isEmpty
|
|
17
|
+
} from '@@/utils/glodash';
|
|
11
18
|
import EMIT_MSG from '@@/constants/emitMsg';
|
|
12
19
|
import {
|
|
13
20
|
limitString,
|
|
@@ -57,7 +64,7 @@ class BaseInstance implements MinipInstanceType {
|
|
|
57
64
|
// 这个currentPath一般认为是在onLoad中获取的当前小程序页面的path,此时SDK还没有parse,保存的还是上一个页面的信息
|
|
58
65
|
const currentPath = self.getCurrentPath();
|
|
59
66
|
const { title } = arguments[0] || {};
|
|
60
|
-
self.growingIO.dataStore.eventHooks.currentPage.
|
|
67
|
+
self.growingIO.dataStore.eventHooks.currentPage.configuredTitle[
|
|
61
68
|
currentPath
|
|
62
69
|
] = title;
|
|
63
70
|
}
|
|
@@ -126,38 +133,58 @@ class BaseInstance implements MinipInstanceType {
|
|
|
126
133
|
|
|
127
134
|
// 获取页面标题
|
|
128
135
|
getPageTitle = (page) => {
|
|
136
|
+
const platform = getPlainPlatform();
|
|
129
137
|
let title = '';
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
}
|
|
138
|
+
let instConfig = getPlainConfig(platform);
|
|
139
|
+
if (typeOf(instConfig) === 'string') {
|
|
140
|
+
instConfig = niceTry(() => JSON.parse(instConfig)) ?? {};
|
|
141
|
+
}
|
|
142
|
+
// 第一优先级在base中的hook setNavigationBarTitle设置的值(在dataStore page实例中实现)
|
|
143
|
+
// 第二优先级支持客户自己在页面中设置页面title
|
|
144
|
+
const data = page?.data || page.$data || {};
|
|
145
|
+
title = isString(data?.gioPageTitle) ? data?.gioPageTitle : '';
|
|
146
|
+
if (instConfig) {
|
|
147
|
+
// 第三优先级app生命周期中拿不到page对象,拿生命周期的参数来匹配
|
|
148
|
+
const { enterParams } = this.growingIO.dataStore.eventHooks.appEffects;
|
|
149
|
+
if (!page.route && !isEmpty(enterParams)) {
|
|
150
|
+
page.route = enterParams.path || '';
|
|
151
|
+
title = this._getTitleFromTabBar(instConfig, page.route);
|
|
145
152
|
}
|
|
146
|
-
//
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
153
|
+
// 第四优先级取页面的navigationBarTitleText
|
|
154
|
+
niceTry(() => {
|
|
155
|
+
if (!title) {
|
|
156
|
+
const instPage = instConfig.page || {};
|
|
157
|
+
const pageInfo =
|
|
158
|
+
instPage[page.route] || instPage[`${page.route}.html`];
|
|
159
|
+
if (pageInfo) {
|
|
160
|
+
title = pageInfo?.window?.navigationBarTitleText;
|
|
161
|
+
} else if (['wx', 'tt'].includes(platform)) {
|
|
162
|
+
title = (instConfig || global || $global)?.global?.window
|
|
163
|
+
?.navigationBarTitleText;
|
|
164
|
+
} else {
|
|
165
|
+
title = (instConfig || global || $global)?.window
|
|
166
|
+
?.navigationBarTitleText;
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
// 第五优先级取tabBar配置
|
|
171
|
+
if (!title) {
|
|
172
|
+
title = this._getTitleFromTabBar(instConfig, page.route);
|
|
154
173
|
}
|
|
155
|
-
} catch (e) {
|
|
156
|
-
return '';
|
|
157
174
|
}
|
|
158
175
|
return limitString(title);
|
|
159
176
|
};
|
|
160
177
|
|
|
178
|
+
private _getTitleFromTabBar = (
|
|
179
|
+
instConfig: any,
|
|
180
|
+
pageRoute: string
|
|
181
|
+
): string => {
|
|
182
|
+
const tabPage = instConfig?.tabBar?.list?.find((p) => {
|
|
183
|
+
return p.pagePath === pageRoute || p.pagePath === `${pageRoute}.html`;
|
|
184
|
+
});
|
|
185
|
+
return tabPage?.text || '';
|
|
186
|
+
};
|
|
187
|
+
|
|
161
188
|
/**
|
|
162
189
|
* 存储相关
|
|
163
190
|
*/
|