-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
122 lines (108 loc) · 3.43 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
export class EmojiNetworkLog {
static slow = `🐢`;
static average = `🐇`;
static fast = `🚀`;
static slowThreshold = 1000;
static averageThreshold = 500;
static fastThreshold = 150;
static info = `🧠`;
static success = `✅`;
static redirect = `🔁`;
static bad = `❌`;
static error = `🔥`;
static cancelled = `❓`;
static invalid = `👺`;
static timingLevel = `slow`;
static statusLevel = `bad`;
static #timingPriority = [`invalid`, `slow`, `average`, `fast`];
static #statusPriority = [`invalid`, `error`, `bad`, `redirect`, `success`, `info`, `cancelled`];
static #enabled = false;
static #patched = false;
static enable(options = {}) {
Object.assign(EmojiNetworkLog, options);
const emojiLog = new EmojiNetworkLog();
emojiLog.#monitorXhr();
emojiLog.#monitorFetch();
EmojiNetworkLog.#enabled = true;
EmojiNetworkLog.#patched = true;
}
static disable() {
EmojiNetworkLog.#enabled = false;
}
#monitorXhr() {
if (!globalThis.XMLHttpRequest) {
return;
}
if (EmojiNetworkLog.#patched) {
return;
}
const origOpen = XMLHttpRequest.prototype.open;
const self = this;
XMLHttpRequest.prototype.open = function () {
const start = new Date();
const requestType = arguments[0];
const url = arguments[1];
this.addEventListener(`load`, () => {
const end = new Date().getTime() - start.getTime();
self.#logRequest(requestType, url, end, this.status);
});
origOpen.apply(this, arguments);
};
}
#monitorFetch() {
if (EmojiNetworkLog.#patched) {
return;
}
const originalFetch = globalThis.fetch;
globalThis.fetch = async (...args) => {
const start = new Date();
const url = args[0];
const options = args[1] || {};
const resp = await originalFetch(...args);
const end = new Date().getTime() - start.getTime();
this.#logRequest(options.method || `GET`, url, end, resp.status);
return resp;
}
}
#logRequest(requestType, url, end, statusCode) {
if (!EmojiNetworkLog.#enabled) {
return;
}
const status = this.#statusType(statusCode);
const timing = this.#timingType(end);
const timingLevel = EmojiNetworkLog.#timingPriority.indexOf(EmojiNetworkLog.timingLevel);
const statusLevel = EmojiNetworkLog.#statusPriority.indexOf(EmojiNetworkLog.statusLevel);
const foundTimingLevel = EmojiNetworkLog.#timingPriority.indexOf(timing);
const foundStatusLevel = EmojiNetworkLog.#statusPriority.indexOf(status);
if (foundStatusLevel <= statusLevel || foundTimingLevel <= timingLevel) {
console.log(EmojiNetworkLog[timing], requestType, url, `${end}ms`, `${EmojiNetworkLog[status]} ${statusCode}`);
}
}
#timingType(time) {
if (time <= EmojiNetworkLog.fastThreshold) {
return `fast`;
} else if (time <= EmojiNetworkLog.averageThreshold) {
return `average`;
} else if (time > EmojiNetworkLog.averageThreshold) {
return `slow`;
}
return `invalid`;
}
// eslint-disable-next-line complexity
#statusType(status) {
if (status < 100) {
return `cancelled`;
} else if (status < 200) {
return `info`;
} else if (status < 300) {
return `success`;
} else if (status < 400) {
return `redirect`;
} else if (status < 500) {
return `bad`;
} else if (status < 600) {
return `error`;
}
return `invalid`;
}
}