ttsc 0.31.1 → 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.
- package/lib/compiler/internal/build/BuildExecution.d.ts +4 -2
- package/lib/compiler/internal/build/BuildExecution.js +40 -12
- package/lib/compiler/internal/build/BuildExecution.js.map +1 -1
- package/lib/compiler/internal/startResidentTransform.js +5 -4
- package/lib/compiler/internal/startResidentTransform.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.js +9 -7
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/internal/javascriptRuntimeCapabilities.d.ts +13 -4
- package/lib/internal/javascriptRuntimeCapabilities.js +56 -6
- package/lib/internal/javascriptRuntimeCapabilities.js.map +1 -1
- package/lib/internal/pluginSource.d.ts +1 -0
- package/lib/internal/pluginSource.js +1 -0
- package/lib/internal/pluginSource.js.map +1 -1
- package/lib/internal/resolveNodeBinary.d.ts +6 -1
- package/lib/internal/resolveNodeBinary.js +6 -2
- package/lib/internal/resolveNodeBinary.js.map +1 -1
- package/lib/internal/runtimeExecutableIdentity.d.ts +22 -13
- package/lib/internal/runtimeExecutableIdentity.js +192 -102
- package/lib/internal/runtimeExecutableIdentity.js.map +1 -1
- package/lib/launcher/internal/runtime/installRuntimeHooks.js +58 -4
- package/lib/launcher/internal/runtime/installRuntimeHooks.js.map +1 -1
- package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.d.ts +5 -1
- package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js +7 -2
- package/lib/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.js.map +1 -1
- package/lib/launcher/internal/ttscserver/runTtscserver.js +8 -1
- package/lib/launcher/internal/ttscserver/runTtscserver.js.map +1 -1
- package/lib/plugin/internal/CapabilityResolutionFormat.d.ts +21 -62
- package/lib/plugin/internal/CapabilityResolutionFormat.js +15 -106
- package/lib/plugin/internal/CapabilityResolutionFormat.js.map +1 -1
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.d.ts +6 -0
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js +4 -4
- package/lib/plugin/internal/load/PluginDescriptorEvaluationCache.js.map +1 -1
- package/lib/plugin/internal/load/loadProjectPlugins.d.ts +12 -1
- package/lib/plugin/internal/load/loadProjectPlugins.js +80 -20
- package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
- package/lib/plugin/internal/readCapabilityResolution.d.ts +6 -0
- package/lib/plugin/internal/readCapabilityResolution.js +8 -5
- package/lib/plugin/internal/readCapabilityResolution.js.map +1 -1
- package/lib/plugin/internal/source/GoEnvironmentReading.d.ts +9 -3
- package/lib/plugin/internal/source/GoEnvironmentReading.js +53 -7
- package/lib/plugin/internal/source/GoEnvironmentReading.js.map +1 -1
- package/lib/plugin/internal/source/NativeSourcePackages.d.ts +44 -6
- package/lib/plugin/internal/source/NativeSourcePackages.js +150 -8
- package/lib/plugin/internal/source/NativeSourcePackages.js.map +1 -1
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.d.ts +21 -3
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js +32 -7
- package/lib/plugin/internal/source/PluginBuildEnvironmentReadings.js.map +1 -1
- package/lib/plugin/internal/source/PluginContentIdentities.d.ts +265 -0
- package/lib/plugin/internal/source/PluginContentIdentities.js +452 -0
- package/lib/plugin/internal/source/PluginContentIdentities.js.map +1 -0
- package/lib/plugin/internal/source/PluginLoadAnswers.d.ts +63 -0
- package/lib/plugin/internal/source/PluginLoadAnswers.js +128 -0
- package/lib/plugin/internal/source/PluginLoadAnswers.js.map +1 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.d.ts +10 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.js +12 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.js.map +1 -1
- package/lib/plugin/internal/source/SourcePluginWorkspace.d.ts +5 -2
- package/lib/plugin/internal/source/SourcePluginWorkspace.js +5 -3
- package/lib/plugin/internal/source/SourcePluginWorkspace.js.map +1 -1
- package/lib/plugin/internal/source/buildSourcePlugin.d.ts +15 -2
- package/lib/plugin/internal/source/buildSourcePlugin.js +27 -4
- package/lib/plugin/internal/source/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/source/computeCacheKey.d.ts +21 -5
- package/lib/plugin/internal/source/computeCacheKey.js +71 -29
- package/lib/plugin/internal/source/computeCacheKey.js.map +1 -1
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.d.ts +7 -3
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.js +74 -35
- package/lib/plugin/internal/source/hashPluginBuildEnvironment.js.map +1 -1
- package/lib/plugin/internal/source/pluginBuildEnvironment.d.ts +8 -3
- package/lib/plugin/internal/source/pluginBuildEnvironment.js +8 -4
- package/lib/plugin/internal/source/pluginBuildEnvironment.js.map +1 -1
- package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js +12 -2
- package/lib/plugin/internal/source/pluginBuildEnvironmentWorker.js.map +1 -1
- package/lib/plugin/internal/source/pluginBuildVersions.d.ts +2 -2
- package/lib/plugin/internal/source/pluginBuildVersions.js +4 -17
- package/lib/plugin/internal/source/pluginBuildVersions.js.map +1 -1
- package/lib/plugin/internal/source/pluginSourceState.d.ts +6 -2
- package/lib/plugin/internal/source/pluginSourceState.js +20 -8
- package/lib/plugin/internal/source/pluginSourceState.js.map +1 -1
- package/lib/plugin/internal/source/pluginSourceStateHolds.d.ts +7 -2
- package/lib/plugin/internal/source/pluginSourceStateHolds.js +12 -7
- package/lib/plugin/internal/source/pluginSourceStateHolds.js.map +1 -1
- package/lib/plugin/internal/source/processPluginBuildEnvironment.d.ts +7 -2
- package/lib/plugin/internal/source/processPluginBuildEnvironment.js +8 -3
- package/lib/plugin/internal/source/processPluginBuildEnvironment.js.map +1 -1
- package/lib/plugin/internal/source/provenPluginSourceDigest.d.ts +28 -0
- package/lib/plugin/internal/source/provenPluginSourceDigest.js +41 -0
- package/lib/plugin/internal/source/provenPluginSourceDigest.js.map +1 -0
- package/lib/plugin/internal/source/pruneCacheFileRoot.d.ts +3 -2
- package/lib/plugin/internal/source/pruneCacheFileRoot.js +3 -2
- package/lib/plugin/internal/source/pruneCacheFileRoot.js.map +1 -1
- package/lib/plugin/internal/source/ttscPackageVersion.d.ts +26 -0
- package/lib/plugin/internal/source/ttscPackageVersion.js +47 -0
- package/lib/plugin/internal/source/ttscPackageVersion.js.map +1 -0
- package/lib/plugin/internal/writeCapabilityResolution.d.ts +6 -0
- package/lib/plugin/internal/writeCapabilityResolution.js +11 -7
- package/lib/plugin/internal/writeCapabilityResolution.js.map +1 -1
- package/lib/plugin/resolveCapabilityPlugins.js +67 -15
- package/lib/plugin/resolveCapabilityPlugins.js.map +1 -1
- package/package.json +8 -8
- package/src/compiler/internal/build/BuildExecution.ts +46 -13
- package/src/compiler/internal/startResidentTransform.ts +12 -3
- package/src/compiler/internal/transformProjectInMemory.ts +10 -2
- package/src/internal/javascriptRuntimeCapabilities.ts +71 -5
- package/src/internal/pluginSource.ts +1 -0
- package/src/internal/resolveNodeBinary.ts +12 -1
- package/src/internal/runtimeExecutableIdentity.ts +227 -141
- package/src/launcher/internal/runtime/installRuntimeHooks.ts +68 -3
- package/src/launcher/internal/ttscserver/captureLSPPluginSelectionInputs.ts +11 -2
- package/src/launcher/internal/ttscserver/runTtscserver.ts +18 -1
- package/src/plugin/internal/CapabilityResolutionFormat.ts +23 -107
- package/src/plugin/internal/load/PluginDescriptorEvaluationCache.ts +14 -4
- package/src/plugin/internal/load/loadProjectPlugins.ts +212 -94
- package/src/plugin/internal/readCapabilityResolution.ts +17 -6
- package/src/plugin/internal/source/GoEnvironmentReading.ts +74 -5
- package/src/plugin/internal/source/NativeSourcePackages.ts +262 -5
- package/src/plugin/internal/source/PluginBuildEnvironmentReadings.ts +41 -5
- package/src/plugin/internal/source/PluginContentIdentities.ts +563 -0
- package/src/plugin/internal/source/PluginLoadAnswers.ts +151 -0
- package/src/plugin/internal/source/SourceBuildCacheLayout.ts +14 -0
- package/src/plugin/internal/source/SourcePluginWorkspace.ts +6 -1
- package/src/plugin/internal/source/buildSourcePlugin.ts +43 -3
- package/src/plugin/internal/source/computeCacheKey.ts +103 -47
- package/src/plugin/internal/source/hashPluginBuildEnvironment.ts +144 -29
- package/src/plugin/internal/source/pluginBuildEnvironment.ts +9 -2
- package/src/plugin/internal/source/pluginBuildEnvironmentWorker.ts +18 -2
- package/src/plugin/internal/source/pluginBuildVersions.ts +5 -26
- package/src/plugin/internal/source/pluginSourceState.ts +28 -12
- package/src/plugin/internal/source/pluginSourceStateHolds.ts +15 -8
- package/src/plugin/internal/source/processPluginBuildEnvironment.ts +8 -2
- package/src/plugin/internal/source/provenPluginSourceDigest.ts +45 -0
- package/src/plugin/internal/source/pruneCacheFileRoot.ts +3 -2
- package/src/plugin/internal/source/ttscPackageVersion.ts +45 -0
- package/src/plugin/internal/writeCapabilityResolution.ts +29 -8
- package/src/plugin/resolveCapabilityPlugins.ts +87 -13
|
@@ -2,6 +2,7 @@ import path from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import { resolveNodeBinary } from "../../internal/resolveNodeBinary";
|
|
4
4
|
import { loadProjectPlugins } from "../../plugin/internal/load/loadProjectPlugins";
|
|
5
|
+
import type { PluginContentIdentities } from "../../plugin/internal/source/PluginContentIdentities";
|
|
5
6
|
import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
|
|
6
7
|
import type { ITtscLoadedNativePlugin } from "../../structures/internal/ITtscLoadedNativePlugin";
|
|
7
8
|
import { ResidentTransformProcess } from "./ResidentTransformProcess";
|
|
@@ -94,7 +95,13 @@ export function startResidentTransform(
|
|
|
94
95
|
],
|
|
95
96
|
binary: host.binary,
|
|
96
97
|
cwd: project.root,
|
|
97
|
-
env: residentEnv(
|
|
98
|
+
env: residentEnv(
|
|
99
|
+
context,
|
|
100
|
+
project.root,
|
|
101
|
+
tsgoBinary,
|
|
102
|
+
loaded.nativePlugins,
|
|
103
|
+
loaded.identities,
|
|
104
|
+
),
|
|
98
105
|
});
|
|
99
106
|
return { process: resident, projectRoot: project.root };
|
|
100
107
|
}
|
|
@@ -106,13 +113,15 @@ export function startResidentTransform(
|
|
|
106
113
|
* plugin config anchor (an embedder compiling through a generated wrapper
|
|
107
114
|
* tsconfig) so config-file discovery walks the real project instead of the
|
|
108
115
|
* wrapper's temp-dir ancestry, and forwards linked transform plugins via
|
|
109
|
-
* `TTSC_LINKED_PLUGINS_JSON`.
|
|
116
|
+
* `TTSC_LINKED_PLUGINS_JSON`. The load's record store proves the Node runtime
|
|
117
|
+
* from metadata instead of streaming it again (#1723).
|
|
110
118
|
*/
|
|
111
119
|
function residentEnv(
|
|
112
120
|
context: ITtscCompilerContext,
|
|
113
121
|
projectRoot: string,
|
|
114
122
|
tsgoBinary: string,
|
|
115
123
|
nativePlugins: readonly ITtscLoadedNativePlugin[],
|
|
124
|
+
identities: PluginContentIdentities.Store | undefined,
|
|
116
125
|
): NodeJS.ProcessEnv {
|
|
117
126
|
const pluginConfigDir = resolvePluginConfigDir(context);
|
|
118
127
|
const env = SidecarEnvironment.merge(
|
|
@@ -128,7 +137,7 @@ function residentEnv(
|
|
|
128
137
|
context.env,
|
|
129
138
|
{ TTSC_TSGO_BINARY: tsgoBinary },
|
|
130
139
|
);
|
|
131
|
-
const node = resolveNodeBinary(env, projectRoot);
|
|
140
|
+
const node = resolveNodeBinary(env, projectRoot, identities);
|
|
132
141
|
SidecarEnvironment.write(env, "TTSC_NODE_BINARY", node);
|
|
133
142
|
// The anchor is per-invocation state owned by this host: when this run
|
|
134
143
|
// declared none (and the caller's env does not name one), drop any value
|
|
@@ -5,6 +5,7 @@ import { collectProjectHostInputs } from "../../plugin/internal/load/collectProj
|
|
|
5
5
|
import { hashHostInputPaths } from "../../plugin/internal/load/hashHostInputPaths";
|
|
6
6
|
import { loadProjectPlugins } from "../../plugin/internal/load/loadProjectPlugins";
|
|
7
7
|
import { realpathHostInputPaths } from "../../plugin/internal/load/realpathHostInputPaths";
|
|
8
|
+
import type { PluginContentIdentities } from "../../plugin/internal/source/PluginContentIdentities";
|
|
8
9
|
import type { ITtscCompilerContext } from "../../structures/ITtscCompilerContext";
|
|
9
10
|
import type { ITtscCompilerTransformation } from "../../structures/ITtscCompilerTransformation";
|
|
10
11
|
import type { ITtscLoadedNativePlugin } from "../../structures/internal/ITtscLoadedNativePlugin";
|
|
@@ -301,6 +302,7 @@ function transformProjectWithPlugins(
|
|
|
301
302
|
tsgoBinary,
|
|
302
303
|
loaded.nativePlugins,
|
|
303
304
|
checks,
|
|
305
|
+
loaded.identities,
|
|
304
306
|
);
|
|
305
307
|
const checkedHostInputs = mergeHostInputs(
|
|
306
308
|
loaded.hostInputs,
|
|
@@ -414,6 +416,7 @@ function transformProjectWithPlugins(
|
|
|
414
416
|
tsgoBinary,
|
|
415
417
|
loaded.nativePlugins,
|
|
416
418
|
plugin,
|
|
419
|
+
loaded.identities,
|
|
417
420
|
),
|
|
418
421
|
},
|
|
419
422
|
);
|
|
@@ -688,6 +691,7 @@ function runNativeChecks(
|
|
|
688
691
|
tsgoBinary: string,
|
|
689
692
|
nativePlugins: readonly ITtscLoadedNativePlugin[],
|
|
690
693
|
checks: readonly ITtscLoadedNativePlugin[],
|
|
694
|
+
identities: PluginContentIdentities.Store | undefined,
|
|
691
695
|
): TtscBuildResult {
|
|
692
696
|
let result: TtscBuildResult = {
|
|
693
697
|
diagnostics: [],
|
|
@@ -716,6 +720,7 @@ function runNativeChecks(
|
|
|
716
720
|
tsgoBinary,
|
|
717
721
|
nativePlugins,
|
|
718
722
|
plugin,
|
|
723
|
+
identities,
|
|
719
724
|
),
|
|
720
725
|
},
|
|
721
726
|
);
|
|
@@ -804,7 +809,9 @@ function serializeNativePlugins(
|
|
|
804
809
|
* the caller declared a plugin config anchor (an embedder compiling through a
|
|
805
810
|
* generated wrapper tsconfig) so config-file discovery walks the real project
|
|
806
811
|
* instead of the wrapper's temp-dir ancestry. For transform plugins, also
|
|
807
|
-
* passes `TTSC_LINKED_PLUGINS_JSON` when linked sources are present.
|
|
812
|
+
* passes `TTSC_LINKED_PLUGINS_JSON` when linked sources are present. The load's
|
|
813
|
+
* record store proves the Node runtime from metadata instead of streaming it
|
|
814
|
+
* before every spawn of every generation (#1723).
|
|
808
815
|
*/
|
|
809
816
|
function nativePluginEnv(
|
|
810
817
|
options: ITtscCompilerContext,
|
|
@@ -812,6 +819,7 @@ function nativePluginEnv(
|
|
|
812
819
|
tsgoBinary: string,
|
|
813
820
|
nativePlugins?: readonly ITtscLoadedNativePlugin[],
|
|
814
821
|
plugin?: ITtscLoadedNativePlugin,
|
|
822
|
+
identities?: PluginContentIdentities.Store,
|
|
815
823
|
): NodeJS.ProcessEnv {
|
|
816
824
|
const pluginConfigDir = resolvePluginConfigDir(options);
|
|
817
825
|
const env = SidecarEnvironment.merge(
|
|
@@ -827,7 +835,7 @@ function nativePluginEnv(
|
|
|
827
835
|
options.env,
|
|
828
836
|
{ TTSC_TSGO_BINARY: tsgoBinary },
|
|
829
837
|
);
|
|
830
|
-
const node = resolveNodeBinary(env, projectRoot);
|
|
838
|
+
const node = resolveNodeBinary(env, projectRoot, identities);
|
|
831
839
|
SidecarEnvironment.write(env, "TTSC_NODE_BINARY", node);
|
|
832
840
|
// The anchor is per-invocation state owned by this host: when this run
|
|
833
841
|
// declared none (and the caller's env does not name one), drop any value
|
|
@@ -4,6 +4,8 @@ import path from "node:path";
|
|
|
4
4
|
|
|
5
5
|
import { captureProcessOutput } from "../compiler/internal/captureProcessOutput";
|
|
6
6
|
import { SidecarEnvironment } from "../compiler/internal/sharedHost/SidecarEnvironment";
|
|
7
|
+
import type { PluginContentIdentities } from "../plugin/internal/source/PluginContentIdentities";
|
|
8
|
+
import { PluginLoadAnswers } from "../plugin/internal/source/PluginLoadAnswers";
|
|
7
9
|
import { E2ETrace } from "./E2ETrace";
|
|
8
10
|
import type { IJavaScriptRuntimeCapabilities } from "./IJavaScriptRuntimeCapabilities";
|
|
9
11
|
import { OwnedSynchronousProcess } from "./OwnedSynchronousProcess";
|
|
@@ -20,28 +22,56 @@ import { spawnSyncWithLowDescriptors } from "./spawnSyncWithLowDescriptors";
|
|
|
20
22
|
* Cache-ineligible candidates do not acquire executable proofs used only by
|
|
21
23
|
* cache lookup and publication.
|
|
22
24
|
*
|
|
23
|
-
*
|
|
25
|
+
* With a record store, the executable identity is proven from metadata and a
|
|
26
|
+
* probe answer recorded for that identity is reused by a later process (#1723);
|
|
27
|
+
* a recorded answer must still name an executable this runtime is.
|
|
28
|
+
*
|
|
29
|
+
* @param runtime The interpreter to probe.
|
|
30
|
+
* @param env Caller environment merged over this process's.
|
|
31
|
+
* @param cwd Working directory of the probe.
|
|
32
|
+
* @param identities Optional record store of the caller's plugin cache.
|
|
33
|
+
* @evidence contracts/common.md#principled-implementation A child reports its own feature availability and executable; byte-aware before/after identity and same-executable proof authorize reuse only for a stable absolute runtime without NODE_OPTIONS preload authority, in process or through an answer recorded under that identity.
|
|
24
34
|
* @evidence contracts/common.md#clear-and-simple-design One probe owner coordinates identity, spawning and parsing; the shared fingerprint helper owns file-content proof and the low-descriptor helper owns the POSIX launch distinction.
|
|
25
35
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Feature availability comes from the actual interpreter rather than its name; descriptor fallback handles a supported kernel constraint and failures produce unsupported capabilities, not fabricated success.
|
|
26
36
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs explain measured capabilities, reuse restrictions and freshness, with comments separating platform launch and cache permission from tags.
|
|
27
37
|
* @evidence contracts/portability.md#os-neutral-implementation Shared environment merge and lookup apply native name identity to caller precedence and NODE_OPTIONS preload authority, including Windows aliases; Node spawn receives an executable and argv without shell syntax, and only POSIX descriptor exhaustion uses the isolated broker.
|
|
28
|
-
* @evidence contracts/performance.md#efficient-algorithms Environment merge/name handling first decides cache eligibility. Eligible hits read B executable bytes; eligible misses acquire before/after
|
|
29
|
-
* @evidence contracts/performance.md#reuse-equivalent-work Stable absolute candidates that report their own executable share measured capability results, including false feature flags; changed executable bytes, link/target identity, preload options or wrapper identity require another probe, while failed probes without executable identity are not reused.
|
|
38
|
+
* @evidence contracts/performance.md#efficient-algorithms Environment merge/name handling first decides cache eligibility. Eligible hits prove the executable from a record (three stats and one small read) or read B executable bytes; eligible misses acquire before/after identities around the actual probe. Ineligible calls retain the fresh child without reading executable bytes solely for the forbidden cache. Probe spawning/parsing, a possible descriptor-exhaustion retry and capture-file reads add text/environment/native lookup costs and transient output storage; this adapter sets no explicit byte quota.
|
|
39
|
+
* @evidence contracts/performance.md#reuse-equivalent-work Stable absolute candidates that report their own executable share measured capability results, including false feature flags, within the process and across processes through the record store keyed by the full identity; changed executable bytes, link/target identity, preload options or wrapper identity require another probe, while failed probes without executable identity are not reused.
|
|
30
40
|
* @evidence contracts/performance.md#bound-retention-and-release-resources The synchronous probe owns child completion and fallback captures; finally attempts capture close/removal, whose helper suppresses cleanup failures, so native/file release is unconfirmed on failure. Capability entries retain absolute spellings and path/identity text with no eviction quota; failed identity validation can remove an entry. Returned capability copies transfer to callers.
|
|
31
41
|
*/
|
|
32
42
|
export function javascriptRuntimeCapabilities(
|
|
33
43
|
runtime: string,
|
|
34
44
|
env: NodeJS.ProcessEnv,
|
|
35
45
|
cwd: string,
|
|
46
|
+
identities?: PluginContentIdentities.Store,
|
|
36
47
|
): IJavaScriptRuntimeCapabilities {
|
|
37
48
|
const effectiveEnv = SidecarEnvironment.merge(process.env, env);
|
|
38
49
|
const cacheKey = runtimeCapabilityCacheKey(runtime, effectiveEnv);
|
|
39
50
|
const beforeIdentity =
|
|
40
|
-
cacheKey === undefined
|
|
51
|
+
cacheKey === undefined
|
|
52
|
+
? undefined
|
|
53
|
+
: runtimeExecutableIdentity(runtime, identities);
|
|
41
54
|
if (cacheKey !== undefined && beforeIdentity !== undefined) {
|
|
42
55
|
const cached = runtimeCapabilityCache.get(cacheKey);
|
|
43
56
|
if (cached?.identity === beforeIdentity) return { ...cached.capabilities };
|
|
44
57
|
runtimeCapabilityCache.delete(cacheKey);
|
|
58
|
+
// WARNING (#1723): a launch is a new process, so the memo above is empty
|
|
59
|
+
// on every CLI run. The same proven executable answers the same probe; the
|
|
60
|
+
// record store carries that answer across processes.
|
|
61
|
+
const recorded = recordedCapabilities(
|
|
62
|
+
PluginLoadAnswers.read(identities, RUNTIME_CAPABILITIES, [
|
|
63
|
+
cacheKey,
|
|
64
|
+
beforeIdentity,
|
|
65
|
+
]),
|
|
66
|
+
runtime,
|
|
67
|
+
);
|
|
68
|
+
if (recorded !== undefined) {
|
|
69
|
+
runtimeCapabilityCache.set(cacheKey, {
|
|
70
|
+
capabilities: { ...recorded },
|
|
71
|
+
identity: beforeIdentity,
|
|
72
|
+
});
|
|
73
|
+
return recorded;
|
|
74
|
+
}
|
|
45
75
|
}
|
|
46
76
|
const args = [
|
|
47
77
|
"-e",
|
|
@@ -113,7 +143,9 @@ export function javascriptRuntimeCapabilities(
|
|
|
113
143
|
// This removes a process spawn from the common path without
|
|
114
144
|
// authorizing a replaced or redirected runtime in a long-lived host.
|
|
115
145
|
const afterIdentity =
|
|
116
|
-
cacheKey === undefined
|
|
146
|
+
cacheKey === undefined
|
|
147
|
+
? undefined
|
|
148
|
+
: runtimeExecutableIdentity(runtime, identities);
|
|
117
149
|
if (
|
|
118
150
|
cacheKey !== undefined &&
|
|
119
151
|
capabilities.executable !== undefined &&
|
|
@@ -125,10 +157,44 @@ export function javascriptRuntimeCapabilities(
|
|
|
125
157
|
capabilities: { ...capabilities },
|
|
126
158
|
identity: afterIdentity,
|
|
127
159
|
});
|
|
160
|
+
PluginLoadAnswers.write(
|
|
161
|
+
identities,
|
|
162
|
+
RUNTIME_CAPABILITIES,
|
|
163
|
+
[cacheKey, afterIdentity],
|
|
164
|
+
capabilities,
|
|
165
|
+
);
|
|
128
166
|
}
|
|
129
167
|
return capabilities;
|
|
130
168
|
}
|
|
131
169
|
|
|
170
|
+
/** Answer family of measured runtime capabilities (`PluginLoadAnswers`). */
|
|
171
|
+
const RUNTIME_CAPABILITIES = "javascript-runtime-capabilities";
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* A recorded probe answer in the shape the probe produces, still naming an
|
|
175
|
+
* executable this runtime is, or `undefined`.
|
|
176
|
+
*/
|
|
177
|
+
function recordedCapabilities(
|
|
178
|
+
value: unknown,
|
|
179
|
+
runtime: string,
|
|
180
|
+
): IJavaScriptRuntimeCapabilities | undefined {
|
|
181
|
+
if (typeof value !== "object" || value === null) return undefined;
|
|
182
|
+
const recorded = value as Partial<IJavaScriptRuntimeCapabilities>;
|
|
183
|
+
if (
|
|
184
|
+
typeof recorded.bun !== "boolean" ||
|
|
185
|
+
typeof recorded.registerHooks !== "boolean" ||
|
|
186
|
+
typeof recorded.executable !== "string" ||
|
|
187
|
+
!path.isAbsolute(recorded.executable) ||
|
|
188
|
+
!sameRuntimeExecutable(runtime, recorded.executable)
|
|
189
|
+
)
|
|
190
|
+
return undefined;
|
|
191
|
+
return {
|
|
192
|
+
bun: recorded.bun,
|
|
193
|
+
executable: recorded.executable,
|
|
194
|
+
registerHooks: recorded.registerHooks,
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
132
198
|
type RuntimeCapabilityCacheEntry = {
|
|
133
199
|
capabilities: IJavaScriptRuntimeCapabilities;
|
|
134
200
|
identity: string;
|
|
@@ -22,5 +22,6 @@ export * from "../plugin/internal/source/pluginSourceDigest";
|
|
|
22
22
|
export * from "../plugin/internal/source/pluginSourceState";
|
|
23
23
|
export * from "../plugin/internal/source/pluginSourceStateHolds";
|
|
24
24
|
export * from "../plugin/internal/source/processPluginBuildEnvironment";
|
|
25
|
+
export * from "../plugin/internal/source/provenPluginSourceDigest";
|
|
25
26
|
export * from "../plugin/internal/source/PluginBuildEnvironmentReadings";
|
|
26
27
|
export * from "../plugin/internal/source/prunesPluginSourceDirectory";
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { SidecarEnvironment } from "../compiler/internal/sharedHost/SidecarEnvironment";
|
|
2
|
+
import type { PluginContentIdentities } from "../plugin/internal/source/PluginContentIdentities";
|
|
2
3
|
import { javascriptRuntimeCapabilities } from "./javascriptRuntimeCapabilities";
|
|
3
4
|
|
|
4
5
|
/**
|
|
@@ -7,6 +8,10 @@ import { javascriptRuntimeCapabilities } from "./javascriptRuntimeCapabilities";
|
|
|
7
8
|
* Bun can directly evaluate a descriptor, but it does not implement the
|
|
8
9
|
* synchronous `module.registerHooks` contract used by those loaders.
|
|
9
10
|
*
|
|
11
|
+
* @param env Effective environment naming `TTSC_NODE_BINARY`.
|
|
12
|
+
* @param cwd Working directory of the probes.
|
|
13
|
+
* @param identities Optional record store that lets probes of an unchanged
|
|
14
|
+
* runtime be answered across processes (#1723).
|
|
10
15
|
* @evidence contracts/common.md#principled-implementation Ordered candidates are accepted only after an actual runtime probe reports non-Bun registerHooks support and its absolute executable; names alone do not establish the loader capability.
|
|
11
16
|
* @evidence contracts/common.md#clear-and-simple-design Candidate precedence and duplicate suppression remain here, while the shared probe owns launch, capability parsing and freshness policy.
|
|
12
17
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts The node spelling is a supported final discovery candidate, not an assumed successful runtime; incompatible candidates are skipped without patching modules or globals.
|
|
@@ -19,6 +24,7 @@ import { javascriptRuntimeCapabilities } from "./javascriptRuntimeCapabilities";
|
|
|
19
24
|
export function resolveNodeBinary(
|
|
20
25
|
env: NodeJS.ProcessEnv = process.env,
|
|
21
26
|
cwd: string = process.cwd(),
|
|
27
|
+
identities?: PluginContentIdentities.Store,
|
|
22
28
|
): string | undefined {
|
|
23
29
|
const candidates = [
|
|
24
30
|
SidecarEnvironment.read(env, "TTSC_NODE_BINARY"),
|
|
@@ -31,7 +37,12 @@ export function resolveNodeBinary(
|
|
|
31
37
|
if (candidate === undefined || candidate.trim() === "") continue;
|
|
32
38
|
if (seen.has(candidate)) continue;
|
|
33
39
|
seen.add(candidate);
|
|
34
|
-
const capabilities = javascriptRuntimeCapabilities(
|
|
40
|
+
const capabilities = javascriptRuntimeCapabilities(
|
|
41
|
+
candidate,
|
|
42
|
+
env,
|
|
43
|
+
cwd,
|
|
44
|
+
identities,
|
|
45
|
+
);
|
|
35
46
|
if (
|
|
36
47
|
!capabilities.bun &&
|
|
37
48
|
capabilities.registerHooks &&
|