spy-client 2.1.2 → 2.1.3
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/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/basicSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/checkSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/headSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/index.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/markSpec.ts.html +1 -1
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/metricSpec.ts.html +1 -1
- package/dist/head/base.d.ts +12 -7
- package/dist/lib/interface.d.ts +4 -0
- package/dist/spy-client-basic.d.ts +3 -3
- package/dist/spy-client-basic.esm.js +12 -8
- package/dist/spy-client-basic.iife.js +12 -8
- package/dist/spy-client-basic.iife.min.js +1 -1
- package/dist/spy-client-basic.js +12 -8
- package/dist/spy-client-basic.min.js +1 -1
- package/dist/spy-client-basic.mjs +12 -8
- package/dist/spy-client.d.ts +1 -0
- package/dist/spy-client.esm.js +29 -8
- package/dist/spy-client.iife.js +29 -8
- package/dist/spy-client.iife.min.js +1 -1
- package/dist/spy-client.js +29 -8
- package/dist/spy-client.min.js +1 -1
- package/dist/spy-client.mjs +29 -8
- package/dist/spy-head.js +46 -34
- package/dist/spy-head.min.js +1 -1
- package/dist/spy-local-cache.js +28 -41
- package/dist/spy-local-cache.min.js +1 -1
- package/example/local-cache.html +77 -15
- package/package.json +3 -3
- package/src/head/base.ts +37 -4
- package/src/head/error.ts +9 -19
- package/src/head/whitescreen.ts +14 -14
- package/src/lib/huffman.ts +37 -56
- package/src/lib/interface.ts +5 -0
- package/src/spy-client-basic.ts +20 -15
- package/src/spy-client.ts +19 -1
- package/src/spy-local-cache.ts +12 -2
package/dist/spy-local-cache.js
CHANGED
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
* @return 返回的就是list形式
|
|
75
75
|
*/
|
|
76
76
|
function getNodes(bytes) {
|
|
77
|
-
|
|
77
|
+
// 创建一个list
|
|
78
78
|
var list = [];
|
|
79
|
-
//counts 统计每一个byte出现的次数
|
|
79
|
+
// counts 统计每一个byte出现的次数
|
|
80
80
|
var counts = {};
|
|
81
81
|
for (var _i = 0, bytes_1 = bytes; _i < bytes_1.length; _i++) {
|
|
82
82
|
var b = bytes_1[_i];
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
var parent_1 = new HuffmanNode(null, leftNode.weight + rightNode.weight);
|
|
111
111
|
parent_1.left = leftNode;
|
|
112
112
|
parent_1.right = rightNode;
|
|
113
|
-
|
|
113
|
+
// 将新的二叉树,加入到nodes
|
|
114
114
|
nodes.unshift(parent_1);
|
|
115
115
|
}
|
|
116
116
|
}
|
|
@@ -140,33 +140,32 @@
|
|
|
140
140
|
string2.push(code);
|
|
141
141
|
if (node != null) { // 如果node == null不处理
|
|
142
142
|
// 判断当前node是叶子节点还是非叶子节点
|
|
143
|
-
if (node.data == null) {
|
|
143
|
+
if (node.data == null) { // 非叶子节点
|
|
144
144
|
// 递归处理
|
|
145
145
|
// 向左递归
|
|
146
146
|
getCodes(node.left, '0', string2);
|
|
147
147
|
// 向右递归
|
|
148
148
|
getCodes(node.right, '1', string2);
|
|
149
149
|
}
|
|
150
|
-
else {
|
|
150
|
+
else { // 说明是一个叶子节点
|
|
151
151
|
// 就表示找到了某个叶子节点的最后
|
|
152
152
|
huffmanCodes[node.data] = string2.join('');
|
|
153
153
|
}
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
|
-
getCodes(root,
|
|
156
|
+
getCodes(root, '', strings);
|
|
157
157
|
return huffmanCodes;
|
|
158
158
|
}
|
|
159
|
-
//编写一个方法,将字符串对应的bytes数组,通过生成的赫夫曼编码表,返回一个赫夫曼编码压缩后的byte数组
|
|
160
159
|
/**
|
|
161
|
-
*
|
|
160
|
+
* 编写一个方法,将字符串对应的bytes数组,通过生成的赫夫曼编码表,返回一个赫夫曼编码压缩后的byte数组
|
|
162
161
|
* @param {原始的字符串对应的bytes数组} bytes
|
|
163
162
|
* @param {生成的赫夫曼编码表} huffmanCodes
|
|
164
163
|
* @return 返回的是字符串对应的一个byte数组
|
|
165
164
|
*/
|
|
166
165
|
function zip(bytes, huffmanCodes) {
|
|
167
|
-
//1.利用huffmanCodes将bytes转成赫夫曼编码对应的字符串
|
|
166
|
+
// 1.利用huffmanCodes将bytes转成赫夫曼编码对应的字符串
|
|
168
167
|
var string = [];
|
|
169
|
-
|
|
168
|
+
// 遍历数组
|
|
170
169
|
for (var _i = 0, bytes_2 = bytes; _i < bytes_2.length; _i++) {
|
|
171
170
|
var b = bytes_2[_i];
|
|
172
171
|
string.push(huffmanCodes[b]);
|
|
@@ -174,10 +173,10 @@
|
|
|
174
173
|
return string;
|
|
175
174
|
}
|
|
176
175
|
function huffStringToByte(strs) {
|
|
177
|
-
|
|
176
|
+
// 计算赫夫曼编码字符串的长度
|
|
178
177
|
var str = strs.join('');
|
|
179
178
|
var len = Math.ceil(str.length / 8);
|
|
180
|
-
|
|
179
|
+
// 创建存储压缩后的byte数组
|
|
181
180
|
var huffmanCodeByte = new Array(len + 1);
|
|
182
181
|
var index = 0;
|
|
183
182
|
var strByte = ''; // 记录是第几个byte
|
|
@@ -222,7 +221,7 @@
|
|
|
222
221
|
* @returns 是byte对应的二进制字符串
|
|
223
222
|
*/
|
|
224
223
|
function huffByteToString(flag, byte) {
|
|
225
|
-
|
|
224
|
+
// 如果是
|
|
226
225
|
if (flag) {
|
|
227
226
|
byte |= 256;
|
|
228
227
|
}
|
|
@@ -230,13 +229,10 @@
|
|
|
230
229
|
if (flag) {
|
|
231
230
|
return str.substring(str.length - 8);
|
|
232
231
|
}
|
|
233
|
-
|
|
234
|
-
return str;
|
|
235
|
-
}
|
|
232
|
+
return str;
|
|
236
233
|
}
|
|
237
|
-
//编写一份方法,完成对压缩数据的解码
|
|
238
234
|
/**
|
|
239
|
-
*
|
|
235
|
+
* 编写一份方法,完成对压缩数据的解码
|
|
240
236
|
* @param {赫夫曼编码表} huffmanCodes
|
|
241
237
|
* @param {赫夫曼编码得到的二进制数组} huffmanBytes
|
|
242
238
|
*/
|
|
@@ -244,7 +240,7 @@
|
|
|
244
240
|
// 1.先得到二进制字符串 形式11001111111011......
|
|
245
241
|
var heffmanStrArr = [];
|
|
246
242
|
for (var i = 0; i < huffmanBytes.length - 1; i++) {
|
|
247
|
-
|
|
243
|
+
// 判断是不是最后一个字节
|
|
248
244
|
var flag = (i !== huffmanBytes.length - 2);
|
|
249
245
|
heffmanStrArr.push(huffByteToString(flag, huffmanBytes[i]));
|
|
250
246
|
}
|
|
@@ -274,15 +270,15 @@
|
|
|
274
270
|
break;
|
|
275
271
|
}
|
|
276
272
|
b = map[key];
|
|
277
|
-
if (!b) {
|
|
273
|
+
if (!b) { // 没有匹配到
|
|
278
274
|
count++;
|
|
279
275
|
}
|
|
280
276
|
else {
|
|
281
|
-
|
|
277
|
+
// 匹配到
|
|
282
278
|
flag = false;
|
|
283
279
|
}
|
|
284
280
|
}
|
|
285
|
-
list.push(parseInt(b));
|
|
281
|
+
list.push(parseInt(b, 10));
|
|
286
282
|
i += count;
|
|
287
283
|
}
|
|
288
284
|
// 当for循环结束后,list中就存放了所有的字符
|
|
@@ -309,31 +305,14 @@
|
|
|
309
305
|
var _a = huffmanZip(bytes), result = _a.result, codes = _a.codes;
|
|
310
306
|
return {
|
|
311
307
|
codes: codes,
|
|
312
|
-
result: byteToString(result)
|
|
308
|
+
result: byteToString(result),
|
|
313
309
|
};
|
|
314
310
|
}
|
|
315
311
|
function huffmanDecode(codes, str) {
|
|
316
312
|
var bytes = stringToByte(str);
|
|
317
313
|
var data = decode(codes, bytes);
|
|
318
314
|
return byteToString(data);
|
|
319
|
-
}
|
|
320
|
-
// For test
|
|
321
|
-
// let content = JSON.stringify({
|
|
322
|
-
// type: 3,
|
|
323
|
-
// fm: 'disp',
|
|
324
|
-
// 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"}],
|
|
325
|
-
// qid: 10991431029479106376,
|
|
326
|
-
// did: '8dd09c47c7bc90c9fd7274f0ad2c581e',
|
|
327
|
-
// q: '刘德华',
|
|
328
|
-
// t: 1629773746698
|
|
329
|
-
// });
|
|
330
|
-
// console.log('压缩前的字符串', content, '其长度:', content.length);
|
|
331
|
-
// const res = huffmanEncode(content);
|
|
332
|
-
// console.log('压缩后的字符串长度', res.result.length);
|
|
333
|
-
// console.log('压缩后的字符串', res.result);
|
|
334
|
-
// const out = huffmanDecode(res.codes, res.result);
|
|
335
|
-
// console.log('解压后的字符串', out, '其长度:', out.length);
|
|
336
|
-
// console.log('解压后的数据', JSON.stringify(JSON.parse(out)));
|
|
315
|
+
}
|
|
337
316
|
|
|
338
317
|
var Storage = /** @class */ (function () {
|
|
339
318
|
function Storage() {
|
|
@@ -588,6 +567,9 @@
|
|
|
588
567
|
maxRecordLen: 30,
|
|
589
568
|
onFlush: function () { },
|
|
590
569
|
onSave: function () { },
|
|
570
|
+
onAdd: function () {
|
|
571
|
+
return true;
|
|
572
|
+
},
|
|
591
573
|
storage: IndexedDB.isSupport()
|
|
592
574
|
? 'indexedDB'
|
|
593
575
|
: LS.isSupport()
|
|
@@ -621,6 +603,11 @@
|
|
|
621
603
|
};
|
|
622
604
|
SpyLocalCache.prototype.addLog = function (info) {
|
|
623
605
|
var _this = this;
|
|
606
|
+
if (this.option.onAdd) {
|
|
607
|
+
if (!this.option.onAdd(info)) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
624
611
|
info = JSON.stringify(info);
|
|
625
612
|
this.tmpList.push(info);
|
|
626
613
|
// 控制写日志频率
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SpyLocalCache=e()}(this,function(){"use strict";var r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var o in e)e.hasOwnProperty(o)&&(t[o]=e[o])})(t,e)};function t(t,e){function o(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(o.prototype=e.prototype,new o)}var l=(e.prototype.preOrder=function(t){t.push(this),this.left&&this.left.preOrder(t),this.right&&this.right.preOrder(t)},e);function e(t,e){this.data=t,this.weight=e}function n(t){var e=function(t){if(null==t)return null;var i={};return function t(e,o,r){var n=[].concat(r);n.push(o),null!=e&&(null==e.data?(t(e.left,"0",n),t(e.right,"1",n)):i[e.data]=n.join(""))}(t,"",[]),i}(function(t){for(var e=function(t,e){return t.weight-e.weight};1<t.length;){t.sort(e);var o=t.shift(),r=t.shift();if(o&&r){var n=new l(null,o.weight+r.weight);n.left=o,n.right=r,t.unshift(n)}}return t.shift()}(function(t){for(var e=[],o={},r=0,n=t;r<n.length;r++){var i=n[r];null==o[i]?o[i]=1:o[i]++}for(var a=0,s=Object.entries(o);a<s.length;a++){var u=s[a],h=u[0],c=u[1];e.push(new l(h,c))}return e}(t)));return{result:function(t){for(var e=t.join(""),o=Math.ceil(e.length/8),r=new Array(o+1),n=0,i="",a=0;a<e.length;a+=8)i=e.substring(a,a+8),r[n]=parseInt(i,2),n++;return r[n]=i.length,r}(function(t,e){for(var o=[],r=0,n=t;r<n.length;r++){var i=n[r];o.push(e[i])}return o}(t,e)),codes:e}}function y(t,e){t&&(e|=256);var o=Number(e).toString(2);return t?o.substring(o.length-8):o}function i(t){for(var e=[],o=0;o<t.length;o++)e.push(t.charCodeAt(o));return e}function a(t){for(var e="",o=0,r=t;o<r.length;o++){var n=r[o];e+=String.fromCharCode(n)}return e}function o(t,e){return a(function(t,e){for(var o=[],r=0;r<e.length-1;r++){var n=r!==e.length-2;o.push(y(n,e[r]))}var i=o[o.length-1],a=e[e.length-1];i="00000000".substring(8-(a-i.length))+i,o[o.length-1]=i;for(var s={},u=0,h=Object.entries(t);u<h.length;u++){var c=h[u],l=c[0];s[c[1]]=l}var
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).SpyLocalCache=e()}(this,function(){"use strict";var r=function(t,e){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,e){t.__proto__=e}||function(t,e){for(var o in e)e.hasOwnProperty(o)&&(t[o]=e[o])})(t,e)};function t(t,e){function o(){this.constructor=t}r(t,e),t.prototype=null===e?Object.create(e):(o.prototype=e.prototype,new o)}var l=(e.prototype.preOrder=function(t){t.push(this),this.left&&this.left.preOrder(t),this.right&&this.right.preOrder(t)},e);function e(t,e){this.data=t,this.weight=e}function n(t){var e=function(t){if(null==t)return null;var i={};return function t(e,o,r){var n=[].concat(r);n.push(o),null!=e&&(null==e.data?(t(e.left,"0",n),t(e.right,"1",n)):i[e.data]=n.join(""))}(t,"",[]),i}(function(t){for(var e=function(t,e){return t.weight-e.weight};1<t.length;){t.sort(e);var o=t.shift(),r=t.shift();if(o&&r){var n=new l(null,o.weight+r.weight);n.left=o,n.right=r,t.unshift(n)}}return t.shift()}(function(t){for(var e=[],o={},r=0,n=t;r<n.length;r++){var i=n[r];null==o[i]?o[i]=1:o[i]++}for(var a=0,s=Object.entries(o);a<s.length;a++){var u=s[a],h=u[0],c=u[1];e.push(new l(h,c))}return e}(t)));return{result:function(t){for(var e=t.join(""),o=Math.ceil(e.length/8),r=new Array(o+1),n=0,i="",a=0;a<e.length;a+=8)i=e.substring(a,a+8),r[n]=parseInt(i,2),n++;return r[n]=i.length,r}(function(t,e){for(var o=[],r=0,n=t;r<n.length;r++){var i=n[r];o.push(e[i])}return o}(t,e)),codes:e}}function y(t,e){t&&(e|=256);var o=Number(e).toString(2);return t?o.substring(o.length-8):o}function i(t){for(var e=[],o=0;o<t.length;o++)e.push(t.charCodeAt(o));return e}function a(t){for(var e="",o=0,r=t;o<r.length;o++){var n=r[o];e+=String.fromCharCode(n)}return e}function o(t,e){return a(function(t,e){for(var o=[],r=0;r<e.length-1;r++){var n=r!==e.length-2;o.push(y(n,e[r]))}var i=o[o.length-1],a=e[e.length-1];i="00000000".substring(8-(a-i.length))+i,o[o.length-1]=i;for(var s={},u=0,h=Object.entries(t);u<h.length;u++){var c=h[u],l=c[0];s[c[1]]=l}var p=o.join(""),f=[],d=p.length;for(r=0;r<d;){for(var g=1,v=(n=!0,null);n&&r+g<=d;){if(""===(l=p.substring(r,r+g)))break;(v=s[l])?n=!1:g++}f.push(parseInt(v,10)),r+=g}return f}(t,i(e)))}var s=(u.prototype.set=function(t,e){},u.prototype.get=function(t,e){},u.prototype.rm=function(t){},u);function u(){}var h,c=(t(p,h=s),p.isSupport=function(){return!!window.localStorage},p.prototype.set=function(t,e){try{localStorage.setItem(t,e)}catch(t){console.error(t)}},p.prototype.get=function(t,e){var o=null;try{o=localStorage.getItem(t)}catch(t){console.error(t)}e&&e(o)},p.prototype.rm=function(t){try{localStorage.removeItem(t)}catch(t){console.error(t)}},p);function p(){return null!==h&&h.apply(this,arguments)||this}var f,d=(t(g,f=s),g.isSupport=function(){return!!window.indexedDB},g.prototype.set=function(t,e){this.db?this.db.transaction([this.databaseName],"readwrite").objectStore(this.databaseName).add({key:t,value:e}):this.setQueue.push({key:t,value:e})},g.prototype.get=function(t,e){if(this.db){var o=this.db.transaction([this.databaseName]).objectStore(this.databaseName).get(t);o.onsuccess=function(){var t=o.result?o.result:{value:""};e(t.value)}}else this.getQueue.push({key:t,cb:e})},g.prototype.runQueueTask=function(){var e=this;this.setQueue.forEach(function(t){e.set(t.key,t.value)}),this.getQueue.forEach(function(t){e.get(t.key,t.cb)})},g);function g(){var e=f.call(this)||this;e.databaseName="spyLC",e.db=null,e.setQueue=[],e.getQueue=[];var t=window.indexedDB.open(e.databaseName);return t.onupgradeneeded=function(t){e.db=t.target&&t.target.result,e.db&&!e.db.objectStoreNames.contains(e.databaseName)&&e.db.createObjectStore(e.databaseName,{keyPath:"key"}),e.runQueueTask()},t.onsuccess=function(){e.db=t.result,e.runQueueTask()},e}function v(t,e){if(void 0===e&&(e=!1),!t)return"";e||(t=function(t){for(var e="",o=0;o<t.length;o++){var r=t.charCodeAt(o);r<128?e+=String.fromCharCode(r):(127<r&&r<2048?e+=String.fromCharCode(r>>6|192):(e+=String.fromCharCode(r>>12|224),e+=String.fromCharCode(r>>6&63|128)),e+=String.fromCharCode(63&r|128))}return e}(t));function o(){s.push(1<u.length?String.fromCharCode(a[u]):u)}var r,n,i,a={},s=[],u=t.charAt(0),h=u,c=h,l=256;for(e&&s.push(u),r=1;r<t.length;r++)n=t.charAt(r),e?(i=t.charCodeAt(r),u=i<256?n:a[i]||u+h,s.push(u),h=u.charAt(0),a[l++]=c+h,c=u):a.hasOwnProperty(u+n)?u+=n:(o(),a[u+n]=l++,u=n);e||o();var p=s.join("");return e&&(p=function(t){for(var e="",o=0,r=0,n=0,i=0;o<t.length;)(r=t.charCodeAt(o))<128?(e+=String.fromCharCode(r),o++):191<r&&r<224?(n=t.charCodeAt(o+1),e+=String.fromCharCode((31&r)<<6|63&n),o+=2):(n=t.charCodeAt(o+1),i=t.charCodeAt(o+2),e+=String.fromCharCode((15&r)<<12|(63&n)<<6|63&i),o+=3);return e}(p)),p}function m(t){void 0===t&&(t={}),this.tmpList=[],this.option=function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];return(Object.assign||function(t){for(var e=void 0,o=1,r=arguments.length;o<r;o++)for(var n in e=arguments[o])Object.prototype.hasOwnProperty.call(e,n)&&(t[n]=e[n]);return t}).apply(this,t)}({defaultTrigger:!0,compress:"lzw",key:"SpyLocalCache",interval:500,maxRecordLen:30,onFlush:function(){},onSave:function(){},onAdd:function(){return!0},storage:d.isSupport()?"indexedDB":c.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 c:this.storage=new s,"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 e=this;this.option.onAdd&&!this.option.onAdd(t)||(t=JSON.stringify(t),this.tmpList.push(t),this.timer&&clearTimeout(this.timer),this.timer=setTimeout(function(){e.save()},this.option.interval))},m.prototype.getData=function(r){var n=this;try{this.storage.get(this.option.key,function(o){o?n.storage.get(n.option.key+"Codes",function(t){var e=[];try{t=t&&JSON.parse(t),e=n.unzip(o,t).split("\n")}catch(t){console.error(t)}r(e)}):r([])})}catch(t){console.error(t),r([])}},m.prototype.save=function(){var u=this,h=Date.now();this.getData(function(t){var e=u.option.maxRecordLen-1,o=(t.length>e?t.slice(t.length-e,t.length):t).concat(u.tmpList),r=o.join("\n"),n=null,i=0;try{var a=u.zip(r),s="";a.codes?(s=JSON.stringify(a.codes),u.storage.set(u.option.key+"Codes",s)):u.storage.rm(u.option.key+"Codes"),u.storage.set(u.option.key,a.result),i=a.result.length}catch(t){n=t,console.error(t)}u.tmpList=[],u.option.onSave&&u.option.onSave({cost:Date.now()-h,length:i/1024,list:o,error:n})})},m.prototype.flushLog=function(){var o=this;this.getData(function(e){try{for(var t=0;t<e.length;t++)e[t]=JSON.parse(e[t])}catch(t){e=[],o.storage.rm(o.option.key),console.error(t)}for(t=0;t<o.tmpList.length;t++)e.push(JSON.parse(o.tmpList[t]));o.option.onFlush&&o.option.onFlush(e)})},m.prototype.zip=function(t){return"lzw"===this.option.compress?{codes:null,result:v(t)}:"huffman"===this.option.compress?function(t){var e=n(i(t)),o=e.result;return{codes:e.codes,result:a(o)}}(t):{codes:null,result:t}},m.prototype.unzip=function(t,e){return"lzw"===this.option.compress?v(t,!0):"huffman"===this.option.compress?o(e,t):t},m});
|
package/example/local-cache.html
CHANGED
|
@@ -9,11 +9,11 @@
|
|
|
9
9
|
// 配置
|
|
10
10
|
window.__spyHead && window.__spyHead.init({
|
|
11
11
|
pid: '1_1000',
|
|
12
|
-
lid: '',
|
|
12
|
+
lid: 'xx',
|
|
13
13
|
// 数据类型:异常,触发时间:OnLoadResourceError
|
|
14
14
|
resourceError: {
|
|
15
15
|
group: 'resource',
|
|
16
|
-
sample: 1,
|
|
16
|
+
sample: 0.1,
|
|
17
17
|
handler: function (data) {
|
|
18
18
|
|
|
19
19
|
}
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
// 数据类型:异常,触发时间:OnJudgeReturnFalseWhenTimeout
|
|
30
30
|
whiteScreenError: {
|
|
31
|
-
sample: 1,
|
|
31
|
+
sample: 0.1,
|
|
32
32
|
group: 'whiteScreen',
|
|
33
33
|
selector: 'body',
|
|
34
34
|
subSelector: 'button1',
|
|
@@ -38,15 +38,6 @@
|
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
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
41
|
</script>
|
|
51
42
|
</head>
|
|
52
43
|
<body>
|
|
@@ -60,19 +51,90 @@
|
|
|
60
51
|
|
|
61
52
|
</div>
|
|
62
53
|
<script src="https://mss0.bdstatic.com/se/static/js/iphone/zbios/zbiosT_f69.js"></script>
|
|
54
|
+
<script src="/dist/spy-client.js"></script>
|
|
63
55
|
<script src="/dist/spy-local-cache.js"></script>
|
|
64
56
|
|
|
65
57
|
<script type="text/javascript">
|
|
66
58
|
const localCache = new SpyLocalCache({
|
|
67
59
|
storage: 'localstorage',
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
60
|
+
maxRecordLen: 300,
|
|
61
|
+
compress: 'no',
|
|
62
|
+
onAdd(log) {
|
|
63
|
+
// 仅保存性能异常
|
|
64
|
+
console.log('onAdd', log && log.type && (log.type === 'perf' || log.type === 'except'));
|
|
65
|
+
return log && log.type && (log.type === 'perf' || log.type === 'except');
|
|
66
|
+
},
|
|
71
67
|
onFlush(list) {
|
|
72
68
|
console.log('flushed list', list);
|
|
69
|
+
|
|
70
|
+
if (list.length) {
|
|
71
|
+
// 将回捞的日志上报的spy,记住在spy平台配置 对应group
|
|
72
|
+
spy.sendPost({
|
|
73
|
+
pid: '1_1000',
|
|
74
|
+
type: 'except',
|
|
75
|
+
group: 'localCache',
|
|
76
|
+
ts: Date.now(),
|
|
77
|
+
lid: 'xxxx',
|
|
78
|
+
info: {
|
|
79
|
+
msg: 'localcache',
|
|
80
|
+
pageUrl: location.href,
|
|
81
|
+
log: JSON.stringify(list)
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
const spy = new SpyClient({
|
|
90
|
+
pid: '1_1000',
|
|
91
|
+
lid: 'xxxx',
|
|
92
|
+
localCache: localCache
|
|
93
|
+
});
|
|
94
|
+
// 采用spy-client sdk内置的抽样配置,则此异常日志不管是否命中抽样,都会存在本地,同时若命中抽样,则日志发送给服务端
|
|
95
|
+
// 那么所有spy sdk发送的日志会存到localstorage
|
|
96
|
+
spy.sendExcept({
|
|
97
|
+
info: {
|
|
98
|
+
msg: 'xxxx is not undefined'
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
// 若自行做了抽样,那么此时则需要主动将此异常或性能日志存在本地,才能百分百保存异常信息到本地
|
|
104
|
+
localCache.addLog({
|
|
105
|
+
type: 'except',
|
|
106
|
+
ts: Date.now(),
|
|
107
|
+
lid: 'xxx',
|
|
108
|
+
info: {
|
|
109
|
+
msg: 'module "jquery" miss',
|
|
110
|
+
pageUrl: location.href,
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
if (Math.random() < 0.1) {
|
|
114
|
+
spy.sendExcept({
|
|
115
|
+
info: {
|
|
116
|
+
msg: 'module "jquery" miss',
|
|
117
|
+
pageUrl: location.href,
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
spy.sendPerf({
|
|
124
|
+
// 可选, 分组,默认common,用户自定义
|
|
125
|
+
group: 'test',
|
|
126
|
+
// 必须, 指标信息,每个字段为一个指标,由用户自定义
|
|
127
|
+
info: {
|
|
128
|
+
fisrtScreen: 200, // 需要你自行计算好时间再发送,不能带单位
|
|
73
129
|
},
|
|
130
|
+
// 可选,维度信息,每个字段为一个维度,由用户自定义
|
|
131
|
+
dim: {
|
|
132
|
+
os: 'ios',
|
|
133
|
+
netType: 'wifi'
|
|
134
|
+
}
|
|
74
135
|
});
|
|
75
136
|
|
|
137
|
+
|
|
76
138
|
// 当有22条如下日志时
|
|
77
139
|
// lzw 压缩率 68%,耗时 2ms
|
|
78
140
|
// huffman压缩率 21% ,耗时2ms
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spy-client",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"description": "spy client",
|
|
5
5
|
"main": "dist/spy-client.js",
|
|
6
6
|
"module": "dist/spy-client.esm.js",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"lint": "eslint src/**/*.ts",
|
|
16
16
|
"example": "npm run dev && echo 'open url http://localhost:8000/example' && python -m SimpleHTTPServer 8000 ",
|
|
17
17
|
"test": "karma start karma.conf.js",
|
|
18
|
-
"release_pre": "npm
|
|
19
|
-
"release": "
|
|
18
|
+
"release_pre": "rm -fr dist && npm run build && npm run lint && npm run test",
|
|
19
|
+
"release": "npm version patch && npm publish",
|
|
20
20
|
"release_post": "git push origin master && git push origin --tags"
|
|
21
21
|
},
|
|
22
22
|
"directories": {
|
package/src/head/base.ts
CHANGED
|
@@ -7,20 +7,53 @@ import {
|
|
|
7
7
|
SpyHeadConf,
|
|
8
8
|
} from '../lib/spyHeadInterface';
|
|
9
9
|
|
|
10
|
+
interface SendObj {
|
|
11
|
+
type?: 'perf'| 'except' | 'dist' | 'count';
|
|
12
|
+
group: string;
|
|
13
|
+
info: any;
|
|
14
|
+
dim?: any;
|
|
15
|
+
lid?: string;
|
|
16
|
+
pid?: string;
|
|
17
|
+
ts?: number;
|
|
18
|
+
}
|
|
19
|
+
|
|
10
20
|
export default {
|
|
11
21
|
conf: {} as SpyHeadConf,
|
|
12
|
-
winerrors: [] as
|
|
22
|
+
winerrors: [] as SendObj[],
|
|
13
23
|
errorDestroy() {},
|
|
14
24
|
observerDestroy() {},
|
|
15
25
|
entryMap: {} as any,
|
|
16
26
|
init(conf: SpyHeadConf) {
|
|
17
27
|
this.conf = conf;
|
|
18
28
|
},
|
|
19
|
-
|
|
20
|
-
|
|
29
|
+
addError(obj: SendObj) {
|
|
30
|
+
// 有些错误一下出现很多次,都聚合都一个错误,加上次数
|
|
31
|
+
if (this.winerrors.length > 0) {
|
|
32
|
+
const lastObj = this.winerrors[this.winerrors.length - 1];
|
|
33
|
+
if (obj.info.msg === lastObj.info.msg) {
|
|
34
|
+
lastObj.info.count += (lastObj.info.count || 0);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
if (this.winerrors.length < 1000) {
|
|
39
|
+
this.winerrors.push(obj);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
send(obj: SendObj, isSend?: boolean, logServer?: string) {
|
|
21
43
|
const conf = this.conf;
|
|
44
|
+
obj.type = obj.type || 'except';
|
|
45
|
+
obj.pid = conf.pid;
|
|
46
|
+
obj.lid = conf.lid;
|
|
47
|
+
obj.ts = Date.now();
|
|
48
|
+
|
|
49
|
+
this.addError(obj);
|
|
50
|
+
this.interceptor && this.interceptor(obj);
|
|
51
|
+
if (isSend === false) {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
22
55
|
logServer = logServer || conf.logServer;
|
|
23
|
-
let logUrl = `${logServer}?pid=${
|
|
56
|
+
let logUrl = `${logServer}?pid=${obj.pid}&lid=${obj.lid}&ts=${obj.ts}`
|
|
24
57
|
+ `&type=${obj.type}&group=${obj.group}&info=${encodeURIComponent(JSON.stringify(obj.info))}`;
|
|
25
58
|
|
|
26
59
|
if (obj.dim) {
|
package/src/head/error.ts
CHANGED
|
@@ -58,10 +58,10 @@ export function init(conf: SpyHeadConf) {
|
|
|
58
58
|
|
|
59
59
|
// 历史错误
|
|
60
60
|
const historys = [];
|
|
61
|
-
for (let index = 0; index <
|
|
62
|
-
const item =
|
|
63
|
-
const prefix = item.count > 1 ? `(${item.count})` : '';
|
|
64
|
-
historys.push(prefix + (item.msg as string));
|
|
61
|
+
for (let index = 0; index < winerrors.length; index++) {
|
|
62
|
+
const item = winerrors[index];
|
|
63
|
+
const prefix = item.info.count > 1 ? `(${item.info.count})` : '';
|
|
64
|
+
historys.push(prefix + (item.info.msg as string));
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
info.hisErrors = historys.join('----');
|
|
@@ -71,8 +71,8 @@ export function init(conf: SpyHeadConf) {
|
|
|
71
71
|
allow = jsError.handler(obj);
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
-
if (allow !== false
|
|
75
|
-
spyHead.send(obj);
|
|
74
|
+
if (allow !== false) {
|
|
75
|
+
spyHead.send(obj, isSendJserror);
|
|
76
76
|
}
|
|
77
77
|
}
|
|
78
78
|
// 资源错误
|
|
@@ -98,22 +98,12 @@ export function init(conf: SpyHeadConf) {
|
|
|
98
98
|
allow = resourceError.handler(obj);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
if (allow !== false
|
|
102
|
-
spyHead.send(obj);
|
|
101
|
+
if (allow !== false) {
|
|
102
|
+
spyHead.send(obj, isSendResource);
|
|
103
103
|
}
|
|
104
104
|
|
|
105
105
|
resourceErrorCount++;
|
|
106
106
|
}
|
|
107
|
-
|
|
108
|
-
// 有些错误一下出现很多次,都聚合都一个错误,加上次数
|
|
109
|
-
if (winerrors.length > 0) {
|
|
110
|
-
const lastInfo = winerrors[winerrors.length - 1];
|
|
111
|
-
if (info.msg === lastInfo.msg) {
|
|
112
|
-
lastInfo.count += (lastInfo.count || 0);
|
|
113
|
-
return;
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
winerrors.push(info);
|
|
117
107
|
}
|
|
118
108
|
catch (e) {
|
|
119
109
|
console.error(e);
|
|
@@ -122,7 +112,7 @@ export function init(conf: SpyHeadConf) {
|
|
|
122
112
|
window.addEventListener('error', spyListenError, true);
|
|
123
113
|
spyHead.errorDestroy = function () {
|
|
124
114
|
window.removeEventListener('error', spyListenError, true);
|
|
125
|
-
spyHead.winerrors =
|
|
115
|
+
spyHead.winerrors = [];
|
|
126
116
|
};
|
|
127
117
|
}
|
|
128
118
|
|
package/src/head/whitescreen.ts
CHANGED
|
@@ -42,8 +42,8 @@ export function init(conf: SpyHeadConf) {
|
|
|
42
42
|
const errors = spyHead.winerrors;
|
|
43
43
|
const historys = [];
|
|
44
44
|
for (let i = 0; i < errors.length; i++) {
|
|
45
|
-
const stack = (errors[i].stack || '').split('\n')[0];
|
|
46
|
-
historys.push(`(${i })${stack || errors[i].msg}`);
|
|
45
|
+
const stack = (errors[i].info.stack || '').split('\n')[0];
|
|
46
|
+
historys.push(`(${i })${stack || errors[i].info.msg}`);
|
|
47
47
|
}
|
|
48
48
|
return historys.join(';;');
|
|
49
49
|
}
|
|
@@ -76,19 +76,19 @@ export function init(conf: SpyHeadConf) {
|
|
|
76
76
|
return false;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
if (
|
|
79
|
+
if (selector) {
|
|
80
80
|
setTimeout(function () {
|
|
81
|
-
const obj = {
|
|
82
|
-
group: whiteScreenError.group,
|
|
83
|
-
info: {
|
|
84
|
-
msg: '',
|
|
85
|
-
netTime: getNetTime(),
|
|
86
|
-
hisErrors: getHisError(),
|
|
87
|
-
deviceInfo: getDeviceInfo(),
|
|
88
|
-
},
|
|
89
|
-
} as ErrorHandlerData;
|
|
90
|
-
|
|
91
81
|
if (isWhiteScreen()) {
|
|
82
|
+
const obj = {
|
|
83
|
+
group: whiteScreenError.group,
|
|
84
|
+
info: {
|
|
85
|
+
msg: '',
|
|
86
|
+
netTime: getNetTime(),
|
|
87
|
+
hisErrors: getHisError(),
|
|
88
|
+
deviceInfo: getDeviceInfo(),
|
|
89
|
+
},
|
|
90
|
+
} as ErrorHandlerData;
|
|
91
|
+
|
|
92
92
|
obj.info.msg = 'WhiteScren Error';
|
|
93
93
|
|
|
94
94
|
let allow: boolean | undefined | void = true;
|
|
@@ -97,7 +97,7 @@ export function init(conf: SpyHeadConf) {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
if (allow !== false && obj.info.msg) {
|
|
100
|
-
spyHead && spyHead.send(obj);
|
|
100
|
+
spyHead && spyHead.send(obj, isSend);
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
103
|
}, timeout);
|