@vzn/vx 0.0.329 → 0.0.331

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.329",
3
+ "version": "0.0.331",
4
4
  "description": "A fast, correct 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.329",
25
- "@vzn/vx-linux-arm64": "0.0.329",
26
- "@vzn/vx-darwin-x64": "0.0.329",
27
- "@vzn/vx-darwin-arm64": "0.0.329"
24
+ "@vzn/vx-linux-x64": "0.0.331",
25
+ "@vzn/vx-linux-arm64": "0.0.331",
26
+ "@vzn/vx-darwin-x64": "0.0.331",
27
+ "@vzn/vx-darwin-arm64": "0.0.331"
28
28
  },
29
29
  "dependencies": {
30
30
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -11,8 +11,9 @@ import type { TaskNode } from './task-graph.js'
11
11
  * restore-tier task is a confirmed hit that never waits on its deps, so it
12
12
  * blocks only the exec-tier tasks that depend on it: an exec-tier task's
13
13
  * count is taken over the exec tier alone, which is exact, and a restore's
14
- * is the sum over its direct exec-tier dependents of one plus theirs, so a
15
- * restore that feeds pending work still goes first. A warm run's exec tier
14
+ * is the sum over its direct exec-tier dependents of one plus theirs, plus
15
+ * the weight of each restore that depends on it, so a restore that feeds
16
+ * pending work, directly or through other restores, still goes first. A warm run's exec tier
16
17
  * is its group tasks with no edges among them, and the closure over the
17
18
  * whole graph (476 packages: 1,428 nodes, 12.8k edges of 45-word bitsets)
18
19
  * was 6 ms of the run-graph stage for a ranking the restores never needed.
@@ -24,13 +25,44 @@ export function tieredReverseDepCount(
24
25
  const exec = new Map<string, TaskNode>()
25
26
  for (const [id, node] of nodes) if (!restoreTier.has(id)) exec.set(id, node)
26
27
  const counts = computeReverseDepCount(exec)
28
+ let feeds = false
27
29
  for (const node of exec.values()) {
28
30
  const weight = 1 + counts.get(node.id)!
29
31
  for (const dep of node.deps) {
30
- if (restoreTier.has(dep) && nodes.has(dep)) counts.set(dep, (counts.get(dep) ?? 0) + weight)
32
+ if (!restoreTier.has(dep) || !nodes.has(dep)) continue
33
+ counts.set(dep, (counts.get(dep) ?? 0) + weight)
34
+ feeds = true
31
35
  }
32
36
  }
33
37
  for (const id of restoreTier) if (nodes.has(id) && !counts.has(id)) counts.set(id, 0)
38
+ if (!feeds) return counts
39
+ // A restore's dependents are released only once its own deps have
40
+ // settled (scheduler.ts, item 963), so a restore under another restore
41
+ // blocks whatever that one blocks: r1 → r2 → e held e until r1 restored,
42
+ // and r1 ranked 0 behind every idle restore (C-51). Each restore hands
43
+ // its weight to its restore deps, dependents first (Kahn over the
44
+ // restore tier's reversed edges). A diamond counts twice; the order
45
+ // among restores is a heuristic, and this pass stays linear. A run with
46
+ // no restore feeding an exec task (every task a hit) skips it.
47
+ const above = new Map<string, number>()
48
+ for (const id of restoreTier) {
49
+ for (const dep of nodes.get(id)?.deps ?? []) {
50
+ if (restoreTier.has(dep) && nodes.has(dep)) above.set(dep, (above.get(dep) ?? 0) + 1)
51
+ }
52
+ }
53
+ const ready: string[] = []
54
+ for (const id of restoreTier) if (nodes.has(id) && !above.has(id)) ready.push(id)
55
+ while (ready.length > 0) {
56
+ const id = ready.pop()!
57
+ const weight = counts.get(id)!
58
+ for (const dep of nodes.get(id)!.deps) {
59
+ if (!restoreTier.has(dep) || !nodes.has(dep)) continue
60
+ counts.set(dep, counts.get(dep)! + weight)
61
+ const left = above.get(dep)! - 1
62
+ above.set(dep, left)
63
+ if (left === 0) ready.push(dep)
64
+ }
65
+ }
34
66
  return counts
35
67
  }
36
68