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.
Files changed (261) hide show
  1. package/cmd/ttsc/compiler_argument_cwd_test.go +38 -38
  2. package/cmd/ttscserver/main.go +2 -12
  3. package/cmd/ttscserver/resolve_launch_uses_native_flag_authority_test.go +7 -7
  4. package/driver/lsp.go +4 -43
  5. package/driver/rewrite.go +1 -1
  6. package/internal/e2etrace/completion_hints.go +3 -3
  7. package/internal/e2etrace/completion_hints_test.go +26 -12
  8. package/internal/graph/build.go +5 -6
  9. package/internal/graph/graph.go +3 -3
  10. package/internal/graph/line_model.go +2 -35
  11. package/internal/lspserver/lsp_clean_didopen_refreshes_compiler_state_test.go +13 -36
  12. package/internal/lspserver/lsp_hints_refresh_ignores_a_superseded_generation_test.go +9 -3
  13. package/internal/lspserver/lsp_plugin.go +19 -0
  14. package/internal/lspserver/lsp_proxy.go +9 -129
  15. package/internal/lspserver/lsp_server.go +0 -8
  16. package/internal/lspserver/lsp_watched_file_changes_reach_compiler_caches_test.go +6 -36
  17. package/internal/sourceprocess/windows_target_owns_suspended_admission_test.go +5 -5
  18. package/lib/TtscCompiler.js +1 -1
  19. package/lib/TtscCompiler.js.map +1 -1
  20. package/lib/compiler/internal/ResidentCheckProcess.d.ts +74 -96
  21. package/lib/compiler/internal/ResidentCheckProcess.js +150 -335
  22. package/lib/compiler/internal/ResidentCheckProcess.js.map +1 -1
  23. package/lib/compiler/internal/ResidentCheckProcessHost.d.ts +127 -0
  24. package/lib/compiler/internal/ResidentCheckProcessHost.js +447 -0
  25. package/lib/compiler/internal/ResidentCheckProcessHost.js.map +1 -0
  26. package/lib/compiler/internal/ResidentCheckProcessProtocol.d.ts +64 -0
  27. package/lib/compiler/internal/ResidentCheckProcessProtocol.js +3 -0
  28. package/lib/compiler/internal/ResidentCheckProcessProtocol.js.map +1 -0
  29. package/lib/compiler/internal/build/BuildExecution.d.ts +103 -1
  30. package/lib/compiler/internal/build/BuildExecution.js +92 -12
  31. package/lib/compiler/internal/build/BuildExecution.js.map +1 -1
  32. package/lib/compiler/internal/build/ResidentCheckWatchSession.d.ts +16 -11
  33. package/lib/compiler/internal/build/ResidentCheckWatchSession.js +37 -21
  34. package/lib/compiler/internal/build/ResidentCheckWatchSession.js.map +1 -1
  35. package/lib/compiler/internal/build/RunBuildOptions.d.ts +6 -5
  36. package/lib/compiler/internal/build/TsgoArguments.js.map +1 -1
  37. package/lib/compiler/internal/build/WatchInputPublication.d.ts +59 -0
  38. package/lib/compiler/internal/build/WatchInputPublication.js +93 -0
  39. package/lib/compiler/internal/build/WatchInputPublication.js.map +1 -0
  40. package/lib/compiler/internal/build/runBuild.d.ts +29 -2
  41. package/lib/compiler/internal/build/runBuild.js +45 -19
  42. package/lib/compiler/internal/build/runBuild.js.map +1 -1
  43. package/lib/compiler/internal/buildNativeCompiler.d.ts +2 -0
  44. package/lib/compiler/internal/buildNativeCompiler.js +1 -0
  45. package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
  46. package/lib/compiler/internal/compileProjectInMemory.js +4 -2
  47. package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
  48. package/lib/compiler/internal/project/CompilerProjectSelection.d.ts +9 -8
  49. package/lib/compiler/internal/project/CompilerProjectSelection.js +11 -9
  50. package/lib/compiler/internal/project/CompilerProjectSelection.js.map +1 -1
  51. package/lib/compiler/internal/project/resolveOwningProjectConfig.d.ts +25 -8
  52. package/lib/compiler/internal/project/resolveOwningProjectConfig.js +26 -14
  53. package/lib/compiler/internal/project/resolveOwningProjectConfig.js.map +1 -1
  54. package/lib/compiler/internal/readEffectiveCompilerOptions.js +1 -1
  55. package/lib/compiler/internal/readEffectiveCompilerOptions.js.map +1 -1
  56. package/lib/compiler/internal/resolveBinary.d.ts +1 -0
  57. package/lib/compiler/internal/resolveBinary.js.map +1 -1
  58. package/lib/compiler/internal/resolveTsgo.d.ts +6 -0
  59. package/lib/compiler/internal/resolveTsgo.js.map +1 -1
  60. package/lib/compiler/internal/runSingleFileEmit.d.ts +32 -4
  61. package/lib/compiler/internal/runSingleFileEmit.js +124 -89
  62. package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
  63. package/lib/compiler/internal/startResidentTransform.js +8 -2
  64. package/lib/compiler/internal/startResidentTransform.js.map +1 -1
  65. package/lib/compiler/internal/transformProjectInMemory.js +11 -3
  66. package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
  67. package/lib/compiler/internal/transformProjectInWorker.d.ts +1 -1
  68. package/lib/compiler/internal/transformProjectInWorker.js +3 -2
  69. package/lib/compiler/internal/transformProjectInWorker.js.map +1 -1
  70. package/lib/flags/ParseOptions.d.ts +2 -2
  71. package/lib/internal/E2ETrace.js.map +1 -1
  72. package/lib/internal/OwnedNativeProcess.d.ts +2 -2
  73. package/lib/internal/OwnedNativeProcess.js +2 -2
  74. package/lib/internal/SourceNativeRetirement.d.ts +8 -7
  75. package/lib/internal/SourceNativeRetirement.js +19 -10
  76. package/lib/internal/SourceNativeRetirement.js.map +1 -1
  77. package/lib/internal/TtsxNodeOptions.d.ts +79 -0
  78. package/lib/internal/TtsxNodeOptions.js +121 -0
  79. package/lib/internal/TtsxNodeOptions.js.map +1 -0
  80. package/lib/internal/javascriptRuntimeCapabilities.js +4 -1
  81. package/lib/internal/javascriptRuntimeCapabilities.js.map +1 -1
  82. package/lib/internal/parseWindowsDirectoryCaseSensitivity.d.ts +5 -5
  83. package/lib/internal/parseWindowsDirectoryCaseSensitivity.js +5 -5
  84. package/lib/internal/pathIdentity/createCaseSensitivityObservations.d.ts +35 -0
  85. package/lib/internal/pathIdentity/createCaseSensitivityObservations.js +209 -0
  86. package/lib/internal/pathIdentity/createCaseSensitivityObservations.js.map +1 -0
  87. package/lib/internal/pathIdentity/createFilesystemPathIdentityContext.js +2 -143
  88. package/lib/internal/pathIdentity/createFilesystemPathIdentityContext.js.map +1 -1
  89. package/lib/internal/projectInputPathIdentity.d.ts +1 -0
  90. package/lib/internal/projectInputPathIdentity.js +1 -0
  91. package/lib/internal/projectInputPathIdentity.js.map +1 -1
  92. package/lib/internal/workerModuleUrl.d.ts +28 -0
  93. package/lib/internal/workerModuleUrl.js +40 -0
  94. package/lib/internal/workerModuleUrl.js.map +1 -0
  95. package/lib/launcher/internal/buildSingleRootProject.js +2 -1
  96. package/lib/launcher/internal/buildSingleRootProject.js.map +1 -1
  97. package/lib/launcher/internal/getCompilerVersionText.js +3 -2
  98. package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
  99. package/lib/launcher/internal/parseTtsxCLI.d.ts +5 -4
  100. package/lib/launcher/internal/parseTtsxCLI.js +5 -4
  101. package/lib/launcher/internal/parseTtsxCLI.js.map +1 -1
  102. package/lib/launcher/internal/prepareExecution.js +2 -1
  103. package/lib/launcher/internal/prepareExecution.js.map +1 -1
  104. package/lib/launcher/internal/resolveSingleFileOutput.d.ts +8 -9
  105. package/lib/launcher/internal/resolveSingleFileOutput.js +8 -9
  106. package/lib/launcher/internal/resolveSingleFileOutput.js.map +1 -1
  107. package/lib/launcher/internal/runTtsc.js +91 -41
  108. package/lib/launcher/internal/runTtsc.js.map +1 -1
  109. package/lib/launcher/internal/runTtsx.js +5 -2
  110. package/lib/launcher/internal/runTtsx.js.map +1 -1
  111. package/lib/launcher/internal/runtime/CommonJsRuntimeSource.d.ts +10 -6
  112. package/lib/launcher/internal/runtime/CommonJsRuntimeSource.js +11 -9
  113. package/lib/launcher/internal/runtime/CommonJsRuntimeSource.js.map +1 -1
  114. package/lib/launcher/internal/runtime/RuntimeEntrySources.d.ts +40 -0
  115. package/lib/launcher/internal/runtime/RuntimeEntrySources.js +57 -0
  116. package/lib/launcher/internal/runtime/RuntimeEntrySources.js.map +1 -0
  117. package/lib/launcher/internal/runtime/RuntimeProjectOwnership.d.ts +5 -4
  118. package/lib/launcher/internal/runtime/RuntimeProjectOwnership.js +8 -6
  119. package/lib/launcher/internal/runtime/RuntimeProjectOwnership.js.map +1 -1
  120. package/lib/launcher/internal/runtime/advertiseTypeScriptExtensions.d.ts +20 -0
  121. package/lib/launcher/internal/runtime/advertiseTypeScriptExtensions.js +27 -0
  122. package/lib/launcher/internal/runtime/advertiseTypeScriptExtensions.js.map +1 -0
  123. package/lib/launcher/internal/runtime/commonJsExportNames.d.ts +2 -1
  124. package/lib/launcher/internal/runtime/commonJsExportNames.js +2 -1
  125. package/lib/launcher/internal/runtime/commonJsExportNames.js.map +1 -1
  126. package/lib/launcher/internal/runtime/installRuntimeHooks.d.ts +5 -3
  127. package/lib/launcher/internal/runtime/installRuntimeHooks.js +42 -12
  128. package/lib/launcher/internal/runtime/installRuntimeHooks.js.map +1 -1
  129. package/lib/launcher/internal/runtime/resolveRuntimeCleanTargets.js +3 -1
  130. package/lib/launcher/internal/runtime/resolveRuntimeCleanTargets.js.map +1 -1
  131. package/lib/launcher/internal/watch/AsyncWatchTopology.d.ts +113 -0
  132. package/lib/launcher/internal/watch/AsyncWatchTopology.js +232 -0
  133. package/lib/launcher/internal/watch/AsyncWatchTopology.js.map +1 -0
  134. package/lib/launcher/internal/watch/WatchSettlement.d.ts +49 -0
  135. package/lib/launcher/internal/watch/WatchSettlement.js +70 -0
  136. package/lib/launcher/internal/watch/WatchSettlement.js.map +1 -0
  137. package/lib/launcher/internal/watch/WatchTopology.d.ts +103 -13
  138. package/lib/launcher/internal/watch/WatchTopology.js +380 -95
  139. package/lib/launcher/internal/watch/WatchTopology.js.map +1 -1
  140. package/lib/launcher/internal/watch/WatchTopologyWorkerProtocol.d.ts +121 -0
  141. package/lib/launcher/internal/watch/WatchTopologyWorkerProtocol.js +3 -0
  142. package/lib/launcher/internal/watch/WatchTopologyWorkerProtocol.js.map +1 -0
  143. package/lib/launcher/internal/watch/projectInputReloadEventShouldNotify.d.ts +4 -1
  144. package/lib/launcher/internal/watch/projectInputReloadEventShouldNotify.js +3 -2
  145. package/lib/launcher/internal/watch/projectInputReloadEventShouldNotify.js.map +1 -1
  146. package/lib/launcher/internal/watch/serveWatchTopologyWorker.d.ts +19 -0
  147. package/lib/launcher/internal/watch/serveWatchTopologyWorker.js +62 -0
  148. package/lib/launcher/internal/watch/serveWatchTopologyWorker.js.map +1 -0
  149. package/lib/launcher/internal/watch/watchTopologyWorker.d.ts +1 -0
  150. package/lib/launcher/internal/watch/watchTopologyWorker.js +22 -0
  151. package/lib/launcher/internal/watch/watchTopologyWorker.js.map +1 -0
  152. package/lib/plugin/CapabilityPluginResolver.d.ts +1 -1
  153. package/lib/plugin/CapabilityPluginResolver.js +3 -2
  154. package/lib/plugin/CapabilityPluginResolver.js.map +1 -1
  155. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.d.ts +15 -12
  156. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js +13 -11
  157. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js.map +1 -1
  158. package/lib/plugin/internal/load/PluginPackageResolution.d.ts +2 -2
  159. package/lib/plugin/internal/load/PluginPackageResolution.js +13 -7
  160. package/lib/plugin/internal/load/PluginPackageResolution.js.map +1 -1
  161. package/lib/plugin/internal/load/ProjectPluginEntries.d.ts +23 -7
  162. package/lib/plugin/internal/load/ProjectPluginEntries.js +36 -14
  163. package/lib/plugin/internal/load/ProjectPluginEntries.js.map +1 -1
  164. package/lib/plugin/internal/load/collectProjectHostInputs.d.ts +3 -1
  165. package/lib/plugin/internal/load/collectProjectHostInputs.js +5 -2
  166. package/lib/plugin/internal/load/collectProjectHostInputs.js.map +1 -1
  167. package/lib/plugin/internal/load/hasProjectPluginEntries.d.ts +3 -1
  168. package/lib/plugin/internal/load/hasProjectPluginEntries.js +4 -2
  169. package/lib/plugin/internal/load/hasProjectPluginEntries.js.map +1 -1
  170. package/lib/plugin/internal/load/loadProjectPlugins.d.ts +36 -5
  171. package/lib/plugin/internal/load/loadProjectPlugins.js +477 -421
  172. package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
  173. package/lib/plugin/internal/load/pluginResolutionFailure.d.ts +18 -0
  174. package/lib/plugin/internal/load/pluginResolutionFailure.js +32 -0
  175. package/lib/plugin/internal/load/pluginResolutionFailure.js.map +1 -0
  176. package/lib/plugin/internal/load/resolveNativeSource.js +2 -3
  177. package/lib/plugin/internal/load/resolveNativeSource.js.map +1 -1
  178. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.d.ts +1 -1
  179. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js +3 -2
  180. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js.map +1 -1
  181. package/lib/plugin/internal/source/pluginModuleReplaceDirectories.d.ts +4 -1
  182. package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js +9 -2
  183. package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js.map +1 -1
  184. package/lib/structures/ITtscCompilerContext.d.ts +12 -12
  185. package/lib/structures/ITtscPlugin.d.ts +7 -5
  186. package/lib/structures/ITtscPluginFactoryContext.d.ts +9 -8
  187. package/lib/structures/internal/TtscCommonOptions.d.ts +2 -2
  188. package/lib/structures/internal/TtscSingleFileEmitOptions.d.ts +12 -6
  189. package/package.json +9 -9
  190. package/src/TtscCompiler.ts +1 -1
  191. package/src/compiler/internal/ResidentCheckProcess.ts +159 -374
  192. package/src/compiler/internal/ResidentCheckProcessHost.ts +502 -0
  193. package/src/compiler/internal/ResidentCheckProcessProtocol.ts +53 -0
  194. package/src/compiler/internal/build/BuildExecution.ts +123 -11
  195. package/src/compiler/internal/build/ResidentCheckWatchSession.ts +41 -24
  196. package/src/compiler/internal/build/RunBuildOptions.ts +9 -5
  197. package/src/compiler/internal/build/TsgoArguments.ts +4 -1
  198. package/src/compiler/internal/build/WatchInputPublication.ts +106 -0
  199. package/src/compiler/internal/build/runBuild.ts +58 -34
  200. package/src/compiler/internal/buildNativeCompiler.ts +4 -0
  201. package/src/compiler/internal/compileProjectInMemory.ts +8 -2
  202. package/src/compiler/internal/project/CompilerProjectSelection.ts +14 -14
  203. package/src/compiler/internal/project/resolveOwningProjectConfig.ts +42 -16
  204. package/src/compiler/internal/readEffectiveCompilerOptions.ts +1 -1
  205. package/src/compiler/internal/resolveBinary.ts +4 -1
  206. package/src/compiler/internal/resolveTsgo.ts +7 -0
  207. package/src/compiler/internal/runSingleFileEmit.ts +145 -101
  208. package/src/compiler/internal/startResidentTransform.ts +9 -2
  209. package/src/compiler/internal/transformProjectInMemory.ts +12 -3
  210. package/src/compiler/internal/transformProjectInWorker.ts +10 -2
  211. package/src/flags/ParseOptions.ts +2 -2
  212. package/src/internal/E2ETrace.ts +3 -1
  213. package/src/internal/OwnedNativeProcess.ts +2 -2
  214. package/src/internal/SourceNativeRetirement.ts +42 -19
  215. package/src/internal/TtsxNodeOptions.ts +124 -0
  216. package/src/internal/javascriptRuntimeCapabilities.ts +6 -1
  217. package/src/internal/parseWindowsDirectoryCaseSensitivity.ts +5 -5
  218. package/src/internal/pathIdentity/createCaseSensitivityObservations.ts +242 -0
  219. package/src/internal/pathIdentity/createFilesystemPathIdentityContext.ts +2 -169
  220. package/src/internal/projectInputPathIdentity.ts +1 -0
  221. package/src/internal/workerModuleUrl.ts +34 -0
  222. package/src/launcher/internal/buildSingleRootProject.ts +2 -0
  223. package/src/launcher/internal/getCompilerVersionText.ts +3 -2
  224. package/src/launcher/internal/parseTtsxCLI.ts +5 -4
  225. package/src/launcher/internal/prepareExecution.ts +6 -1
  226. package/src/launcher/internal/resolveSingleFileOutput.ts +8 -9
  227. package/src/launcher/internal/runTtsc.ts +127 -49
  228. package/src/launcher/internal/runTtsx.ts +17 -8
  229. package/src/launcher/internal/runtime/CommonJsRuntimeSource.ts +11 -9
  230. package/src/launcher/internal/runtime/RuntimeEntrySources.ts +57 -0
  231. package/src/launcher/internal/runtime/RuntimeProjectOwnership.ts +23 -10
  232. package/src/launcher/internal/runtime/advertiseTypeScriptExtensions.ts +25 -0
  233. package/src/launcher/internal/runtime/commonJsExportNames.ts +11 -4
  234. package/src/launcher/internal/runtime/installRuntimeHooks.ts +62 -16
  235. package/src/launcher/internal/runtime/resolveRuntimeCleanTargets.ts +17 -5
  236. package/src/launcher/internal/watch/AsyncWatchTopology.ts +267 -0
  237. package/src/launcher/internal/watch/WatchSettlement.ts +67 -0
  238. package/src/launcher/internal/watch/WatchTopology.ts +461 -102
  239. package/src/launcher/internal/watch/WatchTopologyWorkerProtocol.ts +106 -0
  240. package/src/launcher/internal/watch/projectInputReloadEventShouldNotify.ts +14 -9
  241. package/src/launcher/internal/watch/serveWatchTopologyWorker.ts +75 -0
  242. package/src/launcher/internal/watch/watchTopologyWorker.ts +29 -0
  243. package/src/plugin/CapabilityPluginResolver.ts +9 -2
  244. package/src/plugin/internal/load/PluginDescriptorEvaluationCache.ts +17 -12
  245. package/src/plugin/internal/load/PluginPackageResolution.ts +14 -9
  246. package/src/plugin/internal/load/ProjectPluginEntries.ts +40 -15
  247. package/src/plugin/internal/load/collectProjectHostInputs.ts +7 -1
  248. package/src/plugin/internal/load/hasProjectPluginEntries.ts +8 -3
  249. package/src/plugin/internal/load/loadProjectPlugins.ts +683 -593
  250. package/src/plugin/internal/load/pluginResolutionFailure.ts +37 -0
  251. package/src/plugin/internal/load/resolveNativeSource.ts +10 -4
  252. package/src/plugin/internal/source/PluginBuildEnvironmentReadings.ts +8 -2
  253. package/src/plugin/internal/source/pluginModuleReplaceDirectories.ts +10 -1
  254. package/src/structures/ITtscCompilerContext.ts +12 -12
  255. package/src/structures/ITtscPlugin.ts +7 -5
  256. package/src/structures/ITtscPluginFactoryContext.ts +9 -8
  257. package/src/structures/internal/TtscCommonOptions.ts +2 -2
  258. package/src/structures/internal/TtscSingleFileEmitOptions.ts +22 -11
  259. package/internal/graphsymbols/position_helpers_follow_ecma_line_terminators_test.go +0 -78
  260. package/internal/graphsymbols/provider.go +0 -650
  261. package/internal/lspserver/lsp_symbols.go +0 -212
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
 
