ttsc 0.31.0 → 0.31.2

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 (155) hide show
  1. package/cmd/platform/main.go +2 -2
  2. package/internal/sourceprocess/contain_windows.go +10 -13
  3. package/internal/sourceprocess/started_windows.go +41 -0
  4. package/internal/sourceprocess/windows_started_publication_distinguishes_pending_from_refusal_test.go +76 -0
  5. package/internal/watchhelper/run.go +30 -20
  6. package/internal/watchhelper/run_other.go +4 -4
  7. package/internal/watchhelper/run_windows.go +471 -0
  8. package/internal/watchhelper/watchhelper.go +8 -2
  9. package/internal/watchhelper/windows_notifications_preserve_mutations_without_access_noise_test.go +506 -0
  10. package/lib/compiler/internal/build/BuildExecution.d.ts +4 -2
  11. package/lib/compiler/internal/build/BuildExecution.js +40 -12
  12. package/lib/compiler/internal/build/BuildExecution.js.map +1 -1
  13. package/lib/compiler/internal/startResidentTransform.js +5 -4
  14. package/lib/compiler/internal/startResidentTransform.js.map +1 -1
  15. package/lib/compiler/internal/transformProjectInMemory.js +9 -7
  16. package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
  17. package/lib/internal/javascriptRuntimeCapabilities.d.ts +13 -4
  18. package/lib/internal/javascriptRuntimeCapabilities.js +56 -6
  19. package/lib/internal/javascriptRuntimeCapabilities.js.map +1 -1
  20. package/lib/internal/nativeBinary.d.ts +3 -3
  21. package/lib/internal/nativeBinary.js +3 -3
  22. package/lib/internal/pluginSource.d.ts +1 -0
  23. package/lib/internal/pluginSource.js +1 -0
  24. package/lib/internal/pluginSource.js.map +1 -1
  25. package/lib/internal/resolveNodeBinary.d.ts +6 -1
  26. package/lib/internal/resolveNodeBinary.js +6 -2
  27. package/lib/internal/resolveNodeBinary.js.map +1 -1
  28. package/lib/internal/runtimeExecutableIdentity.d.ts +22 -13
  29. package/lib/internal/runtimeExecutableIdentity.js +192 -102
  30. package/lib/internal/runtimeExecutableIdentity.js.map +1 -1
  31. package/lib/launcher/internal/runtime/installRuntimeHooks.js +58 -4
  32. package/lib/launcher/internal/runtime/installRuntimeHooks.js.map +1 -1
  33. package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.d.ts +5 -1
  34. package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js +7 -2
  35. package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js.map +1 -1
  36. package/lib/launcher/internal/ttscserver/runTtscserver.js +8 -1
  37. package/lib/launcher/internal/ttscserver/runTtscserver.js.map +1 -1
  38. package/lib/plugin/internal/CapabilityResolutionFormat.d.ts +21 -62
  39. package/lib/plugin/internal/CapabilityResolutionFormat.js +15 -106
  40. package/lib/plugin/internal/CapabilityResolutionFormat.js.map +1 -1
  41. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.d.ts +6 -0
  42. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js +4 -4
  43. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js.map +1 -1
  44. package/lib/plugin/internal/load/loadProjectPlugins.d.ts +24 -14
  45. package/lib/plugin/internal/load/loadProjectPlugins.js +141 -56
  46. package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
  47. package/lib/plugin/internal/readCapabilityResolution.d.ts +6 -0
  48. package/lib/plugin/internal/readCapabilityResolution.js +8 -5
  49. package/lib/plugin/internal/readCapabilityResolution.js.map +1 -1
  50. package/lib/plugin/internal/source/GoEnvironmentReading.d.ts +48 -0
  51. package/lib/plugin/internal/source/GoEnvironmentReading.js +156 -0
  52. package/lib/plugin/internal/source/GoEnvironmentReading.js.map +1 -0
  53. package/lib/plugin/internal/source/NativeSourcePackages.d.ts +51 -13
  54. package/lib/plugin/internal/source/NativeSourcePackages.js +182 -27
  55. package/lib/plugin/internal/source/NativeSourcePackages.js.map +1 -1
  56. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.d.ts +42 -3
  57. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js +68 -7
  58. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js.map +1 -1
  59. package/lib/plugin/internal/source/PluginBuildEnvironmentWitness.d.ts +5 -3
  60. package/lib/plugin/internal/source/PluginBuildEnvironmentWitness.js +14 -8
  61. package/lib/plugin/internal/source/PluginBuildEnvironmentWitness.js.map +1 -1
  62. package/lib/plugin/internal/source/PluginContentIdentities.d.ts +265 -0
  63. package/lib/plugin/internal/source/PluginContentIdentities.js +452 -0
  64. package/lib/plugin/internal/source/PluginContentIdentities.js.map +1 -0
  65. package/lib/plugin/internal/source/PluginLoadAnswers.d.ts +63 -0
  66. package/lib/plugin/internal/source/PluginLoadAnswers.js +128 -0
  67. package/lib/plugin/internal/source/PluginLoadAnswers.js.map +1 -0
  68. package/lib/plugin/internal/source/SourceBuildCacheLayout.d.ts +10 -0
  69. package/lib/plugin/internal/source/SourceBuildCacheLayout.js +12 -0
  70. package/lib/plugin/internal/source/SourceBuildCacheLayout.js.map +1 -1
  71. package/lib/plugin/internal/source/SourcePluginWorkspace.d.ts +53 -19
  72. package/lib/plugin/internal/source/SourcePluginWorkspace.js +111 -22
  73. package/lib/plugin/internal/source/SourcePluginWorkspace.js.map +1 -1
  74. package/lib/plugin/internal/source/buildSourcePlugin.d.ts +34 -18
  75. package/lib/plugin/internal/source/buildSourcePlugin.js +52 -24
  76. package/lib/plugin/internal/source/buildSourcePlugin.js.map +1 -1
  77. package/lib/plugin/internal/source/computeCacheKey.d.ts +25 -7
  78. package/lib/plugin/internal/source/computeCacheKey.js +85 -34
  79. package/lib/plugin/internal/source/computeCacheKey.js.map +1 -1
  80. package/lib/plugin/internal/source/hashPluginBuildEnvironment.d.ts +7 -3
  81. package/lib/plugin/internal/source/hashPluginBuildEnvironment.js +75 -102
  82. package/lib/plugin/internal/source/hashPluginBuildEnvironment.js.map +1 -1
  83. package/lib/plugin/internal/source/pluginBuildEnvironment.d.ts +8 -3
  84. package/lib/plugin/internal/source/pluginBuildEnvironment.js +8 -4
  85. package/lib/plugin/internal/source/pluginBuildEnvironment.js.map +1 -1
  86. package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js +12 -2
  87. package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js.map +1 -1
  88. package/lib/plugin/internal/source/pluginBuildVersions.d.ts +2 -2
  89. package/lib/plugin/internal/source/pluginBuildVersions.js +4 -17
  90. package/lib/plugin/internal/source/pluginBuildVersions.js.map +1 -1
  91. package/lib/plugin/internal/source/pluginModuleReplaceDirectories.d.ts +6 -5
  92. package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js +10 -17
  93. package/lib/plugin/internal/source/pluginModuleReplaceDirectories.js.map +1 -1
  94. package/lib/plugin/internal/source/pluginSourceState.d.ts +6 -2
  95. package/lib/plugin/internal/source/pluginSourceState.js +20 -8
  96. package/lib/plugin/internal/source/pluginSourceState.js.map +1 -1
  97. package/lib/plugin/internal/source/pluginSourceStateHolds.d.ts +7 -2
  98. package/lib/plugin/internal/source/pluginSourceStateHolds.js +12 -7
  99. package/lib/plugin/internal/source/pluginSourceStateHolds.js.map +1 -1
  100. package/lib/plugin/internal/source/processPluginBuildEnvironment.d.ts +7 -2
  101. package/lib/plugin/internal/source/processPluginBuildEnvironment.js +8 -3
  102. package/lib/plugin/internal/source/processPluginBuildEnvironment.js.map +1 -1
  103. package/lib/plugin/internal/source/provenPluginSourceDigest.d.ts +28 -0
  104. package/lib/plugin/internal/source/provenPluginSourceDigest.js +41 -0
  105. package/lib/plugin/internal/source/provenPluginSourceDigest.js.map +1 -0
  106. package/lib/plugin/internal/source/pruneCacheFileRoot.d.ts +3 -2
  107. package/lib/plugin/internal/source/pruneCacheFileRoot.js +3 -2
  108. package/lib/plugin/internal/source/pruneCacheFileRoot.js.map +1 -1
  109. package/lib/plugin/internal/source/ttscPackageVersion.d.ts +26 -0
  110. package/lib/plugin/internal/source/ttscPackageVersion.js +47 -0
  111. package/lib/plugin/internal/source/ttscPackageVersion.js.map +1 -0
  112. package/lib/plugin/internal/writeCapabilityResolution.d.ts +6 -0
  113. package/lib/plugin/internal/writeCapabilityResolution.js +11 -7
  114. package/lib/plugin/internal/writeCapabilityResolution.js.map +1 -1
  115. package/lib/plugin/resolveCapabilityPlugins.js +67 -15
  116. package/lib/plugin/resolveCapabilityPlugins.js.map +1 -1
  117. package/package.json +8 -8
  118. package/src/compiler/internal/build/BuildExecution.ts +46 -13
  119. package/src/compiler/internal/startResidentTransform.ts +12 -3
  120. package/src/compiler/internal/transformProjectInMemory.ts +10 -2
  121. package/src/internal/javascriptRuntimeCapabilities.ts +71 -5
  122. package/src/internal/nativeBinary.ts +3 -3
  123. package/src/internal/pluginSource.ts +1 -0
  124. package/src/internal/resolveNodeBinary.ts +12 -1
  125. package/src/internal/runtimeExecutableIdentity.ts +227 -141
  126. package/src/launcher/internal/runtime/installRuntimeHooks.ts +68 -3
  127. package/src/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.ts +11 -2
  128. package/src/launcher/internal/ttscserver/runTtscserver.ts +18 -1
  129. package/src/plugin/internal/CapabilityResolutionFormat.ts +23 -107
  130. package/src/plugin/internal/load/PluginDescriptorEvaluationCache.ts +14 -4
  131. package/src/plugin/internal/load/loadProjectPlugins.ts +421 -211
  132. package/src/plugin/internal/readCapabilityResolution.ts +17 -6
  133. package/src/plugin/internal/source/GoEnvironmentReading.ts +178 -0
  134. package/src/plugin/internal/source/NativeSourcePackages.ts +365 -48
  135. package/src/plugin/internal/source/PluginBuildEnvironmentReadings.ts +83 -5
  136. package/src/plugin/internal/source/PluginBuildEnvironmentWitness.ts +18 -8
  137. package/src/plugin/internal/source/PluginContentIdentities.ts +563 -0
  138. package/src/plugin/internal/source/PluginLoadAnswers.ts +151 -0
  139. package/src/plugin/internal/source/SourceBuildCacheLayout.ts +14 -0
  140. package/src/plugin/internal/source/SourcePluginWorkspace.ts +148 -25
  141. package/src/plugin/internal/source/buildSourcePlugin.ts +104 -36
  142. package/src/plugin/internal/source/computeCacheKey.ts +129 -55
  143. package/src/plugin/internal/source/hashPluginBuildEnvironment.ts +152 -105
  144. package/src/plugin/internal/source/pluginBuildEnvironment.ts +9 -2
  145. package/src/plugin/internal/source/pluginBuildEnvironmentWorker.ts +18 -2
  146. package/src/plugin/internal/source/pluginBuildVersions.ts +5 -26
  147. package/src/plugin/internal/source/pluginModuleReplaceDirectories.ts +13 -25
  148. package/src/plugin/internal/source/pluginSourceState.ts +28 -12
  149. package/src/plugin/internal/source/pluginSourceStateHolds.ts +15 -8
  150. package/src/plugin/internal/source/processPluginBuildEnvironment.ts +8 -2
  151. package/src/plugin/internal/source/provenPluginSourceDigest.ts +45 -0
  152. package/src/plugin/internal/source/pruneCacheFileRoot.ts +3 -2
  153. package/src/plugin/internal/source/ttscPackageVersion.ts +45 -0
  154. package/src/plugin/internal/writeCapabilityResolution.ts +29 -8
  155. package/src/plugin/resolveCapabilityPlugins.ts +87 -13
