web-tracing-core 2.1.1 → 2.1.2
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/__test__/css/performance.css +3 -0
- package/__test__/err-batch.spec.ts +47 -0
- package/__test__/err.spec.ts +82 -0
- package/__test__/event.spec.ts +62 -0
- package/__test__/html/performance.html +57 -0
- package/__test__/html/recordscreen.html +39 -0
- package/__test__/http.spec.ts +143 -0
- package/__test__/img/performance.png +0 -0
- package/__test__/js/performance.js +3 -0
- package/__test__/performance.spec.ts +115 -0
- package/__test__/recordscreen.spec.ts +50 -0
- package/__test__/utils/index.ts +132 -0
- package/__test__/utils/pollify.ts +14 -0
- package/__test__/utils.spec.ts +18 -0
- package/{index.cjs → dist/index.cjs} +1 -1
- package/{index.iife.js → dist/index.iife.js} +1 -1
- package/{index.iife.min.js → dist/index.iife.min.js} +1 -1
- package/{index.mjs → dist/index.mjs} +1 -1
- package/dist/package.json +49 -0
- package/index.ts +76 -0
- package/package.json +9 -9
- package/src/common/config.ts +13 -0
- package/src/common/constant.ts +57 -0
- package/src/common/index.ts +2 -0
- package/src/lib/base.ts +129 -0
- package/src/lib/err-batch.ts +134 -0
- package/src/lib/err.ts +323 -0
- package/src/lib/event-dwell.ts +63 -0
- package/src/lib/event.ts +252 -0
- package/src/lib/eventBus.ts +97 -0
- package/src/lib/exportMethods.ts +208 -0
- package/src/lib/http.ts +197 -0
- package/src/lib/intersectionObserver.ts +169 -0
- package/src/lib/line-status.ts +45 -0
- package/src/lib/options.ts +325 -0
- package/src/lib/performance.ts +302 -0
- package/src/lib/pv.ts +199 -0
- package/src/lib/recordscreen.ts +169 -0
- package/src/lib/replace.ts +371 -0
- package/src/lib/sendData.ts +264 -0
- package/src/observer/computed.ts +52 -0
- package/src/observer/config.ts +1 -0
- package/src/observer/dep.ts +21 -0
- package/src/observer/index.ts +91 -0
- package/src/observer/ref.ts +80 -0
- package/src/observer/types.ts +22 -0
- package/src/observer/watch.ts +19 -0
- package/src/observer/watcher.ts +88 -0
- package/src/types/index.ts +126 -0
- package/src/utils/debug.ts +17 -0
- package/src/utils/element.ts +47 -0
- package/src/utils/fingerprintjs.ts +2132 -0
- package/src/utils/getIps.ts +127 -0
- package/src/utils/global.ts +50 -0
- package/src/utils/index.ts +552 -0
- package/src/utils/is.ts +78 -0
- package/src/utils/localStorage.ts +70 -0
- package/src/utils/polyfill.ts +11 -0
- package/src/utils/session.ts +29 -0
- /package/{LICENSE → dist/LICENSE} +0 -0
- /package/{README.md → dist/README.md} +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
package/src/lib/event.ts
ADDED
|
@@ -0,0 +1,252 @@
|
|
|
1
|
+
import { isValidKey, getLocationHref, getTimestamp } from '../utils'
|
|
2
|
+
import { getElByAttr, isSimpleEl, getNodeXPath } from '../utils/element'
|
|
3
|
+
import { sendData } from './sendData'
|
|
4
|
+
import { eventBus } from './eventBus'
|
|
5
|
+
import { EVENTTYPES, SEDNEVENTTYPES } from '../common'
|
|
6
|
+
import { options } from './options'
|
|
7
|
+
|
|
8
|
+
class RequestTemplateClick {
|
|
9
|
+
eventId = '' // 事件ID
|
|
10
|
+
eventType = '' // 事件类型
|
|
11
|
+
title = '' // 事件名
|
|
12
|
+
triggerPageUrl = '' // 当前页面URL
|
|
13
|
+
x = -1 // 被点击元素与屏幕左边距离
|
|
14
|
+
y = -1 // 被点击元素与屏幕上边距离
|
|
15
|
+
params = {} // 事件参数
|
|
16
|
+
elementPath = '' // 被点击元素的层级
|
|
17
|
+
triggerTime = -1 // 事件发生时间
|
|
18
|
+
constructor(config = {}) {
|
|
19
|
+
Object.keys(config).forEach(key => {
|
|
20
|
+
if (isValidKey(key, config)) {
|
|
21
|
+
this[key] = config[key] || null
|
|
22
|
+
}
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* 监听 - 点击事件
|
|
29
|
+
*/
|
|
30
|
+
function clickCollection() {
|
|
31
|
+
eventBus.addEvent({
|
|
32
|
+
type: EVENTTYPES.CLICK,
|
|
33
|
+
callback: (e: MouseEvent) => {
|
|
34
|
+
const _config = new RequestTemplateClick({
|
|
35
|
+
eventType: SEDNEVENTTYPES.CLICK
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
// 获取被点击的元素到最外层元素组成的数组
|
|
39
|
+
const path: HTMLElement[] = e.composedPath()
|
|
40
|
+
? (e.composedPath() as HTMLElement[])
|
|
41
|
+
: e.target
|
|
42
|
+
? getNodePath(e.target as HTMLElement)
|
|
43
|
+
: []
|
|
44
|
+
|
|
45
|
+
// 检查被点击的元素以及其父级元素是否有这些属性(从内到外)
|
|
46
|
+
const target = path.find(
|
|
47
|
+
el =>
|
|
48
|
+
el.hasAttribute &&
|
|
49
|
+
(el.hasAttribute('data-warden-container') ||
|
|
50
|
+
el.hasAttribute('data-warden-event-id') ||
|
|
51
|
+
el.hasAttribute('data-warden-title'))
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
if (!target) return
|
|
55
|
+
|
|
56
|
+
const { scrollTop, scrollLeft } = document.documentElement // html距离上和左侧的距离(一般都是0)
|
|
57
|
+
const { top, left } = (e.target as HTMLElement).getBoundingClientRect() // 元素距离html的距离
|
|
58
|
+
_config.x = left + scrollLeft
|
|
59
|
+
_config.y = top + scrollTop
|
|
60
|
+
_config.triggerTime = getTimestamp() // 点击时间
|
|
61
|
+
_config.triggerPageUrl = getLocationHref() // 当前页面的url
|
|
62
|
+
_config.title = extractTitleByTarget(target) // 获取title属性
|
|
63
|
+
_config.eventId = extractDataByPath(path) // 提取数据事件ID
|
|
64
|
+
_config.params = extractParamsByPath(path) // 提取数据参数
|
|
65
|
+
_config.elementPath = getNodeXPath(target).slice(-128) // 长度限制128字符
|
|
66
|
+
sendData.emit(_config)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* 获取目标元素到最外层元素组成的数组
|
|
73
|
+
*/
|
|
74
|
+
function getNodePath(
|
|
75
|
+
node: HTMLElement,
|
|
76
|
+
options = { includeSelf: true, order: 'asc' }
|
|
77
|
+
) {
|
|
78
|
+
if (!node) return []
|
|
79
|
+
const { includeSelf, order } = options
|
|
80
|
+
let parent = includeSelf ? node : node.parentElement
|
|
81
|
+
let result: HTMLElement[] = []
|
|
82
|
+
while (parent) {
|
|
83
|
+
result = order === 'asc' ? result.concat(parent) : [parent].concat(result)
|
|
84
|
+
parent = parent.parentElement
|
|
85
|
+
}
|
|
86
|
+
return result
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* 获取title属性(data-warden-title 或者 title)
|
|
91
|
+
*/
|
|
92
|
+
function extractTitleByTarget(target: HTMLElement) {
|
|
93
|
+
const selfTitle = getNodeTitle(target)
|
|
94
|
+
if (selfTitle) return selfTitle
|
|
95
|
+
|
|
96
|
+
// 向上找其父节点
|
|
97
|
+
let container = target.parentElement
|
|
98
|
+
|
|
99
|
+
while (container && container !== document.body) {
|
|
100
|
+
if (container.hasAttribute('data-warden-container')) break
|
|
101
|
+
container = container.parentElement
|
|
102
|
+
}
|
|
103
|
+
const superTitle = getNodeTitle(container)
|
|
104
|
+
if (superTitle) return superTitle
|
|
105
|
+
|
|
106
|
+
// 自身以及父级都没有拿到 title 值的情况下
|
|
107
|
+
const { tagName } = target
|
|
108
|
+
return !target.hasChildNodes() || tagName.toLowerCase() === 'svg'
|
|
109
|
+
? handleLeafNode(target)
|
|
110
|
+
: handleNoLeafNode(target)
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* 获取元素的 data-warden-title 属性或者 title属性
|
|
114
|
+
*/
|
|
115
|
+
function getNodeTitle(node: HTMLElement | null) {
|
|
116
|
+
if (node) {
|
|
117
|
+
return node.hasAttribute('data-warden-title')
|
|
118
|
+
? node.getAttribute('data-warden-title')
|
|
119
|
+
: node.title
|
|
120
|
+
}
|
|
121
|
+
return ''
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 获取 title - 叶子元素的情况下,取其特殊值
|
|
125
|
+
* 叶子元素(也就是不包含其他HTML元素,也不能有文本内容)
|
|
126
|
+
*/
|
|
127
|
+
function handleLeafNode(target: any) {
|
|
128
|
+
const { tagName, textContent } = target
|
|
129
|
+
if (tagName === 'IMG') return target.getAttribute('alt') || null
|
|
130
|
+
if (tagName === 'svg') {
|
|
131
|
+
const a = [...Array(target.children)].find(item => item.tagName === 'use')
|
|
132
|
+
if (a) return a.getAttribute('xlink:href') || null
|
|
133
|
+
}
|
|
134
|
+
return textContent
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* 获取 title - 非叶子元素的情况
|
|
138
|
+
*/
|
|
139
|
+
function handleNoLeafNode(target: Element) {
|
|
140
|
+
const { tagName, textContent } = target
|
|
141
|
+
if (tagName === 'A') {
|
|
142
|
+
const res = isSimpleEl([...Array.from(target.children)])
|
|
143
|
+
return res ? textContent : target.getAttribute('href') || null
|
|
144
|
+
}
|
|
145
|
+
if (tagName === 'BUTTON') {
|
|
146
|
+
const name = target.getAttribute('name')
|
|
147
|
+
const res = isSimpleEl([...Array.from(target.children)])
|
|
148
|
+
return name || res ? textContent : target.getAttribute('href') || null
|
|
149
|
+
}
|
|
150
|
+
const { length } = [...Array.from(target.children)].filter(() =>
|
|
151
|
+
target.hasChildNodes()
|
|
152
|
+
)
|
|
153
|
+
return length > 0 ? null : textContent
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* 提取数据事件ID
|
|
158
|
+
*/
|
|
159
|
+
function extractDataByPath(list: HTMLElement[] = []) {
|
|
160
|
+
// data-warden-event-id
|
|
161
|
+
const hasIdEl = getElByAttr(list, 'data-warden-event-id')
|
|
162
|
+
if (hasIdEl) return hasIdEl.getAttribute('data-warden-event-id')!
|
|
163
|
+
|
|
164
|
+
// title
|
|
165
|
+
const hasTitleEl = getElByAttr(list, 'title')
|
|
166
|
+
if (hasTitleEl) return hasTitleEl.getAttribute('title')!
|
|
167
|
+
|
|
168
|
+
// container
|
|
169
|
+
const container = getElByAttr(list, 'data-warden-container')
|
|
170
|
+
if (container) {
|
|
171
|
+
if (container.getAttribute('data-warden-event-id')) {
|
|
172
|
+
return container.getAttribute('data-warden-event-id')!
|
|
173
|
+
}
|
|
174
|
+
if (container.getAttribute('title')) {
|
|
175
|
+
return container.getAttribute('title')!
|
|
176
|
+
}
|
|
177
|
+
const id2 = container.getAttribute('data-warden-container')!
|
|
178
|
+
if (typeof id2 === 'string' && id2) return id2
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// 都没有则以 tagname 去当做ID
|
|
182
|
+
return list[0].tagName.toLowerCase()
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* 提取数据参数
|
|
187
|
+
* 如果本身节点没有埋点属性的话会用父级埋点属性
|
|
188
|
+
*/
|
|
189
|
+
function extractParamsByPath(list: HTMLElement[] = []) {
|
|
190
|
+
const regex = /^data-warden-/
|
|
191
|
+
let target
|
|
192
|
+
let targetIndex = -1
|
|
193
|
+
|
|
194
|
+
// 遍历从子节点到body下最大的节点,遍历他们的属性,直到某个节点的属性能通过校验的节点
|
|
195
|
+
for (let index = 0; index < list.length; index++) {
|
|
196
|
+
const el = list[index]
|
|
197
|
+
const attributes = (el && el.attributes && Array.from(el.attributes)) || []
|
|
198
|
+
target = attributes.find(item =>
|
|
199
|
+
item.nodeName.match(regex)
|
|
200
|
+
? item.nodeName.match(regex)
|
|
201
|
+
: item.nodeName.indexOf('data-warden-container') !== -1
|
|
202
|
+
)
|
|
203
|
+
if (target) {
|
|
204
|
+
targetIndex = index
|
|
205
|
+
break
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (targetIndex < 0) return {}
|
|
209
|
+
|
|
210
|
+
const container = list[targetIndex]
|
|
211
|
+
const attrList = Array.from(container.attributes) || []
|
|
212
|
+
const params: Record<string, string | null> = {}
|
|
213
|
+
const defaultKey = ['container', 'title', 'event-id']
|
|
214
|
+
attrList.forEach(item => {
|
|
215
|
+
if (item.nodeName.indexOf('data-warden') < 0) return // 过滤非标准命名 如 data-v-fbcf7454
|
|
216
|
+
const key = item.nodeName.replace(regex, '')
|
|
217
|
+
if (defaultKey.includes(key)) return // 过滤sdk自定义属性
|
|
218
|
+
params[key] = item.nodeValue
|
|
219
|
+
})
|
|
220
|
+
|
|
221
|
+
return params
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function initEvent() {
|
|
225
|
+
options.value.event.core && clickCollection()
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* 主动触发事件上报
|
|
230
|
+
* @param options 自定义配置信息
|
|
231
|
+
*/
|
|
232
|
+
function handleSendEvent(options = {}, flush = false) {
|
|
233
|
+
sendData.emit(
|
|
234
|
+
{
|
|
235
|
+
...options,
|
|
236
|
+
eventType: SEDNEVENTTYPES.CUSTOM,
|
|
237
|
+
triggerTime: getTimestamp(),
|
|
238
|
+
triggerPageUrl: getLocationHref()
|
|
239
|
+
},
|
|
240
|
+
flush
|
|
241
|
+
)
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* 卸载所有事件监听
|
|
246
|
+
*/
|
|
247
|
+
export function destroyEvent() {
|
|
248
|
+
// 清除事件相关的事件类型
|
|
249
|
+
eventBus.removeEvents([EVENTTYPES.CLICK, EVENTTYPES.LOAD])
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
export { initEvent, handleSendEvent }
|
|
@@ -0,0 +1,97 @@
|
|
|
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 }
|
|
@@ -0,0 +1,208 @@
|
|
|
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
|
+
}
|