@vzn/vx 0.0.82 → 0.0.83

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.82",
3
+ "version": "0.0.83",
4
4
  "description": "An open, extensible monorepo task runner.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -17,10 +17,10 @@
17
17
  "node": ">=18"
18
18
  },
19
19
  "optionalDependencies": {
20
- "@vzn/vx-linux-x64": "0.0.82",
21
- "@vzn/vx-linux-arm64": "0.0.82",
22
- "@vzn/vx-darwin-x64": "0.0.82",
23
- "@vzn/vx-darwin-arm64": "0.0.82"
20
+ "@vzn/vx-linux-x64": "0.0.83",
21
+ "@vzn/vx-linux-arm64": "0.0.83",
22
+ "@vzn/vx-darwin-x64": "0.0.83",
23
+ "@vzn/vx-darwin-arm64": "0.0.83"
24
24
  },
25
25
  "dependencies": {
26
26
  "@anthropic-ai/sandbox-runtime": "^0.0.76"
@@ -37,12 +37,36 @@ export type DownloadMode = 'eager' | 'deferred' | 'never'
37
37
  export function deferralEligibility(nodes: Map<string, TaskNode>): Map<string, string> {
38
38
  const ineligible = new Map<string, string>()
39
39
 
40
- const readersByProject = new Map<string, { taskId: string; prefixes: string[] }[]>()
40
+ type Reader = { taskId: string; prefixes: string[]; via: string }
41
+ const readersByProject = new Map<string, Reader[]>()
42
+ const addReader = (n: TaskNode, prefixes: string[], via: string): void => {
43
+ const list = readersByProject.get(n.projectName)
44
+ if (list) list.push({ taskId: n.id, prefixes, via })
45
+ else readersByProject.set(n.projectName, [{ taskId: n.id, prefixes, via }])
46
+ }
47
+ // A task with no `cache` block keys on every file in its project, and a
48
+ // cached task that depends on it folds that key: deferring a producer
49
+ // there moved both keys with the transfer flag. Only such a task is a
50
+ // reader — one nothing cached folds keys nothing that lasts.
51
+ const folded = new Set<string>()
52
+ const stack = [...nodes.values()]
53
+ .filter((n) => n.config.cache !== undefined)
54
+ .flatMap((n) => n.deps)
55
+ for (let id = stack.pop(); id !== undefined; id = stack.pop()) {
56
+ if (folded.has(id)) continue
57
+ folded.add(id)
58
+ stack.push(...(nodes.get(id)?.deps ?? []))
59
+ }
41
60
  let workspaceReader: string | undefined
42
61
  let runtimeReader: string | undefined
43
62
  for (const n of nodes.values()) {
44
63
  const cache = n.config.cache
45
- if (cache === undefined) continue
64
+ if (cache === undefined) {
65
+ if (folded.has(n.id) && !isGroupTask(n) && n.config.exec?.persistent === undefined) {
66
+ addReader(n, ['.'], 'as a task with no cache block that a cached task folds')
67
+ }
68
+ continue
69
+ }
46
70
  if ((cache.inputs?.workspaceFiles?.length ?? 0) > 0) workspaceReader ??= n.id
47
71
  // A `runtime` input is a SHELL COMMAND whose reads are unknowable —
48
72
  // the same reason vx refuses to infer inputs by tracing. It can `cat` a
@@ -60,10 +84,11 @@ export function deferralEligibility(nodes: Map<string, TaskNode>): Map<string, s
60
84
  runtimeReader ??= n.id
61
85
  }
62
86
  const files = cache.inputs?.files
63
- const prefixes = files === undefined || files.length === 0 ? ['.'] : files.map(staticPrefix)
64
- const list = readersByProject.get(n.projectName)
65
- if (list) list.push({ taskId: n.id, prefixes })
66
- else readersByProject.set(n.projectName, [{ taskId: n.id, prefixes }])
87
+ addReader(
88
+ n,
89
+ files === undefined || files.length === 0 ? ['.'] : files.map(staticPrefix),
90
+ 'with cache.inputs.files',
91
+ )
67
92
  }
68
93
 
69
94
  for (const n of nodes.values()) {
@@ -101,7 +126,7 @@ export function deferralEligibility(nodes: Map<string, TaskNode>): Map<string, s
101
126
  if (clash !== undefined) {
102
127
  ineligible.set(
103
128
  n.id,
104
- `${reader.taskId} reads ${clash === '.' ? 'the whole project' : clash} with cache.inputs.files`,
129
+ `${reader.taskId} reads ${clash === '.' ? 'the whole project' : clash} ${reader.via}`,
105
130
  )
106
131
  break
107
132
  }