ttsc 0.31.1 → 0.31.3

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 (146) hide show
  1. package/lib/compiler/internal/build/BuildExecution.d.ts +6 -3
  2. package/lib/compiler/internal/build/BuildExecution.js +40 -12
  3. package/lib/compiler/internal/build/BuildExecution.js.map +1 -1
  4. package/lib/compiler/internal/build/RunBuildOptions.d.ts +2 -1
  5. package/lib/compiler/internal/startResidentTransform.js +5 -4
  6. package/lib/compiler/internal/startResidentTransform.js.map +1 -1
  7. package/lib/compiler/internal/transformProjectInMemory.js +9 -7
  8. package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
  9. package/lib/internal/javascriptRuntimeCapabilities.d.ts +13 -4
  10. package/lib/internal/javascriptRuntimeCapabilities.js +56 -6
  11. package/lib/internal/javascriptRuntimeCapabilities.js.map +1 -1
  12. package/lib/internal/pluginSource.d.ts +1 -0
  13. package/lib/internal/pluginSource.js +1 -0
  14. package/lib/internal/pluginSource.js.map +1 -1
  15. package/lib/internal/resolveNodeBinary.d.ts +6 -1
  16. package/lib/internal/resolveNodeBinary.js +6 -2
  17. package/lib/internal/resolveNodeBinary.js.map +1 -1
  18. package/lib/internal/runtimeExecutableIdentity.d.ts +22 -13
  19. package/lib/internal/runtimeExecutableIdentity.js +192 -102
  20. package/lib/internal/runtimeExecutableIdentity.js.map +1 -1
  21. package/lib/launcher/internal/runTtsc.js +2 -2
  22. package/lib/launcher/internal/runTtsc.js.map +1 -1
  23. package/lib/launcher/internal/runtime/installRuntimeHooks.js +58 -4
  24. package/lib/launcher/internal/runtime/installRuntimeHooks.js.map +1 -1
  25. package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.d.ts +5 -1
  26. package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js +7 -2
  27. package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js.map +1 -1
  28. package/lib/launcher/internal/ttscserver/runTtscserver.js +8 -1
  29. package/lib/launcher/internal/ttscserver/runTtscserver.js.map +1 -1
  30. package/lib/launcher/internal/watch/WatchTopology.d.ts +20 -3
  31. package/lib/launcher/internal/watch/WatchTopology.js +31 -9
  32. package/lib/launcher/internal/watch/WatchTopology.js.map +1 -1
  33. package/lib/plugin/internal/CapabilityResolutionFormat.d.ts +21 -62
  34. package/lib/plugin/internal/CapabilityResolutionFormat.js +15 -106
  35. package/lib/plugin/internal/CapabilityResolutionFormat.js.map +1 -1
  36. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.d.ts +6 -0
  37. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js +4 -4
  38. package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js.map +1 -1
  39. package/lib/plugin/internal/load/loadProjectPlugins.d.ts +17 -3
  40. package/lib/plugin/internal/load/loadProjectPlugins.js +86 -23
  41. package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
  42. package/lib/plugin/internal/readCapabilityResolution.d.ts +6 -0
  43. package/lib/plugin/internal/readCapabilityResolution.js +8 -5
  44. package/lib/plugin/internal/readCapabilityResolution.js.map +1 -1
  45. package/lib/plugin/internal/source/GoEnvironmentReading.d.ts +9 -3
  46. package/lib/plugin/internal/source/GoEnvironmentReading.js +53 -7
  47. package/lib/plugin/internal/source/GoEnvironmentReading.js.map +1 -1
  48. package/lib/plugin/internal/source/NativeSourcePackages.d.ts +44 -6
  49. package/lib/plugin/internal/source/NativeSourcePackages.js +150 -8
  50. package/lib/plugin/internal/source/NativeSourcePackages.js.map +1 -1
  51. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.d.ts +21 -3
  52. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js +32 -7
  53. package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js.map +1 -1
  54. package/lib/plugin/internal/source/PluginContentIdentities.d.ts +265 -0
  55. package/lib/plugin/internal/source/PluginContentIdentities.js +452 -0
  56. package/lib/plugin/internal/source/PluginContentIdentities.js.map +1 -0
  57. package/lib/plugin/internal/source/PluginLoadAnswers.d.ts +63 -0
  58. package/lib/plugin/internal/source/PluginLoadAnswers.js +128 -0
  59. package/lib/plugin/internal/source/PluginLoadAnswers.js.map +1 -0
  60. package/lib/plugin/internal/source/SourceBuildCacheLayout.d.ts +10 -0
  61. package/lib/plugin/internal/source/SourceBuildCacheLayout.js +12 -0
  62. package/lib/plugin/internal/source/SourceBuildCacheLayout.js.map +1 -1
  63. package/lib/plugin/internal/source/SourcePluginWorkspace.d.ts +13 -2
  64. package/lib/plugin/internal/source/SourcePluginWorkspace.js +140 -4
  65. package/lib/plugin/internal/source/SourcePluginWorkspace.js.map +1 -1
  66. package/lib/plugin/internal/source/buildSourcePlugin.d.ts +15 -2
  67. package/lib/plugin/internal/source/buildSourcePlugin.js +27 -4
  68. package/lib/plugin/internal/source/buildSourcePlugin.js.map +1 -1
  69. package/lib/plugin/internal/source/computeCacheKey.d.ts +21 -5
  70. package/lib/plugin/internal/source/computeCacheKey.js +71 -29
  71. package/lib/plugin/internal/source/computeCacheKey.js.map +1 -1
  72. package/lib/plugin/internal/source/hashPluginBuildEnvironment.d.ts +7 -3
  73. package/lib/plugin/internal/source/hashPluginBuildEnvironment.js +74 -35
  74. package/lib/plugin/internal/source/hashPluginBuildEnvironment.js.map +1 -1
  75. package/lib/plugin/internal/source/pluginBuildEnvironment.d.ts +8 -3
  76. package/lib/plugin/internal/source/pluginBuildEnvironment.js +8 -4
  77. package/lib/plugin/internal/source/pluginBuildEnvironment.js.map +1 -1
  78. package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js +12 -2
  79. package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js.map +1 -1
  80. package/lib/plugin/internal/source/pluginBuildVersions.d.ts +2 -2
  81. package/lib/plugin/internal/source/pluginBuildVersions.js +4 -17
  82. package/lib/plugin/internal/source/pluginBuildVersions.js.map +1 -1
  83. package/lib/plugin/internal/source/pluginSourceState.d.ts +6 -2
  84. package/lib/plugin/internal/source/pluginSourceState.js +20 -8
  85. package/lib/plugin/internal/source/pluginSourceState.js.map +1 -1
  86. package/lib/plugin/internal/source/pluginSourceStateHolds.d.ts +7 -2
  87. package/lib/plugin/internal/source/pluginSourceStateHolds.js +12 -7
  88. package/lib/plugin/internal/source/pluginSourceStateHolds.js.map +1 -1
  89. package/lib/plugin/internal/source/processPluginBuildEnvironment.d.ts +7 -2
  90. package/lib/plugin/internal/source/processPluginBuildEnvironment.js +8 -3
  91. package/lib/plugin/internal/source/processPluginBuildEnvironment.js.map +1 -1
  92. package/lib/plugin/internal/source/provenPluginSourceDigest.d.ts +28 -0
  93. package/lib/plugin/internal/source/provenPluginSourceDigest.js +41 -0
  94. package/lib/plugin/internal/source/provenPluginSourceDigest.js.map +1 -0
  95. package/lib/plugin/internal/source/pruneCacheFileRoot.d.ts +3 -2
  96. package/lib/plugin/internal/source/pruneCacheFileRoot.js +3 -2
  97. package/lib/plugin/internal/source/pruneCacheFileRoot.js.map +1 -1
  98. package/lib/plugin/internal/source/ttscPackageVersion.d.ts +26 -0
  99. package/lib/plugin/internal/source/ttscPackageVersion.js +47 -0
  100. package/lib/plugin/internal/source/ttscPackageVersion.js.map +1 -0
  101. package/lib/plugin/internal/writeCapabilityResolution.d.ts +6 -0
  102. package/lib/plugin/internal/writeCapabilityResolution.js +11 -7
  103. package/lib/plugin/internal/writeCapabilityResolution.js.map +1 -1
  104. package/lib/plugin/resolveCapabilityPlugins.js +67 -15
  105. package/lib/plugin/resolveCapabilityPlugins.js.map +1 -1
  106. package/lib/structures/internal/TtscSingleFileEmitOptions.d.ts +5 -1
  107. package/package.json +8 -8
  108. package/src/compiler/internal/build/BuildExecution.ts +48 -14
  109. package/src/compiler/internal/build/RunBuildOptions.ts +2 -1
  110. package/src/compiler/internal/startResidentTransform.ts +12 -3
  111. package/src/compiler/internal/transformProjectInMemory.ts +10 -2
  112. package/src/internal/javascriptRuntimeCapabilities.ts +71 -5
  113. package/src/internal/pluginSource.ts +1 -0
  114. package/src/internal/resolveNodeBinary.ts +12 -1
  115. package/src/internal/runtimeExecutableIdentity.ts +227 -141
  116. package/src/launcher/internal/runTtsc.ts +6 -2
  117. package/src/launcher/internal/runtime/installRuntimeHooks.ts +68 -3
  118. package/src/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.ts +11 -2
  119. package/src/launcher/internal/ttscserver/runTtscserver.ts +18 -1
  120. package/src/launcher/internal/watch/WatchTopology.ts +38 -9
  121. package/src/plugin/internal/CapabilityResolutionFormat.ts +23 -107
  122. package/src/plugin/internal/load/PluginDescriptorEvaluationCache.ts +14 -4
  123. package/src/plugin/internal/load/loadProjectPlugins.ts +226 -98
  124. package/src/plugin/internal/readCapabilityResolution.ts +17 -6
  125. package/src/plugin/internal/source/GoEnvironmentReading.ts +74 -5
  126. package/src/plugin/internal/source/NativeSourcePackages.ts +262 -5
  127. package/src/plugin/internal/source/PluginBuildEnvironmentReadings.ts +41 -5
  128. package/src/plugin/internal/source/PluginContentIdentities.ts +563 -0
  129. package/src/plugin/internal/source/PluginLoadAnswers.ts +151 -0
  130. package/src/plugin/internal/source/SourceBuildCacheLayout.ts +14 -0
  131. package/src/plugin/internal/source/SourcePluginWorkspace.ts +176 -2
  132. package/src/plugin/internal/source/buildSourcePlugin.ts +43 -3
  133. package/src/plugin/internal/source/computeCacheKey.ts +103 -47
  134. package/src/plugin/internal/source/hashPluginBuildEnvironment.ts +144 -29
  135. package/src/plugin/internal/source/pluginBuildEnvironment.ts +9 -2
  136. package/src/plugin/internal/source/pluginBuildEnvironmentWorker.ts +18 -2
  137. package/src/plugin/internal/source/pluginBuildVersions.ts +5 -26
  138. package/src/plugin/internal/source/pluginSourceState.ts +28 -12
  139. package/src/plugin/internal/source/pluginSourceStateHolds.ts +15 -8
  140. package/src/plugin/internal/source/processPluginBuildEnvironment.ts +8 -2
  141. package/src/plugin/internal/source/provenPluginSourceDigest.ts +45 -0
  142. package/src/plugin/internal/source/pruneCacheFileRoot.ts +3 -2
  143. package/src/plugin/internal/source/ttscPackageVersion.ts +45 -0
  144. package/src/plugin/internal/writeCapabilityResolution.ts +29 -8
  145. package/src/plugin/resolveCapabilityPlugins.ts +87 -13
  146. package/src/structures/internal/TtscSingleFileEmitOptions.ts +8 -1