@@ -1,27 +1,29 @@
1
1
  import crypto from "node:crypto";
2
- import fs from "node:fs";
3
2
  import path from "node:path";
4
3
 
5
4
  import { SidecarEnvironment } from "../../compiler/internal/sharedHost/SidecarEnvironment";
6
5
  import { runtimeExecutableIdentity } from "../../internal/runtimeExecutableIdentity";
6
+ import type { PluginContentIdentities } from "./source/PluginContentIdentities";
7
7
  import { SourceBuildCacheLayout } from "./source/SourceBuildCacheLayout";
8
8
  import { resolveSourceBuildCachePaths } from "./source/resolveSourceBuildCachePaths";
9
9
 
10
10
  /**
11
11
  * The on-disk format of the capability-resolution cache, shared by its reader
12
- * and writer so both agree on the entry's location, version tag, and how a
13
- * plugin source's metadata signature is taken. What proves an entry still
14
- * describes the project is the host inputs' states and the plugin sources'
15
- * states, each by the rule its producer applies.
12
+ * and writer so both agree on the entry's location and version tag. What proves
13
+ * an entry still describes the project is the host inputs' states and the
14
+ * plugin sources' states, each by the rule its producer applies; a plugin
15
+ * source's metadata signature and the clock reference it is judged against
16
+ * belong to `PluginContentIdentities`, which every cross-process plugin proof
17
+ * shares.
16
18
  *
17
- * @evidence contracts/common.md#principled-implementation Reader and writer share format/key and source-metadata witness rules. Metadata acceleration requires a matching device and older reported mtime, relying on native metadata/clock semantics rather than certifying arbitrary timestamp restoration or content mutation.
18
- * @evidence contracts/common.md#clear-and-simple-design The namespace owns format identity and witness construction, while entry acceptance and answer production stay with their reader/writer.
19
- * @evidence contracts/common.md#prohibited-implementation-shortcuts Version tags and NUL delimiters encode the persistence contract; unavailable clock/device evidence causes full content proof rather than guessed reuse.
20
- * @evidence contracts/common.md#meaningful-documentation Native JSDoc explains format evolution, unforgeable path separation and clock proof premises in separate paragraphs; function/tag spacing follows the documentation skill.
21
- * @evidence contracts/portability.md#os-neutral-implementation Native path joins, cache-root resolution and bigint stat device identities preserve OS-neutral filesystem behavior; clock witnesses are matched per device rather than assumed from platform names.
22
- * @evidence contracts/performance.md#efficient-algorithms Key construction orders and serializes environment/name bytes, streams runtime content and delegates native ancestor/manifest/cache-layout selection. Clock witnesses create/query/remove a probe, and each source witness queries native metadata and formats numeric text; path/native/text costs remain distinct from source-content proof owned by the reader.
23
- * @evidence contracts/performance.md#reuse-equivalent-work Project/version keys share one answer across requested capabilities; digest reuse additionally requires matching signature and device-clock separation.
24
- * @evidence contracts/performance.md#bound-retention-and-release-resources Clock probes are call-owned and removed in finally; cache entries belong to the source-cache pruning owner rather than a process-global answer collection. Failed probe removal can leave a small file and is best effort.
19
+ * @evidence contracts/common.md#principled-implementation Reader and writer share format/key rules; source-metadata witnesses come from the shared identity owner, so this cache and the build path apply one separable-stamp rule.
20
+ * @evidence contracts/common.md#clear-and-simple-design The namespace owns format identity and entry location, while entry acceptance, answer production and metadata witnesses stay with their owners.
21
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts Version tags and NUL delimiters encode the persistence contract rather than guessed reuse.
22
+ * @evidence contracts/common.md#meaningful-documentation Native JSDoc explains format evolution, unforgeable path separation and the witness owner in separate paragraphs; function/tag spacing follows the documentation skill.
23
+ * @evidence contracts/portability.md#os-neutral-implementation Native path joins and cache-root resolution preserve OS-neutral filesystem behavior.
24
+ * @evidence contracts/performance.md#efficient-algorithms Key construction orders and serializes environment/name bytes, streams runtime content and delegates native ancestor/manifest/cache-layout selection.
25
+ * @evidence contracts/performance.md#reuse-equivalent-work Project/version keys share one answer across requested capabilities.
26
+ * @evidenceExclude contracts/performance.md#bound-retention-and-release-resources Cache entries belong to the source-cache pruning owner; this namespace retains nothing.
25
27
  */
