ttsc 0.34.2 → 0.35.0
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/driver/compileraliases/names.go +69 -0
- package/driver/compileraliases/names_test.go +57 -0
- package/lib/compiler/internal/build/BuildExecution.d.ts +26 -0
- package/lib/compiler/internal/build/BuildExecution.js +13 -3
- package/lib/compiler/internal/build/BuildExecution.js.map +1 -1
- package/lib/compiler/internal/build/RunBuildOptions.d.ts +2 -0
- package/lib/compiler/internal/build/RuntimeBuildCache.d.ts +47 -0
- package/lib/compiler/internal/build/RuntimeBuildCache.js +235 -0
- package/lib/compiler/internal/build/RuntimeBuildCache.js.map +1 -0
- package/lib/compiler/internal/build/RuntimeBuildInputs.d.ts +44 -0
- package/lib/compiler/internal/build/RuntimeBuildInputs.js +282 -0
- package/lib/compiler/internal/build/RuntimeBuildInputs.js.map +1 -0
- package/lib/compiler/internal/build/RuntimeInputProof.d.ts +50 -0
- package/lib/compiler/internal/build/RuntimeInputProof.js +315 -0
- package/lib/compiler/internal/build/RuntimeInputProof.js.map +1 -0
- package/lib/compiler/internal/build/TsgoArguments.d.ts +5 -4
- package/lib/compiler/internal/build/TsgoArguments.js +11 -5
- package/lib/compiler/internal/build/TsgoArguments.js.map +1 -1
- package/lib/compiler/internal/build/runBuild.d.ts +3 -3
- package/lib/compiler/internal/build/runBuild.js +17 -4
- package/lib/compiler/internal/build/runBuild.js.map +1 -1
- package/lib/compiler/internal/resolveNativeTypeScriptPackage.d.ts +27 -0
- package/lib/compiler/internal/resolveNativeTypeScriptPackage.js +103 -0
- package/lib/compiler/internal/resolveNativeTypeScriptPackage.js.map +1 -0
- package/lib/compiler/internal/resolveTsgo.d.ts +7 -6
- package/lib/compiler/internal/resolveTsgo.js +16 -35
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runNativeCheckWithObservations.d.ts +18 -14
- package/lib/compiler/internal/runNativeCheckWithObservations.js +42 -18
- package/lib/compiler/internal/runNativeCheckWithObservations.js.map +1 -1
- package/lib/flags/FLAG_SCHEMA.js +7 -0
- package/lib/flags/FLAG_SCHEMA.js.map +1 -1
- package/lib/internal/nativeBinary.d.ts +4 -0
- package/lib/internal/nativeBinary.js +6 -1
- package/lib/internal/nativeBinary.js.map +1 -1
- package/lib/launcher/internal/parseTtsxCLI.d.ts +1 -0
- package/lib/launcher/internal/parseTtsxCLI.js +1 -0
- package/lib/launcher/internal/parseTtsxCLI.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.d.ts +2 -0
- package/lib/launcher/internal/prepareExecution.js +11 -2
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +5 -0
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/launcher/internal/runtime/installRuntimeHooks.js +7 -0
- package/lib/launcher/internal/runtime/installRuntimeHooks.js.map +1 -1
- package/lib/plugin/internal/load/loadProjectPlugins.js +1 -0
- package/lib/plugin/internal/load/loadProjectPlugins.js.map +1 -1
- package/lib/plugin/internal/source/SourceBuildCacheLayout.d.ts +2 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.js +3 -0
- package/lib/plugin/internal/source/SourceBuildCacheLayout.js.map +1 -1
- package/lib/plugin/internal/source/pluginBuildVersions.d.ts +8 -7
- package/lib/plugin/internal/source/pluginBuildVersions.js +13 -13
- package/lib/plugin/internal/source/pluginBuildVersions.js.map +1 -1
- package/lib/structures/ITtscPluginCapabilities.d.ts +13 -2
- package/package.json +9 -9
- package/src/compiler/internal/build/BuildExecution.ts +32 -16
- package/src/compiler/internal/build/RunBuildOptions.ts +3 -0
- package/src/compiler/internal/build/RuntimeBuildCache.ts +252 -0
- package/src/compiler/internal/build/RuntimeBuildInputs.ts +349 -0
- package/src/compiler/internal/build/RuntimeInputProof.ts +346 -0
- package/src/compiler/internal/build/TsgoArguments.ts +11 -5
- package/src/compiler/internal/build/runBuild.ts +20 -5
- package/src/compiler/internal/resolveNativeTypeScriptPackage.ts +110 -0
- package/src/compiler/internal/resolveTsgo.ts +17 -36
- package/src/compiler/internal/runNativeCheckWithObservations.ts +41 -18
- package/src/flags/FLAG_SCHEMA.ts +7 -0
- package/src/internal/nativeBinary.ts +4 -0
- package/src/launcher/internal/parseTtsxCLI.ts +1 -0
- package/src/launcher/internal/prepareExecution.ts +20 -2
- package/src/launcher/internal/runTtsx.ts +5 -0
- package/src/launcher/internal/runtime/installRuntimeHooks.ts +11 -0
- package/src/plugin/internal/load/loadProjectPlugins.ts +1 -0
- package/src/plugin/internal/source/SourceBuildCacheLayout.ts +4 -0
- package/src/plugin/internal/source/pluginBuildVersions.ts +13 -15
- package/src/structures/ITtscPluginCapabilities.ts +14 -2
- package/utility/host.go +22 -1
|
@@ -7,36 +7,40 @@ import type { TtscBuildResult } from "../../structures/internal/TtscBuildResult"
|
|
|
7
7
|
import { parseReferenceGraph } from "./parseNativeTransformOutput";
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Execute a check with
|
|
11
|
-
* selected host, original diagnostics, streams and status.
|
|
10
|
+
* Execute a check or opted-in build with same-generation input observations,
|
|
11
|
+
* preserving the selected host, original diagnostics, streams and status.
|
|
12
12
|
*
|
|
13
|
-
* The selected native verb must be check
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* The selected native verb must be check, or build with the separate
|
|
14
|
+
* emitObservations capability, before negotiating its generation channel. A
|
|
15
|
+
* check-stage descriptor can also serve effectful fix/format verbs; those
|
|
16
|
+
* retain their original result and never acquire an invented check graph. An
|
|
17
|
+
* opted-in host writes a private sidecar even when its check fails. Hosts
|
|
17
18
|
* without that transport run their original command under their existing
|
|
18
19
|
* descriptor and declared-input contract; omission does not assert complete
|
|
19
20
|
* driver observations. No check is rerun to infer what the earlier generation
|
|
20
21
|
* read. Missing metadata after an interrupted failed opted-in check likewise
|
|
21
|
-
* withholds reuse
|
|
22
|
-
* error
|
|
22
|
+
* withholds reuse. Missing or malformed successful check metadata is a protocol
|
|
23
|
+
* error. Build metadata is optional cache evidence: unavailable setup, records
|
|
24
|
+
* or cleanup retain the original build result with incomplete observations, so
|
|
25
|
+
* loss of caching cannot turn a fresh successful emit into failure.
|
|
23
26
|
*
|
|
24
27
|
* The callback receives only additional transport arguments. This operation
|
|
25
28
|
* owns their accepted canonical private directory and attempts file and empty
|
|
26
29
|
* directory removal without recursive deletion. Setup observes ownership before
|
|
27
30
|
* entering the cleanup boundary, so a setup observation failure can leave the
|
|
28
31
|
* allocation unclaimed. Cleanup failures retain the original thrown failure or
|
|
29
|
-
* completed result as their cause. Before reading and removing the
|
|
30
|
-
* the parent must still have its captured native identity; a replaced
|
|
31
|
-
* is left untouched and
|
|
32
|
-
* an atomic descriptor or ABA
|
|
32
|
+
* completed check result as their cause. Before reading and removing the
|
|
33
|
+
* artifact, the parent must still have its captured native identity; a replaced
|
|
34
|
+
* directory is left untouched and withholds build reuse or reports check
|
|
35
|
+
* failure. These observations do not provide an atomic descriptor or ABA
|
|
36
|
+
* guarantee.
|
|
33
37
|
*
|
|
34
|
-
* @evidence contracts/common.md#principled-implementation
|
|
38
|
+
* @evidence contracts/common.md#principled-implementation Actual check and build verbs negotiate independent declared observation capabilities; fix/format verbs retain their own result. Build witness IO/protocol failures preserve the one original build with incomplete observations, while checks retain their strict metadata contract. Legacy hosts keep their original command without fabricated completeness.
|
|
35
39
|
* @evidence contracts/common.md#clear-and-simple-design The actual verb and descriptor opt-in jointly select one adapter for strict wire decoding and private artifact lifetime; its callback retains command and diagnostic normalization ownership.
|
|
36
40
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Neither a later project-input query nor a separate transform can reconstruct check observations; unknown hosts receive no guessed flag and malformed metadata cannot become a complete empty observation.
|
|
37
41
|
* @evidence contracts/common.md#meaningful-documentation Native paragraphs distinguish failed-check metadata, unavailable transport, protocol errors and cleanup ownership, with body and tags separated according to the documentation skill.
|
|
38
42
|
* @evidence contracts/portability.md#os-neutral-implementation Node native absolute paths locate the canonical private artifact, and an additional argv element conveys it without shell quoting or platform-specific filename guesses.
|
|
39
|
-
* @evidence contracts/performance.md#efficient-algorithms One original check callback runs; this adapter adds canonical temp acquisition/native ownership observations, complete sidecar read/JSON decoding and indexed input membership/witness validation. Work and temporary storage follow wire/path bytes and declared inputs plus delegated
|
|
43
|
+
* @evidence contracts/performance.md#efficient-algorithms One original check or build callback runs; this adapter adds canonical temp acquisition/native ownership observations, complete sidecar read/JSON decoding and indexed input membership/witness validation. Work and temporary storage follow wire/path bytes and declared inputs plus delegated producer runtime; it does not add a second compiler generation or source-content rehash, and supplies no callback timeout or metadata-byte ceiling.
|
|
40
44
|
*
|
|
41
45
|
* @evidenceExclude contracts/performance.md#reuse-equivalent-work This adapter supplies the generation's proof to its cache owner rather than retaining or sharing a completed check itself.
|
|
42
46
|
*
|
|
@@ -48,17 +52,32 @@ export function runNativeCheckWithObservations(
|
|
|
48
52
|
/** Actual argv verb; legacy direct callers already represent a check. */
|
|
49
53
|
command: string = "check",
|
|
50
54
|
): TtscBuildResult {
|
|
51
|
-
|
|
55
|
+
const emitting =
|
|
56
|
+
command === "build" && plugin.capabilities?.emitObservations === true;
|
|
57
|
+
if (
|
|
58
|
+
!emitting &&
|
|
59
|
+
(command !== "check" || plugin.capabilities?.checkObservations !== true)
|
|
60
|
+
)
|
|
52
61
|
return run([]);
|
|
53
62
|
|
|
54
|
-
|
|
55
|
-
|
|
63
|
+
let directory: string;
|
|
64
|
+
let ownership: fs.Stats;
|
|
65
|
+
try {
|
|
66
|
+
directory = createCanonicalTempDirectory("ttsc-check-observations-");
|
|
67
|
+
ownership = fs.lstatSync(directory);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
if (emitting) return { ...run([]), observationsComplete: false };
|
|
70
|
+
throw error;
|
|
71
|
+
}
|
|
56
72
|
const file = path.join(directory, "observations.json");
|
|
57
73
|
let completed: TtscBuildResult | undefined;
|
|
58
74
|
let failed = false;
|
|
59
75
|
let failure: unknown;
|
|
60
76
|
try {
|
|
61
|
-
completed = run([
|
|
77
|
+
completed = run([
|
|
78
|
+
(emitting ? "--emit-observations-json=" : "--check-observations-json=") +
|
|
79
|
+
file,
|
|
80
|
+
]);
|
|
62
81
|
if (completed.processCompletedNormally !== true)
|
|
63
82
|
return { ...completed, observationsComplete: false };
|
|
64
83
|
let text: string;
|
|
@@ -68,6 +87,7 @@ export function runNativeCheckWithObservations(
|
|
|
68
87
|
throw new Error("check observation artifact is not an ordinary file");
|
|
69
88
|
text = fs.readFileSync(file, "utf8");
|
|
70
89
|
} catch (error) {
|
|
90
|
+
if (emitting) return { ...completed, observationsComplete: false };
|
|
71
91
|
if (
|
|
72
92
|
completed.status !== 0 &&
|
|
73
93
|
(error as NodeJS.ErrnoException).code === "ENOENT"
|
|
@@ -80,6 +100,7 @@ export function runNativeCheckWithObservations(
|
|
|
80
100
|
try {
|
|
81
101
|
return { ...completed, ...parseObservations(JSON.parse(text)) };
|
|
82
102
|
} catch (error) {
|
|
103
|
+
if (emitting) return { ...completed, observationsComplete: false };
|
|
83
104
|
throw new Error("ttsc: invalid check observation metadata", {
|
|
84
105
|
cause: new AggregateError([completed, error]),
|
|
85
106
|
});
|
|
@@ -108,6 +129,8 @@ export function runNativeCheckWithObservations(
|
|
|
108
129
|
}
|
|
109
130
|
}
|
|
110
131
|
if (errors.length !== 0) {
|
|
132
|
+
if (emitting && completed !== undefined && !failed)
|
|
133
|
+
return { ...completed, observationsComplete: false };
|
|
111
134
|
const primary = failed ? failure : completed;
|
|
112
135
|
throw new AggregateError(
|
|
113
136
|
[primary, ...errors],
|
package/src/flags/FLAG_SCHEMA.ts
CHANGED
|
@@ -352,6 +352,13 @@ export const FLAG_SCHEMA: readonly FlagSpec[] = [
|
|
|
352
352
|
// -------------------------------------------------------------------------
|
|
353
353
|
// ttsx-specific options.
|
|
354
354
|
// -------------------------------------------------------------------------
|
|
355
|
+
{
|
|
356
|
+
name: "--no-cache",
|
|
357
|
+
kind: "boolean",
|
|
358
|
+
subcommands: ["ttsx"],
|
|
359
|
+
consumedBy: ["launcher"],
|
|
360
|
+
description: "Disable persistent runtime project emit reuse.",
|
|
361
|
+
},
|
|
355
362
|
{
|
|
356
363
|
name: "--require",
|
|
357
364
|
aliases: ["-r"],
|
|
@@ -7,5 +7,9 @@
|
|
|
7
7
|
* `@ttsc/unplugin` runs its native watch helpers, imports them from here, so
|
|
8
8
|
* the helper always comes from the binary ttsc itself uses and no consumer
|
|
9
9
|
* carries a copy of the rules.
|
|
10
|
+
*
|
|
11
|
+
* `resolveTsgo` selects the consumer's native TypeScript compiler, including
|
|
12
|
+
* npm aliases targeting TypeScript used alongside legacy tooling.
|
|
10
13
|
*/
|
|
11
14
|
export { resolveBinary } from "../compiler/internal/resolveBinary";
|
|
15
|
+
export { resolveTsgo } from "../compiler/internal/resolveTsgo";
|
|
@@ -120,6 +120,7 @@ export function parseTtsxCLI(argv: readonly string[]) {
|
|
|
120
120
|
checkers: getNumber(result, "--checkers"),
|
|
121
121
|
cwd: getString(result, "--cwd"),
|
|
122
122
|
entry,
|
|
123
|
+
noCache: getBoolean(result, "--no-cache") === true,
|
|
123
124
|
noPlugins: getBoolean(result, "--no-plugins") === true,
|
|
124
125
|
passthrough: postEntryArgs,
|
|
125
126
|
preload,
|
|
@@ -65,6 +65,9 @@ export function prepareExecution(
|
|
|
65
65
|
|
|
66
66
|
/** Internal cache key for more than one checked entry in this process. */
|
|
67
67
|
runtimeCacheKey?: string;
|
|
68
|
+
|
|
69
|
+
/** False bypasses persistent project emits while keeping normal execution. */
|
|
70
|
+
runtimeCache?: boolean;
|
|
68
71
|
} = {},
|
|
69
72
|
): {
|
|
70
73
|
/** Claimed runtime generation whose cleanup ownership transfers to the caller. */
|
|
@@ -383,6 +386,15 @@ function createProjectContext(
|
|
|
383
386
|
runtimeCacheKey,
|
|
384
387
|
processDir,
|
|
385
388
|
pluginCacheDir: explicitCacheDir === undefined ? undefined : cacheDir,
|
|
389
|
+
runtimeBuildCacheDir:
|
|
390
|
+
options.runtimeCache === false ||
|
|
391
|
+
env.TTSX_DISABLE_CACHE === "1" ||
|
|
392
|
+
env.TTSC_PLUGIN_DESCRIPTOR_LOAD === "1"
|
|
393
|
+
? undefined
|
|
394
|
+
: path.join(
|
|
395
|
+
cacheRoot,
|
|
396
|
+
SourceBuildCacheLayout.RUNTIME_BUILD_CACHE_DIRNAME,
|
|
397
|
+
),
|
|
386
398
|
orphanCacheDir: path.join(
|
|
387
399
|
cacheRoot,
|
|
388
400
|
SourceBuildCacheLayout.ORPHAN_CACHE_DIRNAME,
|
|
@@ -527,6 +539,7 @@ function buildProject(
|
|
|
527
539
|
emit: true,
|
|
528
540
|
env: options.env,
|
|
529
541
|
cacheDir: context.pluginCacheDir,
|
|
542
|
+
runtimeCacheDir: context.runtimeBuildCacheDir,
|
|
530
543
|
outDir: context.emitDir,
|
|
531
544
|
// Every output this build writes stays in ttsx's private directory: a
|
|
532
545
|
// declared `declarationDir`, `tsBuildInfoFile`, or `outFile`, and any
|
|
@@ -743,7 +756,9 @@ function collectLinkDirectories(projectRoot: string): string[] {
|
|
|
743
756
|
}
|
|
744
757
|
|
|
745
758
|
/**
|
|
746
|
-
* Whether mirroring `directory` would reach a filesystem
|
|
759
|
+
* Whether mirroring `directory` would reach a filesystem root, the temporary
|
|
760
|
+
* root or any of its ancestors. A caller can place its temporary root inside
|
|
761
|
+
* its project; its parents still contain shared entries outside that project.
|
|
747
762
|
* Identity comparison is required on Windows, where `os.tmpdir()` can carry an
|
|
748
763
|
* 8.3 component while a project created below it is returned in long spelling.
|
|
749
764
|
*/
|
|
@@ -754,7 +769,10 @@ function isUnsafeVirtualParent(
|
|
|
754
769
|
const resolved = identities.resolve(directory);
|
|
755
770
|
const root = identities.resolve(path.parse(resolved.path).root);
|
|
756
771
|
const temporaryRoot = identities.resolve(os.tmpdir());
|
|
757
|
-
return
|
|
772
|
+
return (
|
|
773
|
+
resolved.key === root.key ||
|
|
774
|
+
identities.isWithin(resolved.path, temporaryRoot.path)
|
|
775
|
+
);
|
|
758
776
|
}
|
|
759
777
|
|
|
760
778
|
/**
|
|
@@ -110,6 +110,7 @@ async function run(
|
|
|
110
110
|
cacheDir: resolveCacheDir(cwd, parsed.cacheDir),
|
|
111
111
|
checkers: parsed.checkers,
|
|
112
112
|
cwd,
|
|
113
|
+
env: parsed.noCache ? { TTSX_DISABLE_CACHE: "1" } : undefined,
|
|
113
114
|
passthrough: parsed.tsgoFlags,
|
|
114
115
|
// `--no-plugins` builds the entry's owning project with plugin
|
|
115
116
|
// discovery and loading disabled. ttsc's own config loaders use it
|
|
@@ -121,6 +122,7 @@ async function run(
|
|
|
121
122
|
// tsconfig deliberately does not satisfy.
|
|
122
123
|
plugins: parsed.noPlugins ? false : undefined,
|
|
123
124
|
project: parsed.project,
|
|
125
|
+
runtimeCache: !parsed.noCache,
|
|
124
126
|
singleThreaded: parsed.singleThreaded,
|
|
125
127
|
});
|
|
126
128
|
await settleSignals();
|
|
@@ -159,6 +161,7 @@ function printHelp(): void {
|
|
|
159
161
|
" -P, --project <file> Use an explicit tsconfig.json",
|
|
160
162
|
" --cwd <dir> Resolve entry/project relative to this directory",
|
|
161
163
|
" --cache-dir <dir> Override the runner and source-plugin cache root",
|
|
164
|
+
" --no-cache Disable persistent runtime project emit reuse",
|
|
162
165
|
" --binary <path> Use an explicit tsgo binary",
|
|
163
166
|
" --no-plugins Build the project without ttsc plugins",
|
|
164
167
|
" -r, --require <module> Preload a module before the entrypoint",
|
|
@@ -244,6 +247,7 @@ async function runJavaScriptEntry(
|
|
|
244
247
|
];
|
|
245
248
|
const env: NodeJS.ProcessEnv = {
|
|
246
249
|
...process.env,
|
|
250
|
+
...(parsed.noCache ? { TTSX_DISABLE_CACHE: "1" } : {}),
|
|
247
251
|
// ttsc's own helpers run with what the user passed (#1740).
|
|
248
252
|
...TtsxNodeOptions.give(
|
|
249
253
|
process.env,
|
|
@@ -329,6 +333,7 @@ async function runPreparedEntry(
|
|
|
329
333
|
];
|
|
330
334
|
const runtimeEnv: NodeJS.ProcessEnv = {
|
|
331
335
|
...process.env,
|
|
336
|
+
...(parsed.noCache ? { TTSX_DISABLE_CACHE: "1" } : {}),
|
|
332
337
|
// ttsc's own helpers run with what the user passed (#1740).
|
|
333
338
|
...TtsxNodeOptions.give(
|
|
334
339
|
process.env,
|
|
@@ -22,7 +22,9 @@ import { createCanonicalTempDirectory } from "../../../internal/createCanonicalT
|
|
|
22
22
|
import { runtimeExecutableIdentity } from "../../../internal/runtimeExecutableIdentity";
|
|
23
23
|
import { moduleResolutionBaseSelects } from "../../../plugin/internal/load/moduleResolutionBaseSelects";
|
|
24
24
|
import { PluginContentIdentities } from "../../../plugin/internal/source/PluginContentIdentities";
|
|
25
|
+
import { SourceBuildCacheLayout } from "../../../plugin/internal/source/SourceBuildCacheLayout";
|
|
25
26
|
import { recordCacheFileUse } from "../../../plugin/internal/source/recordCacheFileUse";
|
|
27
|
+
import { resolveSourceBuildCachePaths } from "../../../plugin/internal/source/resolveSourceBuildCachePaths";
|
|
26
28
|
import { buildSingleRootProject } from "../buildSingleRootProject";
|
|
27
29
|
import { inlineServedSourceMap } from "../inlineServedSourceMap";
|
|
28
30
|
import { runtimeCompilerArgs } from "../runtimeCompilerArgs";
|
|
@@ -2192,6 +2194,15 @@ function buildDependency(
|
|
|
2192
2194
|
fs.mkdirSync(emitDir, { recursive: true });
|
|
2193
2195
|
const result = runBuild({
|
|
2194
2196
|
cwd: project.root,
|
|
2197
|
+
runtimeCacheDir:
|
|
2198
|
+
process.env.TTSX_DISABLE_CACHE === "1" ||
|
|
2199
|
+
process.env.TTSC_PLUGIN_DESCRIPTOR_LOAD === "1"
|
|
2200
|
+
? undefined
|
|
2201
|
+
: path.join(
|
|
2202
|
+
runtimeRecordStore()?.root ??
|
|
2203
|
+
resolveSourceBuildCachePaths(project.root).root,
|
|
2204
|
+
SourceBuildCacheLayout.RUNTIME_BUILD_CACHE_DIRNAME,
|
|
2205
|
+
),
|
|
2195
2206
|
forceEmitProvenance: true,
|
|
2196
2207
|
// Emit-only means diagnostics never withhold the emit, so a dependency's
|
|
2197
2208
|
// own `noEmitOnError` is switched off: honoured, it would turn any
|
|
@@ -80,6 +80,9 @@ export namespace SourceBuildCacheLayout {
|
|
|
80
80
|
/** Directory of the lowered orphan sources inside the cache root. */
|
|
81
81
|
export const ORPHAN_CACHE_DIRNAME = "ttsx-orphan";
|
|
82
82
|
|
|
83
|
+
/** Checksummed completed runtime project emits, independent of run lifetime. */
|
|
84
|
+
export const RUNTIME_BUILD_CACHE_DIRNAME = "runtime-builds";
|
|
85
|
+
|
|
83
86
|
/**
|
|
84
87
|
* The parts of the cache root whose entries are single files, each collected
|
|
85
88
|
* by `pruneCacheFileRoot` and removed by `ttsc clean`.
|
|
@@ -90,6 +93,7 @@ export namespace SourceBuildCacheLayout {
|
|
|
90
93
|
IDENTITY_CACHE_DIRNAME,
|
|
91
94
|
ANSWER_CACHE_DIRNAME,
|
|
92
95
|
ORPHAN_CACHE_DIRNAME,
|
|
96
|
+
RUNTIME_BUILD_CACHE_DIRNAME,
|
|
93
97
|
];
|
|
94
98
|
|
|
95
99
|
/**
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import { createRequire } from "node:module";
|
|
3
1
|
import path from "node:path";
|
|
4
2
|
|
|
3
|
+
import { resolveNativeTypeScriptPackage } from "../../../compiler/internal/resolveNativeTypeScriptPackage";
|
|
5
4
|
import { ttscPackageVersion } from "./ttscPackageVersion";
|
|
6
5
|
|
|
7
6
|
/**
|
|
@@ -14,14 +13,15 @@ import { ttscPackageVersion } from "./ttscPackageVersion";
|
|
|
14
13
|
* consumer that keeps a transform's output beyond the process that produced it,
|
|
15
14
|
* as a persisted shared compile of `@ttsc/unplugin` is, names it by these
|
|
16
15
|
* versions with the rule the build applies instead of a copy of it: ttsc's own
|
|
17
|
-
* package version, and the version of the
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
16
|
+
* package version, and the version of the native TypeScript package the project
|
|
17
|
+
* selects (declared npm aliases before `typescript`), or `"unknown"` when
|
|
18
|
+
* resolution/read/parse fails or its version is absent. The host label falls
|
|
19
|
+
* back to `"0.0.0"` and is cached even after an unsuccessful first read. The
|
|
20
|
+
* host installation is assumed stable for the process lifetime; changing its
|
|
21
|
+
* manifest does not refresh that label.
|
|
22
22
|
*
|
|
23
|
-
* @param projectRoot The project base used to resolve
|
|
24
|
-
*
|
|
23
|
+
* @param projectRoot The project base used to resolve the native TypeScript
|
|
24
|
+
* manifest.
|
|
25
25
|
* @evidence contracts/common.md#principled-implementation Package-version labels supply the same metadata tuple used by plugin keys; absent/unreadable metadata receives the documented unknown/default label rather than an executable identity certificate.
|
|
26
26
|
* @evidence contracts/common.md#clear-and-simple-design The host label comes from its own owner (`ttscPackageVersion`), which a reader needing only that label calls without this function's project resolution; the project-version reader is separate because project resolution varies per call.
|
|
27
27
|
* @evidence contracts/common.md#prohibited-implementation-shortcuts Node package resolution determines the actual project dependency; no particular project or fixture version is embedded.
|
|
@@ -40,14 +40,12 @@ export function pluginBuildVersions(projectRoot: string): {
|
|
|
40
40
|
|
|
41
41
|
function readTsgoVersion(projectRoot: string): string {
|
|
42
42
|
try {
|
|
43
|
-
const
|
|
43
|
+
const selected = resolveNativeTypeScriptPackage(
|
|
44
44
|
path.join(projectRoot, "package.json"),
|
|
45
45
|
);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
};
|
|
50
|
-
return pkg.version ?? "unknown";
|
|
46
|
+
return typeof selected?.manifest.version === "string"
|
|
47
|
+
? selected.manifest.version
|
|
48
|
+
: "unknown";
|
|
51
49
|
} catch {
|
|
52
50
|
return "unknown";
|
|
53
51
|
}
|
|
@@ -83,13 +83,25 @@ export interface ITtscPluginCapabilities {
|
|
|
83
83
|
* from an output filename or configuration prediction.
|
|
84
84
|
*
|
|
85
85
|
* When omitted, ttsc does not pass the option to a strict third-party host. A
|
|
86
|
-
* runtime operation
|
|
87
|
-
*
|
|
86
|
+
* runtime operation then uses the existing externally observed provenance
|
|
87
|
+
* adapter, whose incomplete proof remains visible to the runtime consumer.
|
|
88
88
|
*
|
|
89
89
|
* @default false
|
|
90
90
|
*/
|
|
91
91
|
emitProvenance?: true;
|
|
92
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Whether build accepts `--emit-observations-json=<absolute private path>`
|
|
95
|
+
* and publishes its generation's compiler and native input observations.
|
|
96
|
+
* Missing support keeps runtime emits fresh rather than assuming reusable
|
|
97
|
+
* input completeness. This protocol is independent of output ownership. Hosts
|
|
98
|
+
* publish the same observation envelope as checkObservations, including
|
|
99
|
+
* failures, before releasing their Program.
|
|
100
|
+
*
|
|
101
|
+
* @default false
|
|
102
|
+
*/
|
|
103
|
+
emitObservations?: true;
|
|
104
|
+
|
|
93
105
|
/**
|
|
94
106
|
* Whether the sidecar accepts ttsc's `--project-context-json` identity
|
|
95
107
|
* protocol. The payload keeps lexical selection paths, physical Program
|
package/utility/host.go
CHANGED
|
@@ -40,6 +40,9 @@ type hostOptions struct {
|
|
|
40
40
|
// checkObservationsJSON is the caller-owned absolute check input result path.
|
|
41
41
|
checkObservationsJSON string
|
|
42
42
|
|
|
43
|
+
// emitObservationsJSON is the caller-owned absolute build input result path.
|
|
44
|
+
emitObservationsJSON string
|
|
45
|
+
|
|
43
46
|
// observationsIncomplete points to the resident host's committed generation
|
|
44
47
|
// state. It is nil for non-resident calls and updated only after success.
|
|
45
48
|
observationsIncomplete *bool
|
|
@@ -201,6 +204,10 @@ func RunBuild(args []string) int {
|
|
|
201
204
|
// diagnostics. Analysis-only success writes an empty map. The original build
|
|
202
205
|
// status remains authoritative; absent or invalid metadata supplies no ownership
|
|
203
206
|
// proof. Callers own the artifact's removal.
|
|
207
|
+
// A separately negotiated absolute emit-observations path receives this same
|
|
208
|
+
// Program's compiler and native input witnesses before its checker lease closes,
|
|
209
|
+
// including failing loaded builds. Unavailable optional observations withhold
|
|
210
|
+
// reuse without changing the build status. They supply no authority by themselves.
|
|
204
211
|
// Program.Close returns its checker lease; it does not remove emitted files or
|
|
205
212
|
// private metadata. Summary and diagnostic stream writes are best-effort here,
|
|
206
213
|
// so a zero status does not certify delivery to the supplied io.Writer values.
|
|
@@ -211,7 +218,7 @@ func RunBuild(args []string) int {
|
|
|
211
218
|
// @evidence contracts/common.md#meaningful-documentation Native paragraphs identify stream ownership, failure statuses, private metadata admission and caller artifact removal following the documentation skill.
|
|
212
219
|
// @evidence contracts/portability.md#os-neutral-implementation Driver loading and DefaultWriteFile own native paths and filesystem APIs; output streams are not replaced globally.
|
|
213
220
|
// @evidence contracts/performance.md#efficient-algorithms Admission and loading include argument/plugin-manifest parsing, native project and diagnostic work. Emission dispatches linked AST transforms through the driver, which owns native generation and one authored-coordinate correction. The final writer indexes compiler carrier/map paths and shifts generated map coordinates only when it inserts missing preamble text, including JSON/base64/VLQ and output-byte work. Optional provenance adds output-path candidate collection, successful-write bookkeeping, source-proof checks, owner sorting and JSON/file publication; costs depend on source/graph, output and metadata bytes rather than only the number of emit calls.
|
|
214
|
-
// @evidence contracts/performance.md#reuse-equivalent-work The same loaded compiler generation validates and
|
|
221
|
+
// @evidence contracts/performance.md#reuse-equivalent-work The same loaded compiler generation validates, emits and optionally publishes its input witnesses; linked program hooks remain latched rather than independently reexecuted for output files. Completed-generation reuse belongs to the caller.
|
|
215
222
|
// @evidence contracts/performance.md#bound-retention-and-release-resources Successful loading transfers one Program checker lease to a deferred Close on analysis-only, normal and failure returns. The final writer retains output-path decisions and maps awaiting their carrier without a byte cap, releases pending map entries as their carrier arrives, and reports unfinished pairs at emit completion. Facade graphs, provenance maps, writer closures and serialization buffers lose local ownership when the invocation ends; Close does not destroy all program memory, supplied-stream state or emitted disk artifacts. Callers own stream lifetime and metadata/output removal, with no invocation-enforced byte cap.
|
|
216
223
|
func RunBuildWithIO(args []string, stdout, stderr io.Writer) int {
|
|
217
224
|
opts, ok := parseHostOptions("build", args, stdout, stderr)
|
|
@@ -224,6 +231,13 @@ func RunBuildWithIO(args []string, stdout, stderr io.Writer) int {
|
|
|
224
231
|
return 2
|
|
225
232
|
}
|
|
226
233
|
defer prog.Close()
|
|
234
|
+
defer func() {
|
|
235
|
+
if opts.emitObservationsJSON != "" {
|
|
236
|
+
if err := driver.WriteCheckObservationsJSON(opts.emitObservationsJSON, prog); err != nil {
|
|
237
|
+
fmt.Fprintf(opts.stderr, "ttsc utility: emit observations write failed: %v\n", err)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}()
|
|
227
241
|
driver.WritePrettyDiagnostics(opts.stderr, diags, opts.cwd)
|
|
228
242
|
if opts.noEmit {
|
|
229
243
|
if len(diags) != 0 {
|
|
@@ -446,8 +460,10 @@ func parseHostOptions(command string, args []string, stdout, stderr io.Writer) (
|
|
|
446
460
|
tsgoArgsRaw := fs.String("tsgo-args", "", "JSON array of forwarded tsgo CLI flags")
|
|
447
461
|
provenanceJSON := ""
|
|
448
462
|
checkObservationsJSON := ""
|
|
463
|
+
emitObservationsJSON := ""
|
|
449
464
|
if command == "build" {
|
|
450
465
|
fs.StringVar(&provenanceJSON, "emit-provenance-json", "", "private absolute emit provenance result path")
|
|
466
|
+
fs.StringVar(&emitObservationsJSON, "emit-observations-json", "", "private absolute build input result path")
|
|
451
467
|
}
|
|
452
468
|
if command == "check" {
|
|
453
469
|
fs.StringVar(&checkObservationsJSON, "check-observations-json", "", "private absolute check input result path")
|
|
@@ -463,6 +479,10 @@ func parseHostOptions(command string, args []string, stdout, stderr io.Writer) (
|
|
|
463
479
|
fmt.Fprintln(stderr, "ttsc utility: check observations path must be absolute")
|
|
464
480
|
return hostOptions{}, false
|
|
465
481
|
}
|
|
482
|
+
if emitObservationsJSON != "" && !filepath.IsAbs(emitObservationsJSON) {
|
|
483
|
+
fmt.Fprintln(stderr, "ttsc utility: emit observations path must be absolute")
|
|
484
|
+
return hostOptions{}, false
|
|
485
|
+
}
|
|
466
486
|
var tsgoArgs []string
|
|
467
487
|
if *tsgoArgsRaw != "" {
|
|
468
488
|
if err := json.Unmarshal([]byte(*tsgoArgsRaw), &tsgoArgs); err != nil {
|
|
@@ -507,6 +527,7 @@ func parseHostOptions(command string, args []string, stdout, stderr io.Writer) (
|
|
|
507
527
|
stderr: stderr,
|
|
508
528
|
provenanceJSON: provenanceJSON,
|
|
509
529
|
checkObservationsJSON: checkObservationsJSON,
|
|
530
|
+
emitObservationsJSON: emitObservationsJSON,
|
|
510
531
|
}, true
|
|
511
532
|
}
|
|
512
533
|
|