@vzn/vx 0.0.77 → 0.0.78
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 +5 -5
- package/src/orchestrator/excluded-keys.ts +0 -2
- package/src/orchestrator/execute-task.ts +18 -0
- package/src/orchestrator/keyed-projects.ts +1 -5
- package/src/orchestrator/plan.ts +0 -8
- package/src/orchestrator/stable-keys.ts +5 -13
- package/src/orchestrator/upstream.ts +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vzn/vx",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.78",
|
|
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.
|
|
21
|
-
"@vzn/vx-linux-arm64": "0.0.
|
|
22
|
-
"@vzn/vx-darwin-x64": "0.0.
|
|
23
|
-
"@vzn/vx-darwin-arm64": "0.0.
|
|
20
|
+
"@vzn/vx-linux-x64": "0.0.78",
|
|
21
|
+
"@vzn/vx-linux-arm64": "0.0.78",
|
|
22
|
+
"@vzn/vx-darwin-x64": "0.0.78",
|
|
23
|
+
"@vzn/vx-darwin-arm64": "0.0.78"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
|
@@ -54,8 +54,6 @@ export async function keyExcludedDependencies(args: KeyExcludedArgs): Promise<vo
|
|
|
54
54
|
const derive = async (node: TaskNode): Promise<string | undefined> => {
|
|
55
55
|
const upstream = await outcomes(fullDeps(node))
|
|
56
56
|
if (isGroupTask(node)) return computeGroupHash(upstream)
|
|
57
|
-
// A persistent task has no key on the live path, so none here either.
|
|
58
|
-
if (node.config.exec?.persistent !== undefined) return undefined
|
|
59
57
|
return computeTaskHash({
|
|
60
58
|
node,
|
|
61
59
|
upstream,
|
|
@@ -260,6 +260,23 @@ async function executePersistentTask(args: ExecuteArgs): Promise<TaskOutcome> {
|
|
|
260
260
|
const effectiveForwardArgs = node.requested ? (args.forwardArgs ?? []) : []
|
|
261
261
|
const env = taskEnv(node, step, args.workspaceRoot)
|
|
262
262
|
const wallclockStartNs = process.hrtime.bigint() - args.runStartHrTimeNs
|
|
263
|
+
// Keyed like an uncached task (its whole project), so a cached dependant
|
|
264
|
+
// behind a dev server re-runs when the server's sources change; with no
|
|
265
|
+
// key the dependant folded nothing of it and replayed a stale e2e (A-17).
|
|
266
|
+
const hash =
|
|
267
|
+
args.noDependants === true
|
|
268
|
+
? undefined
|
|
269
|
+
: await computeTaskHash({
|
|
270
|
+
node,
|
|
271
|
+
upstream: args.upstream,
|
|
272
|
+
workspaceRoot: args.workspaceRoot,
|
|
273
|
+
workspaceFingerprint: args.workspaceFingerprint,
|
|
274
|
+
cache: args.cache,
|
|
275
|
+
forwardArgs: args.forwardArgs,
|
|
276
|
+
nestedProjectDirs: args.nestedProjectDirs,
|
|
277
|
+
...(args.gitFilesCache !== undefined ? { gitFilesCache: args.gitFilesCache } : {}),
|
|
278
|
+
...(args.hashCache !== undefined ? { hashCache: args.hashCache } : {}),
|
|
279
|
+
})
|
|
263
280
|
|
|
264
281
|
// The args after `--` reach a server as they reach any task. A readyWhen
|
|
265
282
|
// server once got none — "so the matcher sees the unmodified output",
|
|
@@ -383,6 +400,7 @@ async function executePersistentTask(args: ExecuteArgs): Promise<TaskOutcome> {
|
|
|
383
400
|
status: 'success',
|
|
384
401
|
exitCode: 0,
|
|
385
402
|
durationMs: spawn.readyMs(),
|
|
403
|
+
...(hash !== undefined ? { hash } : {}),
|
|
386
404
|
wallclockStartNs,
|
|
387
405
|
wallclockEndNs: process.hrtime.bigint() - args.runStartHrTimeNs,
|
|
388
406
|
}
|
|
@@ -18,10 +18,7 @@ import { selectFoldedDeps, type FoldCandidate } from './upstream.js'
|
|
|
18
18
|
* selects them (absent, or no `cache` at all, means all);
|
|
19
19
|
* - a group folds every dependency (`computeGroupHash`) and folds no
|
|
20
20
|
* files of its own;
|
|
21
|
-
* - a persistent task
|
|
22
|
-
* no one and its own dependencies reach no key through it. (The local
|
|
23
|
-
* classify pass does give it one — stable-keys.ts — so a key there can
|
|
24
|
-
* move with more than this set names; never with less.)
|
|
21
|
+
* - a persistent task is keyed as a task with no `cache` (A-17).
|
|
25
22
|
*
|
|
26
23
|
* Every exec task reached contributes its project, cached or not: a key
|
|
27
24
|
* folds the task's own project files, and a task with no `cache` declares
|
|
@@ -71,7 +68,6 @@ function folded(node: TaskNode, nodes: ReadonlyMap<string, TaskNode>): FoldCandi
|
|
|
71
68
|
const candidates: FoldCandidate[] = []
|
|
72
69
|
for (const id of node.deps) {
|
|
73
70
|
const dep = nodes.get(id)!
|
|
74
|
-
if (dep.config.exec?.persistent !== undefined) continue
|
|
75
71
|
candidates.push({ node: dep, unit: foldUnit(dep) })
|
|
76
72
|
}
|
|
77
73
|
if (isGroupTask(node)) return candidates
|
package/src/orchestrator/plan.ts
CHANGED
|
@@ -131,14 +131,6 @@ export async function plan(args: PlanArgs): Promise<RunPlan> {
|
|
|
131
131
|
cacheStatusById.set(node.id, 'group')
|
|
132
132
|
return planOutcome(node, computeGroupHash(upstream))
|
|
133
133
|
}
|
|
134
|
-
// A persistent task has no key on the live path (its outcome carries
|
|
135
|
-
// none, `stable-keys.ts`), so a dependant folds nothing for it. The
|
|
136
|
-
// plan keyed it and folded that, and `--dry` then called a dependant
|
|
137
|
-
// a miss under a key the run never looks up (item 766).
|
|
138
|
-
if (node.config.exec?.persistent !== undefined) {
|
|
139
|
-
cacheStatusById.set(node.id, 'no-cache')
|
|
140
|
-
return planOutcome(node, undefined)
|
|
141
|
-
}
|
|
142
134
|
|
|
143
135
|
const hash = await computeTaskHash({
|
|
144
136
|
node,
|
|
@@ -87,13 +87,12 @@ export async function deriveStableKeys(args: DeriveStableKeysArgs): Promise<Stab
|
|
|
87
87
|
const unfoldedById = new Map<string, ProjectSet>()
|
|
88
88
|
const wsRewriters = new Set<string>()
|
|
89
89
|
// A cached rewriter matters only to a key that leaves a dependency's key
|
|
90
|
-
// out: a `cache.inputs.tasks` filter
|
|
91
|
-
//
|
|
92
|
-
//
|
|
93
|
-
// memoised walk over the 3,000-task bench; item 750).
|
|
90
|
+
// out: a `cache.inputs.tasks` filter. With none in the graph every edge
|
|
91
|
+
// folds and the sets above stay empty, so they are not built (about 2 ms,
|
|
92
|
+
// median, of a 27 ms memoised walk over the 3,000-task bench; item 750).
|
|
94
93
|
let anyUnfolded = false
|
|
95
94
|
for (const n of args.nodes.values()) {
|
|
96
|
-
if (n.config.cache?.inputs?.tasks !== undefined
|
|
95
|
+
if (n.config.cache?.inputs?.tasks !== undefined) {
|
|
97
96
|
anyUnfolded = true
|
|
98
97
|
break
|
|
99
98
|
}
|
|
@@ -188,12 +187,6 @@ export async function deriveStableKeys(args: DeriveStableKeysArgs): Promise<Stab
|
|
|
188
187
|
continue
|
|
189
188
|
}
|
|
190
189
|
|
|
191
|
-
// A persistent task has no key on the live path (its outcome carries no
|
|
192
|
-
// hash, so a dependent folds nothing of it); recording one here gave
|
|
193
|
-
// its dependents a second key, which a `--force` or remote run never
|
|
194
|
-
// saved under.
|
|
195
|
-
if (node.config.exec?.persistent !== undefined) continue
|
|
196
|
-
|
|
197
190
|
const hash = await computeTaskHash({
|
|
198
191
|
node,
|
|
199
192
|
upstream,
|
|
@@ -226,8 +219,7 @@ export async function deriveStableKeys(args: DeriveStableKeysArgs): Promise<Stab
|
|
|
226
219
|
/**
|
|
227
220
|
* Does this task's key fold the dependency's? What `computeTaskHash` folds
|
|
228
221
|
* (`filterUpstreamHashes` over the same synthetic outcomes); a group folds
|
|
229
|
-
* every keyed member.
|
|
230
|
-
* none.
|
|
222
|
+
* every keyed member.
|
|
231
223
|
*/
|
|
232
224
|
function foldedBy(
|
|
233
225
|
node: TaskNode,
|
|
@@ -47,7 +47,7 @@ export function keyedDeps(node: TaskNode): readonly string[] {
|
|
|
47
47
|
* folded into the cache key (the fold sorts by hash, so ordering here
|
|
48
48
|
* doesn't affect derivation); the task id rides along so Tier-3's
|
|
49
49
|
* `entry_inputs` rows can NAME which upstream a hash came from. An
|
|
50
|
-
* upstream with no hash
|
|
50
|
+
* upstream with no hash folds nothing.
|
|
51
51
|
*/
|
|
52
52
|
export function filterUpstreamHashes(
|
|
53
53
|
upstream: TaskOutcome[],
|