web-tracing-core 2.1.0 → 2.1.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/{dist/README.md → README.md} +8 -0
- package/{dist/index.cjs → index.cjs} +24 -5
- package/{dist/index.iife.js → index.iife.js} +24 -5
- package/{dist/index.iife.min.js → index.iife.min.js} +9 -9
- package/{dist/index.mjs → index.mjs} +24 -5
- package/package.json +9 -9
- package/__test__/css/performance.css +0 -3
- package/__test__/err-batch.spec.ts +0 -47
- package/__test__/err.spec.ts +0 -82
- package/__test__/event.spec.ts +0 -62
- package/__test__/html/performance.html +0 -57
- package/__test__/html/recordscreen.html +0 -39
- package/__test__/http.spec.ts +0 -143
- package/__test__/img/performance.png +0 -0
- package/__test__/js/performance.js +0 -3
- package/__test__/performance.spec.ts +0 -112
- package/__test__/recordscreen.spec.ts +0 -50
- package/__test__/utils/index.ts +0 -99
- package/__test__/utils/pollify.ts +0 -14
- package/__test__/utils.spec.ts +0 -18
- package/dist/package.json +0 -49
- package/index.ts +0 -75
- package/src/common/config.ts +0 -13
- package/src/common/constant.ts +0 -57
- package/src/common/index.ts +0 -2
- package/src/lib/base.ts +0 -129
- package/src/lib/err-batch.ts +0 -134
- package/src/lib/err.ts +0 -323
- package/src/lib/event-dwell.ts +0 -63
- package/src/lib/event.ts +0 -252
- package/src/lib/eventBus.ts +0 -97
- package/src/lib/exportMethods.ts +0 -208
- package/src/lib/http.ts +0 -197
- package/src/lib/intersectionObserver.ts +0 -164
- package/src/lib/line-status.ts +0 -45
- package/src/lib/options.ts +0 -325
- package/src/lib/performance.ts +0 -302
- package/src/lib/pv.ts +0 -199
- package/src/lib/recordscreen.ts +0 -169
- package/src/lib/replace.ts +0 -371
- package/src/lib/sendData.ts +0 -264
- package/src/observer/computed.ts +0 -52
- package/src/observer/config.ts +0 -1
- package/src/observer/dep.ts +0 -21
- package/src/observer/index.ts +0 -91
- package/src/observer/ref.ts +0 -80
- package/src/observer/types.ts +0 -22
- package/src/observer/watch.ts +0 -19
- package/src/observer/watcher.ts +0 -88
- package/src/types/index.ts +0 -126
- package/src/utils/debug.ts +0 -17
- package/src/utils/element.ts +0 -47
- package/src/utils/fingerprintjs.ts +0 -2132
- package/src/utils/getIps.ts +0 -127
- package/src/utils/global.ts +0 -49
- package/src/utils/index.ts +0 -551
- package/src/utils/is.ts +0 -78
- package/src/utils/localStorage.ts +0 -70
- package/src/utils/session.ts +0 -27
- /package/{dist/LICENSE → LICENSE} +0 -0
- /package/{dist/index.d.ts → index.d.ts} +0 -0
package/src/lib/eventBus.ts
DELETED
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import type { AnyFun } from '../types'
|
|
2
|
-
import { EVENTTYPES } from '../common'
|
|
3
|
-
import { _support } from '../utils/global'
|
|
4
|
-
|
|
5
|
-
interface EventHandler {
|
|
6
|
-
type: EVENTTYPES
|
|
7
|
-
callback: AnyFun
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
type Handlers = {
|
|
11
|
-
[key in EVENTTYPES]?: AnyFun[]
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class EventBus {
|
|
15
|
-
private handlers: Handlers
|
|
16
|
-
constructor() {
|
|
17
|
-
this.handlers = {}
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* 为目标类型事件添加回调
|
|
21
|
-
* @param handler 需要被添加的类型以及回调函数
|
|
22
|
-
*/
|
|
23
|
-
addEvent(handler: EventHandler) {
|
|
24
|
-
!this.handlers[handler.type] && (this.handlers[handler.type] = [])
|
|
25
|
-
const funIndex = this._getCallbackIndex(handler)
|
|
26
|
-
if (funIndex === -1) {
|
|
27
|
-
this.handlers[handler.type]?.push(handler.callback)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* 为目标类型事件删除回调
|
|
32
|
-
* @param handler 需要被删除的类型以及回调函数
|
|
33
|
-
*/
|
|
34
|
-
delEvent(handler: EventHandler) {
|
|
35
|
-
const funIndex = this._getCallbackIndex(handler)
|
|
36
|
-
if (funIndex !== -1) {
|
|
37
|
-
this.handlers[handler.type]?.splice(funIndex, 1)
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* 为目标类型事件更改回调
|
|
42
|
-
* @param handler 需要被更改的类型以及回调函数
|
|
43
|
-
* @param newCallback 新的回调函数
|
|
44
|
-
*/
|
|
45
|
-
changeEvent(handler: EventHandler, newCallback: AnyFun) {
|
|
46
|
-
const funIndex = this._getCallbackIndex(handler)
|
|
47
|
-
if (funIndex !== -1) {
|
|
48
|
-
this.handlers[handler.type]?.splice(funIndex, 1, newCallback)
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
/**
|
|
52
|
-
* 获取目标类型事件所有的回调
|
|
53
|
-
* @param type 事件类型
|
|
54
|
-
*/
|
|
55
|
-
getEvent(type: EVENTTYPES): AnyFun[] {
|
|
56
|
-
return this.handlers[type] || []
|
|
57
|
-
}
|
|
58
|
-
/**
|
|
59
|
-
* 执行目标类型事件所有的回调
|
|
60
|
-
* @param type 事件类型
|
|
61
|
-
* @param args 额外参数
|
|
62
|
-
*/
|
|
63
|
-
runEvent(type: EVENTTYPES, ...args: any[]): void {
|
|
64
|
-
const allEvent = this.getEvent(type)
|
|
65
|
-
allEvent.forEach(fun => {
|
|
66
|
-
fun(...args)
|
|
67
|
-
})
|
|
68
|
-
}
|
|
69
|
-
/**
|
|
70
|
-
* 获取函数在 callback 列表中的位置
|
|
71
|
-
*/
|
|
72
|
-
private _getCallbackIndex(handler: EventHandler): number {
|
|
73
|
-
if (this.handlers[handler.type]) {
|
|
74
|
-
const callbackList = this.handlers[handler.type]
|
|
75
|
-
if (callbackList) {
|
|
76
|
-
return callbackList.findIndex(fun => fun === handler.callback)
|
|
77
|
-
} else {
|
|
78
|
-
return -1
|
|
79
|
-
}
|
|
80
|
-
} else {
|
|
81
|
-
return -1
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* 移除多个指定类型的事件监听
|
|
86
|
-
* @param types 事件类型数组
|
|
87
|
-
*/
|
|
88
|
-
removeEvents(types: EVENTTYPES[]) {
|
|
89
|
-
types.forEach(type => {
|
|
90
|
-
delete this.handlers[type]
|
|
91
|
-
})
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const eventBus = _support.eventBus || (_support.eventBus = new EventBus())
|
|
96
|
-
|
|
97
|
-
export { eventBus }
|
package/src/lib/exportMethods.ts
DELETED
|
@@ -1,208 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
InternalOptions,
|
|
3
|
-
AnyFun,
|
|
4
|
-
TargetGather,
|
|
5
|
-
ElementOrList,
|
|
6
|
-
VoidFun
|
|
7
|
-
} from '../types'
|
|
8
|
-
import { options } from './options'
|
|
9
|
-
import { _support } from '../utils/global'
|
|
10
|
-
import { getIPs as _getIPs } from '../utils/getIps'
|
|
11
|
-
import { validateMethods, deepCopy } from '../utils'
|
|
12
|
-
import { handleSendError } from './err'
|
|
13
|
-
import { handleSendPerformance } from './performance'
|
|
14
|
-
import { handleSendEvent } from './event'
|
|
15
|
-
import { handleSendPageView } from './pv'
|
|
16
|
-
import { intersection } from './intersectionObserver'
|
|
17
|
-
import { sendData } from './sendData'
|
|
18
|
-
import { SDK_LOCAL_KEY } from '../common/config'
|
|
19
|
-
import { LocalStorageUtil } from '../utils/localStorage'
|
|
20
|
-
import { unzip } from '../lib/recordscreen'
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* 解压错误录屏数据
|
|
24
|
-
*/
|
|
25
|
-
export function unzipRecordscreen(recordscreen: string) {
|
|
26
|
-
return unzip(recordscreen)
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* 钩子:放入事件队列之前
|
|
31
|
-
* @param fun 回调函数
|
|
32
|
-
*/
|
|
33
|
-
export function beforePushEventList(fun: AnyFun): void {
|
|
34
|
-
if (!validateMethods('beforePushEventList')) return
|
|
35
|
-
|
|
36
|
-
options.value.beforePushEventList.push(fun)
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 钩子:发送之前
|
|
41
|
-
* @param fun 回调函数
|
|
42
|
-
*/
|
|
43
|
-
export function beforeSendData(fun: AnyFun): void {
|
|
44
|
-
if (!validateMethods('beforeSendData')) return
|
|
45
|
-
|
|
46
|
-
options.value.beforeSendData.push(fun)
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* 钩子:发送之后
|
|
51
|
-
* @param fun 回调函数
|
|
52
|
-
*/
|
|
53
|
-
export function afterSendData(fun: AnyFun): void {
|
|
54
|
-
if (!validateMethods('afterSendData')) return
|
|
55
|
-
|
|
56
|
-
options.value.afterSendData.push(fun)
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* 设置用户id
|
|
61
|
-
* @param id 用户id
|
|
62
|
-
*/
|
|
63
|
-
export function setUserUuid(id: string): void {
|
|
64
|
-
if (!validateMethods('setUserUuid')) return
|
|
65
|
-
|
|
66
|
-
options.value.userUuid = id
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* 获取用户id(此id是手动设置的id)
|
|
71
|
-
*/
|
|
72
|
-
export function getUserUuid(): string | void {
|
|
73
|
-
if (!validateMethods('getUserUuid')) return
|
|
74
|
-
|
|
75
|
-
return options.value.userUuid
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* 获取sdk中的用户id
|
|
80
|
-
*/
|
|
81
|
-
export function getSDKUserUuid(): string | void {
|
|
82
|
-
if (!validateMethods('getSDKUserUuid')) return
|
|
83
|
-
|
|
84
|
-
return options.value.sdkUserUuid
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
/**
|
|
88
|
-
* 获取在sdk中记录的所有基础的信息(包括硬件,地理位置等等)
|
|
89
|
-
*/
|
|
90
|
-
export function getBaseInfo(): object | void {
|
|
91
|
-
if (!validateMethods('getBaseInfo')) return
|
|
92
|
-
|
|
93
|
-
return {
|
|
94
|
-
..._support.baseInfo.base,
|
|
95
|
-
userUuid: options.value.userUuid
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* 获取首屏数据
|
|
101
|
-
*/
|
|
102
|
-
export function getFirstScreen(): object | void {
|
|
103
|
-
if (!validateMethods('getFirstScreen')) return
|
|
104
|
-
|
|
105
|
-
return { ..._support.firstScreen }
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* 主动触发error事件上报
|
|
110
|
-
* @param options 自定义配置信息
|
|
111
|
-
*/
|
|
112
|
-
export function traceError(options = {}, flush = false) {
|
|
113
|
-
if (!validateMethods('traceError')) return
|
|
114
|
-
|
|
115
|
-
return handleSendError(options, flush)
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* 主动触发性能事件上报
|
|
120
|
-
* @param options 自定义配置信息
|
|
121
|
-
*/
|
|
122
|
-
export function tracePerformance(options = {}, flush = false) {
|
|
123
|
-
if (!validateMethods('tracePerformance')) return
|
|
124
|
-
|
|
125
|
-
return handleSendPerformance(options, flush)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
/**
|
|
129
|
-
* 主动触发事件上报
|
|
130
|
-
* @param options 自定义配置信息
|
|
131
|
-
*/
|
|
132
|
-
export function traceCustomEvent(options = {}, flush = false) {
|
|
133
|
-
if (!validateMethods('traceCustomEvent')) return
|
|
134
|
-
|
|
135
|
-
return handleSendEvent(options, flush)
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
* 主动触发pv事件上报
|
|
140
|
-
* @param options 自定义配置信息
|
|
141
|
-
*/
|
|
142
|
-
export function tracePageView(option = {}, flush = false) {
|
|
143
|
-
if (!validateMethods('tracePageView')) return
|
|
144
|
-
|
|
145
|
-
return handleSendPageView(option, flush)
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 获取公网ip
|
|
150
|
-
*/
|
|
151
|
-
export function getIPs(): Promise<string> {
|
|
152
|
-
return _getIPs().then((res: any) => res[0])
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* 曝光 - 对目标元素进行监听
|
|
157
|
-
* @param params 附带的额外参数
|
|
158
|
-
*/
|
|
159
|
-
export function intersectionObserver(gather: TargetGather): void {
|
|
160
|
-
if (!validateMethods('intersectionObserver')) return
|
|
161
|
-
intersection.observe(gather)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* 曝光 - 对目标元素进行取消监听
|
|
166
|
-
*/
|
|
167
|
-
export function intersectionUnobserve(target: ElementOrList): void {
|
|
168
|
-
if (!validateMethods('intersectionUnobserve')) return
|
|
169
|
-
intersection.unobserve(target)
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/**
|
|
173
|
-
* 曝光 - 取消所有监听
|
|
174
|
-
*/
|
|
175
|
-
export function intersectionDisconnect(): void {
|
|
176
|
-
if (!validateMethods('intersectionDisconnect')) return
|
|
177
|
-
intersection.disconnect()
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* 手动发送本地数据
|
|
182
|
-
*/
|
|
183
|
-
export function sendLocal(): void {
|
|
184
|
-
if (!validateMethods('sendData') && !options.value.localization) return
|
|
185
|
-
const localItem = LocalStorageUtil.getItem(SDK_LOCAL_KEY)
|
|
186
|
-
if (localItem) {
|
|
187
|
-
sendData.sendLocal(localItem)
|
|
188
|
-
LocalStorageUtil.removeItem(SDK_LOCAL_KEY)
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* 设置本地化存储溢出后的回调
|
|
194
|
-
* @param overFlowFun 回调函数
|
|
195
|
-
*/
|
|
196
|
-
export function setLocalizationOverFlow(overFlowFun: VoidFun): void {
|
|
197
|
-
if (!validateMethods('localizationOverFlow') && !options.value.localization)
|
|
198
|
-
return
|
|
199
|
-
options.value.localizationOverFlow = overFlowFun
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* 获取sdk内部的参数配置
|
|
204
|
-
* 这个参数配置并不是入参配置,sdk内部的参数是整理过后的
|
|
205
|
-
*/
|
|
206
|
-
export function getOptions(): InternalOptions {
|
|
207
|
-
return deepCopy(options.value)
|
|
208
|
-
}
|
package/src/lib/http.ts
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
on,
|
|
3
|
-
isValidKey,
|
|
4
|
-
getTimestamp,
|
|
5
|
-
parseGetParams,
|
|
6
|
-
getBaseUrl
|
|
7
|
-
} from '../utils'
|
|
8
|
-
import { handleSendError } from './err'
|
|
9
|
-
import { eventBus } from './eventBus'
|
|
10
|
-
import { EVENTTYPES, SENDID } from '../common'
|
|
11
|
-
import { options } from './options'
|
|
12
|
-
import { handleSendPerformance } from './performance'
|
|
13
|
-
// import { debug } from '../utils/debug'
|
|
14
|
-
import { isRegExp } from '../utils/is'
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* fetch请求拦截
|
|
18
|
-
*/
|
|
19
|
-
function interceptFetch(): void {
|
|
20
|
-
eventBus.addEvent({
|
|
21
|
-
type: EVENTTYPES.FETCH,
|
|
22
|
-
callback: async (
|
|
23
|
-
reqUrl: string,
|
|
24
|
-
_options: Partial<Request> = {},
|
|
25
|
-
res: Response,
|
|
26
|
-
fetchStart: number,
|
|
27
|
-
traceObj: Partial<Request> = {}
|
|
28
|
-
) => {
|
|
29
|
-
const { method = 'GET', body = {} } = _options
|
|
30
|
-
const { url, status, statusText } = res
|
|
31
|
-
const requestMethod = String(method).toLocaleLowerCase()
|
|
32
|
-
|
|
33
|
-
if (isIgnoreHttp(url)) return
|
|
34
|
-
|
|
35
|
-
if (status === 200 || status === 304) {
|
|
36
|
-
if (options.value.performance.server) {
|
|
37
|
-
handleSendPerformance({
|
|
38
|
-
eventId: SENDID.SERVER,
|
|
39
|
-
requestUrl: url,
|
|
40
|
-
triggerTime: fetchStart,
|
|
41
|
-
duration: getTimestamp() - fetchStart,
|
|
42
|
-
responseStatus: status,
|
|
43
|
-
requestMethod,
|
|
44
|
-
requestType: 'fetch',
|
|
45
|
-
...traceObj,
|
|
46
|
-
params: method.toUpperCase() === 'POST' ? body : parseGetParams(url)
|
|
47
|
-
})
|
|
48
|
-
}
|
|
49
|
-
} else if (options.value.error.server) {
|
|
50
|
-
handleSendError({
|
|
51
|
-
eventId: SENDID.SERVER,
|
|
52
|
-
triggerTime: fetchStart,
|
|
53
|
-
duration: getTimestamp() - fetchStart,
|
|
54
|
-
errMessage: statusText,
|
|
55
|
-
requestUrl: getBaseUrl(url),
|
|
56
|
-
responseStatus: status,
|
|
57
|
-
requestMethod,
|
|
58
|
-
requestType: 'fetch',
|
|
59
|
-
...traceObj,
|
|
60
|
-
params: method.toUpperCase() === 'POST' ? body : parseGetParams(url)
|
|
61
|
-
})
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
})
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
class RequestTemplate {
|
|
68
|
-
requestUrl = '' // 请求地址
|
|
69
|
-
requestMethod = '' // 请求类型 GET POST
|
|
70
|
-
requestParams = {} // get请求的参数
|
|
71
|
-
triggerTime = -1 // 请求发生时间
|
|
72
|
-
constructor(config = {}) {
|
|
73
|
-
Object.keys(config).forEach(key => {
|
|
74
|
-
if (isValidKey(key, config)) {
|
|
75
|
-
this[key] = config[key] || null
|
|
76
|
-
}
|
|
77
|
-
})
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* xhr 请求拦截
|
|
83
|
-
*/
|
|
84
|
-
function interceptXHR(): void {
|
|
85
|
-
const _config = new RequestTemplate()
|
|
86
|
-
|
|
87
|
-
eventBus.addEvent({
|
|
88
|
-
type: EVENTTYPES.XHROPEN,
|
|
89
|
-
callback: (method, url) => {
|
|
90
|
-
_config.requestMethod = String(method).toLocaleLowerCase()
|
|
91
|
-
_config.requestUrl = url
|
|
92
|
-
_config.requestParams = parseGetParams(url)
|
|
93
|
-
}
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
eventBus.addEvent({
|
|
97
|
-
type: EVENTTYPES.XHRSEND,
|
|
98
|
-
callback: (that: XMLHttpRequest & any, body) => {
|
|
99
|
-
// readyState发生改变时触发,也就是请求状态改变时
|
|
100
|
-
// readyState 会依次变为 2,3,4 也就是会触发三次这里
|
|
101
|
-
on(that, EVENTTYPES.READYSTATECHANGE, function () {
|
|
102
|
-
const { readyState, status, responseURL, statusText } = that
|
|
103
|
-
const responseText =
|
|
104
|
-
that.responseType === '' || that.responseType === 'text'
|
|
105
|
-
? that.responseText
|
|
106
|
-
: ''
|
|
107
|
-
|
|
108
|
-
if (readyState === 4) {
|
|
109
|
-
const requestUrl = responseURL || _config.requestUrl
|
|
110
|
-
if (isIgnoreHttp(requestUrl)) return
|
|
111
|
-
|
|
112
|
-
// 请求已完成,且响应已就绪
|
|
113
|
-
if (status === 200 || status === 304) {
|
|
114
|
-
if (options.value.performance.server) {
|
|
115
|
-
handleSendPerformance({
|
|
116
|
-
eventId: SENDID.SERVER,
|
|
117
|
-
requestUrl,
|
|
118
|
-
requestMethod: _config.requestMethod,
|
|
119
|
-
requestType: 'xhr',
|
|
120
|
-
responseStatus: status,
|
|
121
|
-
duration: getTimestamp() - _config.triggerTime,
|
|
122
|
-
params:
|
|
123
|
-
_config.requestMethod === 'post'
|
|
124
|
-
? body
|
|
125
|
-
: _config.requestParams
|
|
126
|
-
})
|
|
127
|
-
}
|
|
128
|
-
} else if (options.value.error.server) {
|
|
129
|
-
handleSendError({
|
|
130
|
-
eventId: SENDID.SERVER,
|
|
131
|
-
errMessage: statusText || responseText,
|
|
132
|
-
requestUrl,
|
|
133
|
-
requestMethod: _config.requestMethod,
|
|
134
|
-
requestType: 'xhr',
|
|
135
|
-
responseStatus: status,
|
|
136
|
-
params:
|
|
137
|
-
_config.requestMethod === 'post' ? body : _config.requestParams
|
|
138
|
-
})
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
})
|
|
142
|
-
|
|
143
|
-
_config.triggerTime = getTimestamp()
|
|
144
|
-
}
|
|
145
|
-
})
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* 判断请求地址是否为需要拦截的
|
|
150
|
-
* @param url 请求地址
|
|
151
|
-
*/
|
|
152
|
-
function isIgnoreHttp(url: string): boolean {
|
|
153
|
-
if (!options.value.ignoreRequest.length) return false
|
|
154
|
-
if (!url) return false
|
|
155
|
-
|
|
156
|
-
return options.value.ignoreRequest.some(item => {
|
|
157
|
-
if (isRegExp(item)) {
|
|
158
|
-
if ((item as RegExp).test(url)) {
|
|
159
|
-
// debug(`ignoreRequest拦截成功 - 截条件:${item} 拦截地址:${url}`)
|
|
160
|
-
return true
|
|
161
|
-
} else {
|
|
162
|
-
return false
|
|
163
|
-
}
|
|
164
|
-
} else {
|
|
165
|
-
if (url === item) {
|
|
166
|
-
// debug(`ignoreRequest拦截成功 - 截条件:${item} 拦截地址:${url}`)
|
|
167
|
-
return true
|
|
168
|
-
} else {
|
|
169
|
-
return false
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
})
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* 初始化http监控
|
|
177
|
-
*/
|
|
178
|
-
function initHttp(): void {
|
|
179
|
-
if (!options.value.performance.server && !options.value.error.server) return
|
|
180
|
-
|
|
181
|
-
interceptXHR()
|
|
182
|
-
interceptFetch()
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* 卸载所有请求监听
|
|
187
|
-
*/
|
|
188
|
-
export function destroyHttp() {
|
|
189
|
-
// 清除HTTP请求相关的事件类型
|
|
190
|
-
eventBus.removeEvents([
|
|
191
|
-
EVENTTYPES.FETCH,
|
|
192
|
-
EVENTTYPES.XHROPEN,
|
|
193
|
-
EVENTTYPES.XHRSEND
|
|
194
|
-
])
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
export { initHttp }
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import type { ElementOrList, TargetGather, AnyObj } from '../types'
|
|
2
|
-
import { unKnowToArray, getTimestamp, getLocationHref } from '../utils'
|
|
3
|
-
import { sendData } from './sendData'
|
|
4
|
-
import { _support } from '../utils/global'
|
|
5
|
-
import { SEDNEVENTTYPES } from '../common'
|
|
6
|
-
|
|
7
|
-
interface IoMap {
|
|
8
|
-
[key: number]: IntersectionObserver
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
interface TargetMap {
|
|
12
|
-
target: Element
|
|
13
|
-
threshold: number
|
|
14
|
-
observeTime: number // sdk开始监视的时间
|
|
15
|
-
showTime?: number // sdk检测到的开始时间
|
|
16
|
-
showEndTime?: number // sdk检测到的结束时间
|
|
17
|
-
params?: AnyObj
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* 元素曝光收集
|
|
22
|
-
* 收集参数:曝光开始时间、曝光结束时间、被曝光元素上附带的额外参数
|
|
23
|
-
* 收集契机:划出目标元素的收集范围
|
|
24
|
-
*/
|
|
25
|
-
class Intersection {
|
|
26
|
-
private ioMap: IoMap = {}
|
|
27
|
-
private targetMap: TargetMap[] = []
|
|
28
|
-
private options = {
|
|
29
|
-
root: null,
|
|
30
|
-
rootMargin: '0px',
|
|
31
|
-
threshold: 0.5 // 阀值设为0.5,当只有比例达到一半时才触发回调函数
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* 针对 threshold 生成不同监听对象 (不允许同一个dom被两个监听对象监听)
|
|
35
|
-
* @param threshold 阈值
|
|
36
|
-
*/
|
|
37
|
-
private initObserver(threshold: number) {
|
|
38
|
-
return new IntersectionObserver(
|
|
39
|
-
entries => {
|
|
40
|
-
entries.forEach(entry => {
|
|
41
|
-
if (entry.isIntersecting) {
|
|
42
|
-
const targetObj = this.targetMap.find(
|
|
43
|
-
mapTarget => mapTarget.target === entry.target
|
|
44
|
-
)
|
|
45
|
-
if (targetObj) {
|
|
46
|
-
targetObj.showTime = getTimestamp()
|
|
47
|
-
}
|
|
48
|
-
} else {
|
|
49
|
-
const targetObj = this.targetMap.find(
|
|
50
|
-
mapTarget => mapTarget.target === entry.target
|
|
51
|
-
)
|
|
52
|
-
if (targetObj) {
|
|
53
|
-
// 在进入页面时指定了没有在屏幕可视界面的dom,会立即触发这里
|
|
54
|
-
// 此时需要根据有无 showTime 区分是否为一个完整事件再去发送
|
|
55
|
-
if (!targetObj.showTime) return
|
|
56
|
-
targetObj.showEndTime = getTimestamp()
|
|
57
|
-
this.sendEvent(targetObj)
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
})
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
...this.options,
|
|
64
|
-
threshold
|
|
65
|
-
}
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
/**
|
|
69
|
-
* 发送事件
|
|
70
|
-
*/
|
|
71
|
-
private sendEvent(targetObj: TargetMap) {
|
|
72
|
-
sendData.emit({
|
|
73
|
-
eventType: SEDNEVENTTYPES.INTERSECTION,
|
|
74
|
-
triggerPageUrl: getLocationHref(),
|
|
75
|
-
...targetObj
|
|
76
|
-
})
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* 开始观察目标元素
|
|
80
|
-
* 分为初始加载和过程中加载
|
|
81
|
-
* @param params 附带的额外参数
|
|
82
|
-
*/
|
|
83
|
-
public observe(gather: TargetGather | TargetGather[]) {
|
|
84
|
-
const _gather = unKnowToArray(gather)
|
|
85
|
-
_gather.forEach(item => {
|
|
86
|
-
const _targetList = unKnowToArray(item.target)
|
|
87
|
-
|
|
88
|
-
if (!Object.prototype.hasOwnProperty.call(this.ioMap, item.threshold)) {
|
|
89
|
-
this.ioMap[item.threshold] = this.initObserver(item.threshold || 0.5)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
_targetList.forEach(target => {
|
|
93
|
-
const index = this.targetMap.findIndex(
|
|
94
|
-
mapTarget => mapTarget.target === target
|
|
95
|
-
)
|
|
96
|
-
// 不允许重复观察
|
|
97
|
-
if (index === -1) {
|
|
98
|
-
this.ioMap[item.threshold].observe(target)
|
|
99
|
-
|
|
100
|
-
// 记录哪些元素被监听
|
|
101
|
-
this.targetMap.push({
|
|
102
|
-
target,
|
|
103
|
-
threshold: item.threshold,
|
|
104
|
-
observeTime: getTimestamp(), // 开始监听的时间
|
|
105
|
-
params: item.params
|
|
106
|
-
})
|
|
107
|
-
}
|
|
108
|
-
})
|
|
109
|
-
})
|
|
110
|
-
}
|
|
111
|
-
/**
|
|
112
|
-
* 对元素停止观察
|
|
113
|
-
*/
|
|
114
|
-
public unobserve(target: ElementOrList) {
|
|
115
|
-
const _targetList = unKnowToArray(target)
|
|
116
|
-
|
|
117
|
-
_targetList.forEach(_target => {
|
|
118
|
-
// 第一步:找出此元素代表的 threshold 值
|
|
119
|
-
const targetIndex = this.targetMap.findIndex(
|
|
120
|
-
mapTarget => mapTarget.target === _target
|
|
121
|
-
)
|
|
122
|
-
if (targetIndex === -1) return // 不存在的元素则跳过
|
|
123
|
-
|
|
124
|
-
// 第二步:根据 threshold 值从 ioMap 获取到 io 实例
|
|
125
|
-
const io = this.ioMap[this.targetMap[targetIndex].threshold]
|
|
126
|
-
if (!io) return
|
|
127
|
-
|
|
128
|
-
this.targetMap.splice(targetIndex, 1)
|
|
129
|
-
|
|
130
|
-
// 第二步:io 实例执行 unobserve 方法
|
|
131
|
-
io.unobserve(_target)
|
|
132
|
-
})
|
|
133
|
-
}
|
|
134
|
-
/**
|
|
135
|
-
* 对所有元素停止观察
|
|
136
|
-
*/
|
|
137
|
-
public disconnect() {
|
|
138
|
-
for (const key in this.ioMap) {
|
|
139
|
-
if (Object.prototype.hasOwnProperty.call(this.ioMap, key)) {
|
|
140
|
-
const io = this.ioMap[key]
|
|
141
|
-
io.disconnect()
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
this.targetMap = []
|
|
145
|
-
this.ioMap = {}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
export let intersection: Intersection
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* 初始化曝光监听
|
|
153
|
-
*/
|
|
154
|
-
export function initIntersection() {
|
|
155
|
-
_support.intersection = new Intersection()
|
|
156
|
-
intersection = _support.intersection
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* 卸载所有曝光监听
|
|
161
|
-
*/
|
|
162
|
-
export function destroyIntersection() {
|
|
163
|
-
intersection?.disconnect()
|
|
164
|
-
}
|
package/src/lib/line-status.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { _support } from '../utils/global'
|
|
2
|
-
import { EVENTTYPES } from '../common'
|
|
3
|
-
import { eventBus } from './eventBus'
|
|
4
|
-
import { debug } from '../utils/debug'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* 监听网络状态
|
|
8
|
-
* 当处于断网状态下的所有埋点事件都无效(认为此时采集的数据大部分是无效的)
|
|
9
|
-
*/
|
|
10
|
-
export class LineStatus {
|
|
11
|
-
onLine = true
|
|
12
|
-
constructor() {
|
|
13
|
-
this.init()
|
|
14
|
-
}
|
|
15
|
-
init() {
|
|
16
|
-
eventBus.addEvent({
|
|
17
|
-
type: EVENTTYPES.OFFLINE,
|
|
18
|
-
callback: e => {
|
|
19
|
-
if (e.type === 'offline') {
|
|
20
|
-
debug('网络断开')
|
|
21
|
-
this.onLine = false
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
})
|
|
25
|
-
eventBus.addEvent({
|
|
26
|
-
type: EVENTTYPES.ONLINE,
|
|
27
|
-
callback: e => {
|
|
28
|
-
if (e.type === 'online') {
|
|
29
|
-
debug('网络连接')
|
|
30
|
-
this.onLine = true
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
})
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export let lineStatus: LineStatus
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* 初始化网络监听
|
|
41
|
-
*/
|
|
42
|
-
export function initLineStatus() {
|
|
43
|
-
_support.lineStatus = new LineStatus()
|
|
44
|
-
lineStatus = _support.lineStatus
|
|
45
|
-
}
|