spy-client 2.1.1-alpha.4 → 2.1.4
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 +9 -3
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/index.html +171 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome 92.0.4515.159 (Mac OS 10.15.7)/html/sorter.js +170 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/index.html +171 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome 95.0.4638.69 (Mac OS 10.15.7)/html/sorter.js +170 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/base.css +224 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/basicSpec.ts.html +740 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/block-navigation.js +79 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/checkSpec.ts.html +479 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/favicon.png +0 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/headSpec.ts.html +695 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/index.html +171 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/markSpec.ts.html +284 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/metricSpec.ts.html +977 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/prettify.css +1 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/prettify.js +2 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/sort-arrow-sprite.png +0 -0
- package/coverage/Chrome 96.0.4664.55 (Mac OS 10.15.7)/html/sorter.js +170 -0
- package/dist/head/base.d.ts +12 -7
- package/dist/lib/interface.d.ts +4 -0
- package/dist/spy-client-basic.d.ts +4 -1
- package/dist/spy-client-basic.esm.js +80 -21
- package/dist/spy-client-basic.iife.js +80 -21
- package/dist/spy-client-basic.iife.min.js +1 -1
- package/dist/spy-client-basic.js +80 -21
- package/dist/spy-client-basic.min.js +1 -1
- package/dist/spy-client-basic.mjs +80 -21
- package/dist/spy-client.d.ts +1 -0
- package/dist/spy-client.esm.js +107 -31
- package/dist/spy-client.iife.js +107 -31
- package/dist/spy-client.iife.min.js +1 -1
- package/dist/spy-client.js +107 -31
- package/dist/spy-client.min.js +1 -1
- package/dist/spy-client.mjs +107 -31
- package/dist/spy-head.js +46 -34
- package/dist/spy-head.min.js +1 -1
- package/dist/spy-local-cache.js +65 -65
- package/dist/spy-local-cache.min.js +1 -1
- package/example/local-cache.html +77 -15
- package/package.json +4 -12
- 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 +92 -23
- package/src/spy-client.ts +19 -1
- package/src/spy-local-cache.ts +41 -16
package/dist/spy-client.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/*! *****************************************************************************
|
|
2
|
-
Copyright (c) Microsoft Corporation.
|
|
2
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
4
|
+
this file except in compliance with the License. You may obtain a copy of the
|
|
5
|
+
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
7
|
+
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
8
|
+
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
9
|
+
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
10
|
+
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
10
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
11
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
12
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
13
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
12
|
+
See the Apache Version 2.0 License for specific language governing permissions
|
|
13
|
+
and limitations under the License.
|
|
14
14
|
***************************************************************************** */
|
|
15
15
|
/* global Reflect, Promise */
|
|
16
16
|
|
|
@@ -132,7 +132,8 @@ function getxpath(el) {
|
|
|
132
132
|
* @author kaivean
|
|
133
133
|
*/
|
|
134
134
|
var defaultLogServer = 'https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif?';
|
|
135
|
-
var
|
|
135
|
+
var ver = navigator.userAgent.toLowerCase().match(/cpu iphone os (.*?)_/);
|
|
136
|
+
var isLtIos14 = ver && ver[2] && (+ver[2] < 14);
|
|
136
137
|
function err(msg) {
|
|
137
138
|
console.error("[SpyClient_log]" + msg);
|
|
138
139
|
// throw new Error(msg);
|
|
@@ -149,6 +150,9 @@ function stringify(obj) {
|
|
|
149
150
|
return encodeURIComponent(key) + '=' + encodeURIComponent(value);
|
|
150
151
|
}).join('&');
|
|
151
152
|
}
|
|
153
|
+
function isArray(arr) {
|
|
154
|
+
return Object.prototype.toString.call(arr) === '[object Array]';
|
|
155
|
+
}
|
|
152
156
|
var SpyClient$1 = /** @class */ (function () {
|
|
153
157
|
function SpyClient(option) {
|
|
154
158
|
this.sample = {};
|
|
@@ -161,38 +165,93 @@ var SpyClient$1 = /** @class */ (function () {
|
|
|
161
165
|
lid: option.lid,
|
|
162
166
|
check: option.check !== false,
|
|
163
167
|
sample: option.sample,
|
|
168
|
+
localCache: option.localCache,
|
|
164
169
|
logServer: option.logServer || defaultLogServer,
|
|
165
170
|
};
|
|
166
171
|
}
|
|
167
|
-
SpyClient.prototype.
|
|
168
|
-
if (!
|
|
172
|
+
SpyClient.prototype.fetch = function (url, data) {
|
|
173
|
+
if (!window.fetch) {
|
|
169
174
|
return;
|
|
170
175
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
+
fetch(url, {
|
|
177
|
+
method: 'POST',
|
|
178
|
+
credentials: 'include',
|
|
179
|
+
headers: {
|
|
180
|
+
'Content-Type': 'application/json',
|
|
181
|
+
},
|
|
182
|
+
body: JSON.stringify(data),
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
SpyClient.prototype.sendPost = function (data) {
|
|
186
|
+
var logItems = isArray(data) ? data : [data];
|
|
187
|
+
var first = logItems[0];
|
|
188
|
+
// 需要在页面暴漏出来pid等基本信息,方式调试查看基本信息与兼容目前的监控
|
|
189
|
+
var query = {
|
|
190
|
+
pid: first.pid,
|
|
191
|
+
type: first.type,
|
|
192
|
+
group: first.group,
|
|
193
|
+
};
|
|
194
|
+
var url = this.option.logServer + stringify(query);
|
|
195
|
+
if (!(!isLtIos14
|
|
196
|
+
&& navigator.sendBeacon
|
|
197
|
+
&& navigator.sendBeacon(url, JSON.stringify(data)))) {
|
|
198
|
+
this.fetch(url, data);
|
|
176
199
|
}
|
|
177
|
-
|
|
200
|
+
};
|
|
201
|
+
SpyClient.prototype.handle = function (logItem) {
|
|
202
|
+
if (!this.check(logItem)) {
|
|
178
203
|
return;
|
|
179
204
|
}
|
|
180
|
-
|
|
205
|
+
logItem = assign({
|
|
181
206
|
pid: this.option.pid,
|
|
182
207
|
lid: this.option.lid,
|
|
183
208
|
ts: Date.now(),
|
|
184
209
|
group: 'common',
|
|
185
|
-
},
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
//
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
210
|
+
}, logItem);
|
|
211
|
+
if (this.option.localCache) {
|
|
212
|
+
this.option.localCache.addLog(logItem);
|
|
213
|
+
}
|
|
214
|
+
// 当前api设置了抽样,
|
|
215
|
+
if (typeof logItem.sample === 'number') {
|
|
216
|
+
if (Math.random() > logItem.sample) {
|
|
217
|
+
return;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
else if (typeof this.option.sample === 'number' && Math.random() > this.option.sample) { // 否则,用全局抽样
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
delete logItem.sample;
|
|
224
|
+
return logItem;
|
|
225
|
+
};
|
|
226
|
+
SpyClient.prototype.send = function (data, post) {
|
|
227
|
+
if (post === void 0) { post = false; }
|
|
228
|
+
var logItems = isArray(data) ? data : [data];
|
|
229
|
+
var postData = [];
|
|
230
|
+
for (var _i = 0, logItems_1 = logItems; _i < logItems_1.length; _i++) {
|
|
231
|
+
var logItem = logItems_1[_i];
|
|
232
|
+
logItem = this.handle(logItem);
|
|
233
|
+
if (!logItem) {
|
|
234
|
+
continue;
|
|
235
|
+
}
|
|
236
|
+
postData.push(logItem);
|
|
237
|
+
// 期望通过post方式上传日志
|
|
238
|
+
if (post) {
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
var url = this.option.logServer + stringify(logItem);
|
|
242
|
+
// 目前服务器端支持sendBeacon的post请求,可以优先采用,该api可以降低打点丢失率
|
|
243
|
+
// 但是ios有些问题:在webkit浏览内核环境下,beacon requests的请求方式存在证书验证的bug,发送失败但返回正确.
|
|
244
|
+
// 修复说明在如下链接中:https://bugs.webkit.org/show_bug.cgi?id=193508
|
|
245
|
+
// 但是目前为止,在iOS12.2版本中该问题依旧存在
|
|
246
|
+
// 2021-11-11: 发现ios 14可以送,故小于14的不发送
|
|
247
|
+
if (!(!isLtIos14
|
|
248
|
+
&& navigator.sendBeacon
|
|
249
|
+
&& navigator.sendBeacon(url))) {
|
|
250
|
+
(new Image()).src = url;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
if (post) {
|
|
254
|
+
this.sendPost(postData);
|
|
196
255
|
}
|
|
197
256
|
};
|
|
198
257
|
SpyClient.prototype.check = function (query) {
|
|
@@ -1307,8 +1366,25 @@ var SpyClient = /** @class */ (function (_super) {
|
|
|
1307
1366
|
document.addEventListener('visibilitychange', _this.visibilitychangeCB);
|
|
1308
1367
|
window.addEventListener('beforeunload', _this.leave, false);
|
|
1309
1368
|
window.addEventListener('unload', _this.leave, false);
|
|
1369
|
+
_this.handleHead();
|
|
1310
1370
|
return _this;
|
|
1311
1371
|
}
|
|
1372
|
+
SpyClient.prototype.handleHead = function () {
|
|
1373
|
+
var _this = this;
|
|
1374
|
+
if (this.option.localCache) {
|
|
1375
|
+
var spyHead = window.__spyHead;
|
|
1376
|
+
if (spyHead && spyHead.winerrors) {
|
|
1377
|
+
for (var index = 0; index < spyHead.winerrors.length; index++) {
|
|
1378
|
+
var obj = spyHead.winerrors[index];
|
|
1379
|
+
this.option.localCache.addLog(obj);
|
|
1380
|
+
}
|
|
1381
|
+
// Head发送的异常,也保存一份到本地,主要是JS错误和资源加载异常
|
|
1382
|
+
spyHead.interceptor = function (obj) {
|
|
1383
|
+
_this.option.localCache.addLog(obj);
|
|
1384
|
+
};
|
|
1385
|
+
}
|
|
1386
|
+
}
|
|
1387
|
+
};
|
|
1312
1388
|
SpyClient.prototype.listenFID = function (cb) {
|
|
1313
1389
|
this.invoke('listenFID', cb);
|
|
1314
1390
|
};
|
package/dist/spy-head.js
CHANGED
|
@@ -87,11 +87,32 @@
|
|
|
87
87
|
init: function (conf) {
|
|
88
88
|
this.conf = conf;
|
|
89
89
|
},
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
addError: function (obj) {
|
|
91
|
+
// 有些错误一下出现很多次,都聚合都一个错误,加上次数
|
|
92
|
+
if (this.winerrors.length > 0) {
|
|
93
|
+
var lastObj = this.winerrors[this.winerrors.length - 1];
|
|
94
|
+
if (obj.info.msg === lastObj.info.msg) {
|
|
95
|
+
lastObj.info.count += (lastObj.info.count || 0);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (this.winerrors.length < 1000) {
|
|
100
|
+
this.winerrors.push(obj);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
103
|
+
send: function (obj, isSend, logServer) {
|
|
92
104
|
var conf = this.conf;
|
|
105
|
+
obj.type = obj.type || 'except';
|
|
106
|
+
obj.pid = conf.pid;
|
|
107
|
+
obj.lid = conf.lid;
|
|
108
|
+
obj.ts = Date.now();
|
|
109
|
+
this.addError(obj);
|
|
110
|
+
this.interceptor && this.interceptor(obj);
|
|
111
|
+
if (isSend === false) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
93
114
|
logServer = logServer || conf.logServer;
|
|
94
|
-
var logUrl = logServer + "?pid=" +
|
|
115
|
+
var logUrl = logServer + "?pid=" + obj.pid + "&lid=" + obj.lid + "&ts=" + obj.ts
|
|
95
116
|
+ ("&type=" + obj.type + "&group=" + obj.group + "&info=" + encodeURIComponent(JSON.stringify(obj.info)));
|
|
96
117
|
if (obj.dim) {
|
|
97
118
|
logUrl += '&dim=' + encodeURIComponent(JSON.stringify(obj.dim));
|
|
@@ -147,18 +168,18 @@
|
|
|
147
168
|
}
|
|
148
169
|
// 历史错误
|
|
149
170
|
var historys = [];
|
|
150
|
-
for (var index = 0; index <
|
|
151
|
-
var item =
|
|
152
|
-
var prefix = item.count > 1 ? "(" + item.count + ")" : '';
|
|
153
|
-
historys.push(prefix + item.msg);
|
|
171
|
+
for (var index = 0; index < winerrors.length; index++) {
|
|
172
|
+
var item = winerrors[index];
|
|
173
|
+
var prefix = item.info.count > 1 ? "(" + item.info.count + ")" : '';
|
|
174
|
+
historys.push(prefix + item.info.msg);
|
|
154
175
|
}
|
|
155
176
|
info.hisErrors = historys.join('----');
|
|
156
177
|
var allow = true;
|
|
157
178
|
if (jsError.handler) {
|
|
158
179
|
allow = jsError.handler(obj);
|
|
159
180
|
}
|
|
160
|
-
if (allow !== false
|
|
161
|
-
spyHead.send(obj);
|
|
181
|
+
if (allow !== false) {
|
|
182
|
+
spyHead.send(obj, isSendJserror);
|
|
162
183
|
}
|
|
163
184
|
}
|
|
164
185
|
// 资源错误
|
|
@@ -178,20 +199,11 @@
|
|
|
178
199
|
if (resourceError.handler) {
|
|
179
200
|
allow = resourceError.handler(obj);
|
|
180
201
|
}
|
|
181
|
-
if (allow !== false
|
|
182
|
-
spyHead.send(obj);
|
|
202
|
+
if (allow !== false) {
|
|
203
|
+
spyHead.send(obj, isSendResource);
|
|
183
204
|
}
|
|
184
205
|
resourceErrorCount++;
|
|
185
206
|
}
|
|
186
|
-
// 有些错误一下出现很多次,都聚合都一个错误,加上次数
|
|
187
|
-
if (winerrors.length > 0) {
|
|
188
|
-
var lastInfo = winerrors[winerrors.length - 1];
|
|
189
|
-
if (info.msg === lastInfo.msg) {
|
|
190
|
-
lastInfo.count += (lastInfo.count || 0);
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
winerrors.push(info);
|
|
195
207
|
}
|
|
196
208
|
catch (e) {
|
|
197
209
|
console.error(e);
|
|
@@ -200,7 +212,7 @@
|
|
|
200
212
|
window.addEventListener('error', spyListenError, true);
|
|
201
213
|
spyHead.errorDestroy = function () {
|
|
202
214
|
window.removeEventListener('error', spyListenError, true);
|
|
203
|
-
spyHead.winerrors =
|
|
215
|
+
spyHead.winerrors = [];
|
|
204
216
|
};
|
|
205
217
|
}
|
|
206
218
|
|
|
@@ -270,8 +282,8 @@
|
|
|
270
282
|
var errors = spyHead.winerrors;
|
|
271
283
|
var historys = [];
|
|
272
284
|
for (var i = 0; i < errors.length; i++) {
|
|
273
|
-
var stack = (errors[i].stack || '').split('\n')[0];
|
|
274
|
-
historys.push("(" + i + ")" + (stack || errors[i].msg));
|
|
285
|
+
var stack = (errors[i].info.stack || '').split('\n')[0];
|
|
286
|
+
historys.push("(" + i + ")" + (stack || errors[i].info.msg));
|
|
275
287
|
}
|
|
276
288
|
return historys.join(';;');
|
|
277
289
|
}
|
|
@@ -301,25 +313,25 @@
|
|
|
301
313
|
}
|
|
302
314
|
return false;
|
|
303
315
|
}
|
|
304
|
-
if (
|
|
316
|
+
if (selector) {
|
|
305
317
|
setTimeout(function () {
|
|
306
|
-
var obj = {
|
|
307
|
-
group: whiteScreenError.group,
|
|
308
|
-
info: {
|
|
309
|
-
msg: '',
|
|
310
|
-
netTime: getNetTime(),
|
|
311
|
-
hisErrors: getHisError(),
|
|
312
|
-
deviceInfo: getDeviceInfo(),
|
|
313
|
-
},
|
|
314
|
-
};
|
|
315
318
|
if (isWhiteScreen()) {
|
|
319
|
+
var obj = {
|
|
320
|
+
group: whiteScreenError.group,
|
|
321
|
+
info: {
|
|
322
|
+
msg: '',
|
|
323
|
+
netTime: getNetTime(),
|
|
324
|
+
hisErrors: getHisError(),
|
|
325
|
+
deviceInfo: getDeviceInfo(),
|
|
326
|
+
},
|
|
327
|
+
};
|
|
316
328
|
obj.info.msg = 'WhiteScren Error';
|
|
317
329
|
var allow = true;
|
|
318
330
|
if (handler) {
|
|
319
331
|
allow = handler(obj);
|
|
320
332
|
}
|
|
321
333
|
if (allow !== false && obj.info.msg) {
|
|
322
|
-
spyHead && spyHead.send(obj);
|
|
334
|
+
spyHead && spyHead.send(obj, isSend);
|
|
323
335
|
}
|
|
324
336
|
}
|
|
325
337
|
}, timeout);
|
package/dist/spy-head.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,
|
|
1
|
+
!function(e,r){"object"==typeof exports&&"undefined"!=typeof module?module.exports=r():"function"==typeof define&&define.amd?define(r):(e="undefined"!=typeof globalThis?globalThis:e||self).__spyHead=r()}(this,function(){"use strict";function E(e){var r=function(e){if(URL){var r=new URL(e);if(void 0!==r.host)return{protocol:r.protocol,host:r.host,pathname:r.pathname,ext:""}}}(e);if(!r){var n=document.createElement("a");n.href=e,r={protocol:n.protocol,host:n.host||location.host,pathname:n.pathname,ext:""}}var t=r.pathname.split(".");return r.ext=t[t.length-1],r}function c(e){return+e.toFixed(1)}var T={conf:{},winerrors:[],errorDestroy:function(){},observerDestroy:function(){},entryMap:{},init:function(e){this.conf=e},addError:function(e){if(0<this.winerrors.length){var r=this.winerrors[this.winerrors.length-1];if(e.info.msg===r.info.msg)return void(r.info.count+=r.info.count||0)}this.winerrors.length<1e3&&this.winerrors.push(e)},send:function(e,r,n){var t=this.conf;if(e.type=e.type||"except",e.pid=t.pid,e.lid=t.lid,e.ts=Date.now(),this.addError(e),this.interceptor&&this.interceptor(e),!1!==r){var o=(n=n||t.logServer)+"?pid="+e.pid+"&lid="+e.lid+"&ts="+e.ts+"&type="+e.type+"&group="+e.group+"&info="+encodeURIComponent(JSON.stringify(e.info));e.dim&&(o+="&dim="+encodeURIComponent(JSON.stringify(e.dim)));var i=new Image;i.src=o,i.onload=i.onerror=function(){i=null}}}};function r(e){var h=e.resourceError||{},m=e.jsError||{},g=Math.random()<(m.sample?m.sample:0),v=Math.random()<(h.sample?h.sample:0),w=T.winerrors,y=0;function r(e){try{var r=e.target,n={info:{},dim:{},group:""},t=n.info,o=e.srcElement,i=navigator.connection||{};if(t.downlink=i.downlink,t.effectiveType=i.effectiveType,t.rtt=i.rtt,t.deviceMemory=navigator.deviceMemory||0,t.hardwareConcurrency=navigator.hardwareConcurrency||0,o===window){n.group=m.group;var a=e.error||{};if(t.msg=e.message,t.file=e.filename,t.ln=e.lineno,t.col=e.colno,t.stack=(a.stack||"").split("\n").slice(0,3).join("\n"),-1!==t.msg.indexOf("MODULE_TIMEOUT")){var s=t.msg.match(/^.*Hang:(.*); Miss:(.*)/);s&&s[2]&&(t.msg="MODULE_TIMEOUT for miss:"+s[2])}for(var c=[],f=0;f<w.length;f++){var d=w[f],u=1<d.info.count?"("+d.info.count+")":"";c.push(u+d.info.msg)}t.hisErrors=c.join("----");var p=!0;m.handler&&(p=m.handler(n)),!1!==p&&T.send(n,g)}else{n.group=h.group,n.dim.type=o.tagName.toLowerCase();var l=o.src||o.href;t.msg=l||"unknown load eror",n.dim.host=E(l).host,r&&"IMG"===r.tagName&&(t.xpath=function(e){if(!e)return{xpath:""};for(var r=[];e&&1===e.nodeType&&e!==e.parentNode;){var n=e.tagName.toLowerCase();if(e.getAttribute("id")?n+="[#"+e.getAttribute("id")+"]":e.classList&&e.classList.length&&(n+="[."+e.classList[e.classList.length-1]+"]"),r.push(n),e===document.body)break;e=e.parentNode}return{xpath:r.join("<")}}(r).xpath),y&&(t.hisErrCount=y);p=!0;h.handler&&(p=h.handler(n)),!1!==p&&T.send(n,v),y++}}catch(e){console.error(e)}}window.addEventListener("error",r,!0),T.errorDestroy=function(){window.removeEventListener("error",r,!0),T.winerrors=[]}}function n(e){var n=e.whiteScreenError||{},t=n.handler,o=n.selector,i=n.subSelector,r=n.timeout||6e3,a=Math.random()<(n.sample?n.sample:0);function s(){if(!window.performance)return!1;var e=function(e){return{wait:c(e.domainLookupStart-(e.navigationStart||e.fetchStart||e.startTime)),dns:c(e.domainLookupEnd-e.domainLookupStart),connect:c(e.connectEnd-e.connectStart),req:c(e.responseStart-e.requestStart),res:c(e.responseEnd-e.responseStart)}}(window.performance.timing);return"&wait="+e.wait+"&dns="+e.dns+"&connect="+e.connect+"&requestTime="+e.req+"&resoneTime="+e.res}o&&setTimeout(function(){if(function(){var e=document.querySelector(o);return!e||(!e.querySelector(i)||e.clientHeight<2*window.innerHeight/3)}()){var e={group:n.group,info:{msg:"",netTime:s(),hisErrors:function(){if(!T.winerrors)return!1;for(var e=T.winerrors,r=[],n=0;n<e.length;n++){var t=(e[n].info.stack||"").split("\n")[0];r.push("("+n+")"+(t||e[n].info.msg))}return r.join(";;")}(),deviceInfo:function(){var e={},r=navigator.connection||{};return e.downlink=r.downlink,e.effectiveType=r.effectiveType,e.rtt=r.rtt,e.deviceMemory=navigator.deviceMemory||0,e.hardwareConcurrency=navigator.hardwareConcurrency||0,e}()}};e.info.msg="WhiteScren Error";var r=!0;t&&(r=t(e)),!1!==r&&e.info.msg&&T&&T.send(e,a)}},r)}return T.init=function(e){e.logServer||(e.logServer="https://sp1.baidu.com/5b1ZeDe5KgQFm2e88IuM_a/mwb2.gif"),r(this.conf=e),function(){if(window.PerformanceObserver){var e=new window.PerformanceObserver(function(e){for(var r=T.entryMap,n=e.getEntries(),t=0;t<n.length;t++){var o=n[t];r[o.entryType]||(r[o.entryType]=[]),r[o.entryType].push(o)}});T.observerDestroy=function(){e.disconnect()};try{e.observe({entryTypes:["longtask","layout-shift","first-input","largest-contentful-paint"]})}catch(e){}}}(),n(e)},window.__spyclientConf&&T.init(window.__spyclientConf),T});
|
package/dist/spy-local-cache.js
CHANGED
|
@@ -5,18 +5,18 @@
|
|
|
5
5
|
}(this, (function () { 'use strict';
|
|
6
6
|
|
|
7
7
|
/*! *****************************************************************************
|
|
8
|
-
Copyright (c) Microsoft Corporation.
|
|
8
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
9
|
+
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
10
|
+
this file except in compliance with the License. You may obtain a copy of the
|
|
11
|
+
License at http://www.apache.org/licenses/LICENSE-2.0
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
|
|
15
|
+
WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
|
|
16
|
+
MERCHANTABLITY OR NON-INFRINGEMENT.
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
16
|
-
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
17
|
-
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
18
|
-
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
19
|
-
PERFORMANCE OF THIS SOFTWARE.
|
|
18
|
+
See the Apache Version 2.0 License for specific language governing permissions
|
|
19
|
+
and limitations under the License.
|
|
20
20
|
***************************************************************************** */
|
|
21
21
|
/* global Reflect, Promise */
|
|
22
22
|
|
|
@@ -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() {
|
|
@@ -587,6 +566,10 @@
|
|
|
587
566
|
interval: 500,
|
|
588
567
|
maxRecordLen: 30,
|
|
589
568
|
onFlush: function () { },
|
|
569
|
+
onSave: function () { },
|
|
570
|
+
onAdd: function () {
|
|
571
|
+
return true;
|
|
572
|
+
},
|
|
590
573
|
storage: IndexedDB.isSupport()
|
|
591
574
|
? 'indexedDB'
|
|
592
575
|
: LS.isSupport()
|
|
@@ -620,6 +603,11 @@
|
|
|
620
603
|
};
|
|
621
604
|
SpyLocalCache.prototype.addLog = function (info) {
|
|
622
605
|
var _this = this;
|
|
606
|
+
if (this.option.onAdd) {
|
|
607
|
+
if (!this.option.onAdd(info)) {
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
623
611
|
info = JSON.stringify(info);
|
|
624
612
|
this.tmpList.push(info);
|
|
625
613
|
// 控制写日志频率
|
|
@@ -662,27 +650,39 @@
|
|
|
662
650
|
};
|
|
663
651
|
SpyLocalCache.prototype.save = function () {
|
|
664
652
|
var _this = this;
|
|
653
|
+
var st = Date.now();
|
|
665
654
|
this.getData(function (list) {
|
|
666
655
|
// 只保留最近的maxRecordLen条日志
|
|
667
656
|
var reserveLen = _this.option.maxRecordLen - 1;
|
|
668
657
|
var originList = list.length > reserveLen ? list.slice(list.length - reserveLen, list.length) : list;
|
|
669
|
-
var
|
|
670
|
-
var
|
|
671
|
-
var
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
_this.
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
658
|
+
var newList = originList.concat(_this.tmpList);
|
|
659
|
+
var content = newList.join('\n');
|
|
660
|
+
var error = null;
|
|
661
|
+
var len = 0;
|
|
662
|
+
try {
|
|
663
|
+
var data = _this.zip(content);
|
|
664
|
+
var codesStr = '';
|
|
665
|
+
if (data.codes) {
|
|
666
|
+
codesStr = JSON.stringify(data.codes);
|
|
667
|
+
_this.storage.set(_this.option.key + 'Codes', codesStr);
|
|
668
|
+
}
|
|
669
|
+
else {
|
|
670
|
+
_this.storage.rm(_this.option.key + 'Codes');
|
|
671
|
+
}
|
|
672
|
+
_this.storage.set(_this.option.key, data.result);
|
|
673
|
+
len = data.result.length;
|
|
678
674
|
}
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
if (_this.option.costTime) {
|
|
683
|
-
_this.option.costTime(costTime);
|
|
675
|
+
catch (e) {
|
|
676
|
+
error = e;
|
|
677
|
+
console.error(e);
|
|
684
678
|
}
|
|
685
679
|
_this.tmpList = [];
|
|
680
|
+
_this.option.onSave && _this.option.onSave({
|
|
681
|
+
cost: Date.now() - st,
|
|
682
|
+
length: len / 1024,
|
|
683
|
+
list: newList,
|
|
684
|
+
error: error,
|
|
685
|
+
});
|
|
686
686
|
});
|
|
687
687
|
};
|
|
688
688
|
SpyLocalCache.prototype.flushLog = function () {
|