@smthrs/engine-store 1.0.0-rc.6 → 1.0.0-rc.7
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/README.md +10 -10
- package/dist/cjs/StepBoundary.d.ts +8 -6
- package/dist/cjs/StepBoundary.d.ts.map +1 -1
- package/dist/cjs/StepBoundary.js +10 -7
- package/dist/cjs/StepBoundary.js.map +2 -2
- package/dist/esm/StepBoundary.d.ts +8 -6
- package/dist/esm/StepBoundary.d.ts.map +1 -1
- package/dist/esm/StepBoundary.js +17 -8
- package/dist/esm/StepBoundary.js.map +1 -1
- package/docs/api.md +19 -16
- package/package.json +18 -18
- package/src/StepBoundary.ts +29 -14
package/src/StepBoundary.ts
CHANGED
|
@@ -496,12 +496,14 @@ export interface FileSystemOptions {
|
|
|
496
496
|
*/
|
|
497
497
|
readonly maxTotalInlineBytes?: number | undefined
|
|
498
498
|
/**
|
|
499
|
-
* The workspace root
|
|
500
|
-
*
|
|
501
|
-
*
|
|
502
|
-
*
|
|
503
|
-
*
|
|
504
|
-
*
|
|
499
|
+
* The workspace root every declared path resolves against: `prepare` and
|
|
500
|
+
* `settle` measure under it, and cache replay confines its writes, removals,
|
|
501
|
+
* and prune walk to it. A filesystem already confined to a root (the
|
|
502
|
+
* kernel-guarded layer's service, or a `confined` view) keeps its own root
|
|
503
|
+
* and ignores this. Otherwise it defaults to the process working directory,
|
|
504
|
+
* the root a path-based host resolves a relative path against. {@link layer}
|
|
505
|
+
* passes the kernel `Workspace` root when one is in context, which is the
|
|
506
|
+
* root a step's own FileSystem resolves against (issue #3911).
|
|
505
507
|
*/
|
|
506
508
|
readonly root?: string | undefined
|
|
507
509
|
}
|
|
@@ -573,7 +575,16 @@ export const makeFileSystem = (
|
|
|
573
575
|
const digest = yield* Schema.decodeUnknownEffect(Sha256)(bytes).pipe(Effect.orDie)
|
|
574
576
|
return { digest, bytes } satisfies MeasuredDigest
|
|
575
577
|
})
|
|
576
|
-
|
|
578
|
+
// Declared paths are workspace-relative. A confined filesystem resolves them
|
|
579
|
+
// against its own root, but a path-based host resolves them against the
|
|
580
|
+
// process working directory, where a same-named file would answer the dirty
|
|
581
|
+
// check and let a stale declaration serve a cache hit (issue #3911). Such a
|
|
582
|
+
// host is handed each path resolved against the configured root; results
|
|
583
|
+
// stay keyed by the declared path.
|
|
584
|
+
const readRoot = KernelFileSystem.confinedRoot(fs) === undefined ? options.root : undefined
|
|
585
|
+
const hostPath = (path: string): string => readRoot === undefined ? path : platformPath.resolve(readRoot, path)
|
|
586
|
+
const enumeration: FileEnumeration.EnumerationOptions = readRoot === undefined ? {} : { resolve: hostPath }
|
|
587
|
+
const readDigest = (path: string) => readDigestFrom(fs, hostPath(path))
|
|
577
588
|
const batch = KernelFileSystem.batch(fs)
|
|
578
589
|
const measurements = Effect.fn("StepBoundary.measurements")(
|
|
579
590
|
function*(paths: ReadonlyArray<string>, content: boolean) {
|
|
@@ -594,7 +605,7 @@ export const makeFileSystem = (
|
|
|
594
605
|
const response = yield* batch.execute(
|
|
595
606
|
paths.slice(offset, offset + batch.maxSize).map((path) => ({
|
|
596
607
|
operation: "digest",
|
|
597
|
-
path,
|
|
608
|
+
path: hostPath(path),
|
|
598
609
|
content
|
|
599
610
|
}))
|
|
600
611
|
).pipe(Effect.mapError(hostFailure))
|
|
@@ -636,10 +647,14 @@ export const makeFileSystem = (
|
|
|
636
647
|
// workspace-relative expansion and let a tree replay delete dotfiles the
|
|
637
648
|
// producer wrote.
|
|
638
649
|
const expandGlob = Effect.fn("StepBoundary.expandGlob")(function*(glob: FileSet.Glob) {
|
|
639
|
-
return yield* FileEnumeration.expandGlob(fs, glob).pipe(Effect.mapError(hostFailure))
|
|
650
|
+
return yield* FileEnumeration.expandGlob(fs, glob, enumeration).pipe(Effect.mapError(hostFailure))
|
|
640
651
|
})
|
|
641
|
-
const treeEntries = Effect.fn("StepBoundary.treeEntries")(function*(
|
|
642
|
-
|
|
652
|
+
const treeEntries = Effect.fn("StepBoundary.treeEntries")(function*(
|
|
653
|
+
host: FileSystem.FileSystem,
|
|
654
|
+
path: string,
|
|
655
|
+
resolution: FileEnumeration.EnumerationOptions
|
|
656
|
+
) {
|
|
657
|
+
return yield* FileEnumeration.entriesUnder(host, path, resolution).pipe(Effect.mapError(hostFailure))
|
|
643
658
|
})
|
|
644
659
|
// Replay writes and deletes what evidence names, so the lexical check alone
|
|
645
660
|
// is not a boundary: a symlink planted on a lexically valid path would carry
|
|
@@ -647,7 +662,7 @@ export const makeFileSystem = (
|
|
|
647
662
|
// its prune walk go through a view pinned to the root, where each call is
|
|
648
663
|
// one descriptor-relative, no-follow request and a symlink anywhere on the
|
|
649
664
|
// path is refused rather than followed. `prepare` and `settle` only read,
|
|
650
|
-
// and keep the caller's filesystem
|
|
665
|
+
// and keep the caller's filesystem, rooted through `hostPath`.
|
|
651
666
|
const replayRoot = KernelFileSystem.confinedRoot(fs) ?? options.root ?? "."
|
|
652
667
|
const replayHost: Effect.Effect<FileSystem.FileSystem, UnsupportedBoundary> = KernelFileSystem.isConfinable(fs)
|
|
653
668
|
? KernelFileSystem.confined(fs, replayRoot).pipe(
|
|
@@ -849,7 +864,7 @@ export const makeFileSystem = (
|
|
|
849
864
|
if (typeof entry === "string") outputPaths.push(entry)
|
|
850
865
|
else if (entry._tag === "Glob") outputPaths.push(...yield* expandGlob(entry))
|
|
851
866
|
else {
|
|
852
|
-
const files = (yield* treeEntries(fs, entry.path)).files
|
|
867
|
+
const files = (yield* treeEntries(fs, entry.path, enumeration)).files
|
|
853
868
|
outputPaths.push(...files)
|
|
854
869
|
treeMembers.push({ path: entry.path, files })
|
|
855
870
|
}
|
|
@@ -1007,7 +1022,7 @@ export const makeFileSystem = (
|
|
|
1007
1022
|
.map((output) => output.path)
|
|
1008
1023
|
.filter((path) => path.startsWith(prefix))
|
|
1009
1024
|
)
|
|
1010
|
-
const entries = yield* treeEntries(host, tree.path)
|
|
1025
|
+
const entries = yield* treeEntries(host, tree.path, {})
|
|
1011
1026
|
for (const path of entries.files) {
|
|
1012
1027
|
if (!recorded.has(path)) yield* host.remove(path).pipe(Effect.mapError(hostFailure))
|
|
1013
1028
|
}
|