@zhongxiaobing/monitor-vue 0.1.0
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 +51 -0
- package/dist/index.d.mts +133 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +750 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +723 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +42 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,750 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
+
|
|
22
|
+
// src/index.ts
|
|
23
|
+
var index_exports = {};
|
|
24
|
+
__export(index_exports, {
|
|
25
|
+
createVueMonitor: () => createVueMonitor,
|
|
26
|
+
createVueMonitorPlugin: () => createVueMonitorPlugin,
|
|
27
|
+
useMonitor: () => useMonitor
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(index_exports);
|
|
30
|
+
|
|
31
|
+
// ../monitor-shared/src/utils/uuid.ts
|
|
32
|
+
function createEventId() {
|
|
33
|
+
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
34
|
+
return crypto.randomUUID();
|
|
35
|
+
}
|
|
36
|
+
return `evt_${Date.now()}_${Math.random().toString(16).slice(2)}`;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ../monitor-shared/src/utils/error.ts
|
|
40
|
+
function normalizeError(error) {
|
|
41
|
+
if (error instanceof Error) {
|
|
42
|
+
return {
|
|
43
|
+
name: error.name,
|
|
44
|
+
message: error.message,
|
|
45
|
+
stack: error.stack
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (typeof error === "string") {
|
|
49
|
+
return {
|
|
50
|
+
message: error
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (typeof error === "object" && error !== null && "message" in error && typeof error.message === "string") {
|
|
54
|
+
const maybeError = error;
|
|
55
|
+
return {
|
|
56
|
+
name: typeof maybeError.name === "string" ? maybeError.name : void 0,
|
|
57
|
+
message: maybeError.message,
|
|
58
|
+
stack: typeof maybeError.stack === "string" ? maybeError.stack : void 0
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
message: "Unknown error"
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ../monitor-shared/src/utils/browser.ts
|
|
67
|
+
function getLocationInfo() {
|
|
68
|
+
return {
|
|
69
|
+
url: window.location.href,
|
|
70
|
+
pathname: window.location.pathname,
|
|
71
|
+
title: document.title,
|
|
72
|
+
userAgent: navigator.userAgent
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ../monitor-transport/src/queue.ts
|
|
77
|
+
var EventQueue = class {
|
|
78
|
+
constructor() {
|
|
79
|
+
__publicField(this, "events", []);
|
|
80
|
+
}
|
|
81
|
+
add(event) {
|
|
82
|
+
this.events.push(event);
|
|
83
|
+
}
|
|
84
|
+
drain() {
|
|
85
|
+
const current = [...this.events];
|
|
86
|
+
this.events = [];
|
|
87
|
+
return current;
|
|
88
|
+
}
|
|
89
|
+
size() {
|
|
90
|
+
return this.events.length;
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
// ../monitor-transport/src/sender.ts
|
|
95
|
+
async function sendEvents(dsn, events) {
|
|
96
|
+
if (!events.length) return;
|
|
97
|
+
if (navigator.sendBeacon) {
|
|
98
|
+
const blob = new Blob([JSON.stringify({ events })], {
|
|
99
|
+
type: "application/json"
|
|
100
|
+
});
|
|
101
|
+
navigator.sendBeacon(dsn, blob);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
await fetch(dsn, {
|
|
105
|
+
method: "POST",
|
|
106
|
+
headers: {
|
|
107
|
+
"Content-Type": "application/json"
|
|
108
|
+
},
|
|
109
|
+
body: JSON.stringify({ events }),
|
|
110
|
+
keepalive: true
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// ../monitor-core/src/context.ts
|
|
115
|
+
function createBaseContext(options) {
|
|
116
|
+
const locationInfo = getLocationInfo();
|
|
117
|
+
return {
|
|
118
|
+
appId: options.appId,
|
|
119
|
+
appName: options.appName,
|
|
120
|
+
env: options.env,
|
|
121
|
+
release: options.release,
|
|
122
|
+
...locationInfo
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// ../monitor-core/src/plugin-system.ts
|
|
127
|
+
function setupPlugins(plugins, api, options) {
|
|
128
|
+
const disposers = [];
|
|
129
|
+
for (const plugin of plugins) {
|
|
130
|
+
const disposer = plugin.setup({ api, options });
|
|
131
|
+
if (typeof disposer === "function") {
|
|
132
|
+
disposers.push(disposer);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
return () => {
|
|
136
|
+
for (const dispose of disposers) {
|
|
137
|
+
dispose();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// ../monitor-core/src/monitor.ts
|
|
143
|
+
var Monitor = class {
|
|
144
|
+
constructor(options) {
|
|
145
|
+
__publicField(this, "queue", new EventQueue());
|
|
146
|
+
__publicField(this, "options");
|
|
147
|
+
__publicField(this, "context");
|
|
148
|
+
__publicField(this, "disposePlugins", null);
|
|
149
|
+
var _a;
|
|
150
|
+
this.options = options;
|
|
151
|
+
this.context = createBaseContext(options);
|
|
152
|
+
this.disposePlugins = setupPlugins((_a = options.plugins) != null ? _a : [], this, options);
|
|
153
|
+
}
|
|
154
|
+
emit(event) {
|
|
155
|
+
const mergedEvent = {
|
|
156
|
+
...this.context,
|
|
157
|
+
...event,
|
|
158
|
+
appId: event.appId || this.context.appId,
|
|
159
|
+
appName: event.appName || this.context.appName,
|
|
160
|
+
env: event.env || this.context.env,
|
|
161
|
+
release: event.release || this.context.release,
|
|
162
|
+
url: event.url || this.context.url,
|
|
163
|
+
pathname: event.pathname || this.context.pathname,
|
|
164
|
+
title: event.title || this.context.title,
|
|
165
|
+
userAgent: event.userAgent || this.context.userAgent,
|
|
166
|
+
eventId: event.eventId || createEventId(),
|
|
167
|
+
timestamp: event.timestamp || Date.now()
|
|
168
|
+
};
|
|
169
|
+
const finalEvent = this.options.beforeSend ? this.options.beforeSend(mergedEvent) : mergedEvent;
|
|
170
|
+
if (!finalEvent) return;
|
|
171
|
+
this.queue.add(finalEvent);
|
|
172
|
+
void this.flush();
|
|
173
|
+
}
|
|
174
|
+
captureException(error, extra) {
|
|
175
|
+
const normalized = normalizeError(error);
|
|
176
|
+
const event = {
|
|
177
|
+
eventId: "",
|
|
178
|
+
eventType: "exception",
|
|
179
|
+
appId: "",
|
|
180
|
+
env: "",
|
|
181
|
+
url: "",
|
|
182
|
+
pathname: "",
|
|
183
|
+
title: "",
|
|
184
|
+
timestamp: 0,
|
|
185
|
+
userAgent: "",
|
|
186
|
+
extra,
|
|
187
|
+
error: {
|
|
188
|
+
name: normalized.name,
|
|
189
|
+
message: normalized.message,
|
|
190
|
+
stack: normalized.stack,
|
|
191
|
+
source: "react"
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
this.emit(event);
|
|
195
|
+
}
|
|
196
|
+
async flush() {
|
|
197
|
+
const events = this.queue.drain();
|
|
198
|
+
await sendEvents(this.options.dsn, events);
|
|
199
|
+
}
|
|
200
|
+
destroy() {
|
|
201
|
+
var _a;
|
|
202
|
+
(_a = this.disposePlugins) == null ? void 0 : _a.call(this);
|
|
203
|
+
this.disposePlugins = null;
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
function initMonitor(options) {
|
|
207
|
+
return new Monitor(options);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
// ../monitor-plugin-blank-screen/src/dedupe.ts
|
|
211
|
+
function normalizeScore(score) {
|
|
212
|
+
return score.toFixed(1);
|
|
213
|
+
}
|
|
214
|
+
function createDedupeKey(input) {
|
|
215
|
+
return [input.pathname, input.trigger, normalizeScore(input.score)].join("|");
|
|
216
|
+
}
|
|
217
|
+
function createBlankScreenDedupe(windowMs) {
|
|
218
|
+
const cache = /* @__PURE__ */ new Map();
|
|
219
|
+
function shouldReport(input) {
|
|
220
|
+
const now = Date.now();
|
|
221
|
+
const key = createDedupeKey(input);
|
|
222
|
+
const lastReportedAt = cache.get(key);
|
|
223
|
+
if (!lastReportedAt || now - lastReportedAt > windowMs) {
|
|
224
|
+
cache.set(key, now);
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
function cleanup() {
|
|
230
|
+
const now = Date.now();
|
|
231
|
+
for (const [key, timestamp] of cache.entries()) {
|
|
232
|
+
if (now - timestamp > windowMs) {
|
|
233
|
+
cache.delete(key);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return {
|
|
238
|
+
shouldReport,
|
|
239
|
+
cleanup
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// ../monitor-plugin-blank-screen/src/root.ts
|
|
244
|
+
function getRootElement(rootSelector) {
|
|
245
|
+
if (rootSelector) {
|
|
246
|
+
const customRoot = document.querySelector(rootSelector);
|
|
247
|
+
if (customRoot) {
|
|
248
|
+
return customRoot;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
const appRoot = document.querySelector("#app");
|
|
252
|
+
if (appRoot) {
|
|
253
|
+
return appRoot;
|
|
254
|
+
}
|
|
255
|
+
const reactRoot = document.querySelector("#root");
|
|
256
|
+
if (reactRoot) {
|
|
257
|
+
return reactRoot;
|
|
258
|
+
}
|
|
259
|
+
return document.body;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// ../monitor-plugin-blank-screen/src/sampler.ts
|
|
263
|
+
var DEFAULT_SAMPLE_POINTS = [
|
|
264
|
+
[0.5, 0.5],
|
|
265
|
+
[0.2, 0.2],
|
|
266
|
+
[0.5, 0.2],
|
|
267
|
+
[0.8, 0.2],
|
|
268
|
+
[0.2, 0.5],
|
|
269
|
+
[0.8, 0.5],
|
|
270
|
+
[0.2, 0.8],
|
|
271
|
+
[0.5, 0.8],
|
|
272
|
+
[0.8, 0.8]
|
|
273
|
+
];
|
|
274
|
+
function getSamplePoints(samplePoints) {
|
|
275
|
+
return (samplePoints == null ? void 0 : samplePoints.length) ? samplePoints : DEFAULT_SAMPLE_POINTS;
|
|
276
|
+
}
|
|
277
|
+
function sampleElements(points) {
|
|
278
|
+
const width = window.innerWidth;
|
|
279
|
+
const height = window.innerHeight;
|
|
280
|
+
return points.map(([xRatio, yRatio]) => {
|
|
281
|
+
const x = Math.floor(width * xRatio);
|
|
282
|
+
const y = Math.floor(height * yRatio);
|
|
283
|
+
const element = document.elementFromPoint(x, y);
|
|
284
|
+
return {
|
|
285
|
+
x,
|
|
286
|
+
y,
|
|
287
|
+
element
|
|
288
|
+
};
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// ../monitor-plugin-blank-screen/src/score.ts
|
|
293
|
+
function matchesIgnoreSelectors(element, ignoreSelectors) {
|
|
294
|
+
return ignoreSelectors.some((selector) => {
|
|
295
|
+
try {
|
|
296
|
+
return element.matches(selector) || !!element.closest(selector);
|
|
297
|
+
} catch {
|
|
298
|
+
return false;
|
|
299
|
+
}
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
function isContainerElement(element, rootElement) {
|
|
303
|
+
const tagName = element.tagName.toLowerCase();
|
|
304
|
+
if (tagName === "html" || tagName === "body") {
|
|
305
|
+
return true;
|
|
306
|
+
}
|
|
307
|
+
if (element === rootElement) {
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
return false;
|
|
311
|
+
}
|
|
312
|
+
function getElementSummary(element) {
|
|
313
|
+
if (!element) return "null";
|
|
314
|
+
const tagName = element.tagName.toLowerCase();
|
|
315
|
+
const id = element.id ? `#${element.id}` : "";
|
|
316
|
+
const className = typeof element.className === "string" && element.className.trim() ? `.${element.className.trim().split(/\s+/).join(".")}` : "";
|
|
317
|
+
return `${tagName}${id}${className}`;
|
|
318
|
+
}
|
|
319
|
+
function calculateBlankScore(sampledElements, rootElement, ignoreSelectors) {
|
|
320
|
+
let blankCount = 0;
|
|
321
|
+
const domSummary = sampledElements.map(({ element }) => {
|
|
322
|
+
if (!element) {
|
|
323
|
+
blankCount += 1;
|
|
324
|
+
return "null";
|
|
325
|
+
}
|
|
326
|
+
if (matchesIgnoreSelectors(element, ignoreSelectors)) {
|
|
327
|
+
blankCount += 1;
|
|
328
|
+
return `${getElementSummary(element)}(ignored)`;
|
|
329
|
+
}
|
|
330
|
+
if (isContainerElement(element, rootElement)) {
|
|
331
|
+
blankCount += 1;
|
|
332
|
+
return `${getElementSummary(element)}(container)`;
|
|
333
|
+
}
|
|
334
|
+
return getElementSummary(element);
|
|
335
|
+
});
|
|
336
|
+
return {
|
|
337
|
+
score: sampledElements.length ? blankCount / sampledElements.length : 0,
|
|
338
|
+
domSummary
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// ../monitor-plugin-blank-screen/src/detect.ts
|
|
343
|
+
function runBlankScreenCheck(options) {
|
|
344
|
+
const {
|
|
345
|
+
rootSelector,
|
|
346
|
+
scoreThreshold = 0.8,
|
|
347
|
+
samplePoints,
|
|
348
|
+
ignoreSelectors = []
|
|
349
|
+
} = options;
|
|
350
|
+
const rootElement = getRootElement(rootSelector);
|
|
351
|
+
const points = getSamplePoints(samplePoints);
|
|
352
|
+
const sampledElements = sampleElements(points);
|
|
353
|
+
const { score, domSummary } = calculateBlankScore(
|
|
354
|
+
sampledElements,
|
|
355
|
+
rootElement,
|
|
356
|
+
ignoreSelectors
|
|
357
|
+
);
|
|
358
|
+
if (score < scoreThreshold) {
|
|
359
|
+
return null;
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
score,
|
|
363
|
+
rootSelector,
|
|
364
|
+
domSummary
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// ../monitor-plugin-blank-screen/src/normalize.ts
|
|
369
|
+
function createBlankScreenEvent({
|
|
370
|
+
score,
|
|
371
|
+
rootSelector,
|
|
372
|
+
domSummary,
|
|
373
|
+
trigger
|
|
374
|
+
}) {
|
|
375
|
+
return {
|
|
376
|
+
eventId: "",
|
|
377
|
+
eventType: "blank_screen",
|
|
378
|
+
appId: "",
|
|
379
|
+
env: "",
|
|
380
|
+
url: "",
|
|
381
|
+
pathname: "",
|
|
382
|
+
title: "",
|
|
383
|
+
timestamp: 0,
|
|
384
|
+
userAgent: "",
|
|
385
|
+
blankScreen: {
|
|
386
|
+
score,
|
|
387
|
+
rootSelector,
|
|
388
|
+
domSummary,
|
|
389
|
+
readyState: document.readyState,
|
|
390
|
+
trigger
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// ../monitor-plugin-blank-screen/src/route-change.ts
|
|
396
|
+
function registerRouteChangeListener(onRouteChange) {
|
|
397
|
+
const originalPushState = history.pushState;
|
|
398
|
+
const originalReplaceState = history.replaceState;
|
|
399
|
+
const handleRouteChange = () => {
|
|
400
|
+
onRouteChange();
|
|
401
|
+
};
|
|
402
|
+
history.pushState = function(...args) {
|
|
403
|
+
const result = originalPushState.apply(this, args);
|
|
404
|
+
handleRouteChange();
|
|
405
|
+
return result;
|
|
406
|
+
};
|
|
407
|
+
history.replaceState = function(...args) {
|
|
408
|
+
const result = originalReplaceState.apply(this, args);
|
|
409
|
+
handleRouteChange();
|
|
410
|
+
return result;
|
|
411
|
+
};
|
|
412
|
+
window.addEventListener("popstate", handleRouteChange);
|
|
413
|
+
window.addEventListener("hashchange", handleRouteChange);
|
|
414
|
+
return () => {
|
|
415
|
+
history.pushState = originalPushState;
|
|
416
|
+
history.replaceState = originalReplaceState;
|
|
417
|
+
window.removeEventListener("popstate", handleRouteChange);
|
|
418
|
+
window.removeEventListener("hashchange", handleRouteChange);
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// ../monitor-plugin-blank-screen/src/index.ts
|
|
423
|
+
function blankScreenPlugin(options = {}) {
|
|
424
|
+
const {
|
|
425
|
+
delayMs = 3e3,
|
|
426
|
+
detectOnRouteChange = true,
|
|
427
|
+
routeChangeDelayMs = 2e3,
|
|
428
|
+
dedupeWindowMs = 1e4
|
|
429
|
+
} = options;
|
|
430
|
+
return {
|
|
431
|
+
name: "blank-screen-plugin",
|
|
432
|
+
setup({ api }) {
|
|
433
|
+
if (typeof window === "undefined" || typeof document === "undefined") {
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
const dedupe = createBlankScreenDedupe(dedupeWindowMs);
|
|
437
|
+
const emitIfNeeded = (trigger) => {
|
|
438
|
+
dedupe.cleanup();
|
|
439
|
+
const result = runBlankScreenCheck(options);
|
|
440
|
+
if (!result) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const pathname = window.location.pathname;
|
|
444
|
+
const shouldReport = dedupe.shouldReport({
|
|
445
|
+
pathname,
|
|
446
|
+
trigger,
|
|
447
|
+
score: result.score
|
|
448
|
+
});
|
|
449
|
+
if (!shouldReport) {
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
api.emit(
|
|
453
|
+
createBlankScreenEvent({
|
|
454
|
+
score: result.score,
|
|
455
|
+
rootSelector: result.rootSelector,
|
|
456
|
+
domSummary: result.domSummary,
|
|
457
|
+
trigger
|
|
458
|
+
})
|
|
459
|
+
);
|
|
460
|
+
};
|
|
461
|
+
const initialTimer = window.setTimeout(() => {
|
|
462
|
+
emitIfNeeded("initial");
|
|
463
|
+
}, delayMs);
|
|
464
|
+
let routeTimer = null;
|
|
465
|
+
const disposeRouteChange = detectOnRouteChange ? registerRouteChangeListener(() => {
|
|
466
|
+
if (routeTimer !== null) {
|
|
467
|
+
window.clearTimeout(routeTimer);
|
|
468
|
+
}
|
|
469
|
+
routeTimer = window.setTimeout(() => {
|
|
470
|
+
emitIfNeeded("route_change");
|
|
471
|
+
}, routeChangeDelayMs);
|
|
472
|
+
}) : () => {
|
|
473
|
+
};
|
|
474
|
+
return () => {
|
|
475
|
+
window.clearTimeout(initialTimer);
|
|
476
|
+
if (routeTimer !== null) {
|
|
477
|
+
window.clearTimeout(routeTimer);
|
|
478
|
+
}
|
|
479
|
+
disposeRouteChange();
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
};
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
// ../monitor-plugin-error/src/normalize.ts
|
|
486
|
+
function createExceptionEvent({
|
|
487
|
+
error,
|
|
488
|
+
source
|
|
489
|
+
}) {
|
|
490
|
+
const normalized = normalizeError(error);
|
|
491
|
+
return {
|
|
492
|
+
eventId: "",
|
|
493
|
+
eventType: "exception",
|
|
494
|
+
appId: "",
|
|
495
|
+
env: "",
|
|
496
|
+
url: "",
|
|
497
|
+
pathname: "",
|
|
498
|
+
title: "",
|
|
499
|
+
timestamp: 0,
|
|
500
|
+
userAgent: "",
|
|
501
|
+
error: {
|
|
502
|
+
name: normalized.name,
|
|
503
|
+
message: normalized.message,
|
|
504
|
+
stack: normalized.stack,
|
|
505
|
+
source
|
|
506
|
+
}
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
// ../monitor-plugin-error/src/unhandledrejection.ts
|
|
511
|
+
function registerUnhandledRejection(api) {
|
|
512
|
+
const handler = (event) => {
|
|
513
|
+
const exceptionEvent = createExceptionEvent({
|
|
514
|
+
error: event.reason,
|
|
515
|
+
source: "unhandledrejection"
|
|
516
|
+
});
|
|
517
|
+
api.emit(exceptionEvent);
|
|
518
|
+
};
|
|
519
|
+
window.addEventListener("unhandledrejection", handler);
|
|
520
|
+
return () => {
|
|
521
|
+
window.removeEventListener("unhandledrejection", handler);
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// ../monitor-plugin-error/src/onerror.ts
|
|
526
|
+
function registerWindowOnError(api) {
|
|
527
|
+
const handler = (message, _source, _lineno, _colno, error) => {
|
|
528
|
+
const targetError = error != null ? error : message;
|
|
529
|
+
const event = createExceptionEvent({
|
|
530
|
+
error: targetError,
|
|
531
|
+
source: "window.onerror"
|
|
532
|
+
});
|
|
533
|
+
api.emit(event);
|
|
534
|
+
return false;
|
|
535
|
+
};
|
|
536
|
+
window.onerror = handler;
|
|
537
|
+
return () => {
|
|
538
|
+
if (window.onerror === handler) {
|
|
539
|
+
window.onerror = null;
|
|
540
|
+
}
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// ../monitor-plugin-error/src/index.ts
|
|
545
|
+
function errorPlugin(options = {}) {
|
|
546
|
+
const {
|
|
547
|
+
captureOnError = true,
|
|
548
|
+
captureUnhandledRejection = true
|
|
549
|
+
} = options;
|
|
550
|
+
return {
|
|
551
|
+
name: "error-plugin",
|
|
552
|
+
setup({ api }) {
|
|
553
|
+
const disposers = [];
|
|
554
|
+
if (captureOnError) {
|
|
555
|
+
disposers.push(registerWindowOnError(api));
|
|
556
|
+
}
|
|
557
|
+
if (captureUnhandledRejection) {
|
|
558
|
+
disposers.push(registerUnhandledRejection(api));
|
|
559
|
+
}
|
|
560
|
+
return () => {
|
|
561
|
+
for (const dispose of disposers) {
|
|
562
|
+
dispose();
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
// ../monitor-plugin-network/src/normalize.ts
|
|
570
|
+
function createHttpErrorEvent({
|
|
571
|
+
url,
|
|
572
|
+
method,
|
|
573
|
+
status,
|
|
574
|
+
duration,
|
|
575
|
+
responseMessage
|
|
576
|
+
}) {
|
|
577
|
+
return {
|
|
578
|
+
eventId: "",
|
|
579
|
+
eventType: "http_error",
|
|
580
|
+
appId: "",
|
|
581
|
+
env: "",
|
|
582
|
+
url: "",
|
|
583
|
+
pathname: "",
|
|
584
|
+
title: "",
|
|
585
|
+
timestamp: 0,
|
|
586
|
+
userAgent: "",
|
|
587
|
+
request: {
|
|
588
|
+
url,
|
|
589
|
+
method,
|
|
590
|
+
status,
|
|
591
|
+
duration,
|
|
592
|
+
success: false,
|
|
593
|
+
source: "fetch"
|
|
594
|
+
},
|
|
595
|
+
response: {
|
|
596
|
+
message: responseMessage
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
// ../monitor-plugin-network/src/url.ts
|
|
602
|
+
function resolveUrlObject(url) {
|
|
603
|
+
return new URL(url, window.location.origin);
|
|
604
|
+
}
|
|
605
|
+
function isMonitorRequest(requestUrl, dsn) {
|
|
606
|
+
try {
|
|
607
|
+
const request = resolveUrlObject(requestUrl);
|
|
608
|
+
const target = resolveUrlObject(dsn);
|
|
609
|
+
return request.origin === target.origin && request.pathname === target.pathname;
|
|
610
|
+
} catch {
|
|
611
|
+
return requestUrl === dsn;
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// ../monitor-plugin-network/src/patch-fetch.ts
|
|
616
|
+
function patchFetch(api, sdkOptions, options) {
|
|
617
|
+
if (typeof window === "undefined" || typeof window.fetch !== "function") {
|
|
618
|
+
return () => {
|
|
619
|
+
};
|
|
620
|
+
}
|
|
621
|
+
const originalFetch = window.fetch.bind(window);
|
|
622
|
+
const {
|
|
623
|
+
capture5xx = true,
|
|
624
|
+
captureNetworkError = true
|
|
625
|
+
} = options;
|
|
626
|
+
window.fetch = async (input, init) => {
|
|
627
|
+
const method = ((init == null ? void 0 : init.method) || "GET").toUpperCase();
|
|
628
|
+
const requestUrl = typeof input === "string" ? input : input instanceof URL ? input.toString() : input.url;
|
|
629
|
+
if (isMonitorRequest(requestUrl, sdkOptions.dsn)) {
|
|
630
|
+
return originalFetch(input, init);
|
|
631
|
+
}
|
|
632
|
+
const startedAt = Date.now();
|
|
633
|
+
try {
|
|
634
|
+
const response = await originalFetch(input, init);
|
|
635
|
+
const duration = Date.now() - startedAt;
|
|
636
|
+
if (capture5xx && response.status >= 500) {
|
|
637
|
+
api.emit(
|
|
638
|
+
createHttpErrorEvent({
|
|
639
|
+
url: requestUrl,
|
|
640
|
+
method,
|
|
641
|
+
status: response.status,
|
|
642
|
+
duration,
|
|
643
|
+
responseMessage: response.statusText
|
|
644
|
+
})
|
|
645
|
+
);
|
|
646
|
+
}
|
|
647
|
+
return response;
|
|
648
|
+
} catch (error) {
|
|
649
|
+
const duration = Date.now() - startedAt;
|
|
650
|
+
if (captureNetworkError) {
|
|
651
|
+
api.emit(
|
|
652
|
+
createHttpErrorEvent({
|
|
653
|
+
url: requestUrl,
|
|
654
|
+
method,
|
|
655
|
+
duration,
|
|
656
|
+
responseMessage: error instanceof Error ? error.message : "Fetch request failed"
|
|
657
|
+
})
|
|
658
|
+
);
|
|
659
|
+
}
|
|
660
|
+
throw error;
|
|
661
|
+
}
|
|
662
|
+
};
|
|
663
|
+
return () => {
|
|
664
|
+
window.fetch = originalFetch;
|
|
665
|
+
};
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
// ../monitor-plugin-network/src/index.ts
|
|
669
|
+
function networkPlugin(options = {}) {
|
|
670
|
+
return {
|
|
671
|
+
name: "network-plugin",
|
|
672
|
+
setup({ api, options: sdkOptions }) {
|
|
673
|
+
const disposeFetch = patchFetch(api, sdkOptions, options);
|
|
674
|
+
return () => {
|
|
675
|
+
disposeFetch();
|
|
676
|
+
};
|
|
677
|
+
}
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// src/symbols.ts
|
|
682
|
+
var monitorInjectionKey = /* @__PURE__ */ Symbol("monitor");
|
|
683
|
+
|
|
684
|
+
// src/plugin.ts
|
|
685
|
+
function createVueMonitorPlugin(monitor) {
|
|
686
|
+
return {
|
|
687
|
+
install(app) {
|
|
688
|
+
app.provide(monitorInjectionKey, monitor);
|
|
689
|
+
const previousErrorHandler = app.config.errorHandler;
|
|
690
|
+
app.config.errorHandler = (error, instance, info) => {
|
|
691
|
+
monitor.captureException(error, {
|
|
692
|
+
vueInfo: info
|
|
693
|
+
});
|
|
694
|
+
previousErrorHandler == null ? void 0 : previousErrorHandler(error, instance, info);
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
|
|
700
|
+
// src/createVueMonitor.ts
|
|
701
|
+
function createVueMonitor(options) {
|
|
702
|
+
var _a;
|
|
703
|
+
const monitor = initMonitor({
|
|
704
|
+
...options,
|
|
705
|
+
plugins: [
|
|
706
|
+
...getDefaultPlugins(options),
|
|
707
|
+
...(_a = options.plugins) != null ? _a : []
|
|
708
|
+
]
|
|
709
|
+
});
|
|
710
|
+
const plugin = createVueMonitorPlugin(monitor);
|
|
711
|
+
return {
|
|
712
|
+
monitor,
|
|
713
|
+
plugin,
|
|
714
|
+
install(app) {
|
|
715
|
+
app.use(plugin);
|
|
716
|
+
}
|
|
717
|
+
};
|
|
718
|
+
}
|
|
719
|
+
function getDefaultPlugins(options) {
|
|
720
|
+
var _a;
|
|
721
|
+
const disabled = new Set((_a = options.disableDefaultPlugins) != null ? _a : []);
|
|
722
|
+
const plugins = [];
|
|
723
|
+
if (!disabled.has("error")) {
|
|
724
|
+
plugins.push(errorPlugin(options.error));
|
|
725
|
+
}
|
|
726
|
+
if (!disabled.has("network")) {
|
|
727
|
+
plugins.push(networkPlugin(options.network));
|
|
728
|
+
}
|
|
729
|
+
if (!disabled.has("blankScreen")) {
|
|
730
|
+
plugins.push(blankScreenPlugin(options.blankScreen));
|
|
731
|
+
}
|
|
732
|
+
return plugins;
|
|
733
|
+
}
|
|
734
|
+
|
|
735
|
+
// src/useMonitor.ts
|
|
736
|
+
var import_vue = require("vue");
|
|
737
|
+
function useMonitor() {
|
|
738
|
+
const monitor = (0, import_vue.inject)(monitorInjectionKey, null);
|
|
739
|
+
if (!monitor) {
|
|
740
|
+
throw new Error("Monitor instance is not provided");
|
|
741
|
+
}
|
|
742
|
+
return monitor;
|
|
743
|
+
}
|
|
744
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
745
|
+
0 && (module.exports = {
|
|
746
|
+
createVueMonitor,
|
|
747
|
+
createVueMonitorPlugin,
|
|
748
|
+
useMonitor
|
|
749
|
+
});
|
|
750
|
+
//# sourceMappingURL=index.js.map
|