@@ -5,9 +5,11 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.readCapabilityResolution = readCapabilityResolution;
7
7
  const node_fs_1 = __importDefault(require("node:fs"));
8
+ const node_path_1 = __importDefault(require("node:path"));
8
9
  const CapabilityResolutionFormat_1 = require("./CapabilityResolutionFormat");
9
10
  const hashHostInputPaths_1 = require("./load/hashHostInputPaths");
10
11
  const realpathHostInputPaths_1 = require("./load/realpathHostInputPaths");
12
+ const PluginContentIdentities_1 = require("./source/PluginContentIdentities");
11
13
  const pluginSourceFilesSignature_1 = require("./source/pluginSourceFilesSignature");
12
14
  const pluginSourceStateHolds_1 = require("./source/pluginSourceStateHolds");
13
15
  const recordCacheFileUse_1 = require("./source/recordCacheFileUse");
@@ -70,10 +72,11 @@ function readCapabilityResolution(options) {
70
72
  // old one still exists.
71
73
  const sources = Object.entries(entry.pluginSources);
72
74
  const evidence = sources.some(([, source]) => source.signature !== undefined)
73
- ? CapabilityResolutionFormat_1.CapabilityResolutionFormat.sourceEvidence(CapabilityResolutionFormat_1.CapabilityResolutionFormat.clockReference(file))
75
+ ? PluginContentIdentities_1.PluginContentIdentities.sourceEvidence(PluginContentIdentities_1.PluginContentIdentities.mintReference(node_path_1.default.dirname(file)))
74
76
  : undefined;
77
+ const projectRoot = node_path_1.default.resolve(options.cwd);
75
78
  for (const [directory, source] of sources)
76
- if (!pluginSourceProven(directory, source, evidence))
79
+ if (!pluginSourceProven(directory, source, evidence, projectRoot))
77
80
  return null;
78
81
  for (const plugin of entry.plugins)
79
82
  if (!node_fs_1.default.existsSync(plugin.binary))
@@ -90,7 +93,7 @@ function readCapabilityResolution(options) {
90
93
  * tick, which only a fresh reference rules out. The build environment is proven
91
94
  * either way.
92
95
  */
93
- function pluginSourceProven(directory, source, evidence) {
96
+ function pluginSourceProven(directory, source, evidence, projectRoot) {
94
97
  try {
95
98
  const now = source.signature === undefined || evidence === undefined
96
99
  ? undefined
@@ -99,8 +102,8 @@ function pluginSourceProven(directory, source, evidence) {
99
102
  now.separable &&
100
103
  now.signature === source.signature &&
101
104
  source.digest !== undefined
102
- ? { sourceDigest: source.digest }
103
- : {});
105
+ ? { projectRoot, sourceDigest: source.digest }
106
+ : { projectRoot });
104
107
  }
105
108
  catch {
106
109
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"readCapabilityResolution.js","sourceRoot":"","sources":["../../../src/plugin/internal/readCapabilityResolution.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"readCapabilityResolution.js","sourceRoot":"","sources":["../../../src/plugin/internal/readCapabilityResolution.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { PluginBuildEnvironmentWitness } from "./PluginBuildEnvironmentWitness";
2
+ import type { PluginContentIdentities } from "./PluginContentIdentities";
2
3
  /**
3
4
  * Acquire current Go values together with their environment-file evidence.
4
5
  * Build digests and syntax readers share this owner; a file-location hint is
@@ -27,6 +28,11 @@ export declare namespace GoEnvironmentReading {
27
28
  * one witnessed. A file that keeps moving between runs leaves the reading
28
29
  * unwitnessable, so a kept reading or a build keyed on it never holds.
29
30
  *
31
+ * The location hint also comes from the record store when one is supplied, so
32
+ * a new process witnesses the right file on its first run instead of running
33
+ * `go env` once only to learn the name.
34
+ *
35
+ * @param identities Optional record store carrying the hint across processes.
30
36
  * @returns The parsed object, or `undefined` when native acquisition or JSON
31
37
  * object decoding failed.
32
38
  * @evidence contracts/common.md#principled-implementation Actual Go supplies values and the environment-file path; pre-read metadata and bounded rediscovery preserve the earliest file witness instead of attaching a later state to an earlier read.
@@ -35,8 +41,8 @@ export declare namespace GoEnvironmentReading {
35
41
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain why file discovery can repeat and distinguish unavailable acquisition from current authority.
36
42
  * @evidence contracts/portability.md#os-neutral-implementation Go reports its actual environment-file location; native path metadata and the existing Go process owner supply observation and execution semantics.
37
43
  * @evidence contracts/performance.md#efficient-algorithms Hashing the complete tool/environment identity and up to three native Go queries process full name/value/output bytes. Requested keys contribute argument bytes; file discovery uses metadata rather than an SDK walk.
38
- * @evidence contracts/performance.md#reuse-equivalent-work Only file-location discovery hints are shared across equal selected-tool/environment identities. Current Go values and file authority are reacquired for every call.
39
- * @evidence contracts/performance.md#bound-retention-and-release-resources The module retains one file-location hint per historical tool/environment identity, without eviction, but no positive reading or native handle. Command capture/retirement belongs to spawnGoTool and the caller owns the transferred witness.
44
+ * @evidence contracts/performance.md#reuse-equivalent-work Only file-location discovery hints are shared: in process across equal selected-tool/environment identities, and through the record store across equal selected tools and location variables, since the reading verifies any hint against the file Go reports. Current Go values and file authority are reacquired for every call.
45
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The module retains one file-location hint per historical tool/environment identity, without eviction, but no positive reading or native handle; persisted hints belong to the single-file collector. Command capture/retirement belongs to spawnGoTool and the caller owns the transferred witness.
40
46
  */
41
- function read(goBinary: string, cwd: string, env: NodeJS.ProcessEnv, keys: readonly string[], witness: PluginBuildEnvironmentWitness.Record | undefined): Record<string, unknown> | undefined;
47
+ function read(goBinary: string, cwd: string, env: NodeJS.ProcessEnv, keys: readonly string[], witness: PluginBuildEnvironmentWitness.Record | undefined, identities?: PluginContentIdentities.Store): Record<string, unknown> | undefined;
42
48
  }
@@ -5,8 +5,10 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.GoEnvironmentReading = void 0;
7
7
  const node_crypto_1 = __importDefault(require("node:crypto"));
8
+ const SidecarEnvironment_1 = require("../../../compiler/internal/sharedHost/SidecarEnvironment");
8
9
  const GoSourceInputs_1 = require("./GoSourceInputs");
9
10
  const PluginBuildEnvironmentWitness_1 = require("./PluginBuildEnvironmentWitness");
11
+ const PluginLoadAnswers_1 = require("./PluginLoadAnswers");
10
12
  const spawnGoTool_1 = require("./spawnGoTool");
11
13
  /**
12
14
  * Acquire current Go values together with their environment-file evidence.
@@ -29,6 +31,26 @@ var GoEnvironmentReading;
29
31
  * which lets a reading witness that file before `go env` reads it.
30
32
  */
31
33
  const goEnvironmentFiles = new Map();
34
+ /**
35
+ * Answer family that carries the same location hint across processes, so a
36
+ * new process does not run `go env` once merely to learn it (#1722). A wrong
37
+ * or stale hint only costs the existing rediscovery run.
38
+ */
39
+ const ENVIRONMENT_FILE_HINT = "go-environment-file";
40
+ /**
41
+ * What chooses the file's location: `GOENV`, else `os.UserConfigDir()`
42
+ * (`%AppData%`, `$XDG_CONFIG_HOME`, `$HOME`, Plan 9's `$home`). The hint
43
+ * across processes is keyed by these alone, because a launch rarely repeats
44
+ * every unrelated variable, such as a per-run trace path, and a hint that
45
+ * misses costs the rediscovery run on every launch.
46
+ */
47
+ const LOCATION_VARIABLES = [
48
+ "GOENV",
49
+ "APPDATA",
50
+ "XDG_CONFIG_HOME",
51
+ "HOME",
52
+ "home",
53
+ ];
32
54
  /**
33
55
  * Run `go env -json` for the requested keys and `GOENV`, the file `go env -w`
34
56
  * writes, witnessing that file before the run reads it.
@@ -42,6 +64,11 @@ var GoEnvironmentReading;
42
64
  * one witnessed. A file that keeps moving between runs leaves the reading
43
65
  * unwitnessable, so a kept reading or a build keyed on it never holds.
44
66
  *
67
+ * The location hint also comes from the record store when one is supplied, so
68
+ * a new process witnesses the right file on its first run instead of running
69
+ * `go env` once only to learn the name.
70
+ *
71
+ * @param identities Optional record store carrying the hint across processes.
45
72
  * @returns The parsed object, or `undefined` when native acquisition or JSON
46
73
  * object decoding failed.
47
74
  * @evidence contracts/common.md#principled-implementation Actual Go supplies values and the environment-file path; pre-read metadata and bounded rediscovery preserve the earliest file witness instead of attaching a later state to an earlier read.
@@ -50,10 +77,10 @@ var GoEnvironmentReading;
50
77
  * @evidence contracts/common.md#meaningful-documentation Native paragraphs explain why file discovery can repeat and distinguish unavailable acquisition from current authority.
51
78
  * @evidence contracts/portability.md#os-neutral-implementation Go reports its actual environment-file location; native path metadata and the existing Go process owner supply observation and execution semantics.
52
79
  * @evidence contracts/performance.md#efficient-algorithms Hashing the complete tool/environment identity and up to three native Go queries process full name/value/output bytes. Requested keys contribute argument bytes; file discovery uses metadata rather than an SDK walk.
53
- * @evidence contracts/performance.md#reuse-equivalent-work Only file-location discovery hints are shared across equal selected-tool/environment identities. Current Go values and file authority are reacquired for every call.
54
- * @evidence contracts/performance.md#bound-retention-and-release-resources The module retains one file-location hint per historical tool/environment identity, without eviction, but no positive reading or native handle. Command capture/retirement belongs to spawnGoTool and the caller owns the transferred witness.
80
+ * @evidence contracts/performance.md#reuse-equivalent-work Only file-location discovery hints are shared: in process across equal selected-tool/environment identities, and through the record store across equal selected tools and location variables, since the reading verifies any hint against the file Go reports. Current Go values and file authority are reacquired for every call.
81
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The module retains one file-location hint per historical tool/environment identity, without eviction, but no positive reading or native handle; persisted hints belong to the single-file collector. Command capture/retirement belongs to spawnGoTool and the caller owns the transferred witness.
55
82
  */
56
- function read(goBinary, cwd, env, keys, witness) {
83
+ function read(goBinary, cwd, env, keys, witness, identities) {
57
84
  const memo = node_crypto_1.default.createHash("sha256").update(goBinary);
58
85
  for (const [key, value] of Object.entries(env).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)) {
59
86
  if (value !== undefined)
@@ -61,6 +88,12 @@ var GoEnvironmentReading;
61
88
  }
62
89
  const memoKey = memo.digest("hex");
63
90
  let named = goEnvironmentFiles.get(memoKey);
91
+ if (named === undefined) {
92
+ const hinted = PluginLoadAnswers_1.PluginLoadAnswers.read(identities, ENVIRONMENT_FILE_HINT, hintKey(goBinary, env));
93
+ if (hinted === null || typeof hinted === "string")
94
+ named = hinted;
95
+ }
96
+ const remembered = named;
64
97
  for (let attempt = 0; attempt < 3; attempt += 1) {
65
98
  if (named !== undefined && named !== null)
66
99
  PluginBuildEnvironmentWitness_1.PluginBuildEnvironmentWitness.add(witness, named);
@@ -89,22 +122,35 @@ var GoEnvironmentReading;
89
122
  parsed.GOENV !== "off"
90
123
  ? parsed.GOENV
91
124
  : null;
92
- if (reported === named)
125
+ if (reported === named) {
126
+ goEnvironmentFiles.set(memoKey, named);
127
+ if (named !== remembered)
128
+ PluginLoadAnswers_1.PluginLoadAnswers.write(identities, ENVIRONMENT_FILE_HINT, hintKey(goBinary, env), named);
93
129
  return parsed;
130
+ }
94
131
  if (named !== undefined && named !== null)
95
132
  witness?.delete(named);
96
133
  named = reported;
97
134
  goEnvironmentFiles.set(memoKey, named);
98
135
  // No file to witness: the reading depends on none.
99
- if (named === null)
100
- return parsed;
101
- if (witness === undefined)
136
+ if (named === null || witness === undefined) {
137
+ if (named !== remembered)
138
+ PluginLoadAnswers_1.PluginLoadAnswers.write(identities, ENVIRONMENT_FILE_HINT, hintKey(goBinary, env), named);
102
139
  return parsed;
140
+ }
103
141
  }
104
142
  if (named !== undefined && named !== null)
105
143
  PluginBuildEnvironmentWitness_1.PluginBuildEnvironmentWitness.refuse(witness, named);
106
144
  return undefined;
107
145
  }
108
146
  GoEnvironmentReading.read = read;
147
+ // A wrong hint is safe: the reading compares it with the `GOENV` Go reports
148
+ // and runs again with the reported file witnessed.
149
+ function hintKey(goBinary, env) {
150
+ return [
151
+ goBinary,
152
+ LOCATION_VARIABLES.map((name) => SidecarEnvironment_1.SidecarEnvironment.read(env, name) ?? null),
153
+ ];
154
+ }
109
155
  })(GoEnvironmentReading || (exports.GoEnvironmentReading = GoEnvironmentReading = {}));
110
156
  //# sourceMappingURL=GoEnvironmentReading.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"GoEnvironmentReading.js","sourceRoot":"","sources":["../../../../src/plugin/internal/source/GoEnvironmentReading.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"GoEnvironmentReading.js","sourceRoot":"","sources":["../../../../src/plugin/internal/source/GoEnvironmentReading.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,5 @@
1
+ import { PluginBuildEnvironmentWitness } from "./PluginBuildEnvironmentWitness";
2
+ import { PluginContentIdentities } from "./PluginContentIdentities";
1
3
  import { SourcePluginWorkspace } from "./SourcePluginWorkspace";
2
4
  /**
3
5
  * Observe Go-selected packages under the native builder's workspace policy.
@@ -11,7 +13,7 @@ import { SourcePluginWorkspace } from "./SourcePluginWorkspace";
11
13
  * @evidence contracts/common.md#meaningful-documentation Native prose distinguishes metadata selection from compilation and later materialized admission.
12
14
  * @evidence contracts/portability.md#os-neutral-implementation Native path/fs operations and the shared Go tool selector preserve environment-name and path identity without blanket case folding; Go itself applies target platform and cgo selection.
13
15
  * @evidence contracts/performance.md#efficient-algorithms One list command observes all distinct package entries in each prepared context. Context materialization traverses and copies admitted host/contributor files; workspace setup delegates manifest commands and list skips dependency loading. Framing and JSON parsing process complete output bytes, and retained results scale with selected packages/files.
14
- * @evidence contracts/performance.md#reuse-equivalent-work Entries are deduplicated within a contextual observation; callers group equivalent module contexts for one load. No metadata result is cached across source, environment or toolchain changes. Cold admission uses the already prepared real build workspace.
16
+ * @evidence contracts/performance.md#reuse-equivalent-work Entries are deduplicated within a contextual observation; callers group equivalent module contexts for one load. With a record store, a successful selection is answered across loads and processes under an identity built from the content of everything Go reads, so any source, overlay, contributor, manifest, Go variable or toolchain change observes Go again (#1721); erroneous selections are never recorded. Cold admission uses the already prepared real build workspace.
15
17
  * @evidence contracts/performance.md#bound-retention-and-release-resources Each metadata scratch has finally-based retirement-aware cleanup, and capture resources belong to spawnGoTool. Unknown native retirement retains scratch under the existing scope; results and complete output remain caller-owned with no independent byte ceiling.
16
18
  */
17
19
  export declare namespace NativeSourcePackages {
@@ -41,6 +43,32 @@ export declare namespace NativeSourcePackages {
41
43
  Err: string;
42
44
  };
43
45
  }
46
+ /**
47
+ * One load's readings, shared by its package selections and its builds:
48
+ * source directory digests and module build-environment digests, each by
49
+ * absolute directory. The builds fill and report the same maps, so a load
50
+ * reads each directory and each module's toolchain once.
51
+ *
52
+ * @evidence contracts/common.md#principled-implementation Both maps carry readings already taken in this load under its fixed effective environment; builds still take their own environment reading with a witness.
53
+ * @evidence contracts/common.md#clear-and-simple-design Two maps already owned by the loader travel together.
54
+ * @evidence contracts/common.md#prohibited-implementation-shortcuts The maps never outlive the load; cross-process reuse belongs to the record store.
55
+ * @evidence contracts/common.md#meaningful-documentation Members state their keys and values.
56
+ * @evidence contracts/portability.md#os-neutral-implementation Keys are native absolute paths.
57
+ * @evidenceExclude contracts/performance.md#efficient-algorithms A record type runs no algorithm.
58
+ * @evidence contracts/performance.md#reuse-equivalent-work Selections and builds of one load share one reading per directory and module.
59
+ * @evidence contracts/performance.md#bound-retention-and-release-resources The loader owns both maps for one load.
60
+ */
61
+ interface SelectionReadings {
62
+ /** `pluginSourceDigest` of each directory this load read. */
63
+ sources?: Map<string, string>;
64
+ /** Build-environment digest of each module root this load read. */
65
+ environments?: Map<string, string>;
66
+ /**
67
+ * Witness of each reading in `environments`, so a build of the same
68
+ * directory keys on that reading instead of probing Go again.
69
+ */
70
+ witnesses?: Map<string, PluginBuildEnvironmentWitness.Record>;
71
+ }
44
72
  /**
45
73
  * Observe entries together in a private module layout for their context.
46
74
  *
@@ -50,7 +78,7 @@ export declare namespace NativeSourcePackages {
50
78
  * @evidence contracts/common.md#meaningful-documentation Native prose states this operation's authority and delegated boundaries; fields retain separate native comments.
51
79
  * @evidence contracts/portability.md#os-neutral-implementation Native copy/path and selected tool/environment owners preserve platform identity; contribution target containment is checked.
52
80
  * @evidence contracts/performance.md#efficient-algorithms Copies admitted host/contributor bytes and enumerates entries; workspace setup reads manifests and one list command skips dependencies.
53
- * @evidence contracts/performance.md#reuse-equivalent-work All entries share one prepared context; optional readers are scoped to one load and the same selected tool/effective environment.
81
+ * @evidence contracts/performance.md#reuse-equivalent-work All entries share one prepared context; optional readers are scoped to one load and the same selected tool/effective environment. A supplied record store answers an equal selection without copying or running Go, under the content identity of the module, contributors, overlays, proposal manifests, toolchain/environment digest, Go variables, entries and command; an answer is recorded only when the copies matched their keyed digests, no package reported an error and the overlays still held their digests after Go ran.
54
82
  * @evidence contracts/performance.md#bound-retention-and-release-resources Finally releases owned scratch through retirement authority; unknown native closure defers removal and capture cleanup remains delegated.
55
83
  */
56
84
  function inspect(opts: {
@@ -64,6 +92,16 @@ export declare namespace NativeSourcePackages {
64
92
  }[];
65
93
  readers?: Map<string, SourcePluginWorkspace.GoModReader>;
66
94
  proposal?: boolean;
95
+ /**
96
+ * Record store under which an equal selection is answered without Go
97
+ * (#1721); without it every load runs the full observation.
98
+ */
99
+ identities?: PluginContentIdentities.Store;
100
+ /**
101
+ * The load's source and environment readings, shared with its builds so one
102
+ * load reads each directory and each module's toolchain once.
103
+ */
104
+ readings?: SelectionReadings;
67
105
  }): Package[];
68
106
  /**
69
107
  * Group one load's standalone candidates by their actual owning module.
@@ -74,13 +112,13 @@ export declare namespace NativeSourcePackages {
74
112
  * @evidence contracts/common.md#meaningful-documentation Native prose states this operation's authority and delegated boundaries; fields retain separate native comments.
75
113
  * @evidence contracts/portability.md#os-neutral-implementation Native module roots retain their selected spelling, without blanket case folding.
76
114
  * @evidence contracts/performance.md#efficient-algorithms One grouping pass plus contextual copies and metadata work for each distinct module; output storage scales with input population.
77
- * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries in a module share one list; overlay module observations share the load's selected-tool readers, without global metadata caching.
115
+ * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries in a module share one list; overlay module observations share the load's selected-tool readers, and the load's readings and record store reach each contextual observation so equal selections are answered from their content identity.
78
116
  * @evidence contracts/performance.md#bound-retention-and-release-resources Grouping/maps/results live for this call/load; scratch and native captures remain with inspect/read.
79
117
  */
80
118
  function ownPackages(inputs: readonly {
81
119
  source: string;
82
120
  label: string;
83
- }[], env: NodeJS.ProcessEnv, readers?: Map<string, SourcePluginWorkspace.GoModReader>): Package[];
121
+ }[], env: NodeJS.ProcessEnv, readers?: Map<string, SourcePluginWorkspace.GoModReader>, identities?: PluginContentIdentities.Store, readings?: SelectionReadings): Package[];
84
122
  /**
85
123
  * Propose ownership with the candidate-selected tool before final admission.
86
124
  *
@@ -96,14 +134,14 @@ export declare namespace NativeSourcePackages {
96
134
  * @evidence contracts/common.md#meaningful-documentation Native prose states deterministic proposal authority and mandatory final ownership confirmation.
97
135
  * @evidence contracts/portability.md#os-neutral-implementation Native module/tool/environment owners preserve candidate-relative tool and source layout identity.
98
136
  * @evidence contracts/performance.md#efficient-algorithms Groups inputs by module and actual/prospective mode, copies each admitted module once per context, and batches entries through Go metadata; retained work scales with source bytes and distinct contexts.
99
- * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries share one observation and per-load manifest readers; no result crosses a load or changed context.
137
+ * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries share one observation and per-load manifest readers; a result crosses loads only through the record store's content identity, so a changed context observes Go again.
100
138
  * @evidence contracts/performance.md#bound-retention-and-release-resources Group records live for this call; scratch/process cleanup remains with inspect and no independent output byte cap is imposed.
101
139
  */