5
5
  import { resolveTsgo } from "../../compiler/internal/resolveTsgo";
6
6
  import { E2ETrace } from "../../internal/E2ETrace";
7
+ import { TtsxNodeOptions } from "../../internal/TtsxNodeOptions";
7
8
  import { TtsxEntryOptions } from "./TtsxEntryOptions";
8
9
  import { getCompilerVersionText } from "./getCompilerVersionText";
9
10
  import { parseTtsxCLI } from "./parseTtsxCLI";
@@ -243,9 +244,13 @@ async function runJavaScriptEntry(
243
244
  ];
244
245
  const env: NodeJS.ProcessEnv = {
245
246
  ...process.env,
246
- NODE_OPTIONS: appendNodeOption(
247
- process.env.NODE_OPTIONS,
248
- `--require ${JSON.stringify(path.join(__dirname, "..", "..", "register.js"))}`,
247
+ // ttsc's own helpers run with what the user passed (#1740).
248
+ ...TtsxNodeOptions.give(
249
+ process.env,
250
+ appendNodeOption(
251
+ process.env.NODE_OPTIONS,
252
+ `--require ${JSON.stringify(path.join(__dirname, "..", "..", "register.js"))}`,
253
+ ),
249
254
  ),
250
255
  ...(parsed.binary !== undefined
251
256
  ? { TTSC_TSGO_BINARY: path.resolve(cwd, parsed.binary) }
@@ -324,12 +329,16 @@ async function runPreparedEntry(
324
329
  ];
325
330
  const runtimeEnv: NodeJS.ProcessEnv = {
326
331
  ...process.env,
327
- NODE_OPTIONS: appendNodeOption(
328
- prependNodeOption(
329
- process.env.NODE_OPTIONS,
330
- `--require ${JSON.stringify(path.join(__dirname, "runtimeOwnerPreload.js"))}`,
332
+ // ttsc's own helpers run with what the user passed (#1740).
333
+ ...TtsxNodeOptions.give(
334
+ process.env,
335
+ appendNodeOption(
336
+ prependNodeOption(
337
+ process.env.NODE_OPTIONS,
338
+ `--require ${JSON.stringify(path.join(__dirname, "runtimeOwnerPreload.js"))}`,
339
+ ),
340
+ `--require ${JSON.stringify(path.join(__dirname, "runtimeHookPreload.js"))}`,
331
341
  ),
332
- `--require ${JSON.stringify(path.join(__dirname, "runtimeHookPreload.js"))}`,
333
342
  ),
334
343
  // The compiler this run resolved, which already honours an inherited
335
344
  // `TTSC_TSGO_BINARY` when no `--binary` was given.
@@ -71,16 +71,20 @@ export namespace CommonJsRuntimeSource {
71
71
  }
72
72
 
73
73
  /**
74
- * Construct an owned require with local TypeScript extension advertisements.
74
+ * Construct an owned require sharing the original live extension registry.
75
75
  *
76
- * @evidence contracts/common.md#principled-implementation createRequire loads through Node's shared CommonJS cache; copied public properties preserve cache/main access, while a copied registry advertises the already-supported source extensions without changing their actual loader.
76
+ * Node's loader and every native require share this registration object.
77
+ * Copying it hides later registrations, replacements and deletions from one
78
+ * side; source-extension advertisement belongs to runtime installation.
79
+ *
80
+ * @evidence contracts/common.md#principled-implementation createRequire loads through Node's shared CommonJS cache; copied public properties preserve cache/main access, and the original registry reference preserves the public extension-registration contract across later edits. Missing original metadata falls back to the native registry.
77
81
  * @evidence contracts/common.md#clear-and-simple-design The callable and resolve member share one filename anchor; source recovery remains in the configured policy.
78
- * @evidence contracts/common.md#prohibited-implementation-shortcuts Extension entries belong to this new function, not Module._extensions or a foreign require; no private loader slot is assigned.
79
- * @evidence contracts/common.md#meaningful-documentation Native prose identifies ownership and distinguishes advertisements from actual loading.
82
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Construction assigns only the owned function's properties, adds no extension capability and replaces no foreign handler or private loader slot. Runtime installation separately advertises its supported CommonJS source extensions.
83
+ * @evidence contracts/common.md#meaningful-documentation Native prose explains why live registry identity is required and assigns advertisement to the installation owner.
80
84
  * @evidence contracts/portability.md#os-neutral-implementation The public createRequire API takes the native filename; no OS-name or path-string case heuristic is introduced.
81
- * @evidence contracts/performance.md#efficient-algorithms Construction copies public require properties and E extension entries, including their property observations, and creates a native filename-anchored require. Calls delegate native resolution, module evaluation/cache work or the configured resolver; their cost is not bounded by construction or extension count.
85
+ * @evidence contracts/performance.md#efficient-algorithms Construction copies P public require properties and creates a native filename-anchored require without traversing or allocating another extension registry. Calls delegate native resolution, module evaluation/cache work or the configured resolver; their cost is not bounded by property count.
82
86
  * @evidence contracts/performance.md#reuse-equivalent-work Callable loading delegates to Node's CommonJS cache; the configured resolve policy remains a distinct per-call operation, not a cached result of constructing the function.
83
- * @evidence contracts/performance.md#bound-retention-and-release-resources The evaluated module owns the returned function, captured filename/native require and copied extension registry. Captured cache/main references share Node or original-require state rather than copying all cached modules; the factory adds no historical module collection or native handle.
87
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The evaluated module owns the returned function and captured filename/native require. Cache, main and extension-registry references share Node or original-require state; the factory adds no registry copy, historical module collection or native handle.
84
88
  */
85
89
  export function create(
86
90
  original: NodeJS.Require,
@@ -107,9 +111,7 @@ export namespace CommonJsRuntimeSource {
107
111
  )) as NodeJS.RequireResolve;
108
112
  owned.resolve.paths = native.resolve.paths;
109
113
  owned.cache = original.cache ?? native.cache;
110
- owned.extensions = { ...(original.extensions ?? native.extensions) };
111
- for (const extension of [".ts", ".tsx", ".cts", ".mts"])
112
- owned.extensions[extension] = owned.extensions[".js"]!;
114
+ owned.extensions = original.extensions ?? native.extensions;
113
115
  return owned;
114
116
  }
115
117
 
@@ -0,0 +1,57 @@
1
+ import type { RuntimeManifest } from "./RuntimeManifest";
2
+
3
+ /**
4
+ * The served source of each entry module a checked entry build emitted,
5
+ * prepared once.
6
+ *
7
+ * A checked entry build's emit is immutable for the run: ttsx prepares it
8
+ * before the program starts, and a root `ttsc/register` prepares stays
9
+ * registered (`RuntimeManifestRegistry`). Node 22.15 nevertheless calls the
10
+ * `load` hook twice for the process entry, and each call read and source-mapped
11
+ * the same emitted file again (samchon/ttsc#1749). A repeated entry load of one
12
+ * build's emitted file is answered from its first preparation. A module served
13
+ * by any other lane, a project build or an isolated emit of a file the program
14
+ * may rewrite, is prepared on every load as before, and so is a non-entry
15
+ * module, whose text Node already holds.
16
+ *
17
+ * @evidence contracts/common.md#principled-implementation Only an entry module's emitted file of a registered checked build, the registry's immutable premise, is remembered, keyed by that build, so a reused answer is the answer a repeated read would give.
18
+ * @evidence contracts/common.md#clear-and-simple-design One map per build and one accessor; the caller supplies the preparation it already performs.
19
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Nothing about Node's loader is patched; the hook still answers every call Node makes, and lanes whose source can change are never remembered.
20
+ * @evidence contracts/common.md#meaningful-documentation Native prose names the repeated call, the immutable entry emit and the lanes left unaffected.
21
+ * @evidence contracts/portability.md#os-neutral-implementation Files are keyed by the emitted path the build's ownership index returned, under the build object that owns it.
22
+ * @evidence contracts/performance.md#efficient-algorithms One WeakMap and one map lookup per serve.
23
+ * @evidence contracts/performance.md#reuse-equivalent-work A repeated entry load of an entry build's emitted file reuses the first preparation.
24
+ * @evidence contracts/performance.md#bound-retention-and-release-resources One served source per entry module, held while the registry keeps its build; a run has one entry and a handful of JavaScript-to-TypeScript boundaries.
25
+ */
26
+ export namespace RuntimeEntrySources {
27
+ /**
28
+ * The served source of entry module `emittedFile` from checked entry build
29
+ * `manifest`, prepared by `prepare` on its first serve only.
30
+ *
31
+ * @evidence contracts/common.md#principled-implementation Only an entry load of a registered checked build's emitted file asks; that emit is immutable for the run, so the first preparation is the answer a repeated one would give.
32
+ * @evidence contracts/common.md#clear-and-simple-design One lookup or one preparation and insertion.
33
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The caller's own preparation runs unchanged on the first serve.
34
+ * @evidence contracts/common.md#meaningful-documentation Native prose states which serve prepares.
35
+ * @evidence contracts/portability.md#os-neutral-implementation Files are keyed by the emitted path the ownership index returned.
36
+ * @evidence contracts/performance.md#efficient-algorithms One WeakMap and one map lookup, and on the first serve one insertion.
37
+ * @evidence contracts/performance.md#reuse-equivalent-work A repeated serve returns the first preparation.
38
+ * @evidence contracts/performance.md#bound-retention-and-release-resources One source per entry module is retained while its build is.
39
+ */
40
+ export function serve<Source>(
41
+ manifest: RuntimeManifest,
42
+ emittedFile: string,
43
+ prepare: () => Source,
44
+ ): Source {
45
+ let files = served.get(manifest);
46
+ if (files === undefined) {
47
+ files = new Map();
48
+ served.set(manifest, files);
49
+ }
50
+ if (files.has(emittedFile)) return files.get(emittedFile) as Source;
51
+ const source = prepare();
52
+ files.set(emittedFile, source);
53
+ return source;
54
+ }
55
+ }
56
+
57
+ const served = new WeakMap<RuntimeManifest, Map<string, unknown>>();
@@ -24,8 +24,8 @@ export namespace RuntimeProjectOwnership {
24
24
  const cache = new Map<string, Lookup>();
25
25
 
26
26
  /**
27
- * Whether a physical source path passes through an installed directory.
28
- * A linked workspace physically outside that directory remains user source.
27
+ * Whether a physical source path passes through an installed directory. A
28
+ * linked workspace physically outside that directory remains user source.
29
29
  * Alternate spellings count only when the native lowercase installed spelling
30
30
  * resolves to the same physical directory; failed identity reads prove none.
31
31
  *
@@ -39,7 +39,7 @@ export namespace RuntimeProjectOwnership {
39
39
  * @evidence contracts/performance.md#bound-retention-and-release-resources The synchronous walk retains no handles or historical identities.
40
40
  */
41
41
  export function isInstalledPackageSource(real: string): boolean {
42
- for (let directory = path.dirname(real);;) {
42
+ for (let directory = path.dirname(real); ; ) {
43
43
  if (isInstalledDirectory(directory)) return true;
44
44
  const parent = path.dirname(directory);
45
45
  if (parent === directory) return false;
@@ -54,8 +54,9 @@ export namespace RuntimeProjectOwnership {
54
54
  * Cached walks recheck both candidate files and the native boundary topology.
55
55
  * Creating/deleting a config or adding/removing an installed alias therefore
56
56
  * cannot retain an earlier consumer or isolated selection. The observer
57
- * brackets config candidates and alternate directory identities for descriptor
58
- * dependency recording; it does not pin the filesystem during compilation.
57
+ * brackets config candidates and alternate directory identities for
58
+ * descriptor dependency recording; it does not pin the filesystem during
59
+ * compilation.
59
60
  *
60
61
  * @evidence contracts/common.md#principled-implementation Upward traversal selects the first existing config before the installed boundary. Cache entries retain ordered candidates and their stopping boundary; current candidate and native topology checks establish whether the old selection still applies.
61
62
  * @evidence contracts/common.md#clear-and-simple-design The same private predicate serves fresh lookup, cached topology validation and installed-source classification. One directory-keyed cache shares the walked suffix without a second casing policy.
@@ -79,18 +80,28 @@ export namespace RuntimeProjectOwnership {
79
80
  if (cached !== undefined) {
80
81
  observe(cached.candidates);
81
82
  const topologyCurrent =
82
- (cached.boundary === undefined || isInstalledDirectory(cached.boundary, observe)) &&
83
- cached.candidates.every((candidate) => !isInstalledDirectory(path.dirname(candidate), observe));
83
+ (cached.boundary === undefined ||
84
+ isInstalledDirectory(cached.boundary, observe)) &&
85
+ cached.candidates.every(
86
+ (candidate) =>
87
+ !isInstalledDirectory(path.dirname(candidate), observe),
88
+ );
84
89
  const current = nearestExisting(cached.candidates);
85
90
  observe(cached.candidates);
86
91
  if (topologyCurrent && current === cached.result)
87
- return remember(chain, cached.result, cached.candidates, cached.boundary);
92
+ return remember(
93
+ chain,
94
+ cached.result,
95
+ cached.candidates,
96
+ cached.boundary,
97
+ );
88
98
  cache.delete(directory);
89
99
  }
90
100
  chain.push(directory);
91
101
  const candidate = path.join(directory, "tsconfig.json");
92
102
  observe([candidate]);
93
- if (RuntimeFilesystem.isFile(candidate)) return remember(chain, candidate);
103
+ if (RuntimeFilesystem.isFile(candidate))
104
+ return remember(chain, candidate);
94
105
  const parent = path.dirname(directory);
95
106
  if (parent === directory) return remember(chain, null);
96
107
  directory = parent;
@@ -108,7 +119,9 @@ export namespace RuntimeProjectOwnership {
108
119
  const inputs = [directory, lowercase];
109
120
  observe(inputs);
110
121
  try {
111
- return fs.realpathSync.native(directory) === fs.realpathSync.native(lowercase);
122
+ return (
123
+ fs.realpathSync.native(directory) === fs.realpathSync.native(lowercase)
124
+ );
112
125
  } catch {
113
126
  return false;
114
127
  } finally {
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Publish the CommonJS source extensions served by the installed runtime hooks.
3
+ *
4
+ * Tools such as tsconfig-paths enumerate the process registry before asking
5
+ * Node to resolve a file, and rechoir checks it before loading a typed config.
6
+ * A module-local copy cannot satisfy those checks. Add only missing entries
7
+ * using Node's JavaScript handler; registerHooks still owns source compilation
8
+ * and existing loader handlers keep their identity. Node probes these entries
9
+ * after its existing extensions, preserving JavaScript precedence.
10
+ *
11
+ * @evidence contracts/common.md#principled-implementation The public require.extensions registry advertises supported CommonJS source loading to consumers that inspect extensions before resolution; absent entries delegate to Node's existing JavaScript handler, which consumes the source supplied by registerHooks.
12
+ * @evidence contracts/common.md#clear-and-simple-design One installation operation publishes loader capability without adding a second compilation or resolution path.
13
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Only missing public registry entries are added; no foreign handler or method is replaced and no consumer identity affects production behavior. The source suffixes describe the supported CommonJS contract rather than fixture-specific routes.
14
+ * @evidence contracts/common.md#meaningful-documentation The prose explains why process-wide advertisement is needed, who compiles the source, which handlers remain authoritative and how native precedence is preserved.
15
+ * @evidenceExclude contracts/portability.md#os-neutral-implementation Registry updates use JavaScript property semantics without filesystem, path or process arguments; Node's loader owns native resolution.
16
+ * @evidence contracts/performance.md#efficient-algorithms A fixed set of three CommonJS source extensions requires constant time and space, without scanning modules or files.
17
+ * @evidenceExclude contracts/performance.md#reuse-equivalent-work This capability publication shares no computed compilation or resolution result.
18
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The caller's process registry retains at most three added references to an existing Node handler for the installed hooks' process lifetime; no handle or task is acquired.
19
+ */
20
+ export function advertiseTypeScriptExtensions(
21
+ extensions: NodeJS.RequireExtensions,
22
+ ): void {
23
+ for (const extension of [".ts", ".tsx", ".cts"])
24
+ extensions[extension] ??= extensions[".js"]!;
25
+ }
@@ -13,7 +13,8 @@ import { realPath } from "./realPath";
13
13
  * become resolution origins. Targets are not evaluated. Failed resolution adds
14
14
  * no names and leaves the eventual native load to report its error, whereas a
15
15
  * reader's ownership error propagates. Root default metadata is retained for
16
- * the facade's native own-property ordering; nested default is not re-exported.
16
+ * the facade's native own-property ordering; nested default is not
17
+ * re-exported.
17
18
  *
18
19
  * @evidence contracts/common.md#principled-implementation Node createRequire resolves each edge from the physical source module using require conditions; the runtime supplies its existing source-rescue resolver on supported hook variants. Owned compiler bytes retain TypeScript elision and lowering. Static parsing discovers possible names, while the original loaded helper and facade own values and property semantics.
19
20
  * @evidence contracts/common.md#clear-and-simple-design One traversal serves both JavaScript and TypeScript facades. A call-scoped physical seen set prevents mixed-source cycles and duplicate reads without separate emitted/source resolution policies.
@@ -28,8 +29,10 @@ export function commonJsExportNames(
28
29
  source: string,
29
30
  filename: string,
30
31
  readSource: (file: string) => string | null,
31
- resolve: (parent: string, specifier: string) => string = (parent, specifier) =>
32
- createRequire(parent).resolve(specifier),
32
+ resolve: (parent: string, specifier: string) => string = (
33
+ parent,
34
+ specifier,
35
+ ) => createRequire(parent).resolve(specifier),
33
36
  ): string[] {
34
37
  const names = new Set<string>();
35
38
  const seen = new Set<string>();
@@ -42,7 +45,11 @@ export function commonJsExportNames(
42
45
  if (root || name !== "default") names.add(name);
43
46
  for (const specifier of parsed.reexports) {
44
47
  let target: string;
45
- try { target = resolve(real, specifier); } catch { continue; }
48
+ try {
49
+ target = resolve(real, specifier);
50
+ } catch {
51
+ continue;
52
+ }
46
53
  if (!path.isAbsolute(target)) continue;
47
54
  if ([".json", ".node", ".mjs"].includes(path.extname(target))) continue;
48
55
  const physical = realPath(target);
@@ -34,14 +34,16 @@ import type { OwningModuleOptions } from "./OwningModuleOptions";
34
34
  import { PluginDescriptorInputObservation } from "./PluginDescriptorInputObservation";
35
35
  import type { ResolveResult } from "./ResolveResult";
36
36
  import { RuntimeEmitProvenance } from "./RuntimeEmitProvenance";
37
+ import { RuntimeEntrySources } from "./RuntimeEntrySources";
37
38
  import { RuntimeFilesystem } from "./RuntimeFilesystem";
38
39
  import type { RuntimeHookOptions } from "./RuntimeHookOptions";
39
40
  import { RuntimeIsolatedEmit } from "./RuntimeIsolatedEmit";
40
41
  import { RuntimeLoaderCapabilities } from "./RuntimeLoaderCapabilities";
41
42
  import type { RuntimeManifest } from "./RuntimeManifest";
42
43
  import { RuntimeManifestRegistry } from "./RuntimeManifestRegistry";
43
- import { RuntimeProjectOwnership } from "./RuntimeProjectOwnership";
44
44
  import { RuntimeModuleFormat } from "./RuntimeModuleFormat";
45
+ import { RuntimeProjectOwnership } from "./RuntimeProjectOwnership";
46
+ import { advertiseTypeScriptExtensions } from "./advertiseTypeScriptExtensions";
45
47
  import { checkNodeRuntimeSupport } from "./checkNodeRuntimeSupport";
46
48
  import { commonJsExportNames } from "./commonJsExportNames";
47
49
  import { commonJsImportFacade } from "./commonJsImportFacade";
@@ -93,8 +95,10 @@ import { selectRuntimePluginPolicy } from "./selectRuntimePluginPolicy";
93
95
  * reach the API lacks on some releases is `require.resolve`, which is probed
94
96
  * before installation. Served CommonJS bodies receive an owned require function
95
97
  * whose resolve member applies the same source policy on those releases. Its
96
- * copied extension registry advertises the supported source extensions; foreign
97
- * resolver methods and global extension registries are never replaced.
98
+ * shared extension registry preserves live registrations. Installation also
99
+ * advertises missing CommonJS source extensions in the process registry because
100
+ * ecosystem tools inspect it before resolution; existing handlers remain intact
101
+ * and foreign resolver methods are never replaced.
98
102
  *
99
103
  * Direct descriptor evaluation records user preloads after hook installation.
100
104
  * Only the generated CommonJS output sibling takes Node's native resolve/load
@@ -103,7 +107,7 @@ import { selectRuntimePluginPolicy } from "./selectRuntimePluginPolicy";
103
107
  *
104
108
  * @evidence contracts/common.md#principled-implementation Resolution preserves successful Node decisions, rescues source spellings only after documented resolution fails, and serves only outputs whose ownership index names the exact source. CommonJS facades delegate native evaluation and project detected own named exports under the selected namespace capability; an owned module-local require supplies source resolution when native require.resolve bypasses public hooks.
105
109
  * @evidence contracts/common.md#clear-and-simple-design One synchronous hook owner coordinates source selection, emission ownership and descriptor observation; the entry, owning-project and orphan lanes remain explicit because they have distinct compilation premises. Private helpers carry those policies without a second foreign-resolver layer.
106
- * @evidence contracts/common.md#prohibited-implementation-shortcuts Public registerHooks handles resolution and loading; installation mutates neither Module._resolveFilename nor require.extensions. Source-extension recovery implements emitted-to-source spelling under the runtime contract, and module-local require adaptation addresses the probed public-hook difference without replacing Node methods.
110
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Public registerHooks handles resolution and loading; installation adds missing public extension entries with Node's own JavaScript handler while preserving every existing handler and resolver method. Source-extension recovery implements emitted-to-source spelling under the runtime contract, and module-local require adaptation addresses the probed public-hook difference without replacing Node methods.
107
111
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs describe the three serving lanes, compile gates, source identity, capability-based local adaptation and extension-registry ownership; helper comments state ownership and failure effects with descriptive prose separated from tags.
108
112
  * @evidence contracts/portability.md#os-neutral-implementation Node URL conversion, native filesystem paths and physical resolution preserve OS spelling boundaries. Actual public-hook probes select runtime capabilities, native emit uses executable arguments without shell interpolation, and unresolved filesystem observation refuses reusable descriptor proof.
109
113
  * @evidence contracts/performance.md#efficient-algorithms Source ownership indexes replace repeated whole-emit scans with indexed source/native-identity queries. Export discovery processes source/emit bytes, reexport edges, native resolution and Set/name unions under traversal-local seen sets; separate roots can repeat traversal. Config-chain validation reads discovered inputs. Compiler identity brackets and streams executable bytes on valid lookups, refusing failed observations. Native build/name-scan/orphan paths add compilation, path/metadata/IO cost; recursive graphs remain subject to stack limits.
@@ -133,6 +137,7 @@ export function installRuntimeHooks(options: RuntimeHookOptions = {}): void {
133
137
  process.setSourceMapsEnabled(true);
134
138
  }
135
139
  registerHooks({ load, resolve });
140
+ advertiseTypeScriptExtensions(require.extensions);
136
141
  PluginDescriptorInputObservation.begin(true);
137
142
  installed = true;
138
143
  }
@@ -390,7 +395,9 @@ function observePluginDescriptorResolutionCandidates(
390
395
  appendPluginDescriptorInputs(
391
396
  observation
392
397
  .commit(
393
- selectedURL === undefined ? undefined : runtimeFilePath(selectedURL),
398
+ selectedURL === undefined
399
+ ? undefined
400
+ : runtimeFilePath(selectedURL),
394
401
  )
395
402
  .map((record) => `${JSON.stringify({ parent, ...record })}\n`),
396
403
  );
@@ -1003,13 +1010,17 @@ function servesCommonJsFromSource(url: string): boolean {
1003
1010
  }
1004
1011
 
1005
1012
  /** Scan both facade lanes from source paths using their actual require policy. */
1006
- function runtimeCommonJsExportNames(filename: string, source: string): string[] {
1013
+ function runtimeCommonJsExportNames(
1014
+ filename: string,
1015
+ source: string,
1016
+ ): string[] {
1007
1017
  return commonJsExportNames(
1008
1018
  source,
1009
1019
  filename,
1010
- (target) => isTypeScriptSource(target)
1011
- ? emitCommonJsForNameScan(target)
1012
- : readFileOrNull(target),
1020
+ (target) =>
1021
+ isTypeScriptSource(target)
1022
+ ? emitCommonJsForNameScan(target)
1023
+ : readFileOrNull(target),
1013
1024
  (parent, specifier) => {
1014
1025
  const native = createRequire(parent).resolve;
1015
1026
  return resolveCommonJsRequest(native, specifier, undefined, parent);
@@ -1227,20 +1238,20 @@ function resolveServedSource(
1227
1238
  prepareAsEntry: boolean = false,
1228
1239
  ): ServedSource {
1229
1240
  const real = realPath(filename);
1230
- let served = serveEntryEmit(real);
1241
+ let served = serveInlinedEntryEmit(real, prepareAsEntry);
1231
1242
  if (served !== null) {
1232
- return withInlineSourceMap(served);
1243
+ return served;
1233
1244
  }
1234
1245
  // Only the public preload can prepare a newly discovered root; direct ttsx
1235
1246
  // prepared its one entry before the child started.
1236
1247
  const prepareEntry = prepareAsEntry ? prepareRuntimeEntry : undefined;
1237
1248
  if (prepareEntry !== undefined) {
1238
1249
  RuntimeManifestRegistry.registerManifest(prepareEntry(real));
1239
- served = serveEntryEmit(real);
1250
+ served = serveInlinedEntryEmit(real, true);
1240
1251
  if (served === null) {
1241
1252
  throw new Error(`ttsx: prepared entry emit not found for ${filename}`);
1242
1253
  }
1243
- return withInlineSourceMap(served);
1254
+ return served;
1244
1255
  }
1245
1256
  const built = serveProjectEmit(real);
1246
1257
  if (built !== null) {
@@ -1723,10 +1734,36 @@ class RuntimeEmitOwnershipError extends Error {}
1723
1734
  * next lane and run something else.
1724
1735
  */
1725
1736
  function serveEntryEmit(real: string): ServedSource | null {
1737
+ const owner = RuntimeManifestRegistry.findEntryEmit(real);
1738
+ return owner === null ? null : entryEmitSource(owner, real);
1739
+ }
1740
+
1741
+ /**
1742
+ * {@link serveEntryEmit} with the emit's source map inlined, as a module load
1743
+ * serves it. A checked entry build's emit is immutable for the run, so an entry
1744
+ * load, which Node 22.15 repeats for the process entry, reads and source-maps
1745
+ * each emitted file once (`RuntimeEntrySources`, samchon/ttsc#1749). Other
1746
+ * modules are not remembered: Node keeps each loaded module, and holding every
1747
+ * served text beside it would retain the whole program's emit.
1748
+ */
1749
+ function serveInlinedEntryEmit(
1750
+ real: string,
1751
+ entry: boolean,
1752
+ ): ServedSource | null {
1726
1753
  const owner = RuntimeManifestRegistry.findEntryEmit(real);
1727
1754
  if (owner === null) {
1728
1755
  return null;
1729
1756
  }
1757
+ const prepare = () => withInlineSourceMap(entryEmitSource(owner, real));
1758
+ return entry
1759
+ ? RuntimeEntrySources.serve(owner.manifest, owner.emittedFile, prepare)
1760
+ : prepare();
1761
+ }
1762
+
1763
+ function entryEmitSource(
1764
+ owner: NonNullable<ReturnType<typeof RuntimeManifestRegistry.findEntryEmit>>,
1765
+ real: string,
1766
+ ): ServedSource {
1730
1767
  return {
1731
1768
  emittedFile: owner.emittedFile,
1732
1769
  moduleOptions: owner.manifest.moduleOptions ?? {},
@@ -2339,16 +2376,25 @@ function owningTsconfig(real: string): string | null {
2339
2376
  recordPluginDescriptorProjectInputs,
2340
2377
  );
2341
2378
  if (nearest === null) return null;
2342
- // Config spelling and target identity do not prove that inherited options,
2343
- // reference roots or directory membership are unchanged. The resolver owns
2344
- // lookup-scoped reuse; a later import must ask it for a current answer.
2379
+ // The project this selects is built once per process (`ensureProjectBuilt`),
2380
+ // so the reference roots that select it are kept for the process as well;
2381
+ // re-expanding them for every module cost a compiler run per referenced
2382
+ // project (samchon/ttsc#1747). A file created after an expansion is still
2383
+ // expanded for afresh.
2345
2384
  return resolveOwningProjectConfig({
2385
+ expansions: ownerExpansions,
2346
2386
  file: real,
2347
2387
  onConfig: (config) => recordPluginDescriptorProjectInputs([config]),
2348
2388
  tsconfig: nearest,
2349
2389
  });
2350
2390
  }
2351
2391
 
2392
+ /** Reference roots `owningTsconfig` expanded in this process, by config. */
2393
+ const ownerExpansions = new Map<
2394
+ string,
2395
+ { files: readonly string[]; takenAt: number }
2396
+ >();
2397
+
2352
2398
  function readFileOrNull(file: string | null): string | null {
2353
2399
  if (file === null) {
2354
2400
  return null;
@@ -67,13 +67,22 @@ export function resolveRuntimeCleanTargets(cacheRoot: string): {
67
67
  const removable: string[] = [];
68
68
  for (const entry of entries) {
69
69
  const directory = path.join(physicalRuns, entry);
70
- const observe = E2ETrace.runtimeCleanup(directory, runtime, "runtime-clean-selection");
70
+ const observe = E2ETrace.runtimeCleanup(
71
+ directory,
72
+ runtime,
73
+ "runtime-clean-selection",
74
+ );
71
75
  observe?.("selection-started");
72
76
  let ownership: ReturnType<typeof ProcessOwnedDirectory.ownership>;
73
77
  try {
74
- ownership = ProcessOwnedDirectory.ownership(directory, false,
75
- observe === undefined ? undefined : (observation) =>
76
- observe("owner-observation", undefined, undefined, observation));
78
+ ownership = ProcessOwnedDirectory.ownership(
79
+ directory,
80
+ false,
81
+ observe === undefined
82
+ ? undefined
83
+ : (observation) =>
84
+ observe("owner-observation", undefined, undefined, observation),
85
+ );
77
86
  } catch (cause) {
78
87
  observe?.("selection-failed", undefined, cause);
79
88
  throw cause;
@@ -81,7 +90,10 @@ export function resolveRuntimeCleanTargets(cacheRoot: string): {
81
90
  observe?.("ownership", ownership);
82
91
  if (ownership !== "abandoned") kept.push(directory);
83
92
  else removable.push(directory);
84
- observe?.(ownership === "abandoned" ? "removal-selected" : "retention-selected", ownership);
93
+ observe?.(
94
+ ownership === "abandoned" ? "removal-selected" : "retention-selected",
95
+ ownership,
96
+ );
85
97
  }
86
98
  return {
87
99
  kept,