ttsc 0.32.0 → 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/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 +91 -11
- 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/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/resolveOwningProjectConfig.d.ts +7 -2
- package/lib/compiler/internal/project/resolveOwningProjectConfig.js +6 -3
- 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 +28 -1
- package/lib/compiler/internal/runSingleFileEmit.js +120 -86
- 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/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/prepareExecution.js +2 -1
- package/lib/launcher/internal/prepareExecution.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/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/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/installRuntimeHooks.d.ts +5 -3
- package/lib/launcher/internal/runtime/installRuntimeHooks.js +7 -3
- package/lib/launcher/internal/runtime/installRuntimeHooks.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 +29 -1
- package/lib/launcher/internal/watch/WatchTopology.js +86 -10
- 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/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 +466 -416
- 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/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/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/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 +118 -9
- package/src/compiler/internal/build/ResidentCheckWatchSession.ts +41 -24
- package/src/compiler/internal/build/RunBuildOptions.ts +9 -5
- 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/resolveOwningProjectConfig.ts +16 -5
- 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 +139 -99
- 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/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/prepareExecution.ts +2 -0
- package/src/launcher/internal/runTtsc.ts +123 -45
- package/src/launcher/internal/runtime/CommonJsRuntimeSource.ts +11 -9
- package/src/launcher/internal/runtime/advertiseTypeScriptExtensions.ts +25 -0
- package/src/launcher/internal/runtime/installRuntimeHooks.ts +7 -3
- 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 +84 -13
- package/src/launcher/internal/watch/WatchTopologyWorkerProtocol.ts +106 -0
- 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 +672 -594
- package/src/plugin/internal/load/pluginResolutionFailure.ts +37 -0
- package/src/plugin/internal/source/PluginBuildEnvironmentReadings.ts +8 -2
- 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/TtscSingleFileEmitOptions.ts +22 -11
|
@@ -9,6 +9,7 @@ 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");
|
|
@@ -80,6 +81,9 @@ const visitImportMappedCandidates_1 = require("./visitImportMappedCandidates");
|
|
|
80
81
|
* declaration. Sequential content, metadata and physical-path observations are
|
|
81
82
|
* not an atomic snapshot or detection of every omitted read.
|
|
82
83
|
*
|
|
84
|
+
* Synchronous callers require synchronous watch-input handlers; use
|
|
85
|
+
* {@link loadProjectPlugins.async} to await a worker's baseline publication.
|
|
86
|
+
*
|
|
83
87
|
* @param options.binary - Absolute path to the ttsc native helper binary.
|
|
84
88
|
* @param options.cacheDir - Override the plugin binary cache directory.
|
|
85
89
|
* @param options.cwd - Working directory for resolving relative paths.
|
|
@@ -90,11 +94,12 @@ const visitImportMappedCandidates_1 = require("./visitImportMappedCandidates");
|
|
|
90
94
|
* native environment-name identity. Defaults to `process.env` for CLI
|
|
91
95
|
* callers, so ambient behavior is unchanged.
|
|
92
96
|
* @param options.file - Path to the tsconfig/jsconfig file.
|
|
93
|
-
* @param options.pluginConfigDir - Caller-declared
|
|
94
|
-
* config-file discovery
|
|
95
|
-
* @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.
|
|
96
101
|
* @param options.tsconfig - Alias for `file`.
|
|
97
|
-
* @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.
|
|
98
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.
|
|
99
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.
|
|
100
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.
|
|
@@ -104,420 +109,463 @@ const visitImportMappedCandidates_1 = require("./visitImportMappedCandidates");
|
|
|
104
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.
|
|
105
110
|
*/
|
|
106
111
|
function loadProjectPlugins(options) {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return {
|
|
129
|
-
...collectHostInputSnapshot(project, {}, [], projectHostInputs, revalidateHostInputHashes(projectHostInputHashes, projectHostInputs), revalidateHostInputRealpaths(projectHostInputRealpaths, projectHostInputs)),
|
|
130
|
-
descriptorReadsDeclared: true,
|
|
131
|
-
discoveryInputsComplete: project.configInputsComplete === true,
|
|
132
|
-
nativePlugins: [],
|
|
133
|
-
pluginSources: {},
|
|
134
|
-
project,
|
|
135
|
-
};
|
|
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));
|
|
136
133
|
}
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
cacheDir: options.cacheDir,
|
|
157
|
-
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,
|
|
158
153
|
});
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const request = PluginPackageResolution_1.PluginPackageResolution.resolvePluginRequest(specifier, entry.baseDir);
|
|
177
|
-
// Keep the candidates of the search roots up to the one the entry
|
|
178
|
-
// resolved in: the lookup never read the roots after it
|
|
179
|
-
// (`moduleResolutionBaseSelects`).
|
|
180
|
-
const read = new Set(collectModuleResolutionCandidates(specifier, entryParent, request).map((candidate) => node_path_1.default.resolve(candidate)));
|
|
181
|
-
const entryCandidates = probedCandidates.filter((candidate) => read.has(node_path_1.default.resolve(candidate)));
|
|
182
|
-
const entryCandidateHashes = pickHostInputEntries(probedCandidateHashes, entryCandidates);
|
|
183
|
-
const entryCandidateRealpaths = pickHostInputEntries(probedCandidateRealpaths, entryCandidates);
|
|
184
|
-
const loaded = loadPluginEntry(entry.config, { ...context, plugin: entry.config }, request, effectiveEnv, descriptorCache);
|
|
185
|
-
const loadedHostInputHashes = mergeObservedHostInputHashes(loaded.hostInputHashes, (0, hashHostInputPaths_1.hashHostInputPaths)(Object.keys(loaded.hostInputHashes)));
|
|
186
|
-
const loadedHostInputRealpaths = mergeObservedHostInputRealpaths(loaded.hostInputRealpaths, (0, realpathHostInputPaths_1.realpathHostInputPaths)(Object.keys(loaded.hostInputRealpaths)));
|
|
187
|
-
const hostInputHashes = mergeObservedHostInputHashes(entryCandidateHashes, loadedHostInputHashes);
|
|
188
|
-
const hostInputRealpaths = mergeObservedHostInputRealpaths(entryCandidateRealpaths, loadedHostInputRealpaths);
|
|
189
|
-
for (const input of loaded.hostInputs) {
|
|
190
|
-
const absolute = node_path_1.default.resolve(input);
|
|
191
|
-
if (!Object.prototype.hasOwnProperty.call(loadedHostInputHashes, absolute)) {
|
|
192
|
-
delete hostInputHashes[absolute];
|
|
193
|
-
}
|
|
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
|
+
};
|
|
194
171
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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,
|
|
201
182
|
};
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
// One reading of each source directory, shared by package selection and
|
|
220
|
-
// every build below and reported as the state the binaries were keyed on.
|
|
221
|
-
const sourceDigests = new Map();
|
|
222
|
-
// And one reading of the environment each build directory is keyed on, which
|
|
223
|
-
// a plugin module root's state reports as it is.
|
|
224
|
-
const environmentDigests = new Map();
|
|
225
|
-
// With the witness of each such reading, so a build of a directory package
|
|
226
|
-
// selection already read keys on that reading instead of probing Go again.
|
|
227
|
-
const environmentWitnesses = new Map();
|
|
228
|
-
const readings = {
|
|
229
|
-
sources: sourceDigests,
|
|
230
|
-
environments: environmentDigests,
|
|
231
|
-
witnesses: environmentWitnesses,
|
|
232
|
-
};
|
|
233
|
-
// Records describing sources must never land inside one, so the store is
|
|
234
|
-
// admitted for source proofs only once every source of the load is known.
|
|
235
|
-
const sourceIdentities = PluginContentIdentities_1.PluginContentIdentities.outside(identities, [
|
|
236
|
-
...candidates.flatMap((candidate) => [
|
|
237
|
-
candidate.moduleRoot,
|
|
238
|
-
candidate.packageDir,
|
|
239
|
-
...(candidate.contributors ?? []).map((input) => input.source),
|
|
240
|
-
]),
|
|
241
|
-
...SourcePluginWorkspace_1.SourcePluginWorkspace.findTtscOverlayDirs(),
|
|
242
|
-
]);
|
|
243
|
-
// One fixed-effective-environment load owns manifest syntax sharing from the
|
|
244
|
-
// first watch query through metadata and builds. Do not allocate this after
|
|
245
|
-
// watch projection: that silently repeats selected-Go work (#1712).
|
|
246
|
-
const packageReaders = new Map();
|
|
247
|
-
const watchReplacements = options.onWatchInputs === undefined
|
|
248
|
-
? undefined
|
|
249
|
-
: new Map();
|
|
250
|
-
if (options.onWatchInputs !== undefined) {
|
|
251
|
-
// The prospective context reads the admitted module layout and anchors its
|
|
252
|
-
// tool there before kind exists. Keep both possible final-root baselines:
|
|
253
|
-
// a linked package keeps packageDir, and an executable keeps moduleRoot.
|
|
254
|
-
const interests = new Set(candidates
|
|
255
|
-
.flatMap((candidate) => [
|
|
256
|
-
candidate.moduleRoot,
|
|
257
|
-
candidate.packageDir,
|
|
258
|
-
...(candidate.contributors ?? []).map((input) => input.source),
|
|
259
|
-
])
|
|
260
|
-
.filter(reportsPluginSource));
|
|
261
|
-
// WARNING (#1728): hand the watch owner this load's store with the roots.
|
|
262
|
-
// It baselines each root before any build reads it; without the store it
|
|
263
|
-
// read every source the load proves from records a moment later.
|
|
264
|
-
options.onWatchInputs([...interests].sort(), sourceIdentities);
|
|
265
|
-
const initialSize = interests.size;
|
|
266
|
-
for (const candidate of candidates) {
|
|
267
|
-
// Nested source-only proposals replace the outer root manifests. Do not
|
|
268
|
-
// activate their irrelevant module graph just to discover watch inputs.
|
|
269
|
-
if (candidate.stage === "transform" && candidate.entry !== ".")
|
|
270
|
-
continue;
|
|
271
|
-
for (const directory of pluginReplacementWatchDirectories(candidate.moduleRoot, effectiveEnv, watchReplacements, packageReaders, sourceIdentities))
|
|
272
|
-
if (reportsPluginSource(directory))
|
|
273
|
-
interests.add(directory);
|
|
274
|
-
}
|
|
275
|
-
if (interests.size !== initialSize)
|
|
276
|
-
options.onWatchInputs([...interests].sort(), sourceIdentities);
|
|
277
|
-
}
|
|
278
|
-
const proposals = NativeSourcePackages_1.NativeSourcePackages.propose(candidates.map((candidate) => ({
|
|
279
|
-
...candidate,
|
|
280
|
-
ownModule: candidate.stage !== "transform",
|
|
281
|
-
})), effectiveEnv, packageReaders, sourceIdentities, readings);
|
|
282
|
-
const records = candidates.map(({ plugin, index, stage, contributors, source, packageDir }) => {
|
|
283
|
-
const { kind, moduleRoot } = (0, resolveNativeSource_1.resolveNativeSource)(source, plugin, entries[index].config, index, {
|
|
284
|
-
env: effectiveEnv,
|
|
285
|
-
observation: proposals[index].observation,
|
|
286
|
-
});
|
|
287
|
-
if (kind === "linked" && stage !== "transform") {
|
|
288
|
-
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`);
|
|
289
|
-
}
|
|
290
|
-
const linkedContributorName = kind === "linked"
|
|
291
|
-
? `linked_${String(index).padStart(6, "0")}`
|
|
292
|
-
: undefined;
|
|
293
|
-
const hostInputs = validatePluginHostInputs(plugin, index);
|
|
294
|
-
const pluginHostInputHashes = validatePluginHostInputHashes(plugin, index, hostInputs);
|
|
295
|
-
const pluginHostInputRealpaths = validatePluginHostInputRealpaths(plugin, index, hostInputs);
|
|
296
|
-
return {
|
|
297
|
-
capabilities: plugin.capabilities,
|
|
298
|
-
contributors,
|
|
299
|
-
config: entries[index].config,
|
|
300
|
-
kind,
|
|
301
|
-
label: (0, pluginLabel_1.pluginLabel)(plugin, entries[index].config, index),
|
|
302
|
-
linkedContributorName,
|
|
303
|
-
name: plugin.name,
|
|
304
|
-
reportsTypeScriptDiagnostics: plugin.reportsTypeScriptDiagnostics === true,
|
|
305
|
-
request: loadedEntries[index].request,
|
|
306
|
-
hostInputHashes: mergePluginHostInputHashes(loadedEntries[index].hostInputHashes, pluginHostInputHashes, loadedEntries[index].hostInputs, hostInputs),
|
|
307
|
-
hostInputRealpaths: mergePluginHostInputHashes(loadedEntries[index].hostInputRealpaths, pluginHostInputRealpaths, loadedEntries[index].hostInputs, hostInputs),
|
|
308
|
-
hostInputs: [...loadedEntries[index].hostInputs, ...hostInputs],
|
|
309
|
-
moduleRoot,
|
|
310
|
-
packageDir,
|
|
311
|
-
source,
|
|
312
|
-
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,
|
|
313
200
|
};
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
// Admission can now narrow the provisional interests without restamping the
|
|
319
|
-
// retained package/module baselines. Final host errors still keep these roots.
|
|
320
|
-
options.onWatchInputs?.(buildDirectories, sourceIdentities);
|
|
321
|
-
const keyedDirectories = new Set(buildDirectories);
|
|
322
|
-
const linkedContributors = records
|
|
323
|
-
.filter((record) => record.stage === "transform")
|
|
324
|
-
.flatMap((record) => record.kind === "linked"
|
|
325
|
-
? [{ name: record.linkedContributorName, source: record.source }]
|
|
326
|
-
: []);
|
|
327
|
-
const transformHosts = records.filter((record) => record.stage === "transform" && record.kind === "executable");
|
|
328
|
-
const hostContributors = linkedContributors.length === 0 ? undefined : linkedContributors;
|
|
329
|
-
// Every host compiles the linked sources under its own module/tool context.
|
|
330
|
-
// Equivalent entries in one module share this metadata command and reader;
|
|
331
|
-
// a second executable host can select a genuinely different Go context.
|
|
332
|
-
const admittedExecutables = new Set();
|
|
333
|
-
if (linkedContributors.length !== 0) {
|
|
334
|
-
const hosts = transformHosts.length === 0
|
|
335
|
-
? [
|
|
336
|
-
{
|
|
337
|
-
source: node_path_1.default.join(ttscPackageRoot(), "cmd", "utility-host"),
|
|
338
|
-
label: "linked-plugin-host",
|
|
339
|
-
},
|
|
340
|
-
]
|
|
341
|
-
: transformHosts;
|
|
342
|
-
const contexts = new Map();
|
|
343
|
-
for (const host of hosts) {
|
|
344
|
-
const moduleRoot = (0, resolvePluginGoModule_1.resolvePluginGoModule)(host.source, host.label).moduleRoot;
|
|
345
|
-
let context = contexts.get(moduleRoot);
|
|
346
|
-
if (context === undefined) {
|
|
347
|
-
context = { source: host.source, label: host.label, records: [] };
|
|
348
|
-
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`);
|
|
349
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);
|
|
350
323
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
}));
|
|
358
|
-
const observations = NativeSourcePackages_1.NativeSourcePackages.inspect({
|
|
359
|
-
source: host.source,
|
|
360
|
-
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, {
|
|
361
330
|
env: effectiveEnv,
|
|
362
|
-
|
|
363
|
-
identities: sourceIdentities,
|
|
364
|
-
readings,
|
|
365
|
-
packages: [
|
|
366
|
-
...hostEntries,
|
|
367
|
-
...linkedContributors.map((input) => ({
|
|
368
|
-
...input,
|
|
369
|
-
entry: `./contrib/${input.name}`,
|
|
370
|
-
})),
|
|
371
|
-
],
|
|
372
|
-
});
|
|
373
|
-
moduleHosts.forEach((record, index) => {
|
|
374
|
-
NativeSourcePackages_1.NativeSourcePackages.kind(observations[index], record.label, "executable");
|
|
375
|
-
admittedExecutables.add(record.source);
|
|
331
|
+
observation: proposals[index].observation,
|
|
376
332
|
});
|
|
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
|
-
|
|
451
|
-
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,
|
|
452
407
|
env: effectiveEnv,
|
|
453
|
-
|
|
408
|
+
readers: packageReaders,
|
|
454
409
|
identities: sourceIdentities,
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
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);
|
|
463
422
|
});
|
|
464
|
-
|
|
465
|
-
|
|
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
|
+
}));
|
|
466
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
|
+
});
|
|
467
539
|
return {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
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,
|
|
491
565
|
};
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
descriptorReadsDeclared: loadedEntries.every((entry) => entry.observationsComplete && (0, declaresHostInputReads_1.declaresHostInputReads)(entry.plugin)),
|
|
496
|
-
discoveryInputsComplete: project.configInputsComplete === true,
|
|
497
|
-
...(identities === undefined ? {} : { identities }),
|
|
498
|
-
nativePlugins: orderNativePlugins(nativePlugins),
|
|
499
|
-
...(loadedEntries.some((entry) => !entry.observationsComplete)
|
|
500
|
-
? { observationsComplete: false }
|
|
501
|
-
: {}),
|
|
502
|
-
// The directories the watch inputs named before the builds, as the builds
|
|
503
|
-
// read them. Package selection shares these readings and also reads a
|
|
504
|
-
// linked plugin's module root, which no build keys on, so only the build
|
|
505
|
-
// directories are reported.
|
|
506
|
-
pluginSources: Object.fromEntries([...sourceDigests]
|
|
507
|
-
.filter(([directory]) => keyedDirectories.has(directory))
|
|
508
|
-
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
509
|
-
.map(([directory, sourceDigest]) => [
|
|
510
|
-
directory,
|
|
511
|
-
(0, pluginSourceState_1.pluginSourceState)(directory, {
|
|
512
|
-
env: effectiveEnv,
|
|
513
|
-
sourceDigest,
|
|
514
|
-
environment: environmentDigests.get(directory) ??
|
|
515
|
-
(0, pluginBuildEnvironment_1.pluginBuildEnvironment)(directory, effectiveEnv, undefined, sourceIdentities),
|
|
516
|
-
}),
|
|
517
|
-
])),
|
|
518
|
-
project,
|
|
519
|
-
};
|
|
520
|
-
}
|
|
566
|
+
}
|
|
567
|
+
loadProjectPlugins.steps = steps;
|
|
568
|
+
})(loadProjectPlugins || (exports.loadProjectPlugins = loadProjectPlugins = {}));
|
|
521
569
|
/**
|
|
522
570
|
* Collect exact JavaScript-host files that universally influence the loaded
|
|
523
571
|
* transform. Program files belong to the native reference graph; this list is
|
|
@@ -598,16 +646,16 @@ function collectHostInputSnapshot(project, context, records, baselineInputs, bas
|
|
|
598
646
|
* cache proof for the ambiguous snapshot.
|
|
599
647
|
*/
|
|
600
648
|
function readProjectHostInputSnapshot(options) {
|
|
601
|
-
const { includePluginDiscovery, ...projectOptions } = options;
|
|
649
|
+
const { includePluginDiscovery, pluginConfigDir, ...projectOptions } = options;
|
|
602
650
|
let project = (0, readProjectConfig_1.readProjectConfig)(projectOptions);
|
|
603
|
-
let hostInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(project, includePluginDiscovery);
|
|
651
|
+
let hostInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(project, includePluginDiscovery, pluginConfigDir);
|
|
604
652
|
const observedInputs = new Set(hostInputs);
|
|
605
653
|
for (let attempt = 0; attempt < 3; attempt++) {
|
|
606
654
|
const before = (0, hashHostInputPaths_1.hashHostInputPaths)(hostInputs);
|
|
607
655
|
const beforeRealpaths = (0, realpathHostInputPaths_1.realpathHostInputPaths)(hostInputs);
|
|
608
656
|
const beforeSignatures = hostInputMetadataSignatures(hostInputs);
|
|
609
657
|
const candidateProject = (0, readProjectConfig_1.readProjectConfig)(projectOptions);
|
|
610
|
-
const candidateInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(candidateProject, includePluginDiscovery);
|
|
658
|
+
const candidateInputs = (0, collectProjectHostInputs_1.collectProjectHostInputs)(candidateProject, includePluginDiscovery, pluginConfigDir);
|
|
611
659
|
for (const input of candidateInputs)
|
|
612
660
|
observedInputs.add(input);
|
|
613
661
|
const after = (0, hashHostInputPaths_1.hashHostInputPaths)(candidateInputs);
|
|
@@ -928,7 +976,7 @@ function loadPluginDescriptor(request, context, effectiveEnv, descriptorCache) {
|
|
|
928
976
|
!error.retryWithTtsx) {
|
|
929
977
|
throw error;
|
|
930
978
|
}
|
|
931
|
-
const loaded = loadDescriptorViaTtsx(request, context, effectiveEnv, descriptorCache
|
|
979
|
+
const loaded = loadDescriptorViaTtsx(request, context, effectiveEnv, descriptorCache);
|
|
932
980
|
if (loaded === undefined) {
|
|
933
981
|
throw error;
|
|
934
982
|
}
|
|
@@ -965,17 +1013,19 @@ function loadCommonJsDescriptor(request, context, loadEnv, descriptorCache) {
|
|
|
965
1013
|
const effectiveEnv = TtsxNodeOptions_1.TtsxNodeOptions.forHelpers(loadEnv);
|
|
966
1014
|
const runtime = pluginDescriptorRuntimeBinary(effectiveEnv);
|
|
967
1015
|
const ttsx = effectiveEnv.TTSC_TTSX_BINARY ?? process.env.TTSC_TTSX_BINARY;
|
|
968
|
-
const runtimeCapabilities = (0, javascriptRuntimeCapabilities_1.javascriptRuntimeCapabilities)(runtime, effectiveEnv,
|
|
1016
|
+
const runtimeCapabilities = (0, javascriptRuntimeCapabilities_1.javascriptRuntimeCapabilities)(runtime, effectiveEnv, descriptorCache.projectRoot, descriptorCache.identities);
|
|
969
1017
|
const node = !runtimeCapabilities.bun &&
|
|
970
1018
|
runtimeCapabilities.registerHooks &&
|
|
971
1019
|
runtimeCapabilities.executable !== undefined
|
|
972
1020
|
? runtimeCapabilities.executable
|
|
973
|
-
: (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv,
|
|
1021
|
+
: (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv, descriptorCache.projectRoot, descriptorCache.identities);
|
|
974
1022
|
const cacheAuthority = {
|
|
975
1023
|
additionalRuntime: node,
|
|
976
1024
|
cacheDir: descriptorCache.cacheDir,
|
|
977
1025
|
identities: descriptorCache.identities,
|
|
978
1026
|
context,
|
|
1027
|
+
// Factory context anchors the consumer; the evaluator runs at the source root.
|
|
1028
|
+
cwd: descriptorCache.projectRoot,
|
|
979
1029
|
// Everything the child receives besides the per-evaluation output paths.
|
|
980
1030
|
env: {
|
|
981
1031
|
...effectiveEnv,
|
|
@@ -983,7 +1033,7 @@ function loadCommonJsDescriptor(request, context, loadEnv, descriptorCache) {
|
|
|
983
1033
|
...descriptorRecordRoot(descriptorCache.identities),
|
|
984
1034
|
TTSC_TTSX_BINARY: ttsx,
|
|
985
1035
|
},
|
|
986
|
-
projectRoot:
|
|
1036
|
+
projectRoot: descriptorCache.projectRoot,
|
|
987
1037
|
request,
|
|
988
1038
|
runtime,
|
|
989
1039
|
version: descriptorCache.version,
|
|
@@ -1049,7 +1099,7 @@ function loadCommonJsDescriptor(request, context, loadEnv, descriptorCache) {
|
|
|
1049
1099
|
...(runtimeCapabilities.bun ? [] : ["--input-type", ""]),
|
|
1050
1100
|
shim,
|
|
1051
1101
|
], {
|
|
1052
|
-
cwd:
|
|
1102
|
+
cwd: descriptorCache.projectRoot,
|
|
1053
1103
|
env: {
|
|
1054
1104
|
...effectiveEnv,
|
|
1055
1105
|
// The direct evaluator may be Bun, but ttsx and native config
|
|
@@ -1312,11 +1362,11 @@ const TS_SOURCE_PATTERN = /\.(?:[cm]?ts|tsx)$/i;
|
|
|
1312
1362
|
* shim with plugins disabled across the whole graph. Returns `undefined` when
|
|
1313
1363
|
* `ttsx` is unavailable, so the caller can rethrow the original load error.
|
|
1314
1364
|
*/
|
|
1315
|
-
function loadDescriptorViaTtsx(request, context, effectiveEnv,
|
|
1365
|
+
function loadDescriptorViaTtsx(request, context, effectiveEnv, descriptorCache) {
|
|
1316
1366
|
// Binary discovery prefers the instance environment, then the ambient
|
|
1317
1367
|
// process.env (where `withPluginLoaderEnv` injects ttsc's own node/ttsx paths
|
|
1318
1368
|
// just before this runs), then the running interpreter.
|
|
1319
|
-
const node = (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv,
|
|
1369
|
+
const node = (0, resolveNodeBinary_1.resolveNodeBinary)(effectiveEnv, descriptorCache.projectRoot, descriptorCache.identities);
|
|
1320
1370
|
const ttsx = effectiveEnv.TTSC_TTSX_BINARY ?? process.env.TTSC_TTSX_BINARY;
|
|
1321
1371
|
if (node === undefined || ttsx === undefined || ttsx.length === 0) {
|
|
1322
1372
|
return undefined;
|
|
@@ -1337,9 +1387,9 @@ function loadDescriptorViaTtsx(request, context, effectiveEnv, identities) {
|
|
|
1337
1387
|
},
|
|
1338
1388
|
}));
|
|
1339
1389
|
node_fs_1.default.writeFileSync(shim, PLUGIN_DESCRIPTOR_SHIM_SOURCE_1.PLUGIN_DESCRIPTOR_SHIM_SOURCE);
|
|
1340
|
-
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");
|
|
1341
1391
|
const result = spawnOwnedDescriptor(node, [ttsx, "--no-plugins", shim], {
|
|
1342
|
-
cwd:
|
|
1392
|
+
cwd: descriptorCache.projectRoot,
|
|
1343
1393
|
encoding: "utf8",
|
|
1344
1394
|
env: {
|
|
1345
1395
|
...effectiveEnv,
|
|
@@ -1347,7 +1397,7 @@ function loadDescriptorViaTtsx(request, context, effectiveEnv, identities) {
|
|
|
1347
1397
|
// may recurse into further descriptor loads) finds them even when the
|
|
1348
1398
|
// instance-env snapshot predates `withPluginLoaderEnv`.
|
|
1349
1399
|
TTSC_NODE_BINARY: node,
|
|
1350
|
-
...descriptorRecordRoot(identities),
|
|
1400
|
+
...descriptorRecordRoot(descriptorCache.identities),
|
|
1351
1401
|
TTSC_TTSX_BINARY: ttsx,
|
|
1352
1402
|
TTSC_PLUGIN_CONTEXT: JSON.stringify({
|
|
1353
1403
|
binary: context.binary,
|