mikser-io 10.8.0 → 10.9.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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/logger.js +21 -7
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mikser-io",
3
- "version": "10.8.0",
3
+ "version": "10.9.0",
4
4
  "files": [
5
5
  "app.js",
6
6
  "index.js",
package/src/logger.js CHANGED
@@ -530,10 +530,21 @@ function progressDetail(detail) {
530
530
  return relative.startsWith('..') ? text : relative
531
531
  }
532
532
 
533
- // `0s` for anything under a second reports the whole phase as nothing. Below
534
- // a second the number IS the information.
535
- function formatDuration(ms) {
536
- return ms < 1000 ? `${ms}ms` : `${(ms / 1000).toFixed(1)}s`
533
+ // A duration rounded away to nothing is not a measurement.
534
+ //
535
+ // `finished: 5 0s` was the first version of this and `0s` said nothing;
536
+ // millisecond resolution moved the same defect one order of magnitude down,
537
+ // where nine of a plain build's thirteen phases still printed `0ms`. The
538
+ // clock is the cause rather than the format — Date.now() cannot resolve
539
+ // below a millisecond — so phases are timed with performance.now(), and each
540
+ // band is printed at the resolution it actually has. The floor exists
541
+ // because even a monotonic clock can report two identical readings, and
542
+ // `0.00ms` would be the same lie a third time.
543
+ export function formatDuration(ms) {
544
+ if (ms >= 1000) return `${(ms / 1000).toFixed(1)}s`
545
+ if (ms >= 1) return `${Math.round(ms)}ms`
546
+ if (ms >= 0.01) return `${ms.toFixed(2)}ms`
547
+ return '<0.01ms'
537
548
  }
538
549
 
539
550
  function emitProgress({ name, total, value, detail }) {
@@ -568,7 +579,8 @@ export function trackProgress(name, total) {
568
579
  // --json would have extended that to every machine reading the output.
569
580
  // Losing the graphics is the point; losing the information is not.
570
581
  const drawn = !carriesDocument && Boolean(process.stdout.isTTY) && Boolean(runtime.options.info)
571
- currentBar = { name, total, value: 0, started: Date.now(), drawn, lastReport: Date.now(), detail: null }
582
+ const now = performance.now()
583
+ currentBar = { name, total, value: 0, started: now, drawn, lastReport: now, detail: null }
572
584
  if (drawn) ensureGauge().show({ section: name, subsection: `0/${total}` }, 0)
573
585
  }
574
586
 
@@ -589,7 +601,7 @@ export function updateProgress(detail) {
589
601
  // documents is 800 lines of noise if this counts the way the bar does.
590
602
  // A phase that finishes inside the interval says nothing at all while
591
603
  // it runs — its finished line covers it.
592
- const now = Date.now()
604
+ const now = performance.now()
593
605
  if (now - currentBar.lastReport >= PROGRESS_INTERVAL_MS && value < total) {
594
606
  currentBar.lastReport = now
595
607
  emitProgress(currentBar)
@@ -602,7 +614,9 @@ export function stopProgress() {
602
614
  if (!currentBar) return
603
615
  const logger = useLogger()
604
616
  const { name, total, value, started } = currentBar
605
- const ms = Date.now() - started
617
+ // Rounded so the field carries real sub-millisecond precision without
618
+ // float noise; the message formats it separately.
619
+ const ms = Math.round((performance.now() - started) * 1000) / 1000
606
620
  gauge?.hide()
607
621
  // Structured either way, so a machine reading --json's stderr gets the
608
622
  // same facts a person reads off the bar.