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
|
@@ -68,11 +68,13 @@ export function compileProjectInMemory(options: ITtscCompilerContext): {
|
|
|
68
68
|
return compileProjectWithPlugins(options, cwd, project);
|
|
69
69
|
}
|
|
70
70
|
const tsconfig = project.path;
|
|
71
|
+
const env = inheritedSidecarEnv(options.env, options.binary);
|
|
71
72
|
const binary = buildNativeCompiler({
|
|
72
73
|
cacheBaseDir: project.root,
|
|
73
74
|
cacheDir:
|
|
74
75
|
options.cacheDir ??
|
|
75
76
|
SidecarEnvironment.read(options.env, "TTSC_CACHE_DIR"),
|
|
77
|
+
env,
|
|
76
78
|
packageRoot: packageRootDir(),
|
|
77
79
|
});
|
|
78
80
|
const res = spawnNative(
|
|
@@ -80,7 +82,7 @@ export function compileProjectInMemory(options: ITtscCompilerContext): {
|
|
|
80
82
|
["api-compile", "--cwd", project.root, "--tsconfig", tsconfig],
|
|
81
83
|
{
|
|
82
84
|
cwd: project.root,
|
|
83
|
-
env
|
|
85
|
+
env,
|
|
84
86
|
},
|
|
85
87
|
);
|
|
86
88
|
if (res.error) {
|
|
@@ -110,7 +112,11 @@ function hasConfiguredPlugins(
|
|
|
110
112
|
options: ITtscCompilerContext,
|
|
111
113
|
project: ITtscParsedProjectConfig,
|
|
112
114
|
): boolean {
|
|
113
|
-
return hasProjectPluginEntries(
|
|
115
|
+
return hasProjectPluginEntries(
|
|
116
|
+
project,
|
|
117
|
+
options.plugins,
|
|
118
|
+
options.pluginConfigDir,
|
|
119
|
+
);
|
|
114
120
|
}
|
|
115
121
|
|
|
116
122
|
/**
|
|
@@ -24,11 +24,11 @@ export namespace CompilerProjectSelection {
|
|
|
24
24
|
* Resolve one compiler project without rebasing its original argument frame.
|
|
25
25
|
*
|
|
26
26
|
* Validated visible selectors retain their positions beside original response
|
|
27
|
-
* tokens. The existing observed inspector projects those frames for
|
|
28
|
-
* the native producer still receives their original bytes and owns
|
|
29
|
-
* Positional discovery starts at the supplied file until an
|
|
30
|
-
* assignment selects another config. Explicit
|
|
31
|
-
* their independent API authority.
|
|
27
|
+
* tokens. The existing observed inspector projects those frames for
|
|
28
|
+
* selection; the native producer still receives their original bytes and owns
|
|
29
|
+
* validation. Positional discovery starts at the supplied file until an
|
|
30
|
+
* observed project assignment selects another config. Explicit
|
|
31
|
+
* resolvedProject callers retain their independent API authority.
|
|
32
32
|
* Observations are sequential and do not pin bytes across a later producer.
|
|
33
33
|
*
|
|
34
34
|
* @evidence contracts/common.md#principled-implementation Existing schema occurrence metadata and observed response inspection establish ordered canonical project assignments; one selected config is returned separately from the retained compiler argument cwd.
|
|
@@ -49,7 +49,8 @@ export namespace CompilerProjectSelection {
|
|
|
49
49
|
},
|
|
50
50
|
) {
|
|
51
51
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
52
|
-
const file =
|
|
52
|
+
const file =
|
|
53
|
+
options.file ??
|
|
53
54
|
(options.files?.length === 1 ? options.files[0] : undefined);
|
|
54
55
|
let initial = options.resolvedProject?.identity;
|
|
55
56
|
let initialError: unknown;
|
|
@@ -117,7 +118,8 @@ export namespace CompilerProjectSelection {
|
|
|
117
118
|
if (responseFrames.length !== 0 && inspectionError === undefined) {
|
|
118
119
|
projectGuard = ["-p", project.path];
|
|
119
120
|
} else if (
|
|
120
|
-
options.resolvedProject !== undefined &&
|
|
121
|
+
options.resolvedProject !== undefined &&
|
|
122
|
+
assignments.has("project")
|
|
121
123
|
) {
|
|
122
124
|
// A reporting/selection guard must not become a missing top-level scalar
|
|
123
125
|
// operand. An unsafe native request retains its original diagnostic frame.
|
|
@@ -141,8 +143,8 @@ export namespace CompilerProjectSelection {
|
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
/**
|
|
144
|
-
* Reject a changed response generation before a consumer publishes or runs
|
|
145
|
-
* This is a sequential reobservation, not an atomic producer snapshot.
|
|
146
|
+
* Reject a changed response generation before a consumer publishes or runs
|
|
147
|
+
* it. This is a sequential reobservation, not an atomic producer snapshot.
|
|
146
148
|
*
|
|
147
149
|
* @evidence contracts/common.md#principled-implementation Current physical/content observations must match every response input admitted by this selection before its consumer proceeds.
|
|
148
150
|
* @evidence contracts/common.md#clear-and-simple-design One loop delegates actual file observation to the existing owner and propagates read failures.
|
|
@@ -154,10 +156,7 @@ export namespace CompilerProjectSelection {
|
|
|
154
156
|
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Synchronous observation retains no handle or history; the selection belongs to its caller.
|
|
155
157
|
*/
|
|
156
158
|
export function assertCurrent(
|
|
157
|
-
selection: Pick<
|
|
158
|
-
ReturnType<typeof read>,
|
|
159
|
-
"observations"
|
|
160
|
-
>,
|
|
159
|
+
selection: Pick<ReturnType<typeof read>, "observations">,
|
|
161
160
|
): void {
|
|
162
161
|
for (const [file, observation] of selection.observations)
|
|
163
162
|
if (CompilerArgumentsInspection.observeInputFile(file) !== observation)
|
|
@@ -169,7 +168,8 @@ export namespace CompilerProjectSelection {
|
|
|
169
168
|
/**
|
|
170
169
|
* Pin an established project only after the current forwarded frame is safe.
|
|
171
170
|
* A phase may filter or extend argv after context acquisition; it must retain
|
|
172
|
-
* that live payload without letting a final flag satisfy an incomplete
|
|
171
|
+
* that live payload without letting a final flag satisfy an incomplete
|
|
172
|
+
* scalar.
|
|
173
173
|
*
|
|
174
174
|
* @evidence contracts/common.md#principled-implementation An unchanged observed frame reuses its admitted guard; changed phase arguments receive the existing conservative inspection before the selected project can be pinned.
|
|
175
175
|
* @evidence contracts/common.md#clear-and-simple-design One guard reader preserves live argv and the context's selected project without duplicating option arity or response grammar.
|
|
@@ -39,16 +39,21 @@ import { selectReferencedProject } from "./selectReferencedProject";
|
|
|
39
39
|
* realpaths and case capabilities, retaining best-effort spelling when native
|
|
40
40
|
* identity lookup is unavailable.
|
|
41
41
|
*
|
|
42
|
-
* Graph observations are shared only within this lookup
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
*
|
|
42
|
+
* Graph observations are shared only within this lookup, unless the caller
|
|
43
|
+
* hands in `expansions`, which keeps each config's expanded roots for as long
|
|
44
|
+
* as the caller keeps the map. Later requests can otherwise see changed
|
|
45
|
+
* configs, inherited options, directory membership or compiler inputs; a config
|
|
46
|
+
* pathname alone cannot establish that the expansion is still valid. A file
|
|
47
|
+
* created after a kept expansion was taken is still expanded for afresh. The
|
|
48
|
+
* callback observes direct config reads, not every inherited config or compiler
|
|
49
|
+
* input consulted by expansion. Synchronous compiler work has no explicit
|
|
50
|
+
* execution deadline in this operation.
|
|
48
51
|
*
|
|
49
52
|
* @param props.tsconfig - The config project discovery found for the file.
|
|
50
53
|
* @param props.file - The file whose project is asked for.
|
|
51
54
|
* @param props.binary - An explicit TypeScript-Go binary, when one was given.
|
|
55
|
+
* @param props.env - Complete environment shared by compiler selection and
|
|
56
|
+
* root-file expansion; omission inherits the current process environment.
|
|
52
57
|
* @param props.onConfig - Called with every config this reads, so a caller that
|
|
53
58
|
* fingerprints its inputs can record them.
|
|
54
59
|
* @evidence contracts/common.md#principled-implementation Successful compiler showConfig supplies root membership observations, best-effort filesystem identity compares aliases, and visited identity keys terminate repeated graph states while declaration-order DFS selects the first observed containing project. Failed observations preserve the discovered fallback without certifying membership.
|
|
@@ -57,8 +62,8 @@ import { selectReferencedProject } from "./selectReferencedProject";
|
|
|
57
62
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs state ownership order, fallback, callbacks and lookup-scoped reuse, with parameter explanations separated from acknowledgments.
|
|
58
63
|
* @evidence contracts/portability.md#os-neutral-implementation Node path operations select native config spellings, actual filesystem identity compares target and roots, and spawnNative owns executable representation rather than applying OS-name case guesses.
|
|
59
64
|
* @evidence contracts/performance.md#efficient-algorithms Each distinct observed config identity key is visited once in the DFS and receives at most one expansion plus one ctime-based retry; ctime can change for metadata updates as well as creation. Direct config reads/parsing, reference path text/stat work, delegated identity/case probes and binary selection precede or accompany compiler execution. Root-list decoding and membership scans cost their bytes and entries; DFS stack depth follows the reference chain and native recursion limits still apply. The no-reference path avoids a compiler subprocess, not config I/O.
|
|
60
|
-
* @evidence contracts/performance.md#reuse-equivalent-work The lookup reuses discovered reference edges and filesystem identity observations; visited keys prevent expansion of a repeated observed identity, while later requests rerun because paths alone cannot prove unchanged inheritance, directory membership or compiler selection. Best-effort identity cannot guarantee deduplication of every physical alias.
|
|
61
|
-
* @evidence contracts/performance.md#bound-retention-and-release-resources Identity maps, visited keys and root observations are lookup-local
|
|
65
|
+
* @evidence contracts/performance.md#reuse-equivalent-work The lookup reuses discovered reference edges and filesystem identity observations; visited keys prevent expansion of a repeated observed identity, while later requests rerun because paths alone cannot prove unchanged inheritance, directory membership or compiler selection, unless the caller keeps expansions for a lifetime its own builds already assume. Best-effort identity cannot guarantee deduplication of every physical alias.
|
|
66
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources Identity maps, visited keys and root observations are lookup-local; only a caller-supplied expansions map retains root lists, one per config, for the caller's lifetime. Synchronous expansion delegates capture cleanup to spawnNative's finally path, whose cleanup failures are suppressed; output storage and child duration have no configured ceiling here. A nonterminating child prevents the lookup from finishing, rather than being released by this graph traversal.
|
|
62
67
|
*/
|
|
63
68
|
export function resolveOwningProjectConfig(props: {
|
|
64
69
|
/** Absolute or invocation-relative spelling of the discovered config. */
|
|
@@ -73,8 +78,19 @@ export function resolveOwningProjectConfig(props: {
|
|
|
73
78
|
*/
|
|
74
79
|
binary?: string;
|
|
75
80
|
|
|
81
|
+
/** Complete environment for compiler selection and root-file expansion. */
|
|
82
|
+
env?: NodeJS.ProcessEnv;
|
|
83
|
+
|
|
76
84
|
/** Observe each directly read config, including ones with no reference edges. */
|
|
77
85
|
onConfig?: (config: string) => void;
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Expanded root files kept across lookups, by config path, for a caller whose
|
|
89
|
+
* selected builds and compiler environment already hold for the same
|
|
90
|
+
* lifetime: ttsx builds each owning project once per process
|
|
91
|
+
* (samchon/ttsc#1747).
|
|
92
|
+
*/
|
|
93
|
+
expansions?: Map<string, { files: readonly string[]; takenAt: number }>;
|
|
78
94
|
}): string {
|
|
79
95
|
const discovered = path.resolve(props.tsconfig);
|
|
80
96
|
const discoveredReferences = readReferences(discovered, props.onConfig);
|
|
@@ -108,14 +124,19 @@ export function resolveOwningProjectConfig(props: {
|
|
|
108
124
|
* root observations.
|
|
109
125
|
*/
|
|
110
126
|
function contains(config: string): boolean {
|
|
111
|
-
const roots =
|
|
127
|
+
const roots = props.expansions?.get(config) ?? expand(config);
|
|
112
128
|
if (listed(roots)) return true;
|
|
113
129
|
// Recent ctime permits one retry after a miss; it can reflect a metadata
|
|
114
|
-
// change rather than creation and is not an atomic freshness proof.
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
130
|
+
// change rather than creation and is not an atomic freshness proof. A kept
|
|
131
|
+
// expansion taken before the file appeared is retried the same way.
|
|
132
|
+
return createdSince(props.file, roots.takenAt) && listed(expand(config));
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/** Expand `config` now, and keep the expansion when the caller asked to. */
|
|
136
|
+
function expand(config: string): RootFiles {
|
|
137
|
+
const roots = rootFiles(config, props.binary, props.env);
|
|
138
|
+
props.expansions?.set(config, roots);
|
|
139
|
+
return roots;
|
|
119
140
|
}
|
|
120
141
|
return selectReferencedProject(discovered, discoveredReferences, {
|
|
121
142
|
identity: (config) => identities.resolve(config).key,
|
|
@@ -199,14 +220,19 @@ interface RootFiles {
|
|
|
199
220
|
* include approximation or permanent failed answer substitutes for compiler
|
|
200
221
|
* behavior.
|
|
201
222
|
*/
|
|
202
|
-
function rootFiles(
|
|
223
|
+
function rootFiles(
|
|
224
|
+
config: string,
|
|
225
|
+
binary: string | undefined,
|
|
226
|
+
env: NodeJS.ProcessEnv | undefined,
|
|
227
|
+
): RootFiles {
|
|
203
228
|
const takenAt = Date.now();
|
|
204
229
|
let files: string[] = [];
|
|
205
230
|
try {
|
|
206
231
|
const directory = path.dirname(config);
|
|
207
|
-
const tsgo = resolveTsgo({ binary, cwd: directory });
|
|
232
|
+
const tsgo = resolveTsgo({ binary, cwd: directory, env });
|
|
208
233
|
const result = spawnNative(tsgo.binary, ["-p", config, "--showConfig"], {
|
|
209
234
|
cwd: directory,
|
|
235
|
+
env,
|
|
210
236
|
encoding: "utf8",
|
|
211
237
|
});
|
|
212
238
|
if (result.status === 0) {
|
|
@@ -84,7 +84,7 @@ export function readEffectiveCompilerOptions(
|
|
|
84
84
|
} catch {
|
|
85
85
|
return null;
|
|
86
86
|
}
|
|
87
|
-
const tsgo = resolveTsgo({ cwd: project.root, binary });
|
|
87
|
+
const tsgo = resolveTsgo({ cwd: project.root, binary, env });
|
|
88
88
|
const result = spawnNative(
|
|
89
89
|
tsgo.binary,
|
|
90
90
|
["-p", project.path, ...passthrough, "-p", project.path, "--showConfig"],
|
|
@@ -29,7 +29,10 @@ import { SidecarEnvironment } from "./sharedHost/SidecarEnvironment";
|
|
|
29
29
|
* @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Resolution owns no persistent map, descriptor or task and returns only the selected path spelling.
|
|
30
30
|
*/
|
|
31
31
|
export function resolveBinary(
|
|
32
|
-
opts: {
|
|
32
|
+
opts: {
|
|
33
|
+
/** Complete selection environment; omission reads the current process. */
|
|
34
|
+
env?: NodeJS.ProcessEnv;
|
|
35
|
+
} = {},
|
|
33
36
|
): string | null {
|
|
34
37
|
const env = opts.env ?? process.env;
|
|
35
38
|
const explicit = SidecarEnvironment.read(env, "TTSC_BINARY");
|
|
@@ -41,6 +41,13 @@ export function resolveTsgo(
|
|
|
41
41
|
|
|
42
42
|
/** Directory from which to discover `typescript`. */
|
|
43
43
|
cwd?: string;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Complete environment for executable selection; omission reads the current
|
|
47
|
+
* process environment. Public compiler owners merge caller overrides before
|
|
48
|
+
* invoking this resolver, retaining their original overlay for channel
|
|
49
|
+
* ownership.
|
|
50
|
+
*/
|
|
44
51
|
env?: NodeJS.ProcessEnv;
|
|
45
52
|
|
|
46
53
|
/**
|
|
@@ -4,10 +4,12 @@ import path from "node:path";
|
|
|
4
4
|
import { createCanonicalTempDirectory } from "../../internal/createCanonicalTempDirectory";
|
|
5
5
|
import type { TtscSingleFileEmitOptions } from "../../structures/internal/TtscSingleFileEmitOptions";
|
|
6
6
|
import { EmitOwnershipIndex } from "./EmitOwnershipIndex";
|
|
7
|
+
import { WatchInputPublication } from "./build/WatchInputPublication";
|
|
7
8
|
import { runBuild } from "./build/runBuild";
|
|
8
9
|
import { CompilerProjectSelection } from "./project/CompilerProjectSelection";
|
|
9
10
|
import { readProjectConfig } from "./project/readProjectConfig";
|
|
10
11
|
import { readEffectiveCompilerOptions } from "./readEffectiveCompilerOptions";
|
|
12
|
+
import { SidecarEnvironment } from "./sharedHost/SidecarEnvironment";
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* Emit one source file by building its project into a temporary directory.
|
|
@@ -20,10 +22,12 @@ import { readEffectiveCompilerOptions } from "./readEffectiveCompilerOptions";
|
|
|
20
22
|
* failure propagates on success and is aggregated with an earlier operation
|
|
21
23
|
* failure rather than replacing it.
|
|
22
24
|
*
|
|
23
|
-
* A launcher-supplied selection shares its project and original compiler
|
|
24
|
-
* cwd with public output planning. Response freshness is checked
|
|
25
|
-
* work and publication; these sequential checks do not pin bytes
|
|
26
|
-
* Callers without that record retain explicit config/nearest-file
|
|
25
|
+
* A launcher-supplied selection shares its project and original compiler
|
|
26
|
+
* argument cwd with public output planning. Response freshness is checked
|
|
27
|
+
* before native work and publication; these sequential checks do not pin bytes
|
|
28
|
+
* atomically. Callers without that record retain explicit config/nearest-file
|
|
29
|
+
* discovery. Watch-input handlers must complete synchronously; use
|
|
30
|
+
* {@link runSingleFileEmit.async} for promise-returning handlers.
|
|
27
31
|
*
|
|
28
32
|
* @returns The transformed JavaScript source text.
|
|
29
33
|
* @throws When the build exits non-zero, proves no JavaScript for the requested
|
|
@@ -43,107 +47,147 @@ export function runSingleFileEmit(
|
|
|
43
47
|
options: TtscSingleFileEmitOptions,
|
|
44
48
|
selection?: ReturnType<typeof CompilerProjectSelection.read>,
|
|
45
49
|
): string {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
options
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
50
|
+
return WatchInputPublication.run(runSingleFileEmit.steps(options, selection));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Keep synchronous and awaited single-file emission on one temporary lifetime.
|
|
55
|
+
*
|
|
56
|
+
* @evidence contracts/common.md#principled-implementation Both entries share project/root selection, producing build, response freshness, provenance lookup and temporary-output cleanup; awaited completion joins every nested publication before compilation and output selection.
|
|
57
|
+
* @evidence contracts/common.md#clear-and-simple-design One generator owns project emission, optional public output and cleanup for both completion modes; the companion adds a runner without another output-selection implementation.
|
|
58
|
+
* @evidence contracts/common.md#prohibited-implementation-shortcuts Pending registration cannot authorize a build, and rejected publication reaches the same temporary cleanup path. Completion mode preserves response checks and provenance instead of reconstructing source ownership from filenames.
|
|
59
|
+
* @evidence contracts/common.md#meaningful-documentation Each entry states completion mode and the shared temporary lifetime; sequence prose requires rejection delivery into its finally path, while the primary entry documents output selection and cleanup failures.
|
|
60
|
+
* @evidence contracts/portability.md#os-neutral-implementation The shared sequence retains existing native source/output identity, cwd bases and private-directory handling across suspension without another native boundary.
|
|
61
|
+
* @evidence contracts/performance.md#efficient-algorithms One project selection and full-project build serve one provenance lookup; each handoff is awaited once with no additional source or output traversal.
|
|
62
|
+
* @evidenceExclude contracts/performance.md#reuse-equivalent-work Each sequence owns fresh compiler effects rather than an output cache or shared generation; higher-level owners decide equivalent build reuse.
|
|
63
|
+
* @evidence contracts/performance.md#bound-retention-and-release-resources One accepted private output directory spans nested handoff and build work, and the existing finally path removes it on success or failure and preserves cleanup error aggregation.
|
|
64
|
+
*/
|
|
65
|
+
export namespace runSingleFileEmit {
|
|
66
|
+
/**
|
|
67
|
+
* Await watch-input registration before emitting and selecting one source's
|
|
68
|
+
* JavaScript. Rejected publication follows the same temporary cleanup path.
|
|
69
|
+
*/
|
|
70
|
+
export function async(
|
|
71
|
+
options: TtscSingleFileEmitOptions,
|
|
72
|
+
selection?: ReturnType<typeof CompilerProjectSelection.read>,
|
|
73
|
+
): Promise<string> {
|
|
74
|
+
return WatchInputPublication.runAsync(steps(options, selection));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Emit through one selected project while suspending at watch handoffs.
|
|
79
|
+
* Internal completion runners must deliver rejection into this sequence so
|
|
80
|
+
* its finally block retains temporary-output cleanup ownership.
|
|
81
|
+
*/
|
|
82
|
+
export function* steps(
|
|
83
|
+
options: TtscSingleFileEmitOptions,
|
|
84
|
+
selection?: ReturnType<typeof CompilerProjectSelection.read>,
|
|
85
|
+
): WatchInputPublication.Sequence<string> {
|
|
86
|
+
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
87
|
+
const sourceFile = realpathIfExists(
|
|
88
|
+
path.isAbsolute(options.file)
|
|
89
|
+
? options.file
|
|
90
|
+
: path.resolve(cwd, options.file),
|
|
91
|
+
);
|
|
92
|
+
const project =
|
|
93
|
+
selection?.project ??
|
|
94
|
+
readProjectConfig({
|
|
95
|
+
cwd,
|
|
96
|
+
file: options.file,
|
|
97
|
+
projectRoot: options.projectRoot,
|
|
98
|
+
tsconfig: options.tsconfig,
|
|
99
|
+
});
|
|
100
|
+
const tsconfig = project.path;
|
|
101
|
+
const compilerArgsCwd = selection?.compilerArgsCwd ?? project.root;
|
|
102
|
+
if (selection !== undefined)
|
|
103
|
+
CompilerProjectSelection.assertCurrent(selection);
|
|
104
|
+
// The root tsgo lays the outputs against: a `--rootDir` forwarded on the
|
|
105
|
+
// command line, which reaches it after the config; otherwise the declared
|
|
106
|
+
// one, which `readProjectConfig` already absolutized; otherwise the project's
|
|
107
|
+
// own directory, which `pinInferredRootDir` hands it below.
|
|
108
|
+
const effective = readEffectiveCompilerOptions(
|
|
109
|
+
project,
|
|
110
|
+
options.passthrough,
|
|
111
|
+
options.binary,
|
|
112
|
+
SidecarEnvironment.merge(process.env, options.env),
|
|
86
113
|
compilerArgsCwd,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
pinInferredRootDir: true,
|
|
98
|
-
resolvedProject: project,
|
|
99
|
-
tsconfig,
|
|
100
|
-
});
|
|
101
|
-
if (result.status !== 0) {
|
|
102
|
-
throw new Error(
|
|
103
|
-
"ttsc single-file emit exited " +
|
|
104
|
-
result.status +
|
|
105
|
-
"\n" +
|
|
106
|
-
(result.stderr || result.stdout),
|
|
107
|
-
);
|
|
108
|
-
}
|
|
109
|
-
const emitted = new EmitOwnershipIndex({
|
|
110
|
-
emitDir: outDir,
|
|
111
|
-
rootDir,
|
|
112
|
-
emittedSources: result.emittedSources,
|
|
113
|
-
emittedSourceProofFailures: result.emittedSourceProofFailures,
|
|
114
|
-
outputs: EmitOwnershipIndex.listOutputs(outDir),
|
|
115
|
-
}).find(sourceFile);
|
|
116
|
-
if (emitted === null) {
|
|
117
|
-
throw new Error(
|
|
118
|
-
`ttsc single-file emit: ${tsconfig} emitted no JavaScript owned by ${sourceFile}; check that the project includes the source and its options permit JavaScript emission`,
|
|
119
|
-
);
|
|
120
|
-
}
|
|
121
|
-
const transformed = fs.readFileSync(emitted, "utf8");
|
|
122
|
-
if (selection !== undefined) CompilerProjectSelection.assertCurrent(selection);
|
|
123
|
-
if (options.out) {
|
|
124
|
-
const target = path.isAbsolute(options.out)
|
|
125
|
-
? options.out
|
|
126
|
-
: path.resolve(cwd, options.out);
|
|
127
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
128
|
-
fs.writeFileSync(target, transformed, "utf8");
|
|
129
|
-
}
|
|
130
|
-
return transformed;
|
|
131
|
-
} catch (error) {
|
|
132
|
-
failed = true;
|
|
133
|
-
failure = error;
|
|
134
|
-
throw error;
|
|
135
|
-
} finally {
|
|
114
|
+
)?.("rootDir");
|
|
115
|
+
const rootDir =
|
|
116
|
+
typeof effective === "string"
|
|
117
|
+
? path.resolve(compilerArgsCwd, effective)
|
|
118
|
+
: project.root;
|
|
119
|
+
if (selection !== undefined)
|
|
120
|
+
CompilerProjectSelection.assertCurrent(selection);
|
|
121
|
+
const outDir = createCanonicalTempDirectory("ttsc-single-file-");
|
|
122
|
+
let failed = false;
|
|
123
|
+
let failure: unknown;
|
|
136
124
|
try {
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
125
|
+
const result = yield* runBuild.steps({
|
|
126
|
+
...options,
|
|
127
|
+
cwd,
|
|
128
|
+
compilerArgsCwd,
|
|
129
|
+
emit: true,
|
|
130
|
+
forceEmitProvenance: true,
|
|
131
|
+
isolateOutputsTo: outDir,
|
|
132
|
+
outDir,
|
|
133
|
+
// The private temp directory above is an `outDir` this lane injected, not
|
|
134
|
+
// one the project declared, and tsgo answers an inferred common source
|
|
135
|
+
// directory with TS5011 as soon as any `outDir` is in play. Pinning the
|
|
136
|
+
// root tsgo would infer keeps `ttsc <file.ts>` working on a project that
|
|
137
|
+
// declares no output at all, while the producing invocation reports its
|
|
138
|
+
// actual source/output ownership separately.
|
|
139
|
+
pinInferredRootDir: true,
|
|
140
|
+
resolvedProject: project,
|
|
141
|
+
tsconfig,
|
|
142
|
+
});
|
|
143
|
+
if (result.status !== 0) {
|
|
144
|
+
throw new Error(
|
|
145
|
+
"ttsc single-file emit exited " +
|
|
146
|
+
result.status +
|
|
147
|
+
"\n" +
|
|
148
|
+
(result.stderr || result.stdout),
|
|
144
149
|
);
|
|
145
150
|
}
|
|
146
|
-
|
|
151
|
+
const emitted = new EmitOwnershipIndex({
|
|
152
|
+
emitDir: outDir,
|
|
153
|
+
rootDir,
|
|
154
|
+
emittedSources: result.emittedSources,
|
|
155
|
+
emittedSourceProofFailures: result.emittedSourceProofFailures,
|
|
156
|
+
outputs: EmitOwnershipIndex.listOutputs(outDir),
|
|
157
|
+
}).find(sourceFile);
|
|
158
|
+
if (emitted === null) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
`ttsc single-file emit: ${tsconfig} emitted no JavaScript owned by ${sourceFile}; check that the project includes the source and its options permit JavaScript emission`,
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
const transformed = fs.readFileSync(emitted, "utf8");
|
|
164
|
+
if (selection !== undefined)
|
|
165
|
+
CompilerProjectSelection.assertCurrent(selection);
|
|
166
|
+
if (options.out) {
|
|
167
|
+
const target = path.isAbsolute(options.out)
|
|
168
|
+
? options.out
|
|
169
|
+
: path.resolve(cwd, options.out);
|
|
170
|
+
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
171
|
+
fs.writeFileSync(target, transformed, "utf8");
|
|
172
|
+
}
|
|
173
|
+
return transformed;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
failed = true;
|
|
176
|
+
failure = error;
|
|
177
|
+
throw error;
|
|
178
|
+
} finally {
|
|
179
|
+
try {
|
|
180
|
+
fs.rmSync(outDir, { recursive: true, force: true });
|
|
181
|
+
} catch (cleanupError) {
|
|
182
|
+
if (failed) {
|
|
183
|
+
throw new AggregateError(
|
|
184
|
+
[failure, cleanupError],
|
|
185
|
+
"ttsc: single-file emission and temporary output cleanup failed",
|
|
186
|
+
{ cause: failure },
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
throw cleanupError;
|
|
190
|
+
}
|
|
147
191
|
}
|
|
148
192
|
}
|
|
149
193
|
}
|
|
@@ -62,7 +62,10 @@ export function startResidentTransform(
|
|
|
62
62
|
tsconfig: context.tsconfig,
|
|
63
63
|
});
|
|
64
64
|
const loaded = loadProjectPlugins({
|
|
65
|
-
binary:
|
|
65
|
+
binary:
|
|
66
|
+
resolveBinary({
|
|
67
|
+
env: SidecarEnvironment.merge(process.env, context.env),
|
|
68
|
+
}) ?? "",
|
|
66
69
|
cacheDir:
|
|
67
70
|
context.cacheDir ??
|
|
68
71
|
SidecarEnvironment.read(context.env, "TTSC_CACHE_DIR"),
|
|
@@ -85,7 +88,11 @@ export function startResidentTransform(
|
|
|
85
88
|
assertSharedHostCompatibility(transformers, "source-to-source");
|
|
86
89
|
|
|
87
90
|
const host = selectSharedHostPlugin(transformers);
|
|
88
|
-
const tsgoBinary = resolveTsgo({
|
|
91
|
+
const tsgoBinary = resolveTsgo({
|
|
92
|
+
...context,
|
|
93
|
+
cwd: project.root,
|
|
94
|
+
env: SidecarEnvironment.merge(process.env, context.env),
|
|
95
|
+
}).binary;
|
|
89
96
|
const resident = new ResidentTransformProcess({
|
|
90
97
|
args: [
|
|
91
98
|
"serve",
|
|
@@ -109,7 +109,10 @@ export function transformProjectInMemory(options: ITtscCompilerContext): {
|
|
|
109
109
|
} {
|
|
110
110
|
const cwd = path.resolve(options.cwd ?? process.cwd());
|
|
111
111
|
const loaded = loadProjectPlugins({
|
|
112
|
-
binary:
|
|
112
|
+
binary:
|
|
113
|
+
resolveBinary({
|
|
114
|
+
env: SidecarEnvironment.merge(process.env, options.env),
|
|
115
|
+
}) ?? "",
|
|
113
116
|
cacheDir:
|
|
114
117
|
options.cacheDir ??
|
|
115
118
|
SidecarEnvironment.read(options.env, "TTSC_CACHE_DIR"),
|
|
@@ -188,11 +191,13 @@ function transformProjectWithNativeHost(
|
|
|
188
191
|
baseline?.hostInputs ?? [],
|
|
189
192
|
projectHostInputs,
|
|
190
193
|
);
|
|
194
|
+
const env = inheritedSidecarEnv(options.env);
|
|
191
195
|
const binary = buildNativeCompiler({
|
|
192
196
|
cacheBaseDir: project.root,
|
|
193
197
|
cacheDir:
|
|
194
198
|
options.cacheDir ??
|
|
195
199
|
SidecarEnvironment.read(options.env, "TTSC_CACHE_DIR"),
|
|
200
|
+
env,
|
|
196
201
|
packageRoot: packageRootDir(),
|
|
197
202
|
});
|
|
198
203
|
const res = spawnNative(
|
|
@@ -200,7 +205,7 @@ function transformProjectWithNativeHost(
|
|
|
200
205
|
["api-transform", "--cwd", project.root, "--tsconfig", project.path],
|
|
201
206
|
{
|
|
202
207
|
cwd: project.root,
|
|
203
|
-
env
|
|
208
|
+
env,
|
|
204
209
|
},
|
|
205
210
|
);
|
|
206
211
|
if (res.error) {
|
|
@@ -295,7 +300,11 @@ function transformProjectWithPlugins(
|
|
|
295
300
|
const tsgoBinary =
|
|
296
301
|
loaded.nativePlugins.length === 0
|
|
297
302
|
? ""
|
|
298
|
-
: resolveTsgo({
|
|
303
|
+
: resolveTsgo({
|
|
304
|
+
...options,
|
|
305
|
+
cwd: project.root,
|
|
306
|
+
env: SidecarEnvironment.merge(process.env, options.env),
|
|
307
|
+
}).binary;
|
|
299
308
|
const checked = runNativeChecks(
|
|
300
309
|
options,
|
|
301
310
|
project,
|
|
@@ -3,6 +3,7 @@ import path from "node:path";
|
|
|
3
3
|
import { Worker } from "node:worker_threads";
|
|
4
4
|
|
|
5
5
|
import { CompilerContextSnapshot } from "../../internal/CompilerContextSnapshot";
|
|
6
|
+
import { workerModuleUrl } from "../../internal/workerModuleUrl";
|
|
6
7
|
import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
|
|
7
8
|
import type { TransformProjectWorkerReply } from "./TransformProjectWorkerReply";
|
|
8
9
|
import type { TransformProjectWorkerRequest } from "./TransformProjectWorkerRequest";
|
|
@@ -50,7 +51,7 @@ import type { transformProjectInMemory } from "./transformProjectInMemory";
|
|
|
50
51
|
* @evidence contracts/common.md#clear-and-simple-design The public operation owns checkout, exclusive event listeners and return to the idle pool; two private helpers isolate idle-worker retirement from active request settlement.
|
|
51
52
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Blocking work runs in a supported worker boundary rather than rewriting the caller's environment around synchronous work; failures preserve real exceptions and do not substitute measured or expected results.
|
|
52
53
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs explain why all transform phases move off-thread, environment isolation, warm reuse and retained-population limits following the documentation skill.
|
|
53
|
-
* @evidence contracts/portability.md#os-neutral-implementation
|
|
54
|
+
* @evidence contracts/portability.md#os-neutral-implementation A supported module URL requires the native CommonJS source or emitted worker entry while Node retains inherited execution options and preload hooks. The environment snapshot uses native name identity; Windows worker copies are case-sensitive, so canonical merging prevents aliases from defeating caller overrides inside the worker.
|
|
54
55
|
* @evidence contracts/performance.md#efficient-algorithms Pool checkout removes one entry and listeners; environment merge and plugin JSON serialization visit caller data before structured cloning, whose cost includes context, serialized payload and environment bytes. Caller JSON conversion can add arbitrary work. Idle-worker retirement searches/compacts at most the pool budget; worker startup and native transform costs remain delegated, and output cloning is transport work rather than a second transform.
|
|
55
56
|
* @evidence contracts/performance.md#reuse-equivalent-work An exclusively checked-out warm worker reuses the loader's input-validated caches; each request adopts its complete current environment and still executes the transform, so thread reuse is not an unsupported response cache.
|
|
56
57
|
* @evidence contracts/performance.md#bound-retention-and-release-resources At most the module-initialization CPU budget remains in the idle pool with event-loop references removed. Excess/failed workers receive unawaited termination requests; retiring native threads are not covered by the reusable-entry count. Terminal settlement removes active listeners, while pooled module caches retain their owning data policy. Active requests and live transforms have no concurrency cap or implicit deadline.
|
|
@@ -65,7 +66,14 @@ export function transformProjectInWorker(
|
|
|
65
66
|
};
|
|
66
67
|
const worker =
|
|
67
68
|
takeIdleWorker() ??
|
|
68
|
-
new Worker(
|
|
69
|
+
new Worker(
|
|
70
|
+
workerModuleUrl(
|
|
71
|
+
path.join(
|
|
72
|
+
__dirname,
|
|
73
|
+
`transformProjectWorker${path.extname(__filename)}`,
|
|
74
|
+
),
|
|
75
|
+
),
|
|
76
|
+
);
|
|
69
77
|
worker.ref();
|
|
70
78
|
return new Promise((resolve, reject) => {
|
|
71
79
|
let settled = false;
|
|
@@ -29,8 +29,8 @@ export interface ParseOptions {
|
|
|
29
29
|
readonly errorPrefix: string;
|
|
30
30
|
|
|
31
31
|
/**
|
|
32
|
-
* Observe a validated launcher assignment at its compiler-frame position.
|
|
33
|
-
*
|
|
32
|
+
* Observe a validated launcher assignment at its compiler-frame position. The
|
|
33
|
+
* canonical schema name and parsed value retain alias/value semantics;
|
|
34
34
|
* passthroughIndex counts compiler tokens already forwarded at this point.
|
|
35
35
|
* Exceptions propagate from the caller's observer.
|
|
36
36
|
*
|