1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
13 | if (k2 === undefined) k2 = k;
|
14 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
15 | }) : (function(o, m, k, k2) {
|
16 | if (k2 === undefined) k2 = k;
|
17 | o[k2] = m[k];
|
18 | }));
|
19 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
20 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
21 | }) : function(o, v) {
|
22 | o["default"] = v;
|
23 | });
|
24 | var __importStar = (this && this.__importStar) || function (mod) {
|
25 | if (mod && mod.__esModule) return mod;
|
26 | var result = {};
|
27 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
28 | __setModuleDefault(result, mod);
|
29 | return result;
|
30 | };
|
31 | Object.defineProperty(exports, "__esModule", { value: true });
|
32 | exports.benchmarkOneLiner = exports.horizontalHtmlResultTable = exports.verticalHtmlResultTable = exports.horizontalTermResultTable = exports.verticalTermResultTable = exports.automaticResultTable = exports.spinner = void 0;
|
33 | const stripAnsi = require("strip-ansi");
|
34 | const table = __importStar(require("table"));
|
35 | const ua_parser_js_1 = require("ua-parser-js");
|
36 | const ansi = require("ansi-escape-sequences");
|
37 | exports.spinner = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'].map((frame) => ansi.format(`[blue]{${frame}}`));
|
38 |
|
39 |
|
40 |
|
41 | function automaticResultTable(results) {
|
42 |
|
43 |
|
44 |
|
45 |
|
46 | const fixed = [];
|
47 | const unfixed = [];
|
48 | const possiblyFixed = [
|
49 | benchmarkDimension,
|
50 | versionDimension,
|
51 | browserDimension,
|
52 | sampleSizeDimension,
|
53 | bytesSentDimension,
|
54 | ];
|
55 | for (const dimension of possiblyFixed) {
|
56 | const values = new Set();
|
57 | for (const res of results) {
|
58 | values.add(dimension.format(res));
|
59 | }
|
60 | if (values.size === 1) {
|
61 | fixed.push(dimension);
|
62 | }
|
63 | else {
|
64 | unfixed.push(dimension);
|
65 | }
|
66 | }
|
67 |
|
68 |
|
69 | unfixed.push(runtimeConfidenceIntervalDimension);
|
70 | if (results.length > 1) {
|
71 |
|
72 | const labelFn = makeUniqueLabelFn(results.map((result) => result.result));
|
73 | for (let i = 0; i < results.length; i++) {
|
74 | unfixed.push({
|
75 | label: `vs ${labelFn(results[i].result)}`,
|
76 | tableConfig: {
|
77 | alignment: 'right',
|
78 | },
|
79 | format: (r) => {
|
80 | if (r.differences === undefined) {
|
81 | return '';
|
82 | }
|
83 | const diff = r.differences[i];
|
84 | if (diff === null) {
|
85 | return ansi.format('\n[gray]{-} ');
|
86 | }
|
87 | return formatDifference(diff);
|
88 | },
|
89 | });
|
90 | }
|
91 | }
|
92 | const fixedTable = { dimensions: fixed, results: [results[0]] };
|
93 | const unfixedTable = { dimensions: unfixed, results };
|
94 | return { fixed: fixedTable, unfixed: unfixedTable };
|
95 | }
|
96 | exports.automaticResultTable = automaticResultTable;
|
97 |
|
98 |
|
99 |
|
100 |
|
101 |
|
102 |
|
103 |
|
104 |
|
105 |
|
106 |
|
107 |
|
108 | function verticalTermResultTable({ dimensions, results }) {
|
109 | const columns = dimensions.map((d) => d.tableConfig || {});
|
110 | const rows = [
|
111 | dimensions.map((d) => ansi.format(`[bold]{${d.label}}`)),
|
112 | ...results.map((r) => dimensions.map((d) => d.format(r))),
|
113 | ];
|
114 | return table.table(rows, {
|
115 | border: table.getBorderCharacters('norc'),
|
116 | columns,
|
117 | });
|
118 | }
|
119 | exports.verticalTermResultTable = verticalTermResultTable;
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 | function horizontalTermResultTable({ dimensions, results }) {
|
130 | const columns = [
|
131 | { alignment: 'right' },
|
132 | ...results.map(() => ({ alignment: 'left' })),
|
133 | ];
|
134 | const rows = dimensions.map((d) => {
|
135 | return [
|
136 | ansi.format(`[bold]{${d.label}}`),
|
137 | ...results.map((r) => d.format(r)),
|
138 | ];
|
139 | });
|
140 | return table.table(rows, {
|
141 | border: table.getBorderCharacters('norc'),
|
142 | columns,
|
143 | });
|
144 | }
|
145 | exports.horizontalTermResultTable = horizontalTermResultTable;
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 | function verticalHtmlResultTable({ dimensions, results }) {
|
156 | const headers = dimensions.map((d) => `<th>${d.label}</th>`);
|
157 | const rows = [];
|
158 | for (const r of results) {
|
159 | const cells = dimensions.map((d) => `<td>${ansiCellToHtml(d.format(r))}</td>`);
|
160 | rows.push(`<tr>${cells.join('')}</tr>`);
|
161 | }
|
162 | return `<table>
|
163 | <tr>${headers.join('')}</tr>
|
164 | ${rows.join('')}
|
165 | </table>`;
|
166 | }
|
167 | exports.verticalHtmlResultTable = verticalHtmlResultTable;
|
168 |
|
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 |
|
176 | function horizontalHtmlResultTable({ dimensions, results }) {
|
177 | const rows = [];
|
178 | for (const d of dimensions) {
|
179 | const cells = [
|
180 | `<th align="right">${d.label}</th>`,
|
181 | ...results.map((r) => `<td>${ansiCellToHtml(d.format(r))}</td>`),
|
182 | ];
|
183 | rows.push(`<tr>${cells.join('')}</tr>`);
|
184 | }
|
185 | return `<table>${rows.join('')}</table>`;
|
186 | }
|
187 | exports.horizontalHtmlResultTable = horizontalHtmlResultTable;
|
188 | function ansiCellToHtml(ansi) {
|
189 |
|
190 |
|
191 |
|
192 | return stripAnsi(ansi).replace(/ /g, ' ');
|
193 | }
|
194 |
|
195 |
|
196 |
|
197 | const formatConfidenceInterval = (ci, format) => {
|
198 | return ansi.format(`${format(ci.low)} [gray]{-} ${format(ci.high)}`);
|
199 | };
|
200 |
|
201 |
|
202 |
|
203 | const colorizeSign = (n, format) => {
|
204 | if (n > 0) {
|
205 | return ansi.format(`[red bold]{+}${format(n)}`);
|
206 | }
|
207 | else if (n < 0) {
|
208 |
|
209 | return ansi.format(`[green bold]{-}${format(-n)}`);
|
210 | }
|
211 | else {
|
212 | return format(n);
|
213 | }
|
214 | };
|
215 | const benchmarkDimension = {
|
216 | label: 'Benchmark',
|
217 | format: (r) => r.result.name,
|
218 | };
|
219 | const versionDimension = {
|
220 | label: 'Version',
|
221 | format: (r) => r.result.version || ansi.format('[gray]{<none>}'),
|
222 | };
|
223 | const browserDimension = {
|
224 | label: 'Browser',
|
225 | format: (r) => {
|
226 | const browser = r.result.browser;
|
227 | let s = browser.name;
|
228 | if (browser.headless) {
|
229 | s += '-headless';
|
230 | }
|
231 | if (browser.remoteUrl) {
|
232 | s += `\n@${browser.remoteUrl}`;
|
233 | }
|
234 | if (r.result.userAgent !== '') {
|
235 |
|
236 |
|
237 | const ua = new ua_parser_js_1.UAParser(r.result.userAgent).getBrowser();
|
238 | s += `\n${ua.version}`;
|
239 | }
|
240 | return s;
|
241 | },
|
242 | };
|
243 | const sampleSizeDimension = {
|
244 | label: 'Sample size',
|
245 | format: (r) => r.result.millis.length.toString(),
|
246 | };
|
247 | const bytesSentDimension = {
|
248 | label: 'Bytes',
|
249 | format: (r) => (r.result.bytesSent / 1024).toFixed(2) + ' KiB',
|
250 | };
|
251 | const runtimeConfidenceIntervalDimension = {
|
252 | label: 'Avg time',
|
253 | tableConfig: {
|
254 | alignment: 'right',
|
255 | },
|
256 | format: (r) => formatConfidenceInterval(r.stats.meanCI, milli),
|
257 | };
|
258 | function formatDifference({ absolute, relative }) {
|
259 | let word, rel, abs;
|
260 | if (absolute.low > 0 && relative.low > 0) {
|
261 | word = `[bold red]{slower}`;
|
262 | rel = formatConfidenceInterval(relative, percent);
|
263 | abs = formatConfidenceInterval(absolute, milli);
|
264 | }
|
265 | else if (absolute.high < 0 && relative.high < 0) {
|
266 | word = `[bold green]{faster}`;
|
267 | rel = formatConfidenceInterval(negate(relative), percent);
|
268 | abs = formatConfidenceInterval(negate(absolute), milli);
|
269 | }
|
270 | else {
|
271 | word = `[bold blue]{unsure}`;
|
272 | rel = formatConfidenceInterval(relative, (n) => colorizeSign(n, percent));
|
273 | abs = formatConfidenceInterval(absolute, (n) => colorizeSign(n, milli));
|
274 | }
|
275 | return ansi.format(`${word}\n${rel}\n${abs}`);
|
276 | }
|
277 | function percent(n) {
|
278 | return (n * 100).toFixed(0) + '%';
|
279 | }
|
280 | function milli(n) {
|
281 | return n.toFixed(2) + 'ms';
|
282 | }
|
283 | function negate(ci) {
|
284 | return {
|
285 | low: -ci.high,
|
286 | high: -ci.low,
|
287 | };
|
288 | }
|
289 |
|
290 |
|
291 |
|
292 |
|
293 | function makeUniqueLabelFn(results) {
|
294 | const names = new Set();
|
295 | const versions = new Set();
|
296 | const browsers = new Set();
|
297 | for (const result of results) {
|
298 | names.add(result.name);
|
299 | versions.add(result.version);
|
300 | browsers.add(result.browser.name);
|
301 | }
|
302 | return (result) => {
|
303 | const fields = [];
|
304 | if (names.size > 1) {
|
305 | fields.push(result.name);
|
306 | }
|
307 | if (versions.size > 1) {
|
308 | fields.push(result.version);
|
309 | }
|
310 | if (browsers.size > 1) {
|
311 | fields.push(result.browser.name);
|
312 | }
|
313 | return fields.join('\n');
|
314 | };
|
315 | }
|
316 |
|
317 |
|
318 |
|
319 |
|
320 |
|
321 | function benchmarkOneLiner(spec) {
|
322 | let maybeVersion = '';
|
323 | if (spec.url.kind === 'local' && spec.url.version !== undefined) {
|
324 | maybeVersion = ` [@${spec.url.version.label}]`;
|
325 | }
|
326 | return `${spec.browser.name} ${spec.name}${maybeVersion}`;
|
327 | }
|
328 | exports.benchmarkOneLiner = benchmarkOneLiner;
|
329 |
|
\ | No newline at end of file |