ttsc 0.31.6 → 0.32.1
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/cmd/ttsc/compiler_argument_cwd_test.go +38 -38
- package/cmd/ttscserver/main.go +2 -12
- package/cmd/ttscserver/resolve_launch_uses_native_flag_authority_test.go +7 -7
- package/driver/lsp.go +4 -43
- package/driver/rewrite.go +1 -1
- package/internal/e2etrace/completion_hints.go +3 -3
- package/internal/e2etrace/completion_hints_test.go +26 -12
- package/internal/graph/build.go +5 -6
- package/internal/graph/graph.go +3 -3
- package/internal/graph/line_model.go +2 -35
- package/internal/lspserver/lsp_clean_didopen_refreshes_compiler_state_test.go +13 -36
- package/internal/lspserver/lsp_hints_refresh_ignores_a_superseded_generation_test.go +9 -3
- package/internal/lspserver/lsp_plugin.go +19 -0
- package/internal/lspserver/lsp_proxy.go +9 -129
- package/internal/lspserver/lsp_server.go +0 -8
- package/internal/lspserver/lsp_watched_file_changes_reach_compiler_caches_test.go +6 -36
- package/internal/sourceprocess/windows_target_owns_suspended_admission_test.go +5 -5
- package/lib/TtscCompiler.js +1 -1
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/ResidentCheckProcess.d.ts +74 -96
- package/lib/compiler/internal/ResidentCheckProcess.js +150 -335
- package/lib/compiler/internal/ResidentCheckProcess.js.map +1 -1
- package/lib/compiler/internal/ResidentCheckProcessHost.d.ts +127 -0
- package/lib/compiler/internal/ResidentCheckProcessHost.js +447 -0
- package/lib/compiler/internal/ResidentCheckProcessHost.js.map +1 -0
- package/lib/compiler/internal/ResidentCheckProcessProtocol.d.ts +64 -0
- package/lib/compiler/internal/ResidentCheckProcessProtocol.js +3 -0
- package/lib/compiler/internal/ResidentCheckProcessProtocol.js.map +1 -0
- package/lib/compiler/internal/build/BuildExecution.d.ts +103 -1
- package/lib/compiler/internal/build/BuildExecution.js +92 -12
- package/lib/compiler/internal/build/BuildExecution.js.map +1 -1
- package/lib/compiler/internal/build/ResidentCheckWatchSession.d.ts +16 -11
- package/lib/compiler/internal/build/ResidentCheckWatchSession.js +37 -21
- package/lib/compiler/internal/build/ResidentCheckWatchSession.js.map +1 -1
- package/lib/compiler/internal/build/RunBuildOptions.d.ts +6 -5
- package/lib/compiler/internal/build/TsgoArguments.js.map +1 -1
- package/lib/compiler/internal/build/WatchInputPublication.d.ts +59 -0
- package/lib/compiler/internal/build/WatchInputPublication.js +93 -0
- package/lib/compiler/internal/build/WatchInputPublication.js.map +1 -0
- package/lib/compiler/internal/build/runBuild.d.ts +29 -2
- package/lib/compiler/internal/build/runBuild.js +45 -19
- package/lib/compiler/internal/build/runBuild.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.d.ts +2 -0
- package/lib/compiler/internal/buildNativeCompiler.js +1 -0
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.js +4 -2
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/project/CompilerProjectSelection.d.ts +9 -8
- package/lib/compiler/internal/project/CompilerProjectSelection.js +11 -9
- package/lib/compiler/internal/project/CompilerProjectSelection.js.map +1 -1
- package/lib/compiler/internal/project/resolveOwningProjectConfig.d.ts +25 -8
- package/lib/compiler/internal/project/resolveOwningProjectConfig.js +26 -14
- package/lib/compiler/internal/project/resolveOwningProjectConfig.js.map +1 -1
- package/lib/compiler/internal/readEffectiveCompilerOptions.js +1 -1
- package/lib/compiler/internal/readEffectiveCompilerOptions.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.d.ts +1 -0
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.d.ts +6 -0
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.d.ts +32 -4
- package/lib/compiler/internal/runSingleFileEmit.js +124 -89
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/startResidentTransform.js +8 -2
- package/lib/compiler/internal/startResidentTransform.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.js +11 -3
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/transformProjectInWorker.d.ts +1 -1
- package/lib/compiler/internal/transformProjectInWorker.js +3 -2
- package/lib/compiler/internal/transformProjectInWorker.js.map +1 -1
- package/lib/flags/ParseOptions.d.ts +2 -2
- package/lib/internal/E2ETrace.js.map +1 -1
- package/lib/internal/OwnedNativeProcess.d.ts +2 -2
- package/lib/internal/OwnedNativeProcess.js +2 -2
- package/lib/internal/SourceNativeRetirement.d.ts +8 -7
- package/lib/internal/SourceNativeRetirement.js +19 -10
- package/lib/internal/SourceNativeRetirement.js.map +1 -1
- package/lib/internal/TtsxNodeOptions.d.ts +79 -0
- package/lib/internal/TtsxNodeOptions.js +121 -0
- package/lib/internal/TtsxNodeOptions.js.map +1 -0
- package/lib/internal/javascriptRuntimeCapabilities.js +4 -1
- package/lib/internal/javascriptRuntimeCapabilities.js.map +1 -1
- package/lib/internal/parseWindowsDirectoryCaseSensitivity.d.ts +5 -5
- package/lib/internal/parseWindowsDirectoryCaseSensitivity.js +5 -5
- package/lib/internal/pathIdentity/createCaseSensitivityObservations.d.ts +35 -0
- package/lib/internal/pathIdentity/createCaseSensitivityObservations.js +209 -0
- package/lib/internal/pathIdentity/createCaseSensitivityObservations.js.map +1 -0
- package/lib/internal/pathIdentity/createFilesystemPathIdentityContext.js +2 -143
- package/lib/internal/pathIdentity/createFilesystemPathIdentityContext.js.map +1 -1
- package/lib/internal/projectInputPathIdentity.d.ts +1 -0
- package/lib/internal/projectInputPathIdentity.js +1 -0
- package/lib/internal/projectInputPathIdentity.js.map +1 -1
- package/lib/internal/workerModuleUrl.d.ts +28 -0
- package/lib/internal/workerModuleUrl.js +40 -0
- package/lib/internal/workerModuleUrl.js.map +1 -0
- package/lib/launcher/internal/buildSingleRootProject.js +2 -1
- package/lib/launcher/internal/buildSingleRootProject.js.map +1 -1
- package/lib/launcher/internal/getCompilerVersionText.js +3 -2
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/parseTtsxCLI.d.ts +5 -4
- package/lib/launcher/internal/parseTtsxCLI.js +5 -4
- package/lib/launcher/internal/parseTtsxCLI.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +2 -1
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/resolveSingleFileOutput.d.ts +8 -9
- package/lib/launcher/internal/resolveSingleFileOutput.js +8 -9
- package/lib/launcher/internal/resolveSingleFileOutput.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +91 -41
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +5 -2
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/launcher/internal/runtime/CommonJsRuntimeSource.d.ts +10 -6
- package/lib/launcher/internal/runtime/CommonJsRuntimeSource.js +11 -9
- package/lib/launcher/internal/runtime/CommonJsRuntimeSource.js.map +1 -1
- package/lib/launcher/internal/runtime/RuntimeEntrySources.d.ts +40 -0
- package/lib/launcher/internal/runtime/RuntimeEntrySources.js +57 -0
- package/lib/launcher/internal/runtime/RuntimeEntrySources.js.map +1 -0
- package/lib/launcher/internal/runtime/RuntimeProjectOwnership.d.ts +5 -4
- package/lib/launcher/internal/runtime/RuntimeProjectOwnership.js +8 -6
- package/lib/launcher/internal/runtime/RuntimeProjectOwnership.js.map +1 -1
- package/lib/launcher/internal/runtime/advertiseTypeScriptExtensions.d.ts +20 -0
- package/lib/launcher/internal/runtime/advertiseTypeScriptExtensions.js +27 -0
- package/lib/launcher/internal/runtime/advertiseTypeScriptExtensions.js.map +1 -0
- package/lib/launcher/internal/runtime/commonJsExportNames.d.ts +2 -1
- package/lib/launcher/internal/runtime/commonJsExportNames.js +2 -1
- package/lib/launcher/internal/runtime/commonJsExportNames.js.map +1 -1
- package/lib/launcher/internal/runtime/installRuntimeHooks.d.ts +5 -3
- package/lib/launcher/internal/runtime/installRuntimeHooks.js +42 -12
- package/lib/launcher/internal/runtime/installRuntimeHooks.js.map +1 -1
- package/lib/launcher/internal/runtime/resolveRuntimeCleanTargets.js +3 -1
- package/lib/launcher/internal/runtime/resolveRuntimeCleanTargets.js.map +1 -1
- package/lib/launcher/internal/watch/AsyncWatchTopology.d.ts +113 -0
- package/lib/launcher/internal/watch/AsyncWatchTopology.js +232 -0
- package/lib/launcher/internal/watch/AsyncWatchTopology.js.map +1 -0
- package/lib/launcher/internal/watch/WatchSettlement.d.ts +49 -0
- package/lib/launcher/internal/watch/WatchSettlement.js +70 -0
- package/lib/launcher/internal/watch/WatchSettlement.js.map +1 -0
- package/lib/launcher/internal/watch/WatchTopology.d.ts +103 -13
- package/lib/launcher/internal/watch/WatchTopology.js +380 -95
- package/lib/launcher/internal/watch/WatchTopology.js.map +1 -1
- package/lib/launcher/internal/watch/WatchTopologyWorkerProtocol.d.ts +121 -0
- package/lib/launcher/internal/watch/WatchTopologyWorkerProtocol.js +3 -0
- package/lib/launcher/internal/watch/WatchTopologyWorkerProtocol.js.map +1 -0
- package/lib/launcher/internal/watch/projectInputReloadEventShouldNotify.d.ts +4 -1
- package/lib/launcher/internal/watch/projectInputReloadEventShouldNotify.js +3 -2
- package/lib/launcher/internal/watch/projectInputReloadEventShouldNotify.js.map +1 -1
- package/lib/launcher/internal/watch/serveWatchTopologyWorker.d.ts +19 -0
- package/lib/launcher/internal/watch/serveWatchTopologyWorker.js +62 -0
- package/lib/launcher/internal/watch/serveWatchTopologyWorker.js.map +1 -0
- package/lib/launcher/internal/watch/watchTopologyWorker.d.ts +1 -0
- package/lib/launcher/internal/watch/watchTopologyWorker.js +22 -0
- package/lib/launcher/internal/watch/watchTopologyWorker.js.map +1 -0
- package/lib/plugin/CapabilityPluginResolver.d.ts +1 -1
- package/lib/plugin/CapabilityPluginResolver.js +3 -2
- package/lib/plugin/CapabilityPluginResolver.js.map +1 -1
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.d.ts +15 -12
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js +13 -11
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js.map +1 -1
- package/lib/plugin/internal/load/PluginPackageResolution.d.ts +2 -2
- package/lib/plugin/internal/load/PluginPackageResolution.js +13 -7
- package/lib/plugin/internal/load/PluginPackageResolution.js.map +1 -1
- package/lib/plugin/internal/load/ProjectPluginEntries.d.ts +23 -7
- package/lib/plugin/internal/load/ProjectPluginEntries.js +36 -14
- package/lib/plugin/internal/load/ProjectPluginEntries.js.map +1 -1
- package/lib/plugin/internal/load/collectProjectHostInputs.d.ts +3 -1
- package/lib/plugin/internal/load/collectProjectHostInputs.js +5 -2
- package/lib/plugin/internal/load/collectProjectHostInputs.js.map +1 -1
- package/lib/plugin/internal/load/hasProjectPluginEntries.d.ts +3 -1
- package/lib/plugin/internal/load/hasProjectPluginEntries.js +4 -2
- package/lib/plugin/internal/load/hasProjectPluginEntries.js.map +1 -1
- package/lib/plugin/internal/load/loadProjectPlugins.d.ts +36 -5
- package/lib/plugin/internal/load/loadProjectPlugins.js +477 -421
- package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
- package/lib/plugin/internal/load/pluginResolutionFailure.d.ts +18 -0
- package/lib/plugin/internal/load/pluginResolutionFailure.js +32 -0
- package/lib/plugin/internal/load/pluginResolutionFailure.js.map +1 -0
- package/lib/plugin/internal/load/resolveNativeSource.js +2 -3
- package/lib/plugin/internal/load/resolveNativeSource.js.map +1 -1
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.d.ts +1 -1
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js +3 -2
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js.map +1 -1
- package/lib/plugin/internal/source/pluginModuleReplaceDirectories.d.ts +4 -1
- package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js +9 -2
- package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js.map +1 -1
- package/lib/structures/ITtscCompilerContext.d.ts +12 -12
- package/lib/structures/ITtscPlugin.d.ts +7 -5
- package/lib/structures/ITtscPluginFactoryContext.d.ts +9 -8
- package/lib/structures/internal/TtscCommonOptions.d.ts +2 -2
- package/lib/structures/internal/TtscSingleFileEmitOptions.d.ts +12 -6
- package/package.json +9 -9
- package/src/TtscCompiler.ts +1 -1
- package/src/compiler/internal/ResidentCheckProcess.ts +159 -374
- package/src/compiler/internal/ResidentCheckProcessHost.ts +502 -0
- package/src/compiler/internal/ResidentCheckProcessProtocol.ts +53 -0
- package/src/compiler/internal/build/BuildExecution.ts +123 -11
- package/src/compiler/internal/build/ResidentCheckWatchSession.ts +41 -24
- package/src/compiler/internal/build/RunBuildOptions.ts +9 -5
- package/src/compiler/internal/build/TsgoArguments.ts +4 -1
- package/src/compiler/internal/build/WatchInputPublication.ts +106 -0
- package/src/compiler/internal/build/runBuild.ts +58 -34
- package/src/compiler/internal/buildNativeCompiler.ts +4 -0
- package/src/compiler/internal/compileProjectInMemory.ts +8 -2
- package/src/compiler/internal/project/CompilerProjectSelection.ts +14 -14
- package/src/compiler/internal/project/resolveOwningProjectConfig.ts +42 -16
- package/src/compiler/internal/readEffectiveCompilerOptions.ts +1 -1
- package/src/compiler/internal/resolveBinary.ts +4 -1
- package/src/compiler/internal/resolveTsgo.ts +7 -0
- package/src/compiler/internal/runSingleFileEmit.ts +145 -101
- package/src/compiler/internal/startResidentTransform.ts +9 -2
- package/src/compiler/internal/transformProjectInMemory.ts +12 -3
- package/src/compiler/internal/transformProjectInWorker.ts +10 -2
- package/src/flags/ParseOptions.ts +2 -2
- package/src/internal/E2ETrace.ts +3 -1
- package/src/internal/OwnedNativeProcess.ts +2 -2
- package/src/internal/SourceNativeRetirement.ts +42 -19
- package/src/internal/TtsxNodeOptions.ts +124 -0
- package/src/internal/javascriptRuntimeCapabilities.ts +6 -1
- package/src/internal/parseWindowsDirectoryCaseSensitivity.ts +5 -5
- package/src/internal/pathIdentity/createCaseSensitivityObservations.ts +242 -0
- package/src/internal/pathIdentity/createFilesystemPathIdentityContext.ts +2 -169
- package/src/internal/projectInputPathIdentity.ts +1 -0
- package/src/internal/workerModuleUrl.ts +34 -0
- package/src/launcher/internal/buildSingleRootProject.ts +2 -0
- package/src/launcher/internal/getCompilerVersionText.ts +3 -2
- package/src/launcher/internal/parseTtsxCLI.ts +5 -4
- package/src/launcher/internal/prepareExecution.ts +6 -1
- package/src/launcher/internal/resolveSingleFileOutput.ts +8 -9
- package/src/launcher/internal/runTtsc.ts +127 -49
- package/src/launcher/internal/runTtsx.ts +17 -8
- package/src/launcher/internal/runtime/CommonJsRuntimeSource.ts +11 -9
- package/src/launcher/internal/runtime/RuntimeEntrySources.ts +57 -0
- package/src/launcher/internal/runtime/RuntimeProjectOwnership.ts +23 -10
- package/src/launcher/internal/runtime/advertiseTypeScriptExtensions.ts +25 -0
- package/src/launcher/internal/runtime/commonJsExportNames.ts +11 -4
- package/src/launcher/internal/runtime/installRuntimeHooks.ts +62 -16
- package/src/launcher/internal/runtime/resolveRuntimeCleanTargets.ts +17 -5
- package/src/launcher/internal/watch/AsyncWatchTopology.ts +267 -0
- package/src/launcher/internal/watch/WatchSettlement.ts +67 -0
- package/src/launcher/internal/watch/WatchTopology.ts +461 -102
- package/src/launcher/internal/watch/WatchTopologyWorkerProtocol.ts +106 -0
- package/src/launcher/internal/watch/projectInputReloadEventShouldNotify.ts +14 -9
- package/src/launcher/internal/watch/serveWatchTopologyWorker.ts +75 -0
- package/src/launcher/internal/watch/watchTopologyWorker.ts +29 -0
- package/src/plugin/CapabilityPluginResolver.ts +9 -2
- package/src/plugin/internal/load/PluginDescriptorEvaluationCache.ts +17 -12
- package/src/plugin/internal/load/PluginPackageResolution.ts +14 -9
- package/src/plugin/internal/load/ProjectPluginEntries.ts +40 -15
- package/src/plugin/internal/load/collectProjectHostInputs.ts +7 -1
- package/src/plugin/internal/load/hasProjectPluginEntries.ts +8 -3
- package/src/plugin/internal/load/loadProjectPlugins.ts +683 -593
- package/src/plugin/internal/load/pluginResolutionFailure.ts +37 -0
- package/src/plugin/internal/load/resolveNativeSource.ts +10 -4
- package/src/plugin/internal/source/PluginBuildEnvironmentReadings.ts +8 -2
- package/src/plugin/internal/source/pluginModuleReplaceDirectories.ts +10 -1
- package/src/structures/ITtscCompilerContext.ts +12 -12
- package/src/structures/ITtscPlugin.ts +7 -5
- package/src/structures/ITtscPluginFactoryContext.ts +9 -8
- package/src/structures/internal/TtscCommonOptions.ts +2 -2
- package/src/structures/internal/TtscSingleFileEmitOptions.ts +22 -11
- package/internal/graphsymbols/position_helpers_follow_ecma_line_terminators_test.go +0 -78
- package/internal/graphsymbols/provider.go +0 -650
- package/internal/lspserver/lsp_symbols.go +0 -212
|
@@ -9,11 +9,13 @@ const node_fs_1 = __importDefault(require("node:fs"));
|
|
|
9
9
|
const node_module_1 = require("node:module");
|
|
10
10
|
const node_path_1 = __importDefault(require("node:path"));
|
|
11
11
|
const node_url_1 = require("node:url");
|
|
12
|
+
const WatchInputPublication_1 = require("../../../compiler/internal/build/WatchInputPublication");
|
|
12
13
|
const readJsonFile_1 = require("../../../compiler/internal/project/readJsonFile");
|
|
13
14
|
const readProjectConfig_1 = require("../../../compiler/internal/project/readProjectConfig");
|
|
14
15
|
const SidecarEnvironment_1 = require("../../../compiler/internal/sharedHost/SidecarEnvironment");
|
|
15
16
|
const E2ETrace_1 = require("../../../internal/E2ETrace");
|
|
16
17
|
const OwnedSynchronousProcess_1 = require("../../../internal/OwnedSynchronousProcess");
|
|
18
|
+
const TtsxNodeOptions_1 = require("../../../internal/TtsxNodeOptions");
|
|
17
19
|
const createCanonicalTempDirectory_1 = require("../../../internal/createCanonicalTempDirectory");
|
|
18
20
|
const javascriptRuntimeCapabilities_1 = require("../../../internal/javascriptRuntimeCapabilities");
|
|
19
21
|
const resolveNodeBinary_1 = require("../../../internal/resolveNodeBinary");
|
|
@@ -79,6 +81,9 @@ const visitImportMappedCandidates_1 = require("./visitImportMappedCandidates");
|
|
|
79
81
|
* declaration. Sequential content, metadata and physical-path observations are
|
|
80
82
|
* not an atomic snapshot or detection of every omitted read.
|
|
81
83
|
*
|
|
84
|
+
* Synchronous callers require synchronous watch-input handlers; use
|
|
85
|
+
* {@link loadProjectPlugins.async} to await a worker's baseline publication.
|
|
86
|
+
*
|
|
82
87
|
* @param options.binary - Absolute path to the ttsc native helper binary.
|
|
83
88
|
* @param options.cacheDir - Override the plugin binary cache directory.
|
|
84
89
|
* @param options.cwd - Working directory for resolving relative paths.
|
|
@@ -89,11 +94,12 @@ const visitImportMappedCandidates_1 = require("./visitImportMappedCandidates");
|
|
|
89
94
|
* native environment-name identity. Defaults to `process.env` for CLI
|
|
90
95
|
* callers, so ambient behavior is unchanged.
|
|
91
96
|
* @param options.file - Path to the tsconfig/jsconfig file.
|
|
92
|
-
* @param options.pluginConfigDir - Caller-declared
|
|
93
|
-
* config-file discovery
|
|
94
|
-
* @param options.projectRoot - Override the
|
|
97
|
+
* @param options.pluginConfigDir - Caller-declared consumer directory for
|
|
98
|
+
* plugin packages, factory contexts and config-file discovery.
|
|
99
|
+
* @param options.projectRoot - Override the source root, native working
|
|
100
|
+
* directory, cache anchor and returned relative Go-source base.
|
|
95
101
|
* @param options.tsconfig - Alias for `file`.
|
|
96
|
-
* @evidence contracts/common.md#principled-implementation The loader brackets
|
|
102
|
+
* @evidence contracts/common.md#principled-implementation The loader brackets discovery at the selected config or explicit pluginConfigDir and factories receive that consumer anchor, independently of the source root retained for descriptor/native process cwd, caches and relative Go sources. It validates declarations before publishing conservative source repair interests. Metadata refusal remains terminal; valid records narrow watch interests before final admission/build, while contradictory content or physical observations are omitted from proof rather than retroactively blessed.
|
|
97
103
|
* @evidence contracts/common.md#clear-and-simple-design The operation owns one ordered load generation; private helpers separate discovery, evaluation, validation, composition and proof merging, while package resolution and source building remain their own modules.
|
|
98
104
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Descriptor module caches are isolated rather than deleting application singletons. ttsx retry occurs only for explicit supported TypeScript loader incompatibility, with plugins disabled to avoid recursive self-hosting; arbitrary descriptor failures are not retried into false success.
|
|
99
105
|
* @evidence contracts/common.md#meaningful-documentation Native JSDoc explains result provenance, environment and path options; helper comments explain input races, conservative proof omission, fallback authority and cleanup. Member/tag spacing and separated concepts follow the documentation skill.
|
|
@@ -103,420 +109,463 @@ const visitImportMappedCandidates_1 = require("./visitImportMappedCandidates");
|
|
|
103
109
|
* @evidence contracts/performance.md#bound-retention-and-release-resources Finally restores injected environment locators, attempts evaluator directory removal and closes direct-evaluator diagnostic descriptors. Close/removal can fail; synchronous completion concerns the selected evaluator and does not certify arbitrary descendants are gone. Generation maps/results scale with observed data, and disk diagnostics/result/observation files have no independent byte ceiling here. Default disk pruning has its own interval/protection/failure policy; explicit roots remain caller-owned.
|
|
104
110
|
*/
|
|
105
111
|
function loadProjectPlugins(options) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
return {
|
|
128
|
-
...collectHostInputSnapshot(project, {}, [], projectHostInputs, revalidateHostInputHashes(projectHostInputHashes, projectHostInputs), revalidateHostInputRealpaths(projectHostInputRealpaths, projectHostInputs)),
|
|
129
|
-
descriptorReadsDeclared: true,
|
|
130
|
-
discoveryInputsComplete: project.configInputsComplete === true,
|
|
131
|
-
nativePlugins: [],
|
|
132
|
-
pluginSources: {},
|
|
133
|
-
project,
|
|
134
|
-
};
|
|
112
|
+
return WatchInputPublication_1.WatchInputPublication.run(loadProjectPlugins.steps(options));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Keep synchronous loading and awaited watch handoffs on one load sequence.
|
|
116
|
+
*
|
|
117
|
+
* @evidence contracts/common.md#principled-implementation Both completion modes advance one ordered discovery, admission, publication and build sequence. Awaited stepping preserves baseline-before-read handoffs before package selection and source builds, including empty selection and conservative repair roots.
|
|
118
|
+
* @evidence contracts/common.md#clear-and-simple-design The namespace adds an awaited runner beside synchronous loading and exposes one generator to build orchestration; existing helpers retain discovery, validation and compilation responsibilities.
|
|
119
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Publication suspension retains failed-build interests and source proof rather than rebuilding a baseline after compilation. Pending publication cannot establish observation; rejection enters the real load failure path without replacing admission or native builds.
|
|
120
|
+
* @evidence contracts/common.md#meaningful-documentation Entry prose distinguishes completion modes, baseline-before-read ordering and internal sequence completion/rejection duties; the primary loader documents input and result provenance.
|
|
121
|
+
* @evidence contracts/portability.md#os-neutral-implementation The shared sequence retains existing native resolution, paths, environment and argument-array handling; the namespace adds no independent boundary.
|
|
122
|
+
* @evidence contracts/performance.md#efficient-algorithms Discovery, source hashing, Go metadata, validation and builds retain their original input costs; each publication adds one suspension without repeating those phases.
|
|
123
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Validated descriptor/source records and load-local digest/reader sharing remain available across suspension; the completion wrapper retains no reusable load or in-flight cache.
|
|
124
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources One load generation stays live while its current handoff settles; evaluator cleanup and returned-generation ownership remain with the sequence, and handler rejection enters generator cleanup.
|
|
125
|
+
*/
|
|
126
|
+
(function (loadProjectPlugins) {
|
|
127
|
+
/**
|
|
128
|
+
* Load plugins after each watch owner confirms its reported input baseline. A
|
|
129
|
+
* rejected handoff fails loading before the next source read or build.
|
|
130
|
+
*/
|
|
131
|
+
function async(options) {
|
|
132
|
+
return WatchInputPublication_1.WatchInputPublication.runAsync(steps(options));
|
|
135
133
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
cacheDir: options.cacheDir,
|
|
156
|
-
env: effectiveEnv,
|
|
134
|
+
loadProjectPlugins.async = async;
|
|
135
|
+
/**
|
|
136
|
+
* Produce one load, suspending at each watch-input handoff before continuing.
|
|
137
|
+
* Internal build orchestration consumes the whole sequence with its chosen
|
|
138
|
+
* completion runner; it must deliver rejection back into the sequence.
|
|
139
|
+
*/
|
|
140
|
+
function* steps(options) {
|
|
141
|
+
// Snapshot the caller environment before `withPluginLoaderEnv` injects
|
|
142
|
+
// host-owned Node/ttsx locators into process.env. Under a Bun parent the
|
|
143
|
+
// direct descriptor evaluator must remain Bun unless the caller explicitly
|
|
144
|
+
// selected another runtime.
|
|
145
|
+
const effectiveEnv = SidecarEnvironment_1.SidecarEnvironment.merge(options.env ?? process.env);
|
|
146
|
+
const projectSnapshot = readProjectHostInputSnapshot({
|
|
147
|
+
cwd: options.cwd,
|
|
148
|
+
file: options.file,
|
|
149
|
+
includePluginDiscovery: options.entries === undefined,
|
|
150
|
+
pluginConfigDir: options.pluginConfigDir,
|
|
151
|
+
projectRoot: options.projectRoot,
|
|
152
|
+
tsconfig: options.tsconfig,
|
|
157
153
|
});
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
const request = PluginPackageResolution_1.PluginPackageResolution.resolvePluginRequest(specifier, entry.baseDir);
|
|
176
|
-
// Keep the candidates of the search roots up to the one the entry
|
|
177
|
-
// resolved in: the lookup never read the roots after it
|
|
178
|
-
// (`moduleResolutionBaseSelects`).
|
|
179
|
-
const read = new Set(collectModuleResolutionCandidates(specifier, entryParent, request).map((candidate) => node_path_1.default.resolve(candidate)));
|
|
180
|
-
const entryCandidates = probedCandidates.filter((candidate) => read.has(node_path_1.default.resolve(candidate)));
|
|
181
|
-
const entryCandidateHashes = pickHostInputEntries(probedCandidateHashes, entryCandidates);
|
|
182
|
-
const entryCandidateRealpaths = pickHostInputEntries(probedCandidateRealpaths, entryCandidates);
|
|
183
|
-
const loaded = loadPluginEntry(entry.config, { ...context, plugin: entry.config }, request, effectiveEnv, descriptorCache);
|
|
184
|
-
const loadedHostInputHashes = mergeObservedHostInputHashes(loaded.hostInputHashes, (0, hashHostInputPaths_1.hashHostInputPaths)(Object.keys(loaded.hostInputHashes)));
|
|
185
|
-
const loadedHostInputRealpaths = mergeObservedHostInputRealpaths(loaded.hostInputRealpaths, (0, realpathHostInputPaths_1.realpathHostInputPaths)(Object.keys(loaded.hostInputRealpaths)));
|
|
186
|
-
const hostInputHashes = mergeObservedHostInputHashes(entryCandidateHashes, loadedHostInputHashes);
|
|
187
|
-
const hostInputRealpaths = mergeObservedHostInputRealpaths(entryCandidateRealpaths, loadedHostInputRealpaths);
|
|
188
|
-
for (const input of loaded.hostInputs) {
|
|
189
|
-
const absolute = node_path_1.default.resolve(input);
|
|
190
|
-
if (!Object.prototype.hasOwnProperty.call(loadedHostInputHashes, absolute)) {
|
|
191
|
-
delete hostInputHashes[absolute];
|
|
192
|
-
}
|
|
154
|
+
const { project } = projectSnapshot;
|
|
155
|
+
const projectHostInputs = projectSnapshot.hostInputs;
|
|
156
|
+
const projectHostInputHashes = projectSnapshot.hostInputHashes;
|
|
157
|
+
const projectHostInputRealpaths = projectSnapshot.hostInputRealpaths;
|
|
158
|
+
const entries = options.entries === false
|
|
159
|
+
? []
|
|
160
|
+
: ProjectPluginEntries_1.ProjectPluginEntries.resolvePluginEntries(project, options.entries, options.pluginConfigDir).filter((entry) => entry.config.enabled !== false);
|
|
161
|
+
if (entries.length === 0) {
|
|
162
|
+
yield options.onWatchInputs?.([]);
|
|
163
|
+
return {
|
|
164
|
+
...collectHostInputSnapshot(project, {}, [], projectHostInputs, revalidateHostInputHashes(projectHostInputHashes, projectHostInputs), revalidateHostInputRealpaths(projectHostInputRealpaths, projectHostInputs)),
|
|
165
|
+
descriptorReadsDeclared: true,
|
|
166
|
+
discoveryInputsComplete: project.configInputsComplete === true,
|
|
167
|
+
nativePlugins: [],
|
|
168
|
+
pluginSources: {},
|
|
169
|
+
project,
|
|
170
|
+
};
|
|
193
171
|
}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
172
|
+
const cwd = node_path_1.default.resolve(options.cwd ?? process.cwd());
|
|
173
|
+
const context = {
|
|
174
|
+
binary: options.binary,
|
|
175
|
+
cwd,
|
|
176
|
+
...(options.pluginConfigDir === undefined ||
|
|
177
|
+
options.pluginConfigDir === ""
|
|
178
|
+
? {}
|
|
179
|
+
: { pluginConfigDir: node_path_1.default.resolve(cwd, options.pluginConfigDir) }),
|
|
180
|
+
projectRoot: project.root,
|
|
181
|
+
tsconfig: project.path,
|
|
200
182
|
};
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
// One reading of each source directory, shared by package selection and
|
|
219
|
-
// every build below and reported as the state the binaries were keyed on.
|
|
220
|
-
const sourceDigests = new Map();
|
|
221
|
-
// And one reading of the environment each build directory is keyed on, which
|
|
222
|
-
// a plugin module root's state reports as it is.
|
|
223
|
-
const environmentDigests = new Map();
|
|
224
|
-
// With the witness of each such reading, so a build of a directory package
|
|
225
|
-
// selection already read keys on that reading instead of probing Go again.
|
|
226
|
-
const environmentWitnesses = new Map();
|
|
227
|
-
const readings = {
|
|
228
|
-
sources: sourceDigests,
|
|
229
|
-
environments: environmentDigests,
|
|
230
|
-
witnesses: environmentWitnesses,
|
|
231
|
-
};
|
|
232
|
-
// Records describing sources must never land inside one, so the store is
|
|
233
|
-
// admitted for source proofs only once every source of the load is known.
|
|
234
|
-
const sourceIdentities = PluginContentIdentities_1.PluginContentIdentities.outside(identities, [
|
|
235
|
-
...candidates.flatMap((candidate) => [
|
|
236
|
-
candidate.moduleRoot,
|
|
237
|
-
candidate.packageDir,
|
|
238
|
-
...(candidate.contributors ?? []).map((input) => input.source),
|
|
239
|
-
]),
|
|
240
|
-
...SourcePluginWorkspace_1.SourcePluginWorkspace.findTtscOverlayDirs(),
|
|
241
|
-
]);
|
|
242
|
-
// One fixed-effective-environment load owns manifest syntax sharing from the
|
|
243
|
-
// first watch query through metadata and builds. Do not allocate this after
|
|
244
|
-
// watch projection: that silently repeats selected-Go work (#1712).
|
|
245
|
-
const packageReaders = new Map();
|
|
246
|
-
const watchReplacements = options.onWatchInputs === undefined
|
|
247
|
-
? undefined
|
|
248
|
-
: new Map();
|
|
249
|
-
if (options.onWatchInputs !== undefined) {
|
|
250
|
-
// The prospective context reads the admitted module layout and anchors its
|
|
251
|
-
// tool there before kind exists. Keep both possible final-root baselines:
|
|
252
|
-
// a linked package keeps packageDir, and an executable keeps moduleRoot.
|
|
253
|
-
const interests = new Set(candidates
|
|
254
|
-
.flatMap((candidate) => [
|
|
255
|
-
candidate.moduleRoot,
|
|
256
|
-
candidate.packageDir,
|
|
257
|
-
...(candidate.contributors ?? []).map((input) => input.source),
|
|
258
|
-
])
|
|
259
|
-
.filter(reportsPluginSource));
|
|
260
|
-
// WARNING (#1728): hand the watch owner this load's store with the roots.
|
|
261
|
-
// It baselines each root before any build reads it; without the store it
|
|
262
|
-
// read every source the load proves from records a moment later.
|
|
263
|
-
options.onWatchInputs([...interests].sort(), sourceIdentities);
|
|
264
|
-
const initialSize = interests.size;
|
|
265
|
-
for (const candidate of candidates) {
|
|
266
|
-
// Nested source-only proposals replace the outer root manifests. Do not
|
|
267
|
-
// activate their irrelevant module graph just to discover watch inputs.
|
|
268
|
-
if (candidate.stage === "transform" && candidate.entry !== ".")
|
|
269
|
-
continue;
|
|
270
|
-
for (const directory of pluginReplacementWatchDirectories(candidate.moduleRoot, effectiveEnv, watchReplacements, packageReaders))
|
|
271
|
-
if (reportsPluginSource(directory))
|
|
272
|
-
interests.add(directory);
|
|
273
|
-
}
|
|
274
|
-
if (interests.size !== initialSize)
|
|
275
|
-
options.onWatchInputs([...interests].sort(), sourceIdentities);
|
|
276
|
-
}
|
|
277
|
-
const proposals = NativeSourcePackages_1.NativeSourcePackages.propose(candidates.map((candidate) => ({
|
|
278
|
-
...candidate,
|
|
279
|
-
ownModule: candidate.stage !== "transform",
|
|
280
|
-
})), effectiveEnv, packageReaders, sourceIdentities, readings);
|
|
281
|
-
const records = candidates.map(({ plugin, index, stage, contributors, source, packageDir }) => {
|
|
282
|
-
const { kind, moduleRoot } = (0, resolveNativeSource_1.resolveNativeSource)(source, plugin, entries[index].config, index, {
|
|
283
|
-
env: effectiveEnv,
|
|
284
|
-
observation: proposals[index].observation,
|
|
285
|
-
});
|
|
286
|
-
if (kind === "linked" && stage !== "transform") {
|
|
287
|
-
throw new Error(`ttsc: plugin "${(0, pluginLabel_1.pluginLabel)(plugin, entries[index].config, index)}" source is a linked Go package, but only transform-stage plugins can be linked into a compiler host`);
|
|
288
|
-
}
|
|
289
|
-
const linkedContributorName = kind === "linked"
|
|
290
|
-
? `linked_${String(index).padStart(6, "0")}`
|
|
291
|
-
: undefined;
|
|
292
|
-
const hostInputs = validatePluginHostInputs(plugin, index);
|
|
293
|
-
const pluginHostInputHashes = validatePluginHostInputHashes(plugin, index, hostInputs);
|
|
294
|
-
const pluginHostInputRealpaths = validatePluginHostInputRealpaths(plugin, index, hostInputs);
|
|
295
|
-
return {
|
|
296
|
-
capabilities: plugin.capabilities,
|
|
297
|
-
contributors,
|
|
298
|
-
config: entries[index].config,
|
|
299
|
-
kind,
|
|
300
|
-
label: (0, pluginLabel_1.pluginLabel)(plugin, entries[index].config, index),
|
|
301
|
-
linkedContributorName,
|
|
302
|
-
name: plugin.name,
|
|
303
|
-
reportsTypeScriptDiagnostics: plugin.reportsTypeScriptDiagnostics === true,
|
|
304
|
-
request: loadedEntries[index].request,
|
|
305
|
-
hostInputHashes: mergePluginHostInputHashes(loadedEntries[index].hostInputHashes, pluginHostInputHashes, loadedEntries[index].hostInputs, hostInputs),
|
|
306
|
-
hostInputRealpaths: mergePluginHostInputHashes(loadedEntries[index].hostInputRealpaths, pluginHostInputRealpaths, loadedEntries[index].hostInputs, hostInputs),
|
|
307
|
-
hostInputs: [...loadedEntries[index].hostInputs, ...hostInputs],
|
|
308
|
-
moduleRoot,
|
|
309
|
-
packageDir,
|
|
310
|
-
source,
|
|
311
|
-
stage,
|
|
183
|
+
// Where isolated descriptor evaluations keep their answers across launches
|
|
184
|
+
// (`PluginDescriptorEvaluationCache`).
|
|
185
|
+
// WARNING (#1721, #1722, #1723): a warm load must prove its unchanged inputs
|
|
186
|
+
// from this store, not re-read them. Every launch is a new process, so any
|
|
187
|
+
// module-level memo of this load's work dies with it; a 27 s warm typia
|
|
188
|
+
// launch whose native build took 0.28 s is what that looked like.
|
|
189
|
+
const identities = options.identities ??
|
|
190
|
+
PluginContentIdentities_1.PluginContentIdentities.open({
|
|
191
|
+
projectRoot: project.root,
|
|
192
|
+
cacheDir: options.cacheDir,
|
|
193
|
+
env: effectiveEnv,
|
|
194
|
+
});
|
|
195
|
+
const descriptorCache = {
|
|
196
|
+
cacheDir: options.cacheDir,
|
|
197
|
+
identities,
|
|
198
|
+
projectRoot: project.root,
|
|
199
|
+
version: (0, pluginBuildVersions_1.pluginBuildVersions)(project.root).ttsc,
|
|
312
200
|
};
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
// Admission can now narrow the provisional interests without restamping the
|
|
318
|
-
// retained package/module baselines. Final host errors still keep these roots.
|
|
319
|
-
options.onWatchInputs?.(buildDirectories, sourceIdentities);
|
|
320
|
-
const keyedDirectories = new Set(buildDirectories);
|
|
321
|
-
const linkedContributors = records
|
|
322
|
-
.filter((record) => record.stage === "transform")
|
|
323
|
-
.flatMap((record) => record.kind === "linked"
|
|
324
|
-
? [{ name: record.linkedContributorName, source: record.source }]
|
|
325
|
-
: []);
|
|
326
|
-
const transformHosts = records.filter((record) => record.stage === "transform" && record.kind === "executable");
|
|
327
|
-
const hostContributors = linkedContributors.length === 0 ? undefined : linkedContributors;
|
|
328
|
-
// Every host compiles the linked sources under its own module/tool context.
|
|
329
|
-
// Equivalent entries in one module share this metadata command and reader;
|
|
330
|
-
// a second executable host can select a genuinely different Go context.
|
|
331
|
-
const admittedExecutables = new Set();
|
|
332
|
-
if (linkedContributors.length !== 0) {
|
|
333
|
-
const hosts = transformHosts.length === 0
|
|
334
|
-
? [
|
|
335
|
-
{
|
|
336
|
-
source: node_path_1.default.join(ttscPackageRoot(), "cmd", "utility-host"),
|
|
337
|
-
label: "linked-plugin-host",
|
|
338
|
-
},
|
|
339
|
-
]
|
|
340
|
-
: transformHosts;
|
|
341
|
-
const contexts = new Map();
|
|
342
|
-
for (const host of hosts) {
|
|
343
|
-
const moduleRoot = (0, resolvePluginGoModule_1.resolvePluginGoModule)(host.source, host.label).moduleRoot;
|
|
344
|
-
let context = contexts.get(moduleRoot);
|
|
345
|
-
if (context === undefined) {
|
|
346
|
-
context = { source: host.source, label: host.label, records: [] };
|
|
347
|
-
contexts.set(moduleRoot, context);
|
|
201
|
+
const loadedEntries = withPluginLoaderEnv(() => entries.map((entry) => {
|
|
202
|
+
const specifier = entry.config.transform;
|
|
203
|
+
if (typeof specifier !== "string" || specifier.length === 0) {
|
|
204
|
+
throw new Error(`ttsc: plugin entry is missing a string "transform" field`);
|
|
348
205
|
}
|
|
206
|
+
const entryParent = node_path_1.default.join(entry.baseDir, "package.json");
|
|
207
|
+
const probedCandidates = collectModuleResolutionCandidates(specifier, entryParent, undefined);
|
|
208
|
+
// Capture every candidate before resolution chooses the descriptor entry.
|
|
209
|
+
// A post-resolution snapshot could bless a higher-priority file created
|
|
210
|
+
// after the resolver had already selected the old entry.
|
|
211
|
+
const probedCandidateHashes = (0, hashHostInputPaths_1.hashHostInputPaths)(probedCandidates);
|
|
212
|
+
const probedCandidateRealpaths = (0, realpathHostInputPaths_1.realpathHostInputPaths)(probedCandidates);
|
|
213
|
+
const request = PluginPackageResolution_1.PluginPackageResolution.resolvePluginRequest(specifier, entry.baseDir);
|
|
214
|
+
// Keep the candidates of the search roots up to the one the entry
|
|
215
|
+
// resolved in: the lookup never read the roots after it
|
|
216
|
+
// (`moduleResolutionBaseSelects`).
|
|
217
|
+
const read = new Set(collectModuleResolutionCandidates(specifier, entryParent, request).map((candidate) => node_path_1.default.resolve(candidate)));
|
|
218
|
+
const entryCandidates = probedCandidates.filter((candidate) => read.has(node_path_1.default.resolve(candidate)));
|
|
219
|
+
const entryCandidateHashes = pickHostInputEntries(probedCandidateHashes, entryCandidates);
|
|
220
|
+
const entryCandidateRealpaths = pickHostInputEntries(probedCandidateRealpaths, entryCandidates);
|
|
221
|
+
const loaded = loadPluginEntry(entry.config, {
|
|
222
|
+
...context,
|
|
223
|
+
plugin: entry.config,
|
|
224
|
+
// Package factories such as typia resolve their own package from
|
|
225
|
+
// this consumer anchor. Keep the compiler source root below for
|
|
226
|
+
// native cwd, cache ownership and returned relative Go sources.
|
|
227
|
+
projectRoot: ProjectPluginEntries_1.ProjectPluginEntries.resolvePluginBaseDir(project, options.pluginConfigDir),
|
|
228
|
+
}, request, effectiveEnv, descriptorCache);
|
|
229
|
+
const loadedHostInputHashes = mergeObservedHostInputHashes(loaded.hostInputHashes, (0, hashHostInputPaths_1.hashHostInputPaths)(Object.keys(loaded.hostInputHashes)));
|
|
230
|
+
const loadedHostInputRealpaths = mergeObservedHostInputRealpaths(loaded.hostInputRealpaths, (0, realpathHostInputPaths_1.realpathHostInputPaths)(Object.keys(loaded.hostInputRealpaths)));
|
|
231
|
+
const hostInputHashes = mergeObservedHostInputHashes(entryCandidateHashes, loadedHostInputHashes);
|
|
232
|
+
const hostInputRealpaths = mergeObservedHostInputRealpaths(entryCandidateRealpaths, loadedHostInputRealpaths);
|
|
233
|
+
for (const input of loaded.hostInputs) {
|
|
234
|
+
const absolute = node_path_1.default.resolve(input);
|
|
235
|
+
if (!Object.prototype.hasOwnProperty.call(loadedHostInputHashes, absolute)) {
|
|
236
|
+
delete hostInputHashes[absolute];
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
return {
|
|
240
|
+
...loaded,
|
|
241
|
+
hostInputHashes,
|
|
242
|
+
hostInputRealpaths,
|
|
243
|
+
hostInputs: [...loaded.hostInputs, ...entryCandidates],
|
|
244
|
+
request,
|
|
245
|
+
};
|
|
246
|
+
}), identities);
|
|
247
|
+
const plugins = (0, composePluginSources_1.composePluginSources)(entries, loadedEntries.map((entry) => entry.plugin));
|
|
248
|
+
const { ttsc: ttscVersion, tsgo: tsgoVersion } = (0, pluginBuildVersions_1.pluginBuildVersions)(context.projectRoot);
|
|
249
|
+
const candidates = plugins
|
|
250
|
+
.map((plugin, index) => {
|
|
251
|
+
const stage = PluginDescriptorAdmission_1.PluginDescriptorAdmission.stage(plugin);
|
|
252
|
+
(0, validatePluginSource_1.validatePluginSource)(plugin);
|
|
253
|
+
const contributors = (0, validatePluginContributors_1.validatePluginContributors)(plugin);
|
|
254
|
+
const source = resolvePluginSource(plugin.source, context.projectRoot);
|
|
255
|
+
const label = (0, pluginLabel_1.pluginLabel)(plugin, entries[index].config, index);
|
|
256
|
+
(0, requirePluginSource_1.requirePluginSource)(source, label);
|
|
257
|
+
return { plugin, index, stage, contributors, source, label };
|
|
258
|
+
})
|
|
259
|
+
.map((candidate) => ({
|
|
260
|
+
...candidate,
|
|
261
|
+
...(0, resolvePluginGoModule_1.resolvePluginGoModule)(candidate.source, candidate.label),
|
|
262
|
+
}));
|
|
263
|
+
// One reading of each source directory, shared by package selection and
|
|
264
|
+
// every build below and reported as the state the binaries were keyed on.
|
|
265
|
+
const sourceDigests = new Map();
|
|
266
|
+
// And one reading of the environment each build directory is keyed on, which
|
|
267
|
+
// a plugin module root's state reports as it is.
|
|
268
|
+
const environmentDigests = new Map();
|
|
269
|
+
// With the witness of each such reading, so a build of a directory package
|
|
270
|
+
// selection already read keys on that reading instead of probing Go again.
|
|
271
|
+
const environmentWitnesses = new Map();
|
|
272
|
+
const readings = {
|
|
273
|
+
sources: sourceDigests,
|
|
274
|
+
environments: environmentDigests,
|
|
275
|
+
witnesses: environmentWitnesses,
|
|
276
|
+
};
|
|
277
|
+
// Records describing sources must never land inside one, so the store is
|
|
278
|
+
// admitted for source proofs only once every source of the load is known.
|
|
279
|
+
const sourceIdentities = PluginContentIdentities_1.PluginContentIdentities.outside(identities, [
|
|
280
|
+
...candidates.flatMap((candidate) => [
|
|
281
|
+
candidate.moduleRoot,
|
|
282
|
+
candidate.packageDir,
|
|
283
|
+
...(candidate.contributors ?? []).map((input) => input.source),
|
|
284
|
+
]),
|
|
285
|
+
...SourcePluginWorkspace_1.SourcePluginWorkspace.findTtscOverlayDirs(),
|
|
286
|
+
]);
|
|
287
|
+
// One fixed-effective-environment load owns manifest syntax sharing from the
|
|
288
|
+
// first watch query through metadata and builds. Do not allocate this after
|
|
289
|
+
// watch projection: that silently repeats selected-Go work (#1712).
|
|
290
|
+
const packageReaders = new Map();
|
|
291
|
+
const watchReplacements = options.onWatchInputs === undefined
|
|
292
|
+
? undefined
|
|
293
|
+
: new Map();
|
|
294
|
+
if (options.onWatchInputs !== undefined) {
|
|
295
|
+
// The prospective context reads the admitted module layout and anchors its
|
|
296
|
+
// tool there before kind exists. Keep both possible final-root baselines:
|
|
297
|
+
// a linked package keeps packageDir, and an executable keeps moduleRoot.
|
|
298
|
+
const interests = new Set(candidates
|
|
299
|
+
.flatMap((candidate) => [
|
|
300
|
+
candidate.moduleRoot,
|
|
301
|
+
candidate.packageDir,
|
|
302
|
+
...(candidate.contributors ?? []).map((input) => input.source),
|
|
303
|
+
])
|
|
304
|
+
.filter(reportsPluginSource));
|
|
305
|
+
// WARNING (#1728): hand the watch owner this load's store with the roots.
|
|
306
|
+
// It baselines each root before any build reads it; without the store it
|
|
307
|
+
// read every source the load proves from records a moment later.
|
|
308
|
+
// A worker owns the watch baseline now. Complete this handoff before Go
|
|
309
|
+
// metadata or source proof consumes the roots, preserving #1728 (#1758).
|
|
310
|
+
yield options.onWatchInputs([...interests].sort(), sourceIdentities);
|
|
311
|
+
const initialSize = interests.size;
|
|
312
|
+
for (const candidate of candidates) {
|
|
313
|
+
// Nested source-only proposals replace the outer root manifests. Do not
|
|
314
|
+
// activate their irrelevant module graph just to discover watch inputs.
|
|
315
|
+
if (candidate.stage === "transform" && candidate.entry !== ".")
|
|
316
|
+
continue;
|
|
317
|
+
for (const directory of pluginReplacementWatchDirectories(candidate.moduleRoot, effectiveEnv, watchReplacements, packageReaders, sourceIdentities))
|
|
318
|
+
if (reportsPluginSource(directory))
|
|
319
|
+
interests.add(directory);
|
|
320
|
+
}
|
|
321
|
+
if (interests.size !== initialSize)
|
|
322
|
+
yield options.onWatchInputs([...interests].sort(), sourceIdentities);
|
|
349
323
|
}
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
}));
|
|
357
|
-
const observations = NativeSourcePackages_1.NativeSourcePackages.inspect({
|
|
358
|
-
source: host.source,
|
|
359
|
-
pluginName: host.label,
|
|
324
|
+
const proposals = NativeSourcePackages_1.NativeSourcePackages.propose(candidates.map((candidate) => ({
|
|
325
|
+
...candidate,
|
|
326
|
+
ownModule: candidate.stage !== "transform",
|
|
327
|
+
})), effectiveEnv, packageReaders, sourceIdentities, readings);
|
|
328
|
+
const records = candidates.map(({ plugin, index, stage, contributors, source, packageDir }) => {
|
|
329
|
+
const { kind, moduleRoot } = (0, resolveNativeSource_1.resolveNativeSource)(source, plugin, entries[index].config, index, {
|
|
360
330
|
env: effectiveEnv,
|
|
361
|
-
|
|
362
|
-
identities: sourceIdentities,
|
|
363
|
-
readings,
|
|
364
|
-
packages: [
|
|
365
|
-
...hostEntries,
|
|
366
|
-
...linkedContributors.map((input) => ({
|
|
367
|
-
...input,
|
|
368
|
-
entry: `./contrib/${input.name}`,
|
|
369
|
-
})),
|
|
370
|
-
],
|
|
371
|
-
});
|
|
372
|
-
moduleHosts.forEach((record, index) => {
|
|
373
|
-
NativeSourcePackages_1.NativeSourcePackages.kind(observations[index], record.label, "executable");
|
|
374
|
-
admittedExecutables.add(record.source);
|
|
331
|
+
observation: proposals[index].observation,
|
|
375
332
|
});
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
}
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
contributors: record.contributors,
|
|
333
|
+
if (kind === "linked" && stage !== "transform") {
|
|
334
|
+
throw new Error(`ttsc: plugin "${(0, pluginLabel_1.pluginLabel)(plugin, entries[index].config, index)}" source is a linked Go package, but only transform-stage plugins can be linked into a compiler host`);
|
|
335
|
+
}
|
|
336
|
+
const linkedContributorName = kind === "linked"
|
|
337
|
+
? `linked_${String(index).padStart(6, "0")}`
|
|
338
|
+
: undefined;
|
|
339
|
+
const hostInputs = validatePluginHostInputs(plugin, index);
|
|
340
|
+
const pluginHostInputHashes = validatePluginHostInputHashes(plugin, index, hostInputs);
|
|
341
|
+
const pluginHostInputRealpaths = validatePluginHostInputRealpaths(plugin, index, hostInputs);
|
|
342
|
+
return {
|
|
343
|
+
capabilities: plugin.capabilities,
|
|
344
|
+
contributors,
|
|
345
|
+
config: entries[index].config,
|
|
346
|
+
kind,
|
|
347
|
+
label: (0, pluginLabel_1.pluginLabel)(plugin, entries[index].config, index),
|
|
348
|
+
linkedContributorName,
|
|
349
|
+
name: plugin.name,
|
|
350
|
+
reportsTypeScriptDiagnostics: plugin.reportsTypeScriptDiagnostics === true,
|
|
351
|
+
request: loadedEntries[index].request,
|
|
352
|
+
hostInputHashes: mergePluginHostInputHashes(loadedEntries[index].hostInputHashes, pluginHostInputHashes, loadedEntries[index].hostInputs, hostInputs),
|
|
353
|
+
hostInputRealpaths: mergePluginHostInputHashes(loadedEntries[index].hostInputRealpaths, pluginHostInputRealpaths, loadedEntries[index].hostInputs, hostInputs),
|
|
354
|
+
hostInputs: [...loadedEntries[index].hostInputs, ...hostInputs],
|
|
355
|
+
moduleRoot,
|
|
356
|
+
packageDir,
|
|
357
|
+
source,
|
|
358
|
+
stage,
|
|
359
|
+
};
|
|
360
|
+
});
|
|
361
|
+
const executableCandidates = candidates.filter((candidate) => records[candidate.index].kind === "executable" &&
|
|
362
|
+
!proposals[candidate.index].ownModule);
|
|
363
|
+
const buildDirectories = pluginBuildDirectories(records, effectiveEnv, watchReplacements, packageReaders, sourceIdentities);
|
|
364
|
+
// Admission can now narrow the provisional interests without restamping the
|
|
365
|
+
// retained package/module baselines. Final host errors still keep these roots.
|
|
366
|
+
yield options.onWatchInputs?.(buildDirectories, sourceIdentities);
|
|
367
|
+
const keyedDirectories = new Set(buildDirectories);
|
|
368
|
+
const linkedContributors = records
|
|
369
|
+
.filter((record) => record.stage === "transform")
|
|
370
|
+
.flatMap((record) => record.kind === "linked"
|
|
371
|
+
? [{ name: record.linkedContributorName, source: record.source }]
|
|
372
|
+
: []);
|
|
373
|
+
const transformHosts = records.filter((record) => record.stage === "transform" && record.kind === "executable");
|
|
374
|
+
const hostContributors = linkedContributors.length === 0 ? undefined : linkedContributors;
|
|
375
|
+
// Every host compiles the linked sources under its own module/tool context.
|
|
376
|
+
// Equivalent entries in one module share this metadata command and reader;
|
|
377
|
+
// a second executable host can select a genuinely different Go context.
|
|
378
|
+
const admittedExecutables = new Set();
|
|
379
|
+
if (linkedContributors.length !== 0) {
|
|
380
|
+
const hosts = transformHosts.length === 0
|
|
381
|
+
? [
|
|
382
|
+
{
|
|
383
|
+
source: node_path_1.default.join(ttscPackageRoot(), "cmd", "utility-host"),
|
|
384
|
+
label: "linked-plugin-host",
|
|
385
|
+
},
|
|
386
|
+
]
|
|
387
|
+
: transformHosts;
|
|
388
|
+
const contexts = new Map();
|
|
389
|
+
for (const host of hosts) {
|
|
390
|
+
const moduleRoot = (0, resolvePluginGoModule_1.resolvePluginGoModule)(host.source, host.label).moduleRoot;
|
|
391
|
+
let context = contexts.get(moduleRoot);
|
|
392
|
+
if (context === undefined) {
|
|
393
|
+
context = { source: host.source, label: host.label, records: [] };
|
|
394
|
+
contexts.set(moduleRoot, context);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
for (const record of transformHosts)
|
|
398
|
+
contexts.get(record.moduleRoot).records.push(record);
|
|
399
|
+
for (const host of contexts.values()) {
|
|
400
|
+
const moduleHosts = host.records;
|
|
401
|
+
const hostEntries = moduleHosts.map((record) => ({
|
|
402
|
+
entry: (0, resolvePluginGoModule_1.resolvePluginGoModule)(record.source, record.label).entry,
|
|
403
|
+
}));
|
|
404
|
+
const observations = NativeSourcePackages_1.NativeSourcePackages.inspect({
|
|
405
|
+
source: host.source,
|
|
406
|
+
pluginName: host.label,
|
|
451
407
|
env: effectiveEnv,
|
|
452
|
-
|
|
408
|
+
readers: packageReaders,
|
|
453
409
|
identities: sourceIdentities,
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
410
|
+
readings,
|
|
411
|
+
packages: [
|
|
412
|
+
...hostEntries,
|
|
413
|
+
...linkedContributors.map((input) => ({
|
|
414
|
+
...input,
|
|
415
|
+
entry: `./contrib/${input.name}`,
|
|
416
|
+
})),
|
|
417
|
+
],
|
|
418
|
+
});
|
|
419
|
+
moduleHosts.forEach((record, index) => {
|
|
420
|
+
NativeSourcePackages_1.NativeSourcePackages.kind(observations[index], record.label, "executable");
|
|
421
|
+
admittedExecutables.add(record.source);
|
|
462
422
|
});
|
|
463
|
-
|
|
464
|
-
|
|
423
|
+
linkedContributors.forEach((input, index) => {
|
|
424
|
+
NativeSourcePackages_1.NativeSourcePackages.kind(observations[hostEntries.length + index], `${input.name} inside host ${host.label}`, "linked");
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// A nested main proposal still needs its actual owning manifests. Hosts
|
|
429
|
+
// with linked contributors were admitted together above; other equivalent
|
|
430
|
+
// entries share one standalone observation, with no repeated host copy.
|
|
431
|
+
const standaloneCandidates = executableCandidates.filter((candidate) => !admittedExecutables.has(candidate.source));
|
|
432
|
+
const executablePackages = NativeSourcePackages_1.NativeSourcePackages.ownPackages(standaloneCandidates, effectiveEnv, packageReaders, sourceIdentities, readings);
|
|
433
|
+
standaloneCandidates.forEach((candidate, index) => {
|
|
434
|
+
NativeSourcePackages_1.NativeSourcePackages.kind(executablePackages[index], candidate.label, "executable");
|
|
435
|
+
});
|
|
436
|
+
const packageOwnership = (source, label, linked) => [
|
|
437
|
+
{
|
|
438
|
+
entry: (0, resolvePluginGoModule_1.resolvePluginGoModule)(source, label).entry,
|
|
439
|
+
kind: "executable",
|
|
440
|
+
},
|
|
441
|
+
...(linked
|
|
442
|
+
? linkedContributors.map((input) => ({
|
|
443
|
+
entry: `./contrib/${input.name}`,
|
|
444
|
+
kind: "linked",
|
|
445
|
+
}))
|
|
446
|
+
: []),
|
|
447
|
+
];
|
|
448
|
+
const builtTransformHosts = new Map();
|
|
449
|
+
for (const record of transformHosts) {
|
|
450
|
+
builtTransformHosts.set(record, (0, buildSourcePlugin_1.buildSourcePlugin)({
|
|
451
|
+
baseDir: context.projectRoot,
|
|
452
|
+
cacheDir: options.cacheDir,
|
|
453
|
+
contributors: mergeContributors(record.contributors, hostContributors),
|
|
454
|
+
env: effectiveEnv,
|
|
455
|
+
goModReaders: packageReaders,
|
|
456
|
+
identities: sourceIdentities,
|
|
457
|
+
pluginName: record.label,
|
|
458
|
+
packageOwnership: packageOwnership(record.source, record.label, true),
|
|
459
|
+
source: record.source,
|
|
460
|
+
environmentDigests,
|
|
461
|
+
environmentWitnesses,
|
|
462
|
+
sourceDigests,
|
|
463
|
+
ttscVersion,
|
|
464
|
+
tsgoVersion,
|
|
465
|
+
}));
|
|
465
466
|
}
|
|
467
|
+
const fallbackDriverHost = transformHosts.length === 0 && linkedContributors.length !== 0
|
|
468
|
+
? (0, buildSourcePlugin_1.buildSourcePlugin)({
|
|
469
|
+
baseDir: context.projectRoot,
|
|
470
|
+
cacheDir: options.cacheDir,
|
|
471
|
+
contributors: linkedContributors,
|
|
472
|
+
env: effectiveEnv,
|
|
473
|
+
goModReaders: packageReaders,
|
|
474
|
+
identities: sourceIdentities,
|
|
475
|
+
label: "linked plugin host",
|
|
476
|
+
pluginName: "linked-plugin-host",
|
|
477
|
+
source: node_path_1.default.join(ttscPackageRoot(), "cmd", "utility-host"),
|
|
478
|
+
packageOwnership: packageOwnership(node_path_1.default.join(ttscPackageRoot(), "cmd", "utility-host"), "linked-plugin-host", true),
|
|
479
|
+
environmentDigests,
|
|
480
|
+
environmentWitnesses,
|
|
481
|
+
sourceDigests,
|
|
482
|
+
ttscVersion,
|
|
483
|
+
tsgoVersion,
|
|
484
|
+
})
|
|
485
|
+
: undefined;
|
|
486
|
+
const selectedTransformHost = transformHosts.length === 0
|
|
487
|
+
? fallbackDriverHost
|
|
488
|
+
: builtTransformHosts.get(transformHosts[0]);
|
|
489
|
+
const nativePlugins = records.map((record) => {
|
|
490
|
+
const binary = record.stage === "transform" && record.kind === "linked"
|
|
491
|
+
? selectedTransformHost
|
|
492
|
+
: record.stage === "transform"
|
|
493
|
+
? builtTransformHosts.get(record)
|
|
494
|
+
: (0, buildSourcePlugin_1.buildSourcePlugin)({
|
|
495
|
+
baseDir: context.projectRoot,
|
|
496
|
+
cacheDir: options.cacheDir,
|
|
497
|
+
contributors: record.contributors,
|
|
498
|
+
env: effectiveEnv,
|
|
499
|
+
goModReaders: packageReaders,
|
|
500
|
+
identities: sourceIdentities,
|
|
501
|
+
pluginName: record.label,
|
|
502
|
+
packageOwnership: packageOwnership(record.source, record.label, false),
|
|
503
|
+
source: record.source,
|
|
504
|
+
environmentDigests,
|
|
505
|
+
environmentWitnesses,
|
|
506
|
+
sourceDigests,
|
|
507
|
+
ttscVersion,
|
|
508
|
+
tsgoVersion,
|
|
509
|
+
});
|
|
510
|
+
if (binary === undefined) {
|
|
511
|
+
throw new Error(`ttsc: plugin "${record.label}" is a linked Go package, but no compiler host is available`);
|
|
512
|
+
}
|
|
513
|
+
return {
|
|
514
|
+
binary,
|
|
515
|
+
// This fallback is compiled from our utility-host, whose actual writer
|
|
516
|
+
// publishes provenance and supports a separate compiler argument cwd.
|
|
517
|
+
// A separately selected executable host must opt in itself; a linked
|
|
518
|
+
// library cannot certify that foreign host. An undeclared capability
|
|
519
|
+
// only withholds the optional protocol: build execution still runs such
|
|
520
|
+
// a host and observes it from outside, never rejecting it.
|
|
521
|
+
capabilities: record.stage === "transform" &&
|
|
522
|
+
record.kind === "linked" &&
|
|
523
|
+
fallbackDriverHost !== undefined
|
|
524
|
+
? {
|
|
525
|
+
...record.capabilities,
|
|
526
|
+
compilerArgsCwd: true,
|
|
527
|
+
emitProvenance: true,
|
|
528
|
+
}
|
|
529
|
+
: record.capabilities,
|
|
530
|
+
config: record.config,
|
|
531
|
+
contributors: record.contributors,
|
|
532
|
+
kind: record.kind,
|
|
533
|
+
name: record.name,
|
|
534
|
+
reportsTypeScriptDiagnostics: record.reportsTypeScriptDiagnostics,
|
|
535
|
+
source: record.source,
|
|
536
|
+
stage: record.stage,
|
|
537
|
+
};
|
|
538
|
+
});
|
|
466
539
|
return {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
540
|
+
...collectHostInputSnapshot(project, context, records, projectHostInputs, revalidateHostInputHashes(projectHostInputHashes, projectHostInputs), revalidateHostInputRealpaths(projectHostInputRealpaths, projectHostInputs)),
|
|
541
|
+
descriptorReadsDeclared: loadedEntries.every((entry) => entry.observationsComplete && (0, declaresHostInputReads_1.declaresHostInputReads)(entry.plugin)),
|
|
542
|
+
discoveryInputsComplete: project.configInputsComplete === true,
|
|
543
|
+
...(identities === undefined ? {} : { identities }),
|
|
544
|
+
nativePlugins: orderNativePlugins(nativePlugins),
|
|
545
|
+
...(loadedEntries.some((entry) => !entry.observationsComplete)
|
|
546
|
+
? { observationsComplete: false }
|
|
547
|
+
: {}),
|
|
548
|
+
// The directories the watch inputs named before the builds, as the builds
|
|
549
|
+
// read them. Package selection shares these readings and also reads a
|
|
550
|
+
// linked plugin's module root, which no build keys on, so only the build
|
|
551
|
+
// directories are reported.
|
|
552
|
+
pluginSources: Object.fromEntries([...sourceDigests]
|
|
553
|
+
.filter(([directory]) => keyedDirectories.has(directory))
|
|
554
|
+
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
555
|
+
.map(([directory, sourceDigest]) => [
|
|
556
|
+
directory,
|
|
557
|
+
(0, pluginSourceState_1.pluginSourceState)(directory, {
|
|
558
|
+
env: effectiveEnv,
|
|
559
|
+
sourceDigest,
|
|
560
|
+
environment: environmentDigests.get(directory) ??
|
|
561
|
+
(0, pluginBuildEnvironment_1.pluginBuildEnvironment)(directory, effectiveEnv, undefined, sourceIdentities),
|
|
562
|
+
}),
|
|
563
|
+
])),
|
|
564
|
+
project,
|
|
490
565
|
};
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
descriptorReadsDeclared: loadedEntries.every((entry) => entry.observationsComplete && (0, declaresHostInputReads_1.declaresHostInputReads)(entry.plugin)),
|
|
495
|
-
discoveryInputsComplete: project.configInputsComplete === true,
|
|
496
|
-
...(identities === undefined ? {} : { identities }),
|
|
497
|
-
nativePlugins: orderNativePlugins(nativePlugins),
|
|
498
|
-
...(loadedEntries.some((entry) => !entry.observationsComplete)
|
|
499
|
-
? { observationsComplete: false }
|
|
500
|
-
: {}),
|
|
501
|
-
// The directories the watch inputs named before the builds, as the builds
|
|
502
|
-
// read them. Package selection shares these readings and also reads a
|
|
503
|
-
// linked plugin's module root, which no build keys on, so only the build
|
|
504
|
-
// directories are reported.
|
|
505
|
-
pluginSources: Object.fromEntries([...sourceDigests]
|
|
506
|
-
.filter(([directory]) => keyedDirectories.has(directory))
|
|
507
|
-
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
508
|
-
.map(([directory, sourceDigest]) => [
|
|
509
|
-
directory,
|
|
510
|
-
(0, pluginSourceState_1.pluginSourceState)(directory, {
|
|
511
|
-
env: effectiveEnv,
|
|
512
|
-
sourceDigest,
|
|
513
|
-
environment: environmentDigests.get(directory) ??
|
|
514
|
-
(0, pluginBuildEnvironment_1.pluginBuildEnvironment)(directory, effectiveEnv, undefined, sourceIdentities),
|
|
515
|
-
}),
|
|
516
|
-
])),
|
|
517
|
-
project,
|
|
518
|
-
};
|
|
519
|
-
}
|
|
566
|
+
}
|
|
567
|
+
loadProjectPlugins.steps = steps;
|
|
568
|
+
})(loadProjectPlugins || (exports.loadProjectPlugins = loadProjectPlugins = {}));
|
|
520
569
|
/**
|
|
521
570
|
* Collect exact JavaScript-host files that universally influence the loaded
|
|
522
571
|
* transform. Program files belong to the native reference graph; this list is
|
|
@@ -597,16 +646,16 @@ function collectHostInputSnapshot(project, context, records, baselineInputs, bas
|
|
|
597
646
|
* cache proof for the ambiguous snapshot.
|
|
598
647
|
*/
|
|
599
648
|
function readProjectHostInputSnapshot(options) {
|
|
600
|
-
const { includePluginDiscovery, ...projectOptions } = options;
|
|
649
|
+
const { includePluginDiscovery, pluginConfigDir, ...projectOptions } = options;
|
|
601
650
|
let project = (0, readProjectConfig_1.readProjectConfig)(projectOptions);
|
|
602
|
-
let hostInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(project, includePluginDiscovery);
|
|
651
|
+
let hostInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(project, includePluginDiscovery, pluginConfigDir);
|
|
603
652
|
const observedInputs = new Set(hostInputs);
|
|
604
653
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
605
654
|
const before = (0, hashHostInputPaths_1.hashHostInputPaths)(hostInputs);
|
|
606
655
|
const beforeRealpaths = (0, realpathHostInputPaths_1.realpathHostInputPaths)(hostInputs);
|
|
607
656
|
const beforeSignatures = hostInputMetadataSignatures(hostInputs);
|
|
608
657
|
const candidateProject = (0, readProjectConfig_1.readProjectConfig)(projectOptions);
|
|
609
|
-
const candidateInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(candidateProject, includePluginDiscovery);
|
|
658
|
+
const candidateInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(candidateProject, includePluginDiscovery, pluginConfigDir);
|
|
610
659
|
for (const input of candidateInputs)
|
|
611
660
|
observedInputs.add(input);
|
|
612
661
|
const after = (0, hashHostInputPaths_1.hashHostInputPaths)(candidateInputs);
|
|
@@ -927,7 +976,7 @@ function loadPluginDescriptor(request, context, effectiveEnv, descriptorCache) {
|
|
|
927
976
|
!error.retryWithTtsx) {
|
|
928
977
|
throw error;
|
|
929
978
|
}
|
|
930
|
-
const loaded = loadDescriptorViaTtsx(request, context, effectiveEnv, descriptorCache
|
|
979
|
+
const loaded = loadDescriptorViaTtsx(request, context, effectiveEnv, descriptorCache);
|
|
931
980
|
if (loaded === undefined) {
|
|
932
981
|
throw error;
|
|
933
982
|
}
|
|
@@ -957,20 +1006,26 @@ class CommonJsDescriptorLoadError extends Error {
|
|
|
957
1006
|
* (`PluginDescriptorEvaluationCache`): an unchanged project pays a proof of its
|
|
958
1007
|
* descriptor inputs instead of a runtime start and a graph load.
|
|
959
1008
|
*/
|
|
960
|
-
function loadCommonJsDescriptor(request, context,
|
|
1009
|
+
function loadCommonJsDescriptor(request, context, loadEnv, descriptorCache) {
|
|
1010
|
+
// The evaluator is ttsc's own helper: inside a ttsx run it gets the user's
|
|
1011
|
+
// NODE_OPTIONS, not ttsx's preloads, which would refuse the descriptor cache
|
|
1012
|
+
// and run in every evaluation (#1740). The runtime probe below does the same.
|
|
1013
|
+
const effectiveEnv = TtsxNodeOptions_1.TtsxNodeOptions.forHelpers(loadEnv);
|
|
961
1014
|
const runtime = pluginDescriptorRuntimeBinary(effectiveEnv);
|
|
962
1015
|
const ttsx = effectiveEnv.TTSC_TTSX_BINARY ?? process.env.TTSC_TTSX_BINARY;
|
|
963
|
-
const runtimeCapabilities = (0, javascriptRuntimeCapabilities_1.javascriptRuntimeCapabilities)(runtime, effectiveEnv,
|
|
1016
|
+
const runtimeCapabilities = (0, javascriptRuntimeCapabilities_1.javascriptRuntimeCapabilities)(runtime, effectiveEnv, descriptorCache.projectRoot, descriptorCache.identities);
|
|
964
1017
|
const node = !runtimeCapabilities.bun &&
|
|
965
1018
|
runtimeCapabilities.registerHooks &&
|
|
966
1019
|
runtimeCapabilities.executable !== undefined
|
|
967
1020
|
? runtimeCapabilities.executable
|
|
968
|
-
: (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv,
|
|
1021
|
+
: (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv, descriptorCache.projectRoot, descriptorCache.identities);
|
|
969
1022
|
const cacheAuthority = {
|
|
970
1023
|
additionalRuntime: node,
|
|
971
1024
|
cacheDir: descriptorCache.cacheDir,
|
|
972
1025
|
identities: descriptorCache.identities,
|
|
973
1026
|
context,
|
|
1027
|
+
// Factory context anchors the consumer; the evaluator runs at the source root.
|
|
1028
|
+
cwd: descriptorCache.projectRoot,
|
|
974
1029
|
// Everything the child receives besides the per-evaluation output paths.
|
|
975
1030
|
env: {
|
|
976
1031
|
...effectiveEnv,
|
|
@@ -978,7 +1033,7 @@ function loadCommonJsDescriptor(request, context, effectiveEnv, descriptorCache)
|
|
|
978
1033
|
...descriptorRecordRoot(descriptorCache.identities),
|
|
979
1034
|
TTSC_TTSX_BINARY: ttsx,
|
|
980
1035
|
},
|
|
981
|
-
projectRoot:
|
|
1036
|
+
projectRoot: descriptorCache.projectRoot,
|
|
982
1037
|
request,
|
|
983
1038
|
runtime,
|
|
984
1039
|
version: descriptorCache.version,
|
|
@@ -1044,7 +1099,7 @@ function loadCommonJsDescriptor(request, context, effectiveEnv, descriptorCache)
|
|
|
1044
1099
|
...(runtimeCapabilities.bun ? [] : ["--input-type", ""]),
|
|
1045
1100
|
shim,
|
|
1046
1101
|
], {
|
|
1047
|
-
cwd:
|
|
1102
|
+
cwd: descriptorCache.projectRoot,
|
|
1048
1103
|
env: {
|
|
1049
1104
|
...effectiveEnv,
|
|
1050
1105
|
// The direct evaluator may be Bun, but ttsx and native config
|
|
@@ -1307,11 +1362,11 @@ const TS_SOURCE_PATTERN = /\.(?:[cm]?ts|tsx)$/i;
|
|
|
1307
1362
|
* shim with plugins disabled across the whole graph. Returns `undefined` when
|
|
1308
1363
|
* `ttsx` is unavailable, so the caller can rethrow the original load error.
|
|
1309
1364
|
*/
|
|
1310
|
-
function loadDescriptorViaTtsx(request, context, effectiveEnv,
|
|
1365
|
+
function loadDescriptorViaTtsx(request, context, effectiveEnv, descriptorCache) {
|
|
1311
1366
|
// Binary discovery prefers the instance environment, then the ambient
|
|
1312
1367
|
// process.env (where `withPluginLoaderEnv` injects ttsc's own node/ttsx paths
|
|
1313
1368
|
// just before this runs), then the running interpreter.
|
|
1314
|
-
const node = (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv,
|
|
1369
|
+
const node = (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv, descriptorCache.projectRoot, descriptorCache.identities);
|
|
1315
1370
|
const ttsx = effectiveEnv.TTSC_TTSX_BINARY ?? process.env.TTSC_TTSX_BINARY;
|
|
1316
1371
|
if (node === undefined || ttsx === undefined || ttsx.length === 0) {
|
|
1317
1372
|
return undefined;
|
|
@@ -1332,9 +1387,9 @@ function loadDescriptorViaTtsx(request, context, effectiveEnv, identities) {
|
|
|
1332
1387
|
},
|
|
1333
1388
|
}));
|
|
1334
1389
|
node_fs_1.default.writeFileSync(shim, PLUGIN_DESCRIPTOR_SHIM_SOURCE_1.PLUGIN_DESCRIPTOR_SHIM_SOURCE);
|
|
1335
|
-
const trace = E2ETrace_1.E2ETrace.begin(node, [ttsx, "--no-plugins", shim], { cwd:
|
|
1390
|
+
const trace = E2ETrace_1.E2ETrace.begin(node, [ttsx, "--no-plugins", shim], { cwd: descriptorCache.projectRoot }, "plugin-descriptor");
|
|
1336
1391
|
const result = spawnOwnedDescriptor(node, [ttsx, "--no-plugins", shim], {
|
|
1337
|
-
cwd:
|
|
1392
|
+
cwd: descriptorCache.projectRoot,
|
|
1338
1393
|
encoding: "utf8",
|
|
1339
1394
|
env: {
|
|
1340
1395
|
...effectiveEnv,
|
|
@@ -1342,7 +1397,7 @@ function loadDescriptorViaTtsx(request, context, effectiveEnv, identities) {
|
|
|
1342
1397
|
// may recurse into further descriptor loads) finds them even when the
|
|
1343
1398
|
// instance-env snapshot predates `withPluginLoaderEnv`.
|
|
1344
1399
|
TTSC_NODE_BINARY: node,
|
|
1345
|
-
...descriptorRecordRoot(identities),
|
|
1400
|
+
...descriptorRecordRoot(descriptorCache.identities),
|
|
1346
1401
|
TTSC_TTSX_BINARY: ttsx,
|
|
1347
1402
|
TTSC_PLUGIN_CONTEXT: JSON.stringify({
|
|
1348
1403
|
binary: context.binary,
|
|
@@ -1625,12 +1680,12 @@ function resolvePluginSource(source, projectRoot) {
|
|
|
1625
1680
|
* that it replaces a module with, which the build compiles in place
|
|
1626
1681
|
* (`pluginModuleReplaceDirectories`).
|
|
1627
1682
|
*/
|
|
1628
|
-
function pluginBuildDirectories(records, env, replacements, readers) {
|
|
1683
|
+
function pluginBuildDirectories(records, env, replacements, readers, identities) {
|
|
1629
1684
|
const directories = new Set();
|
|
1630
1685
|
for (const record of records) {
|
|
1631
1686
|
directories.add(node_path_1.default.resolve(record.kind === "linked" ? record.packageDir : record.moduleRoot));
|
|
1632
1687
|
if (record.kind === "executable") {
|
|
1633
|
-
for (const directory of pluginReplacementWatchDirectories(record.moduleRoot, env, replacements, readers))
|
|
1688
|
+
for (const directory of pluginReplacementWatchDirectories(record.moduleRoot, env, replacements, readers, identities))
|
|
1634
1689
|
directories.add(directory);
|
|
1635
1690
|
}
|
|
1636
1691
|
for (const contributor of record.contributors ?? [])
|
|
@@ -1643,13 +1698,14 @@ function pluginBuildDirectories(records, env, replacements, readers) {
|
|
|
1643
1698
|
* The load shares this best-effort watch projection, not package validity or a
|
|
1644
1699
|
* cross-load manifest cache. Go metadata/build admission still owns errors.
|
|
1645
1700
|
*/
|
|
1646
|
-
function pluginReplacementWatchDirectories(moduleRoot, env, observed, readers) {
|
|
1701
|
+
function pluginReplacementWatchDirectories(moduleRoot, env, observed, readers, identities) {
|
|
1647
1702
|
const previous = observed?.get(moduleRoot);
|
|
1648
1703
|
if (previous !== undefined)
|
|
1649
1704
|
return previous;
|
|
1650
1705
|
let directories;
|
|
1651
1706
|
try {
|
|
1652
|
-
|
|
1707
|
+
// The load's store goes with the reader this registers first (#1739).
|
|
1708
|
+
directories = (0, pluginModuleReplaceDirectories_1.pluginModuleReplaceDirectories)(moduleRoot, env, undefined, undefined, readers, identities).map((replacement) => replacement.directory);
|
|
1653
1709
|
}
|
|
1654
1710
|
catch {
|
|
1655
1711
|
// An unreadable manifest/tool is not valid metadata. The already observed
|