@vzn/vx 0.0.621 → 0.0.622

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vzn/vx",
3
- "version": "0.0.621",
3
+ "version": "0.0.622",
4
4
  "description": "The fastest task runner and build cache for JavaScript monorepos.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -21,10 +21,10 @@
21
21
  "node": ">=18"
22
22
  },
23
23
  "optionalDependencies": {
24
- "@vzn/vx-linux-x64": "0.0.621",
25
- "@vzn/vx-linux-arm64": "0.0.621",
26
- "@vzn/vx-darwin-x64": "0.0.621",
27
- "@vzn/vx-darwin-arm64": "0.0.621"
24
+ "@vzn/vx-linux-x64": "0.0.622",
25
+ "@vzn/vx-linux-arm64": "0.0.622",
26
+ "@vzn/vx-darwin-x64": "0.0.622",
27
+ "@vzn/vx-darwin-arm64": "0.0.622"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -283,6 +283,7 @@ export function defaultLogger(
283
283
  let restoredLocal = 0
284
284
  let restoredRemote = 0
285
285
  let skippedCount = 0
286
+ let savedMs = 0
286
287
  // Cache-miss duration spread, accumulated incrementally (the same
287
288
  // numbers the final summary computes from the outcome list).
288
289
  let spreadMax = 0
@@ -369,6 +370,7 @@ export function defaultLogger(
369
370
  restoredRemote,
370
371
  miss: succeeded + failed - noCache,
371
372
  noCache,
373
+ savedMs,
372
374
  left: total - done,
373
375
  spread:
374
376
  spreadCount > 0
@@ -698,10 +700,12 @@ export function defaultLogger(
698
700
  case 'cache-hit':
699
701
  if (outcome.restored === false) upToDate++
700
702
  else restoredLocal++
703
+ savedMs += outcome.storedDurationMs ?? 0
701
704
  break
702
705
  case 'cache-hit-remote':
703
706
  if (outcome.restored === false) upToDate++
704
707
  else restoredRemote++
708
+ savedMs += outcome.storedDurationMs ?? 0
705
709
  break
706
710
  case 'skipped':
707
711
  skippedCount++
@@ -6,6 +6,7 @@
6
6
  import type { TaskOutcome } from '../graph/index.js'
7
7
  import { paint, type ColorSupport } from './colors.js'
8
8
  import { tallyOutcomes } from './tally.js'
9
+ import { isCacheHit } from './telemetry.js'
9
10
  import { outcomeLabel, projectOutcome, ranNoCache } from './events.js'
10
11
  import { isGroupTask } from '../graph/index.js'
11
12
  import { formatElapsed } from '../util/index.js'
@@ -119,6 +120,8 @@ export interface SummaryStats {
119
120
  spread: { maxMs: number; minMs: number; sumMs: number; count: number } | null
120
121
  /** Tasks an `admit` policy held with a worker free, and the waits summed. Absent with no hold. */
121
122
  held?: { count: number; sumMs: number }
123
+ /** The hits' stored exec times summed: the work the cache skipped. */
124
+ savedMs?: number
122
125
  /** A run of groups only: their names, so `0 tasks` says why. */
123
126
  emptyGroups?: readonly string[]
124
127
  }
@@ -320,6 +323,10 @@ function resultLine(
320
323
  : `${hits} cached (${Math.floor((hits / cacheable) * 100)}%)`,
321
324
  )
322
325
  if (noCache > 0) parts.push(paint('', `${noCache} no-cache`, colors, { dim: true }))
326
+ // What the cache paid back, beside what the run cost: the stored exec
327
+ // time of every hit, never the restore this run spent on it.
328
+ if ((stats.savedMs ?? 0) >= 1)
329
+ parts.push(paint(SUCCESS, `${formatElapsed(stats.savedMs!)} saved`, colors))
323
330
  parts.push(formatElapsed(totalMs))
324
331
  return parts.join(` ${paint('', '\u00b7', colors, { dim: true })} `)
325
332
  }
@@ -373,6 +380,9 @@ export function formatRunSummary(
373
380
  const durations = outcomes
374
381
  .filter((o) => (o.status === 'success' || o.status === 'failed') && !isGroupTask(o.node))
375
382
  .map((o) => o.durationMs)
383
+ let savedMs = 0
384
+ for (const o of outcomes)
385
+ if (isCacheHit(o.status) && !isGroupTask(o.node)) savedMs += o.storedDurationMs ?? 0
376
386
  const heldOutcomes = outcomes.filter((o) => o.admissionHeldMs !== undefined)
377
387
  const notRun = outcomes.filter((o) => neverStarted(o) && !isGroupTask(o.node)).length
378
388
  const emptyGroups = outcomes.every((o) => isGroupTask(o.node))
@@ -391,6 +401,7 @@ export function formatRunSummary(
391
401
  restoredRemote: t.restoredRemote,
392
402
  miss: t.total - t.skipped - (t.cachedLocal + t.cachedRemote) - noCache,
393
403
  noCache,
404
+ savedMs,
394
405
  spread:
395
406
  durations.length > 0
396
407
  ? {