102
140
  function propose(inputs: readonly {
103
141
  source: string;
104
142
  label: string;
105
143
  ownModule?: boolean;
106
- }[], env: NodeJS.ProcessEnv, readers?: Map<string, SourcePluginWorkspace.GoModReader>): Array<{
144
+ }[], env: NodeJS.ProcessEnv, readers?: Map<string, SourcePluginWorkspace.GoModReader>, identities?: PluginContentIdentities.Store, readings?: SelectionReadings): Array<{
107
145
  observation: Package;
108
146
  ownModule: boolean;
109
147
  }>;
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.NativeSourcePackages = void 0;
7
+ const node_crypto_1 = __importDefault(require("node:crypto"));
7
8
  const node_fs_1 = __importDefault(require("node:fs"));
8
9
  const node_path_1 = __importDefault(require("node:path"));
9
10
  const SidecarEnvironment_1 = require("../../../compiler/internal/sharedHost/SidecarEnvironment");
@@ -12,9 +13,13 @@ const SourceNativeRetirement_1 = require("../../../internal/SourceNativeRetireme
12
13
  const createCanonicalTempDirectory_1 = require("../../../internal/createCanonicalTempDirectory");
13
14
  const GoSourceInputs_1 = require("./GoSourceInputs");
14
15
  const GoToolResolution_1 = require("./GoToolResolution");
16
+ const PluginContentIdentities_1 = require("./PluginContentIdentities");
17
+ const PluginLoadAnswers_1 = require("./PluginLoadAnswers");
15
18
  const SourcePluginAdmission_1 = require("./SourcePluginAdmission");
16
19
  const SourcePluginWorkspace_1 = require("./SourcePluginWorkspace");
17
20
  const ensureExecutableGoToolchain_1 = require("./ensureExecutableGoToolchain");
21
+ const hashPluginBuildEnvironment_1 = require("./hashPluginBuildEnvironment");
22
+ const pluginSourceDigest_1 = require("./pluginSourceDigest");
18
23
  const resolveGoCompiler_1 = require("./resolveGoCompiler");
19
24
  const resolvePluginGoModule_1 = require("./resolvePluginGoModule");
20
25
  const spawnGoTool_1 = require("./spawnGoTool");
@@ -30,7 +35,7 @@ const spawnGoTool_1 = require("./spawnGoTool");
30
35
  * @evidence contracts/common.md#meaningful-documentation Native prose distinguishes metadata selection from compilation and later materialized admission.
31
36
  * @evidence contracts/portability.md#os-neutral-implementation Native path/fs operations and the shared Go tool selector preserve environment-name and path identity without blanket case folding; Go itself applies target platform and cgo selection.
32
37
  * @evidence contracts/performance.md#efficient-algorithms One list command observes all distinct package entries in each prepared context. Context materialization traverses and copies admitted host/contributor files; workspace setup delegates manifest commands and list skips dependency loading. Framing and JSON parsing process complete output bytes, and retained results scale with selected packages/files.
33
- * @evidence contracts/performance.md#reuse-equivalent-work Entries are deduplicated within a contextual observation; callers group equivalent module contexts for one load. No metadata result is cached across source, environment or toolchain changes. Cold admission uses the already prepared real build workspace.
38
+ * @evidence contracts/performance.md#reuse-equivalent-work Entries are deduplicated within a contextual observation; callers group equivalent module contexts for one load. With a record store, a successful selection is answered across loads and processes under an identity built from the content of everything Go reads, so any source, overlay, contributor, manifest, Go variable or toolchain change observes Go again (#1721); erroneous selections are never recorded. Cold admission uses the already prepared real build workspace.
34
39
  * @evidence contracts/performance.md#bound-retention-and-release-resources Each metadata scratch has finally-based retirement-aware cleanup, and capture resources belong to spawnGoTool. Unknown native retirement retains scratch under the existing scope; results and complete output remain caller-owned with no independent byte ceiling.
35
40
  */
36
41
  var NativeSourcePackages;
@@ -44,7 +49,7 @@ var NativeSourcePackages;
44
49
  * @evidence contracts/common.md#meaningful-documentation Native prose states this operation's authority and delegated boundaries; fields retain separate native comments.
45
50
  * @evidence contracts/portability.md#os-neutral-implementation Native copy/path and selected tool/environment owners preserve platform identity; contribution target containment is checked.
46
51
  * @evidence contracts/performance.md#efficient-algorithms Copies admitted host/contributor bytes and enumerates entries; workspace setup reads manifests and one list command skips dependencies.
47
- * @evidence contracts/performance.md#reuse-equivalent-work All entries share one prepared context; optional readers are scoped to one load and the same selected tool/effective environment.
52
+ * @evidence contracts/performance.md#reuse-equivalent-work All entries share one prepared context; optional readers are scoped to one load and the same selected tool/effective environment. A supplied record store answers an equal selection without copying or running Go, under the content identity of the module, contributors, overlays, proposal manifests, toolchain/environment digest, Go variables, entries and command; an answer is recorded only when the copies matched their keyed digests, no package reported an error and the overlays still held their digests after Go ran.
48
53
  * @evidence contracts/performance.md#bound-retention-and-release-resources Finally releases owned scratch through retirement authority; unknown native closure defers removal and capture cleanup remains delegated.
49
54
  */
50
55
  function inspect(opts) {
@@ -53,6 +58,18 @@ var NativeSourcePackages;
53
58
  const compiler = (0, resolveGoCompiler_1.resolveGoCompiler)(env);
54
59
  const goBinary = GoToolResolution_1.GoToolResolution.resolveGoToolForBuild(compiler.binary, env, moduleRoot);
55
60
  (0, ensureExecutableGoToolchain_1.ensureExecutableGoToolchain)(goBinary, compiler.bundled);
61
+ // WARNING (#1721): never drop this lookup or narrow its identity. Without
62
+ // it every warm launch and every unplugin generation copied the module
63
+ // twice and ran `go list` twice (6 s+ on Windows) to rediscover an answer
64
+ // its unchanged inputs already determined.
65
+ const identity = opts.identities === undefined
66
+ ? undefined
67
+ : selectionIdentity(opts, moduleRoot, goBinary, env, opts.identities);
68
+ if (identity !== undefined) {
69
+ const recalled = recallSelection(PluginLoadAnswers_1.PluginLoadAnswers.read(opts.identities, SELECTION_ANSWER, identity), moduleRoot, opts.packages.length);
70
+ if (recalled !== undefined)
71
+ return recalled;
72
+ }
56
73
  const scratch = (0, createCanonicalTempDirectory_1.createCanonicalTempDirectory)("ttsc-package-selection-");
57
74
  let taskFailure;
58
75
  try {
@@ -61,6 +78,11 @@ var NativeSourcePackages;
61
78
  retainedPaths: [scratch],
62
79
  });
63
80
  SourcePluginWorkspace_1.SourcePluginWorkspace.materialize(moduleRoot, scratch);
81
+ // An answer is recorded only for the copy its identity describes: a
82
+ // module edited between the identity reading and the copy observed
83
+ // other bytes than the key names.
84
+ let copiesKeyed = identity === undefined ||
85
+ (0, pluginSourceDigest_1.pluginSourceDigest)(scratch) === identity.module;
64
86
  if (opts.proposal === true) {
65
87
  // Only root manifests change. Relative Go inputs retain the source
66
88
  // module layout, while its irrelevant graph/toolchain stays inactive.
@@ -86,16 +108,32 @@ var NativeSourcePackages;
86
108
  if (node_fs_1.default.existsSync(target))
87
109
  throw new Error(`ttsc: package selection target already exists: ${target}`);
88
110
  SourcePluginWorkspace_1.SourcePluginWorkspace.materialize(input.source, target);
111
+ if (identity !== undefined)
112
+ copiesKeyed &&=
113
+ (0, pluginSourceDigest_1.pluginSourceDigest)(target) ===
114
+ identity.entries.find((entry) => entry[0] === input.entry)?.[2];
89
115
  }
90
- const reader = SourcePluginWorkspace_1.SourcePluginWorkspace.createGoModReader(goBinary, opts.pluginName, env, opts.readers);
116
+ const reader = SourcePluginWorkspace_1.SourcePluginWorkspace.createGoModReader(goBinary, opts.pluginName, env, opts.readers, opts.identities);
91
117
  SourcePluginWorkspace_1.SourcePluginWorkspace.writeGoWork(scratch, SourcePluginWorkspace_1.SourcePluginWorkspace.findTtscOverlayDirs(), goBinary, opts.pluginName, env, reader);
92
- return read({
118
+ const observed = read({
93
119
  cwd: scratch,
94
120
  entries: opts.packages.map((input) => input.entry),
95
121
  env: GoSourceInputs_1.GoSourceInputs.goBuildEnv(goBinary, undefined, env),
96
122
  goBinary,
97
123
  pluginName: opts.pluginName,
98
124
  });
125
+ if (identity !== undefined &&
126
+ copiesKeyed &&
127
+ observed.every((input) => input.Error === undefined) &&
128
+ JSON.stringify(overlayDigests(opts.identities)) ===
129
+ JSON.stringify(identity.overlays))
130
+ PluginLoadAnswers_1.PluginLoadAnswers.write(opts.identities, SELECTION_ANSWER, identity, observed.map((input) => ({
131
+ ...input,
132
+ Dir: input.Dir === undefined
133
+ ? undefined
134
+ : node_path_1.default.relative(scratch, input.Dir),
135
+ })));
136
+ return observed;
99
137
  }
100
138
  catch (error) {
101
139
  taskFailure = { error };
@@ -117,10 +155,10 @@ var NativeSourcePackages;
117
155
  * @evidence contracts/common.md#meaningful-documentation Native prose states this operation's authority and delegated boundaries; fields retain separate native comments.
118
156
  * @evidence contracts/portability.md#os-neutral-implementation Native module roots retain their selected spelling, without blanket case folding.
119
157
  * @evidence contracts/performance.md#efficient-algorithms One grouping pass plus contextual copies and metadata work for each distinct module; output storage scales with input population.
120
- * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries in a module share one list; overlay module observations share the load's selected-tool readers, without global metadata caching.
158
+ * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries in a module share one list; overlay module observations share the load's selected-tool readers, and the load's readings and record store reach each contextual observation so equal selections are answered from their content identity.
121
159
  * @evidence contracts/performance.md#bound-retention-and-release-resources Grouping/maps/results live for this call/load; scratch and native captures remain with inspect/read.
122
160
  */
123
- function ownPackages(inputs, env, readers = new Map()) {
161
+ function ownPackages(inputs, env, readers = new Map(), identities, readings) {
124
162
  const groups = new Map();
125
163
  inputs.forEach((input, index) => {
126
164
  const target = (0, resolvePluginGoModule_1.resolvePluginGoModule)(input.source, input.label);
@@ -136,6 +174,8 @@ var NativeSourcePackages;
136
174
  pluginName: first.label,
137
175
  env,
138
176
  readers,
177
+ identities,
178
+ readings,
139
179
  packages: group.map(({ entry }) => ({ entry })),
140
180
  });
141
181
  group.forEach(({ index }, offset) => {
@@ -160,10 +200,10 @@ var NativeSourcePackages;
160
200
  * @evidence contracts/common.md#meaningful-documentation Native prose states deterministic proposal authority and mandatory final ownership confirmation.
161
201
  * @evidence contracts/portability.md#os-neutral-implementation Native module/tool/environment owners preserve candidate-relative tool and source layout identity.
162
202
  * @evidence contracts/performance.md#efficient-algorithms Groups inputs by module and actual/prospective mode, copies each admitted module once per context, and batches entries through Go metadata; retained work scales with source bytes and distinct contexts.
163
- * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries share one observation and per-load manifest readers; no result crosses a load or changed context.
203
+ * @evidence contracts/performance.md#reuse-equivalent-work Equivalent entries share one observation and per-load manifest readers; a result crosses loads only through the record store's content identity, so a changed context observes Go again.
164
204
  * @evidence contracts/performance.md#bound-retention-and-release-resources Group records live for this call; scratch/process cleanup remains with inspect and no independent output byte cap is imposed.
165
205
  */
166
- function propose(inputs, env, readers = new Map()) {
206
+ function propose(inputs, env, readers = new Map(), identities, readings) {
167
207
  const groups = new Map();
168
208
  inputs.forEach((input, index) => {
169
209
  const target = (0, resolvePluginGoModule_1.resolvePluginGoModule)(input.source, input.label);
@@ -181,6 +221,8 @@ var NativeSourcePackages;
181
221
  pluginName: first.label,
182
222
  env,
183
223
  readers,
224
+ identities,
225
+ readings,
184
226
  proposal: !group[0].ownModule,
185
227
  packages: group.map(({ entry }) => ({ entry })),
186
228
  });
@@ -327,4 +369,104 @@ var NativeSourcePackages;
327
369
  function genericHostSource() {
328
370
  return node_path_1.default.resolve(__dirname, "../../../..", "cmd/utility-host");
329
371
  }
372
+ /** Answer family of package selections (`PluginLoadAnswers`). */
373
+ const SELECTION_ANSWER = "go-package-selection";
374
+ /** Fields `read` asks Go for; part of the selection identity. */
375
+ const SELECTION_FIELDS = "-json=Dir,Name,GoFiles,CgoFiles,Error";
376
+ function selectionIdentity(opts, moduleRoot, goBinary, env, identities) {
377
+ try {
378
+ const readings = opts.readings ?? {};
379
+ const directory = (root) => {
380
+ const resolved = node_path_1.default.resolve(root);
381
+ let digest = readings.sources?.get(resolved);
382
+ if (digest === undefined) {
383
+ digest = PluginContentIdentities_1.PluginContentIdentities.sourceDirectory(identities, resolved);
384
+ readings.sources?.set(resolved, digest);
385
+ }
386
+ return digest;
387
+ };
388
+ const resolvedRoot = node_path_1.default.resolve(moduleRoot);
389
+ let environment = readings.environments?.get(resolvedRoot);
390
+ if (environment === undefined) {
391
+ const hash = node_crypto_1.default.createHash("sha256");
392
+ const witness = new Map();
393
+ (0, hashPluginBuildEnvironment_1.hashPluginBuildEnvironment)(hash, goBinary, moduleRoot, env, { readFile: (location) => node_fs_1.default.readFileSync(location) }, witness, identities);
394
+ environment = hash.digest("hex");
395
+ readings.environments?.set(resolvedRoot, environment);
396
+ readings.witnesses?.set(resolvedRoot, witness);
397
+ }
398
+ const host = opts.proposal === true
399
+ ? (0, resolvePluginGoModule_1.resolvePluginGoModule)(genericHostSource(), opts.pluginName).moduleRoot
400
+ : undefined;
401
+ return {
402
+ format: 1,
403
+ command: [
404
+ "list",
405
+ ...GoSourceInputs_1.GoSourceInputs.BUILD_FLAGS,
406
+ "-find",
407
+ "-e",
408
+ SELECTION_FIELDS,
409
+ ],
410
+ mode: opts.proposal === true ? "proposal" : "actual",
411
+ module: directory(moduleRoot),
412
+ environment,
413
+ variables: Object.entries(GoSourceInputs_1.GoSourceInputs.goBuildEnv(goBinary, undefined, env))
414
+ .filter((entry) => entry[1] !== undefined && /^(GO|CGO_)/i.test(entry[0]))
415
+ .sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0)),
416
+ manifests: host === undefined
417
+ ? null
418
+ : ["go.mod", "go.sum"].map((name) => fileDigest(node_path_1.default.join(host, name))),
419
+ overlays: SourcePluginWorkspace_1.SourcePluginWorkspace.findTtscOverlayDirs().map(directory),
420
+ entries: opts.packages.map((input) => [
421
+ input.entry,
422
+ input.name ?? null,
423
+ input.source === undefined ? null : directory(input.source),
424
+ ]),
425
+ };
426
+ }
427
+ catch {
428
+ // An identity that cannot be formed only costs the real observation.
429
+ return undefined;
430
+ }
431
+ }
432
+ /** The digest of every overlay module, in the generated workspace's order. */
433
+ function overlayDigests(identities) {
434
+ return SourcePluginWorkspace_1.SourcePluginWorkspace.findTtscOverlayDirs().map((directory) => PluginContentIdentities_1.PluginContentIdentities.sourceDirectory(identities, directory));
435
+ }
436
+ /** A small manifest's content digest, or null when it does not exist. */
437
+ function fileDigest(file) {
438
+ try {
439
+ return node_crypto_1.default
440
+ .createHash("sha256")
441
+ .update(node_fs_1.default.readFileSync(file))
442
+ .digest("hex");
443
+ }
444
+ catch (error) {
445
+ if (error.code === "ENOENT")
446
+ return null;
447
+ throw error;
448
+ }
449
+ }
450
+ /**
451
+ * A recorded selection rebased onto the module it now describes, or `undefined`
452
+ * when the record does not have the shape `read` produces.
453
+ */
454
+ function recallSelection(value, moduleRoot, count) {
455
+ if (!Array.isArray(value) || value.length !== count)
456
+ return undefined;
457
+ try {
458
+ const packages = NativeSourcePackages.parse(value.map((input) => JSON.stringify(input)).join("\n"));
459
+ if (packages.length !== count)
460
+ return undefined;
461
+ return packages.map((input) => ({
462
+ ...input,
463
+ Dir: input.Dir === undefined
464
+ ? undefined
465
+ : node_path_1.default.resolve(moduleRoot, input.Dir),
466
+ }));
467
+ }
468
+ catch {
469
+ return undefined;
470
+ }
471
+ }
330
472
  //# sourceMappingURL=NativeSourcePackages.js.map