keeson-web-report-sdk 1.0.3 → 1.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/bundle.min.js +1 -432
- package/package.json +12 -2
package/bundle.min.js
CHANGED
|
@@ -1,432 +1 @@
|
|
|
1
|
-
(function (
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.umd = {}));
|
|
5
|
-
})(this, (function (exports) { 'use strict';
|
|
6
|
-
|
|
7
|
-
// 错误上报
|
|
8
|
-
|
|
9
|
-
// 全局错误处理
|
|
10
|
-
function globalErrorHandler(callback) {
|
|
11
|
-
window.onerror = function (msg, url, line, col, error) {
|
|
12
|
-
callback && callback({msg, url, line, col, error});
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function promiseErrorHandler(callback) {
|
|
17
|
-
window.addEventListener("unhandledrejection", function (event) {
|
|
18
|
-
// console.log("Unhandled Promise Rejection:", event.reason);
|
|
19
|
-
callback && callback(event);
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* @param {*} v vue2的话是Vue,vue3的话是app
|
|
25
|
-
*/
|
|
26
|
-
function vueErrorHandler(v, callback) {
|
|
27
|
-
// vue2 vue3
|
|
28
|
-
v.config.errorHandler = function (err, vm, info) {
|
|
29
|
-
// handle error
|
|
30
|
-
// `info` 是 Vue 特定的错误信息,比如错误发生在哪一个组件上
|
|
31
|
-
console.error(`Error in ${info}:`, err);
|
|
32
|
-
callback && callback({err, vm, info});
|
|
33
|
-
};
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
// react
|
|
37
|
-
// export function reactErrorHandler() {
|
|
38
|
-
// }
|
|
39
|
-
|
|
40
|
-
// 性能上报
|
|
41
|
-
function reportPerformance(callback) {
|
|
42
|
-
if (PerformanceNavigationTiming) {
|
|
43
|
-
const time =
|
|
44
|
-
PerformanceNavigationTiming.loadEventEnd -
|
|
45
|
-
PerformanceNavigationTiming.navigationStart;
|
|
46
|
-
console.log("Page load time: " + time + "ms");
|
|
47
|
-
|
|
48
|
-
const lcp = PerformanceNavigationTiming.getEntriesByType(
|
|
49
|
-
"largest-contentful-paint"
|
|
50
|
-
)[0];
|
|
51
|
-
console.log("Largest Contentful Paint:", lcp.startTime);
|
|
52
|
-
const fcp = PerformanceNavigationTiming.getEntriesByType(
|
|
53
|
-
"first-contentful-paint"
|
|
54
|
-
)[0];
|
|
55
|
-
console.log("First Contentful Paint:", fcp.startTime);
|
|
56
|
-
const cls = PerformanceNavigationTiming.getEntriesByType("layout-shift")[0];
|
|
57
|
-
console.log("Cumulative Layout Shift:", cls.value);
|
|
58
|
-
const fmp =
|
|
59
|
-
PerformanceNavigationTiming.getEntriesByType("first-input-delay")[0];
|
|
60
|
-
console.log("First Input Delay:", fmp.startTime);
|
|
61
|
-
console.log("Total Blocking Time:", fmp.value);
|
|
62
|
-
const FID = PerformanceNavigationTiming.getEntriesByType("first-input")[0];
|
|
63
|
-
console.log("First Input:", FID.startTime);
|
|
64
|
-
|
|
65
|
-
// 计算DNS查询时间
|
|
66
|
-
const dnsTime =
|
|
67
|
-
PerformanceNavigationTiming.domainLookupEnd -
|
|
68
|
-
PerformanceNavigationTiming.domainLookupStart;
|
|
69
|
-
console.log("DNS查询时间:", dnsTime);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
callback && callback({
|
|
73
|
-
time,
|
|
74
|
-
lcp,
|
|
75
|
-
fcp,
|
|
76
|
-
cls,
|
|
77
|
-
fmp,
|
|
78
|
-
FID,
|
|
79
|
-
dnsTime
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
function xhrReportHandle(onsuccess, onerror) {
|
|
85
|
-
var oldOpen = XMLHttpRequest.prototype.open;
|
|
86
|
-
XMLHttpRequest.prototype.open = function (method, url, async, user, pass) {
|
|
87
|
-
let startTime = Date.now();
|
|
88
|
-
this.addEventListener("load", function () {
|
|
89
|
-
const endTime = Date.now();
|
|
90
|
-
const duration = endTime - startTime;
|
|
91
|
-
onsuccess &&
|
|
92
|
-
onsuccess({
|
|
93
|
-
url: url,
|
|
94
|
-
method: method,
|
|
95
|
-
duration: duration,
|
|
96
|
-
status: this.status,
|
|
97
|
-
statusText: this.statusText,
|
|
98
|
-
response: this.responseText,
|
|
99
|
-
});
|
|
100
|
-
// 可以在这里处理响应
|
|
101
|
-
console.log("Response:", this.responseText);
|
|
102
|
-
});
|
|
103
|
-
this.addEventListener("error", function () {
|
|
104
|
-
console.log("Error:", this.statusText);
|
|
105
|
-
onerror &&
|
|
106
|
-
onerror({
|
|
107
|
-
url: url,
|
|
108
|
-
method: method,
|
|
109
|
-
duration: duration,
|
|
110
|
-
status: this.status,
|
|
111
|
-
statusText: this.statusText,
|
|
112
|
-
response: this.responseText,
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
// 修改或记录原始请求信息
|
|
116
|
-
console.log("Request URL:", url);
|
|
117
|
-
console.log("Request Method:", method);
|
|
118
|
-
// 继续原有的open调用
|
|
119
|
-
oldOpen.call(this, method, url, async, user, pass);
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
function fetchReportHandle(onsuccess, onerror) {
|
|
124
|
-
var realFetch = window.fetch;
|
|
125
|
-
window.fetch = function (url, options) {
|
|
126
|
-
console.log("Fetch URL:", url);
|
|
127
|
-
console.log("Fetch Options:", options);
|
|
128
|
-
// 可以在这里修改options,例如添加headers等
|
|
129
|
-
if (options && options.headers) {
|
|
130
|
-
options.headers["X-Custom-Header"] = "Value";
|
|
131
|
-
}
|
|
132
|
-
let startTime = Date.now();
|
|
133
|
-
// 继续原有的fetch调用
|
|
134
|
-
return realFetch(url, options)
|
|
135
|
-
.then((response) => {
|
|
136
|
-
const endTime = Date.now();
|
|
137
|
-
const duration = endTime - startTime;
|
|
138
|
-
onsuccess &&
|
|
139
|
-
onsuccess({
|
|
140
|
-
url: url,
|
|
141
|
-
method: method,
|
|
142
|
-
duration: duration,
|
|
143
|
-
status: response.status,
|
|
144
|
-
statusText: response.statusText,
|
|
145
|
-
response: response.responseText,
|
|
146
|
-
});
|
|
147
|
-
// 可以在这里处理响应
|
|
148
|
-
console.log("Response:", response);
|
|
149
|
-
return response;
|
|
150
|
-
})
|
|
151
|
-
.catch((error) => {
|
|
152
|
-
console.log("Error:", error);
|
|
153
|
-
onerror &&
|
|
154
|
-
onerror({
|
|
155
|
-
url: url,
|
|
156
|
-
method: method,
|
|
157
|
-
duration: duration,
|
|
158
|
-
// status: response.status,
|
|
159
|
-
// statusText: response.statusText,
|
|
160
|
-
// response: response.responseText,
|
|
161
|
-
});
|
|
162
|
-
});
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
// 用户行为上报
|
|
167
|
-
|
|
168
|
-
// 路由跳转监听
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* 监听地址栏路由变化,包括传统路由和虚拟路由(如Vue Router、React Router)
|
|
172
|
-
* 通过监听History API和popstate事件实现
|
|
173
|
-
* @param {Function} callback 路由变化时的回调函数,接收{ to, from }参数
|
|
174
|
-
* @returns {Function} 清理函数,用于移除监听
|
|
175
|
-
*/
|
|
176
|
-
function routeChangeHandler(callback) {
|
|
177
|
-
// 保存原始的pushState和replaceState方法
|
|
178
|
-
const originalPushState = history.pushState;
|
|
179
|
-
const originalReplaceState = history.replaceState;
|
|
180
|
-
|
|
181
|
-
// 重写pushState方法
|
|
182
|
-
history.pushState = function (...args) {
|
|
183
|
-
const from = window.location.href;
|
|
184
|
-
const result = originalPushState.apply(this, args);
|
|
185
|
-
const to = window.location.href;
|
|
186
|
-
if (from !== to) {
|
|
187
|
-
callback({ to, from });
|
|
188
|
-
}
|
|
189
|
-
return result;
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
// 重写replaceState方法
|
|
193
|
-
history.replaceState = function (...args) {
|
|
194
|
-
const from = window.location.href;
|
|
195
|
-
const result = originalReplaceState.apply(this, args);
|
|
196
|
-
const to = window.location.href;
|
|
197
|
-
if (from !== to) {
|
|
198
|
-
callback({ to, from });
|
|
199
|
-
}
|
|
200
|
-
return result;
|
|
201
|
-
};
|
|
202
|
-
|
|
203
|
-
// 监听popstate事件(back/forward按钮)
|
|
204
|
-
const popstateHandler = () => {
|
|
205
|
-
// 对于popstate事件,我们无法直接获取from,所以使用当前URL作为from和to
|
|
206
|
-
// 在实际应用中,可以通过维护一个路由历史栈来获取更准确的from信息
|
|
207
|
-
callback({ to: window.location.href, from: window.location.href });
|
|
208
|
-
};
|
|
209
|
-
window.addEventListener("popstate", popstateHandler);
|
|
210
|
-
|
|
211
|
-
// 返回清理函数
|
|
212
|
-
return () => {
|
|
213
|
-
window.removeEventListener("popstate", popstateHandler);
|
|
214
|
-
// 恢复原始方法
|
|
215
|
-
history.pushState = originalPushState;
|
|
216
|
-
history.replaceState = originalReplaceState;
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
// /**
|
|
221
|
-
// * Vue Router路由监听
|
|
222
|
-
// * @param {Object} router Vue Router实例
|
|
223
|
-
// * @param {Function} callback 路由变化时的回调函数,接收{ to, from }参数
|
|
224
|
-
// * @returns {Function} 清理函数,用于移除监听
|
|
225
|
-
// */
|
|
226
|
-
// function vueRouterChangeHandler(router, callback) {
|
|
227
|
-
// if (!router) {
|
|
228
|
-
// console.warn('Vue Router实例未提供,无法监听路由变化');
|
|
229
|
-
// return () => {};
|
|
230
|
-
// }
|
|
231
|
-
|
|
232
|
-
// // 使用Vue Router的beforeEach钩子监听路由变化
|
|
233
|
-
// const removeRouterHook = router.beforeEach((to, from, next) => {
|
|
234
|
-
// callback({ to, from });
|
|
235
|
-
// next();
|
|
236
|
-
// });
|
|
237
|
-
|
|
238
|
-
// // 同时监听History API变化,确保覆盖所有路由变化场景
|
|
239
|
-
// const removeHistoryListener = routeChangeHandler(callback);
|
|
240
|
-
|
|
241
|
-
// // 返回组合的清理函数
|
|
242
|
-
// return () => {
|
|
243
|
-
// removeRouterHook();
|
|
244
|
-
// removeHistoryListener();
|
|
245
|
-
// };
|
|
246
|
-
// }
|
|
247
|
-
|
|
248
|
-
// /**
|
|
249
|
-
// * React Router路由监听(支持v4+)
|
|
250
|
-
// * @param {Object} history React Router的history对象
|
|
251
|
-
// * @param {Function} callback 路由变化时的回调函数,接收{ to, from }参数
|
|
252
|
-
// * @returns {Function} 清理函数,用于移除监听
|
|
253
|
-
// */
|
|
254
|
-
// function reactRouterChangeHandler(history, callback) {
|
|
255
|
-
// if (!history) {
|
|
256
|
-
// console.warn('React Router的history对象未提供,无法监听路由变化');
|
|
257
|
-
// return () => {};
|
|
258
|
-
// }
|
|
259
|
-
|
|
260
|
-
// let lastLocation = history.location;
|
|
261
|
-
|
|
262
|
-
// // 使用history.listen监听路由变化
|
|
263
|
-
// const unlisten = history.listen((location) => {
|
|
264
|
-
// callback({ to: location, from: lastLocation });
|
|
265
|
-
// lastLocation = location;
|
|
266
|
-
// });
|
|
267
|
-
|
|
268
|
-
// // 同时监听History API变化,确保覆盖所有路由变化场景
|
|
269
|
-
// const removeHistoryListener = routeChangeHandler(callback);
|
|
270
|
-
|
|
271
|
-
// // 返回组合的清理函数
|
|
272
|
-
// return () => {
|
|
273
|
-
// unlisten();
|
|
274
|
-
// removeHistoryListener();
|
|
275
|
-
// };
|
|
276
|
-
// }
|
|
277
|
-
|
|
278
|
-
/**
|
|
279
|
-
* 初始化路由监听
|
|
280
|
-
* @param {Object} options 配置选项
|
|
281
|
-
* @param {Object} [options.vueRouter] Vue Router实例
|
|
282
|
-
* @param {Object} [options.reactHistory] React Router的history对象
|
|
283
|
-
* @param {Function} callback 路由变化时的回调函数
|
|
284
|
-
* @returns {Function} 清理函数,用于移除所有监听
|
|
285
|
-
*/
|
|
286
|
-
function initRouteListener(callback) {
|
|
287
|
-
const cleanups = [];
|
|
288
|
-
|
|
289
|
-
// // 如果提供了Vue Router实例,使用Vue Router的监听方式
|
|
290
|
-
// if (options.vueRouter) {
|
|
291
|
-
// cleanups.push(vueRouterChangeHandler(options.vueRouter, callback));
|
|
292
|
-
// }
|
|
293
|
-
|
|
294
|
-
// // 如果提供了React Router的history对象,使用React Router的监听方式
|
|
295
|
-
// else if (options.reactHistory) {
|
|
296
|
-
// cleanups.push(reactRouterChangeHandler(options.reactHistory, callback));
|
|
297
|
-
// }
|
|
298
|
-
|
|
299
|
-
// // 否则使用通用的路由监听方式
|
|
300
|
-
// else {
|
|
301
|
-
// cleanups.push(routeChangeHandler(callback));
|
|
302
|
-
// }
|
|
303
|
-
cleanups.push(routeChangeHandler(callback));
|
|
304
|
-
// 返回组合的清理函数
|
|
305
|
-
return () => {
|
|
306
|
-
cleanups.forEach((cleanup) => cleanup());
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const defaultOptions = {
|
|
311
|
-
appId: "", // appId
|
|
312
|
-
// appName: '',
|
|
313
|
-
// appVersion: '',
|
|
314
|
-
env: "production",
|
|
315
|
-
appUrl: window.location.origin, // 站点地址, 对应应用配置网站站点地址
|
|
316
|
-
|
|
317
|
-
reportError: true,
|
|
318
|
-
reportPromiseReject: true,
|
|
319
|
-
reportVueError: true,
|
|
320
|
-
vueInstance: null,
|
|
321
|
-
|
|
322
|
-
reportPerformance: true, // 是否上报性能数据
|
|
323
|
-
|
|
324
|
-
reportLongTimeRequest: true, // 是否上报长请求时间接口
|
|
325
|
-
longTimeRequestThreshold: 2000, // 长请求时间阈值,单位毫秒
|
|
326
|
-
reportErrorReqest: true, // 是否上报报错请求
|
|
327
|
-
|
|
328
|
-
reportUserNavigate: true, // 是否上报用户导航行为
|
|
329
|
-
};
|
|
330
|
-
|
|
331
|
-
class Report {
|
|
332
|
-
records = [];
|
|
333
|
-
timer = null;
|
|
334
|
-
options = {};
|
|
335
|
-
constructor(options) {
|
|
336
|
-
this.options = { ...defaultOptions, ...options };
|
|
337
|
-
}
|
|
338
|
-
init() {
|
|
339
|
-
// listen and callback
|
|
340
|
-
if (this.options.reportError) {
|
|
341
|
-
globalErrorHandler(({ msg, url, line, col, error }) => {
|
|
342
|
-
console.log({ msg, url, line, col, error });
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
if (this.options.reportPromiseReject) {
|
|
346
|
-
promiseErrorHandler((event) => {
|
|
347
|
-
console.log("Unhandled Promise Rejection:", event, event.reason);
|
|
348
|
-
});
|
|
349
|
-
}
|
|
350
|
-
if (this.options.reportVueError && this.options.vueInstance) {
|
|
351
|
-
vueErrorHandler(
|
|
352
|
-
this.options.vueInstance,
|
|
353
|
-
({ err, vm, info }) => {
|
|
354
|
-
console.log("Vue error:", err, vm, info);
|
|
355
|
-
}
|
|
356
|
-
);
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
if (this.options.reportPerformance) {
|
|
360
|
-
reportPerformance(
|
|
361
|
-
({ time, lcp, fcp, cls, fmp, FID, dnsTime }) => {
|
|
362
|
-
console.log({
|
|
363
|
-
time,
|
|
364
|
-
lcp,
|
|
365
|
-
fcp,
|
|
366
|
-
cls,
|
|
367
|
-
fmp,
|
|
368
|
-
FID,
|
|
369
|
-
dnsTime,
|
|
370
|
-
});
|
|
371
|
-
}
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if (this.options.reportLongTimeRequest) {
|
|
376
|
-
xhrReportHandle(
|
|
377
|
-
(duration) => {
|
|
378
|
-
console.log(duration);
|
|
379
|
-
},
|
|
380
|
-
(error) => {
|
|
381
|
-
console.log(error);
|
|
382
|
-
}
|
|
383
|
-
);
|
|
384
|
-
fetchReportHandle(
|
|
385
|
-
(duration) => {
|
|
386
|
-
console.log(duration);
|
|
387
|
-
},
|
|
388
|
-
(error) => {
|
|
389
|
-
console.log(error);
|
|
390
|
-
}
|
|
391
|
-
);
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
if (this.options.reportUserNavigate) {
|
|
395
|
-
const href = window.location.href;
|
|
396
|
-
// 上报当前路由
|
|
397
|
-
console.log("current href:", href);
|
|
398
|
-
initRouteListener((record) => {
|
|
399
|
-
// 上报路由变化
|
|
400
|
-
// this.addReportRecord(record);
|
|
401
|
-
console.log("route change:", record);
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
addReportRecord(record) {
|
|
406
|
-
this.timer && clearTimeout(this.timer);
|
|
407
|
-
this.timer = setTimeout(() => {
|
|
408
|
-
try {
|
|
409
|
-
this.sendReport(JSON.parse(JSON.stringify(this.records)));
|
|
410
|
-
this.records = [];
|
|
411
|
-
} catch (error) {
|
|
412
|
-
console.log(error);
|
|
413
|
-
}
|
|
414
|
-
}, 1000);
|
|
415
|
-
this.records.push(record);
|
|
416
|
-
}
|
|
417
|
-
sendReport(records) {
|
|
418
|
-
// if(this.records.length === 0) return;
|
|
419
|
-
// todo: 上报数据 api
|
|
420
|
-
this.apiDo(this.records);
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
let report;
|
|
425
|
-
function init(options = {}) {
|
|
426
|
-
if (!report) report = new Report(options);
|
|
427
|
-
report.init();
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
exports.init = init;
|
|
431
|
-
|
|
432
|
-
}));
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).umd={})}(this,function(e){"use strict";function t(e,t,o){return t&&function(e,t){for(var o=0;o<t.length;o++){var n=t[o];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(e,i(n.key),n)}}(e.prototype,t),Object.defineProperty(e,"prototype",{writable:!1}),e}function o(e,t,o){return(t=i(t))in e?Object.defineProperty(e,t,{value:o,enumerable:!0,configurable:!0,writable:!0}):e[t]=o,e}function n(e,t){var o=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter(function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable})),o.push.apply(o,n)}return o}function r(e){for(var t=1;t<arguments.length;t++){var r=null!=arguments[t]?arguments[t]:{};t%2?n(Object(r),!0).forEach(function(t){o(e,t,r[t])}):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(r)):n(Object(r)).forEach(function(t){Object.defineProperty(e,t,Object.getOwnPropertyDescriptor(r,t))})}return e}function i(e){var t=function(e,t){if("object"!=typeof e||!e)return e;var o=e[Symbol.toPrimitive];if(void 0!==o){var n=o.call(e,t);if("object"!=typeof n)return n;throw new TypeError("@@toPrimitive must return a primitive value.")}return String(e)}(e,"string");return"symbol"==typeof t?t:t+""}function s(e){var t=[];return t.push(function(e){var t=history.pushState,o=history.replaceState;history.pushState=function(){for(var o=window.location.href,n=arguments.length,r=new Array(n),i=0;i<n;i++)r[i]=arguments[i];var s=t.apply(this,r),a=window.location.href;return o!==a&&e({to:a,from:o}),s},history.replaceState=function(){for(var t=window.location.href,n=arguments.length,r=new Array(n),i=0;i<n;i++)r[i]=arguments[i];var s=o.apply(this,r),a=window.location.href;return t!==a&&e({to:a,from:t}),s};var n=function(){e({to:window.location.href,from:window.location.href})};return window.addEventListener("popstate",n),function(){window.removeEventListener("popstate",n),history.pushState=t,history.replaceState=o}}(e)),function(){t.forEach(function(e){return e()})}}var a,c={appId:"",env:"production",appUrl:window.location.origin,reportError:!0,reportPromiseReject:!0,reportVueError:!0,vueInstance:null,reportPerformance:!0,reportLongTimeRequest:!0,longTimeRequestThreshold:2e3,reportErrorReqest:!0,reportUserNavigate:!0},u=function(){return t(function e(t){!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),o(this,"records",[]),o(this,"timer",null),o(this,"options",{}),this.options=r(r({},c),t)},[{key:"init",value:function(){var e,t,o,n;if(this.options.reportError&&(e=function(e){var t=e.msg,o=e.url,n=e.line,r=e.col,i=e.error;console.log({msg:t,url:o,line:n,col:r,error:i})},window.onerror=function(t,o,n,r,i){e&&e({msg:t,url:o,line:n,col:r,error:i})}),this.options.reportPromiseReject&&function(e){window.addEventListener("unhandledrejection",function(t){e&&e(t)})}(function(e){console.log("Unhandled Promise Rejection:",e,e.reason)}),this.options.reportVueError&&this.options.vueInstance&&function(e,t){e.config.errorHandler=function(e,o,n){console.error("Error in ".concat(n,":"),e),t&&t({err:e,vm:o,info:n})}}(this.options.vueInstance,function(e){var t=e.err,o=e.vm,n=e.info;console.log("Vue error:",t,o,n)}),this.options.reportPerformance&&function(e){if(PerformanceNavigationTiming){var t=PerformanceNavigationTiming.loadEventEnd-PerformanceNavigationTiming.navigationStart;console.log("Page load time: "+t+"ms");var o=PerformanceNavigationTiming.getEntriesByType("largest-contentful-paint")[0];console.log("Largest Contentful Paint:",o.startTime);var n=PerformanceNavigationTiming.getEntriesByType("first-contentful-paint")[0];console.log("First Contentful Paint:",n.startTime);var r=PerformanceNavigationTiming.getEntriesByType("layout-shift")[0];console.log("Cumulative Layout Shift:",r.value);var i=PerformanceNavigationTiming.getEntriesByType("first-input-delay")[0];console.log("First Input Delay:",i.startTime),console.log("Total Blocking Time:",i.value);var s=PerformanceNavigationTiming.getEntriesByType("first-input")[0];console.log("First Input:",s.startTime);var a=PerformanceNavigationTiming.domainLookupEnd-PerformanceNavigationTiming.domainLookupStart;console.log("DNS查询时间:",a),e&&e({time:t,lcp:o,fcp:n,cls:r,fmp:i,FID:s,dnsTime:a})}}(function(e){var t=e.time,o=e.lcp,n=e.fcp,r=e.cls,i=e.fmp,s=e.FID,a=e.dnsTime;console.log({time:t,lcp:o,fcp:n,cls:r,fmp:i,FID:s,dnsTime:a})}),this.options.reportLongTimeRequest&&(t=function(e){console.log(e)},o=function(e){console.log(e)},n=XMLHttpRequest.prototype.open,XMLHttpRequest.prototype.open=function(e,r,i,s,a){var c=Date.now();this.addEventListener("load",function(){var o=Date.now();t&&t({url:r,method:e,duration:o-c,status:this.status,statusText:this.statusText,response:this.responseText}),console.log("Response:",this.responseText)}),this.addEventListener("error",function(){console.log("Error:",this.statusText),o&&o({url:r,method:e,duration:duration,status:this.status,statusText:this.statusText,response:this.responseText})}),console.log("Request URL:",r),console.log("Request Method:",e),n.call(this,e,r,i,s,a)},function(e,t){var o=window.fetch;window.fetch=function(n,r){console.log("Fetch URL:",n),console.log("Fetch Options:",r),r&&r.headers&&(r.headers["X-Custom-Header"]="Value");var i=Date.now();return o(n,r).then(function(t){var o=Date.now();return e&&e({url:n,method:method,duration:o-i,status:t.status,statusText:t.statusText,response:t.responseText}),console.log("Response:",t),t}).catch(function(e){console.log("Error:",e),t&&t({url:n,method:method,duration:duration})})}}(function(e){console.log(e)},function(e){console.log(e)})),this.options.reportUserNavigate){var r=window.location.href;console.log("current href:",r),s(function(e){console.log("route change:",e)})}}},{key:"addReportRecord",value:function(e){var t=this;this.timer&&clearTimeout(this.timer),this.timer=setTimeout(function(){try{t.sendReport(JSON.parse(JSON.stringify(t.records))),t.records=[]}catch(e){console.log(e)}},1e3),this.records.push(e)}},{key:"sendReport",value:function(e){this.apiDo(this.records)}}])}();e.init=function(){a||(a=new u(arguments.length>0&&void 0!==arguments[0]?arguments[0]:{})),a.init()}});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "keeson-web-report-sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "for web/h5",
|
|
5
5
|
"main": "bundle.min.js",
|
|
6
6
|
"scripts": {
|
|
@@ -10,8 +10,18 @@
|
|
|
10
10
|
"author": "",
|
|
11
11
|
"license": "ISC",
|
|
12
12
|
"devDependencies": {
|
|
13
|
+
"@babel/core": "^7.28.5",
|
|
14
|
+
"@babel/preset-env": "^7.28.5",
|
|
15
|
+
"@rollup/plugin-babel": "^6.1.0",
|
|
16
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
13
17
|
"@rollup/plugin-terser": "^0.4.4",
|
|
18
|
+
"core-js": "^3.47.0",
|
|
14
19
|
"rollup": "^4.55.1"
|
|
15
20
|
},
|
|
16
|
-
"files": [
|
|
21
|
+
"files": [
|
|
22
|
+
"bundle.min.js"
|
|
23
|
+
],
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"regenerator-runtime": "^0.14.1"
|
|
26
|
+
}
|
|
17
27
|
}
|