@smthrs/std 0.0.0-stage → 1.0.0-rc.12
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/CHANGELOG.md +148 -0
- package/LICENSE +21 -0
- package/README.md +156 -2
- package/dist/cjs/ApplyPatch.d.ts +174 -0
- package/dist/cjs/ApplyPatch.d.ts.map +1 -0
- package/dist/cjs/ApplyPatch.js +309 -0
- package/dist/cjs/ApplyPatch.js.map +7 -0
- package/dist/cjs/Bash.d.ts +390 -0
- package/dist/cjs/Bash.d.ts.map +1 -0
- package/dist/cjs/Bash.js +333 -0
- package/dist/cjs/Bash.js.map +7 -0
- package/dist/cjs/Checkpoints.d.ts +322 -0
- package/dist/cjs/Checkpoints.d.ts.map +1 -0
- package/dist/cjs/Checkpoints.js +233 -0
- package/dist/cjs/Checkpoints.js.map +7 -0
- package/dist/cjs/Container.d.ts +132 -0
- package/dist/cjs/Container.d.ts.map +1 -0
- package/dist/cjs/Container.js +113 -0
- package/dist/cjs/Container.js.map +7 -0
- package/dist/cjs/Edit.d.ts +203 -0
- package/dist/cjs/Edit.d.ts.map +1 -0
- package/dist/cjs/Edit.js +258 -0
- package/dist/cjs/Edit.js.map +7 -0
- package/dist/cjs/ExaWebSearch.d.ts +22 -0
- package/dist/cjs/ExaWebSearch.d.ts.map +1 -0
- package/dist/cjs/ExaWebSearch.js +138 -0
- package/dist/cjs/ExaWebSearch.js.map +7 -0
- package/dist/cjs/Explore.d.ts +328 -0
- package/dist/cjs/Explore.d.ts.map +1 -0
- package/dist/cjs/Explore.js +90 -0
- package/dist/cjs/Explore.js.map +7 -0
- package/dist/cjs/Fetch.d.ts +130 -0
- package/dist/cjs/Fetch.d.ts.map +1 -0
- package/dist/cjs/Fetch.js +64 -0
- package/dist/cjs/Fetch.js.map +7 -0
- package/dist/cjs/Glob.d.ts +204 -0
- package/dist/cjs/Glob.d.ts.map +1 -0
- package/dist/cjs/Glob.js +94 -0
- package/dist/cjs/Glob.js.map +7 -0
- package/dist/cjs/Grep.d.ts +347 -0
- package/dist/cjs/Grep.d.ts.map +1 -0
- package/dist/cjs/Grep.js +181 -0
- package/dist/cjs/Grep.js.map +7 -0
- package/dist/cjs/HttpPost.d.ts +130 -0
- package/dist/cjs/HttpPost.d.ts.map +1 -0
- package/dist/cjs/HttpPost.js +72 -0
- package/dist/cjs/HttpPost.js.map +7 -0
- package/dist/cjs/LanguageServer.d.ts +90 -0
- package/dist/cjs/LanguageServer.d.ts.map +1 -0
- package/dist/cjs/LanguageServer.js +60 -0
- package/dist/cjs/LanguageServer.js.map +7 -0
- package/dist/cjs/Ls.d.ts +164 -0
- package/dist/cjs/Ls.d.ts.map +1 -0
- package/dist/cjs/Ls.js +136 -0
- package/dist/cjs/Ls.js.map +7 -0
- package/dist/cjs/Lsp.d.ts +125 -0
- package/dist/cjs/Lsp.d.ts.map +1 -0
- package/dist/cjs/Lsp.js +137 -0
- package/dist/cjs/Lsp.js.map +7 -0
- package/dist/cjs/Manifest.d.ts +918 -0
- package/dist/cjs/Manifest.d.ts.map +1 -0
- package/dist/cjs/Manifest.js +144 -0
- package/dist/cjs/Manifest.js.map +7 -0
- package/dist/cjs/NativeSearch.d.ts +38 -0
- package/dist/cjs/NativeSearch.d.ts.map +1 -0
- package/dist/cjs/NativeSearch.js +326 -0
- package/dist/cjs/NativeSearch.js.map +7 -0
- package/dist/cjs/NodeLanguageServer.d.ts +128 -0
- package/dist/cjs/NodeLanguageServer.d.ts.map +1 -0
- package/dist/cjs/NodeLanguageServer.js +796 -0
- package/dist/cjs/NodeLanguageServer.js.map +7 -0
- package/dist/cjs/PortableSearch.d.ts +36 -0
- package/dist/cjs/PortableSearch.d.ts.map +1 -0
- package/dist/cjs/PortableSearch.js +240 -0
- package/dist/cjs/PortableSearch.js.map +7 -0
- package/dist/cjs/Probe.d.ts +193 -0
- package/dist/cjs/Probe.d.ts.map +1 -0
- package/dist/cjs/Probe.js +134 -0
- package/dist/cjs/Probe.js.map +7 -0
- package/dist/cjs/Read.d.ts +189 -0
- package/dist/cjs/Read.d.ts.map +1 -0
- package/dist/cjs/Read.js +223 -0
- package/dist/cjs/Read.js.map +7 -0
- package/dist/cjs/Relocate.d.ts +73 -0
- package/dist/cjs/Relocate.d.ts.map +1 -0
- package/dist/cjs/Relocate.js +72 -0
- package/dist/cjs/Relocate.js.map +7 -0
- package/dist/cjs/RemoteSearch.d.ts +54 -0
- package/dist/cjs/RemoteSearch.d.ts.map +1 -0
- package/dist/cjs/RemoteSearch.js +134 -0
- package/dist/cjs/RemoteSearch.js.map +7 -0
- package/dist/cjs/Search.d.ts +163 -0
- package/dist/cjs/Search.d.ts.map +1 -0
- package/dist/cjs/Search.js +51 -0
- package/dist/cjs/Search.js.map +7 -0
- package/dist/cjs/SearchConformance.d.ts +115 -0
- package/dist/cjs/SearchConformance.d.ts.map +1 -0
- package/dist/cjs/SearchConformance.js +172 -0
- package/dist/cjs/SearchConformance.js.map +7 -0
- package/dist/cjs/SearchContract.d.ts +114 -0
- package/dist/cjs/SearchContract.d.ts.map +1 -0
- package/dist/cjs/SearchContract.js +339 -0
- package/dist/cjs/SearchContract.js.map +7 -0
- package/dist/cjs/ShellCommand.d.ts +164 -0
- package/dist/cjs/ShellCommand.d.ts.map +1 -0
- package/dist/cjs/ShellCommand.js +102 -0
- package/dist/cjs/ShellCommand.js.map +7 -0
- package/dist/cjs/StdError.d.ts +55 -0
- package/dist/cjs/StdError.d.ts.map +1 -0
- package/dist/cjs/StdError.js +74 -0
- package/dist/cjs/StdError.js.map +7 -0
- package/dist/cjs/TestRun.d.ts +311 -0
- package/dist/cjs/TestRun.d.ts.map +1 -0
- package/dist/cjs/TestRun.js +228 -0
- package/dist/cjs/TestRun.js.map +7 -0
- package/dist/cjs/TestRunner.d.ts +102 -0
- package/dist/cjs/TestRunner.d.ts.map +1 -0
- package/dist/cjs/TestRunner.js +54 -0
- package/dist/cjs/TestRunner.js.map +7 -0
- package/dist/cjs/TreeFingerprint.d.ts +140 -0
- package/dist/cjs/TreeFingerprint.d.ts.map +1 -0
- package/dist/cjs/TreeFingerprint.js +87 -0
- package/dist/cjs/TreeFingerprint.js.map +7 -0
- package/dist/cjs/UpdatePlan.d.ts +152 -0
- package/dist/cjs/UpdatePlan.d.ts.map +1 -0
- package/dist/cjs/UpdatePlan.js +87 -0
- package/dist/cjs/UpdatePlan.js.map +7 -0
- package/dist/cjs/WebFetch.d.ts +134 -0
- package/dist/cjs/WebFetch.d.ts.map +1 -0
- package/dist/cjs/WebFetch.js +140 -0
- package/dist/cjs/WebFetch.js.map +7 -0
- package/dist/cjs/WebSearch.d.ts +181 -0
- package/dist/cjs/WebSearch.d.ts.map +1 -0
- package/dist/cjs/WebSearch.js +86 -0
- package/dist/cjs/WebSearch.js.map +7 -0
- package/dist/cjs/Write.d.ts +147 -0
- package/dist/cjs/Write.d.ts.map +1 -0
- package/dist/cjs/Write.js +122 -0
- package/dist/cjs/Write.js.map +7 -0
- package/dist/cjs/index.d.ts +129 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +101 -0
- package/dist/cjs/index.js.map +7 -0
- package/dist/cjs/internal/ApplyPatch.d.ts +145 -0
- package/dist/cjs/internal/ApplyPatch.d.ts.map +1 -0
- package/dist/cjs/internal/ApplyPatch.js +462 -0
- package/dist/cjs/internal/ApplyPatch.js.map +7 -0
- package/dist/cjs/internal/CodexText.d.ts +73 -0
- package/dist/cjs/internal/CodexText.d.ts.map +1 -0
- package/dist/cjs/internal/CodexText.js +108 -0
- package/dist/cjs/internal/CodexText.js.map +7 -0
- package/dist/cjs/internal/Declaration.d.ts +49 -0
- package/dist/cjs/internal/Declaration.d.ts.map +1 -0
- package/dist/cjs/internal/Declaration.js +46 -0
- package/dist/cjs/internal/Declaration.js.map +7 -0
- package/dist/cjs/internal/Diagnostics.d.ts +77 -0
- package/dist/cjs/internal/Diagnostics.d.ts.map +1 -0
- package/dist/cjs/internal/Diagnostics.js +89 -0
- package/dist/cjs/internal/Diagnostics.js.map +7 -0
- package/dist/cjs/internal/EnvelopePrecheck.d.ts +69 -0
- package/dist/cjs/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/cjs/internal/EnvelopePrecheck.js +323 -0
- package/dist/cjs/internal/EnvelopePrecheck.js.map +7 -0
- package/dist/cjs/internal/Exec.d.ts +151 -0
- package/dist/cjs/internal/Exec.d.ts.map +1 -0
- package/dist/cjs/internal/Exec.js +207 -0
- package/dist/cjs/internal/Exec.js.map +7 -0
- package/dist/cjs/internal/FileMutation.d.ts +109 -0
- package/dist/cjs/internal/FileMutation.d.ts.map +1 -0
- package/dist/cjs/internal/FileMutation.js +116 -0
- package/dist/cjs/internal/FileMutation.js.map +7 -0
- package/dist/cjs/internal/FsFailure.d.ts +38 -0
- package/dist/cjs/internal/FsFailure.d.ts.map +1 -0
- package/dist/cjs/internal/FsFailure.js +40 -0
- package/dist/cjs/internal/FsFailure.js.map +7 -0
- package/dist/cjs/internal/GitWorktree.d.ts +108 -0
- package/dist/cjs/internal/GitWorktree.d.ts.map +1 -0
- package/dist/cjs/internal/GitWorktree.js +276 -0
- package/dist/cjs/internal/GitWorktree.js.map +7 -0
- package/dist/cjs/internal/Grouping.d.ts +51 -0
- package/dist/cjs/internal/Grouping.d.ts.map +1 -0
- package/dist/cjs/internal/Grouping.js +83 -0
- package/dist/cjs/internal/Grouping.js.map +7 -0
- package/dist/cjs/internal/Html.d.ts +20 -0
- package/dist/cjs/internal/Html.d.ts.map +1 -0
- package/dist/cjs/internal/Html.js +81 -0
- package/dist/cjs/internal/Html.js.map +7 -0
- package/dist/cjs/internal/Http.d.ts +95 -0
- package/dist/cjs/internal/Http.d.ts.map +1 -0
- package/dist/cjs/internal/Http.js +153 -0
- package/dist/cjs/internal/Http.js.map +7 -0
- package/dist/cjs/internal/HttpNetwork.d.ts +27 -0
- package/dist/cjs/internal/HttpNetwork.d.ts.map +1 -0
- package/dist/cjs/internal/HttpNetwork.js +146 -0
- package/dist/cjs/internal/HttpNetwork.js.map +7 -0
- package/dist/cjs/internal/Ignore.d.ts +37 -0
- package/dist/cjs/internal/Ignore.d.ts.map +1 -0
- package/dist/cjs/internal/Ignore.js +100 -0
- package/dist/cjs/internal/Ignore.js.map +7 -0
- package/dist/cjs/internal/LinearRegex.d.ts +19 -0
- package/dist/cjs/internal/LinearRegex.d.ts.map +1 -0
- package/dist/cjs/internal/LinearRegex.js +166 -0
- package/dist/cjs/internal/LinearRegex.js.map +7 -0
- package/dist/cjs/internal/Match.d.ts +85 -0
- package/dist/cjs/internal/Match.d.ts.map +1 -0
- package/dist/cjs/internal/Match.js +99 -0
- package/dist/cjs/internal/Match.js.map +7 -0
- package/dist/cjs/internal/Paths.d.ts +23 -0
- package/dist/cjs/internal/Paths.d.ts.map +1 -0
- package/dist/cjs/internal/Paths.js +52 -0
- package/dist/cjs/internal/Paths.js.map +7 -0
- package/dist/cjs/internal/Preserve.d.ts +25 -0
- package/dist/cjs/internal/Preserve.d.ts.map +1 -0
- package/dist/cjs/internal/Preserve.js +88 -0
- package/dist/cjs/internal/Preserve.js.map +7 -0
- package/dist/cjs/internal/Prune.d.ts +35 -0
- package/dist/cjs/internal/Prune.d.ts.map +1 -0
- package/dist/cjs/internal/Prune.js +54 -0
- package/dist/cjs/internal/Prune.js.map +7 -0
- package/dist/cjs/internal/RemoteTree.d.ts +60 -0
- package/dist/cjs/internal/RemoteTree.d.ts.map +1 -0
- package/dist/cjs/internal/RemoteTree.js +123 -0
- package/dist/cjs/internal/RemoteTree.js.map +7 -0
- package/dist/cjs/internal/SearchContract.d.ts +63 -0
- package/dist/cjs/internal/SearchContract.d.ts.map +1 -0
- package/dist/cjs/internal/SearchContract.js +46 -0
- package/dist/cjs/internal/SearchContract.js.map +7 -0
- package/dist/cjs/internal/Symbols.d.ts +39 -0
- package/dist/cjs/internal/Symbols.d.ts.map +1 -0
- package/dist/cjs/internal/Symbols.js +59 -0
- package/dist/cjs/internal/Symbols.js.map +7 -0
- package/dist/cjs/internal/Tar.d.ts +23 -0
- package/dist/cjs/internal/Tar.d.ts.map +1 -0
- package/dist/cjs/internal/Tar.js +86 -0
- package/dist/cjs/internal/Tar.js.map +7 -0
- package/dist/cjs/internal/TestReport.d.ts +52 -0
- package/dist/cjs/internal/TestReport.d.ts.map +1 -0
- package/dist/cjs/internal/TestReport.js +131 -0
- package/dist/cjs/internal/TestReport.js.map +7 -0
- package/dist/cjs/internal/Text.d.ts +125 -0
- package/dist/cjs/internal/Text.d.ts.map +1 -0
- package/dist/cjs/internal/Text.js +85 -0
- package/dist/cjs/internal/Text.js.map +7 -0
- package/dist/cjs/internal/Url.d.ts +13 -0
- package/dist/cjs/internal/Url.d.ts.map +1 -0
- package/dist/cjs/internal/Url.js +35 -0
- package/dist/cjs/internal/Url.js.map +7 -0
- package/dist/cjs/internal/Walk.d.ts +72 -0
- package/dist/cjs/internal/Walk.d.ts.map +1 -0
- package/dist/cjs/internal/Walk.js +108 -0
- package/dist/cjs/internal/Walk.js.map +7 -0
- package/dist/cjs/package.json +1 -0
- package/dist/esm/ApplyPatch.d.ts +174 -0
- package/dist/esm/ApplyPatch.d.ts.map +1 -0
- package/dist/esm/ApplyPatch.js +346 -0
- package/dist/esm/ApplyPatch.js.map +1 -0
- package/dist/esm/Bash.d.ts +390 -0
- package/dist/esm/Bash.d.ts.map +1 -0
- package/dist/esm/Bash.js +514 -0
- package/dist/esm/Bash.js.map +1 -0
- package/dist/esm/Checkpoints.d.ts +322 -0
- package/dist/esm/Checkpoints.d.ts.map +1 -0
- package/dist/esm/Checkpoints.js +396 -0
- package/dist/esm/Checkpoints.js.map +1 -0
- package/dist/esm/Container.d.ts +132 -0
- package/dist/esm/Container.d.ts.map +1 -0
- package/dist/esm/Container.js +151 -0
- package/dist/esm/Container.js.map +1 -0
- package/dist/esm/Edit.d.ts +203 -0
- package/dist/esm/Edit.d.ts.map +1 -0
- package/dist/esm/Edit.js +296 -0
- package/dist/esm/Edit.js.map +1 -0
- package/dist/esm/ExaWebSearch.d.ts +22 -0
- package/dist/esm/ExaWebSearch.d.ts.map +1 -0
- package/dist/esm/ExaWebSearch.js +107 -0
- package/dist/esm/ExaWebSearch.js.map +1 -0
- package/dist/esm/Explore.d.ts +328 -0
- package/dist/esm/Explore.d.ts.map +1 -0
- package/dist/esm/Explore.js +106 -0
- package/dist/esm/Explore.js.map +1 -0
- package/dist/esm/Fetch.d.ts +130 -0
- package/dist/esm/Fetch.d.ts.map +1 -0
- package/dist/esm/Fetch.js +91 -0
- package/dist/esm/Fetch.js.map +1 -0
- package/dist/esm/Glob.d.ts +204 -0
- package/dist/esm/Glob.d.ts.map +1 -0
- package/dist/esm/Glob.js +177 -0
- package/dist/esm/Glob.js.map +1 -0
- package/dist/esm/Grep.d.ts +347 -0
- package/dist/esm/Grep.d.ts.map +1 -0
- package/dist/esm/Grep.js +289 -0
- package/dist/esm/Grep.js.map +1 -0
- package/dist/esm/HttpPost.d.ts +130 -0
- package/dist/esm/HttpPost.d.ts.map +1 -0
- package/dist/esm/HttpPost.js +89 -0
- package/dist/esm/HttpPost.js.map +1 -0
- package/dist/esm/LanguageServer.d.ts +90 -0
- package/dist/esm/LanguageServer.d.ts.map +1 -0
- package/dist/esm/LanguageServer.js +57 -0
- package/dist/esm/LanguageServer.js.map +1 -0
- package/dist/esm/Ls.d.ts +164 -0
- package/dist/esm/Ls.d.ts.map +1 -0
- package/dist/esm/Ls.js +178 -0
- package/dist/esm/Ls.js.map +1 -0
- package/dist/esm/Lsp.d.ts +125 -0
- package/dist/esm/Lsp.d.ts.map +1 -0
- package/dist/esm/Lsp.js +165 -0
- package/dist/esm/Lsp.js.map +1 -0
- package/dist/esm/Manifest.d.ts +918 -0
- package/dist/esm/Manifest.d.ts.map +1 -0
- package/dist/esm/Manifest.js +153 -0
- package/dist/esm/Manifest.js.map +1 -0
- package/dist/esm/NativeSearch.d.ts +38 -0
- package/dist/esm/NativeSearch.d.ts.map +1 -0
- package/dist/esm/NativeSearch.js +378 -0
- package/dist/esm/NativeSearch.js.map +1 -0
- package/dist/esm/NodeLanguageServer.d.ts +128 -0
- package/dist/esm/NodeLanguageServer.d.ts.map +1 -0
- package/dist/esm/NodeLanguageServer.js +843 -0
- package/dist/esm/NodeLanguageServer.js.map +1 -0
- package/dist/esm/PortableSearch.d.ts +36 -0
- package/dist/esm/PortableSearch.d.ts.map +1 -0
- package/dist/esm/PortableSearch.js +256 -0
- package/dist/esm/PortableSearch.js.map +1 -0
- package/dist/esm/Probe.d.ts +193 -0
- package/dist/esm/Probe.d.ts.map +1 -0
- package/dist/esm/Probe.js +225 -0
- package/dist/esm/Probe.js.map +1 -0
- package/dist/esm/Read.d.ts +189 -0
- package/dist/esm/Read.d.ts.map +1 -0
- package/dist/esm/Read.js +300 -0
- package/dist/esm/Read.js.map +1 -0
- package/dist/esm/Relocate.d.ts +73 -0
- package/dist/esm/Relocate.d.ts.map +1 -0
- package/dist/esm/Relocate.js +153 -0
- package/dist/esm/Relocate.js.map +1 -0
- package/dist/esm/RemoteSearch.d.ts +54 -0
- package/dist/esm/RemoteSearch.d.ts.map +1 -0
- package/dist/esm/RemoteSearch.js +162 -0
- package/dist/esm/RemoteSearch.js.map +1 -0
- package/dist/esm/Search.d.ts +163 -0
- package/dist/esm/Search.d.ts.map +1 -0
- package/dist/esm/Search.js +47 -0
- package/dist/esm/Search.js.map +1 -0
- package/dist/esm/SearchConformance.d.ts +115 -0
- package/dist/esm/SearchConformance.d.ts.map +1 -0
- package/dist/esm/SearchConformance.js +193 -0
- package/dist/esm/SearchConformance.js.map +1 -0
- package/dist/esm/SearchContract.d.ts +114 -0
- package/dist/esm/SearchContract.d.ts.map +1 -0
- package/dist/esm/SearchContract.js +461 -0
- package/dist/esm/SearchContract.js.map +1 -0
- package/dist/esm/ShellCommand.d.ts +164 -0
- package/dist/esm/ShellCommand.d.ts.map +1 -0
- package/dist/esm/ShellCommand.js +159 -0
- package/dist/esm/ShellCommand.js.map +1 -0
- package/dist/esm/StdError.d.ts +55 -0
- package/dist/esm/StdError.d.ts.map +1 -0
- package/dist/esm/StdError.js +71 -0
- package/dist/esm/StdError.js.map +1 -0
- package/dist/esm/TestRun.d.ts +311 -0
- package/dist/esm/TestRun.d.ts.map +1 -0
- package/dist/esm/TestRun.js +316 -0
- package/dist/esm/TestRun.js.map +1 -0
- package/dist/esm/TestRunner.d.ts +102 -0
- package/dist/esm/TestRunner.d.ts.map +1 -0
- package/dist/esm/TestRunner.js +68 -0
- package/dist/esm/TestRunner.js.map +1 -0
- package/dist/esm/TreeFingerprint.d.ts +140 -0
- package/dist/esm/TreeFingerprint.d.ts.map +1 -0
- package/dist/esm/TreeFingerprint.js +170 -0
- package/dist/esm/TreeFingerprint.js.map +1 -0
- package/dist/esm/UpdatePlan.d.ts +152 -0
- package/dist/esm/UpdatePlan.d.ts.map +1 -0
- package/dist/esm/UpdatePlan.js +129 -0
- package/dist/esm/UpdatePlan.js.map +1 -0
- package/dist/esm/WebFetch.d.ts +134 -0
- package/dist/esm/WebFetch.d.ts.map +1 -0
- package/dist/esm/WebFetch.js +151 -0
- package/dist/esm/WebFetch.js.map +1 -0
- package/dist/esm/WebSearch.d.ts +181 -0
- package/dist/esm/WebSearch.d.ts.map +1 -0
- package/dist/esm/WebSearch.js +134 -0
- package/dist/esm/WebSearch.js.map +1 -0
- package/dist/esm/Write.d.ts +147 -0
- package/dist/esm/Write.d.ts.map +1 -0
- package/dist/esm/Write.js +144 -0
- package/dist/esm/Write.js.map +1 -0
- package/dist/esm/index.d.ts +129 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +129 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/ApplyPatch.d.ts +145 -0
- package/dist/esm/internal/ApplyPatch.d.ts.map +1 -0
- package/dist/esm/internal/ApplyPatch.js +489 -0
- package/dist/esm/internal/ApplyPatch.js.map +1 -0
- package/dist/esm/internal/CodexText.d.ts +73 -0
- package/dist/esm/internal/CodexText.d.ts.map +1 -0
- package/dist/esm/internal/CodexText.js +156 -0
- package/dist/esm/internal/CodexText.js.map +1 -0
- package/dist/esm/internal/Declaration.d.ts +49 -0
- package/dist/esm/internal/Declaration.d.ts.map +1 -0
- package/dist/esm/internal/Declaration.js +42 -0
- package/dist/esm/internal/Declaration.js.map +1 -0
- package/dist/esm/internal/Diagnostics.d.ts +77 -0
- package/dist/esm/internal/Diagnostics.d.ts.map +1 -0
- package/dist/esm/internal/Diagnostics.js +99 -0
- package/dist/esm/internal/Diagnostics.js.map +1 -0
- package/dist/esm/internal/EnvelopePrecheck.d.ts +69 -0
- package/dist/esm/internal/EnvelopePrecheck.d.ts.map +1 -0
- package/dist/esm/internal/EnvelopePrecheck.js +426 -0
- package/dist/esm/internal/EnvelopePrecheck.js.map +1 -0
- package/dist/esm/internal/Exec.d.ts +151 -0
- package/dist/esm/internal/Exec.d.ts.map +1 -0
- package/dist/esm/internal/Exec.js +285 -0
- package/dist/esm/internal/Exec.js.map +1 -0
- package/dist/esm/internal/FileMutation.d.ts +109 -0
- package/dist/esm/internal/FileMutation.d.ts.map +1 -0
- package/dist/esm/internal/FileMutation.js +123 -0
- package/dist/esm/internal/FileMutation.js.map +1 -0
- package/dist/esm/internal/FsFailure.d.ts +38 -0
- package/dist/esm/internal/FsFailure.d.ts.map +1 -0
- package/dist/esm/internal/FsFailure.js +39 -0
- package/dist/esm/internal/FsFailure.js.map +1 -0
- package/dist/esm/internal/GitWorktree.d.ts +108 -0
- package/dist/esm/internal/GitWorktree.d.ts.map +1 -0
- package/dist/esm/internal/GitWorktree.js +352 -0
- package/dist/esm/internal/GitWorktree.js.map +1 -0
- package/dist/esm/internal/Grouping.d.ts +51 -0
- package/dist/esm/internal/Grouping.d.ts.map +1 -0
- package/dist/esm/internal/Grouping.js +99 -0
- package/dist/esm/internal/Grouping.js.map +1 -0
- package/dist/esm/internal/Html.d.ts +20 -0
- package/dist/esm/internal/Html.d.ts.map +1 -0
- package/dist/esm/internal/Html.js +70 -0
- package/dist/esm/internal/Html.js.map +1 -0
- package/dist/esm/internal/Http.d.ts +95 -0
- package/dist/esm/internal/Http.d.ts.map +1 -0
- package/dist/esm/internal/Http.js +154 -0
- package/dist/esm/internal/Http.js.map +1 -0
- package/dist/esm/internal/HttpNetwork.d.ts +27 -0
- package/dist/esm/internal/HttpNetwork.d.ts.map +1 -0
- package/dist/esm/internal/HttpNetwork.js +114 -0
- package/dist/esm/internal/HttpNetwork.js.map +1 -0
- package/dist/esm/internal/Ignore.d.ts +37 -0
- package/dist/esm/internal/Ignore.d.ts.map +1 -0
- package/dist/esm/internal/Ignore.js +128 -0
- package/dist/esm/internal/Ignore.js.map +1 -0
- package/dist/esm/internal/LinearRegex.d.ts +19 -0
- package/dist/esm/internal/LinearRegex.d.ts.map +1 -0
- package/dist/esm/internal/LinearRegex.js +176 -0
- package/dist/esm/internal/LinearRegex.js.map +1 -0
- package/dist/esm/internal/Match.d.ts +85 -0
- package/dist/esm/internal/Match.d.ts.map +1 -0
- package/dist/esm/internal/Match.js +142 -0
- package/dist/esm/internal/Match.js.map +1 -0
- package/dist/esm/internal/Paths.d.ts +23 -0
- package/dist/esm/internal/Paths.d.ts.map +1 -0
- package/dist/esm/internal/Paths.js +40 -0
- package/dist/esm/internal/Paths.js.map +1 -0
- package/dist/esm/internal/Preserve.d.ts +25 -0
- package/dist/esm/internal/Preserve.d.ts.map +1 -0
- package/dist/esm/internal/Preserve.js +70 -0
- package/dist/esm/internal/Preserve.js.map +1 -0
- package/dist/esm/internal/Prune.d.ts +35 -0
- package/dist/esm/internal/Prune.d.ts.map +1 -0
- package/dist/esm/internal/Prune.js +60 -0
- package/dist/esm/internal/Prune.js.map +1 -0
- package/dist/esm/internal/RemoteTree.d.ts +60 -0
- package/dist/esm/internal/RemoteTree.d.ts.map +1 -0
- package/dist/esm/internal/RemoteTree.js +132 -0
- package/dist/esm/internal/RemoteTree.js.map +1 -0
- package/dist/esm/internal/SearchContract.d.ts +63 -0
- package/dist/esm/internal/SearchContract.d.ts.map +1 -0
- package/dist/esm/internal/SearchContract.js +66 -0
- package/dist/esm/internal/SearchContract.js.map +1 -0
- package/dist/esm/internal/Symbols.d.ts +39 -0
- package/dist/esm/internal/Symbols.d.ts.map +1 -0
- package/dist/esm/internal/Symbols.js +79 -0
- package/dist/esm/internal/Symbols.js.map +1 -0
- package/dist/esm/internal/Tar.d.ts +23 -0
- package/dist/esm/internal/Tar.d.ts.map +1 -0
- package/dist/esm/internal/Tar.js +97 -0
- package/dist/esm/internal/Tar.js.map +1 -0
- package/dist/esm/internal/TestReport.d.ts +52 -0
- package/dist/esm/internal/TestReport.d.ts.map +1 -0
- package/dist/esm/internal/TestReport.js +172 -0
- package/dist/esm/internal/TestReport.js.map +1 -0
- package/dist/esm/internal/Text.d.ts +125 -0
- package/dist/esm/internal/Text.d.ts.map +1 -0
- package/dist/esm/internal/Text.js +141 -0
- package/dist/esm/internal/Text.js.map +1 -0
- package/dist/esm/internal/Url.d.ts +13 -0
- package/dist/esm/internal/Url.d.ts.map +1 -0
- package/dist/esm/internal/Url.js +27 -0
- package/dist/esm/internal/Url.js.map +1 -0
- package/dist/esm/internal/Walk.d.ts +72 -0
- package/dist/esm/internal/Walk.d.ts.map +1 -0
- package/dist/esm/internal/Walk.js +126 -0
- package/dist/esm/internal/Walk.js.map +1 -0
- package/docs/README.md +119 -0
- package/docs/api.md +499 -0
- package/docs/concepts/effects-and-capabilities.md +138 -0
- package/docs/concepts/flows-and-handlers.md +115 -0
- package/docs/concepts/limits-and-disclosure.md +105 -0
- package/docs/concepts/search-contract.md +182 -0
- package/docs/guides/bind-the-standard-flows.md +116 -0
- package/docs/guides/implement-a-search-peer.md +133 -0
- package/docs/guides/pin-a-checkpoint.md +161 -0
- package/docs/guides/query-a-language-server.md +257 -0
- package/docs/guides/reach-the-network.md +141 -0
- package/docs/guides/read-and-edit-a-file.md +240 -0
- package/docs/guides/run-a-shell-command.md +236 -0
- package/docs/guides/run-the-test-suite.md +154 -0
- package/docs/guides/search-a-workspace.md +148 -0
- package/docs/installation.md +115 -0
- package/docs/quickstart.md +125 -0
- package/docs/reference/flows.md +556 -0
- package/docs/troubleshooting.md +347 -0
- package/package.json +449 -3
- package/src/ApplyPatch.ts +458 -0
- package/src/Bash.ts +619 -0
- package/src/Checkpoints.ts +589 -0
- package/src/Container.ts +212 -0
- package/src/Edit.ts +366 -0
- package/src/ExaWebSearch.ts +145 -0
- package/src/Explore.ts +139 -0
- package/src/Fetch.ts +117 -0
- package/src/Glob.ts +200 -0
- package/src/Grep.ts +320 -0
- package/src/HttpPost.ts +120 -0
- package/src/LanguageServer.ts +110 -0
- package/src/Ls.ts +228 -0
- package/src/Lsp.ts +184 -0
- package/src/Manifest.ts +162 -0
- package/src/NativeSearch.ts +457 -0
- package/src/NodeLanguageServer.ts +1148 -0
- package/src/PortableSearch.ts +284 -0
- package/src/Probe.ts +284 -0
- package/src/Read.ts +359 -0
- package/src/Relocate.ts +166 -0
- package/src/RemoteSearch.ts +199 -0
- package/src/Search.ts +185 -0
- package/src/SearchConformance.ts +288 -0
- package/src/SearchContract.ts +489 -0
- package/src/ShellCommand.ts +201 -0
- package/src/StdError.ts +80 -0
- package/src/TestRun.ts +401 -0
- package/src/TestRunner.ts +119 -0
- package/src/TreeFingerprint.ts +200 -0
- package/src/UpdatePlan.ts +171 -0
- package/src/WebFetch.ts +194 -0
- package/src/WebSearch.ts +165 -0
- package/src/Write.ts +195 -0
- package/src/index.ts +157 -0
- package/src/internal/ApplyPatch.ts +601 -0
- package/src/internal/CodexText.ts +182 -0
- package/src/internal/Declaration.ts +60 -0
- package/src/internal/Diagnostics.ts +134 -0
- package/src/internal/EnvelopePrecheck.ts +489 -0
- package/src/internal/Exec.ts +427 -0
- package/src/internal/FileMutation.ts +231 -0
- package/src/internal/FsFailure.ts +51 -0
- package/src/internal/GitWorktree.ts +491 -0
- package/src/internal/Grouping.ts +106 -0
- package/src/internal/Html.ts +87 -0
- package/src/internal/Http.ts +209 -0
- package/src/internal/HttpNetwork.ts +153 -0
- package/src/internal/Ignore.ts +135 -0
- package/src/internal/LinearRegex.ts +173 -0
- package/src/internal/Match.ts +172 -0
- package/src/internal/Paths.ts +42 -0
- package/src/internal/Preserve.ts +108 -0
- package/src/internal/Prune.ts +62 -0
- package/src/internal/RemoteTree.ts +159 -0
- package/src/internal/SearchContract.ts +77 -0
- package/src/internal/Symbols.ts +88 -0
- package/src/internal/Tar.ts +95 -0
- package/src/internal/TestReport.ts +194 -0
- package/src/internal/Text.ts +185 -0
- package/src/internal/Url.ts +23 -0
- package/src/internal/Walk.ts +176 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/RemoteSearch.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The search contract for a tree on another machine, in two round trips.\n *\n * `PortableSearch` asks `FileSystem` one question per directory, per entry\n * and per file. On a machine reached through a transport, such as a\n * benchmark's task container behind `docker exec`, every question is a\n * process start, so one `grep` over a 6,000-file repository is some 20,000 of\n * them. This peer asks the machine's own shell twice instead. `find` lists\n * the tree under the root, leaving out the directories every walk skips, and\n * `tar` returns its `.gitignore` files with the listing. The in-process peer\n * then decides which files the search reads, a second `tar` returns exactly\n * those, and `PortableSearch` answers over that copy. Every result, notice,\n * and refusal is therefore the in-process peer's own: this module decides\n * only where the bytes come from.\n *\n * It runs through the machine's own `ChildProcessSpawner`, the one\n * `Sandbox.hostContext` serves beside the machine's `FileSystem`. The machine\n * needs `sh`, `find`, `xargs`, `tar`, `head`, and `base64`; GNU, BusyBox, and\n * BSD userlands all have them. Output crosses as base64, so a transport whose\n * channel carries only text returns it intact. A search reads at most\n * {@link maxBytes} of file content and refuses beyond that, naming the root\n * to narrow.\n *\n * @since 1.0.0-rc.8\n */\n\nimport type * as ChildProcessSpawner from \"@smthrs/kernel/ChildProcessSpawner\"\nimport * as Path from \"@smthrs/kernel/Path\"\nimport { Context, Effect } from \"effect\"\nimport * as Base64 from \"effect/encoding/Base64\"\nimport * as FileSystem from \"effect/FileSystem\"\nimport * as Result from \"effect/Result\"\nimport * as Exec from \"./internal/Exec.ts\"\nimport * as Prune from \"./internal/Prune.ts\"\nimport * as RemoteTree from \"./internal/RemoteTree.ts\"\nimport * as Tar from \"./internal/Tar.ts\"\nimport * as PortableSearch from \"./PortableSearch.ts\"\nimport * as Search from \"./Search.ts\"\nimport * as StdError from \"./StdError.ts\"\n\n/**\n * The most file content one search brings back from the machine.\n *\n * The copy is held in memory while the in-process peer reads it, so the\n * bound is on this process's memory rather than on the search: a root that\n * holds more is refused with `response_too_large` and a narrower root or\n * globs answer it.\n *\n * @category constants\n * @since 1.0.0-rc.8\n */\nexport const maxBytes = 256 * 1024 * 1024\n\n/** The most a listing, with its `.gitignore` files, may take. */\nconst maxListingBytes = 64 * 1024 * 1024\n\nconst quoted = (value: string): string => `'${value.replaceAll(\"'\", `'\\\\''`)}'`\n\nconst pruned = `\\\\( ${Prune.repositoryDirectories.map((name) => `-name ${quoted(name)}`).join(\" -o \")} \\\\) -prune`\n\n/** The refusal for a machine without one of the tools a search runs. */\nconst missing = (tool: string) => `searching this machine needs ${tool}, which it does not have`\n\nconst requireTools = `for t in find xargs tar head; do command -v \"$t\" >/dev/null || { ` +\n `echo \"${missing(\"$t\")}\" >&2; exit 3; }; done`\n\n/**\n * `$1` is the root, `$2` the byte bound, and `$3` is `1` to send the\n * `.gitignore` files after the listing. Records are NUL-terminated `<kind><path>`;\n * an `E` record ends the listing, and a tar stream of the ignore files follows.\n */\nconst listing = [\n \"set -f\",\n requireTools,\n \"r=$1\",\n \"{\",\n \" if [ -d \\\"$r\\\" ]; then if [ -r \\\"$r\\\" ] && [ -x \\\"$r\\\" ]; then printf 'd%s\\\\0' \\\"$r\\\"; else printf 'u%s\\\\0' \\\"$r\\\"; fi\",\n \" elif [ -f \\\"$r\\\" ]; then printf 'f%s\\\\0' \\\"$r\\\"\",\n \" elif [ -e \\\"$r\\\" ]; then printf 'o%s\\\\0' \\\"$r\\\"\",\n \" fi\",\n // No `-exec \u2026 {} +` inside parentheses: BusyBox `find` never runs one there.\n ` find -H \"$r\" -mindepth 1 ${pruned} -o -type d -exec printf 'd%s\\\\0' {} + ` +\n `-o -type f -exec printf 'f%s\\\\0' {} + ` +\n `-o -type l -exec sh -c 'for p do if [ -d \"$p\" ]; then k=D; elif [ -f \"$p\" ]; then k=F; else k=L; fi; ` +\n `printf \"%s%s\\\\0\" \"$k\" \"$p\"; done' sh {} + -o -exec printf 'o%s\\\\0' {} + 2>/dev/null`,\n \" printf 'E\\\\0'\",\n ` if [ \"$3\" = 1 ]; then find -H \"$r\" -mindepth 1 ${pruned} -o -type f -name .gitignore -print0 2>/dev/null | ` +\n \"(cd / && COPYFILE_DISABLE=1 xargs -0 -r tar -cf - -- 2>/dev/null); fi\",\n \"} | head -c \\\"$2\\\" | base64\"\n].join(\"\\n\")\n\n/** `$1` is the byte bound; standard input is the NUL-terminated absolute paths to send. */\nconst fetching = [\n requireTools,\n \"cd / && COPYFILE_DISABLE=1 xargs -0 -r tar -chf - -- 2>/dev/null | head -c \\\"$1\\\" | base64\"\n].join(\"\\n\")\n\nconst failed = (root: string, reason: string): StdError.StdError =>\n new StdError.StdError({\n code: \"command_failed\",\n message: `Could not search ${root} on this machine: ${reason}`,\n path: root\n })\n\nconst tooLarge = (root: string, bound: number): StdError.StdError =>\n new StdError.StdError({\n code: \"response_too_large\",\n message: `The files under ${root} come to more than ${bound} bytes; narrow the root or the globs`,\n path: root\n })\n\n/**\n * Reads the program from the first line of standard input, as base64, and\n * runs it with the arguments and the rest of standard input. A program in\n * the argv would be quoted once by the spawner and again by the transport,\n * and a sealed host refuses to start a command line past 4,096 characters;\n * this line stays short whatever the program says.\n */\nconst bootstrap = `command -v base64 >/dev/null || { echo \"${missing(\"base64\")}\" >&2; exit 3; }; ` +\n \"IFS= read -r p && p=$(printf %s \\\"$p\\\" | base64 -d) && exec sh -c \\\"$p\\\" sh \\\"$@\\\"\"\n\n/**\n * Runs one script on the machine and decodes the base64 it prints, refusing\n * output that reached `bound`: `head` cut it, so it is not the whole answer.\n */\nconst run = (\n root: string,\n script: string,\n args: ReadonlyArray<string>,\n bound: number,\n stdin = \"\"\n): Effect.Effect<Uint8Array, StdError.StdError, ChildProcessSpawner.ChildProcessSpawner> =>\n Effect.gen(function*() {\n const result = yield* Exec.exec(\"sh\", {\n args: [\"-c\", bootstrap, \"sh\", ...args],\n stdin: `${Base64.encode(new TextEncoder().encode(script))}\\n${stdin}`\n }).pipe(Effect.mapError((error) => failed(root, error.message)))\n if (result.exitCode !== 0) {\n return yield* Effect.fail(failed(root, result.stderr.trim() || `exit ${result.exitCode}`))\n }\n const decoded = Base64.decode(result.stdout.replaceAll(/\\s/g, \"\"))\n if (Result.isFailure(decoded)) return yield* Effect.fail(failed(root, \"the machine answered with invalid base64\"))\n if (decoded.success.length >= bound) return yield* Effect.fail(tooLarge(root, bound - 1))\n return decoded.success\n })\n\n/**\n * Builds the peer over a machine's spawner and its `Path`, which resolves a\n * relative root where the machine's file operations do. `maxBytes` lowers\n * the bound on the file content one search brings back; the default is\n * {@link maxBytes}.\n *\n * @category constructors\n * @since 1.0.0-rc.8\n */\nexport const make = (\n services: Context.Context<ChildProcessSpawner.ChildProcessSpawner | Path.Path>,\n options?: { readonly maxBytes?: number | undefined }\n): Search.Search => {\n const path = Context.get(services, Path.Path)\n const contentBound = (options?.maxBytes ?? maxBytes) + 1\n const copy = (tree: RemoteTree.Tree) =>\n Context.make(FileSystem.FileSystem, RemoteTree.fileSystem(tree, path)).pipe(Context.add(Path.Path, path))\n const listed = (root: string, noIgnore: boolean | undefined) => {\n const resolved = path.resolve(root)\n const bound = maxListingBytes + 1\n return Effect.flatMap(\n run(root, listing, [resolved, String(bound), noIgnore === true ? \"0\" : \"1\"], bound),\n (bytes) => {\n const tree = RemoteTree.parse(bytes, resolved, path)\n return tree === undefined ? Effect.fail(failed(root, \"the listing came back malformed\")) : Effect.succeed(tree)\n }\n )\n }\n return Search.make({\n grep: (input) =>\n Effect.gen(function*() {\n const tree = yield* listed(input.root, input.noIgnore)\n const read = yield* PortableSearch.searched(input).pipe(Effect.provide(copy(tree)))\n const files = [...new Set(read.map((file) => path.resolve(file)))]\n const bytes = files.length === 0 ? new Uint8Array() : yield* run(\n input.root,\n fetching,\n [String(contentBound)],\n contentBound,\n files.map((file) => `${file}\\0`).join(\"\")\n )\n // `tar` ends every archive it writes, even one whose files it could not read.\n const members = files.length === 0 || bytes.length > 0 ? Tar.files(bytes) : undefined\n if (members === undefined) return yield* Effect.fail(failed(input.root, \"the files came back malformed\"))\n const contents = new Map([...tree.contents, ...RemoteTree.absolute(members)])\n return yield* PortableSearch.make(copy({ ...tree, contents })).grep(input)\n }).pipe(Effect.provide(services)),\n glob: (input) =>\n Effect.flatMap(listed(input.root, input.noIgnore), (tree) => PortableSearch.make(copy(tree)).glob(input)).pipe(\n Effect.provide(services)\n )\n })\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,WAAsB;AACtB,oBAAgC;AAChC,aAAwB;AACxB,iBAA4B;AAC5B,aAAwB;AACxB,WAAsB;AACtB,YAAuB;AACvB,iBAA4B;AAC5B,UAAqB;AACrB,qBAAgC;AAChC,aAAwB;AACxB,eAA0B;AAanB,MAAM,WAAW,MAAM,OAAO;AAGrC,MAAM,kBAAkB,KAAK,OAAO;AAEpC,MAAM,SAAS,CAAC,UAA0B,IAAI,MAAM,WAAW,KAAK,OAAO,CAAC;AAE5E,MAAM,SAAS,OAAO,MAAM,sBAAsB,IAAI,CAAC,SAAS,SAAS,OAAO,IAAI,CAAC,EAAE,EAAE,KAAK,MAAM,CAAC;AAGrG,MAAM,UAAU,CAAC,SAAiB,gCAAgC,IAAI;AAEtE,MAAM,eAAe,0EACV,QAAQ,IAAI,CAAC;AAOxB,MAAM,UAAU;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA,8BAA8B,MAAM;AAAA,EAIpC;AAAA,EACA,oDAAoD,MAAM;AAAA,EAE1D;AACF,EAAE,KAAK,IAAI;AAGX,MAAM,WAAW;AAAA,EACf;AAAA,EACA;AACF,EAAE,KAAK,IAAI;AAEX,MAAM,SAAS,CAAC,MAAc,WAC5B,IAAI,SAAS,SAAS;AAAA,EACpB,MAAM;AAAA,EACN,SAAS,oBAAoB,IAAI,qBAAqB,MAAM;AAAA,EAC5D,MAAM;AACR,CAAC;AAEH,MAAM,WAAW,CAAC,MAAc,UAC9B,IAAI,SAAS,SAAS;AAAA,EACpB,MAAM;AAAA,EACN,SAAS,mBAAmB,IAAI,sBAAsB,KAAK;AAAA,EAC3D,MAAM;AACR,CAAC;AASH,MAAM,YAAY,2CAA2C,QAAQ,QAAQ,CAAC;AAO9E,MAAM,MAAM,CACV,MACA,QACA,MACA,OACA,QAAQ,OAER,qBAAO,IAAI,aAAY;AACrB,QAAM,SAAS,OAAO,KAAK,KAAK,MAAM;AAAA,IACpC,MAAM,CAAC,MAAM,WAAW,MAAM,GAAG,IAAI;AAAA,IACrC,OAAO,GAAG,OAAO,OAAO,IAAI,YAAY,EAAE,OAAO,MAAM,CAAC,CAAC;AAAA,EAAK,KAAK;AAAA,EACrE,CAAC,EAAE,KAAK,qBAAO,SAAS,CAAC,UAAU,OAAO,MAAM,MAAM,OAAO,CAAC,CAAC;AAC/D,MAAI,OAAO,aAAa,GAAG;AACzB,WAAO,OAAO,qBAAO,KAAK,OAAO,MAAM,OAAO,OAAO,KAAK,KAAK,QAAQ,OAAO,QAAQ,EAAE,CAAC;AAAA,EAC3F;AACA,QAAM,UAAU,OAAO,OAAO,OAAO,OAAO,WAAW,OAAO,EAAE,CAAC;AACjE,MAAI,OAAO,UAAU,OAAO,EAAG,QAAO,OAAO,qBAAO,KAAK,OAAO,MAAM,0CAA0C,CAAC;AACjH,MAAI,QAAQ,QAAQ,UAAU,MAAO,QAAO,OAAO,qBAAO,KAAK,SAAS,MAAM,QAAQ,CAAC,CAAC;AACxF,SAAO,QAAQ;AACjB,CAAC;AAWI,MAAM,OAAO,CAClB,UACA,YACkB;AAClB,QAAM,OAAO,sBAAQ,IAAI,UAAU,KAAK,IAAI;AAC5C,QAAM,gBAAgB,SAAS,YAAY,YAAY;AACvD,QAAM,OAAO,CAAC,SACZ,sBAAQ,KAAK,WAAW,YAAY,WAAW,WAAW,MAAM,IAAI,CAAC,EAAE,KAAK,sBAAQ,IAAI,KAAK,MAAM,IAAI,CAAC;AAC1G,QAAM,SAAS,CAAC,MAAc,aAAkC;AAC9D,UAAM,WAAW,KAAK,QAAQ,IAAI;AAClC,UAAM,QAAQ,kBAAkB;AAChC,WAAO,qBAAO;AAAA,MACZ,IAAI,MAAM,SAAS,CAAC,UAAU,OAAO,KAAK,GAAG,aAAa,OAAO,MAAM,GAAG,GAAG,KAAK;AAAA,MAClF,CAAC,UAAU;AACT,cAAM,OAAO,WAAW,MAAM,OAAO,UAAU,IAAI;AACnD,eAAO,SAAS,SAAY,qBAAO,KAAK,OAAO,MAAM,iCAAiC,CAAC,IAAI,qBAAO,QAAQ,IAAI;AAAA,MAChH;AAAA,IACF;AAAA,EACF;AACA,SAAO,OAAO,KAAK;AAAA,IACjB,MAAM,CAAC,UACL,qBAAO,IAAI,aAAY;AACrB,YAAM,OAAO,OAAO,OAAO,MAAM,MAAM,MAAM,QAAQ;AACrD,YAAM,OAAO,OAAO,eAAe,SAAS,KAAK,EAAE,KAAK,qBAAO,QAAQ,KAAK,IAAI,CAAC,CAAC;AAClF,YAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC;AACjE,YAAM,QAAQ,MAAM,WAAW,IAAI,IAAI,WAAW,IAAI,OAAO;AAAA,QAC3D,MAAM;AAAA,QACN;AAAA,QACA,CAAC,OAAO,YAAY,CAAC;AAAA,QACrB;AAAA,QACA,MAAM,IAAI,CAAC,SAAS,GAAG,IAAI,IAAI,EAAE,KAAK,EAAE;AAAA,MAC1C;AAEA,YAAM,UAAU,MAAM,WAAW,KAAK,MAAM,SAAS,IAAI,IAAI,MAAM,KAAK,IAAI;AAC5E,UAAI,YAAY,OAAW,QAAO,OAAO,qBAAO,KAAK,OAAO,MAAM,MAAM,+BAA+B,CAAC;AACxG,YAAM,WAAW,IAAI,IAAI,CAAC,GAAG,KAAK,UAAU,GAAG,WAAW,SAAS,OAAO,CAAC,CAAC;AAC5E,aAAO,OAAO,eAAe,KAAK,KAAK,EAAE,GAAG,MAAM,SAAS,CAAC,CAAC,EAAE,KAAK,KAAK;AAAA,IAC3E,CAAC,EAAE,KAAK,qBAAO,QAAQ,QAAQ,CAAC;AAAA,IAClC,MAAM,CAAC,UACL,qBAAO,QAAQ,OAAO,MAAM,MAAM,MAAM,QAAQ,GAAG,CAAC,SAAS,eAAe,KAAK,KAAK,IAAI,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE;AAAA,MACxG,qBAAO,QAAQ,QAAQ;AAAA,IACzB;AAAA,EACJ,CAAC;AACH;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The implementation seam for the ripgrep search contract.
|
|
3
|
+
*
|
|
4
|
+
* Both implementations answer the same normalized calls. `PortableSearch`
|
|
5
|
+
* performs the work in-process; `NativeSearch` drives the `rg` executable.
|
|
6
|
+
* Callers select an implementation by Layer and cannot observe which one was
|
|
7
|
+
* selected from the result.
|
|
8
|
+
*
|
|
9
|
+
* @since 1.0.0
|
|
10
|
+
*/
|
|
11
|
+
import { Context, Effect, Layer } from "effect";
|
|
12
|
+
import * as StdError from "./StdError.ts";
|
|
13
|
+
/**
|
|
14
|
+
* Normalized grep input shared by both implementations.
|
|
15
|
+
*
|
|
16
|
+
* @category models
|
|
17
|
+
* @since 1.0.0
|
|
18
|
+
*/
|
|
19
|
+
export interface GrepInput {
|
|
20
|
+
readonly pattern: string;
|
|
21
|
+
readonly root: string;
|
|
22
|
+
readonly fixedStrings: boolean;
|
|
23
|
+
readonly ignoreCase: boolean;
|
|
24
|
+
readonly smartCase: boolean;
|
|
25
|
+
readonly globs: ReadonlyArray<string>;
|
|
26
|
+
readonly beforeContext: number;
|
|
27
|
+
readonly afterContext: number;
|
|
28
|
+
readonly maxCount?: number | undefined;
|
|
29
|
+
readonly filesWithMatches: boolean;
|
|
30
|
+
/** Opt out of root-scoped .gitignore rules; defaults to false. */
|
|
31
|
+
readonly noIgnore?: boolean | undefined;
|
|
32
|
+
readonly hidden: boolean;
|
|
33
|
+
readonly symbols: boolean;
|
|
34
|
+
readonly limit: number;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* One matching or context line, as a peer produces it before grouping.
|
|
38
|
+
*
|
|
39
|
+
* @category models
|
|
40
|
+
* @since 1.0.0
|
|
41
|
+
*/
|
|
42
|
+
export interface GrepLine {
|
|
43
|
+
readonly file: string;
|
|
44
|
+
readonly line: number;
|
|
45
|
+
readonly text: string;
|
|
46
|
+
readonly kind: "match" | "context";
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* One context line carried inside the match it belongs to.
|
|
50
|
+
*
|
|
51
|
+
* @category models
|
|
52
|
+
* @since 1.0.0
|
|
53
|
+
*/
|
|
54
|
+
export interface ContextLine {
|
|
55
|
+
readonly line: number;
|
|
56
|
+
readonly text: string;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* The definition enclosing a hit, when the file's shape says so plainly.
|
|
60
|
+
*
|
|
61
|
+
* @category models
|
|
62
|
+
* @since 1.0.0
|
|
63
|
+
*/
|
|
64
|
+
export interface Symbol {
|
|
65
|
+
readonly kind: string;
|
|
66
|
+
readonly name: string;
|
|
67
|
+
readonly startLine: number;
|
|
68
|
+
readonly endLine: number;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* One hit: the matching line, the context that belongs to it, and the
|
|
72
|
+
* definition it sits in.
|
|
73
|
+
*
|
|
74
|
+
* @category models
|
|
75
|
+
* @since 1.0.0
|
|
76
|
+
*/
|
|
77
|
+
export interface GrepMatch {
|
|
78
|
+
readonly file: string;
|
|
79
|
+
readonly line: number;
|
|
80
|
+
readonly text: string;
|
|
81
|
+
readonly before: ReadonlyArray<ContextLine>;
|
|
82
|
+
readonly after: ReadonlyArray<ContextLine>;
|
|
83
|
+
readonly symbol?: Symbol | undefined;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Normalized grep output.
|
|
87
|
+
*
|
|
88
|
+
* @category models
|
|
89
|
+
* @since 1.0.0
|
|
90
|
+
*/
|
|
91
|
+
export interface GrepOutput {
|
|
92
|
+
readonly matches: ReadonlyArray<GrepMatch>;
|
|
93
|
+
readonly files: ReadonlyArray<string>;
|
|
94
|
+
readonly filesSearched: number;
|
|
95
|
+
readonly skippedBinary: number;
|
|
96
|
+
readonly truncated: boolean;
|
|
97
|
+
readonly notice?: string | undefined;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Normalized glob input.
|
|
101
|
+
*
|
|
102
|
+
* @category models
|
|
103
|
+
* @since 1.0.0
|
|
104
|
+
*/
|
|
105
|
+
export interface GlobInput {
|
|
106
|
+
readonly pattern: string;
|
|
107
|
+
readonly root: string;
|
|
108
|
+
/** Opt out of root-scoped .gitignore rules; defaults to false. */
|
|
109
|
+
readonly noIgnore?: boolean | undefined;
|
|
110
|
+
readonly hidden: boolean;
|
|
111
|
+
readonly limit: number;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Normalized glob output.
|
|
115
|
+
*
|
|
116
|
+
* @category models
|
|
117
|
+
* @since 1.0.0
|
|
118
|
+
*/
|
|
119
|
+
export interface GlobOutput {
|
|
120
|
+
readonly paths: ReadonlyArray<string>;
|
|
121
|
+
readonly total: number;
|
|
122
|
+
readonly truncated: boolean;
|
|
123
|
+
readonly notice?: string | undefined;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The one search contract implemented by native and portable peers.
|
|
127
|
+
*
|
|
128
|
+
* @category services
|
|
129
|
+
* @since 1.0.0
|
|
130
|
+
*/
|
|
131
|
+
export interface Search {
|
|
132
|
+
readonly grep: (input: GrepInput) => Effect.Effect<GrepOutput, StdError.StdError>;
|
|
133
|
+
readonly glob: (input: GlobInput) => Effect.Effect<GlobOutput, StdError.StdError>;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The {@link Search} service tag.
|
|
137
|
+
*
|
|
138
|
+
* @category services
|
|
139
|
+
* @since 1.0.0
|
|
140
|
+
*/
|
|
141
|
+
export declare const Search: Context.Service<Search, Search>;
|
|
142
|
+
/**
|
|
143
|
+
* Builds a search service from its two operations.
|
|
144
|
+
*
|
|
145
|
+
* @category constructors
|
|
146
|
+
* @since 1.0.0
|
|
147
|
+
*/
|
|
148
|
+
export declare const make: (service: Search) => Search;
|
|
149
|
+
/**
|
|
150
|
+
* Builds an unavailable search service for compositions that deliberately omit search.
|
|
151
|
+
*
|
|
152
|
+
* @category constructors
|
|
153
|
+
* @since 1.0.0
|
|
154
|
+
*/
|
|
155
|
+
export declare const makeNoop: () => Search;
|
|
156
|
+
/**
|
|
157
|
+
* Provides {@link makeNoop}.
|
|
158
|
+
*
|
|
159
|
+
* @category layers
|
|
160
|
+
* @since 1.0.0
|
|
161
|
+
*/
|
|
162
|
+
export declare const layerNoop: Layer.Layer<Search>;
|
|
163
|
+
//# sourceMappingURL=Search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Search.d.ts","sourceRoot":"","sources":["../../src/Search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var Search_exports = {};
|
|
30
|
+
__export(Search_exports, {
|
|
31
|
+
Search: () => Search,
|
|
32
|
+
layerNoop: () => layerNoop,
|
|
33
|
+
make: () => make,
|
|
34
|
+
makeNoop: () => makeNoop
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(Search_exports);
|
|
37
|
+
var import_effect = require("effect");
|
|
38
|
+
var StdError = __toESM(require("./StdError.js"), 1);
|
|
39
|
+
const Search = import_effect.Context.Service("@smthrs/std/Search");
|
|
40
|
+
const make = (service) => Search.of(service);
|
|
41
|
+
const makeNoop = () => {
|
|
42
|
+
const unavailable = () => import_effect.Effect.fail(
|
|
43
|
+
new StdError.StdError({
|
|
44
|
+
code: "provider_unavailable",
|
|
45
|
+
message: "No search implementation is configured"
|
|
46
|
+
})
|
|
47
|
+
);
|
|
48
|
+
return make({ grep: unavailable, glob: unavailable });
|
|
49
|
+
};
|
|
50
|
+
const layerNoop = import_effect.Layer.succeed(Search, makeNoop());
|
|
51
|
+
//# sourceMappingURL=Search.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/Search.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * The implementation seam for the ripgrep search contract.\n *\n * Both implementations answer the same normalized calls. `PortableSearch`\n * performs the work in-process; `NativeSearch` drives the `rg` executable.\n * Callers select an implementation by Layer and cannot observe which one was\n * selected from the result.\n *\n * @since 1.0.0\n */\n\nimport { Context, Effect, Layer } from \"effect\"\nimport * as StdError from \"./StdError.ts\"\n\n/**\n * Normalized grep input shared by both implementations.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface GrepInput {\n readonly pattern: string\n readonly root: string\n readonly fixedStrings: boolean\n readonly ignoreCase: boolean\n readonly smartCase: boolean\n readonly globs: ReadonlyArray<string>\n readonly beforeContext: number\n readonly afterContext: number\n readonly maxCount?: number | undefined\n readonly filesWithMatches: boolean\n /** Opt out of root-scoped .gitignore rules; defaults to false. */\n readonly noIgnore?: boolean | undefined\n readonly hidden: boolean\n readonly symbols: boolean\n readonly limit: number\n}\n\n/**\n * One matching or context line, as a peer produces it before grouping.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface GrepLine {\n readonly file: string\n readonly line: number\n readonly text: string\n readonly kind: \"match\" | \"context\"\n}\n\n/**\n * One context line carried inside the match it belongs to.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface ContextLine {\n readonly line: number\n readonly text: string\n}\n\n/**\n * The definition enclosing a hit, when the file's shape says so plainly.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface Symbol {\n readonly kind: string\n readonly name: string\n readonly startLine: number\n readonly endLine: number\n}\n\n/**\n * One hit: the matching line, the context that belongs to it, and the\n * definition it sits in.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface GrepMatch {\n readonly file: string\n readonly line: number\n readonly text: string\n readonly before: ReadonlyArray<ContextLine>\n readonly after: ReadonlyArray<ContextLine>\n readonly symbol?: Symbol | undefined\n}\n\n/**\n * Normalized grep output.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface GrepOutput {\n readonly matches: ReadonlyArray<GrepMatch>\n readonly files: ReadonlyArray<string>\n readonly filesSearched: number\n readonly skippedBinary: number\n readonly truncated: boolean\n readonly notice?: string | undefined\n}\n\n/**\n * Normalized glob input.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface GlobInput {\n readonly pattern: string\n readonly root: string\n /** Opt out of root-scoped .gitignore rules; defaults to false. */\n readonly noIgnore?: boolean | undefined\n readonly hidden: boolean\n readonly limit: number\n}\n\n/**\n * Normalized glob output.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface GlobOutput {\n readonly paths: ReadonlyArray<string>\n readonly total: number\n readonly truncated: boolean\n readonly notice?: string | undefined\n}\n\n/**\n * The one search contract implemented by native and portable peers.\n *\n * @category services\n * @since 1.0.0\n */\nexport interface Search {\n readonly grep: (input: GrepInput) => Effect.Effect<GrepOutput, StdError.StdError>\n readonly glob: (input: GlobInput) => Effect.Effect<GlobOutput, StdError.StdError>\n}\n\n/**\n * The {@link Search} service tag.\n *\n * @category services\n * @since 1.0.0\n */\nexport const Search: Context.Service<Search, Search> = Context.Service(\"@smthrs/std/Search\")\n\n/**\n * Builds a search service from its two operations.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const make = (service: Search): Search => Search.of(service)\n\n/**\n * Builds an unavailable search service for compositions that deliberately omit search.\n *\n * @category constructors\n * @since 1.0.0\n */\nexport const makeNoop = (): Search => {\n const unavailable = () =>\n Effect.fail(\n new StdError.StdError({\n code: \"provider_unavailable\",\n message: \"No search implementation is configured\"\n })\n )\n return make({ grep: unavailable, glob: unavailable })\n}\n\n/**\n * Provides {@link makeNoop}.\n *\n * @category layers\n * @since 1.0.0\n */\nexport const layerNoop: Layer.Layer<Search> = Layer.succeed(Search, makeNoop())\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,oBAAuC;AACvC,eAA0B;AA2InB,MAAM,SAA0C,sBAAQ,QAAQ,oBAAoB;AAQpF,MAAM,OAAO,CAAC,YAA4B,OAAO,GAAG,OAAO;AAQ3D,MAAM,WAAW,MAAc;AACpC,QAAM,cAAc,MAClB,qBAAO;AAAA,IACL,IAAI,SAAS,SAAS;AAAA,MACpB,MAAM;AAAA,MACN,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF,SAAO,KAAK,EAAE,MAAM,aAAa,MAAM,YAAY,CAAC;AACtD;AAQO,MAAM,YAAiC,oBAAM,QAAQ,QAAQ,SAAS,CAAC;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A differential conformance kit for {@link Search} implementations.
|
|
3
|
+
*
|
|
4
|
+
* `Search` is a public extension seam: a host binds its own implementation and
|
|
5
|
+
* every `grep` and `glob` call in the package goes through it. Two peers ship
|
|
6
|
+
* here, and the contract they are held to used to live only in
|
|
7
|
+
* `test/SearchConformance.test.ts` — a file `package.json` does not publish, so
|
|
8
|
+
* a third-party peer had the seam and no way to prove it filled it. Worse, the
|
|
9
|
+
* cases there are hand-picked: they pin the divergences somebody already
|
|
10
|
+
* found. A literal `?` matched `fo` in one peer and `foo?` in the other for as
|
|
11
|
+
* long as nobody thought to write that case down.
|
|
12
|
+
*
|
|
13
|
+
* This module is the other half. It generates a tree and a batch of calls from
|
|
14
|
+
* a seed, runs them through two implementations, and reports every answer that
|
|
15
|
+
* differs. Nothing here knows which peer is right: a divergence is the finding,
|
|
16
|
+
* and the reference peer to compare against is the caller's choice —
|
|
17
|
+
* `PortableSearch` is the obvious one, because it needs no external binary.
|
|
18
|
+
*
|
|
19
|
+
* The generator deliberately stays inside the ground both peers claim to
|
|
20
|
+
* share: no symlinks, no unreadable directories, no CRLF, no NUL bytes, no
|
|
21
|
+
* filename a shell would have to quote. Those are the cases the hand-written
|
|
22
|
+
* table pins one by one, with an expected value that says which behaviour is
|
|
23
|
+
* intended. A generator cannot say that; it can only say the two disagree.
|
|
24
|
+
*
|
|
25
|
+
* @since 1.0.0
|
|
26
|
+
*/
|
|
27
|
+
import * as Effect from "effect/Effect";
|
|
28
|
+
import * as FileSystem from "effect/FileSystem";
|
|
29
|
+
import * as Path from "effect/Path";
|
|
30
|
+
import type * as Search from "./Search.ts";
|
|
31
|
+
/**
|
|
32
|
+
* One file the generated tree contains.
|
|
33
|
+
*
|
|
34
|
+
* @category models
|
|
35
|
+
* @since 1.0.0
|
|
36
|
+
*/
|
|
37
|
+
export interface GeneratedFile {
|
|
38
|
+
/** Path relative to the tree root, always with `/` separators. */
|
|
39
|
+
readonly path: string;
|
|
40
|
+
readonly content: string;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A generated tree plus the calls to make against it.
|
|
44
|
+
*
|
|
45
|
+
* @category models
|
|
46
|
+
* @since 1.0.0
|
|
47
|
+
*/
|
|
48
|
+
export interface Plan {
|
|
49
|
+
readonly seed: number;
|
|
50
|
+
readonly root: string;
|
|
51
|
+
readonly files: ReadonlyArray<GeneratedFile>;
|
|
52
|
+
readonly grep: ReadonlyArray<Search.GrepInput>;
|
|
53
|
+
readonly glob: ReadonlyArray<Search.GlobInput>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* One call two implementations answered differently.
|
|
57
|
+
*
|
|
58
|
+
* `subject` and `reference` are the rendered answers, so a report names the
|
|
59
|
+
* bytes that differ rather than saying only that they did.
|
|
60
|
+
*
|
|
61
|
+
* @category models
|
|
62
|
+
* @since 1.0.0
|
|
63
|
+
*/
|
|
64
|
+
export interface Divergence {
|
|
65
|
+
readonly call: "grep" | "glob";
|
|
66
|
+
readonly input: Search.GrepInput | Search.GlobInput;
|
|
67
|
+
readonly subject: string;
|
|
68
|
+
readonly reference: string;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Builds a reproducible tree and call batch from a seed.
|
|
72
|
+
*
|
|
73
|
+
* The same seed and root always produce the same plan, so a divergence a run
|
|
74
|
+
* reports can be replayed exactly by rerunning that seed.
|
|
75
|
+
*
|
|
76
|
+
* @category generators
|
|
77
|
+
* @since 1.0.0
|
|
78
|
+
*/
|
|
79
|
+
export declare const plan: (options: {
|
|
80
|
+
readonly seed: number;
|
|
81
|
+
readonly root: string;
|
|
82
|
+
readonly files?: number | undefined;
|
|
83
|
+
readonly calls?: number | undefined;
|
|
84
|
+
}) => Plan;
|
|
85
|
+
/**
|
|
86
|
+
* Writes a plan's tree under its root.
|
|
87
|
+
*
|
|
88
|
+
* @category generators
|
|
89
|
+
* @since 1.0.0
|
|
90
|
+
*/
|
|
91
|
+
export declare const materialize: (target: Plan) => Effect.Effect<void, never, FileSystem.FileSystem | Path.Path>;
|
|
92
|
+
/**
|
|
93
|
+
* Runs every call in a plan through two implementations and reports the
|
|
94
|
+
* answers that differ.
|
|
95
|
+
*
|
|
96
|
+
* A failure is compared like any other answer: two peers that refuse the same
|
|
97
|
+
* call with the same code agree, and one that refuses where the other answers
|
|
98
|
+
* has diverged.
|
|
99
|
+
*
|
|
100
|
+
* @category conformance
|
|
101
|
+
* @since 1.0.0
|
|
102
|
+
*/
|
|
103
|
+
export declare const compare: (options: {
|
|
104
|
+
readonly plan: Plan;
|
|
105
|
+
readonly subject: Search.Search;
|
|
106
|
+
readonly reference: Search.Search;
|
|
107
|
+
}) => Effect.Effect<ReadonlyArray<Divergence>>;
|
|
108
|
+
/**
|
|
109
|
+
* Renders divergences as the report a failing conformance run should print.
|
|
110
|
+
*
|
|
111
|
+
* @category conformance
|
|
112
|
+
* @since 1.0.0
|
|
113
|
+
*/
|
|
114
|
+
export declare const report: (divergences: ReadonlyArray<Divergence>) => string;
|
|
115
|
+
//# sourceMappingURL=SearchConformance.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchConformance.d.ts","sourceRoot":"","sources":["../../src/SearchConformance.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAC/C,OAAO,KAAK,IAAI,MAAM,aAAa,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,MAAM,aAAa,CAAA;AAG1C;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;CACzB;AAED;;;;;GAKG;AACH,MAAM,WAAW,IAAI;IACnB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,aAAa,CAAC,CAAA;IAC5C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;IAC9C,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAA;CAC/C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAA;IACnD,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;CAC3B;AAiDD;;;;;;;;GAQG;AACH,eAAO,MAAM,IAAI,GAAI,SAAS;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACnC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACpC,KAAG,IAyEH,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,WAAW,GACtB,QAAQ,IAAI,KACX,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAW3D,CAAA;AAaJ;;;;;;;;;;GAUG;AACH,eAAO,MAAM,OAAO,GAAI,SAAS;IAC/B,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAA;IACnB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,CAAA;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,MAAM,CAAA;CAClC,KAAG,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAcvC,CAAA;AAEJ;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,aAAa,aAAa,CAAC,UAAU,CAAC,KAAG,MAOhD,CAAA"}
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var SearchConformance_exports = {};
|
|
30
|
+
__export(SearchConformance_exports, {
|
|
31
|
+
compare: () => compare,
|
|
32
|
+
materialize: () => materialize,
|
|
33
|
+
plan: () => plan,
|
|
34
|
+
report: () => report
|
|
35
|
+
});
|
|
36
|
+
module.exports = __toCommonJS(SearchConformance_exports);
|
|
37
|
+
var Effect = __toESM(require("effect/Effect"), 1);
|
|
38
|
+
var FileSystem = __toESM(require("effect/FileSystem"), 1);
|
|
39
|
+
var Path = __toESM(require("effect/Path"), 1);
|
|
40
|
+
const random = (seed) => {
|
|
41
|
+
let state = seed >>> 0;
|
|
42
|
+
return () => {
|
|
43
|
+
state = state + 1831565813 >>> 0;
|
|
44
|
+
let value = Math.imul(state ^ state >>> 15, 1 | state);
|
|
45
|
+
value = value + Math.imul(value ^ value >>> 7, 61 | value) ^ value;
|
|
46
|
+
return ((value ^ value >>> 14) >>> 0) / 4294967296;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const pick = (next, values) => values[Math.floor(next() * values.length)];
|
|
50
|
+
const chance = (next, probability) => next() < probability;
|
|
51
|
+
const stems = ["alpha", "beta", "gamma", "Delta", "e-psilon", "ze_ta", "eta2", "th.eta", "iota", "kappa"];
|
|
52
|
+
const extensions = [".ts", ".js", ".txt", ".py", ".md"];
|
|
53
|
+
const directories = ["", "one", "one/two", "three", "three/four/five"];
|
|
54
|
+
const lines = [
|
|
55
|
+
"needle",
|
|
56
|
+
"a needle in the line",
|
|
57
|
+
"Needle capitalised",
|
|
58
|
+
"no match here",
|
|
59
|
+
"needle? with a question mark",
|
|
60
|
+
"a+b and x*y and [z]",
|
|
61
|
+
"def widen(value):",
|
|
62
|
+
"class Widget:",
|
|
63
|
+
" needle = value",
|
|
64
|
+
"function widen(value) {",
|
|
65
|
+
"",
|
|
66
|
+
"trailing needle"
|
|
67
|
+
];
|
|
68
|
+
const patterns = ["needle", "Needle", "needle?", "a+b", "[z]", "^needle$", "widen", "no match at all"];
|
|
69
|
+
const globPatterns = ["**/*.ts", "*.ts", "**/*", "one/**/*.ts", "**/*.{ts,js}", "**/alpha*"];
|
|
70
|
+
const plan = (options) => {
|
|
71
|
+
const next = random(options.seed);
|
|
72
|
+
const fileCount = options.files ?? 12;
|
|
73
|
+
const callCount = options.calls ?? 12;
|
|
74
|
+
const files = [];
|
|
75
|
+
for (let index = 0; index < fileCount; index++) {
|
|
76
|
+
const directory = pick(next, directories);
|
|
77
|
+
const name = `${pick(next, stems)}${index}${pick(next, extensions)}`;
|
|
78
|
+
const path = directory === "" ? name : `${directory}/${name}`;
|
|
79
|
+
const body = [];
|
|
80
|
+
for (let line = 0; line < 1 + Math.floor(next() * 8); line++) body.push(pick(next, lines));
|
|
81
|
+
files.push({ path, content: `${body.join("\n")}${chance(next, 0.8) ? "\n" : ""}` });
|
|
82
|
+
}
|
|
83
|
+
if (fileCount > 0) {
|
|
84
|
+
files.push(
|
|
85
|
+
{ path: ".gitignore", content: "*.ignored\n!keep.ignored\n/root-only.ts\ncache/\n" },
|
|
86
|
+
{ path: "drop.ignored", content: "needle\n" },
|
|
87
|
+
{ path: "keep.ignored", content: "needle\n" },
|
|
88
|
+
{ path: "root-only.ts", content: "needle\n" },
|
|
89
|
+
{ path: "cache/a.ts", content: "needle\n" },
|
|
90
|
+
{ path: "nested/.gitignore", content: "!keep.ignored\n/anchored.ts\nframes/\n" },
|
|
91
|
+
{ path: "nested/keep.ignored", content: "needle\n" },
|
|
92
|
+
{ path: "nested/drop.ignored", content: "needle\n" },
|
|
93
|
+
{ path: "nested/anchored.ts", content: "needle\n" },
|
|
94
|
+
{ path: "nested/deep/anchored.ts", content: "needle\n" },
|
|
95
|
+
{ path: "nested/root-only.ts", content: "needle\n" },
|
|
96
|
+
{ path: "nested/frames/a.ts", content: "needle\n" },
|
|
97
|
+
{ path: "other/frames", content: "needle\n" }
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
const roots = [options.root, ...files.map((entry) => `${options.root}/${entry.path}`)];
|
|
101
|
+
const grep = [];
|
|
102
|
+
for (let index = 0; index < callCount; index++) {
|
|
103
|
+
const fixedStrings = chance(next, 0.4);
|
|
104
|
+
const ignoreCase = chance(next, 0.25);
|
|
105
|
+
grep.push({
|
|
106
|
+
pattern: pick(next, patterns),
|
|
107
|
+
root: chance(next, 0.75) ? options.root : pick(next, roots),
|
|
108
|
+
fixedStrings,
|
|
109
|
+
ignoreCase,
|
|
110
|
+
smartCase: !ignoreCase && chance(next, 0.3),
|
|
111
|
+
globs: chance(next, 0.4) ? [pick(next, ["*.ts", "*.txt", "!*.js", "**/*.ts"])] : [],
|
|
112
|
+
beforeContext: Math.floor(next() * 3),
|
|
113
|
+
afterContext: Math.floor(next() * 3),
|
|
114
|
+
...chance(next, 0.3) ? { maxCount: 1 + Math.floor(next() * 2) } : {},
|
|
115
|
+
filesWithMatches: chance(next, 0.25),
|
|
116
|
+
hidden: chance(next, 0.5),
|
|
117
|
+
noIgnore: chance(next, 0.25),
|
|
118
|
+
symbols: chance(next, 0.3),
|
|
119
|
+
limit: 1 + Math.floor(next() * 40)
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const glob = [];
|
|
123
|
+
for (let index = 0; index < callCount; index++) {
|
|
124
|
+
glob.push({
|
|
125
|
+
pattern: pick(next, globPatterns),
|
|
126
|
+
root: options.root,
|
|
127
|
+
hidden: chance(next, 0.5),
|
|
128
|
+
noIgnore: chance(next, 0.25),
|
|
129
|
+
limit: 1 + Math.floor(next() * 20)
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
return { seed: options.seed, root: options.root, files, grep, glob };
|
|
133
|
+
};
|
|
134
|
+
const materialize = (target) => Effect.gen(function* () {
|
|
135
|
+
const fileSystem = yield* FileSystem.FileSystem;
|
|
136
|
+
const path = yield* Path.Path;
|
|
137
|
+
yield* Effect.forEach(target.files, (entry) => {
|
|
138
|
+
const absolute = path.join(target.root, ...entry.path.split("/"));
|
|
139
|
+
return fileSystem.makeDirectory(path.dirname(absolute), { recursive: true }).pipe(
|
|
140
|
+
Effect.andThen(fileSystem.writeFileString(absolute, entry.content)),
|
|
141
|
+
Effect.orDie
|
|
142
|
+
);
|
|
143
|
+
}, { discard: true });
|
|
144
|
+
});
|
|
145
|
+
const rendered = (effect) => effect.pipe(
|
|
146
|
+
Effect.match({
|
|
147
|
+
onSuccess: (value) => JSON.stringify(value),
|
|
148
|
+
onFailure: (error) => JSON.stringify({ failure: error.code })
|
|
149
|
+
})
|
|
150
|
+
);
|
|
151
|
+
const compare = (options) => Effect.gen(function* () {
|
|
152
|
+
const divergences = [];
|
|
153
|
+
for (const input of options.plan.grep) {
|
|
154
|
+
const subject = yield* rendered(options.subject.grep(input));
|
|
155
|
+
const reference = yield* rendered(options.reference.grep(input));
|
|
156
|
+
if (subject !== reference) divergences.push({ call: "grep", input, subject, reference });
|
|
157
|
+
}
|
|
158
|
+
for (const input of options.plan.glob) {
|
|
159
|
+
const subject = yield* rendered(options.subject.glob(input));
|
|
160
|
+
const reference = yield* rendered(options.reference.glob(input));
|
|
161
|
+
if (subject !== reference) divergences.push({ call: "glob", input, subject, reference });
|
|
162
|
+
}
|
|
163
|
+
return divergences;
|
|
164
|
+
});
|
|
165
|
+
const report = (divergences) => divergences.map(
|
|
166
|
+
(divergence) => [
|
|
167
|
+
`${divergence.call}(${JSON.stringify(divergence.input)})`,
|
|
168
|
+
` subject: ${divergence.subject}`,
|
|
169
|
+
` reference: ${divergence.reference}`
|
|
170
|
+
].join("\n")
|
|
171
|
+
).join("\n\n");
|
|
172
|
+
//# sourceMappingURL=SearchConformance.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/SearchConformance.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * A differential conformance kit for {@link Search} implementations.\n *\n * `Search` is a public extension seam: a host binds its own implementation and\n * every `grep` and `glob` call in the package goes through it. Two peers ship\n * here, and the contract they are held to used to live only in\n * `test/SearchConformance.test.ts` \u2014 a file `package.json` does not publish, so\n * a third-party peer had the seam and no way to prove it filled it. Worse, the\n * cases there are hand-picked: they pin the divergences somebody already\n * found. A literal `?` matched `fo` in one peer and `foo?` in the other for as\n * long as nobody thought to write that case down.\n *\n * This module is the other half. It generates a tree and a batch of calls from\n * a seed, runs them through two implementations, and reports every answer that\n * differs. Nothing here knows which peer is right: a divergence is the finding,\n * and the reference peer to compare against is the caller's choice \u2014\n * `PortableSearch` is the obvious one, because it needs no external binary.\n *\n * The generator deliberately stays inside the ground both peers claim to\n * share: no symlinks, no unreadable directories, no CRLF, no NUL bytes, no\n * filename a shell would have to quote. Those are the cases the hand-written\n * table pins one by one, with an expected value that says which behaviour is\n * intended. A generator cannot say that; it can only say the two disagree.\n *\n * @since 1.0.0\n */\n\nimport * as Effect from \"effect/Effect\"\nimport * as FileSystem from \"effect/FileSystem\"\nimport * as Path from \"effect/Path\"\nimport type * as Search from \"./Search.ts\"\nimport type * as StdError from \"./StdError.ts\"\n\n/**\n * One file the generated tree contains.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface GeneratedFile {\n /** Path relative to the tree root, always with `/` separators. */\n readonly path: string\n readonly content: string\n}\n\n/**\n * A generated tree plus the calls to make against it.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface Plan {\n readonly seed: number\n readonly root: string\n readonly files: ReadonlyArray<GeneratedFile>\n readonly grep: ReadonlyArray<Search.GrepInput>\n readonly glob: ReadonlyArray<Search.GlobInput>\n}\n\n/**\n * One call two implementations answered differently.\n *\n * `subject` and `reference` are the rendered answers, so a report names the\n * bytes that differ rather than saying only that they did.\n *\n * @category models\n * @since 1.0.0\n */\nexport interface Divergence {\n readonly call: \"grep\" | \"glob\"\n readonly input: Search.GrepInput | Search.GlobInput\n readonly subject: string\n readonly reference: string\n}\n\n/**\n * mulberry32: 32 bits of state, uniform enough for fixture generation and\n * reproducible from a seed on every host, which a shared `Math.random` is not.\n */\nconst random = (seed: number): () => number => {\n let state = seed >>> 0\n return () => {\n state = (state + 0x6D2B79F5) >>> 0\n let value = Math.imul(state ^ (state >>> 15), 1 | state)\n value = (value + Math.imul(value ^ (value >>> 7), 61 | value)) ^ value\n return ((value ^ (value >>> 14)) >>> 0) / 4_294_967_296\n }\n}\n\nconst pick = <A>(next: () => number, values: ReadonlyArray<A>): A => values[Math.floor(next() * values.length)]!\n\nconst chance = (next: () => number, probability: number): boolean => next() < probability\n\n// Names both peers walk identically: no separator, no dot prefix outside the\n// two deliberate hidden entries, no name a directory skip list contains, and\n// no character that would need quoting on a command line.\nconst stems = [\"alpha\", \"beta\", \"gamma\", \"Delta\", \"e-psilon\", \"ze_ta\", \"eta2\", \"th.eta\", \"iota\", \"kappa\"] as const\nconst extensions = [\".ts\", \".js\", \".txt\", \".py\", \".md\"] as const\nconst directories = [\"\", \"one\", \"one/two\", \"three\", \"three/four/five\"] as const\n\n// Lines drawn from a vocabulary that mixes the needle, near misses, regex\n// metacharacters that must survive `fixedStrings`, and definition headers the\n// `symbols` option reads.\nconst lines = [\n \"needle\",\n \"a needle in the line\",\n \"Needle capitalised\",\n \"no match here\",\n \"needle? with a question mark\",\n \"a+b and x*y and [z]\",\n \"def widen(value):\",\n \"class Widget:\",\n \" needle = value\",\n \"function widen(value) {\",\n \"\",\n \"trailing needle\"\n] as const\n\nconst patterns = [\"needle\", \"Needle\", \"needle?\", \"a+b\", \"[z]\", \"^needle$\", \"widen\", \"no match at all\"] as const\n\nconst globPatterns = [\"**/*.ts\", \"*.ts\", \"**/*\", \"one/**/*.ts\", \"**/*.{ts,js}\", \"**/alpha*\"] as const\n\n/**\n * Builds a reproducible tree and call batch from a seed.\n *\n * The same seed and root always produce the same plan, so a divergence a run\n * reports can be replayed exactly by rerunning that seed.\n *\n * @category generators\n * @since 1.0.0\n */\nexport const plan = (options: {\n readonly seed: number\n readonly root: string\n readonly files?: number | undefined\n readonly calls?: number | undefined\n}): Plan => {\n const next = random(options.seed)\n const fileCount = options.files ?? 12\n const callCount = options.calls ?? 12\n const files: Array<GeneratedFile> = []\n for (let index = 0; index < fileCount; index++) {\n const directory = pick(next, directories)\n // The index makes every generated path unique, including repeated random picks.\n const name = `${pick(next, stems)}${index}${pick(next, extensions)}`\n const path = directory === \"\" ? name : `${directory}/${name}`\n const body: Array<string> = []\n for (let line = 0; line < 1 + Math.floor(next() * 8); line++) body.push(pick(next, lines))\n files.push({ path, content: `${body.join(\"\\n\")}${chance(next, 0.8) ? \"\\n\" : \"\"}` })\n }\n\n // Always exercise precedence, anchoring, directory pruning and nested\n // negation alongside each seed's generated content (without a git repo).\n if (fileCount > 0) {\n files.push(\n { path: \".gitignore\", content: \"*.ignored\\n!keep.ignored\\n/root-only.ts\\ncache/\\n\" },\n { path: \"drop.ignored\", content: \"needle\\n\" },\n { path: \"keep.ignored\", content: \"needle\\n\" },\n { path: \"root-only.ts\", content: \"needle\\n\" },\n { path: \"cache/a.ts\", content: \"needle\\n\" },\n { path: \"nested/.gitignore\", content: \"!keep.ignored\\n/anchored.ts\\nframes/\\n\" },\n { path: \"nested/keep.ignored\", content: \"needle\\n\" },\n { path: \"nested/drop.ignored\", content: \"needle\\n\" },\n { path: \"nested/anchored.ts\", content: \"needle\\n\" },\n { path: \"nested/deep/anchored.ts\", content: \"needle\\n\" },\n { path: \"nested/root-only.ts\", content: \"needle\\n\" },\n { path: \"nested/frames/a.ts\", content: \"needle\\n\" },\n { path: \"other/frames\", content: \"needle\\n\" }\n )\n }\n\n const roots = [options.root, ...files.map((entry) => `${options.root}/${entry.path}`)]\n const grep: Array<Search.GrepInput> = []\n for (let index = 0; index < callCount; index++) {\n const fixedStrings = chance(next, 0.4)\n // `Grep.run` refuses `ignoreCase` together with `smartCase` as mutually\n // exclusive, so a generated call carrying both would be exploring ground\n // the contract does not describe.\n const ignoreCase = chance(next, 0.25)\n grep.push({\n pattern: pick(next, patterns),\n root: chance(next, 0.75) ? options.root : pick(next, roots),\n fixedStrings,\n ignoreCase,\n smartCase: !ignoreCase && chance(next, 0.3),\n globs: chance(next, 0.4) ? [pick(next, [\"*.ts\", \"*.txt\", \"!*.js\", \"**/*.ts\"])] : [],\n beforeContext: Math.floor(next() * 3),\n afterContext: Math.floor(next() * 3),\n ...(chance(next, 0.3) ? { maxCount: 1 + Math.floor(next() * 2) } : {}),\n filesWithMatches: chance(next, 0.25),\n hidden: chance(next, 0.5),\n noIgnore: chance(next, 0.25),\n symbols: chance(next, 0.3),\n limit: 1 + Math.floor(next() * 40)\n })\n }\n\n const glob: Array<Search.GlobInput> = []\n for (let index = 0; index < callCount; index++) {\n glob.push({\n pattern: pick(next, globPatterns),\n root: options.root,\n hidden: chance(next, 0.5),\n noIgnore: chance(next, 0.25),\n limit: 1 + Math.floor(next() * 20)\n })\n }\n\n return { seed: options.seed, root: options.root, files, grep, glob }\n}\n\n/**\n * Writes a plan's tree under its root.\n *\n * @category generators\n * @since 1.0.0\n */\nexport const materialize = (\n target: Plan\n): Effect.Effect<void, never, FileSystem.FileSystem | Path.Path> =>\n Effect.gen(function*() {\n const fileSystem = yield* FileSystem.FileSystem\n const path = yield* Path.Path\n yield* Effect.forEach(target.files, (entry) => {\n const absolute = path.join(target.root, ...entry.path.split(\"/\"))\n return fileSystem.makeDirectory(path.dirname(absolute), { recursive: true }).pipe(\n Effect.andThen(fileSystem.writeFileString(absolute, entry.content)),\n Effect.orDie\n )\n }, { discard: true })\n })\n\n/** A typed answer rendered so two of them can be compared as text. */\nconst rendered = <A>(\n effect: Effect.Effect<A, StdError.StdError>\n): Effect.Effect<string> =>\n effect.pipe(\n Effect.match({\n onSuccess: (value) => JSON.stringify(value),\n onFailure: (error) => JSON.stringify({ failure: error.code })\n })\n )\n\n/**\n * Runs every call in a plan through two implementations and reports the\n * answers that differ.\n *\n * A failure is compared like any other answer: two peers that refuse the same\n * call with the same code agree, and one that refuses where the other answers\n * has diverged.\n *\n * @category conformance\n * @since 1.0.0\n */\nexport const compare = (options: {\n readonly plan: Plan\n readonly subject: Search.Search\n readonly reference: Search.Search\n}): Effect.Effect<ReadonlyArray<Divergence>> =>\n Effect.gen(function*() {\n const divergences: Array<Divergence> = []\n for (const input of options.plan.grep) {\n const subject = yield* rendered(options.subject.grep(input))\n const reference = yield* rendered(options.reference.grep(input))\n if (subject !== reference) divergences.push({ call: \"grep\", input, subject, reference })\n }\n for (const input of options.plan.glob) {\n const subject = yield* rendered(options.subject.glob(input))\n const reference = yield* rendered(options.reference.glob(input))\n if (subject !== reference) divergences.push({ call: \"glob\", input, subject, reference })\n }\n return divergences\n })\n\n/**\n * Renders divergences as the report a failing conformance run should print.\n *\n * @category conformance\n * @since 1.0.0\n */\nexport const report = (divergences: ReadonlyArray<Divergence>): string =>\n divergences.map((divergence) =>\n [\n `${divergence.call}(${JSON.stringify(divergence.input)})`,\n ` subject: ${divergence.subject}`,\n ` reference: ${divergence.reference}`\n ].join(\"\\n\")\n ).join(\"\\n\\n\")\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|