spy-client 2.0.7 → 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/README.md +119 -10
- package/dist/head/base.d.ts +1 -1
- package/dist/lib/huffman.d.ts +9 -0
- package/dist/lib/interface.d.ts +59 -1
- package/dist/lib/util.d.ts +22 -0
- package/dist/module/longtask.d.ts +1 -1
- package/dist/module/resource.d.ts +19 -9
- package/dist/module/tti.d.ts +1 -1
- package/dist/spy-client-basic.esm.js +233 -1167
- package/dist/spy-client-basic.iife.js +237 -1171
- package/dist/spy-client-basic.iife.min.js +1 -1
- package/dist/spy-client-basic.js +238 -1172
- package/dist/spy-client-basic.min.js +1 -1
- package/dist/spy-client-basic.mjs +82 -54
- package/dist/spy-client.d.ts +5 -4
- package/dist/spy-client.esm.js +1393 -5662
- package/dist/spy-client.iife.js +1401 -5670
- package/dist/spy-client.iife.min.js +1 -1
- package/dist/spy-client.js +1402 -5671
- package/dist/spy-client.min.js +1 -1
- package/dist/spy-client.mjs +704 -455
- package/dist/spy-head.js +330 -276
- package/dist/spy-head.min.js +1 -1
- package/dist/spy-local-cache.d.ts +18 -0
- package/dist/spy-local-cache.js +690 -0
- package/dist/spy-local-cache.min.js +1 -0
- package/example/index.html +8 -2
- package/example/local-cache.html +97 -0
- package/example/saveCache.js +41 -0
- package/karma.conf.js +111 -0
- package/package.json +21 -20
- package/src/head/error.ts +14 -15
- package/src/head/whitescreen.ts +8 -5
- package/src/lib/huffman.ts +326 -0
- package/src/lib/interface.ts +70 -1
- package/src/lib/util.ts +101 -0
- package/src/module/resource.ts +226 -129
- package/src/spy-client-basic.ts +8 -7
- package/src/spy-client.ts +15 -6
- package/src/spy-local-cache.ts +385 -0
- package/src/types/globals.d.ts +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
!function(t,o){"object"==typeof exports&&"undefined"!=typeof module?module.exports=o():"function"==typeof define&&define.amd?define(o):(t="undefined"!=typeof globalThis?globalThis:t||self).SpyLocalCache=o()}(this,function(){"use strict";var n=function(t,o){return(n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var r in o)o.hasOwnProperty(r)&&(t[r]=o[r])})(t,o)};function t(t,o){function r(){this.constructor=t}n(t,o),t.prototype=null===o?Object.create(o):(r.prototype=o.prototype,new r)}var c=(o.prototype.preOrder=function(t){t.push(this),this.left&&this.left.preOrder(t),this.right&&this.right.preOrder(t)},o);function o(t,o){this.data=t,this.weight=o}function r(t){if(null==t)return null;var e={};return function t(o,r,n){n=[].concat(n);n.push(r),null!=o&&(null==o.data?(t(o.left,"0",n),t(o.right,"1",n)):e[o.data]=n.join(""))}(t,"",[]),e}function e(t){var o=r(function(t){for(var o=function(t,o){return t.weight-o.weight};1<t.length;){t.sort(o);var r,n=t.shift(),e=t.shift();n&&e&&((r=new c(null,n.weight+e.weight)).left=n,r.right=e,t.unshift(r))}return t.shift()}(function(t){for(var o=[],r={},n=0,e=t;n<e.length;n++){var i=e[n];null==r[i]?r[i]=1:r[i]++}for(var s=0,a=Object.entries(r);s<a.length;s++){var h=a[s],u=h[0],h=h[1];o.push(new c(u,h))}return o}(t)));return{result:function(t){for(var o=t.join(""),t=Math.ceil(o.length/8),r=new Array(t+1),n=0,e="",i=0;i<o.length;i+=8)e=o.substring(i,i+8),r[n]=parseInt(e,2),n++;return r[n]=e.length,r}(function(t,o){for(var r=[],n=0,e=t;n<e.length;n++){var i=e[n];r.push(o[i])}return r}(t,o)),codes:o}}function i(t,o){for(var r,n,e=[],i=0;i<o.length-1;i++){var s=i!==o.length-2;e.push((r=s,n=o[i],r&&(n|=256),n=Number(n).toString(2),r?n.substring(n.length-8):n))}var a=e[e.length-1],h=o[o.length-1],a="00000000".substring(8-(h-a.length))+a;e[e.length-1]=a;for(var u={},c=0,p=Object.entries(t);c<p.length;c++){var l=p[c],f=l[0];u[l[1]]=f}for(var g=e.join(""),d=[],y=g.length,i=0;i<y;){for(var v=1,s=!0,m=null;s&&i+v<=y;){if(""===(f=g.substring(i,i+v)))break;(m=u[f])?s=!1:v++}d.push(parseInt(m)),i+=v}return d}function s(t){for(var o=[],r=0;r<t.length;r++)o.push(t.charCodeAt(r));return o}function a(t){for(var o="",r=0,n=t;r<n.length;r++){var e=n[r];o+=String.fromCharCode(e)}return o}var h=(u.prototype.set=function(t,o){},u.prototype.get=function(t,o){},u.prototype.rm=function(t){},u);function u(){}var p,l=(t(f,p=h),f.isSupport=function(){return!!window.localStorage},f.prototype.set=function(t,o){try{localStorage.setItem(t,o)}catch(t){console.error(t)}},f.prototype.get=function(t,o){var r=null;try{r=localStorage.getItem(t)}catch(t){console.error(t)}o&&o(r)},f.prototype.rm=function(t){try{localStorage.removeItem(t)}catch(t){console.error(t)}},f);function f(){return null!==p&&p.apply(this,arguments)||this}var g,d=(t(y,g=h),y.isSupport=function(){return!!window.indexedDB},y.prototype.set=function(t,o){},y.prototype.get=function(t,o){},y);function y(){return null!==g&&g.apply(this,arguments)||this}function v(t,o){if(!t)return"";(o=void 0===o?!1:o)||(t=function(t){for(var o="",r=0;r<t.length;r++){var n=t.charCodeAt(r);n<128?o+=String.fromCharCode(n):(127<n&&n<2048?o+=String.fromCharCode(n>>6|192):(o+=String.fromCharCode(n>>12|224),o+=String.fromCharCode(n>>6&63|128)),o+=String.fromCharCode(63&n|128))}return o}(t));function r(){a.push(1<h.length?String.fromCharCode(s[h]):h)}var n,e,i,s={},a=[],h=t.charAt(0),u=h,c=u,p=256;for(o&&a.push(h),n=1;n<t.length;n++)e=t.charAt(n),o?(i=t.charCodeAt(n),h=i<256?e:s[i]||h+u,a.push(h),u=h.charAt(0),s[p++]=c+u,c=h):s.hasOwnProperty(h+e)?h+=e:(r(),s[h+e]=p++,h=e);o||r();var l=a.join("");return l=o?function(t){for(var o,r,n="",e=0,i=0;e<t.length;)(o=t.charCodeAt(e))<128?(n+=String.fromCharCode(o),e++):191<o&&o<224?(i=t.charCodeAt(e+1),n+=String.fromCharCode((31&o)<<6|63&i),e+=2):(i=t.charCodeAt(e+1),r=t.charCodeAt(e+2),n+=String.fromCharCode((15&o)<<12|(63&i)<<6|63&r),e+=3);return n}(l):l}function m(t){void 0===t&&(t={}),this.tmpList=[],this.option=function(){for(var t=[],o=0;o<arguments.length;o++)t[o]=arguments[o];return(Object.assign||function(t){for(var o,r=1,n=arguments.length;r<n;r++)for(var e in o=arguments[r])Object.prototype.hasOwnProperty.call(o,e)&&(t[e]=o[e]);return t}).apply(this,t)}({defaultTrigger:!0,compress:"lzw",key:"SpyLocalCache",interval:500,onFlush:function(){},storage:d.isSupport()?"indexedDB":l.isSupport()?"localstorage":"empty"},t),this.load=this.load.bind(this),this.init()}return m.prototype.init=function(){"indexedDB"===this.option.storage?this.storage=new d:"localstorage"===this.option.storage?this.storage=new l:this.storage=new h,"complete"===document.readyState?this.load():window.addEventListener("load",this.load)},m.prototype.load=function(){-1<location.search.indexOf("_FlushLogLocalCache=1")&&this.option.defaultTrigger&&this.flushLog()},m.prototype.addLog=function(t){var o=this;t=JSON.stringify(t),this.tmpList.push(t),this.timer&&clearTimeout(this.timer),this.timer=setTimeout(function(){o.save()},this.option.interval)},m.prototype.getData=function(n){var e=this;try{this.storage.get(this.option.key,function(r){r?e.storage.get(e.option.key+"Codes",function(t){var o=[];try{t=t&&JSON.parse(t);o=e.unzip(r,t).split("\n")}catch(t){console.error(t)}n(o)}):n([])})}catch(t){console.error(t),n([])}},m.prototype.save=function(){var r=this;this.getData(function(t){var o=(29<t.length?t.slice(t.length-29,t.length):t).concat(r.tmpList).join("\n"),t=r.zip(o);t.codes?(o=JSON.stringify(t.codes),r.storage.set(r.option.key+"Codes",o)):r.storage.rm(r.option.key+"Codes"),r.storage.set(r.option.key,t.result),r.tmpList=[]})},m.prototype.flushLog=function(){var r=this;this.getData(function(o){try{for(var t=0;t<o.length;t++)o[t]=JSON.parse(o[t])}catch(t){o=[],r.storage.rm(r.option.key),console.error(t)}for(t=0;t<r.tmpList.length;t++)o.push(JSON.parse(r.tmpList[t]));r.option.onFlush&&r.option.onFlush(o)})},m.prototype.zip=function(t){return"lzw"===this.option.compress?{codes:null,result:v(t)}:"huffman"===this.option.compress?(o=(r=e(s(o=t))).result,{codes:r.codes,result:a(o)}):{codes:null,result:t};var o,r},m.prototype.unzip=function(t,o){return"lzw"===this.option.compress?v(t,!0):"huffman"===this.option.compress?a(i(o,s(t))):t},m});
|
package/example/index.html
CHANGED
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
TypeScriptJavaScriptJavaScript 的超集用于解决大型项目的代码复杂性一种脚本语言,用于创建动态网页。可以在编译期间发现并纠正错误作为一种解释型语言,只能在运行时发现错误强类型,支持静态和动态类型弱类型,没有静态类型选项最终被编译成 JavaScript 代码,使浏览器可以理解可以直接在浏览器中使用支持模块、泛型和接口不支持模块,泛型或接口支持 ES3,ES4,ES5 和 ES6 等不支持编译其他 ES3,ES4,ES5 或 ES6 功能社区的支持仍在增长,而且还不是很大大量的社区支持以及大量文档和解决问题的支持
|
|
52
52
|
</p>
|
|
53
53
|
<img src="https://t7.baidu.com/it/u=1211001202,1148572269&fm=193&app=53&size=w414&n=0&g=0n&f=jpeg?sec=1594890084&t=cde9e5bcd0b06de0c989741a7853bd06&a=1" alt="">
|
|
54
|
-
<img src="https://expertimg.cdn.bcebos.com/expertcms/med/zhongyao.jpg" alt="">
|
|
54
|
+
<img class="bigimg" src="https://expertimg.cdn.bcebos.com/expertcms/med/zhongyao.jpg" alt="">
|
|
55
55
|
<script>window.perfFirstScreen = performance.now();</script>
|
|
56
56
|
</div>
|
|
57
57
|
<script src="https://mss0.bdstatic.com/se/static/js/iphone/zbios/zbiosT_f69.js"></script>
|
|
@@ -240,7 +240,8 @@ spy.listenTTI(function (metric) {
|
|
|
240
240
|
|
|
241
241
|
|
|
242
242
|
// 数据类型:性能,触发时间:500MsAfterOnLoad
|
|
243
|
-
spy.listenResource(function (metric) {
|
|
243
|
+
spy.listenResource(function (metric, hostMetric) {
|
|
244
|
+
console.log('hostMetric', hostMetric);
|
|
244
245
|
spy.sendPerf({
|
|
245
246
|
info: metric
|
|
246
247
|
});
|
|
@@ -256,6 +257,11 @@ spy.listenHttpResource(function (info) {
|
|
|
256
257
|
console.log('info', info);
|
|
257
258
|
});
|
|
258
259
|
|
|
260
|
+
// 数据类型:异常,触发时间:500MsAfterOnLoad
|
|
261
|
+
spy.listenSlowResource(function (info) {
|
|
262
|
+
console.log('slow info', info);
|
|
263
|
+
}, {threshold: 20});
|
|
264
|
+
|
|
259
265
|
// 数据类型:性能,触发时间:OnLoad
|
|
260
266
|
spy.listenFSPLongTask(function (metric) {
|
|
261
267
|
spy.sendPerf({
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<html lang="en">
|
|
2
|
+
<head>
|
|
3
|
+
<meta charset="UTF-8">
|
|
4
|
+
<title>SPY Client Test</title>
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
|
7
|
+
<script src="/dist/spy-head.js"></script>
|
|
8
|
+
<script>
|
|
9
|
+
// 配置
|
|
10
|
+
window.__spyHead && window.__spyHead.init({
|
|
11
|
+
pid: '1_1000',
|
|
12
|
+
lid: '',
|
|
13
|
+
// 数据类型:异常,触发时间:OnLoadResourceError
|
|
14
|
+
resourceError: {
|
|
15
|
+
group: 'resource',
|
|
16
|
+
sample: 1,
|
|
17
|
+
handler: function (data) {
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
// 数据类型:异常,触发时间:OnJSError
|
|
22
|
+
jsError: {
|
|
23
|
+
group: 'js',
|
|
24
|
+
sample: 1,
|
|
25
|
+
handler: function (data) {
|
|
26
|
+
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
// 数据类型:异常,触发时间:OnJudgeReturnFalseWhenTimeout
|
|
30
|
+
whiteScreenError: {
|
|
31
|
+
sample: 1,
|
|
32
|
+
group: 'whiteScreen',
|
|
33
|
+
selector: 'body',
|
|
34
|
+
subSelector: 'button1',
|
|
35
|
+
timeout: 2000,
|
|
36
|
+
handler: function (data) {
|
|
37
|
+
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
function en(c){
|
|
44
|
+
var x='charCodeAt',
|
|
45
|
+
b, e={},
|
|
46
|
+
f=c.split(""),d=[],a=f[0],g=256;for(b=1;b<f.length;b++)c=f[b],null!=e[a+c]?a+=c:(d.push(1<a.length?e[a]:a[x](0)),e[a+c]=g,g++,a=c);d.push(1<a.length?e[a]:a[x](0));for(b=0;b<d.length;b++)d[b]=String.fromCharCode(d[b]);return d.join("")}
|
|
47
|
+
|
|
48
|
+
function de(b){var a,e={},d=b.split(""),c=f=d[0],g=[c],h=o=256;for(b=1;b<d.length;b++)a=d[b].charCodeAt(0),a=h>a?d[b]:e[a]?e[a]:f+c,g.push(a),c=a.charAt(0),e[o]=f+c,o++,f=a;return g.join("")}
|
|
49
|
+
|
|
50
|
+
</script>
|
|
51
|
+
</head>
|
|
52
|
+
<body>
|
|
53
|
+
<!-- <div style="height: 667px;"> -->
|
|
54
|
+
<div id="main">
|
|
55
|
+
<div>open</div>
|
|
56
|
+
|
|
57
|
+
<p>
|
|
58
|
+
TypeScriptJavaScriptJavaScript 的超集用于解决大型项目的代码复杂性一种脚本语言,用于创建动态网页。可以在编译期间发现并纠正错误作为一种解释型语言,只能在运行时发现错误强类型,支持静态和动态类型弱类型,没有静态类型选项最终被编译成 JavaScript 代码,使浏览器可以理解可以直接在浏览器中使用支持模块、泛型和接口不支持模块,泛型或接口支持 ES3,ES4,ES5 和 ES6 等不支持编译其他 ES3,ES4,ES5 或 ES6 功能社区的支持仍在增长,而且还不是很大大量的社区支持以及大量文档和解决问题的支持
|
|
59
|
+
</p>
|
|
60
|
+
|
|
61
|
+
</div>
|
|
62
|
+
<script src="https://mss0.bdstatic.com/se/static/js/iphone/zbios/zbiosT_f69.js"></script>
|
|
63
|
+
<script src="/dist/spy-local-cache.js"></script>
|
|
64
|
+
|
|
65
|
+
<script type="text/javascript">
|
|
66
|
+
const localCache = new SpyLocalCache({
|
|
67
|
+
storage: 'localstorage',
|
|
68
|
+
// compress: 'huffman',
|
|
69
|
+
// compress: 'no',
|
|
70
|
+
compress: 'lzw',
|
|
71
|
+
onFlush(list) {
|
|
72
|
+
console.log('flushed list', list);
|
|
73
|
+
},
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// 当有22条如下日志时
|
|
77
|
+
// lzw 压缩率 68%,耗时 2ms
|
|
78
|
+
// huffman压缩率 21% ,耗时2ms
|
|
79
|
+
localCache.addLog({
|
|
80
|
+
type: 'perf',
|
|
81
|
+
info: {
|
|
82
|
+
res: 200,
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
localCache.addLog({
|
|
87
|
+
type: 3,
|
|
88
|
+
fm: 'disp',
|
|
89
|
+
data: [{"base":{"size":{"doc":{"w":360,"h":4875},"wind":{"w":360,"h":640},"scr":{"w":360,"h":640}},"vsb":"visible","num":16},"t":1629773746698,"path":"/s"}],
|
|
90
|
+
qid: 10991431029479106376,
|
|
91
|
+
did: '8dd09c47c7bc90c9fd7274f0ad2c581e',
|
|
92
|
+
q: '刘德华',
|
|
93
|
+
t: 1629773746698
|
|
94
|
+
});
|
|
95
|
+
</script>
|
|
96
|
+
</body>
|
|
97
|
+
</html>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file saveCache.js
|
|
3
|
+
* @author chaiyanchen(chaiyanchen@baidu.com)
|
|
4
|
+
* 起一个简单的本地服务,可用于接收spy-local-cache中缓存的数据
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const fs = require('fs');
|
|
8
|
+
|
|
9
|
+
const fastify = require('fastify')({
|
|
10
|
+
logger: true,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
fastify.register(require('fastify-cors'), {});
|
|
14
|
+
|
|
15
|
+
// 声明路由
|
|
16
|
+
fastify.post('/saveData', function (request, reply) {
|
|
17
|
+
try {
|
|
18
|
+
const jsonData = JSON.stringify(request.body);
|
|
19
|
+
const filePath = `jsonData_${new Date().getTime()}.json`;
|
|
20
|
+
fs.writeFile(filePath, jsonData, 'utf8', err => {
|
|
21
|
+
if (err) {
|
|
22
|
+
console.error(err);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
console.log('写入成功!');
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.log('写入失败:', error);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
reply.send({hello: 'world'});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
fastify.listen(3000, function (err, address) {
|
|
36
|
+
if (err) {
|
|
37
|
+
fastify.log.error(err);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
fastify.log.info(`server listening on ${address}`);
|
|
41
|
+
});
|
package/karma.conf.js
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file karma测试配置,放弃了karma-typescript,不支持相对导入,采用了webpack
|
|
3
|
+
* @author kaivean
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// const webpack = require('webpack');
|
|
8
|
+
|
|
9
|
+
module.exports = config => {
|
|
10
|
+
config.set({
|
|
11
|
+
|
|
12
|
+
// base path that will be used to resolve all patterns (eg. files, exclude)
|
|
13
|
+
basePath: './',
|
|
14
|
+
|
|
15
|
+
// frameworks to use
|
|
16
|
+
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
|
|
17
|
+
frameworks: ['jasmine', 'karma-typescript'],
|
|
18
|
+
|
|
19
|
+
// plugins: ['karma-webpack'],
|
|
20
|
+
client: {
|
|
21
|
+
jasmine: {
|
|
22
|
+
random: false,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
|
|
26
|
+
// list of files / patterns to load in the browser
|
|
27
|
+
files: [
|
|
28
|
+
'dist/spy-head.js', // 先加载
|
|
29
|
+
// 'dist/spy-client.js', // 先加载
|
|
30
|
+
// 'src/index.ts',
|
|
31
|
+
// 'test/**/basicSpec.ts',
|
|
32
|
+
// 'test/**/headSpec.ts',
|
|
33
|
+
// 'test/**/metricSpec.ts',
|
|
34
|
+
// 'test/**/*Spec.ts',
|
|
35
|
+
{
|
|
36
|
+
pattern: 'test/**/*Spec.ts',
|
|
37
|
+
watched: false, // 监听变化
|
|
38
|
+
included: true, // script加载到页面里
|
|
39
|
+
served: true, // be served by Karma's webserver
|
|
40
|
+
nocache: false, // 为了保证测试到一些case,比如lcp等
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
|
|
44
|
+
// list of files / patterns to exclude
|
|
45
|
+
exclude: [
|
|
46
|
+
|
|
47
|
+
],
|
|
48
|
+
|
|
49
|
+
// preprocess matching files before serving them to the browser
|
|
50
|
+
// available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
|
51
|
+
preprocessors: {
|
|
52
|
+
'test/**/*.ts': ['karma-typescript'],
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
karmaTypescriptConfig: {
|
|
56
|
+
exclude: ['node_modules'],
|
|
57
|
+
include: ['test/**/*.ts'],
|
|
58
|
+
compilerOptions: {
|
|
59
|
+
baseUrl: '.',
|
|
60
|
+
paths: {
|
|
61
|
+
'spy-client': ['dist/spy-client.js'],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
transformPath(filepath) {
|
|
65
|
+
return filepath.replace(/\.(ts|tsx)$/, '.js');
|
|
66
|
+
},
|
|
67
|
+
// tsconfig: './tsconfig.json',
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
reporters: ['progress', 'kjhtml', 'karma-typescript'],
|
|
71
|
+
|
|
72
|
+
// web server port
|
|
73
|
+
port: 9876,
|
|
74
|
+
|
|
75
|
+
// enable / disable colors in the output (reporters and logs)
|
|
76
|
+
colors: true,
|
|
77
|
+
|
|
78
|
+
// level of logging
|
|
79
|
+
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
|
|
80
|
+
logLevel: config.LOG_INFO,
|
|
81
|
+
|
|
82
|
+
// enable / disable watching file and executing tests whenever any file changes
|
|
83
|
+
autoWatch: true,
|
|
84
|
+
|
|
85
|
+
// start these browsers
|
|
86
|
+
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
|
|
87
|
+
browsers: ['Chrome'],
|
|
88
|
+
|
|
89
|
+
// you can define custom flags
|
|
90
|
+
customLaunchers: {
|
|
91
|
+
ChromeHeadlessNoSandbox: {
|
|
92
|
+
base: 'ChromeHeadless',
|
|
93
|
+
flags: ['--no-sandbox'],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
|
|
97
|
+
// Continuous Integration mode
|
|
98
|
+
// if true, Karma captures browsers, runs the tests and exits
|
|
99
|
+
singleRun: true,
|
|
100
|
+
|
|
101
|
+
// Concurrency level
|
|
102
|
+
// how many browser should be started simultaneous
|
|
103
|
+
concurrency: Infinity,
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
if (process.env.TRAVIS) {
|
|
107
|
+
config.set({
|
|
108
|
+
browsers: ['ChromeHeadless', 'ChromeHeadlessNoSandbox'],
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spy-client",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.1.1",
|
|
4
4
|
"description": "spy client",
|
|
5
5
|
"main": "dist/spy-client.js",
|
|
6
6
|
"module": "dist/spy-client.esm.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"build": "rollup -c --environment NODE_ENV:production",
|
|
15
15
|
"lint": "eslint src/**/*.ts",
|
|
16
16
|
"example": "npm run dev && echo 'open url http://localhost:8000/example' && python -m SimpleHTTPServer 8000 ",
|
|
17
|
-
"test": "karma start karma.conf.
|
|
17
|
+
"test": "karma start karma.conf.js",
|
|
18
18
|
"release_pre": "npm version patch",
|
|
19
19
|
"release": "rm -fr dist && npm run build && npm run lint && npm run test && npm publish",
|
|
20
20
|
"release_post": "git push origin master && git push origin --tags"
|
|
@@ -27,52 +27,53 @@
|
|
|
27
27
|
"core-js": "^3.6.4"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@babel/core": "^7.
|
|
30
|
+
"@babel/core": "^7.15.0",
|
|
31
|
+
"@babel/eslint-parser": "^7.15.0",
|
|
32
|
+
"@babel/eslint-plugin": "^7.14.5",
|
|
31
33
|
"@babel/preset-env": "^7.5.5",
|
|
32
|
-
"@ecomfe/eslint-config": "^
|
|
34
|
+
"@ecomfe/eslint-config": "^7.2.1",
|
|
33
35
|
"@rollup/plugin-commonjs": "^11.0.2",
|
|
34
36
|
"@rollup/plugin-node-resolve": "^7.1.1",
|
|
35
|
-
"@rollup/plugin-typescript": "^
|
|
37
|
+
"@rollup/plugin-typescript": "^8.2.5",
|
|
36
38
|
"@types/glob": "^7.1.1",
|
|
37
39
|
"@types/jasmine": "^3.5.10",
|
|
38
40
|
"@types/node": "^12.6.8",
|
|
39
41
|
"@types/uglifyjs-webpack-plugin": "^1.1.0",
|
|
40
42
|
"@types/webpack": "^4.4.35",
|
|
41
43
|
"@types/webpack-merge": "^4.1.5",
|
|
42
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
43
|
-
"@typescript-eslint/parser": "^
|
|
44
|
+
"@typescript-eslint/eslint-plugin": "^4.29.2",
|
|
45
|
+
"@typescript-eslint/parser": "^4.29.2",
|
|
44
46
|
"babel-eslint": "^10.1.0",
|
|
45
47
|
"babel-loader": "^8.0.6",
|
|
46
48
|
"cache-loader": "^4.1.0",
|
|
47
49
|
"css-loader": "^3.1.0",
|
|
48
50
|
"eslint": "^6.8.0",
|
|
49
51
|
"eslint-plugin-babel": "^5.3.0",
|
|
50
|
-
"eslint-plugin-import": "^2.
|
|
52
|
+
"eslint-plugin-import": "^2.24.1",
|
|
53
|
+
"fastify": "^3.21.0",
|
|
54
|
+
"fastify-cors": "^6.0.2",
|
|
51
55
|
"fecs": "^1.6.4",
|
|
52
56
|
"file-loader": "^4.1.0",
|
|
53
57
|
"jasmine-core": "^3.4.0",
|
|
54
|
-
"karma": "^
|
|
58
|
+
"karma": "^6.3.4",
|
|
55
59
|
"karma-chrome-launcher": "^3.1.0",
|
|
56
60
|
"karma-jasmine": "^2.0.1",
|
|
57
61
|
"karma-jasmine-html-reporter": "^1.4.2",
|
|
58
|
-
"karma-
|
|
62
|
+
"karma-typescript": "^5.5.2",
|
|
59
63
|
"less": "^3.9.0",
|
|
60
64
|
"less-loader": "^5.0.0",
|
|
61
|
-
"rollup": "^2.2
|
|
65
|
+
"rollup": "^2.56.2",
|
|
62
66
|
"rollup-plugin-babel": "^4.4.0",
|
|
63
67
|
"rollup-plugin-replace": "^2.2.0",
|
|
64
|
-
"rollup-plugin-typescript2": "^0.
|
|
68
|
+
"rollup-plugin-typescript2": "^0.30.0",
|
|
65
69
|
"rollup-plugin-uglify": "^6.0.4",
|
|
66
70
|
"stylus": "^0.54.5",
|
|
67
71
|
"stylus-loader": "^3.0.2",
|
|
68
72
|
"ts-loader": "^6.0.4",
|
|
69
73
|
"ts-node": "^8.3.0",
|
|
70
|
-
"typescript": "^3.
|
|
74
|
+
"typescript": "^4.3.5",
|
|
71
75
|
"uglifyjs-webpack-plugin": "^2.1.3",
|
|
72
|
-
"url-loader": "^2.1.0"
|
|
73
|
-
"webpack": "^4.36.1",
|
|
74
|
-
"webpack-cli": "^3.3.6",
|
|
75
|
-
"webpack-merge": "^4.2.1"
|
|
76
|
+
"url-loader": "^2.1.0"
|
|
76
77
|
},
|
|
77
78
|
"keywords": [
|
|
78
79
|
"spy",
|
|
@@ -120,8 +121,8 @@
|
|
|
120
121
|
"browserslist": [
|
|
121
122
|
"> 1%",
|
|
122
123
|
"last 2 versions",
|
|
123
|
-
"ie >=
|
|
124
|
-
"android >=
|
|
125
|
-
"ios >=
|
|
124
|
+
"ie >= 9",
|
|
125
|
+
"android >= 4",
|
|
126
|
+
"ios >= 9"
|
|
126
127
|
]
|
|
127
128
|
}
|
package/src/head/error.ts
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
SpyHeadConf,
|
|
9
9
|
ErrorConf,
|
|
10
10
|
} from '../lib/spyHeadInterface';
|
|
11
|
+
import {getUrlInfo, getxpath} from '../lib/util';
|
|
12
|
+
|
|
11
13
|
import spyHead from './base';
|
|
12
14
|
|
|
13
15
|
export function init(conf: SpyHeadConf) {
|
|
@@ -17,20 +19,7 @@ export function init(conf: SpyHeadConf) {
|
|
|
17
19
|
const isSendResource = Math.random() < (resourceError.sample ? resourceError.sample : 0);
|
|
18
20
|
|
|
19
21
|
const winerrors = spyHead.winerrors;
|
|
20
|
-
|
|
21
|
-
function getxpath(el: HTMLElement) {
|
|
22
|
-
const xpath = [];
|
|
23
|
-
while (el && el.nodeType === 1 && el !== el.parentNode) {
|
|
24
|
-
xpath.push(el.tagName.toLowerCase());
|
|
25
|
-
if (el === document.body) {
|
|
26
|
-
break;
|
|
27
|
-
}
|
|
28
|
-
el = el.parentNode as HTMLElement; // 修复缺陷检查
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
xpath: xpath.join('<'),
|
|
32
|
-
};
|
|
33
|
-
}
|
|
22
|
+
let resourceErrorCount = 0;
|
|
34
23
|
|
|
35
24
|
function spyListenError(event: Event) {
|
|
36
25
|
try {
|
|
@@ -47,6 +36,7 @@ export function init(conf: SpyHeadConf) {
|
|
|
47
36
|
info.deviceMemory = navigator.deviceMemory || 0;
|
|
48
37
|
info.hardwareConcurrency = navigator.hardwareConcurrency || 0;
|
|
49
38
|
|
|
39
|
+
// JS错误
|
|
50
40
|
if (srcElement === window) {
|
|
51
41
|
obj.group = jsError.group;
|
|
52
42
|
|
|
@@ -72,7 +62,6 @@ export function init(conf: SpyHeadConf) {
|
|
|
72
62
|
const item = spyHead.winerrors[index];
|
|
73
63
|
const prefix = item.count > 1 ? `(${item.count})` : '';
|
|
74
64
|
historys.push(prefix + (item.msg as string));
|
|
75
|
-
|
|
76
65
|
}
|
|
77
66
|
|
|
78
67
|
info.hisErrors = historys.join('----');
|
|
@@ -86,16 +75,24 @@ export function init(conf: SpyHeadConf) {
|
|
|
86
75
|
spyHead.send(obj);
|
|
87
76
|
}
|
|
88
77
|
}
|
|
78
|
+
// 资源错误
|
|
89
79
|
else {
|
|
90
80
|
obj.group = resourceError.group;
|
|
91
81
|
(obj.dim as any).type = (srcElement as HTMLElement).tagName.toLowerCase();
|
|
82
|
+
|
|
92
83
|
const url = (srcElement as HTMLScriptElement).src || (srcElement as HTMLLinkElement).href;
|
|
93
84
|
info.msg = url || 'unknown load eror';
|
|
94
85
|
|
|
86
|
+
(obj.dim as any).host = getUrlInfo(url).host;
|
|
87
|
+
|
|
95
88
|
if (el && (el as HTMLElement).tagName === 'IMG') {
|
|
96
89
|
info.xpath = getxpath(el as HTMLElement).xpath;
|
|
97
90
|
}
|
|
98
91
|
|
|
92
|
+
if (resourceErrorCount) {
|
|
93
|
+
info.hisErrCount = resourceErrorCount;
|
|
94
|
+
}
|
|
95
|
+
|
|
99
96
|
let allow: boolean | undefined | void = true;
|
|
100
97
|
if (resourceError.handler) {
|
|
101
98
|
allow = resourceError.handler(obj);
|
|
@@ -104,6 +101,8 @@ export function init(conf: SpyHeadConf) {
|
|
|
104
101
|
if (allow !== false && isSendResource) {
|
|
105
102
|
spyHead.send(obj);
|
|
106
103
|
}
|
|
104
|
+
|
|
105
|
+
resourceErrorCount++;
|
|
107
106
|
}
|
|
108
107
|
|
|
109
108
|
// 有些错误一下出现很多次,都聚合都一个错误,加上次数
|