@vzn/vx 0.0.123 → 0.0.125
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.
|
|
3
|
+
"version": "0.0.125",
|
|
4
4
|
"description": "A fast, correct task runner and build cache for JavaScript monorepos.",
|
|
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.125",
|
|
21
|
+
"@vzn/vx-linux-arm64": "0.0.125",
|
|
22
|
+
"@vzn/vx-darwin-x64": "0.0.125",
|
|
23
|
+
"@vzn/vx-darwin-arm64": "0.0.125"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
26
|
"@anthropic-ai/sandbox-runtime": "^0.0.76"
|
package/src/cache/index.ts
CHANGED
package/src/cache/inputs.ts
CHANGED
|
@@ -643,7 +643,18 @@ export async function stampOutputs(args: {
|
|
|
643
643
|
outputs: string[]
|
|
644
644
|
nestedProjectDirs: string[]
|
|
645
645
|
}): Promise<Map<string, OutputStamp>> {
|
|
646
|
-
|
|
646
|
+
return stampFiles(await resolveOutputs(args))
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
/** `stampOutputs` for root-anchored `cache.outputs.workspaceFiles` (A-43). */
|
|
650
|
+
export async function stampWorkspaceOutputs(args: {
|
|
651
|
+
workspaceRoot: string
|
|
652
|
+
outputs: string[]
|
|
653
|
+
}): Promise<Map<string, OutputStamp>> {
|
|
654
|
+
return stampFiles(await resolveWorkspaceOutputs(args))
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
function stampFiles(files: readonly string[]): Map<string, OutputStamp> {
|
|
647
658
|
const out = new Map<string, OutputStamp>()
|
|
648
659
|
for (const f of files) {
|
|
649
660
|
try {
|
|
@@ -668,7 +679,21 @@ export async function ownOutputsSince(
|
|
|
668
679
|
args: { projectDir: string; outputs: string[]; nestedProjectDirs: string[] },
|
|
669
680
|
before: ReadonlyMap<string, OutputStamp>,
|
|
670
681
|
): Promise<string[]> {
|
|
671
|
-
|
|
682
|
+
return changedSince(await resolveOutputs(args), before)
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
/** `ownOutputsSince` for root-anchored `cache.outputs.workspaceFiles` (A-43). */
|
|
686
|
+
export async function ownWorkspaceOutputsSince(
|
|
687
|
+
args: { workspaceRoot: string; outputs: string[] },
|
|
688
|
+
before: ReadonlyMap<string, OutputStamp>,
|
|
689
|
+
): Promise<string[]> {
|
|
690
|
+
return changedSince(await resolveWorkspaceOutputs(args), before)
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function changedSince(
|
|
694
|
+
after: readonly string[],
|
|
695
|
+
before: ReadonlyMap<string, OutputStamp>,
|
|
696
|
+
): string[] {
|
|
672
697
|
const own: string[] = []
|
|
673
698
|
for (const f of after) {
|
|
674
699
|
const was = before.get(f)
|
|
@@ -9,7 +9,9 @@ import {
|
|
|
9
9
|
cleanWorkspaceOutputs,
|
|
10
10
|
type OutputStamp,
|
|
11
11
|
ownOutputsSince,
|
|
12
|
+
ownWorkspaceOutputsSince,
|
|
12
13
|
stampOutputs,
|
|
14
|
+
stampWorkspaceOutputs,
|
|
13
15
|
FULL_CACHE_POLICY,
|
|
14
16
|
type GitFilesCache,
|
|
15
17
|
} from '../cache/index.js'
|
|
@@ -616,6 +618,7 @@ async function executeCachedTask(args: ExecuteArgs): Promise<TaskOutcome> {
|
|
|
616
618
|
// earlier run are its command's to clean, as they are under Turbo.
|
|
617
619
|
const additive = (node.addsToOutputsOf?.length ?? 0) > 0
|
|
618
620
|
let stampedBefore: ReadonlyMap<string, OutputStamp> | undefined
|
|
621
|
+
let wsStampedBefore: ReadonlyMap<string, OutputStamp> | undefined
|
|
619
622
|
|
|
620
623
|
// Cache lookup. On hit, time the user-perceived restore op
|
|
621
624
|
// (clean+restore+log-replay) — that's what the framed-block footer
|
|
@@ -756,7 +759,12 @@ async function executeCachedTask(args: ExecuteArgs): Promise<TaskOutcome> {
|
|
|
756
759
|
endClean()
|
|
757
760
|
args.gitFilesCache?.markOutputsChanged(node.projectDir, cleanedRels)
|
|
758
761
|
}
|
|
759
|
-
if (willWrite && !deferralRequested && wsOutputs.length > 0) {
|
|
762
|
+
if (additive && willWrite && !deferralRequested && wsOutputs.length > 0) {
|
|
763
|
+
// A root-anchored addition is stamped as the project one above: a
|
|
764
|
+
// glob clean deleted the upstream's files before this task, which
|
|
765
|
+
// reads them, ran (A-43).
|
|
766
|
+
wsStampedBefore ??= await stampWorkspaceOutputs(wsCleanArgs)
|
|
767
|
+
} else if (willWrite && !deferralRequested && wsOutputs.length > 0) {
|
|
760
768
|
// Root-anchored deletions can land in other projects' dirs; mark
|
|
761
769
|
// them so stale per-project git snapshots can't survive the wipe.
|
|
762
770
|
const cleanedWsRels = await cleanWorkspaceOutputs(wsCleanArgs)
|
|
@@ -1028,8 +1036,13 @@ async function executeCachedTask(args: ExecuteArgs): Promise<TaskOutcome> {
|
|
|
1028
1036
|
additive && stampedBefore !== undefined
|
|
1029
1037
|
? await ownOutputsSince(cleanArgs, stampedBefore)
|
|
1030
1038
|
: undefined
|
|
1039
|
+
const ownWsOutputFiles =
|
|
1040
|
+
additive && wsStampedBefore !== undefined
|
|
1041
|
+
? await ownWorkspaceOutputsSince(wsCleanArgs, wsStampedBefore)
|
|
1042
|
+
: undefined
|
|
1031
1043
|
const { landed } = await saveMiss({
|
|
1032
1044
|
...(ownOutputFiles !== undefined ? { ownOutputFiles } : {}),
|
|
1045
|
+
...(ownWsOutputFiles !== undefined ? { ownWsOutputFiles } : {}),
|
|
1033
1046
|
node,
|
|
1034
1047
|
hash,
|
|
1035
1048
|
cache,
|
|
@@ -71,6 +71,8 @@ export interface SaveMissArgs {
|
|
|
71
71
|
* would also take the upstream's files the task adds beside.
|
|
72
72
|
*/
|
|
73
73
|
ownOutputFiles?: string[] | undefined
|
|
74
|
+
/** `ownOutputFiles` for `cache.outputs.workspaceFiles` (A-43). */
|
|
75
|
+
ownWsOutputFiles?: string[] | undefined
|
|
74
76
|
/** The Tier-3 input fingerprint rows captured by the pre-exec describe. */
|
|
75
77
|
captured: readonly TaskInputComponent[]
|
|
76
78
|
command: string
|
|
@@ -101,10 +103,12 @@ export async function saveMiss(a: SaveMissArgs): Promise<{ landed: Promise<void>
|
|
|
101
103
|
outputs: a.outputs,
|
|
102
104
|
nestedProjectDirs: a.nestedProjectDirs,
|
|
103
105
|
}))
|
|
104
|
-
const wsOutputFiles =
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
106
|
+
const wsOutputFiles =
|
|
107
|
+
a.ownWsOutputFiles ??
|
|
108
|
+
(await resolveWorkspaceOutputs({
|
|
109
|
+
workspaceRoot: a.workspaceRoot,
|
|
110
|
+
outputs: a.wsOutputs,
|
|
111
|
+
}))
|
|
108
112
|
endResolve()
|
|
109
113
|
// The mirror of the input warning: declared outputs that resolve to
|
|
110
114
|
// nothing save an empty artifact, and the next hit "restores" it —
|
|
@@ -142,9 +142,11 @@ const MAX_CLOSURE_FILES = 32
|
|
|
142
142
|
// defeat it. `random` is denied as a word, not as `Math.random`: a
|
|
143
143
|
// destructured `const { random } = Math` was cached as pure (item 1036).
|
|
144
144
|
// `prompt`, `confirm` and `alert` read the user's terminal, and a cached
|
|
145
|
-
// evaluation replayed the first answer (D-25).
|
|
145
|
+
// evaluation replayed the first answer (D-25). A CommonJS config reaches
|
|
146
|
+
// `require` without naming it as `arguments[1]`, and one reading a file
|
|
147
|
+
// outside its closure so replayed the old bytes (D-36).
|
|
146
148
|
const IMPURE_RE =
|
|
147
|
-
/\b(?:process|Bun|globalThis|global|self|fetch|Date|Temporal|Intl|crypto|performance|navigator|require|eval|Function|constructor|localeCompare|await|toLocale\w*|Reflect|getPrototypeOf|setPrototypeOf|getOwnPropertyNames|getOwnPropertyDescriptor|getOwnPropertyDescriptors|__proto__|prototype|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|random|prompt|confirm|alert)\b|import\s*\.\s*meta|\bimport\s*\(/
|
|
149
|
+
/\b(?:process|Bun|globalThis|global|self|fetch|Date|Temporal|Intl|crypto|performance|navigator|require|eval|Function|constructor|localeCompare|await|toLocale\w*|Reflect|getPrototypeOf|setPrototypeOf|getOwnPropertyNames|getOwnPropertyDescriptor|getOwnPropertyDescriptors|__proto__|prototype|__defineGetter__|__defineSetter__|__lookupGetter__|__lookupSetter__|random|prompt|confirm|alert|arguments)\b|import\s*\.\s*meta|\bimport\s*\(/
|
|
148
150
|
|
|
149
151
|
/** Literal text that names a way to `Function` when used as a computed key. */
|
|
150
152
|
const IMPURE_LITERAL_RE = /constructor|__proto__|prototype/
|