26
28
  export namespace CapabilityResolutionFormat {
27
29
  /**
@@ -106,6 +108,13 @@ export namespace CapabilityResolutionFormat {
106
108
 
107
109
  /** Effective environment selecting workspace-local or explicit storage. */
108
110
  env?: NodeJS.ProcessEnv;
111
+
112
+ /**
113
+ * Record store of the project's plugin cache. WARNING (#1725): without it
114
+ * every lookup streamed the whole runtime executable, several times per
115
+ * capability resolution, in every process.
116
+ */
117
+ identities?: PluginContentIdentities.Store;
109
118
  }): string | null {
110
119
  const environment = SidecarEnvironment.merge(options.env ?? process.env);
111
120
  const runtime =
@@ -115,7 +124,7 @@ export namespace CapabilityResolutionFormat {
115
124
  let root: string;
116
125
  let runtimeIdentity: string;
117
126
  try {
118
- const observed = runtimeExecutableIdentity(runtime);
127
+ const observed = runtimeExecutableIdentity(runtime, options.identities);
119
128
  if (observed === undefined) return null;
120
129
  runtimeIdentity = observed;
121
130
  root = resolveSourceBuildCachePaths(
@@ -152,97 +161,4 @@ export namespace CapabilityResolutionFormat {
152
161
  `${key}.json`,
153
162
  );
154
163
  }
155
-
156
- /**
157
- * A clock reference for plugin source signatures, minted by a write of the
158
- * cache's own beside the entry: the modification stamp a fresh probe file got
159
- * there, by the device that reported it.
160
- *
161
- * A stamp strictly older than the same device's fresh reference satisfies
162
- * this cache's separation policy. Reuse still assumes the filesystem's
163
- * reported metadata reflects writes; the comparison cannot certify arbitrary
164
- * timestamp restoration or future clock behavior. The probe is the cache's
165
- * own file, named for this call, and removal is attempted at once, so
166
- * concurrent readers never lend each other a reference. A failed write, or a
167
- * plugin source on another device, leaves nothing separable, and the proof
168
- * reads the files.
169
- *
170
- * @param entry The entry file, whose directory the probe is written in.
171
- * @evidence contracts/common.md#principled-implementation A unique freshly-written file supplies its native device/mtime reference; acquisition failure clears the witness, and the source observer requires a matching device and strictly older reported stamp under the metadata policy.
172
- * @evidence contracts/common.md#clear-and-simple-design The function returns only device-to-stamp evidence and owns its transient probe from creation through cleanup.
173
- * @evidence contracts/common.md#prohibited-implementation-shortcuts Random probe identity avoids borrowing a concurrent call's witness; failed acquisition does not substitute wall-clock guesses for device evidence.
174
- * @evidence contracts/common.md#meaningful-documentation Native JSDoc explains ended ticks, cross-device refusal and probe lifetime in separate paragraphs; tag separation follows the documentation skill.
175
- * @evidence contracts/portability.md#os-neutral-implementation Native joins and bigint lstat use the actual filesystem's device/stamp values; no fixed timestamp precision or OS-specific temp path is assumed.
176
- * @evidence contracts/performance.md#efficient-algorithms Probe path/UUID/hrtime text construction and mkdir/write/lstat/removal queries produce a witness without reading plugin source bytes; native path/directory work remains and is not bounded by source count.
177
- *
178
- * @evidenceExclude contracts/performance.md#reuse-equivalent-work Each proof needs a fresh clock reference; sharing an earlier probe would defeat the rollback/separation premise.
179
- *
180
- * @evidence contracts/performance.md#bound-retention-and-release-resources The unique call-owned probe is removed in finally even after acquisition failure; removal is best effort and the returned map contains at most its single observed device.
181
- */
182
- export function clockReference(entry: string): ReadonlyMap<bigint, bigint> {
183
- const references = new Map<bigint, bigint>();
184
- const probe = path.join(
185
- path.dirname(entry),
186
- `clock-${process.pid}-${crypto.randomUUID()}.probe`,
187
- );
188
- try {
189
- fs.mkdirSync(path.dirname(probe), { recursive: true });
190
- fs.writeFileSync(probe, `${process.hrtime.bigint()}\n`);
191
- const stats = fs.lstatSync(probe, { bigint: true });
192
- references.set(stats.dev, stats.mtimeNs);
193
- } catch {
194
- references.clear();
195
- } finally {
196
- try {
197
- fs.rmSync(probe, { force: true });
198
- } catch {
199
- // A leftover probe contains this call's hrtime text, not source data.
200
- }
201
- }
202
- return references;
203
- }
204
-
205
- /**
206
- * One plugin source file's metadata signature, and whether its stamp is
207
- * separable from `reference`, for `pluginSourceFilesSignature`.
208
- *
209
- * The files the digest reads are regular files (`collectPluginSourceFiles`),
210
- * so these fields are the observer's metadata signature. Native metadata
211
- * reflecting a write/replacement is a reuse premise; the signature is not
212
- * itself a content hash or proof against arbitrary timestamp restoration.
213
- *
214
- * @param reference The clock reference minted for this proof.
215
- * @evidence contracts/common.md#principled-implementation lstat device/inode/link/mode/size/timestamps form the regular-file metadata signature; strict mtime-before-reference marks separation for a matching device under the cache's native metadata policy, without observing content.
216
- * @evidence contracts/common.md#clear-and-simple-design A closure carries one proof's device references and maps each requested file to signature/separation together.
217
- * @evidence contracts/common.md#prohibited-implementation-shortcuts Unreadable files return no witness, and unmatched device or same/newer stamps cannot authorize digest reuse.
218
- * @evidence contracts/common.md#meaningful-documentation Native JSDoc states the regular-file premise and reference origin, with separate acknowledgment prose following the documentation skill.
219
- * @evidence contracts/portability.md#os-neutral-implementation Metadata comes from native bigint lstat and actual device IDs; separators join numeric fields only and no host path is manually parsed.
220
- * @evidence contracts/performance.md#efficient-algorithms Each invocation performs native path/lstat work and formats seven bigint fields without reading content; fixed field count does not remove native lookup or numeric-text costs.
221
- * @evidence contracts/performance.md#reuse-equivalent-work The closure reuses one reference map across files in the same proof, while each file's current metadata is read anew.
222
- * @evidence contracts/performance.md#bound-retention-and-release-resources The closure retains the supplied reference map until its consumer releases it; clockReference supplies at most one entry, but arbitrary callers can supply larger or mutable maps. No file handle/global source population is retained and reference immutability is a caller premise.
223
- */
224
- export function sourceEvidence(
225
- reference: ReadonlyMap<bigint, bigint>,
226
- ): (file: string) => { separable: boolean; signature: string } | undefined {
227
- return (file) => {
228
- try {
229
- const stats = fs.lstatSync(file, { bigint: true });
230
- const minted = reference.get(stats.dev);
231
- return {
232
- separable: minted !== undefined && stats.mtimeNs < minted,
233
- signature: [
234
- stats.dev,
235
- stats.ino,
236
- stats.nlink,
237
- stats.mode,
238
- stats.size,
239
- stats.mtimeNs,
240
- stats.ctimeNs,
241
- ].join(":"),
242
- };
243
- } catch {
244
- return undefined;
245
- }
246
- };
247
- }
248
164
  }
@@ -4,6 +4,7 @@ import path from "node:path";
4
4
 
5
5
  import { SidecarEnvironment } from "../../../compiler/internal/sharedHost/SidecarEnvironment";
6
6
  import { runtimeExecutableIdentity } from "../../../internal/runtimeExecutableIdentity";
7
+ import type { PluginContentIdentities } from "../source/PluginContentIdentities";
7
8
  import { SourceBuildCacheLayout } from "../source/SourceBuildCacheLayout";
8
9
  import { recordCacheFileUse } from "../source/recordCacheFileUse";
9
10
  import { resolveSourceBuildCachePaths } from "../source/resolveSourceBuildCachePaths";
@@ -127,20 +128,26 @@ export namespace PluginDescriptorEvaluationCache {
127
128
 
128
129
  /** Ttsc build version, invalidating answers from another build. */
129
130
  version: string;
131
+
132
+ /**
133
+ * Record store proving the runtimes' bytes from metadata (#1723); without
134
+ * it each runtime is streamed again.
135
+ */
136
+ identities?: PluginContentIdentities.Store;
130
137
  }): string | null {
131
138
  const environment = SidecarEnvironment.merge(props.env);
132
139
  // Startup preloads can run before the descriptor recorder and read inputs
133
140
  // it never sees; a stable option string cannot prove their current meaning.
134
141
  if (SidecarEnvironment.read(environment, "NODE_OPTIONS")?.trim())
135
142
  return null;
136
- const runtime = runtimeIdentity(props.runtime);
143
+ const runtime = runtimeIdentity(props.runtime, props.identities);
137
144
  if (runtime === null) return null;
138
145
  const additionalRuntime =
139
146
  props.additionalRuntime === undefined
140
147
  ? undefined
141
148
  : props.additionalRuntime === props.runtime
142
149
  ? runtime
143
- : runtimeIdentity(props.additionalRuntime);
150
+ : runtimeIdentity(props.additionalRuntime, props.identities);
144
151
  if (additionalRuntime === null) return null;
145
152
  let root: string;
146
153
  try {
@@ -358,8 +365,11 @@ export namespace PluginDescriptorEvaluationCache {
358
365
  * content digest and bracketed lexical/physical metadata, so replaced bytes
359
366
  * cannot reuse an evaluation by restoring size/timestamps. Null is unproved.
360
367
  */
361
- function runtimeIdentity(runtime: string): string | null {
362
- return runtimeExecutableIdentity(runtime) ?? null;
368
+ function runtimeIdentity(
369
+ runtime: string,
370
+ identities: PluginContentIdentities.Store | undefined,
371
+ ): string | null {
372
+ return runtimeExecutableIdentity(runtime, identities) ?? null;
363
373
  }
364
374
 
365
375
  /**