@xapi-js/core 1.1.0 → 1.2.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.
@@ -1,2485 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined") return require.apply(this, arguments);
5
- throw Error('Dynamic require of "' + x + '" is not supported');
6
- });
7
-
8
- // ../../node_modules/.pnpm/mitata@1.0.34/node_modules/mitata/src/lib.mjs
9
- var AsyncFunction = (async () => {
10
- }).constructor;
11
- var GeneratorFunction = function* () {
12
- }.constructor;
13
- var AsyncGeneratorFunction = async function* () {
14
- }.constructor;
15
- var $ = { _: null, __() {
16
- return print($._);
17
- } };
18
- async function measure(f, ...args) {
19
- return await {
20
- fn,
21
- iter,
22
- yield: generator,
23
- [void 0]() {
24
- throw new TypeError("expected iterator, generator or one-shot function");
25
- }
26
- }[kind(f)](f, ...args);
27
- }
28
- async function generator(gen, opts = {}) {
29
- const ctx = {
30
- get(name) {
31
- return opts.args?.[name];
32
- }
33
- };
34
- const g = gen(ctx);
35
- const n = await g.next();
36
- let $fn = n.value;
37
- if (!n.value?.heap && null != n.value?.heap) opts.heap = false;
38
- opts.concurrency ??= n.value?.concurrency ?? opts.args?.concurrency;
39
- if (!n.value?.counters && null != n.value?.counters) opts.$counters = false;
40
- if (n.done || "fn" !== kind($fn)) {
41
- $fn = n.value?.bench || n.value?.manual;
42
- if ("fn" !== kind($fn, true)) throw new TypeError("expected benchmarkable yield from generator");
43
- opts.params ??= {};
44
- const params = $fn.length;
45
- opts.manual = !n.value.manual ? false : "manual" !== n.value.budget ? "real" : "manual";
46
- for (let o = 0; o < params; o++) {
47
- opts.params[o] = n.value[o];
48
- if ("fn" !== kind(n.value[o])) throw new TypeError("expected function for benchmark parameter");
49
- }
50
- }
51
- const stats = await fn($fn, opts);
52
- if (!(await g.next()).done) throw new TypeError("expected generator to yield once");
53
- return {
54
- ...stats,
55
- kind: "yield"
56
- };
57
- }
58
- var print = (() => {
59
- if (globalThis.console?.log) return globalThis.console.log;
60
- if (globalThis.print && !globalThis.document) return globalThis.print;
61
- return () => {
62
- throw new Error("no print function available");
63
- };
64
- })();
65
- var gc = (() => {
66
- try {
67
- return Bun.gc(true), () => Bun.gc(true);
68
- } catch {
69
- }
70
- try {
71
- return globalThis.gc(), () => globalThis.gc();
72
- } catch {
73
- }
74
- try {
75
- return globalThis.__gc(), () => globalThis.__gc();
76
- } catch {
77
- }
78
- try {
79
- return globalThis.std.gc(), () => globalThis.std.gc();
80
- } catch {
81
- }
82
- try {
83
- return globalThis.$262.gc(), () => globalThis.$262.gc();
84
- } catch {
85
- }
86
- try {
87
- return globalThis.tjs.engine.gc.run(), () => globalThis.tjs.engine.gc.run();
88
- } catch {
89
- }
90
- return Object.assign(globalThis.Graal ? () => new Uint8Array(2 ** 29) : () => new Uint8Array(2 ** 30), { fallback: true });
91
- })();
92
- var now = (() => {
93
- try {
94
- Bun.nanoseconds();
95
- return Bun.nanoseconds;
96
- } catch {
97
- }
98
- try {
99
- $.agent.monotonicNow();
100
- return () => 1e6 * $.agent.monotonicNow();
101
- } catch {
102
- }
103
- try {
104
- $262.agent.monotonicNow();
105
- return () => 1e6 * $262.agent.monotonicNow();
106
- } catch {
107
- }
108
- try {
109
- const now2 = performance.now.bind(performance);
110
- now2();
111
- return () => 1e6 * now2();
112
- } catch {
113
- return () => 1e6 * Date.now();
114
- }
115
- })();
116
- function kind(fn2, _ = false) {
117
- if (!(fn2 instanceof Function || fn2 instanceof AsyncFunction || fn2 instanceof GeneratorFunction || fn2 instanceof AsyncGeneratorFunction)) return;
118
- if (fn2 instanceof GeneratorFunction || fn2 instanceof AsyncGeneratorFunction) return "yield";
119
- if ((_ ? true : 0 === fn2.length) && (fn2 instanceof Function || fn2 instanceof AsyncFunction)) return "fn";
120
- if (0 !== fn2.length && (fn2 instanceof Function || fn2 instanceof AsyncFunction)) return "iter";
121
- }
122
- var k_cpu_time_rescale_heap = 1.1;
123
- var k_cpu_time_rescale_inner_gc = 2;
124
- var k_concurrency = 1;
125
- var k_min_samples = 12;
126
- var k_batch_unroll = 4;
127
- var k_max_samples = 1e9;
128
- var k_warmup_samples = 2;
129
- var k_batch_samples = 4096;
130
- var k_samples_threshold = 12;
131
- var k_batch_threshold = 65536;
132
- var k_min_cpu_time = 642 * 1e6;
133
- var k_warmup_threshold = 5e5;
134
- function defaults(opts) {
135
- opts.gc ??= gc;
136
- opts.now ??= now;
137
- opts.heap ??= null;
138
- opts.params ??= {};
139
- opts.manual ??= false;
140
- opts.inner_gc ??= false;
141
- opts.$counters ??= false;
142
- opts.concurrency ??= k_concurrency;
143
- opts.min_samples ??= k_min_samples;
144
- opts.max_samples ??= k_max_samples;
145
- opts.min_cpu_time ??= k_min_cpu_time;
146
- opts.batch_unroll ??= k_batch_unroll;
147
- opts.batch_samples ??= k_batch_samples;
148
- opts.warmup_samples ??= k_warmup_samples;
149
- opts.batch_threshold ??= k_batch_threshold;
150
- opts.warmup_threshold ??= k_warmup_threshold;
151
- opts.samples_threshold ??= k_samples_threshold;
152
- if (opts.heap) opts.min_cpu_time *= k_cpu_time_rescale_heap;
153
- if (opts.gc && opts.inner_gc) opts.min_cpu_time *= k_cpu_time_rescale_inner_gc;
154
- }
155
- async function fn(fn2, opts = {}) {
156
- defaults(opts);
157
- let async = false;
158
- let batch = false;
159
- const params = Object.keys(opts.params);
160
- warmup: {
161
- const $p = new Array(params.length);
162
- for (let o = 0; o < params.length; o++) {
163
- $p[o] = await opts.params[o]();
164
- }
165
- const t0 = now();
166
- const r = fn2(...$p);
167
- let t1 = now();
168
- if (async = r instanceof Promise) await r, t1 = now();
169
- if (t1 - t0 <= opts.warmup_threshold) {
170
- for (let o = 0; o < opts.warmup_samples; o++) {
171
- for (let oo = 0; oo < params.length; oo++) {
172
- $p[oo] = await opts.params[oo]();
173
- }
174
- const t02 = now();
175
- await fn2(...$p);
176
- const t12 = now();
177
- if (batch = t12 - t02 <= opts.batch_threshold) break;
178
- }
179
- }
180
- }
181
- if (opts.manual) {
182
- batch = false;
183
- opts.concurrency = 1;
184
- }
185
- const loop = new AsyncFunction("$fn", "$gc", "$now", "$heap", "$params", "$counters", `
186
- ${!opts.$counters ? "" : "let _hc = false;"}
187
- ${!opts.$counters ? "" : "try { $counters.init(); _hc = true; } catch {}"}
188
-
189
- let _ = 0; let t = 0;
190
- let samples = new Array(2 ** 20);
191
- ${!opts.heap ? "" : "const heap = { _: 0, total: 0, min: Infinity, max: -Infinity };"}
192
- ${!(opts.gc && opts.inner_gc && !opts.gc.fallback) ? "" : "const gc = { total: 0, min: Infinity, max: -Infinity };"}
193
-
194
- ${!params.length ? "" : Array.from({ length: params.length }, (_, o) => `
195
- ${Array.from({ length: opts.concurrency }, (_2, c) => `
196
- let param_${o}_${c} = ${!batch ? "null" : `new Array(${opts.batch_samples})`};
197
- `.trim()).join(" ")}
198
- `.trim()).join("\n")}
199
-
200
- ${!opts.gc ? "" : `$gc();`}
201
-
202
- for (; _ < ${opts.max_samples}; _++) {
203
- if (_ >= ${opts.min_samples} && t >= ${opts.min_cpu_time}) break;
204
-
205
- ${!params.length ? "" : `
206
- ${!batch ? `
207
- ${Array.from({ length: params.length }, (_, o) => `
208
- ${Array.from({ length: opts.concurrency }, (_2, c) => `
209
- if ((param_${o}_${c} = $params[${o}]()) instanceof Promise) param_${o}_${c} = await param_${o}_${c};
210
- `.trim()).join(" ")}
211
- `.trim()).join("\n")}
212
- ` : `
213
- for (let o = 0; o < ${opts.batch_samples}; o++) {
214
- ${Array.from({ length: params.length }, (_, o) => `
215
- ${Array.from({ length: opts.concurrency }, (_2, c) => `
216
- if ((param_${o}_${c}[o] = $params[${o}]()) instanceof Promise) param_${o}_${c}[o] = await param_${o}_${c}[o];
217
- `.trim()).join(" ")}
218
- `.trim()).join("\n")}
219
- }
220
- `}
221
- `}
222
-
223
- ${!(opts.gc && opts.inner_gc) ? "" : `
224
- igc: {
225
- const t0 = $now();
226
- $gc(); t += $now() - t0;
227
- }
228
- `}
229
-
230
- ${!opts.manual ? "" : "let t2 = 0;"}
231
- ${!opts.heap ? "" : "const h0 = $heap();"}
232
- ${!opts.$counters ? "" : "if (_hc) try { $counters.before(); } catch {};"} const t0 = $now();
233
-
234
- ${!batch ? `
235
- ${!async ? "" : 1 >= opts.concurrency ? "" : "await Promise.all(["}
236
- ${Array.from({ length: opts.concurrency }, (_, c) => `
237
- ${!opts.manual ? "" : "t2 +="} ${!async ? "" : 1 < opts.concurrency ? "" : "await"} ${(!params.length ? `
238
- $fn()
239
- ` : `
240
- $fn(${Array.from({ length: params.length }, (_2, o) => `param_${o}_${c}`).join(", ")})
241
- `).trim()}${!async ? ";" : 1 < opts.concurrency ? "," : ";"}
242
- `.trim()).join("\n")}
243
- ${!async ? "" : 1 >= opts.concurrency ? "" : `]);`}
244
- ` : `
245
- for (let o = 0; o < ${opts.batch_samples / opts.batch_unroll | 0}; o++) {
246
- ${!params.length ? "" : `const param_offset = o * ${opts.batch_unroll};`}
247
-
248
- ${Array.from({ length: opts.batch_unroll }, (_, u) => `
249
- ${!async ? "" : 1 >= opts.concurrency ? "" : "await Promise.all(["}
250
- ${Array.from({ length: opts.concurrency }, (_2, c) => `
251
- ${!async ? "" : 1 < opts.concurrency ? "" : "await"} ${(!params.length ? `
252
- $fn()
253
- ` : `
254
- $fn(${Array.from({ length: params.length }, (_3, o) => `param_${o}_${c}[${u === 0 ? "" : `${u} + `}param_offset]`).join(", ")})
255
- `).trim()}${!async ? ";" : 1 < opts.concurrency ? "," : ";"}
256
- `.trim()).join(" ")}
257
- ${!async ? "" : 1 >= opts.concurrency ? "" : "]);"}
258
- `.trim()).join("\n")}
259
- }
260
- `}
261
-
262
- const t1 = $now();
263
- ${!opts.$counters ? "" : "if (_hc) try { $counters.after(); } catch {};"}
264
-
265
- ${!opts.heap ? "" : `
266
- heap: {
267
- const t0 = $now();
268
- const h1 = ($heap() - h0) ${!batch ? "" : `/ ${opts.batch_samples}`}; t += $now() - t0;
269
-
270
- if (0 <= h1) {
271
- heap._++;
272
- heap.total += h1;
273
- heap.min = Math.min(h1, heap.min);
274
- heap.max = Math.max(h1, heap.max);
275
- }
276
- }
277
- `}
278
-
279
- ${!(opts.gc && opts.inner_gc && !opts.gc.fallback) ? "" : `
280
- igc: {
281
- const t0 = $now();
282
- $gc(); const t1 = $now() - t0;
283
-
284
- t += t1;
285
- gc.total += t1;
286
- gc.min = Math.min(t1, gc.min);
287
- gc.max = Math.max(t1, gc.max);
288
- }
289
- `};
290
-
291
- const diff = ${opts.manual ? "t2" : "t1 - t0"};
292
- t += ${"manual" === opts.manual ? "t2" : "t1 - t0"};
293
- samples[_] = diff ${!batch ? "" : `/ ${opts.batch_samples}`};
294
- }
295
-
296
- samples.length = _;
297
- samples.sort((a, b) => a - b);
298
- if (samples.length > ${opts.samples_threshold}) samples = samples.slice(2, -2);
299
-
300
- return {
301
- samples,
302
- min: samples[0],
303
- max: samples[samples.length - 1],
304
- p25: samples[(.25 * (samples.length - 1)) | 0],
305
- p50: samples[(.50 * (samples.length - 1)) | 0],
306
- p75: samples[(.75 * (samples.length - 1)) | 0],
307
- p99: samples[(.99 * (samples.length - 1)) | 0],
308
- p999: samples[(.999 * (samples.length - 1)) | 0],
309
- avg: samples.reduce((a, v) => a + v, 0) / samples.length,
310
- ticks: samples.length ${!batch ? "" : `* ${opts.batch_samples}`},
311
- ${!opts.heap ? "" : "heap: { ...heap, avg: heap.total / heap._ },"}
312
- ${!(opts.gc && opts.inner_gc && !opts.gc.fallback) ? "" : "gc: { ...gc, avg: gc.total / _ },"}
313
- ${!opts.$counters ? "" : `...(!_hc ? {} : { counters: $counters.translate(${!batch ? 1 : opts.batch_samples}, _) }),`}
314
- };
315
-
316
- ${!opts.$counters ? "" : "if (_hc) try { $counters.deinit(); } catch {};"}
317
- `);
318
- return {
319
- kind: "fn",
320
- debug: loop.toString(),
321
- ...await loop(fn2, opts.gc, opts.now, opts.heap, opts.params, opts.$counters)
322
- };
323
- }
324
- async function iter(iter2, opts = {}) {
325
- const _ = {};
326
- defaults(opts);
327
- let samples = new Array(2 ** 20);
328
- const _i = { next() {
329
- return _.next();
330
- } };
331
- const ctx = {
332
- [Symbol.iterator]() {
333
- return _i;
334
- },
335
- [Symbol.asyncIterator]() {
336
- return _i;
337
- },
338
- get(name) {
339
- return opts.args?.[name];
340
- }
341
- };
342
- const gen = function* () {
343
- let batch = false;
344
- warmup: {
345
- const t0 = now();
346
- yield void 0;
347
- const t1 = now();
348
- if (t1 - t0 <= opts.warmup_threshold) {
349
- for (let o = 0; o < opts.warmup_samples; o++) {
350
- const t02 = now();
351
- yield void 0;
352
- const t12 = now();
353
- if (batch = t12 - t02 <= opts.batch_threshold) break;
354
- }
355
- }
356
- }
357
- const loop = new GeneratorFunction("$gc", "$now", "$samples", _.debug = `
358
- let _ = 0; let t = 0;
359
-
360
- ${!opts.gc ? "" : `$gc();`}
361
-
362
- for (; _ < ${opts.max_samples}; _++) {
363
- if (_ >= ${opts.min_samples} && t >= ${opts.min_cpu_time}) break;
364
-
365
- ${!(opts.gc && opts.inner_gc) ? "" : `
366
- let inner_gc_cost = 0;
367
-
368
- igc: {
369
- const t0 = $now(); $gc();
370
- inner_gc_cost = $now() - t0;
371
- }
372
- `}
373
-
374
- const t0 = $now();
375
-
376
- ${!batch ? "yield void 0;" : `
377
- for (let o = 0; o < ${opts.batch_samples / opts.batch_unroll | 0}; o++) {
378
- ${new Array(opts.batch_unroll).fill("yield void 0;").join(" ")}
379
- }
380
- `}
381
-
382
- const t1 = $now();
383
- const diff = t1 - t0;
384
-
385
- $samples[_] = diff ${!batch ? "" : `/ ${opts.batch_samples}`};
386
- t += diff ${!(opts.gc && opts.inner_gc) ? "" : "+ inner_gc_cost"};
387
- }
388
-
389
- $samples.length = _;
390
- `)(opts.gc, opts.now, samples);
391
- _.batch = batch;
392
- _.next = loop.next.bind(loop);
393
- yield void 0;
394
- }();
395
- await iter2((_.next = gen.next.bind(gen), ctx));
396
- if (samples.length < opts.min_samples) throw new TypeError(`expected at least ${opts.min_samples} samples from iterator`);
397
- samples.sort((a, b) => a - b);
398
- if (samples.length > opts.samples_threshold) samples = samples.slice(2, -2);
399
- return {
400
- samples,
401
- kind: "iter",
402
- debug: _.debug,
403
- min: samples[0],
404
- max: samples[samples.length - 1],
405
- p25: samples[0.25 * (samples.length - 1) | 0],
406
- p50: samples[0.5 * (samples.length - 1) | 0],
407
- p75: samples[0.75 * (samples.length - 1) | 0],
408
- p99: samples[0.99 * (samples.length - 1) | 0],
409
- p999: samples[0.999 * (samples.length - 1) | 0],
410
- avg: samples.reduce((a, v) => a + v, 0) / samples.length,
411
- ticks: samples.length * (!_.batch ? 1 : opts.batch_samples)
412
- };
413
- }
414
-
415
- // ../../node_modules/.pnpm/mitata@1.0.34/node_modules/mitata/src/main.mjs
416
- var FLAGS = 0;
417
- var $counters = null;
418
- var COLLECTIONS = [{ id: 0, name: null, types: [], trials: [] }];
419
- var flags = {
420
- compact: 1 << 0,
421
- baseline: 1 << 1
422
- };
423
- var B = class {
424
- f = null;
425
- _args = {};
426
- _name = "";
427
- _group = 0;
428
- _gc = "once";
429
- flags = FLAGS;
430
- _highlight = false;
431
- constructor(name, f) {
432
- this.f = f;
433
- this.name(name);
434
- if (!kind(f)) throw new TypeError("expected iterator, generator or one-shot function");
435
- }
436
- name(name, color = false) {
437
- return this._name = name, this.highlight(color), this;
438
- }
439
- gc(gc2 = "once") {
440
- if (![true, false, "once", "inner"].includes(gc2)) throw new TypeError("invalid gc type");
441
- return this._gc = gc2, this;
442
- }
443
- highlight(color = false) {
444
- if (!color) return this._highlight = false, this;
445
- if (!$2.colors.includes(color)) throw new TypeError("invalid highlight color");
446
- return this._highlight = color, this;
447
- }
448
- compact(bool = true) {
449
- if (bool) return this.flags |= flags.compact, this;
450
- if (!bool) return this.flags &= ~flags.compact, this;
451
- }
452
- baseline(bool = true) {
453
- if (bool) return this.flags |= flags.baseline, this;
454
- if (!bool) return this.flags &= ~flags.baseline, this;
455
- }
456
- range(name, s, e, m = 8) {
457
- const arr = [];
458
- for (let o = s; o <= e; o *= m) arr.push(Math.min(o, e));
459
- if (!arr.includes(e)) arr.push(e);
460
- return this.args(name, arr);
461
- }
462
- dense_range(name, s, e, a = 1) {
463
- const arr = [];
464
- for (let o = s; o <= e; o += a) arr.push(o);
465
- if (!arr.includes(e)) arr.push(e);
466
- return this.args(name, arr);
467
- }
468
- args(name, args) {
469
- if (name === null) return delete this._args.x, this;
470
- if (Array.isArray(name)) return this._args.x = name, this;
471
- if (null === args && "string" === typeof name) return delete this._args[name], this;
472
- if (Array.isArray(args) && "string" === typeof name) return this._args[name] = args, this;
473
- if (null !== name && "object" === typeof name) {
474
- for (const key in name) {
475
- const v = name[key];
476
- if (v == null) delete this._args[key];
477
- else if (Array.isArray(v)) this._args[key] = v;
478
- else throw new TypeError("invalid arguments map value");
479
- }
480
- return this;
481
- }
482
- throw new TypeError("invalid arguments");
483
- }
484
- *_names() {
485
- const args = Object.keys(this._args);
486
- const kind2 = 0 === args.length ? "static" : 1 === args.length ? "args" : "multi-args";
487
- if (kind2 === "static") {
488
- yield this._name;
489
- } else {
490
- const offsets = new Array(args.length).fill(0);
491
- const runs = args.reduce((len, name) => len * this._args[name].length, 1);
492
- for (let o = 0; o < runs; o++) {
493
- {
494
- const _args = {};
495
- let _name = this._name;
496
- for (let oo = 0; oo < args.length; oo++) _args[args[oo]] = this._args[args[oo]][offsets[oo]];
497
- for (let oo = 0; oo < args.length; oo++) _name = _name.replaceAll(`$${args[oo]}`, _args[args[oo]]);
498
- yield _name;
499
- }
500
- let offset = 0;
501
- do {
502
- offsets[offset] = (1 + offsets[offset]) % this._args[args[offset]].length;
503
- } while (0 === offsets[offset++] && offset < args.length);
504
- }
505
- }
506
- }
507
- async run(thrw = false) {
508
- const args = Object.keys(this._args);
509
- const kind2 = 0 === args.length ? "static" : 1 === args.length ? "args" : "multi-args";
510
- const tune = {
511
- $counters,
512
- inner_gc: "inner" === this._gc,
513
- gc: !this._gc ? false : void 0,
514
- heap: await (async () => {
515
- if (globalThis.Bun) {
516
- const { memoryUsage } = await import("bun:jsc");
517
- return () => {
518
- const m = memoryUsage();
519
- return m.current;
520
- };
521
- }
522
- try {
523
- const { getHeapStatistics } = await import("v8");
524
- getHeapStatistics();
525
- return () => {
526
- const m = getHeapStatistics();
527
- return m.used_heap_size + m.malloced_memory;
528
- };
529
- } catch {
530
- }
531
- })()
532
- };
533
- if (kind2 === "static") {
534
- let stats, error;
535
- try {
536
- stats = await measure(this.f, tune);
537
- } catch (err) {
538
- error = err;
539
- if (thrw) throw err;
540
- }
541
- return {
542
- kind: kind2,
543
- args: this._args,
544
- alias: this._name,
545
- group: this._group,
546
- baseline: !!(this.flags & flags.baseline),
547
- runs: [{
548
- stats,
549
- error,
550
- args: {},
551
- name: this._name
552
- }],
553
- style: {
554
- highlight: this._highlight,
555
- compact: !!(this.flags & flags.compact)
556
- }
557
- };
558
- } else {
559
- const offsets = new Array(args.length).fill(0);
560
- const runs = new Array(args.reduce((len, name) => len * this._args[name].length, 1));
561
- for (let o = 0; o < runs.length; o++) {
562
- {
563
- let stats, error;
564
- const _args = {};
565
- let _name = this._name;
566
- for (let oo = 0; oo < args.length; oo++) _args[args[oo]] = this._args[args[oo]][offsets[oo]];
567
- for (let oo = 0; oo < args.length; oo++) _name = _name.replaceAll(`$${args[oo]}`, _args[args[oo]]);
568
- try {
569
- stats = await measure(this.f, { ...tune, args: _args });
570
- } catch (err) {
571
- error = err;
572
- if (thrw) throw err;
573
- }
574
- runs[o] = {
575
- stats,
576
- error,
577
- args: _args,
578
- name: _name
579
- };
580
- }
581
- let offset = 0;
582
- do {
583
- offsets[offset] = (1 + offsets[offset]) % this._args[args[offset]].length;
584
- } while (0 === offsets[offset++] && offset < args.length);
585
- }
586
- return {
587
- runs,
588
- kind: kind2,
589
- args: this._args,
590
- alias: this._name,
591
- group: this._group,
592
- baseline: !!(this.flags & flags.baseline),
593
- style: {
594
- highlight: this._highlight,
595
- compact: !!(this.flags & flags.compact)
596
- }
597
- };
598
- }
599
- }
600
- };
601
- function bench(n, fn2) {
602
- if (typeof n === "function") fn2 = n, n = fn2.name || "anonymous";
603
- const collection = COLLECTIONS[COLLECTIONS.length - 1];
604
- const b = new B(n, fn2);
605
- b._group = collection.id;
606
- return collection.trials.push(b), b;
607
- }
608
- function colors() {
609
- return globalThis.tjs?.env?.FORCE_COLOR || globalThis.process?.env?.FORCE_COLOR || !globalThis.Deno?.noColor && !globalThis.tjs?.env?.NO_COLOR && !globalThis.process?.env?.NO_COLOR && !globalThis.process?.env?.NODE_DISABLE_COLORS;
610
- }
611
- async function cpu() {
612
- if (globalThis.process?.versions?.webcontainer) return null;
613
- try {
614
- let n;
615
- if (n = __require("os")?.cpus?.()?.[0]?.model) return n;
616
- } catch {
617
- }
618
- try {
619
- let n;
620
- if (n = __require("os")?.cpus?.()?.[0]?.model) return n;
621
- } catch {
622
- }
623
- try {
624
- let n;
625
- if (n = globalThis.tjs?.system?.cpus?.[0]?.model) return n;
626
- } catch {
627
- }
628
- try {
629
- let n;
630
- if (n = (await import("os"))?.cpus?.()?.[0]?.model) return n;
631
- } catch {
632
- }
633
- return null;
634
- }
635
- function version() {
636
- return {
637
- v8: () => globalThis.version?.(),
638
- bun: () => globalThis.Bun?.version,
639
- "txiki.js": () => globalThis.tjs?.version,
640
- deno: () => globalThis.Deno?.version?.deno,
641
- llrt: () => globalThis.process?.versions?.llrt,
642
- node: () => globalThis.process?.versions?.node,
643
- graaljs: () => globalThis.Graal?.versionGraalVM,
644
- webcontainer: () => globalThis.process?.versions?.webcontainer,
645
- "quickjs-ng": () => globalThis.navigator?.userAgent?.split?.("/")[1],
646
- hermes: () => globalThis.HermesInternal?.getRuntimeProperties?.()?.["OSS Release Version"]
647
- }[runtime()]?.() || null;
648
- }
649
- function runtime() {
650
- if (globalThis.d8) return "v8";
651
- if (globalThis.tjs) return "txiki.js";
652
- if (globalThis.Graal) return "graaljs";
653
- if (globalThis.process?.versions?.llrt) return "llrt";
654
- if (globalThis.process?.versions?.webcontainer) return "webcontainer";
655
- if (globalThis.inIon && globalThis.performance?.mozMemory) return "spidermonkey";
656
- if (globalThis.window && globalThis.netscape && globalThis.InternalError) return "firefox";
657
- if (globalThis.window && globalThis.navigator && Error.prepareStackTrace) return "chromium";
658
- if (globalThis.navigator?.userAgent?.toLowerCase?.()?.includes?.("quickjs-ng")) return "quickjs-ng";
659
- if (globalThis.$262 && globalThis.lockdown && globalThis.AsyncDisposableStack) return "XS Moddable";
660
- if (globalThis.$ && "IsHTMLDDA" in globalThis.$ && new Error().stack.includes("runtime@")) return "jsc";
661
- if (globalThis.window && globalThis.navigator && new Error().stack.includes("runtime@")) return "webkit";
662
- if (globalThis.os && globalThis.std) return "quickjs";
663
- if (globalThis.Bun) return "bun";
664
- if (globalThis.Deno) return "deno";
665
- if (globalThis.HermesInternal) return "hermes";
666
- if (globalThis.window && globalThis.navigator) return "browser";
667
- if (globalThis.process) return "node";
668
- else return null;
669
- }
670
- async function arch() {
671
- if (runtime() === "webcontainer") return "js + wasm";
672
- try {
673
- let n;
674
- if (n = Deno?.build?.target) return n;
675
- } catch {
676
- }
677
- try {
678
- const os = await import("os");
679
- return `${os.arch()}-${os.platform()}`;
680
- } catch {
681
- }
682
- if (globalThis.process?.arch && globalThis.process?.platform) {
683
- return `${globalThis.process.arch}-${globalThis.process.platform}`;
684
- }
685
- if (runtime() === "txiki.js") {
686
- return `${globalThis.tjs.system?.arch}-${globalThis.tjs.system?.platform}`;
687
- }
688
- if (runtime() === "spidermonkey") {
689
- try {
690
- const build = globalThis.getBuildConfiguration();
691
- const platforms = ["osx", "linux", "android", "windows"];
692
- const archs = ["arm", "x64", "x86", "wasi", "arm64", "mips32", "mips64", "loong64", "riscv64"];
693
- const arch2 = archs.find((k) => build[k]);
694
- const platform = platforms.find((k) => build[k]);
695
- if (arch2) return !platform ? arch2 : `${arch2}-${platform}`;
696
- } catch {
697
- }
698
- try {
699
- if (globalThis.isAvxPresent()) return "x86_64";
700
- } catch {
701
- }
702
- }
703
- return null;
704
- }
705
- function defaults2(opts) {
706
- opts.print ??= print;
707
- opts.throw ??= false;
708
- opts.filter ??= /.*/;
709
- opts.format ??= "mitata";
710
- opts.colors ??= colors();
711
- opts.observe ??= (trial) => trial;
712
- }
713
- async function run(opts = {}) {
714
- defaults2(opts);
715
- const t = Date.now();
716
- const benchmarks = [];
717
- const noop = await measure(() => {
718
- });
719
- const _cpu = await measure(() => {
720
- }, { batch_unroll: 1 });
721
- const noop_inner_gc = await measure(() => {
722
- }, { inner_gc: true });
723
- const noop_iter = await measure((state) => {
724
- for (const _ of state) ;
725
- });
726
- const context = {
727
- now: t,
728
- arch: await arch(),
729
- version: version(),
730
- runtime: runtime(),
731
- cpu: {
732
- name: await cpu(),
733
- freq: 1 / _cpu.avg
734
- },
735
- noop: {
736
- fn: noop,
737
- iter: noop_iter,
738
- fn_gc: noop_inner_gc
739
- }
740
- };
741
- if (!$counters && context.arch?.includes?.("darwin") && ["bun", "node", "deno"].includes(context.runtime)) {
742
- try {
743
- $counters = await import("@mitata/counters");
744
- if (0 !== process.getuid()) throw $counters = false, 1;
745
- } catch {
746
- }
747
- }
748
- if (!$counters && context.arch?.includes?.("linux") && ["bun", "node", "deno"].includes(context.runtime)) {
749
- try {
750
- $counters = await import("@mitata/counters");
751
- } catch (err) {
752
- if (err?.message?.includes?.("PermissionDenied")) $counters = false;
753
- }
754
- }
755
- const layout = COLLECTIONS.map((c) => ({ name: c.name, types: c.types }));
756
- const format = "string" === typeof opts.format ? opts.format : Object.keys(opts.format)[0];
757
- await formats[format](context, { ...opts, format: opts.format[format] }, benchmarks, layout);
758
- return COLLECTIONS = [{ name: 0, types: [], trials: [] }], { layout, context, benchmarks };
759
- }
760
- var formats = {
761
- async quiet(_, opts, benchmarks) {
762
- for (const collection of COLLECTIONS) {
763
- for (const trial of collection.trials) {
764
- if (opts.filter.test(trial._name)) benchmarks.push(opts.observe(await trial.run(opts.throw)));
765
- }
766
- }
767
- },
768
- async json(ctx, opts, benchmarks, layout) {
769
- const print2 = opts.print;
770
- const debug = opts.format?.debug ?? true;
771
- const samples = opts.format?.samples ?? true;
772
- for (const collection of COLLECTIONS) {
773
- for (const trial of collection.trials) {
774
- if (opts.filter.test(trial._name)) benchmarks.push(opts.observe(await trial.run(opts.throw)));
775
- }
776
- }
777
- print2(JSON.stringify(
778
- {
779
- layout,
780
- benchmarks,
781
- context: ctx
782
- },
783
- (k, v) => {
784
- if (!debug && k === "debug") return "";
785
- if (!samples && k === "samples") return null;
786
- if (!(v instanceof Error)) return v;
787
- return { message: String(v.message), stack: v.stack };
788
- },
789
- 0
790
- ));
791
- },
792
- async markdown(ctx, opts, benchmarks) {
793
- let first = true;
794
- const print2 = opts.print;
795
- print2(`clk: ~${ctx.cpu.freq.toFixed(2)} GHz`);
796
- print2(`cpu: ${ctx.cpu.name}`);
797
- print2(`runtime: ${ctx.runtime}${!ctx.version ? "" : ` ${ctx.version}`} (${ctx.arch})`);
798
- print2("");
799
- for (const collection of COLLECTIONS) {
800
- const trials = [];
801
- if (!collection.trials.length) continue;
802
- for (const trial of collection.trials) {
803
- if (opts.filter.test(trial._name)) {
804
- let bench2 = await trial.run(opts.throw);
805
- bench2 = opts.observe(bench2);
806
- trials.push(bench2);
807
- benchmarks.push(bench2);
808
- }
809
- }
810
- if (!trials.length) continue;
811
- if (!first) print2("");
812
- const name_len = trials.reduce((a, b) => Math.max(a, b.runs.reduce((a2, b2) => Math.max(a2, b2.name.length), 0)), 0);
813
- print2(`| ${(collection.name ? `\u2022 ${collection.name}` : !first ? "" : "benchmark").padEnd(name_len)} | ${"avg".padStart(2 + 14)} | ${"min".padStart(2 + 9)} | ${"p75".padStart(2 + 9)} | ${"p99".padStart(2 + 9)} | ${"max".padStart(2 + 9)} |`);
814
- print2(`| ${"-".repeat(name_len)} | ${"-".repeat(2 + 14)} | ${"-".repeat(2 + 9)} | ${"-".repeat(2 + 9)} | ${"-".repeat(2 + 9)} | ${"-".repeat(2 + 9)} |`);
815
- first = false;
816
- for (const trial of trials) {
817
- for (const run2 of trial.runs) {
818
- if (run2.error) print2(`| ${run2.name.padEnd(name_len)} | error: ${run2.error.message ?? run2.error} |`);
819
- else print2(`| ${run2.name.padEnd(name_len)} | \`${`${$2.time(run2.stats.avg)}/iter`.padStart(14)}\` | \`${$2.time(run2.stats.min).padStart(9)}\` | \`${$2.time(run2.stats.p75).padStart(9)}\` | \`${$2.time(run2.stats.p99).padStart(9)}\` | \`${$2.time(run2.stats.max).padStart(9)}\` |`);
820
- }
821
- }
822
- }
823
- },
824
- async mitata(ctx, opts, benchmarks) {
825
- const print2 = opts.print;
826
- let k_legend = opts.format?.name ?? "longest";
827
- if ("fixed" === k_legend) k_legend = 28;
828
- else if (k_legend === "longest") {
829
- k_legend = 28;
830
- for (const collection of COLLECTIONS) {
831
- for (const trial of collection.trials) {
832
- if (opts.filter.test(trial._name)) {
833
- for (const name of trial._names()) {
834
- k_legend = Math.max(k_legend, name.length);
835
- }
836
- }
837
- }
838
- }
839
- }
840
- k_legend = Math.max(20, k_legend);
841
- if (!opts.colors) print2(`clk: ~${ctx.cpu.freq.toFixed(2)} GHz`);
842
- else print2($2.gray + `clk: ~${ctx.cpu.freq.toFixed(2)} GHz` + $2.reset);
843
- if (!opts.colors) print2(`cpu: ${ctx.cpu.name}`);
844
- else print2($2.gray + `cpu: ${ctx.cpu.name}` + $2.reset);
845
- if (!opts.colors) print2(`runtime: ${ctx.runtime}${!ctx.version ? "" : ` ${ctx.version}`} (${ctx.arch})`);
846
- else print2($2.gray + `runtime: ${ctx.runtime}${!ctx.version ? "" : ` ${ctx.version}`} (${ctx.arch})` + $2.reset);
847
- print2("");
848
- print2(`${"benchmark".padEnd(k_legend - 1)} avg (min \u2026 max) p75 / p99 (min \u2026 top 1%)`);
849
- print2("-".repeat(15 + k_legend) + " " + "-".repeat(31));
850
- let first = true;
851
- let optimized_out_warning = false;
852
- for (const collection of COLLECTIONS) {
853
- const trials = [];
854
- let prev_run_gap = false;
855
- if (!collection.trials.length) continue;
856
- const has_matches = collection.trials.some((trial) => opts.filter.test(trial._name));
857
- if (!has_matches) continue;
858
- else if (first) {
859
- first = false;
860
- if (collection.name) {
861
- print2(`\u2022 ${collection.name}`);
862
- if (!opts.colors) print2("-".repeat(15 + k_legend) + " " + "-".repeat(31));
863
- else print2($2.gray + "-".repeat(15 + k_legend) + " " + "-".repeat(31) + $2.reset);
864
- }
865
- } else {
866
- print2("");
867
- if (collection.name) print2(`\u2022 ${collection.name}`);
868
- if (!opts.colors) print2("-".repeat(15 + k_legend) + " " + "-".repeat(31));
869
- else print2($2.gray + "-".repeat(15 + k_legend) + " " + "-".repeat(31) + $2.reset);
870
- }
871
- for (const trial of collection.trials) {
872
- if (opts.filter.test(trial._name)) {
873
- let bench2 = await trial.run(opts.throw);
874
- bench2 = opts.observe(bench2);
875
- trials.push([trial, bench2]);
876
- benchmarks.push(bench2);
877
- if (-1 === $2.colors.indexOf(trial._highlight)) trial._highlight = null;
878
- const _h = !opts.colors || !trial._highlight ? (x) => x : (x) => $2[trial._highlight] + x + $2.reset;
879
- for (const r of bench2.runs) {
880
- if (prev_run_gap) print2("");
881
- if (r.error) {
882
- if (!opts.colors) print2(`${_h($2.str(r.name, k_legend).padEnd(k_legend))} error: ${r.error.message ?? r.error}`);
883
- else print2(`${_h($2.str(r.name, k_legend).padEnd(k_legend))} ${$2.red + "error:" + $2.reset} ${r.error.message ?? r.error}`);
884
- } else {
885
- const compact = trial.flags & flags.compact;
886
- const noop = "iter" === r.stats.kind ? ctx.noop.iter : trial._gc !== "inner" ? ctx.noop.fn : ctx.noop.fn_gc;
887
- const optimized_out = r.stats.avg < 1.42 * noop.avg;
888
- optimized_out_warning = optimized_out_warning || optimized_out;
889
- if (compact) {
890
- let l = "";
891
- prev_run_gap = false;
892
- const avg = $2.time(r.stats.avg).padStart(9);
893
- const name = $2.str(r.name, k_legend).padEnd(k_legend);
894
- l += _h(name) + " ";
895
- if (!opts.colors) l += avg + "/iter";
896
- else l += $2.bold + $2.yellow + avg + $2.reset + $2.bold + "/iter" + $2.reset;
897
- const p75 = $2.time(r.stats.p75).padStart(9);
898
- const p99 = $2.time(r.stats.p99).padStart(9);
899
- const bins = $2.histogram.bins(r.stats, 11, 0.99);
900
- const histogram = $2.histogram.ascii(bins, 1, { colors: opts.colors });
901
- l += " ";
902
- if (!opts.colors) l += p75 + " " + p99 + " " + histogram[0];
903
- else l += $2.gray + p75 + " " + p99 + $2.reset + " " + histogram[0];
904
- if (optimized_out)
905
- if (!opts.colors) l += " !";
906
- else l += $2.red + " !" + $2.reset;
907
- print2(l);
908
- } else {
909
- let l = "";
910
- const avg = $2.time(r.stats.avg).padStart(9);
911
- const name = $2.str(r.name, k_legend).padEnd(k_legend);
912
- l += _h(name) + " ";
913
- const p75 = $2.time(r.stats.p75).padStart(9);
914
- const bins = $2.histogram.bins(r.stats, 21, 0.99);
915
- const histogram = $2.histogram.ascii(bins, r.stats.gc && r.stats.heap ? 2 : !(r.stats.gc || r.stats.heap) ? 2 : 3, { colors: opts.colors });
916
- if (!opts.colors) l += avg + "/iter " + p75 + " " + histogram[0];
917
- else l += $2.bold + $2.yellow + avg + $2.reset + $2.bold + "/iter" + $2.reset + " " + $2.gray + p75 + $2.reset + " " + histogram[0];
918
- if (optimized_out)
919
- if (!opts.colors) l += " !";
920
- else l += $2.red + " !" + $2.reset;
921
- print2(l);
922
- l = "";
923
- const min = $2.time(r.stats.min);
924
- const max = $2.time(r.stats.max);
925
- const p99 = $2.time(r.stats.p99).padStart(9);
926
- const diff = 2 * 9 - (min.length + max.length);
927
- l += " ".repeat(diff + k_legend - 8);
928
- if (!opts.colors) l += "(" + min + " \u2026 " + max + ")";
929
- else l += $2.gray + "(" + $2.reset + $2.cyan + min + $2.reset + $2.gray + " \u2026 " + $2.reset + $2.magenta + max + $2.reset + $2.gray + ")" + $2.reset;
930
- l += " ";
931
- if (!opts.colors) l += p99 + " " + histogram[1];
932
- else l += $2.gray + p99 + $2.reset + " " + histogram[1];
933
- print2(l);
934
- if (r.stats.gc) {
935
- l = "";
936
- prev_run_gap = true;
937
- l += " ".repeat(k_legend - 10);
938
- const gcm = $2.time(r.stats.gc.min).padStart(9);
939
- const gcx = $2.time(r.stats.gc.max).padStart(9);
940
- if (!opts.colors)
941
- l += "gc(" + gcm + " \u2026 " + gcx + ")";
942
- else l += $2.gray + "gc(" + $2.reset + $2.blue + gcm + $2.reset + $2.gray + " \u2026 " + $2.reset + $2.blue + gcx + $2.reset + $2.gray + ")" + $2.reset;
943
- if (r.stats.heap) {
944
- l += " ";
945
- const ha = $2.bytes(r.stats.heap.avg).padStart(9);
946
- const hm = $2.bytes(r.stats.heap.min).padStart(9);
947
- const hx = $2.bytes(r.stats.heap.max).padStart(9);
948
- if (!opts.colors)
949
- l += ha + " (" + hm + "\u2026" + hx + ")";
950
- else l += $2.yellow + ha + $2.reset + $2.gray + " (" + $2.reset + $2.yellow + hm + $2.reset + $2.gray + "\u2026" + $2.reset + $2.yellow + hx + $2.reset + $2.gray + ")" + $2.reset;
951
- } else {
952
- l += " ";
953
- const gca = $2.time(r.stats.gc.avg).padStart(9);
954
- if (!opts.colors) l += gca + " " + histogram[2];
955
- else l += $2.blue + gca + $2.reset + " " + histogram[2];
956
- }
957
- print2(l);
958
- } else if (r.stats.heap) {
959
- prev_run_gap = true;
960
- l = " ".repeat(k_legend - 8);
961
- const ha = $2.bytes(r.stats.heap.avg).padStart(9);
962
- const hm = $2.bytes(r.stats.heap.min).padStart(9);
963
- const hx = $2.bytes(r.stats.heap.max).padStart(9);
964
- if (!opts.colors)
965
- l += "(" + hm + " \u2026 " + hx + ") " + ha + " " + histogram[2];
966
- else l += $2.gray + "(" + $2.reset + $2.yellow + hm + $2.reset + $2.gray + " \u2026 " + $2.reset + $2.yellow + hx + $2.reset + $2.gray + ") " + $2.reset + $2.yellow + ha + $2.reset + " " + histogram[2];
967
- print2(l);
968
- }
969
- if (r.stats.counters) {
970
- l = "";
971
- prev_run_gap = true;
972
- if (ctx.arch.includes("linux")) {
973
- const _bmispred = r.stats.counters._bmispred.avg;
974
- const ipc = r.stats.counters.instructions.avg / r.stats.counters.cycles.avg;
975
- const cache = 100 - Math.min(100, 100 * r.stats.counters.cache.misses.avg / r.stats.counters.cache.avg);
976
- l += " ".repeat(k_legend - 12);
977
- if (!opts.colors) l += $2.amount(ipc).padStart(7) + " ipc";
978
- else l += $2.bold + $2.green + $2.amount(ipc).padStart(7) + $2.reset + $2.bold + " ipc" + $2.reset;
979
- if (!opts.colors) l += " (" + cache.toFixed(2).padStart(6) + "% cache)";
980
- else l += $2.gray + " (" + $2.reset + (50 > cache ? $2.red : 84 < cache ? $2.green : $2.yellow) + cache.toFixed(2).padStart(6) + "%" + $2.reset + " cache" + $2.gray + ")" + $2.reset;
981
- if (!opts.colors) l += " " + $2.amount(_bmispred).padStart(7) + " branch misses";
982
- else l += " " + $2.green + $2.amount(_bmispred).padStart(7) + $2.reset + " branch misses";
983
- print2(l);
984
- l = "";
985
- l += " ".repeat(k_legend - 20);
986
- if (opts.colors) l += $2.gray;
987
- l += $2.amount(r.stats.counters.cycles.avg).padStart(7) + " cycles";
988
- l += " " + $2.amount(r.stats.counters.instructions.avg).padStart(7) + " instructions";
989
- l += " " + $2.amount(r.stats.counters.cache.avg).padStart(7) + " c-refs";
990
- l += " " + $2.amount(r.stats.counters.cache.misses.avg).padStart(7) + " c-misses";
991
- if (opts.colors) l += $2.reset;
992
- print2(l);
993
- }
994
- if (ctx.arch.includes("darwin")) {
995
- const ipc = r.stats.counters.instructions.avg / r.stats.counters.cycles.avg;
996
- const stalls = 100 * r.stats.counters.cycles.stalls.avg / r.stats.counters.cycles.avg;
997
- const ldst = 100 * r.stats.counters.instructions.loads_and_stores.avg / r.stats.counters.instructions.avg;
998
- const cache = 100 - Math.min(100, 100 * (r.stats.counters.l1.miss_loads.avg + r.stats.counters.l1.miss_stores.avg) / r.stats.counters.instructions.loads_and_stores.avg);
999
- l += " ".repeat(k_legend - 13);
1000
- if (!opts.colors) l += $2.amount(ipc).padStart(7) + " ipc";
1001
- else l += $2.bold + $2.green + $2.amount(ipc).padStart(7) + $2.reset + $2.bold + " ipc" + $2.reset;
1002
- if (!opts.colors) l += " (" + stalls.toFixed(2).padStart(6) + "% stalls)";
1003
- else l += $2.gray + " (" + $2.reset + (12 > stalls ? $2.green : 50 < stalls ? $2.red : $2.yellow) + stalls.toFixed(2).padStart(6) + "%" + $2.reset + " stalls" + $2.gray + ")" + $2.reset;
1004
- if (!opts.colors) l += " " + cache.toFixed(2).padStart(6) + "% L1 data cache";
1005
- else l += " " + (50 > cache ? $2.red : 84 < cache ? $2.green : $2.yellow) + cache.toFixed(2).padStart(6) + "%" + $2.reset + " L1 data cache";
1006
- print2(l);
1007
- l = "";
1008
- l += " ".repeat(k_legend - 20);
1009
- if (opts.colors) l += $2.gray;
1010
- l += $2.amount(r.stats.counters.cycles.avg).padStart(7) + " cycles";
1011
- l += " " + $2.amount(r.stats.counters.instructions.avg).padStart(7) + " instructions";
1012
- l += " " + ldst.toFixed(2).padStart(6) + "% retired LD/ST (" + $2.amount(r.stats.counters.instructions.loads_and_stores.avg).padStart(7) + ")";
1013
- if (opts.colors) l += $2.reset;
1014
- print2(l);
1015
- }
1016
- }
1017
- }
1018
- }
1019
- }
1020
- }
1021
- }
1022
- if (collection.types.includes("b")) {
1023
- const map = {};
1024
- const colors2 = {};
1025
- for (const [trial, bench2] of trials) {
1026
- for (const r of bench2.runs) {
1027
- if (r.error) continue;
1028
- map[r.name] = r.stats.avg;
1029
- colors2[r.name] = $2[trial._highlight];
1030
- }
1031
- }
1032
- if (Object.keys(map).length) {
1033
- print2("");
1034
- $2.barplot.ascii(map, k_legend, 44, {
1035
- steps: -10,
1036
- colors: !opts.colors ? null : colors2
1037
- }).forEach((l) => print2(l));
1038
- }
1039
- }
1040
- if (collection.types.includes("x")) {
1041
- const map = {};
1042
- const colors2 = {};
1043
- if (1 === trials.length) {
1044
- for (const [trial, bench2] of trials) {
1045
- for (const r of bench2.runs) {
1046
- map[r.name] = r.stats;
1047
- colors2[r.name] = $2[trial._highlight];
1048
- }
1049
- }
1050
- } else {
1051
- for (const [trial, bench2] of trials) {
1052
- const runs = bench2.runs.filter((r) => r.stats);
1053
- if (!runs.length) continue;
1054
- if (1 === runs.length) {
1055
- map[runs[0].name] = runs[0].stats;
1056
- colors2[runs[0].name] = $2[trial._highlight];
1057
- } else {
1058
- const stats = {
1059
- avg: 0,
1060
- min: Infinity,
1061
- p25: Infinity,
1062
- p75: -Infinity,
1063
- p99: -Infinity
1064
- };
1065
- for (const r of runs) {
1066
- stats.avg += r.stats.avg;
1067
- stats.min = Math.min(stats.min, r.stats.min);
1068
- stats.p25 = Math.min(stats.p25, r.stats.p25);
1069
- stats.p75 = Math.max(stats.p75, r.stats.p75);
1070
- stats.p99 = Math.max(stats.p99, r.stats.p99);
1071
- }
1072
- map[bench2.alias] = stats;
1073
- stats.avg /= runs.length;
1074
- colors2[bench2.alias] = $2[trial._highlight];
1075
- }
1076
- }
1077
- }
1078
- if (Object.keys(map).length) {
1079
- print2("");
1080
- $2.boxplot.ascii(map, k_legend, 44, {
1081
- colors: !opts.colors ? null : colors2
1082
- }).forEach((l) => print2(l));
1083
- }
1084
- }
1085
- if (collection.types.includes("l")) {
1086
- const map = {};
1087
- const extra = {};
1088
- const colors2 = {};
1089
- const labels = {};
1090
- if (1 === trials.length) {
1091
- for (const [trial, bench2] of trials) {
1092
- const runs = bench2.runs.filter((r) => r.stats);
1093
- if (!runs.length) continue;
1094
- if (1 === runs.length) {
1095
- const { min, max, avg, peak, bins } = $2.histogram.bins(runs[0].stats, 44, 0.99);
1096
- extra.ymax = peak;
1097
- colors2.xmin = $2.cyan;
1098
- colors2.xmax = $2.magenta;
1099
- extra.ymin = $2.min(bins);
1100
- labels.xmin = $2.time(min);
1101
- labels.xmax = $2.time(max);
1102
- extra.xmax = bins.length - 1;
1103
- colors2[runs[0].name] = $2[trial._highlight] || $2.bold;
1104
- map[runs[0].name] = {
1105
- y: bins,
1106
- x: bins.map((_, o) => o),
1107
- format(x, y, s) {
1108
- x = Math.round(x * 44);
1109
- if (!opts.colors) return s;
1110
- if (x === avg) return $2.yellow + s + $2.reset;
1111
- return (x < avg ? $2.cyan : $2.magenta) + s + $2.reset;
1112
- }
1113
- };
1114
- } else {
1115
- const avgs = runs.map((r) => r.stats.avg);
1116
- colors2.ymin = $2.cyan;
1117
- colors2.ymax = $2.magenta;
1118
- extra.ymin = $2.min(avgs);
1119
- extra.ymax = $2.max(avgs);
1120
- extra.xmax = runs.length - 1;
1121
- labels.ymin = $2.time(extra.ymin);
1122
- labels.ymax = $2.time(extra.ymax);
1123
- colors2[bench2.alias] = $2[trial._highlight];
1124
- map[bench2.alias] = {
1125
- y: avgs,
1126
- x: avgs.map((_, o) => o)
1127
- };
1128
- }
1129
- }
1130
- } else {
1131
- if (trials.every(([_, bench2]) => "static" === bench2.kind)) {
1132
- colors2.xmin = $2.cyan;
1133
- colors2.xmax = $2.magenta;
1134
- for (const [trial, bench2] of trials) {
1135
- for (const r of bench2.runs) {
1136
- if (r.error) continue;
1137
- const { bins, peak, steps } = $2.histogram.bins(r.stats, 44, 0.99);
1138
- const y = bins.map((b) => b / peak);
1139
- map[r.name] = { y, x: steps };
1140
- colors2[r.name] = $2[trial._highlight];
1141
- extra.ymin = Math.min($2.min(y), extra.ymin ?? Infinity);
1142
- extra.ymax = Math.max($2.max(y), extra.ymax ?? -Infinity);
1143
- extra.xmin = Math.min($2.min(steps), extra.xmin ?? Infinity);
1144
- extra.xmax = Math.max($2.max(steps), extra.xmax ?? -Infinity);
1145
- labels.xmin = $2.time(extra.xmin);
1146
- labels.xmax = $2.time(extra.xmax);
1147
- }
1148
- }
1149
- } else {
1150
- let min = Infinity;
1151
- let max = -Infinity;
1152
- for (const [trial, bench2] of trials) {
1153
- for (const r of bench2.runs) {
1154
- if (r.error) continue;
1155
- min = Math.min(min, r.stats.avg);
1156
- max = Math.max(max, r.stats.avg);
1157
- }
1158
- }
1159
- colors2.ymin = $2.cyan;
1160
- colors2.ymax = $2.magenta;
1161
- labels.ymin = $2.time(min);
1162
- labels.ymax = $2.time(max);
1163
- for (const [trial, bench2] of trials) {
1164
- const runs = bench2.runs.filter((r) => r.stats);
1165
- if (!runs.length) continue;
1166
- if (1 === runs.length) {
1167
- const y = runs[0].stats.avg / max;
1168
- colors2[runs[0].name] = $2[trial._highlight];
1169
- map[runs[0].name] = { x: [0, 1], y: [y, y] };
1170
- extra.ymin = Math.min(y, extra.ymin ?? Infinity);
1171
- extra.ymax = Math.max(y, extra.ymax ?? -Infinity);
1172
- } else {
1173
- colors2[bench2.alias] = $2[trial._highlight];
1174
- const y = runs.map((r) => r.stats.avg / max);
1175
- extra.ymin = Math.min($2.min(y), extra.ymin ?? Infinity);
1176
- extra.ymax = Math.max($2.max(y), extra.ymax ?? -Infinity);
1177
- map[bench2.alias] = { y, x: runs.map((_, o) => o / (runs.length - 1)) };
1178
- }
1179
- }
1180
- }
1181
- }
1182
- if (Object.keys(map).length) {
1183
- print2("");
1184
- $2.lineplot.ascii(map, {
1185
- labels,
1186
- ...extra,
1187
- width: 44,
1188
- height: 16,
1189
- key: k_legend,
1190
- colors: !opts.colors ? null : colors2
1191
- }).forEach((l) => print2(l));
1192
- }
1193
- }
1194
- if (collection.types.includes("s")) {
1195
- trials.sort((a, b) => {
1196
- const aa = a[1].runs.filter((r) => r.stats);
1197
- const bb = b[1].runs.filter((r) => r.stats);
1198
- if (0 === aa.length) return 1;
1199
- if (0 === bb.length) return -1;
1200
- const a_avg = aa.reduce((a2, r) => a2 + r.stats.avg, 0) / aa.length;
1201
- const b_avg = bb.reduce((a2, r) => a2 + r.stats.avg, 0) / bb.length;
1202
- return a_avg - b_avg;
1203
- });
1204
- if (1 === trials.length) {
1205
- const runs = trials[0][1].runs.filter((r) => r.stats).sort((a, b) => a.stats.avg - b.stats.avg);
1206
- if (1 < runs.length) {
1207
- print2("");
1208
- if (!opts.colors) print2("summary");
1209
- else print2($2.bold + "summary" + $2.reset);
1210
- if (!opts.colors) print2(" " + runs[0].name);
1211
- else print2(" ".repeat(2) + $2.bold + $2.cyan + runs[0].name + $2.reset);
1212
- for (let o = 1; o < runs.length; o++) {
1213
- const r = runs[o];
1214
- const baseline = runs[0];
1215
- const faster = r.stats.avg >= baseline.stats.avg;
1216
- const diff = !faster ? Number((1 / r.stats.avg * baseline.stats.avg).toFixed(2)) : Number((1 / baseline.stats.avg * r.stats.avg).toFixed(2));
1217
- if (!opts.colors) print2(" ".repeat(3) + diff + `x ${faster ? "faster" : "slower"} than ${r.name}`);
1218
- else print2(" ".repeat(3) + (!faster ? $2.red : $2.green) + diff + $2.reset + `x ${faster ? "faster" : "slower"} than ${$2.bold + $2.cyan + r.name + $2.reset}`);
1219
- }
1220
- }
1221
- } else {
1222
- let header = false;
1223
- const baseline = trials.find(([trial, bench2]) => bench2.baseline && bench2.runs.some((r) => r.stats))?.[1] || trials[0][1];
1224
- if (baseline) {
1225
- const bruns = baseline.runs.filter((r) => !r.error).sort((a, b) => a.stats.avg - b.stats.avg);
1226
- for (const [trial, bench2] of trials) {
1227
- if (bench2 === baseline) continue;
1228
- const runs = bench2.runs.filter((r) => !r.error).sort((a, b) => a.stats.avg - b.stats.avg);
1229
- if (!runs.length) continue;
1230
- if (!header) {
1231
- print2("");
1232
- header = true;
1233
- if (!opts.colors) print2("summary");
1234
- else print2($2.bold + "summary" + $2.reset);
1235
- if (1 !== bruns.length) {
1236
- if (!opts.colors) print2(" " + baseline.alias);
1237
- else print2(" ".repeat(2) + $2.bold + $2.cyan + baseline.alias + $2.reset);
1238
- } else {
1239
- if (!opts.colors) print2(" " + bruns[0].name);
1240
- else print2(" ".repeat(2) + $2.bold + $2.cyan + bruns[0].name + $2.reset);
1241
- }
1242
- }
1243
- if (1 === runs.length && 1 === bruns.length) {
1244
- const r = runs[0];
1245
- const br = bruns[0];
1246
- const faster = r.stats.avg >= br.stats.avg;
1247
- const diff = !faster ? Number((1 / r.stats.avg * br.stats.avg).toFixed(2)) : Number((1 / br.stats.avg * r.stats.avg).toFixed(2));
1248
- if (!opts.colors) print2(" ".repeat(3) + diff + `x ${faster ? "faster" : "slower"} than ${r.name}`);
1249
- else print2(" ".repeat(3) + (!faster ? $2.red : $2.green) + diff + $2.reset + `x ${faster ? "faster" : "slower"} than ${$2.bold + $2.cyan + r.name + $2.reset}`);
1250
- } else {
1251
- const rf = runs[0];
1252
- const bf = bruns[0];
1253
- const rs = runs[runs.length - 1];
1254
- const bs = bruns[bruns.length - 1];
1255
- const ravg = runs.reduce((a, r) => a + r.stats.avg, 0) / runs.length;
1256
- const bavg = bruns.reduce((a, r) => a + r.stats.avg, 0) / bruns.length;
1257
- const faster = ravg >= bavg;
1258
- const sfaster = rs.stats.avg >= bs.stats.avg;
1259
- const ffaster = rf.stats.avg >= bf.stats.avg;
1260
- const sdiff = !sfaster ? Number((1 / rs.stats.avg * bs.stats.avg).toFixed(2)) : Number((1 / bs.stats.avg * rs.stats.avg).toFixed(2));
1261
- const fdiff = !ffaster ? Number((1 / rf.stats.avg * bf.stats.avg).toFixed(2)) : Number((1 / bf.stats.avg * rf.stats.avg).toFixed(2));
1262
- if (!opts.colors) print2(
1263
- " ".repeat(3) + (1 === sdiff ? sdiff : (sfaster ? "+" : "-") + sdiff) + "\u2026" + (1 === fdiff ? fdiff : (ffaster ? "+" : "-") + fdiff) + `x ${faster ? "faster" : "slower"} than ${1 === runs.length ? rf.name : bench2.alias}`
1264
- );
1265
- else print2(
1266
- " ".repeat(3) + (1 === sdiff ? $2.gray + sdiff + $2.reset : !sfaster ? $2.red + "-" + sdiff + $2.reset : $2.green + "+" + sdiff + $2.reset) + "\u2026" + (1 === fdiff ? $2.gray + fdiff + $2.reset : !ffaster ? $2.red + "-" + fdiff + $2.reset : $2.green + "+" + fdiff + $2.reset) + `x ${faster ? "faster" : "slower"} than ${$2.bold + $2.cyan + (1 === runs.length ? rf.name : bench2.alias) + $2.reset}`
1267
- );
1268
- }
1269
- }
1270
- }
1271
- }
1272
- }
1273
- }
1274
- let nl = false;
1275
- if (false === $counters)
1276
- if (!opts.colors) print2(""), nl = true, print2("! = run with sudo to enable hardware counters");
1277
- else print2(""), nl = true, print2($2.yellow + "!" + $2.reset + $2.gray + " = " + $2.reset + "run with sudo to enable hardware counters");
1278
- if (optimized_out_warning)
1279
- if (!opts.colors) nl ? null : print2(""), print2(" ".repeat(k_legend - 13) + "benchmark was likely optimized out (dead code elimination) = !"), print2(" ".repeat(k_legend - 13) + "https://github.com/evanwashere/mitata#writing-good-benchmarks");
1280
- else nl ? null : print2(""), print2(" ".repeat(k_legend - 13) + "benchmark was likely optimized out " + $2.gray + "(dead code elimination)" + $2.reset + $2.gray + " = " + $2.reset + $2.red + "!" + $2.reset), print2(" ".repeat(k_legend - 13) + $2.gray + "https://github.com/evanwashere/mitata#writing-good-benchmarks" + $2.reset);
1281
- }
1282
- };
1283
- var $2 = {
1284
- bold: "\x1B[1m",
1285
- reset: "\x1B[0m",
1286
- red: "\x1B[31m",
1287
- cyan: "\x1B[36m",
1288
- blue: "\x1B[34m",
1289
- gray: "\x1B[90m",
1290
- white: "\x1B[37m",
1291
- black: "\x1B[30m",
1292
- green: "\x1B[32m",
1293
- yellow: "\x1B[33m",
1294
- magenta: "\x1B[35m",
1295
- colors: ["red", "cyan", "blue", "green", "yellow", "magenta", "gray", "white", "black"],
1296
- clamp(m, v, x) {
1297
- return v < m ? m : v > x ? x : v;
1298
- },
1299
- min(arr, s = Infinity) {
1300
- return arr.reduce((x, v) => Math.min(x, v), s);
1301
- },
1302
- max(arr, s = -Infinity) {
1303
- return arr.reduce((x, v) => Math.max(x, v), s);
1304
- },
1305
- str(s, len = 3) {
1306
- if (len >= s.length) return s;
1307
- return `${s.slice(0, len - 2)}..`;
1308
- },
1309
- amount(n) {
1310
- if (Number.isNaN(n)) return "NaN";
1311
- if (n < 1e3) return n.toFixed(2);
1312
- n /= 1e3;
1313
- if (n < 1e3) return `${n.toFixed(2)}k`;
1314
- n /= 1e3;
1315
- if (n < 1e3) return `${n.toFixed(2)}M`;
1316
- n /= 1e3;
1317
- if (n < 1e3) return `${n.toFixed(2)}G`;
1318
- n /= 1e3;
1319
- if (n < 1e3) return `${n.toFixed(2)}T`;
1320
- n /= 1e3;
1321
- return `${n.toFixed(2)}P`;
1322
- },
1323
- bytes(b, pad = true) {
1324
- if (Number.isNaN(b)) return "NaN";
1325
- if (b < 1e3) return `${b.toFixed(2)} ${!pad ? "" : " "}b`;
1326
- b /= 1024;
1327
- if (b < 1e3) return `${b.toFixed(2)} kb`;
1328
- b /= 1024;
1329
- if (b < 1e3) return `${b.toFixed(2)} mb`;
1330
- b /= 1024;
1331
- if (b < 1e3) return `${b.toFixed(2)} gb`;
1332
- b /= 1024;
1333
- if (b < 1e3) return `${b.toFixed(2)} tb`;
1334
- b /= 1024;
1335
- return `${b.toFixed(2)} pb`;
1336
- },
1337
- time(ns) {
1338
- if (ns < 1) return `${(ns * 1e3).toFixed(2)} ps`;
1339
- if (ns < 1e3) return `${ns.toFixed(2)} ns`;
1340
- ns /= 1e3;
1341
- if (ns < 1e3) return `${ns.toFixed(2)} \xB5s`;
1342
- ns /= 1e3;
1343
- if (ns < 1e3) return `${ns.toFixed(2)} ms`;
1344
- ns /= 1e3;
1345
- if (ns < 1e3) return `${ns.toFixed(2)} s`;
1346
- ns /= 60;
1347
- if (ns < 1e3) return `${ns.toFixed(2)} m`;
1348
- ns /= 60;
1349
- return `${ns.toFixed(2)} h`;
1350
- },
1351
- barplot: {
1352
- symbols: {
1353
- bar: "\u25A0",
1354
- legend: "\u2524",
1355
- tl: "\u250C",
1356
- tr: "\u2510",
1357
- bl: "\u2514",
1358
- br: "\u2518"
1359
- },
1360
- ascii(map, key = 8, size = 14, { steps = 0, fmt = $2.time, colors: colors2 = true, symbols = $2.barplot.symbols } = {}) {
1361
- const values = Object.values(map);
1362
- const canvas = new Array(2 + values.length).fill("");
1363
- steps += size;
1364
- const min = $2.min(values);
1365
- const max = $2.max(values);
1366
- const step = (max - min) / steps;
1367
- canvas[0] += " ".repeat(1 + key);
1368
- canvas[0] += symbols.tl + " ".repeat(size) + symbols.tr;
1369
- Object.keys(map).forEach((name, o) => {
1370
- const value = map[name];
1371
- const bars = Math.round((value - min) / step);
1372
- if (colors2?.[name]) canvas[o + 1] += colors2[name];
1373
- canvas[o + 1] += $2.str(name, key).padStart(key);
1374
- if (colors2?.[name]) canvas[o + 1] += $2.reset;
1375
- canvas[o + 1] += " " + symbols.legend;
1376
- if (colors2) canvas[o + 1] += $2.gray;
1377
- canvas[o + 1] += symbols.bar.repeat(bars);
1378
- if (colors2) canvas[o + 1] += $2.reset;
1379
- canvas[o + 1] += " ";
1380
- if (colors2) canvas[o + 1] += $2.yellow;
1381
- canvas[o + 1] += fmt(value);
1382
- if (colors2) canvas[o + 1] += $2.reset;
1383
- });
1384
- canvas[canvas.length - 1] += " ".repeat(1 + key);
1385
- canvas[canvas.length - 1] += symbols.bl + " ".repeat(size) + symbols.br;
1386
- return canvas;
1387
- }
1388
- },
1389
- canvas: {
1390
- braille(width, height) {
1391
- const vwidth = 2 * width;
1392
- const vheight = 4 * height;
1393
- const buffer = new Uint8Array(vwidth * vheight);
1394
- const symbols = [
1395
- 10241,
1396
- 10242,
1397
- 10244,
1398
- 10304,
1399
- 10248,
1400
- 10256,
1401
- 10272,
1402
- 10368
1403
- ];
1404
- return {
1405
- buffer,
1406
- width,
1407
- height,
1408
- vwidth,
1409
- vheight,
1410
- set(x, y, tag = 1) {
1411
- buffer[x + y * vwidth] = tag;
1412
- },
1413
- line(s, e, tag = 1) {
1414
- s.x = Math.round(s.x);
1415
- s.y = Math.round(s.y);
1416
- e.x = Math.round(e.x);
1417
- e.y = Math.round(e.y);
1418
- const dx = Math.abs(e.x - s.x);
1419
- const dy = Math.abs(e.y - s.y);
1420
- let err = dx - dy;
1421
- let x = s.x;
1422
- let y = s.y;
1423
- const sx = s.x < e.x ? 1 : -1;
1424
- const sy = s.y < e.y ? 1 : -1;
1425
- while (true) {
1426
- buffer[x + y * vwidth] = tag;
1427
- if (x === e.x && y === e.y) break;
1428
- const e2 = 2 * err;
1429
- if (e2 < dx) y += sy, err += dx;
1430
- if (e2 > -dy) x += sx, err -= dy;
1431
- }
1432
- },
1433
- toString({
1434
- background = false,
1435
- format = (x, y, s, tag, backgorund) => s
1436
- } = {}) {
1437
- const canvas = new Array(height).fill("");
1438
- for (let y = 0; y < vheight; y += 4) {
1439
- const y0 = y * vwidth;
1440
- const y1 = y0 + vwidth;
1441
- const y2 = y1 + vwidth;
1442
- const y3 = y2 + vwidth;
1443
- for (let x = 0; x < vwidth; x += 2) {
1444
- let c = 10240;
1445
- if (buffer[x + y0]) c |= symbols[0];
1446
- if (buffer[1 + x + y0]) c |= symbols[4];
1447
- if (buffer[x + y1]) c |= symbols[1];
1448
- if (buffer[1 + x + y1]) c |= symbols[5];
1449
- if (buffer[x + y2]) c |= symbols[2];
1450
- if (buffer[1 + x + y2]) c |= symbols[6];
1451
- if (buffer[x + y3]) c |= symbols[3];
1452
- if (buffer[1 + x + y3]) c |= symbols[7];
1453
- if (c === 10240 && !background) canvas[y / 4] += " ";
1454
- else canvas[y / 4] += format(x / (vwidth - 1), y / (vheight - 1), String.fromCharCode(c), buffer[x + y0] || buffer[1 + x + y0] || buffer[x + y1] || buffer[1 + x + y1] || buffer[x + y2] || buffer[1 + x + y2] || buffer[x + y3] || buffer[1 + x + y3], c === 10240);
1455
- }
1456
- }
1457
- return canvas;
1458
- }
1459
- };
1460
- }
1461
- },
1462
- lineplot: {
1463
- symbols: {
1464
- tl: "\u250C",
1465
- tr: "\u2510",
1466
- bl: "\u2514",
1467
- br: "\u2518"
1468
- },
1469
- ascii(map, {
1470
- colors: colors2 = true,
1471
- xmin = 0,
1472
- xmax = 1,
1473
- ymin = 0,
1474
- ymax = 1,
1475
- symbols = $2.lineplot.symbols,
1476
- key = 8,
1477
- width = 12,
1478
- height = 12,
1479
- labels = { xmin: null, xmax: null, ymin: null, ymax: null }
1480
- } = {}) {
1481
- const keys = Object.keys(map);
1482
- const _canvas = $2.canvas.braille(width, height);
1483
- const xs = (_canvas.vwidth - 1) / (xmax - xmin);
1484
- const ys = (_canvas.vheight - 1) / (ymax - ymin);
1485
- const colorsv = Object.entries(colors2).filter(([n]) => !Object.keys(labels).includes(n)).map(([_, v]) => v);
1486
- const acolors = $2.colors.filter((n) => !colorsv.includes($2[n]));
1487
- keys.forEach((name, k) => {
1488
- const { x: xp, y: yp } = map[name];
1489
- for (let o = 0; o < xp.length - 1; o++) {
1490
- if (null == xp[o] || null == xp[o + 1]) continue;
1491
- if (null == yp[o] || null == yp[o + 1]) continue;
1492
- const s = { x: Math.round(xs * (xp[o] - xmin)), y: _canvas.vheight - 1 - Math.round(ys * (yp[o] - ymin)) };
1493
- const e = { x: Math.round(xs * (xp[o + 1] - xmin)), y: _canvas.vheight - 1 - Math.round(ys * (yp[o + 1] - ymin)) };
1494
- _canvas.line(s, e, 1 + k);
1495
- }
1496
- });
1497
- const canvas = new Array(2 + _canvas.height).fill("");
1498
- canvas[0] += " ".repeat(1 + key);
1499
- canvas[0] += symbols.tl + " ".repeat(width) + symbols.tr;
1500
- const lines = _canvas.toString({
1501
- format(x, y, s, tag) {
1502
- const name = keys[tag - 1];
1503
- if (map[name].format) return map[name].format(x, y, s);
1504
- else if (colors2?.[name]) return colors2[name] + s + $2.reset;
1505
- else return $2[acolors[(tag - 1) % acolors.length]] + s + $2.reset;
1506
- }
1507
- });
1508
- const plabels = {
1509
- 0: !colors2?.ymax ? labels.ymax || "" : colors2.ymax + (labels.ymax || "") + $2.reset,
1510
- [lines.length - 1]: !colors2?.ymin ? labels.ymin || "" : colors2.ymin + (labels.ymin || "") + $2.reset
1511
- };
1512
- const legends = keys.map((name, k) => {
1513
- if (colors2?.[name]) return colors2[name] + $2.str(name, key).padStart(key) + $2.reset;
1514
- else return $2[acolors[k % acolors.length]] + $2.str(name, key).padStart(key) + $2.reset;
1515
- });
1516
- lines.forEach((l, o) => {
1517
- canvas[o + 1] += legends[o] ?? " ".repeat(key);
1518
- canvas[o + 1] += " ".repeat(2) + l + (!plabels[o] ? "" : " " + plabels[o]);
1519
- });
1520
- canvas[canvas.length - 1] += " ".repeat(1 + key);
1521
- canvas[canvas.length - 1] += symbols.bl + " ".repeat(width) + symbols.br;
1522
- if (labels.xmin || labels.xmax) {
1523
- const xmin2 = labels.xmin || "";
1524
- const xmax2 = labels.xmax || "";
1525
- const gap = 2 + width - xmin2.length;
1526
- canvas.push(
1527
- " ".repeat(key) + " " + (!colors2?.xmin ? xmin2 : colors2.xmin + xmin2 + $2.reset) + (!colors2?.xmax ? xmax2.padStart(gap) : colors2.xmax + xmax2.padStart(gap) + $2.reset)
1528
- );
1529
- }
1530
- return canvas;
1531
- }
1532
- },
1533
- histogram: {
1534
- symbols: ["\u2581", "\u2582", "\u2583", "\u2584", "\u2585", "\u2586", "\u2587", "\u2588"],
1535
- bins(stats, size = 6, percentile = 1) {
1536
- const offset = percentile * (stats.samples.length - 1) | 0;
1537
- let min = stats.min;
1538
- const max = stats.samples[offset] || stats.max || 1;
1539
- const steps = new Array(size);
1540
- const bins = new Array(size).fill(0);
1541
- const step = (max - min) / (size - 1);
1542
- if (0 === step) {
1543
- min = 0;
1544
- for (let o = 0; o < size; o++) steps[o] = o * step;
1545
- bins[$2.clamp(0, Math.round((stats.avg - min) / step), size - 1)] = 1;
1546
- } else {
1547
- for (let o = 0; o < size; o++) steps[o] = min + o * step;
1548
- for (let o = 0; o <= offset; o++) bins[Math.round((stats.samples[o] - min) / step)]++;
1549
- }
1550
- return {
1551
- min,
1552
- max,
1553
- step,
1554
- bins,
1555
- steps,
1556
- peak: $2.max(bins),
1557
- outliers: stats.samples.length - 1 - offset,
1558
- avg: $2.clamp(0, Math.round((stats.avg - min) / step), size - 1)
1559
- };
1560
- },
1561
- ascii(_bins, height = 1, { colors: colors2 = true, symbols = $2.histogram.symbols } = {}) {
1562
- const canvas = new Array(height);
1563
- const { avg, peak, bins } = _bins;
1564
- const scale = (height * symbols.length - 1) / peak;
1565
- for (let y = 0; y < height; y++) {
1566
- let l = "";
1567
- if (0 !== avg) {
1568
- if (colors2) l += $2.cyan;
1569
- for (let o = 0; o < avg; o++) {
1570
- const b = bins[o];
1571
- if (y === 0) l += symbols[$2.clamp(0, Math.round(b * scale), symbols.length - 1)];
1572
- else {
1573
- const min = y * symbols.length;
1574
- const max = (y + 1) * symbols.length;
1575
- const offset = Math.round(b * scale) | 0;
1576
- if (min >= offset) l += " ";
1577
- else if (max <= offset) l += symbols[symbols.length - 1];
1578
- else l += symbols[$2.clamp(min, offset, max) % symbols.length];
1579
- }
1580
- }
1581
- if (colors2) l += $2.reset;
1582
- }
1583
- {
1584
- if (colors2) l += $2.yellow;
1585
- const b = bins[avg];
1586
- if (y === 0) l += symbols[$2.clamp(0, Math.round(b * scale), symbols.length - 1)];
1587
- else {
1588
- const min = y * symbols.length;
1589
- const max = (y + 1) * symbols.length;
1590
- const offset = Math.round(b * scale) | 0;
1591
- if (min >= offset) l += " ";
1592
- else if (max <= offset) l += symbols[symbols.length - 1];
1593
- else l += symbols[$2.clamp(min, offset, max) % symbols.length];
1594
- }
1595
- if (colors2) l += $2.reset;
1596
- }
1597
- if (avg != bins.length - 1) {
1598
- if (colors2) l += $2.magenta;
1599
- for (let o = 1 + avg; o < bins.length; o++) {
1600
- const b = bins[o];
1601
- if (y === 0) l += symbols[$2.clamp(0, Math.round(b * scale), symbols.length - 1)];
1602
- else {
1603
- const min = y * symbols.length;
1604
- const max = (y + 1) * symbols.length;
1605
- const offset = Math.round(b * scale) | 0;
1606
- if (min >= offset) l += " ";
1607
- else if (max <= offset) l += symbols[symbols.length - 1];
1608
- else l += symbols[$2.clamp(min, offset, max) % symbols.length];
1609
- }
1610
- }
1611
- if (colors2) l += $2.reset;
1612
- }
1613
- canvas[y] = l;
1614
- }
1615
- return canvas.reverse();
1616
- }
1617
- },
1618
- boxplot: {
1619
- symbols: {
1620
- v: "\u2502",
1621
- h: "\u2500",
1622
- tl: "\u250C",
1623
- tr: "\u2510",
1624
- bl: "\u2514",
1625
- br: "\u2518",
1626
- avg: {
1627
- top: "\u252C",
1628
- middle: "\u2502",
1629
- bottom: "\u2534"
1630
- },
1631
- tail: {
1632
- top: "\u2577",
1633
- bottom: "\u2575",
1634
- middle: ["\u251C", "\u2524"]
1635
- }
1636
- },
1637
- ascii(map, key = 8, size = 14, { fmt = $2.time, colors: colors2 = true, symbols = $2.boxplot.symbols } = {}) {
1638
- let tmin = Infinity;
1639
- let tmax = -Infinity;
1640
- const keys = Object.keys(map);
1641
- const canvas = new Array(3 + 3 * keys.length).fill("");
1642
- for (const name of keys) {
1643
- const stats = map[name];
1644
- if (tmin > stats.min) tmin = stats.min;
1645
- const max = stats.p99 || stats.max || 1;
1646
- if (max > tmax) tmax = max;
1647
- }
1648
- const steps = 2 + size;
1649
- const step = (tmax - tmin) / (steps - 1);
1650
- canvas[0] += " ".repeat(1 + key);
1651
- canvas[0] += symbols.tl + " ".repeat(size) + symbols.tr;
1652
- keys.forEach((name, o) => {
1653
- o *= 3;
1654
- const stats = map[name];
1655
- const min = stats.min;
1656
- const avg = stats.avg;
1657
- const p25 = stats.p25;
1658
- const p75 = stats.p75;
1659
- const max = stats.p99 || stats.max || 1;
1660
- const min_offset = 1 + Math.min(steps - 1, Math.round((min - tmin) / step));
1661
- const max_offset = 1 + Math.min(steps - 1, Math.round((max - tmin) / step));
1662
- const avg_offset = 1 + Math.min(steps - 1, Math.round((avg - tmin) / step));
1663
- const p25_offset = 1 + Math.min(steps - 1, Math.round((p25 - tmin) / step));
1664
- const p75_offset = 1 + Math.min(steps - 1, Math.round((p75 - tmin) / step));
1665
- const u = new Array(2 + steps).fill(" ");
1666
- const m = new Array(2 + steps).fill(" ");
1667
- const l = new Array(2 + steps).fill(" ");
1668
- u[0] = !colors2 ? "" : $2.cyan;
1669
- m[0] = !colors2 ? "" : $2.cyan;
1670
- l[0] = !colors2 ? "" : $2.cyan;
1671
- if (min_offset < p25_offset) {
1672
- u[min_offset] = symbols.tail.top;
1673
- l[min_offset] = symbols.tail.bottom;
1674
- m[min_offset] = symbols.tail.middle[0];
1675
- for (let o2 = 1 + min_offset; o2 < p25_offset; o2++) m[o2] = symbols.h;
1676
- }
1677
- if (avg_offset > p25_offset) {
1678
- u[p25_offset] = symbols.tl;
1679
- l[p25_offset] = symbols.bl;
1680
- m[p25_offset] = min_offset === p25_offset ? symbols.v : symbols.tail.middle[1];
1681
- for (let o2 = 1 + p25_offset; o2 < avg_offset; o2++) u[o2] = l[o2] = symbols.h;
1682
- }
1683
- u[avg_offset] = !colors2 ? symbols.avg.top : $2.reset + $2.yellow + symbols.avg.top + $2.reset + $2.magenta;
1684
- l[avg_offset] = !colors2 ? symbols.avg.bottom : $2.reset + $2.yellow + symbols.avg.bottom + $2.reset + $2.magenta;
1685
- m[avg_offset] = !colors2 ? symbols.avg.middle : $2.reset + $2.yellow + symbols.avg.middle + $2.reset + $2.magenta;
1686
- if (avg_offset < p75_offset) {
1687
- u[p75_offset] = symbols.tr;
1688
- l[p75_offset] = symbols.br;
1689
- m[p75_offset] = max_offset === p75_offset ? symbols.v : symbols.tail.middle[0];
1690
- for (let o2 = 1 + avg_offset; o2 < p75_offset; o2++) u[o2] = l[o2] = symbols.h;
1691
- }
1692
- if (max_offset > p75_offset) {
1693
- u[max_offset] = symbols.tail.top;
1694
- l[max_offset] = symbols.tail.bottom;
1695
- m[max_offset] = symbols.tail.middle[1];
1696
- for (let o2 = 1 + Math.max(avg_offset, p75_offset); o2 < max_offset; o2++) m[o2] = symbols.h;
1697
- }
1698
- canvas[o + 1] = " ".repeat(1 + key) + u.join("").trimEnd() + (!colors2 ? "" : $2.reset);
1699
- if (colors2?.[name]) canvas[o + 2] += colors2[name];
1700
- canvas[o + 2] += $2.str(name, key).padStart(key);
1701
- if (colors2?.[name]) canvas[o + 2] += $2.reset;
1702
- canvas[o + 2] += " " + m.join("").trimEnd() + (!colors2 ? "" : $2.reset);
1703
- canvas[o + 3] = " ".repeat(1 + key) + l.join("").trimEnd() + (!colors2 ? "" : $2.reset);
1704
- });
1705
- canvas[canvas.length - 2] += " ".repeat(1 + key);
1706
- canvas[canvas.length - 2] += symbols.bl + " ".repeat(size) + symbols.br;
1707
- const rmin = fmt(tmin);
1708
- const rmax = fmt(tmax);
1709
- const rmid = fmt((tmin + tmax) / 2);
1710
- const gap = (size - rmin.length - rmid.length - rmax.length) / 2;
1711
- canvas[canvas.length - 1] += " ".repeat(1 + key);
1712
- canvas[canvas.length - 1] += !colors2 ? rmin : $2.cyan + rmin + $2.reset;
1713
- canvas[canvas.length - 1] += " ".repeat(1 + gap | 0);
1714
- canvas[canvas.length - 1] += !colors2 ? rmid : $2.gray + rmid + $2.reset;
1715
- canvas[canvas.length - 1] += " ".repeat(1 + Math.ceil(gap));
1716
- canvas[canvas.length - 1] += !colors2 ? rmax : $2.magenta + rmax + $2.reset;
1717
- return canvas;
1718
- }
1719
- }
1720
- };
1721
-
1722
- // ../../node_modules/.pnpm/txml@5.1.1/node_modules/txml/dist/txml.mjs
1723
- function parse(S, options) {
1724
- "txml";
1725
- options = options || {};
1726
- var pos = options.pos || 0;
1727
- var keepComments = !!options.keepComments;
1728
- var keepWhitespace = !!options.keepWhitespace;
1729
- var openBracket = "<";
1730
- var openBracketCC = "<".charCodeAt(0);
1731
- var closeBracket = ">";
1732
- var closeBracketCC = ">".charCodeAt(0);
1733
- var minusCC = "-".charCodeAt(0);
1734
- var slashCC = "/".charCodeAt(0);
1735
- var exclamationCC = "!".charCodeAt(0);
1736
- var singleQuoteCC = "'".charCodeAt(0);
1737
- var doubleQuoteCC = '"'.charCodeAt(0);
1738
- var openCornerBracketCC = "[".charCodeAt(0);
1739
- var closeCornerBracketCC = "]".charCodeAt(0);
1740
- function parseChildren(tagName) {
1741
- var children = [];
1742
- while (S[pos]) {
1743
- if (S.charCodeAt(pos) == openBracketCC) {
1744
- if (S.charCodeAt(pos + 1) === slashCC) {
1745
- var closeStart = pos + 2;
1746
- pos = S.indexOf(closeBracket, pos);
1747
- var closeTag = S.substring(closeStart, pos);
1748
- if (closeTag.indexOf(tagName) == -1) {
1749
- var parsedText = S.substring(0, pos).split("\n");
1750
- throw new Error(
1751
- "Unexpected close tag\nLine: " + (parsedText.length - 1) + "\nColumn: " + (parsedText[parsedText.length - 1].length + 1) + "\nChar: " + S[pos]
1752
- );
1753
- }
1754
- if (pos + 1) pos += 1;
1755
- return children;
1756
- } else if (S.charCodeAt(pos + 1) === exclamationCC) {
1757
- if (S.charCodeAt(pos + 2) == minusCC) {
1758
- const startCommentPos = pos;
1759
- while (pos !== -1 && !(S.charCodeAt(pos) === closeBracketCC && S.charCodeAt(pos - 1) == minusCC && S.charCodeAt(pos - 2) == minusCC && pos != -1)) {
1760
- pos = S.indexOf(closeBracket, pos + 1);
1761
- }
1762
- if (pos === -1) {
1763
- pos = S.length;
1764
- }
1765
- if (keepComments) {
1766
- children.push(S.substring(startCommentPos, pos + 1));
1767
- }
1768
- } else if (S.charCodeAt(pos + 2) === openCornerBracketCC && S.charCodeAt(pos + 8) === openCornerBracketCC && S.substr(pos + 3, 5).toLowerCase() === "cdata") {
1769
- var cdataEndIndex = S.indexOf("]]>", pos);
1770
- if (cdataEndIndex == -1) {
1771
- children.push(S.substr(pos + 9));
1772
- pos = S.length;
1773
- } else {
1774
- children.push(S.substring(pos + 9, cdataEndIndex));
1775
- pos = cdataEndIndex + 3;
1776
- }
1777
- continue;
1778
- } else {
1779
- const startDoctype = pos + 1;
1780
- pos += 2;
1781
- var encapsuled = false;
1782
- while ((S.charCodeAt(pos) !== closeBracketCC || encapsuled === true) && S[pos]) {
1783
- if (S.charCodeAt(pos) === openCornerBracketCC) {
1784
- encapsuled = true;
1785
- } else if (encapsuled === true && S.charCodeAt(pos) === closeCornerBracketCC) {
1786
- encapsuled = false;
1787
- }
1788
- pos++;
1789
- }
1790
- children.push(S.substring(startDoctype, pos));
1791
- }
1792
- pos++;
1793
- continue;
1794
- }
1795
- var node = parseNode();
1796
- children.push(node);
1797
- if (node.tagName[0] === "?") {
1798
- children.push(...node.children);
1799
- node.children = [];
1800
- }
1801
- } else {
1802
- var text = parseText();
1803
- if (keepWhitespace) {
1804
- if (text.length > 0) {
1805
- children.push(text);
1806
- }
1807
- } else {
1808
- var trimmed = text.trim();
1809
- if (trimmed.length > 0) {
1810
- children.push(trimmed);
1811
- }
1812
- }
1813
- pos++;
1814
- }
1815
- }
1816
- return children;
1817
- }
1818
- function parseText() {
1819
- var start = pos;
1820
- pos = S.indexOf(openBracket, pos) - 1;
1821
- if (pos === -2)
1822
- pos = S.length;
1823
- return S.slice(start, pos + 1);
1824
- }
1825
- var nameSpacer = "\r\n >/= ";
1826
- function parseName() {
1827
- var start = pos;
1828
- while (nameSpacer.indexOf(S[pos]) === -1 && S[pos]) {
1829
- pos++;
1830
- }
1831
- return S.slice(start, pos);
1832
- }
1833
- var NoChildNodes = options.noChildNodes || ["img", "br", "input", "meta", "link", "hr"];
1834
- function parseNode() {
1835
- pos++;
1836
- const tagName = parseName();
1837
- const attributes = {};
1838
- let children = [];
1839
- while (S.charCodeAt(pos) !== closeBracketCC && S[pos]) {
1840
- var c = S.charCodeAt(pos);
1841
- if (c > 64 && c < 91 || c > 96 && c < 123) {
1842
- var name = parseName();
1843
- var code = S.charCodeAt(pos);
1844
- while (code && code !== singleQuoteCC && code !== doubleQuoteCC && !(code > 64 && code < 91 || code > 96 && code < 123) && code !== closeBracketCC) {
1845
- pos++;
1846
- code = S.charCodeAt(pos);
1847
- }
1848
- if (code === singleQuoteCC || code === doubleQuoteCC) {
1849
- var value = parseString();
1850
- if (pos === -1) {
1851
- return {
1852
- tagName,
1853
- attributes,
1854
- children
1855
- };
1856
- }
1857
- } else {
1858
- value = null;
1859
- pos--;
1860
- }
1861
- attributes[name] = value;
1862
- }
1863
- pos++;
1864
- }
1865
- if (S.charCodeAt(pos - 1) !== slashCC) {
1866
- if (tagName == "script") {
1867
- var start = pos + 1;
1868
- pos = S.indexOf("</script>", pos);
1869
- children = [S.slice(start, pos)];
1870
- pos += 9;
1871
- } else if (tagName == "style") {
1872
- var start = pos + 1;
1873
- pos = S.indexOf("</style>", pos);
1874
- children = [S.slice(start, pos)];
1875
- pos += 8;
1876
- } else if (NoChildNodes.indexOf(tagName) === -1) {
1877
- pos++;
1878
- children = parseChildren(tagName);
1879
- } else {
1880
- pos++;
1881
- }
1882
- } else {
1883
- pos++;
1884
- }
1885
- return {
1886
- tagName,
1887
- attributes,
1888
- children
1889
- };
1890
- }
1891
- function parseString() {
1892
- var startChar = S[pos];
1893
- var startpos = pos + 1;
1894
- pos = S.indexOf(startChar, startpos);
1895
- return S.slice(startpos, pos);
1896
- }
1897
- function findElements() {
1898
- var r = new RegExp("\\s" + options.attrName + `\\s*=['"]` + options.attrValue + `['"]`).exec(S);
1899
- if (r) {
1900
- return r.index;
1901
- } else {
1902
- return -1;
1903
- }
1904
- }
1905
- var out = null;
1906
- if (options.attrValue !== void 0) {
1907
- options.attrName = options.attrName || "id";
1908
- var out = [];
1909
- while ((pos = findElements()) !== -1) {
1910
- pos = S.lastIndexOf("<", pos);
1911
- if (pos !== -1) {
1912
- out.push(parseNode());
1913
- }
1914
- S = S.substr(pos);
1915
- pos = 0;
1916
- }
1917
- } else if (options.parseNode) {
1918
- out = parseNode();
1919
- } else {
1920
- out = parseChildren("");
1921
- }
1922
- if (options.filter) {
1923
- out = filter(out, options.filter);
1924
- }
1925
- if (options.simplify) {
1926
- return simplify(Array.isArray(out) ? out : [out]);
1927
- }
1928
- if (options.setPos) {
1929
- out.pos = pos;
1930
- }
1931
- return out;
1932
- }
1933
- function simplify(children) {
1934
- var out = {};
1935
- if (!children.length) {
1936
- return "";
1937
- }
1938
- if (children.length === 1 && typeof children[0] == "string") {
1939
- return children[0];
1940
- }
1941
- children.forEach(function(child) {
1942
- if (typeof child !== "object") {
1943
- return;
1944
- }
1945
- if (!out[child.tagName])
1946
- out[child.tagName] = [];
1947
- var kids = simplify(child.children);
1948
- out[child.tagName].push(kids);
1949
- if (Object.keys(child.attributes).length && typeof kids !== "string") {
1950
- kids._attributes = child.attributes;
1951
- }
1952
- });
1953
- for (var i in out) {
1954
- if (out[i].length == 1) {
1955
- out[i] = out[i][0];
1956
- }
1957
- }
1958
- return out;
1959
- }
1960
- function filter(children, f, dept = 0, path = "") {
1961
- var out = [];
1962
- children.forEach(function(child, i) {
1963
- if (typeof child === "object" && f(child, i, dept, path)) out.push(child);
1964
- if (child.children) {
1965
- var kids = filter(child.children, f, dept + 1, (path ? path + "." : "") + i + "." + child.tagName);
1966
- out = out.concat(kids);
1967
- }
1968
- });
1969
- return out;
1970
- }
1971
-
1972
- // ../../node_modules/.pnpm/txml@5.1.1/node_modules/txml/dist/transformStream.mjs
1973
- import through2 from "through2";
1974
-
1975
- // ../../node_modules/.pnpm/txml@5.1.1/node_modules/txml/dist/index.mjs
1976
- import "through2";
1977
-
1978
- // src/types.ts
1979
- var NexaVersion = {
1980
- xmlns: "http://www.nexacroplatform.com/platform/dataset",
1981
- version: "4000"
1982
- };
1983
- var ColumnTypeError = class extends Error {
1984
- constructor(message) {
1985
- super(message);
1986
- this.name = "ColumnTypeError";
1987
- }
1988
- };
1989
-
1990
- // src/utils.ts
1991
- function base64ToUint8Array(base64String) {
1992
- const binaryString = atob(base64String);
1993
- const bytes = new Uint8Array(binaryString.length);
1994
- for (let i = 0; i < binaryString.length; i++) {
1995
- bytes[i] = binaryString.charCodeAt(i);
1996
- }
1997
- return bytes;
1998
- }
1999
- function stringToDate(value) {
2000
- if (!value) return void 0;
2001
- let year;
2002
- let month;
2003
- let day;
2004
- let hours = 0;
2005
- let minutes = 0;
2006
- let seconds = 0;
2007
- let milliseconds = 0;
2008
- if (value.length < 6 || value.length > 16) {
2009
- return void 0;
2010
- }
2011
- if (value.length >= 8) {
2012
- year = parseInt(value.substring(0, 4), 10);
2013
- month = parseInt(value.substring(4, 6), 10) - 1;
2014
- day = parseInt(value.substring(6, 8), 10);
2015
- } else {
2016
- year = 1970;
2017
- month = 0;
2018
- day = 1;
2019
- }
2020
- if (value.length === 6) {
2021
- hours = parseInt(value.substring(0, 2), 10);
2022
- minutes = parseInt(value.substring(2, 4), 10);
2023
- seconds = parseInt(value.substring(4, 6), 10);
2024
- } else if (value.length >= 10) {
2025
- hours = parseInt(value.substring(8, 10), 10);
2026
- minutes = parseInt(value.substring(10, 12), 10);
2027
- seconds = parseInt(value.substring(12, 14), 10);
2028
- }
2029
- if (value.length === 16) {
2030
- milliseconds = parseInt(value.substring(14, 16), 10);
2031
- }
2032
- if (year < 1970 || year > 9999 || month < 0 || month > 11 || day < 1 || day > 31 || hours < 0 || hours > 23 || minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59 || milliseconds < 0 || milliseconds > 999) {
2033
- return void 0;
2034
- }
2035
- const date = new Date(year, month, day, hours, minutes, seconds, milliseconds);
2036
- if (isNaN(date.getTime())) {
2037
- return void 0;
2038
- }
2039
- return date;
2040
- }
2041
- var StringWritableStream = class extends WritableStream {
2042
- result = "";
2043
- constructor() {
2044
- const decoder = new TextDecoder();
2045
- super({
2046
- write: (chunk) => {
2047
- this.result += decoder.decode(chunk, { stream: true });
2048
- },
2049
- close: () => {
2050
- this.result += decoder.decode();
2051
- }
2052
- });
2053
- }
2054
- /**
2055
- * Returns the collected string result.
2056
- * @returns The concatenated string from all written chunks.
2057
- */
2058
- getResult() {
2059
- return this.result;
2060
- }
2061
- };
2062
- function convertToColumnType(value, type) {
2063
- switch (type) {
2064
- case "INT":
2065
- case "BIGDECIMAL":
2066
- const intValue = parseInt(value, 10);
2067
- return isNaN(intValue) ? value : intValue;
2068
- case "FLOAT":
2069
- const floatValue = parseFloat(value);
2070
- return isNaN(floatValue) ? value : floatValue;
2071
- case "DECIMAL":
2072
- const decimalValue = parseFloat(value);
2073
- return isNaN(decimalValue) ? value : decimalValue;
2074
- case "DATE":
2075
- case "DATETIME":
2076
- case "TIME":
2077
- return stringToDate(value) || value;
2078
- case "BLOB":
2079
- try {
2080
- return base64ToUint8Array(value);
2081
- } catch {
2082
- return value;
2083
- }
2084
- case "STRING":
2085
- return value;
2086
- default:
2087
- throw new ColumnTypeError(`Unsupported column type: ${type}`);
2088
- }
2089
- }
2090
-
2091
- // src/xapi-data.ts
2092
- var XapiRoot = class {
2093
- /** An array of datasets within the X-API root. */
2094
- datasets = [];
2095
- /** Parameters associated with the X-API root. */
2096
- parameters = { params: [] };
2097
- /**
2098
- * Creates an instance of XapiRoot.
2099
- * @param datasets - Initial array of datasets.
2100
- * @param parameters - Initial parameters.
2101
- */
2102
- constructor(datasets = [], parameters = { params: [] }) {
2103
- this.datasets = datasets;
2104
- this.parameters = parameters;
2105
- }
2106
- /**
2107
- * Adds a dataset to the X-API root.
2108
- * @param dataset - The dataset to add.
2109
- */
2110
- addDataset(dataset) {
2111
- this.datasets.push(dataset);
2112
- }
2113
- /**
2114
- * Retrieves a dataset by its ID.
2115
- * @param id - The ID of the dataset to retrieve.
2116
- * @returns The Dataset object, or undefined if not found.
2117
- */
2118
- getDataset(id) {
2119
- return this.datasets.find((dataset) => dataset.id === id);
2120
- }
2121
- /**
2122
- * Adds a parameter to the X-API root.
2123
- * @param parameter - The parameter to add.
2124
- */
2125
- addParameter(parameter) {
2126
- this.parameters.params.push(parameter);
2127
- }
2128
- /**
2129
- * Retrieves a parameter by its ID.
2130
- * @param id - The ID of the parameter to retrieve.
2131
- * @returns The Parameter object, or undefined if not found.
2132
- */
2133
- getParameter(id) {
2134
- return this.parameters.params.find((param) => param.id === id);
2135
- }
2136
- /**
2137
- * Sets all parameters for the X-API root.
2138
- * @param parameters - The XapiParameters object to set.
2139
- */
2140
- setParameters(parameters) {
2141
- this.parameters = parameters;
2142
- }
2143
- /**
2144
- * Sets the value of a specific parameter, or adds it if it doesn't exist.
2145
- * @param id - The ID of the parameter.
2146
- * @param value - The value to set for the parameter.
2147
- */
2148
- setParameter(id, value) {
2149
- const param = this.parameters.params.find((p) => p.id === id);
2150
- if (param) {
2151
- param.value = value;
2152
- } else {
2153
- this.addParameter({ id, value });
2154
- }
2155
- }
2156
- /**
2157
- * Returns the number of parameters.
2158
- * @returns The count of parameters.
2159
- */
2160
- parameterSize() {
2161
- return this.parameters.params.length;
2162
- }
2163
- /**
2164
- * Returns the number of datasets.
2165
- * @returns The count of datasets.
2166
- */
2167
- datasetSize() {
2168
- return this.datasets.length;
2169
- }
2170
- /**
2171
- * Iterates over the parameters.
2172
- * @returns An IterableIterator for parameters.
2173
- */
2174
- *iterParameters() {
2175
- for (const param of this.parameters.params) {
2176
- yield param;
2177
- }
2178
- }
2179
- /**
2180
- * Iterates over the datasets.
2181
- * @returns An IterableIterator for datasets.
2182
- */
2183
- *iterDatasets() {
2184
- for (const dataset of this.datasets) {
2185
- yield dataset;
2186
- }
2187
- }
2188
- };
2189
- var Dataset = class {
2190
- /** The ID of the dataset. */
2191
- id;
2192
- constColumns = [];
2193
- columns = [];
2194
- /** An array of rows in the dataset. */
2195
- rows = [];
2196
- _columnIndexMap = /* @__PURE__ */ new Map();
2197
- /**
2198
- * Creates an instance of Dataset.
2199
- * @param id - The ID of the dataset.
2200
- * @param constColumns - Initial array of constant columns.
2201
- * @param columns - Initial array of columns.
2202
- * @param rows - Initial array of rows.
2203
- */
2204
- constructor(id, constColumns = [], columns = [], rows = []) {
2205
- this.id = id;
2206
- this.constColumns = constColumns;
2207
- this.columns = columns;
2208
- this.rows = rows;
2209
- }
2210
- /**
2211
- * Adds a column definition to the dataset.
2212
- * @param column - The column definition to add.
2213
- */
2214
- addColumn(column) {
2215
- this.columns.push(column);
2216
- this._columnIndexMap.set(column.id, this.columns.length - 1);
2217
- }
2218
- /**
2219
- * Adds a constant column definition to the dataset.
2220
- * @param column - The constant column definition to add.
2221
- */
2222
- addConstColumn(column) {
2223
- this.constColumns.push(column);
2224
- }
2225
- /**
2226
- * Creates a new empty row and adds it to the dataset.
2227
- * @returns The index of the newly created row.
2228
- */
2229
- newRow() {
2230
- this.rows.push({ cols: [] });
2231
- return this.rows.length - 1;
2232
- }
2233
- /**
2234
- * Adds an existing row to the dataset.
2235
- * @param row - The row to add.
2236
- */
2237
- addRow(row) {
2238
- this.rows.push(row);
2239
- }
2240
- /**
2241
- * Retrieves the index of a column by its ID.
2242
- * @param columnId - The ID of the column.
2243
- * @returns The index of the column, or undefined if not found.
2244
- */
2245
- getColumnIndex(columnId) {
2246
- return this._columnIndexMap.get(columnId);
2247
- }
2248
- /**
2249
- * Retrieves the column definition by its ID.
2250
- * @param columnId - The ID of the column.
2251
- * @returns The Column object, or undefined if not found.
2252
- */
2253
- getColumnInfo(columnId) {
2254
- const colIndex = this.getColumnIndex(columnId);
2255
- if (colIndex !== void 0) {
2256
- return this.columns[colIndex];
2257
- }
2258
- return void 0;
2259
- }
2260
- /**
2261
- * Retrieves the constant column definition by its ID.
2262
- * @param columnId - The ID of the constant column.
2263
- * @returns The ConstColumn object, or undefined if not found.
2264
- */
2265
- getConstColumnInfo(columnId) {
2266
- return this.constColumns.find((col) => col.id === columnId);
2267
- }
2268
- /**
2269
- * Retrieves the value of a column in a specific row.
2270
- * @param rowIdx - The index of the row.
2271
- * @param columnId - The ID of the column.
2272
- * @returns The value of the column, or undefined if the row or column is not found.
2273
- * @throws {Error} if the column ID is not found in the dataset.
2274
- */
2275
- getColumn(rowIdx, columnId) {
2276
- if (rowIdx < this.rows.length) {
2277
- const colIndex = this.getColumnIndex(columnId);
2278
- if (colIndex === void 0) {
2279
- throw new Error(`Column with id ${columnId} not found in dataset ${this.id}`);
2280
- }
2281
- const col = this.rows[rowIdx].cols[colIndex];
2282
- return col?.value;
2283
- }
2284
- return void 0;
2285
- }
2286
- /**
2287
- * Retrieves the original value of a column in a specific row (for OrgRow).
2288
- * @param rowIdx - The index of the row.
2289
- * @param columnId - The ID of the column.
2290
- * @returns The original value of the column, or undefined if the row or column is not found.
2291
- * @throws {Error} if the column ID is not found in the dataset.
2292
- */
2293
- getOrgColumn(rowIdx, columnId) {
2294
- if (rowIdx < this.rows.length) {
2295
- const colIndex = this.getColumnIndex(columnId);
2296
- if (colIndex === void 0) {
2297
- throw new Error(`Column with id ${columnId} not found in dataset ${this.id}`);
2298
- }
2299
- const col = this.rows[rowIdx].orgRow?.[colIndex];
2300
- return col?.value;
2301
- }
2302
- return void 0;
2303
- }
2304
- /**
2305
- * Sets the value of a column in a specific row.
2306
- * @param rowIdx - The index of the row.
2307
- * @param columnId - The ID of the column.
2308
- * @param value - The value to set.
2309
- * @throws {Error} if the row index is out of bounds or the column ID is not found.
2310
- */
2311
- setColumn(rowIdx, columnId, value) {
2312
- if (rowIdx < this.rows.length) {
2313
- const colIndex = this.getColumnIndex(columnId);
2314
- if (colIndex === void 0) {
2315
- throw new Error(`Column with id ${columnId} not found in dataset ${this.id}`);
2316
- }
2317
- this.rows[rowIdx].cols[colIndex] = { id: columnId, value };
2318
- } else {
2319
- throw new Error(`Row index ${rowIdx} out of bounds in dataset ${this.id}`);
2320
- }
2321
- }
2322
- /**
2323
- * Iterates over the constant column definitions.
2324
- * @returns An IterableIterator for constant columns.
2325
- */
2326
- *iterConstColumns() {
2327
- for (const column of this.constColumns) {
2328
- yield column;
2329
- }
2330
- }
2331
- /**
2332
- * Iterates over the column definitions.
2333
- * @returns An IterableIterator for columns.
2334
- */
2335
- *iterColumns() {
2336
- for (const column of this.columns) {
2337
- yield column;
2338
- }
2339
- }
2340
- /**
2341
- * Iterates over the rows in the dataset.
2342
- * @returns An IterableIterator for rows.
2343
- */
2344
- *iterRows() {
2345
- for (const row of this.rows) {
2346
- yield row;
2347
- }
2348
- }
2349
- /**
2350
- * Returns the number of column definitions.
2351
- * @returns The count of columns.
2352
- */
2353
- columnSize() {
2354
- return this.columns.length;
2355
- }
2356
- /**
2357
- * Returns the number of constant column definitions.
2358
- * @returns The count of constant columns.
2359
- */
2360
- constColumnSize() {
2361
- return this.constColumns.length;
2362
- }
2363
- /**
2364
- * Returns the number of rows in the dataset.
2365
- * @returns The count of rows.
2366
- */
2367
- rowSize() {
2368
- return this.rows.length;
2369
- }
2370
- };
2371
-
2372
- // test/performance.test.ts
2373
- var xmlString = `
2374
- <Root>
2375
- <Parameters>
2376
- <Parameter id="param1" type="STRING">value1</Parameter>
2377
- <Parameter id="param2" type="INT">123</Parameter>
2378
- </Parameters>
2379
- <Dataset id="ds_test">
2380
- <ColumnInfo>
2381
- <Column id="col1" type="STRING" size="256"/>
2382
- <Column id="col2" type="INT" size="256"/>
2383
- </ColumnInfo>
2384
- <Rows>
2385
- <Row>
2386
- <Col id="col1">row1_col1</Col>
2387
- <Col id="col2">11</Col>
2388
- </Row>
2389
- <Row>
2390
- <Col id="col1">row2_col1</Col>
2391
- <Col id="col2">22</Col>
2392
- </Row>
2393
- </Rows>
2394
- </Dataset>
2395
- </Root>
2396
- `;
2397
- var defaultOptions = {
2398
- xapiVersion: NexaVersion,
2399
- parseToTypes: true
2400
- };
2401
- var _options = {
2402
- ...defaultOptions
2403
- };
2404
- async function parse_async_txml(xml) {
2405
- const parsedXml = parse(xml);
2406
- const xapiRoot = new XapiRoot();
2407
- const rootElement = parsedXml.find((node) => node.tagName === "Root");
2408
- if (!rootElement) return xapiRoot;
2409
- const parametersElement = rootElement.children.find((node) => node.tagName === "Parameters");
2410
- if (parametersElement) {
2411
- parametersElement.children.forEach((p) => {
2412
- if (p.tagName === "Parameter") {
2413
- const id = p.attributes.id;
2414
- const type = p.attributes.type || "STRING";
2415
- const value = p.children[0];
2416
- xapiRoot.addParameter({
2417
- id,
2418
- type,
2419
- value: _options.parseToTypes ? convertToColumnType(value, type) : value
2420
- });
2421
- }
2422
- });
2423
- }
2424
- const datasetsElement = rootElement.children.find((node) => node.tagName === "Dataset");
2425
- if (datasetsElement) {
2426
- const datasetId = datasetsElement.attributes.id;
2427
- const dataset = new Dataset(datasetId);
2428
- xapiRoot.addDataset(dataset);
2429
- const columnInfoElement = datasetsElement.children.find((node) => node.tagName === "ColumnInfo");
2430
- if (columnInfoElement) {
2431
- columnInfoElement.children.forEach((colInfo) => {
2432
- if (colInfo.tagName === "ConstColumn") {
2433
- dataset.addConstColumn({
2434
- id: colInfo.attributes.id,
2435
- size: parseInt(colInfo.attributes.size || "0", 10),
2436
- type: colInfo.attributes.type || "STRING",
2437
- value: colInfo.attributes.value || void 0
2438
- });
2439
- } else if (colInfo.tagName === "Column") {
2440
- dataset.addColumn({
2441
- id: colInfo.attributes.id,
2442
- size: parseInt(colInfo.attributes.size || "0", 10),
2443
- type: colInfo.attributes.type || "STRING"
2444
- });
2445
- }
2446
- });
2447
- }
2448
- const rowsElement = datasetsElement.children.find((node) => node.tagName === "Rows");
2449
- if (rowsElement) {
2450
- rowsElement.children.forEach((r) => {
2451
- if (r.tagName === "Row") {
2452
- const rowIndex = dataset.newRow();
2453
- dataset.rows[rowIndex].type = r.attributes.type || void 0;
2454
- r.children.forEach((col) => {
2455
- if (col.tagName === "Col") {
2456
- const colId = col.attributes.id;
2457
- const value = col.children[0];
2458
- const columnInfo = dataset.getColumnInfo(colId);
2459
- if (!columnInfo) throw new Error(`Column with id ${colId} not found in dataset ${dataset.id}`);
2460
- const castedValue = _options.parseToTypes ? convertToColumnType(value, columnInfo.type) : value;
2461
- dataset.rows[rowIndex].cols.push({ id: colId, value: castedValue });
2462
- } else if (col.tagName === "OrgRow") {
2463
- dataset.rows[rowIndex].orgRow = [];
2464
- col.children.forEach((orgCol) => {
2465
- if (orgCol.tagName === "Col") {
2466
- const colId = orgCol.attributes.id;
2467
- const value = orgCol.children[0];
2468
- const columnInfo = dataset.getColumnInfo(colId);
2469
- if (!columnInfo) throw new Error(`Column with id ${colId} not found in dataset ${dataset.id}`);
2470
- const castedValue = _options.parseToTypes ? convertToColumnType(value, columnInfo.type) : value;
2471
- dataset.rows[rowIndex].orgRow.push({ id: colId, value: castedValue });
2472
- }
2473
- });
2474
- }
2475
- });
2476
- }
2477
- });
2478
- }
2479
- }
2480
- return xapiRoot;
2481
- }
2482
- bench("TxmlParser", async () => {
2483
- await parse_async_txml(xmlString);
2484
- });
2485
- await run();